Pods – Custom Content Types and Fields - Version 2.6.11

Version Description

  • September 20th 2017 =
  • Fixed: WordPress 4.8.2 introduced a breaking change that no longer correctly prepared number/currency queries. It did not introduce a vulnerability but only produced Database errors.
  • Stay tuned for Pods 2.7 which will be out soon -- Download Pods 2.7 RC1 and join our Pods Slack channel #pods-beta to help us finish the final testing
Download this release

Release Info

Developer sc0ttkclark
Plugin Icon 128x128 Pods – Custom Content Types and Fields
Version 2.6.11
Comparing to
See all releases

Code changes from version 1.14.8 to 2.6.11

CODEOWNERS ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ # These owners will be the default owners for everything in the repo.
2
+ * @sc0ttkclark @pglewis
3
+
4
+ # These owners will be the default owners for JS files in the repo.
5
+ # *.js @exampleuser
6
+
7
+ # These owners will be the default owners for PHP files in the repo.
8
+ # *.php @exampleuser
classes/Pod.php DELETED
@@ -1,1325 +0,0 @@
1
- <?php
2
- class Pod
3
- {
4
- var $id;
5
- var $sql;
6
- var $raw_sql;
7
- var $data;
8
- var $row_number = -1;
9
- var $zebra = false;
10
- var $result;
11
- var $datatype;
12
- var $datatype_id;
13
- var $calc_found_rows = true;
14
- var $count_found_rows = false;
15
- var $total;
16
- var $total_rows;
17
- var $detail_page;
18
- var $rpp = 15;
19
- var $page_var = 'pg';
20
- var $page = 1;
21
- var $pagination = true;
22
- var $search = true;
23
- var $search_var = 'search';
24
- var $search_where = '';
25
- var $search_mode = 'int'; // int | text | text_like
26
-
27
- var $traverse = array();
28
- var $rabit_hole = array();
29
-
30
- /**
31
- * Constructor - Pods CMS core
32
- *
33
- * @param string $datatype The pod name
34
- * @param mixed $id (optional) The ID or slug, to load a single record; Provide array of $params to run findRecords immediately
35
- * @license http://www.gnu.org/licenses/gpl-2.0.html
36
- * @since 1.0.0
37
- */
38
- function __construct($datatype = null, $id = null) {
39
- $datatype = pods_sanitize($datatype);
40
-
41
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE) {
42
- $this->page = 1;
43
- $this->pagination = false;
44
- $this->search = false;
45
- }
46
- else {
47
- // Get the page variable
48
- $this->page = pods_var($this->page_var, 'get');
49
- $this->page = empty($this->page) ? 1 : max((int) $this->page, 1);
50
- if (defined('PODS_GLOBAL_POD_PAGINATION') && !PODS_GLOBAL_POD_PAGINATION) {
51
- $this->page = 1;
52
- $this->pagination = false;
53
- }
54
-
55
- if (defined('PODS_GLOBAL_POD_SEARCH') && !PODS_GLOBAL_POD_SEARCH)
56
- $this->search = false;
57
- if (defined('PODS_GLOBAL_POD_SEARCH_MODE') && in_array(PODS_GLOBAL_POD_SEARCH_MODE, array('int', 'text', 'text_like')))
58
- $this->search_mode = PODS_GLOBAL_POD_SEARCH_MODE;
59
- }
60
-
61
- if (!empty($datatype)) {
62
- $result = pod_query("SELECT id, name, detail_page FROM @wp_pod_types WHERE name = '$datatype' LIMIT 1");
63
- if (0 < pods_mysql_num_rows($result)) {
64
- $row = pods_mysql_fetch_assoc($result);
65
- $this->datatype = $row['name'];
66
- $this->datatype_id = $row['id'];
67
- $this->detail_page = $row['detail_page'];
68
-
69
- if (null !== $id) {
70
- if (is_array($id) || is_object($id))
71
- $this->findRecords($id);
72
- else {
73
- $this->getRecordById($id);
74
- if (!empty($this->data))
75
- $this->id = $this->get_field('id');
76
- }
77
- }
78
- }
79
- else
80
- echo "<e>Error: Pod '{$datatype}' does not exist</e>";
81
- }
82
- }
83
-
84
- /**
85
- * Fetch a row of results from the DB
86
- *
87
- * @since 1.2.0
88
- */
89
- function fetchRecord() {
90
- if ($this->data = pods_mysql_fetch_assoc($this->result)) {
91
- $this->row_number++;
92
- if (true === $this->zebra)
93
- $this->zebra = false;
94
- else
95
- $this->zebra = true;
96
- return $this->data;
97
- }
98
- return false;
99
- }
100
-
101
- /**
102
- * Return a field's value(s)
103
- *
104
- * @param string $name The field name
105
- * @param string $orderby (optional) The orderby string, for PICK fields
106
- * @since 1.2.0
107
- */
108
- function get_field($name, $orderby = null) {
109
- if (empty($this->data) && empty($this->datatype_id)) {
110
- echo "<e>Error: Pod name invalid, no data available</e>";
111
- return null;
112
- }
113
- // No data
114
- elseif ( !isset( $this->data[ 'id' ] ) )
115
- return null;
116
-
117
- if (isset($this->data[$name])) {
118
- return $this->data[$name];
119
- }
120
- elseif ('created' == $name || 'modified' == $name) {
121
- $pod_id = (int) $this->get_pod_id();
122
- if (!empty($pod_id))
123
- $result = pod_query("SELECT id, created, modified FROM @wp_pod WHERE id = {$pod_id} LIMIT 1");
124
- else {
125
- $tbl_row_id = (int) $this->get_field('id');
126
- if (!empty($tbl_row_id))
127
- $result = pod_query("SELECT id, created, modified FROM @wp_pod WHERE tbl_row_id = {$tbl_row_id} LIMIT 1");
128
- else
129
- return;
130
- }
131
- $row = pods_mysql_fetch_assoc($result);
132
- $this->data['pod_id'] = $row['pod_id'];
133
- $this->data['created'] = $row['created'];
134
- $this->data['modified'] = $row['modified'];
135
- return $this->data[$name];
136
- }
137
- elseif ('detail_url' == $name) {
138
- return $this->parse_magic_tags(array('', '', 'detail_url'));
139
- }
140
- else {
141
- // Dot-traversal
142
- $last_loop = false;
143
- $datatype_id = $this->datatype_id;
144
- $tbl_row_ids = ( isset( $this->data[ 'id' ] ) ? $this->data[ 'id' ] : 0 ); // allow for custom selects
145
-
146
- $traverse = (false !== strpos($name, '.')) ? explode('.', $name) : array($name);
147
- $traverse_fields = implode("','", $traverse);
148
-
149
- // Get columns matching traversal names
150
- $result = pod_query("SELECT id, datatype, name, coltype, pickval FROM @wp_pod_fields WHERE name IN ('$traverse_fields')");
151
- if (0 < pods_mysql_num_rows($result)) {
152
- while ($row = pods_mysql_fetch_assoc($result)) {
153
- $all_fields[$row['datatype']][$row['name']] = $row;
154
- }
155
- }
156
- // No matching columns
157
- else {
158
- return false;
159
- }
160
-
161
- $last_coltype = $last_pickval = '';
162
- // Loop through each traversal level
163
- foreach ($traverse as $key => $column_name) {
164
- $last_loop = (1 < count($traverse) - $key) ? false : true;
165
- $column_exists = isset($all_fields[$datatype_id][$column_name]);
166
-
167
- if ($column_exists) {
168
- $col = $all_fields[$datatype_id][$column_name];
169
- $field_id = $col['id'];
170
- $coltype = $col['coltype'];
171
- $pickval = $col['pickval'];
172
-
173
- if ('pick' == $coltype || 'file' == $coltype) {
174
- $last_coltype = $coltype;
175
- $last_pickval = $pickval;
176
- $tbl_row_ids = $this->lookup_row_ids($field_id, $datatype_id, $tbl_row_ids);
177
-
178
- if (false === $tbl_row_ids) {
179
- return false;
180
- }
181
-
182
- // Get datatype ID for non-WP PICK columns
183
- if (
184
- !empty($pickval) &&
185
- !in_array($pickval, array('wp_taxonomy', 'wp_post', 'wp_page', 'wp_user')))
186
- {
187
- $result = pod_query("SELECT id FROM @wp_pod_types WHERE name = '$pickval' LIMIT 1");
188
- $datatype_id = pods_mysql_result($result, 0);
189
- }
190
- }
191
- else {
192
- $last_loop = true;
193
- }
194
- }
195
- // Assume last iteration
196
- else {
197
- // Invalid column name
198
- if (0 == $key) {
199
- return false;
200
- }
201
- $last_loop = true;
202
- }
203
-
204
- if ($last_loop) {
205
- $table = ('file' == $last_coltype) ? 'file' : $last_pickval;
206
-
207
- if (!empty($table)) {
208
- $data = $this->rel_lookup($tbl_row_ids, $table, $orderby);
209
- }
210
-
211
- if (empty($data)) {
212
- $results = false;
213
- }
214
- // Return entire array
215
- elseif (false !== $column_exists && ('pick' == $coltype || 'file' == $coltype)) {
216
- $results = $data;
217
- }
218
- // Return a single column value
219
- elseif (1 == count($data)) {
220
- $results = $data[0][$column_name];
221
- }
222
- // Return an array of single column values
223
- else {
224
- foreach ($data as $key => $val) {
225
- $results[] = $val[$column_name];
226
- }
227
- }
228
- return $results;
229
- }
230
- }
231
- }
232
- }
233
-
234
- /**
235
- * Find items related to a parent field
236
- *
237
- * @param int $field_id The field ID
238
- * @param int $datatype_id The datatype ID
239
- * @param mixed $tbl_row_ids A comma-separated string (or array) of row IDs
240
- * @since 1.2.0
241
- */
242
- function lookup_row_ids($field_id, $datatype_id, $tbl_row_ids) {
243
- if (empty($tbl_row_ids))
244
- $tbl_row_ids = 0;
245
- else {
246
- if (!is_array($tbl_row_ids))
247
- $tbl_row_ids = explode(',', $tbl_row_ids);
248
- foreach ($tbl_row_ids as $key => $id) {
249
- $tbl_row_ids[$key] = (int) $id;
250
- }
251
- $tbl_row_ids = implode(',', $tbl_row_ids);
252
- }
253
-
254
- $field_id = (int) $field_id;
255
- $datatype_id = (int) $datatype_id;
256
-
257
- $sql = "
258
- SELECT
259
- `r`.`tbl_row_id`
260
- FROM
261
- `@wp_pod` AS `p`
262
- INNER JOIN
263
- `@wp_pod_rel` AS `r` ON `r`.`field_id` = {$field_id} AND `r`.`pod_id` = `p`.`id`
264
- WHERE
265
- `p`.`datatype` = {$datatype_id} AND `p`.`tbl_row_id` IN ($tbl_row_ids)
266
- ORDER BY
267
- `r`.`weight`
268
- ";
269
- $result = pod_query($sql);
270
- if (0 < pods_mysql_num_rows($result)) {
271
- while ($row = pods_mysql_fetch_assoc($result)) {
272
- $out[] = $row['tbl_row_id'];
273
- }
274
- return implode(',', $out);
275
- }
276
- return false;
277
- }
278
-
279
- /**
280
- * Lookup values from a single relationship field
281
- *
282
- * @param mixed $tbl_row_ids A comma-separated string of row IDs
283
- * @param string $table The database table alias
284
- * @param string $orderby (optional) MySQL "ORDER BY" clause
285
- * @return array $data Associative array of table column values
286
- * @since 1.2.0
287
- */
288
- function rel_lookup($tbl_row_ids, $table, $orderby = null) {
289
- global $wpdb;
290
- $orderby = empty($orderby) ? '' : "ORDER BY $orderby";
291
-
292
- // WP taxonomy item
293
- if ('wp_taxonomy' == $table) {
294
- $result = pod_query("SELECT * FROM `$wpdb->terms` WHERE `term_id` IN ($tbl_row_ids) $orderby");
295
- }
296
- // WP page, post, or attachment
297
- elseif ('wp_page' == $table || 'wp_post' == $table || 'file' == $table) {
298
- $result = pod_query("SELECT * FROM `$wpdb->posts` WHERE `ID` IN ($tbl_row_ids) $orderby");
299
- }
300
- // WP user
301
- elseif ('wp_user' == $table) {
302
- $result = pod_query("SELECT * FROM `$wpdb->users` WHERE `ID` IN ($tbl_row_ids) $orderby");
303
- }
304
- // Pod table
305
- else {
306
- $result = pod_query("SELECT * FROM `@wp_pod_tbl_$table` WHERE `id` IN ($tbl_row_ids) $orderby");
307
- }
308
-
309
- //override with custom relational query
310
- $result = apply_filters('pods_rel_lookup', $result, $tbl_row_ids, $table, $orderby, $this);
311
-
312
- // Put all related items into an array
313
- if (!is_array($result)) {
314
- while ($row = pods_mysql_fetch_assoc($result)) {
315
- $data[] = $row;
316
- }
317
- }
318
- else
319
- $data = $result;
320
-
321
- //override with custom data
322
- $data = apply_filters('pods_rel_lookup_data', $data, $tbl_row_ids, $table, $orderby, $this);
323
-
324
- return $data;
325
- }
326
-
327
- /**
328
- * Get the current item's pod ID from its datatype ID and tbl_row_id
329
- *
330
- * @todo pod_id should NEVER be needed by users - fix code so tbl_row_id is used instead
331
- * @return int The ID from the wp_pod table
332
- * @since 1.2.0
333
- */
334
- function get_pod_id() {
335
- if (empty($this->data) && empty($this->datatype_id)) {
336
- echo "<e>Error: Pod name invalid, no data available</e>";
337
- return null;
338
- }
339
- elseif (empty($this->data))
340
- return 0;
341
- elseif ((!isset($this->data['pod_id']) ||empty($this->data['pod_id'])) && isset($this->data['id']) && 0 < $this->data['id']) {
342
- $this->data['pod_id'] = 0;
343
- $tbl_row_id = (isset($this->data['id']) ? (int) $this->data['id'] : 0);
344
- $result = pod_query("SELECT `id` FROM `@wp_pod` WHERE `datatype` = '$this->datatype_id' AND `tbl_row_id` = '$tbl_row_id' LIMIT 1");
345
- if (0 < pods_mysql_num_rows($result)) {
346
- $this->data['pod_id'] = pods_mysql_result($result, 0);
347
- }
348
- }
349
- return $this->data['pod_id'];
350
- }
351
-
352
- /**
353
- * Set a custom data value (no database changes)
354
- *
355
- * @param string $name The field name
356
- * @param mixed $data The value to set
357
- * @return mixed The value of $data
358
- * @since 1.2.0
359
- */
360
- function set_field($name, $data) {
361
- return $this->data[$name] = $data;
362
- }
363
-
364
- /**
365
- * Run a helper within a Pod Page or WP Template or Magic Tags
366
- *
367
- * @param string $helper The helper name
368
- * @return mixed Anything returned by the helper
369
- * @since 1.2.0
370
- */
371
- function pod_helper($helper, $value = null, $name = null) {
372
- ob_start();
373
-
374
- do_action('pods_pre_pod_helper', $helper, $value, $name, $this);
375
- do_action("pods_pre_pod_helper_{$helper}", $helper, $value, $name, $this);
376
-
377
- $function_or_file = $helper;
378
- $check_function = $function_or_file;
379
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_HELPER_FUNCTIONS') || !PODS_HELPER_FUNCTIONS))
380
- $check_function = false;
381
- $check_file = null;
382
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_HELPER_FILES') || !PODS_HELPER_FILES))
383
- $check_file = false;
384
- if (false !== $check_function && false !== $check_file)
385
- $function_or_file = pods_function_or_file($function_or_file, $check_function, 'helper', $check_file);
386
- else
387
- $function_or_file = false;
388
-
389
- $content = false;
390
- if (!$function_or_file) {
391
- $api = new PodAPI();
392
- $params = array('name' => $helper, 'type' => 'display');
393
- if (!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE)
394
- $params = pods_sanitize($params);
395
- $content = $api->load_helper($params);
396
- if (false !== $content && 0 < strlen(trim($content['phpcode'])))
397
- $content = $content['phpcode'];
398
- else
399
- $content = false;
400
- }
401
-
402
- if (false === $content && false !== $function_or_file && isset($function_or_file['function']))
403
- echo $function_or_file['function']($value, $name, $this);
404
- elseif (false === $content && false !== $function_or_file && isset($function_or_file['file']))
405
- locate_template($function_or_file['file'], true, true);
406
- elseif (false !== $content) {
407
- if (!defined('PODS_DISABLE_EVAL') || !PODS_DISABLE_EVAL)
408
- eval("?>$content");
409
- else
410
- echo $content;
411
- }
412
-
413
- //post-helper hooks
414
- do_action('pods_post_pod_helper', $helper, $value, $name, $this);
415
- do_action("pods_post_pod_helper_{$helper}", $helper, $value, $name, $this);
416
-
417
- return apply_filters('pods_helper', ob_get_clean(), $helper, $value, $this);
418
- }
419
-
420
- /**
421
- * Get pod or category dropdown values
422
- */
423
- function get_dropdown_values($params) {
424
- global $wpdb;
425
-
426
- $params = (object) $params;
427
-
428
- $params->orderby = empty($params->pick_orderby) ? '`name` ASC' : $params->pick_orderby;
429
-
430
- // WP taxonomy dropdown
431
- if ('wp_taxonomy' == $params->table) {
432
- $where = (false !== $params->unique_vals) ? "WHERE `t`.term_id NOT IN ({$params->unique_vals})" : '';
433
- if (!empty($params->pick_filter)) {
434
- $where .= (empty($where) ? ' WHERE ' : ' AND ') . $params->pick_filter;
435
- }
436
-
437
- $sql = "SELECT `t`.term_id AS id, `t`.`name` FROM `{$wpdb->term_taxonomy}` AS `tx` INNER JOIN `{$wpdb->terms}` AS `t` ON `t`.`term_id` = `tx`.`term_id` {$where} ORDER BY {$params->orderby}";
438
- }
439
- // WP page or post dropdown
440
- elseif ('wp_page' == $params->table || 'wp_post' == $params->table) {
441
- $post_type = substr($params->table, 3);
442
- $where = (false !== $params->unique_vals) ? "AND `id` NOT IN ({$params->unique_vals})" : '';
443
- if (!empty($params->pick_filter)) {
444
- $where .= " AND {$params->pick_filter}";
445
- }
446
-
447
- $sql = "SELECT `t`.ID AS id, `t`.post_title AS `name` FROM `{$wpdb->posts}` AS `t` WHERE `t`.`post_type` = '{$post_type}' {$where} ORDER BY {$params->orderby}";
448
- }
449
- // WP user dropdown
450
- elseif ('wp_user' == $params->table) {
451
- $where = (false !== $params->unique_vals) ? "WHERE `id` NOT IN ({$params->unique_vals})" : '';
452
- if (!empty($params->pick_filter)) {
453
- $where .= (empty($where) ? ' WHERE ' : ' AND ') . $params->pick_filter;
454
- }
455
-
456
- $sql = "SELECT `t`.`ID` AS `id`, `t`.`display_name` AS `name` FROM `{$wpdb->users}` AS `t` {$where} ORDER BY {$params->orderby}";
457
- }
458
- // Pod table dropdown
459
- else {
460
- $where = (false !== $params->unique_vals) ? "WHERE id NOT IN ({$params->unique_vals})" : '';
461
- if (!empty($params->pick_filter)) {
462
- $where .= (empty($where) ? ' WHERE ' : ' AND ') . $params->pick_filter;
463
- }
464
-
465
- $sql = "SELECT * FROM `@wp_pod_tbl_{$params->table}` AS `t` {$where} ORDER BY {$params->orderby}";
466
- }
467
-
468
- //override with custom dropdown values
469
- $sql = apply_filters('pods_get_dropdown_values', $sql, $params, $this);
470
-
471
- $val = array();
472
- $result = pod_query($sql);
473
- while ($row = pods_mysql_fetch_assoc($result)) {
474
- $row['active'] = false;
475
- if (!empty($params->tbl_row_ids)) {
476
- $row['active'] = in_array($row['id'], $params->tbl_row_ids);
477
- }
478
- elseif (isset($_GET[$params->field_name])) {
479
- if ('int' == $this->search_mode && $row['id'] == (int) $_GET[$params->field_name])
480
- $row['active'] = true;
481
- elseif ('text' == $this->search_mode && $row['name'] == $_GET[$params->field_name])
482
- $row['active'] = true;
483
- }
484
- $val[] = $row;
485
- }
486
- return $val;
487
- }
488
-
489
- /**
490
- * Setup fields for rabit hole
491
- */
492
- function feed_rabit ($fields) {
493
- $feed = array();
494
- foreach ($fields as $field => $data) {
495
- if (!is_array($data))
496
- $field = $data;
497
- if (isset($_GET[$field]))
498
- $feed['traverse_' . $field] = array($field);
499
- }
500
- return $feed;
501
- }
502
-
503
- /**
504
- * Recursively join tables based on fields
505
- */
506
- function recurse_rabit_hole ($pod, $fields, $joined = 't', $depth = 0) {
507
- global $wpdb;
508
-
509
- if (!isset($this->rabit_hole[$pod]))
510
- $this->rabit_hole[$pod] = array();
511
- $api = new PodAPI($pod);
512
- $pod_id = (int) $api->dt;
513
- foreach ($api->fields as $field) {
514
- if (!in_array($field['coltype'], array('pick', 'file')) && !isset($this->rabit_hole[$pod][$field['name']]))
515
- continue;
516
- $the_pod = null;
517
- $table = $field['pickval'];
518
- $on = 'id';
519
- $name = 'name';
520
- $recurse = true;
521
- if ('file' == $field['coltype'] || 'wp_page' == $table || 'wp_post' == $table) {
522
- $table = $wpdb->posts;
523
- $on = 'ID';
524
- $name = 'post_title';
525
- $recurse = false;
526
- }
527
- elseif ('wp_taxonomy' == $table) {
528
- $table = $wpdb->terms;
529
- $on = 'term_id';
530
- $recurse = false;
531
- }
532
- elseif ('wp_user' == $table) {
533
- $table = $wpdb->users;
534
- $on = 'ID';
535
- $name = 'display_name';
536
- $recurse = false;
537
- }
538
- elseif (!empty($table)) {
539
- $the_pod = $table;
540
- $table = '@wp_pod_tbl_' . $table;
541
- }
542
- $rabit_hole = array_merge($field,
543
- array('table' => $table,
544
- 'pod' => $the_pod,
545
- 'on' => $on,
546
- 'name' => $name,
547
- 'recurse' => $recurse));
548
- if (isset($this->rabit_hole[$pod][$field['name']]))
549
- $rabit_hole = array_merge($rabit_hole, (array) $this->rabit_hole[$pod][$field['name']]);
550
- $this->rabit_hole[$pod][$field['name']] = apply_filters('pods_rabit_hole', $rabit_hole, $pod, $fields, $joined, $depth);
551
- }
552
- unset($api);
553
-
554
- $joins = array();
555
- if (!isset($fields[$depth]) || empty($fields[$depth]))
556
- return $joins;
557
- $field = $fields[$depth];
558
- if (!isset($this->rabit_hole[$pod][$field]))
559
- return $joins;
560
- $this->rabit_hole[$pod][$field] = array_merge(array('table' => null,
561
- 'pod' => null,
562
- 'on' => 'id',
563
- 'name' => 'name',
564
- 'recurse' => false,
565
- 'id' => 0,
566
- 'coltype' => null),
567
- $this->rabit_hole[$pod][$field]);
568
- $this->rabit_hole[$pod][$field]['id'] = (int) $this->rabit_hole[$pod][$field]['id'];
569
- $field_joined = $field;
570
- if (0 < $depth && 't' != $joined)
571
- $field_joined = $joined . '_' . $field;
572
- if (false !== $this->search) {
573
- if (0 < strlen(pods_var($field_joined, 'get'))) {
574
- $val = absint(pods_var($field_joined, 'get'));
575
- $on = $this->rabit_hole[$pod][$field]['on'];
576
- $search = "`{$field_joined}`.`{$on}` = {$val}";
577
- if ('text' == $this->search_mode) {
578
- $val = pods_var($field_joined, 'get');
579
- $on = $this->rabit_hole[$pod][$field]['name'];
580
- $search = "`{$field_joined}`.`{$on}` = '{$val}'";
581
- }
582
- elseif ('text_like' == $this->search_mode) {
583
- $val = pods_sanitize(like_escape($_GET[$field_joined]));
584
- $on = $this->rabit_hole[$pod][$field]['name'];
585
- $search = "`{$field_joined}`.`{$on}` LIKE '%{$val}%'";
586
- }
587
- $this->search_where .= " AND {$search} ";
588
- }
589
- }
590
- $p_alias = 'p';
591
- $p_join = '';
592
- if (0 < $depth && 't' != $joined) {
593
- $p_alias = 'p_' . $joined;
594
- $p_join = "
595
- LEFT JOIN `@wp_pod` AS `{$p_alias}` ON `{$p_alias}`.`datatype` = {$pod_id} AND `{$p_alias}`.`tbl_row_id` = `{$joined}`.`id`";
596
- }
597
- $rel_alias = 'rel_' . $field_joined;
598
- $the_join = "{$p_join}
599
- LEFT JOIN `@wp_pod_rel` AS `{$rel_alias}` ON `{$rel_alias}`.`field_id` = {$this->rabit_hole[$pod][$field]['id']} AND `{$rel_alias}`.`pod_id` = `{$p_alias}`.id
600
- LEFT JOIN `{$this->rabit_hole[$pod][$field]['table']}` AS `{$field_joined}` ON `{$field_joined}`.`{$this->rabit_hole[$pod][$field]['on']}` = `{$rel_alias}`.`tbl_row_id`
601
- ";
602
- if (!in_array($this->rabit_hole[$pod][$field]['coltype'], array('pick', 'file'))) {
603
- $the_join = "
604
- LEFT JOIN `{$this->rabit_hole[$pod][$field]['table']}` AS `{$field_joined}` ON `{$field_joined}`.`{$this->rabit_hole[$pod][$field]['on']}` = CONVERT(`{$joined}`.`{$field_joined}`, SIGNED)
605
- ";
606
- }
607
- $joins[$pod . '_' . $depth . '_' . $this->rabit_hole[$pod][$field]['id']] = apply_filters('pods_rabit_hole_the_join', $the_join, $pod, $fields, $joined, $depth, $this);
608
- if (($depth + 1) < count($fields) && null !== $this->rabit_hole[$pod][$field]['pod'] && false !== $this->rabit_hole[$pod][$field]['recurse'])
609
- $joins = array_merge($joins, $this->recurse_rabit_hole($this->rabit_hole[$pod][$field]['pod'], $fields, $field_joined, ($depth + 1)));
610
- return $joins;
611
- }
612
-
613
- /**
614
- * Recursively join tables based on fields
615
- */
616
- function rabit_hole ($pod, $fields = null) {
617
- $joins = array();
618
- if (null === $fields) {
619
- $api = new PodAPI($pod);
620
- $fields = $this->feed_rabit($api->fields);
621
- }
622
- foreach ((array) $fields as $field_group) {
623
- if (is_array($field_group))
624
- $joins = array_merge($joins, $this->recurse_rabit_hole($pod, $field_group));
625
- else {
626
- $joins = array_merge($joins, $this->recurse_rabit_hole($pod, $fields));
627
- $joins = array_filter($joins);
628
- return $joins;
629
- }
630
- }
631
- $joins = array_filter($joins);
632
- return $joins;
633
- }
634
-
635
- /**
636
- * Return a single record
637
- */
638
- function getRecordById($id) {
639
- if (empty($this->datatype_id)) {
640
- echo "<e>Error: Pod name invalid</e>";
641
- return null;
642
- }
643
- global $wpdb;
644
- $datatype = $this->datatype;
645
- $datatype_id = $this->datatype_id;
646
- if ($this->is_val($datatype)) {
647
- $this->result = null;
648
- if (is_numeric($id)) {
649
- $id = (int) $id;
650
- $sql = "
651
- SELECT
652
- DISTINCT `t`.*, `p`.`id` AS `pod_id`, `p`.`created`, `p`.`modified`
653
- FROM
654
- `@wp_pod` AS `p`
655
- INNER JOIN
656
- `@wp_pod_tbl_{$datatype}` AS `t` ON `t`.`id` = `p`.`tbl_row_id`
657
- WHERE
658
- `p`.`datatype` = {$datatype_id}
659
- AND `t`.`id` = {$id}
660
- LIMIT 1
661
- ";
662
- $this->raw_sql = $sql;
663
- $this->sql = str_replace('@wp_', $wpdb->prefix, $sql);
664
- $this->result = pod_query($sql);
665
- $this->row_number = 0;
666
- $this->zebra = false;
667
- $this->total = $this->total_rows = 1;
668
- }
669
- else {
670
- // Get the slug column
671
- $fields_result = pod_query("SELECT name FROM @wp_pod_fields WHERE coltype = 'slug' AND datatype = $this->datatype_id LIMIT 1");
672
- if (0 < pods_mysql_num_rows($fields_result)) {
673
- $field_name = pods_mysql_result($fields_result, 0);
674
- $sql = "
675
- SELECT
676
- DISTINCT `t`.*, `p`.`id` AS `pod_id`, `p`.`created`, `p`.`modified`
677
- FROM
678
- `@wp_pod` AS `p`
679
- INNER JOIN
680
- `@wp_pod_tbl_{$datatype}` AS `t` ON `t`.`id` = `p`.`tbl_row_id`
681
- WHERE
682
- `p`.`datatype` = {$datatype_id}
683
- AND `t`.`{$field_name}` = '{$id}'
684
- LIMIT 1
685
- ";
686
- $this->raw_sql = $sql;
687
- $this->sql = str_replace('@wp_', $wpdb->prefix, $sql);
688
- $this->result = pod_query($sql);
689
- $this->row_number = 0;
690
- $this->zebra = false;
691
- $this->total = $this->total_rows = 1;
692
- }
693
- }
694
-
695
- if (0 < pods_mysql_num_rows($this->result)) {
696
- $this->data = pods_mysql_fetch_assoc($this->result);
697
- $this->data['type'] = $datatype;
698
- return $this->data;
699
- }
700
- $this->data = false;
701
- }
702
- else
703
- die('<e>Datatype not set');
704
- }
705
-
706
- /**
707
- * Search and filter records
708
- */
709
- function findRecords($orderby = '`t`.`id` DESC', $rows_per_page = 15, $where = null, $sql = null) {
710
- if (empty($this->datatype_id)) {
711
- echo "<e>Error: Pod name invalid</e>";
712
- return null;
713
- }
714
- global $wpdb;
715
- $join = $groupby = $having = '';
716
- $params = null;
717
- $select = '`t`.*, `p`.`id` AS `pod_id`, `p`.`created`, `p`.`modified`';
718
- $this->traverse = array();
719
-
720
- $defaults = array('select' => $select,
721
- 'join' => $join,
722
- 'where' => $where,
723
- 'groupby' => $groupby,
724
- 'having' => $having,
725
- 'orderby' => (is_array($orderby) ? '`t`.`id` DESC' : $orderby),
726
- 'limit' => $rows_per_page,
727
- 'offset' => null,
728
- 'search' => $this->search,
729
- 'search_var' => $this->search_var,
730
- 'search_mode' => $this->search_mode,
731
- 'traverse' => $this->traverse,
732
- 'page' => $this->page,
733
- 'page_var' => null,
734
- 'pagination' => $this->pagination,
735
- 'calc_found_rows' => $this->calc_found_rows,
736
- 'count_found_rows' => $this->count_found_rows,
737
- 'sql' => $sql);
738
- $defaults = (array) apply_filters('pods_findrecords_defaults', $defaults, $orderby, $this);
739
- $params = (object) $defaults;
740
- if (is_array($orderby) && !empty($orderby))
741
- $params = (object) array_merge($defaults, $orderby);
742
-
743
- if (0 < strlen($params->select))
744
- $select = $params->select;
745
- $join = $params->join;
746
- $this->search = (boolean) $params->search;
747
- $this->search_var = $params->search_var;
748
- $this->search_mode = (in_array($params->search_mode, array('int', 'text')) ? $params->search_mode : 'int');
749
- $this->traverse = (array) $params->traverse;
750
- $where = $params->where;
751
- $groupby = $params->groupby;
752
- $having = $params->having;
753
- $orderby = $params->orderby;
754
- $rows_per_page = (int) $params->limit;
755
- $this->page = (int) $params->page;
756
- if (null !== $params->page_var)
757
- $this->page_var = (int) $params->page_var;
758
- if ($this->page < 1 || null !== $params->page_var)
759
- $this->page = max(pods_var($this->page_var, 'get'), 1);
760
- $this->pagination = (bool) $params->pagination;
761
- $this->calc_found_rows = (boolean) $params->calc_found_rows;
762
- $this->count_found_rows = (boolean) $params->count_found_rows;
763
- $sql = $params->sql;
764
- if (true === $this->count_found_rows && empty($sql))
765
- $this->calc_found_rows = false;
766
- $page = (int) $this->page;
767
- if ($rows_per_page < 0 || false === $this->pagination)
768
- $page = $this->page = 1;
769
- $datatype = $this->datatype;
770
- $datatype_id = (int) $this->datatype_id;
771
- $this->rpp = (int) $rows_per_page;
772
- $this->offset = ($this->rpp * ($page - 1));
773
- if (null !== $params->offset)
774
- $this->offset += (int) $params->offset;
775
-
776
- $sql_builder = false;
777
- if (empty($sql)) {
778
- $sql_builder = true;
779
- $limit = $this->search_where = '';
780
-
781
- // ctype_digit expects a string, or it returns FALSE
782
- if (ctype_digit("$rows_per_page") && 0 <= $rows_per_page) {
783
- $limit = $this->offset . ',' . $rows_per_page;
784
- }
785
- elseif (false !== strpos($rows_per_page, ',')) {
786
- // Custom offset
787
- $limit = $rows_per_page;
788
- }
789
- $where = empty($where) ? '' : " AND ( $where )";
790
-
791
- if (false !== $this->search) {
792
- // Handle search
793
- if (0 < strlen(pods_var($this->search_var, 'get'))) {
794
- $val = pods_sanitize(like_escape($_GET[$this->search_var]));
795
- $this->search_where = " AND (`t`.`name` LIKE '%{$val}%') ";
796
- }
797
- }
798
-
799
- // Add "`t`." prefix to $orderby if needed
800
- if (!empty($orderby) && false === strpos($orderby, ',') && false === strpos($orderby, '(') && false === strpos($orderby, '.')) {
801
- if (false !== strpos($orderby, ' ASC'))
802
- $orderby = '`t`.`' . trim(str_replace(array('`', ' ASC'), '', $orderby)) . '` ASC';
803
- else
804
- $orderby = '`t`.`' . trim(str_replace(array('`', ' DESC'), '', $orderby)) . '` DESC';
805
- }
806
-
807
- $haystack = preg_replace('/\s/', ' ', "$select $where $groupby $having $orderby");
808
- $haystack = preg_replace('/\w\(/', ' ', $haystack);
809
- $haystack = str_replace(array('(', ')', ' '), ' ', $haystack);
810
-
811
- preg_match_all('/`?[\w]+`?(?:\\.`?[\w]+`?)+(?=[^"\']*(?:"[^"]*"[^"]*|\'[^\']*\'[^\']*)*$)/', $haystack, $found, PREG_PATTERN_ORDER);
812
-
813
- $found = (array) @current($found);
814
- $find = $replace = array();
815
- foreach ($found as $key => $value) {
816
- $value = str_replace('`', '', $value);
817
- $value = explode('.', $value);
818
- $dot = array_pop($value);
819
- if (in_array('/\b' . trim($found[$key], '`') . '\b(?=[^"\']*(?:"[^"]*"[^"]*|\'[^\']*\'[^\']*)*$)/', $find)) {
820
- unset($found[$key]);
821
- continue;
822
- }
823
- $find[$key] = '/\b' . trim($found[$key], '`') . '\b(?=[^"\']*(?:"[^"]*"[^"]*|\'[^\']*\'[^\']*)*$)/';
824
- $esc_start = $esc_end = '`';
825
- if (strlen(ltrim($found[$key], '`')) < strlen($found[$key]))
826
- $esc_start = '';
827
- if (strlen(rtrim($found[$key], '`')) < strlen($found[$key]))
828
- $esc_end = '';
829
- if ('*' != $dot)
830
- $dot = '`' . $dot . $esc_end;
831
- $replace[$key] = $esc_start . implode('_', $value) . '`.' . $dot;
832
- if (in_array($value[0], array('t', 'p'))) {
833
- unset($found[$key]);
834
- continue;
835
- }
836
- unset($found[$key]);
837
- if (!in_array($value, $found))
838
- $found[$key] = $value;
839
- }
840
-
841
- if (!empty($this->traverse)) {
842
- foreach ((array) $this->traverse as $key => $traverse) {
843
- $traverse = str_replace('`', '', $traverse);
844
- $already_found = false;
845
- foreach ($found as $traversal) {
846
- if (is_array($traversal))
847
- $traversal = implode('.', $traversal);
848
- if ($traversal == $traverse) {
849
- $already_found = true;
850
- break;
851
- }
852
- }
853
- if (!$already_found)
854
- $found['traverse_' . $key] = explode('.', $traverse);
855
- }
856
- }
857
-
858
- $joins = array();
859
- if (!empty($find)) {
860
- $select = preg_replace($find, $replace, $select);
861
- $where = preg_replace($find, $replace, $where);
862
- $groupby = preg_replace($find, $replace, $groupby);
863
- $having = preg_replace($find, $replace, $having);
864
- $orderby = preg_replace($find, $replace, $orderby);
865
-
866
- if (!empty($found))
867
- $joins = $this->rabit_hole($this->datatype, $found);
868
- elseif (false !== $this->search)
869
- $joins = $this->rabit_hole($this->datatype);
870
- }
871
-
872
- if (0 < strlen($join)) {
873
- $joins[] = "
874
- {$join}
875
- ";
876
- }
877
- $join = apply_filters('pods_findrecords_join', implode(' ', $joins), $params, $this);
878
-
879
- $groupby = trim($groupby);
880
- $orderby = trim($orderby);
881
- $limit = trim($limit);
882
-
883
- $calc_found_rows = '';
884
- if (false !== $this->calc_found_rows)
885
- $calc_found_rows = 'SQL_CALC_FOUND_ROWS';
886
- $sql = "
887
- SELECT
888
- {$calc_found_rows} DISTINCT {$select}
889
- FROM
890
- `@wp_pod` AS `p`
891
- INNER JOIN
892
- `@wp_pod_tbl_{$datatype}` AS `t` ON `t`.`id` = `p`.`tbl_row_id`
893
- {$join}
894
- WHERE
895
- `p`.`datatype` = {$datatype_id}";
896
- if (!empty($this->search_where)) {
897
- $sql .= "
898
- {$this->search_where}";
899
- }
900
- if (!empty($where)) {
901
- $sql .= "
902
- {$where}";
903
- }
904
- if (!empty($groupby)) {
905
- $sql .= "
906
- GROUP BY {$groupby}";
907
- }
908
- if (!empty($having)) {
909
- $sql .= "
910
- HAVING {$having}";
911
- }
912
- if (!empty($orderby)) {
913
- $sql .= "
914
- ORDER BY {$orderby}";
915
- }
916
- if (!empty($limit)) {
917
- $sql .= "
918
- LIMIT {$limit}";
919
- }
920
- }
921
- $this->raw_sql = $sql;
922
- $this->sql = str_replace('@wp_', $wpdb->prefix, $sql);
923
- $this->result = pod_query($sql);
924
- $this->row_number = -1;
925
- $this->zebra = false;
926
- $this->total = absint(@pods_mysql_num_rows($this->result));
927
- if (false !== $this->calc_found_rows) {
928
- $this->total_rows = pod_query("SELECT FOUND_ROWS()");
929
- $this->getTotalRows();
930
- }
931
- elseif (false !== $this->count_found_rows && false !== $sql_builder) {
932
- $sql = "
933
- SELECT
934
- COUNT(*) AS `found_rows`
935
- FROM
936
- `@wp_pod` AS `p`
937
- INNER JOIN
938
- `@wp_pod_tbl_{$datatype}` AS `t` ON `t`.`id` = `p`.`tbl_row_id`
939
- {$join}
940
- WHERE
941
- `p`.`datatype` = {$datatype_id}";
942
- if (!empty($this->search_where)) {
943
- $sql .= "
944
- {$this->search_where}";
945
- }
946
- if (!empty($where)) {
947
- $sql .= "
948
- {$where}";
949
- }
950
- if (!empty($groupby)) {
951
- $sql .= "
952
- GROUP BY {$groupby}";
953
- }
954
- if (!empty($having)) {
955
- $sql .= "
956
- HAVING {$having}";
957
- }
958
- $this->total_rows = pod_query($sql);
959
- $this->getTotalRows();
960
- }
961
- }
962
-
963
- /**
964
- * Fetch the total row count
965
- */
966
- function getTotalRows() {
967
- if (false === is_numeric($this->total_rows)) {
968
- if ($row = pods_mysql_fetch_array($this->total_rows))
969
- $this->total_rows = $row[0];
970
- else
971
- $this->total_rows = 0;
972
- }
973
- return (int) $this->total_rows;
974
- }
975
-
976
- /**
977
- * Fetch the current row number
978
- */
979
- function getRowNumber() {
980
- return (int) $this->row_number;
981
- }
982
-
983
- /**
984
- * Fetch the current row number
985
- */
986
- function getZebra() {
987
- return (boolean) $this->zebra;
988
- }
989
-
990
- /**
991
- * (Re)set the MySQL result pointer
992
- */
993
- function resetPointer($row_number = 0) {
994
- $row_number = absint($row_number);
995
- if (0 < pods_mysql_num_rows($this->result)) {
996
- $this->row_number = $row_number;
997
- $this->zebra = false;
998
- return pods_mysql_data_seek($this->result, $row_number);
999
- }
1000
- return false;
1001
- }
1002
-
1003
- /**
1004
- * Display HTML for all datatype fields
1005
- */
1006
- function showform($pod_id = null, $public_columns = null, $label = 'Save changes') {
1007
- if (empty($this->datatype_id)) {
1008
- echo "<e>Error: Pod name invalid</e>";
1009
- return null;
1010
- }
1011
- $pod_id = absint($pod_id);
1012
- $cache = PodCache::instance();
1013
-
1014
- $datatype = $this->datatype;
1015
- $datatype_id = (int) $this->datatype_id;
1016
- $this->data['pod_id'] = $pod_id = (int) $pod_id;
1017
-
1018
- $where = '';
1019
- if (!empty($public_columns)) {
1020
- foreach ($public_columns as $key => $val) {
1021
- if (is_array($public_columns[$key])) {
1022
- $where[] = $key;
1023
- $attributes[$key] = $val;
1024
- }
1025
- else {
1026
- $where[] = $val;
1027
- $attributes[$val] = array();
1028
- }
1029
- }
1030
- $where = "AND name IN ('" . implode("','", $where) . "')";
1031
- }
1032
-
1033
- $result = pod_query("SELECT * FROM @wp_pod_fields WHERE datatype = $datatype_id $where ORDER BY weight ASC");
1034
- $public_columns = array();
1035
- while ($row = pods_mysql_fetch_assoc($result)) {
1036
- $fields[$row['name']] = $row;
1037
- $public_columns[] = $row['name'];
1038
- }
1039
-
1040
- // Re-order the fields if a public form
1041
- if (!empty($attributes)) {
1042
- $tmp = $fields;
1043
- $fields = array();
1044
- foreach ($attributes as $key => $val) {
1045
- if (isset($tmp[$key]))
1046
- $fields[$key] = $tmp[$key];
1047
- }
1048
- unset($tmp);
1049
- }
1050
-
1051
- // Edit an existing item
1052
- if (!empty($pod_id)) {
1053
- $sql = "
1054
- SELECT
1055
- `t`.*
1056
- FROM
1057
- @wp_pod `p`
1058
- INNER JOIN
1059
- `@wp_pod_tbl_{$datatype}` AS `t` ON `t`.`id` = `p`.`tbl_row_id`
1060
- WHERE
1061
- `p`.`id` = {$pod_id}
1062
- LIMIT
1063
- 1
1064
- ";
1065
- $result = pod_query($sql);
1066
- if (0 < pods_mysql_num_rows($result)) {
1067
- $tbl_cols = pods_mysql_fetch_assoc($result);
1068
- }
1069
- }
1070
- $uri_hash = wp_hash($_SERVER['REQUEST_URI']);
1071
-
1072
- do_action('pods_showform_pre', $pod_id, $public_columns, $label, $this);
1073
-
1074
- foreach ($fields as $key => $field) {
1075
- // Replace field attributes with public form attributes
1076
- if (!empty($attributes) && is_array($attributes[$key])) {
1077
- $field = array_merge($field, $attributes[$key]);
1078
- }
1079
-
1080
- if (empty($field['label'])) {
1081
- $field['label'] = ucwords($key);
1082
- }
1083
-
1084
- if (1 == $field['required']) {
1085
- $field['label'] .= ' <span class="red">*</span>';
1086
- }
1087
-
1088
- if (!empty($field['pickval'])) {
1089
- $val = array();
1090
- $tbl_row_ids = array();
1091
- $table = $field['pickval'];
1092
-
1093
- $result = pod_query("SELECT `id` FROM `@wp_pod_fields` WHERE `datatype` = {$datatype_id} AND `name` = '$key' LIMIT 1");
1094
- $field_id = (int) pods_mysql_result($result, 0);
1095
-
1096
- $result = pod_query("SELECT `tbl_row_id` FROM `@wp_pod_rel` WHERE `field_id` = {$field_id} AND `pod_id` = {$pod_id}");
1097
- while ($row = pods_mysql_fetch_assoc($result)) {
1098
- $tbl_row_ids[] = (int) $row['tbl_row_id'];
1099
- }
1100
-
1101
- // Use default values for public forms
1102
- if (empty($tbl_row_ids) && !empty($field['default'])) {
1103
- $tbl_row_ids = $field['default'];
1104
- if (!is_array($field['default'])) {
1105
- $tbl_row_ids = explode(',', $tbl_row_ids);
1106
- foreach ($tbl_row_ids as $row_key => $row_val) {
1107
- $tbl_row_ids[$row_key] = (int) trim($row_val);
1108
- }
1109
- }
1110
- }
1111
-
1112
- // If the PICK column is unique, get values already chosen
1113
- $unique_vals = false;
1114
- if (1 == $field['unique']) {
1115
- $exclude = empty($pod_id) ? '' : "AND `pod_id` != {$pod_id}";
1116
- $result = pod_query("SELECT `tbl_row_id` FROM `@wp_pod_rel` WHERE `field_id` = {$field_id} {$exclude}");
1117
- if (0 < pods_mysql_num_rows($result)) {
1118
- $unique_vals = array();
1119
- while ($row = pods_mysql_fetch_assoc($result)) {
1120
- $unique_vals[] = (int) $row['tbl_row_id'];
1121
- }
1122
- $unique_vals = implode(',', $unique_vals);
1123
- }
1124
- }
1125
-
1126
- $params = array(
1127
- 'table' => $table,
1128
- 'field_name' => null,
1129
- 'tbl_row_ids' => $tbl_row_ids,
1130
- 'unique_vals' => $unique_vals,
1131
- 'pick_filter' => $field['pick_filter'],
1132
- 'pick_orderby' => $field['pick_orderby']
1133
- );
1134
- $this->data[$key] = $this->get_dropdown_values($params);
1135
- }
1136
- else {
1137
- // Set a default value if no value is entered
1138
- if (!isset($this->data[$key]) && !empty($field['default'])) {
1139
- $this->data[$key] = $field['default'];
1140
- }
1141
- else {
1142
- $this->data[$key] = isset($tbl_cols[$key]) && $this->is_val($tbl_cols[$key]) ? $tbl_cols[$key] : null;
1143
- }
1144
- }
1145
- $this->build_field_html($field);
1146
- }
1147
- $uri_hash = wp_hash($_SERVER['REQUEST_URI']);
1148
-
1149
- $save_button_atts = array(
1150
- 'type' => 'button',
1151
- 'class' => 'button btn_save',
1152
- 'value' => $label,
1153
- 'onclick' => "saveForm($cache->form_count)"
1154
- );
1155
- $save_button_atts = apply_filters('pods_showform_save_button_atts', $save_button_atts, $this);
1156
- $atts = '';
1157
- foreach ($save_button_atts as $att => $value) {
1158
- $atts .= $att.'="'.$value.'" ';
1159
- }
1160
- $save_button = '<input '.$atts.'/>';
1161
- ?>
1162
- <div>
1163
- <input type="hidden" class="form num pod_id" value="<?php echo $pod_id; ?>" />
1164
- <input type="hidden" class="form num tbl_row_id" value="<?php echo (!empty($tbl_cols) ? $tbl_cols['id'] : 0); ?>" />
1165
- <input type="hidden" class="form txt datatype" value="<?php echo $datatype; ?>" />
1166
- <input type="hidden" class="form txt form_count" value="<?php echo $cache->form_count; ?>" />
1167
- <input type="hidden" class="form txt token" value="<?php echo pods_generate_key($datatype, $uri_hash, $public_columns, $cache->form_count); ?>" />
1168
- <input type="hidden" class="form txt uri_hash" value="<?php echo $uri_hash; ?>" />
1169
- <?php echo apply_filters('pods_showform_save_button', $save_button, $save_button_atts, $this); ?>
1170
- </div>
1171
- <?php
1172
- do_action('pods_showform_post', $pod_id, $public_columns, $label, $this);
1173
- }
1174
-
1175
- /**
1176
- * Does the field have a value? (incl. 0)
1177
- */
1178
- function is_val($val) {
1179
- return (null != $val && false !== $val) ? true : false;
1180
- }
1181
-
1182
- /**
1183
- * Display the pagination controls
1184
- */
1185
- function getPagination($label = 'Go to page:') {
1186
- if ($this->rpp < $this->getTotalRows() && 0 < $this->rpp && false !== $this->pagination) {
1187
- include PODS_DIR . '/ui/pagination.php';
1188
- }
1189
- }
1190
-
1191
- /**
1192
- * Display the list filters
1193
- */
1194
- function getFilters($filters = null, $label = 'Filter', $action = '') {
1195
- include PODS_DIR . '/ui/list_filters.php';
1196
- }
1197
-
1198
- /**
1199
- * Build public input form
1200
- */
1201
- function publicForm($public_columns = null, $label = 'Save changes', $thankyou_url = null) {
1202
- include PODS_DIR . '/ui/input_form.php';
1203
- }
1204
-
1205
- /**
1206
- * Build HTML for a single field
1207
- */
1208
- function build_field_html($field) {
1209
- include PODS_DIR . '/ui/input_fields.php';
1210
- }
1211
-
1212
- /**
1213
- * Display the page template
1214
- */
1215
- function showTemplate($template, $code = null) {
1216
- ob_start();
1217
-
1218
- //pre-template hooks
1219
- do_action('pods_pre_showtemplate', $template, $code, $this);
1220
- do_action("pods_pre_showtemplate_$template", $template, $code, $this);
1221
-
1222
- if (!empty($code))
1223
- $function_or_file = false;
1224
- else {
1225
- $function_or_file = $template;
1226
- $check_function = false;
1227
- $check_file = null;
1228
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_TEMPLATE_FILES') || !PODS_TEMPLATE_FILES))
1229
- $check_file = false;
1230
- if (false !== $check_function && false !== $check_file)
1231
- $function_or_file = pods_function_or_file($function_or_file, $check_function, 'template', $check_file);
1232
- else
1233
- $function_or_file = false;
1234
-
1235
- if (!$function_or_file) {
1236
- $api = new PodAPI();
1237
- $params = array('name' => $template);
1238
- if (!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE)
1239
- $params = pods_sanitize($params);
1240
- $code = $api->load_template($params);
1241
- if (false !== $code && 0 < strlen(trim($code['code'])))
1242
- $code = $code['code'];
1243
- else
1244
- $code = false;
1245
- }
1246
- }
1247
-
1248
- if (empty($code) && false !== $function_or_file && isset($function_or_file['file'])) {
1249
- // Only detail templates need $this->id
1250
- if (empty($this->id)) {
1251
- while ($this->fetchRecord()) {
1252
- locate_template($function_or_file['file'], true, true);
1253
- }
1254
- }
1255
- else
1256
- locate_template($function_or_file['file'], true, true);
1257
- }
1258
- elseif (!empty($code)) {
1259
- // Only detail templates need $this->id
1260
- if (empty($this->id)) {
1261
- while ($this->fetchRecord()) {
1262
- echo $this->parse_template_string($code);
1263
- }
1264
- }
1265
- else
1266
- echo $this->parse_template_string($code);
1267
- }
1268
-
1269
- //post-template hooks
1270
- do_action('pods_post_showtemplate', $template, $code, $this);
1271
- do_action("pods_post_showtemplate_$template", $template, $code, $this);
1272
-
1273
- return apply_filters('pods_showtemplate', ob_get_clean(), $template, $code, $this);
1274
- }
1275
-
1276
- /**
1277
- * Parse a template string
1278
- *
1279
- * @param string $in The template string to parse
1280
- * @since 1.8.5
1281
- */
1282
- function parse_template_string($in) {
1283
- ob_start();
1284
- if (!defined('PODS_DISABLE_EVAL') || !PODS_DISABLE_EVAL)
1285
- eval("?>$in");
1286
- else
1287
- echo $in;
1288
- $out = ob_get_clean();
1289
- $out = preg_replace_callback("/({@(.*?)})/m", array($this, "parse_magic_tags"), $out);
1290
- return apply_filters('pods_parse_template_string', $out, $in, $this);
1291
- }
1292
-
1293
- /**
1294
- * Replace magic tags with their values
1295
- */
1296
- function parse_magic_tags($in) {
1297
- $name = $in[2];
1298
- $before = $after = $helper = '';
1299
- if (false !== strpos($name, ',')) {
1300
- @list($name, $helper, $before, $after) = explode(',', $name);
1301
- $name = trim($name);
1302
- $helper = trim($helper);
1303
- $before = trim($before);
1304
- $after = trim($after);
1305
- }
1306
-
1307
- if ('type' == $name)
1308
- $value = $this->datatype;
1309
- elseif ('detail_url' == $name)
1310
- $value = get_bloginfo('url') . '/' . $this->parse_template_string($this->detail_page);
1311
- else
1312
- $value = $this->get_field($name);
1313
-
1314
- // Use helper if necessary
1315
- if (!empty($helper))
1316
- $value = $this->pod_helper($helper, $value, $name);
1317
-
1318
- // Clean out PHP in case it exists
1319
- $value = str_replace(array('<' . '?php', '<' . '?', '?' .'>'), array('&lt;?php', '&lt;?', '?&gt;'), $value);
1320
-
1321
- $value = apply_filters('pods_parse_magic_tags', $value, $name, $helper, $before, $after);
1322
- if (null != $value && false !== $value)
1323
- return $before . $value . $after;
1324
- }
1325
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/PodAPI.php DELETED
@@ -1,2255 +0,0 @@
1
- <?php
2
- class PodAPI
3
- {
4
- var $snap = false;
5
- var $dt;
6
- var $dtname;
7
- var $format;
8
- var $fields;
9
- var $use_pod_id = false; // set to true for save_pod_item to operate off of pod_id (for backwards compatibility with functions using pod_ids)
10
-
11
- /**
12
- * Store and retrieve data programatically
13
- *
14
- * @param string $dtname (optional) The pod name
15
- * @param string $format (optional) Format for import/export, "php" or "csv"
16
- * @since 1.7.1
17
- */
18
- function __construct($dtname = null, $format = 'php') {
19
- $this->dtname = pods_sanitize(trim($dtname));
20
- $this->format = pods_sanitize(trim($format));
21
-
22
- if (!empty($this->dtname)) {
23
- $pod = $this->load_pod(array('name' => $this->dtname));
24
- if (is_array($pod)) {
25
- $this->dt = $pod['id'];
26
- $this->fields = $pod['fields'];
27
- }
28
- }
29
- }
30
-
31
- /**
32
- * Throw an error or die (cake or death?)
33
- *
34
- * @param string $error Error message
35
- * @since 1.9.0
36
- */
37
- function oh_snap($error) {
38
- if (false!==$this->snap) {
39
- throw new Exception($error);
40
- return false;
41
- }
42
- die($error);
43
- }
44
-
45
- /**
46
- * Add or edit a content type
47
- *
48
- * $params['id'] int The datatype ID
49
- * $params['name'] string The datatype name
50
- * $params['label'] string The datatype label
51
- * $params['is_toplevel'] bool Display the pod as a top-level admin menu
52
- * $params['detail_page'] string The URI for single pod items
53
- * $params['pre_save_helpers'] string Comma-separated list of helper names
54
- * $params['pre_drop_helpers'] string Comma-separated list of helper names
55
- * $params['post_save_helpers'] string Comma-separated list of helper names
56
- * $params['post_drop_helpers'] string Comma-separated list of helper names
57
- * $params['order'] string Comma-separated list of field IDs
58
- *
59
- * @param array $params An associative array of parameters
60
- * @since 1.7.9
61
- */
62
- function save_pod($params) {
63
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
64
- $params = pods_sanitize($params);
65
- $params = (object) str_replace('@wp_', '{prefix}', $params);
66
-
67
- // Set defaults
68
- $params = (object) array_merge(array('id' => '',
69
- 'name' => '',
70
- 'label' => '',
71
- 'is_toplevel' => 0,
72
- 'detail_page' => '',
73
- 'pre_save_helpers' => '',
74
- 'pre_drop_helpers' => '',
75
- 'post_save_helpers' => '',
76
- 'post_drop_helpers' => '',
77
- 'order' => 0),
78
- (array) $params);
79
- if (isset($params->action))
80
- unset($params->action);
81
- if (isset($params->_wpnonce))
82
- unset($params->_wpnonce);
83
-
84
- // Add new pod
85
- if (empty($params->id)) {
86
- $params->name = pods_clean_name($params->name);
87
- if (empty($params->name)) {
88
- return $this->oh_snap('<e>Enter a pod name');
89
- }
90
- $sql = "SELECT id FROM @wp_pod_types WHERE name = '{$params->name}' LIMIT 1";
91
- pod_query($sql, 'Duplicate pod name', 'Pod name already exists');
92
-
93
- $set = array();
94
- $columns = array();
95
- foreach ($params as $column => $value) {
96
- if (in_array($column, array('id', 'order', 'return_pod')))
97
- continue;
98
- $columns[] = "`{$column}`";
99
- $set[] = "'{$value}'";
100
- }
101
- $columns = implode(', ', $columns);
102
- $set = implode(', ', $set);
103
- $pod_id = pod_query("INSERT INTO @wp_pod_types ({$columns}) VALUES ({$set})", 'Cannot add new pod');
104
- pod_query("CREATE TABLE `@wp_pod_tbl_{$params->name}` (id int unsigned auto_increment primary key, name varchar(128), slug varchar(128)) DEFAULT CHARSET utf8", 'Cannot add pod database table');
105
- pod_query("INSERT INTO @wp_pod_fields (datatype, name, label, comment, coltype, required, weight) VALUES ({$pod_id}, 'name', 'Name', '', 'txt', 1, 0),({$pod_id}, 'slug', 'Permalink', 'Leave blank to auto-generate', 'slug', 0, 1)");
106
- if (!isset($params->return_pod) || false === $params->return_pod)
107
- return $pod_id;
108
- }
109
- // Edit existing pod
110
- else {
111
- $pod_id = $params->id;
112
- $set = array();
113
- foreach ($params as $column => $value) {
114
- if (in_array($column, array('id', 'name', 'order', 'return_pod')))
115
- continue;
116
- $set[] = "`{$column}` = '{$value}'";
117
- }
118
- if (!empty($set)) {
119
- $set = implode(', ', $set);
120
- $sql = "
121
- UPDATE
122
- `@wp_pod_types`
123
- SET
124
- {$set}
125
- WHERE
126
- `id` = {$pod_id}
127
- LIMIT
128
- 1
129
- ";
130
- pod_query($sql, 'Cannot change Pod settings');
131
- }
132
-
133
- $weight = 0;
134
- $order = (false !== strpos($params->order, ',')) ? explode(',', $params->order) : array($params->order);
135
- foreach ($order as $field_id) {
136
- pod_query("UPDATE `@wp_pod_fields` SET `weight` = '{$weight}' WHERE `id` = '{$field_id}' LIMIT 1", 'Cannot change column order');
137
- $weight++;
138
- }
139
- if (!isset($params->return_pod) || false === $params->return_pod)
140
- return $pod_id;
141
- }
142
- return $this->load_pod(array('id' => $pod_id));
143
- }
144
-
145
- /**
146
- * Add or edit a column within a content type
147
- *
148
- * $params['id'] int The field ID
149
- * $params['name'] string The field name
150
- * $params['datatype'] int The datatype ID
151
- * $params['dtname'] string The datatype name
152
- * $params['coltype'] string The column type ("txt", "desc", "pick", etc)
153
- * $params['sister_field_id'] int (optional) The related field ID
154
- * $params['pickval'] string The related PICK pod name
155
- * $params['label'] string The field label
156
- * $params['comment'] string The field comment
157
- * $params['display_helper'] string (optional) The display helper name
158
- * $params['input_helper'] string (optional) The input helper name
159
- * $params['pick_filter'] string (optional) WHERE clause for PICK fields
160
- * $params['pick_orderby'] string (optional) ORDER BY clause for PICK fields
161
- * $params['required'] bool Is the field required?
162
- * $params['unique'] bool Is the field unique?
163
- * $params['multiple'] bool Is the PICK dropdown a multi-select?
164
- *
165
- * @param array $params An associative array of parameters
166
- * @since 1.7.9
167
- */
168
- function save_column($params) {
169
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
170
- $params = pods_sanitize($params);
171
- $params = (object) str_replace('@wp_', '{prefix}', $params);
172
-
173
- // Set defaults
174
- $params = (object) array_merge(array('id' => '',
175
- 'name' => '',
176
- 'datatype' => '',
177
- 'dtname' => '',
178
- 'coltype' => 'txt',
179
- 'sister_field_id' => 0,
180
- 'pickval' => '',
181
- 'label' => '',
182
- 'comment' => '',
183
- 'display_helper' => '',
184
- 'input_helper' => '',
185
- 'pick_filter' => '',
186
- 'pick_orderby' => '',
187
- 'required' => 0,
188
- 'unique' => 0,
189
- 'multiple' => 0),
190
- (array) $params);
191
-
192
- // Force Types
193
- $params->id = absint($params->id);
194
- $params->sister_field_id = absint($params->sister_field_id);
195
- $params->required = absint($params->required);
196
- $params->unique = absint($params->unique);
197
- $params->multiple = absint($params->multiple);
198
-
199
- $dbtypes = array(
200
- 'bool' => 'bool default 0',
201
- 'date' => 'datetime',
202
- 'num' => 'decimal(12,2)',
203
- 'txt' => 'varchar(128)',
204
- 'slug' => 'varchar(128)',
205
- 'code' => 'longtext',
206
- 'desc' => 'longtext'
207
- );
208
- $dbtypes = apply_filters('pods_column_dbtypes', $dbtypes);
209
-
210
- // Add new column
211
- if (empty($params->id)) {
212
- $params->name = pods_clean_name($params->name);
213
- if (empty($params->name)) {
214
- return $this->oh_snap('<e>Enter a column name');
215
- }
216
- elseif (in_array($params->name, array('id', 'name', 'type', 'created', 'modified', 'p', 't'))) {
217
- return $this->oh_snap("<e>$params->name is a reserved name");
218
- }
219
- $sql = "SELECT id FROM @wp_pod_fields WHERE datatype = $params->datatype AND name = '$params->name' LIMIT 1";
220
- pod_query($sql, 'Cannot get fields', 'Column by this name already exists');
221
-
222
- if ('slug' == $params->coltype) {
223
- $sql = "SELECT id FROM @wp_pod_fields WHERE datatype = $params->datatype AND coltype = 'slug' LIMIT 1";
224
- pod_query($sql, 'Too many permalinks', 'This pod already has a permalink column');
225
- }
226
-
227
- // Sink the new column to the bottom of the list
228
- $weight = 0;
229
- $result = pod_query("SELECT weight FROM @wp_pod_fields WHERE datatype = $params->datatype ORDER BY weight DESC LIMIT 1");
230
- if (0 < pods_mysql_num_rows($result)) {
231
- $row = pods_mysql_fetch_assoc($result);
232
- $weight = (int) $row['weight'] + 1;
233
- }
234
-
235
- if ('pick' != $params->coltype) {
236
- $params->pickval = '';
237
- $params->pick_filter = '';
238
- $params->pick_orderby = '';
239
- $params->sister_field_id = 0;
240
- $params->multiple = 0;
241
- }
242
-
243
- $field_id = pod_query("INSERT INTO @wp_pod_fields (datatype, name, label, comment, display_helper, input_helper, coltype, pickval, pick_filter, pick_orderby, sister_field_id, required, `unique`, `multiple`, weight) VALUES ('$params->datatype', '$params->name', '$params->label', '$params->comment', '$params->display_helper', '$params->input_helper', '$params->coltype', '$params->pickval', '$params->pick_filter', '$params->pick_orderby', '$params->sister_field_id', '$params->required', '$params->unique', '$params->multiple', '$weight')", 'Cannot add new field');
244
-
245
- if ('pick' != $params->coltype && 'file' != $params->coltype) {
246
- $dbtype = $dbtypes[$params->coltype];
247
- pod_query("ALTER TABLE `@wp_pod_tbl_$params->dtname` ADD COLUMN `$params->name` $dbtype", 'Cannot create new column');
248
- }
249
- else {
250
- pod_query("UPDATE @wp_pod_fields SET sister_field_id = '{$field_id}' WHERE id = '{$params->sister_field_id}' LIMIT 1", 'Cannot update sister field');
251
- }
252
- }
253
- // Edit existing column
254
- else {
255
- if ('id' == $params->name) {
256
- return $this->oh_snap("<e>$params->name is not editable.");
257
- }
258
-
259
- $sql = "SELECT id FROM @wp_pod_fields WHERE datatype = $params->datatype AND id != $params->id AND name = '$params->name' LIMIT 1";
260
- pod_query($sql, 'Column already exists', "$params->name already exists.");
261
-
262
- $sql = "SELECT name, coltype FROM @wp_pod_fields WHERE id = $params->id LIMIT 1";
263
- $result = pod_query($sql);
264
-
265
- if (0 < pods_mysql_num_rows($result)) {
266
- $row = pods_mysql_fetch_assoc($result);
267
- $old_coltype = $row['coltype'];
268
- $old_name = $row['name'];
269
-
270
- $dbtype = $dbtypes[$params->coltype];
271
- $pickval = ('pick' != $params->coltype || empty($params->pickval)) ? '' : "$params->pickval";
272
-
273
- if ($params->coltype != $old_coltype) {
274
- if ('pick' == $params->coltype || 'file' == $params->coltype) {
275
- if ('pick' != $old_coltype && 'file' != $old_coltype) {
276
- pod_query("ALTER TABLE `@wp_pod_tbl_$params->dtname` DROP COLUMN `$old_name`");
277
- }
278
- }
279
- elseif ('pick' == $old_coltype || 'file' == $old_coltype) {
280
- pod_query("ALTER TABLE `@wp_pod_tbl_$params->dtname` ADD COLUMN `$params->name` $dbtype", 'Cannot create column');
281
- pod_query("UPDATE @wp_pod_fields SET sister_field_id = NULL WHERE sister_field_id = $params->id");
282
- pod_query("DELETE FROM @wp_pod_rel WHERE field_id = $params->id");
283
- }
284
- else {
285
- pod_query("ALTER TABLE `@wp_pod_tbl_$params->dtname` CHANGE `$old_name` `$params->name` $dbtype");
286
- }
287
- }
288
- elseif ($params->name != $old_name && 'pick' != $params->coltype && 'file' != $params->coltype) {
289
- pod_query("ALTER TABLE `@wp_pod_tbl_$params->dtname` CHANGE `$old_name` `$params->name` $dbtype");
290
- }
291
-
292
- if ('pick' != $params->coltype) {
293
- $params->pickval = '';
294
- $params->pick_filter = '';
295
- $params->pick_orderby = '';
296
- $params->sister_field_id = 0;
297
- $params->multiple = 0;
298
- }
299
-
300
- $sql = "
301
- UPDATE
302
- @wp_pod_fields
303
- SET
304
- name = '$params->name',
305
- label = '$params->label',
306
- comment = '$params->comment',
307
- coltype = '$params->coltype',
308
- pickval = '$params->pickval',
309
- display_helper = '$params->display_helper',
310
- input_helper = '$params->input_helper',
311
- pick_filter = '$params->pick_filter',
312
- pick_orderby = '$params->pick_orderby',
313
- sister_field_id = '$params->sister_field_id',
314
- required = '$params->required',
315
- `unique` = '$params->unique',
316
- `multiple` = '$params->multiple'
317
- WHERE
318
- id = $params->id
319
- LIMIT
320
- 1
321
- ";
322
- pod_query($sql, 'Cannot edit column');
323
- }
324
- }
325
- }
326
-
327
- /**
328
- * Add or edit a Pod Template
329
- *
330
- * $params['id'] int The template ID
331
- * $params['name'] string The template name
332
- * $params['code'] string The template code
333
- *
334
- * @param array $params An associative array of parameters
335
- * @since 1.7.9
336
- */
337
- function save_template($params) {
338
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
339
- $params = pods_sanitize($params);
340
- $params = (object) str_replace('@wp_', '{prefix}', $params);
341
-
342
- // Set defaults
343
- $params = (object) array_merge(array('id' => '',
344
- 'name' => '',
345
- 'code' => ''),
346
- (array) $params);
347
-
348
- // Force Types
349
- $params->id = absint($params->id);
350
-
351
- // Add new template
352
- if (empty($params->id)) {
353
- if (empty($params->name)) {
354
- return $this->oh_snap('<e>Enter a template name');
355
- }
356
-
357
- $sql = "SELECT id FROM @wp_pod_templates WHERE name = '$params->name' LIMIT 1";
358
- pod_query($sql, 'Cannot get Templates', 'Template by this name already exists');
359
- $template_id = pod_query("INSERT INTO @wp_pod_templates (name, code) VALUES ('$params->name', '$params->code')", 'Cannot add new template');
360
-
361
- return $template_id; // return
362
- }
363
- // Edit existing template
364
- else {
365
- $maybename = '';
366
- if (!empty($params->name))
367
- $maybename = "name = '$params->name',";
368
- pod_query("UPDATE @wp_pod_templates SET $maybename code = '$params->code' WHERE id = $params->id LIMIT 1");
369
- }
370
- }
371
-
372
- /**
373
- * Add or edit a Pod Page
374
- *
375
- * $params['id'] int The page ID
376
- * $params['uri'] string The page URI
377
- * $params['title'] string The page title
378
- * $params['page_template'] string The page template
379
- * $params['phpcode'] string The page code
380
- * $params['precode'] string The page pre code
381
- *
382
- * @param array $params An associative array of parameters
383
- * @since 1.7.9
384
- */
385
- function save_page($params) {
386
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
387
- $params = pods_sanitize($params);
388
- $params = (object) str_replace('@wp_', '{prefix}', $params);
389
-
390
- // Set defaults
391
- $params = (object) array_merge(array('id' => '',
392
- 'uri' => '',
393
- 'page_title' => '',
394
- 'page_template' => '',
395
- 'phpcode' => '',
396
- 'precode' => ''),
397
- (array) $params);
398
-
399
- // Force Types
400
- $params->id = absint($params->id);
401
-
402
- // Add new page
403
- if (empty($params->id)) {
404
- if (empty($params->uri)) {
405
- return $this->oh_snap('<e>Enter a page URI');
406
- }
407
- // normalize URI (remove outside /
408
- $params->uri = trim($params->uri,'/');
409
- $sql = "SELECT id FROM @wp_pod_pages WHERE uri = '$params->uri' LIMIT 1";
410
- pod_query($sql, 'Cannot get Pod Pages', 'Page by this URI already exists');
411
- $page_id = pod_query("INSERT INTO @wp_pod_pages (uri, title, page_template, phpcode, precode) VALUES ('$params->uri', '$params->page_title', '$params->page_template', '$params->phpcode', '$params->precode')", 'Cannot add new page');
412
- return $page_id; // return
413
- }
414
- // Edit existing page
415
- else {
416
- $maybename = '';
417
- if (!empty($params->uri))
418
- $maybename = "uri = '$params->uri',";
419
- pod_query("UPDATE @wp_pod_pages SET $maybename title = '$params->page_title', page_template = '$params->page_template', phpcode = '$params->phpcode', precode = '$params->precode' WHERE id = $params->id LIMIT 1");
420
- }
421
- }
422
-
423
- /**
424
- * Add or edit a Pod Helper
425
- *
426
- * $params['id'] int The helper ID
427
- * $params['name'] string The helper name
428
- * $params['helper_type'] string The helper type ("pre_save", "display", etc)
429
- * $params['phpcode'] string The helper code
430
- *
431
- * @param array $params An associative array of parameters
432
- * @since 1.7.9
433
- */
434
- function save_helper($params) {
435
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
436
- $params = pods_sanitize($params);
437
- $params = (object) str_replace('@wp_', '{prefix}', $params);
438
-
439
- // Set defaults
440
- $params = (object) array_merge(array('id' => '',
441
- 'name' => '',
442
- //'helper_type' => 'display',
443
- 'phpcode' => ''),
444
- (array) $params);
445
-
446
- // Force Types
447
- $params->id = absint($params->id);
448
-
449
- // Add new helper
450
- if (empty($params->id)) {
451
- if (empty($params->name)) {
452
- return $this->oh_snap('<e>Enter a helper name');
453
- }
454
- if (!isset($params->helper_type) || empty($params->helper_type))
455
- $params->helper_type = 'display';
456
-
457
- $sql = "SELECT id FROM @wp_pod_helpers WHERE name = '$params->name' LIMIT 1";
458
- pod_query($sql, 'Cannot get helpers', 'helper by this name already exists');
459
- $helper_id = pod_query("INSERT INTO @wp_pod_helpers (name, helper_type, phpcode) VALUES ('$params->name', '$params->helper_type', '$params->phpcode')", 'Cannot add new helper');
460
- return $helper_id; // return
461
- }
462
- // Edit existing helper
463
- else {
464
- $maybename = '';
465
- if (isset($params->name) && !empty($params->name))
466
- $maybename = "name = '$params->name',";
467
- $maybetype = '';
468
- if (isset($params->helper_type) && !empty($params->helper_type))
469
- $maybetype = "helper_type = '$params->helper_type',";
470
- pod_query("UPDATE @wp_pod_helpers SET {$maybename} {$maybetype} phpcode = '$params->phpcode' WHERE id = $params->id LIMIT 1");
471
- }
472
- }
473
-
474
- /**
475
- * Save the entire role structure
476
- *
477
- * @param array $params An associative array of parameters
478
- * @since 1.7.9
479
- */
480
- function save_roles($params) {
481
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
482
- $params = pods_sanitize($params);
483
- $roles = array();
484
- foreach ($params as $key => $val) {
485
- if ('action' != $key) {
486
- $tmp = empty($val) ? array() : explode(',', $val);
487
- $roles[$key] = $tmp;
488
- }
489
- }
490
- delete_option('pods_roles');
491
- add_option('pods_roles', serialize($roles));
492
- }
493
-
494
- /**
495
- * Retrieve an associative array of table values
496
- *
497
- * $params['table'] string The table name (default: "types")
498
- * $params['columns'] string Comma-separated string of columns (default: "*")
499
- * $params['orderby'] string MySQL ORDER BY clause (default: "id ASC")
500
- * $params['where'] string MySQL WHERE clause (default: 1)
501
- * $params['array_key'] string The key column for the returned associative array (default: "id")
502
- *
503
- * @param array $params An associative array of parameters
504
- * @return array The table data array
505
- * @since 1.8.5
506
- */
507
- function get_table_data($params) {
508
- $params = is_array($params) ? $params : array();
509
- $defaults = array(
510
- 'table' => 'types',
511
- 'columns' => '*',
512
- 'orderby' => 'id ASC',
513
- 'where' => 1,
514
- 'array_key' => 'id'
515
- );
516
- $params = (object) array_merge($defaults, $params);
517
- $result = pod_query("SELECT $params->columns FROM @wp_pod_$params->table WHERE $params->where ORDER BY $params->orderby");
518
- if (0 < pods_mysql_num_rows($result)) {
519
- while ($row = pods_mysql_fetch_assoc($result)) {
520
- $data[$row[$params->array_key]] = $row;
521
- }
522
- return $data;
523
- }
524
- }
525
-
526
- /**
527
- * Add or edit a single pod item
528
- *
529
- * $params['datatype'] string The datatype name
530
- * $params['columns'] array (optional) Associative array of column names + values
531
- * $params['data'] array (optional) Associative array of a set of associative arrays of column names + values (for bulk operations)
532
- * $params['pod_id'] int The item's ID from the wp_pod table (or alternatively use the tbl_row_id parameter instead)
533
- * $params['tbl_row_id'] int The item's ID from the wp_pod_tbl_* table (or alternatively use the pod_id parameter instead)
534
- *
535
- * @param array $params An associative array of parameters
536
- * @return int The table row ID
537
- * @since 1.7.9
538
- */
539
- function save_pod_item($params) {
540
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
541
- $params = pods_sanitize($params);
542
- $params = (object) str_replace('@wp_', '{prefix}', $params);
543
-
544
- // Support for multiple save_pod_item operations at the same time
545
- if (isset($params->data) && !empty($params->data) && is_array($params->data)) {
546
- $ids = array();
547
- $new_params = $params;
548
- unset($new_params->data);
549
- foreach ($params->data as $columns){
550
- $new_params->columns = $columns;
551
- $ids[] = $this->save_pod_item($new_params);
552
- }
553
- return $ids;
554
- }
555
-
556
- // Support for bulk edit
557
- if (isset($params->tbl_row_id) && !empty($params->tbl_row_id) && is_array($params->tbl_row_id)) {
558
- $ids = array();
559
- $new_params = $params;
560
- foreach ($params->tbl_row_id as $tbl_row_id){
561
- $new_params->tbl_row_id = $tbl_row_id;
562
- $ids[] = $this->save_pod_item($new_params);
563
- }
564
- return $ids;
565
- }
566
-
567
- // Allow Helpers to bypass subsequent helpers in recursive save_pod_item calls
568
- $bypass_helpers = false;
569
- if (isset($params->bypass_helpers) && true === (boolean) $params->bypass_helpers) {
570
- $bypass_helpers = true;
571
- }
572
-
573
- // Get array of datatypes
574
- $datatypes = $this->get_table_data(array('array_key' => 'name', 'columns' => 'id, name'));
575
- $params->datatype_id = (int) $datatypes[$params->datatype]['id'];
576
-
577
- // Get the datatype fields
578
- $opts = array('table' => 'fields', 'where' => "datatype = {$params->datatype_id}", 'orderby' => 'weight', 'array_key' => 'name');
579
- $columns = $this->get_table_data($opts);
580
-
581
- // Find the active columns (loop through $params->columns to retain order)
582
- if (!empty($params->columns) && is_array($params->columns)) {
583
- foreach ($params->columns as $column_name => $column_val) {
584
- // Support for Pre Key/Value Parameters in previous Pods versions
585
- if (isset($params->name)&&isset($params->$column_val)) {
586
- $column_name = $column_val;
587
- $column_val = $params->$column_name;
588
- }
589
- if (isset($columns[$column_name])) {
590
- $columns[$column_name]['value'] = $column_val;
591
- $active_columns[] = $column_name;
592
- }
593
- }
594
- unset($params->columns);
595
- }
596
-
597
- // Load all helpers
598
- $result = pod_query("SELECT pre_save_helpers, post_save_helpers FROM @wp_pod_types WHERE id = {$params->datatype_id}");
599
- $row = pods_mysql_fetch_assoc($result);
600
- $params->pre_save_helpers = explode(',', $row['pre_save_helpers']);
601
- $params->post_save_helpers = explode(',', $row['post_save_helpers']);
602
-
603
- // Allow Helpers to know what's going on, are we adding or saving?
604
- $is_new_item = false;
605
- if (!empty($params->tbl_row_id)) {
606
- $result = pod_query("SELECT p.id FROM @wp_pod p INNER JOIN @wp_pod_types t ON t.id = p.datatype WHERE p.tbl_row_id = $params->tbl_row_id AND t.name = '$params->datatype' LIMIT 1",'Pod item not found',null,'Pod item not found');
607
- $params->pod_id = pods_mysql_result($result, 0);
608
- }
609
- elseif (!empty($params->pod_id)) {
610
- $result = pod_query("SELECT tbl_row_id FROM @wp_pod WHERE id = $params->pod_id LIMIT 1",'Item not found',null,'Item not found');
611
- $params->tbl_row_id = pods_mysql_result($result, 0);
612
- }
613
- else
614
- $is_new_item = true;
615
-
616
- // Plugin hook
617
- do_action('pods_pre_save_pod_item', $params, $columns);
618
-
619
- // Call any pre-save helpers (if not bypassed)
620
- if(!$bypass_helpers && !empty($params->pre_save_helpers)) {
621
- foreach ($params->pre_save_helpers as $helper) {
622
- $function_or_file = $helper;
623
- $check_function = $function_or_file;
624
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_HELPER_FUNCTIONS') || !PODS_HELPER_FUNCTIONS))
625
- $check_function = false;
626
- $check_file = null;
627
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_HELPER_FILES') || !PODS_HELPER_FILES))
628
- $check_file = false;
629
- if (false !== $check_function && false !== $check_file)
630
- $function_or_file = pods_function_or_file($function_or_file, $check_function, 'helper', $check_file);
631
- else
632
- $function_or_file = false;
633
-
634
- $content = false;
635
- if (!$function_or_file) {
636
- $api = new PodAPI();
637
- $params_helper = array('name' => $helper, 'type' => 'pre_save');
638
- if (!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE)
639
- $params_helper = pods_sanitize($params_helper);
640
- $content = $api->load_helper($params_helper);
641
- if (false !== $content && 0 < strlen(trim($content['phpcode'])))
642
- $content = $content['phpcode'];
643
- else
644
- $content = false;
645
- }
646
-
647
- if (false === $content && false !== $function_or_file && isset($function_or_file['function']))
648
- $function_or_file['function']($params, $columns, $this);
649
- elseif (false === $content && false !== $function_or_file && isset($function_or_file['file']))
650
- locate_template($function_or_file['file'], true, true);
651
- elseif (false !== $content) {
652
- if (!defined('PODS_DISABLE_EVAL') || PODS_DISABLE_EVAL)
653
- eval("?>$content");
654
- else
655
- echo $content;
656
- }
657
- }
658
- }
659
-
660
- // Loop through each active column, validating and preparing the table data
661
- foreach ($active_columns as $key) {
662
- $val = $columns[$key]['value'];
663
- $type = $columns[$key]['coltype'];
664
- $label = $columns[$key]['label'];
665
- $label = empty($label) ? $key : $label;
666
-
667
- // Verify required fields
668
- if (1 == $columns[$key]['required']) {
669
- if ('' == $val || null == $val) {
670
- return $this->oh_snap("<e>$label is empty.");
671
- }
672
- elseif ('num' == $type && !is_numeric($val)) {
673
- return $this->oh_snap("<e>$label is not numeric.");
674
- }
675
- }
676
- // Verify unique fields
677
- if (1 == $columns[$key]['unique'] && !in_array($type, array('pick', 'file'))) {
678
- $exclude = '';
679
- if (!empty($params->pod_id)) {
680
- $result = pod_query("SELECT tbl_row_id FROM @wp_pod WHERE id = '$params->pod_id' AND datatype = '{$params->datatype_id}' LIMIT 1");
681
- if (0 < pods_mysql_num_rows($result)) {
682
- $exclude = 'AND id != ' . pods_mysql_result($result, 0);
683
- }
684
- }
685
-
686
- // Trigger an error if not unique
687
- $sql = "SELECT id FROM `@wp_pod_tbl_$params->datatype` WHERE `$key` = '$val' $exclude LIMIT 1";
688
- pod_query($sql, 'Not unique', "$label needs to be unique.");
689
- }
690
- // Verify slug columns
691
- if ('slug' == $type) {
692
- $slug_val = empty($val) ? $columns['name']['value'] : $val;
693
- $val = pods_unique_slug($slug_val, $key, $params);
694
- }
695
-
696
- // Prepare all table (non-relational) data
697
- if (!in_array($type, array('pick', 'file'))) {
698
- if ('num' == $type)
699
- $val = floatval($val);
700
- elseif ('bool' == $type)
701
- $val = min(absint($val), 1);
702
- if ('num' != $type)
703
- $val = "'$val'";
704
- $table_data[] = "`$key` = $val";
705
- }
706
- // Store relational column data to be looped through later
707
- else {
708
- $rel_columns[$type][$key] = $val;
709
- }
710
- }
711
-
712
- // Create the pod_id if it doesn't exist
713
- if (empty($params->pod_id)&&empty($params->tbl_row_id)) {
714
- $current_time = current_time('mysql');
715
- $user = 0;
716
- if (is_user_logged_in()) {
717
- global $user_ID;
718
- get_currentuserinfo();
719
- $user = $user_ID;
720
- }
721
- $name = $params->datatype;
722
- if (isset($params->name))
723
- $name = $params->name;
724
- if (isset($params->columns) && is_array($params->columns) && isset($params->columns['name']))
725
- $name = $params->columns['name'];
726
- $sql = "INSERT INTO @wp_pod (datatype, name, created, modified, author_id) VALUES ('{$params->datatype_id}', '$name', '$current_time', '$current_time', '$user')";
727
- $params->pod_id = pod_query($sql, 'Cannot add new content');
728
- $params->tbl_row_id = pod_query("INSERT INTO `@wp_pod_tbl_$params->datatype` (name) VALUES (NULL)", 'Cannot add new table row');
729
- }
730
-
731
- // Save the table row
732
- if (isset($table_data)) {
733
- $table_data = implode(',', $table_data);
734
- pod_query("UPDATE `@wp_pod_tbl_$params->datatype` SET $table_data WHERE id = $params->tbl_row_id LIMIT 1");
735
- }
736
-
737
- // Update wp_pod
738
- $item_name = isset($columns['name']['value']) ? ", name = '" . $columns['name']['value'] . "'" : '';
739
- pod_query("UPDATE @wp_pod SET tbl_row_id = $params->tbl_row_id, datatype = $params->datatype_id, modified = '" . current_time('mysql') . "' $item_name WHERE id = $params->pod_id LIMIT 1");
740
-
741
- // Save relational column data
742
- if (isset($rel_columns)) {
743
- // E.g. $rel_columns['pick']['related_events'] = '3,15';
744
- foreach ($rel_columns as $rel_type => $rel_data) {
745
- foreach ($rel_data as $rel_name => $rel_values) {
746
- $field_id = $columns[$rel_name]['id'];
747
-
748
- // Convert values from a comma-separated string into an array
749
- if (empty($rel_values))
750
- $rel_values = array();
751
- elseif (!is_array($rel_values))
752
- $rel_values = explode(',', $rel_values);
753
-
754
- // Remove existing relationships
755
- pod_query("DELETE FROM @wp_pod_rel WHERE pod_id = $params->pod_id AND field_id = $field_id");
756
-
757
- // File relationships
758
- if ('file' == $rel_type) {
759
- $rel_weight = 0;
760
- foreach ($rel_values as $related_id) {
761
- $related_id = absint($related_id);
762
- if (empty($related_id))
763
- continue;
764
- pod_query("INSERT INTO @wp_pod_rel (pod_id, field_id, tbl_row_id, weight) VALUES ($params->pod_id, $field_id, $related_id, $rel_weight)");
765
- $rel_weight++;
766
- }
767
- }
768
- // Pick relationships
769
- elseif ('pick' == $rel_type) {
770
- $pickval = $columns[$rel_name]['pickval'];
771
- $sister_datatype_id = 0;
772
- $sister_field_id = 0;
773
- if (!in_array($pickval, array('wp_taxonomy', 'wp_post', 'wp_page', 'wp_user')) && isset($datatypes[$pickval])) {
774
- $sister_datatype_id = $datatypes[$pickval]['id'];
775
- if (!empty($columns[$rel_name]['sister_field_id']))
776
- $sister_field_id = $columns[$rel_name]['sister_field_id'];
777
- }
778
- $sister_pod_ids = array();
779
-
780
- // Delete parent and sister rels
781
- if (!empty($sister_field_id)) {
782
- // Get sister pod IDs (a sister pod's sister pod is the parent pod)
783
- $result = pod_query("SELECT pod_id FROM @wp_pod_rel WHERE sister_pod_id = $params->pod_id");
784
- if (0 < pods_mysql_num_rows($result)) {
785
- while ($row = pods_mysql_fetch_assoc($result)) {
786
- $sister_pod_ids[] = $row['pod_id'];
787
- }
788
- $sister_pod_ids = implode(',', $sister_pod_ids);
789
-
790
- // Delete the sister pod relationship
791
- pod_query("DELETE FROM @wp_pod_rel WHERE pod_id IN ($sister_pod_ids) AND sister_pod_id = $params->pod_id AND field_id = $sister_field_id");
792
- }
793
- }
794
-
795
- // Add rel values
796
- $rel_weight = 0;
797
- foreach ($rel_values as $related_id) {
798
- $related_id = absint($related_id);
799
- if (empty($related_id))
800
- continue;
801
- $sister_pod_id = 0;
802
- if (!empty($sister_field_id) && !empty($sister_datatype_id)) {
803
- $result = pod_query("SELECT id FROM @wp_pod WHERE datatype = $sister_datatype_id AND tbl_row_id = $related_id LIMIT 1");
804
- if (0 < pods_mysql_num_rows($result)) {
805
- $sister_pod_id = pods_mysql_result($result, 0);
806
- pod_query("INSERT INTO @wp_pod_rel (pod_id, sister_pod_id, field_id, tbl_row_id, weight) VALUES ($sister_pod_id, $params->pod_id, $sister_field_id, $params->tbl_row_id, $rel_weight)", 'Cannot add sister relationships');
807
- }
808
- }
809
- pod_query("INSERT INTO @wp_pod_rel (pod_id, sister_pod_id, field_id, tbl_row_id, weight) VALUES ($params->pod_id, $sister_pod_id, $field_id, $related_id, $rel_weight)", 'Cannot add relationships');
810
- $rel_weight++;
811
- }
812
- }
813
- }
814
- }
815
- }
816
-
817
- // Plugin hook
818
- do_action('pods_post_save_pod_item', $params, $columns);
819
-
820
- // Call any post-save helpers (if not bypassed)
821
- if(!$bypass_helpers && !empty($params->post_save_helpers)) {
822
- foreach ($params->post_save_helpers as $helper) {
823
- $function_or_file = $helper;
824
- $check_function = $function_or_file;
825
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_HELPER_FUNCTIONS') || !PODS_HELPER_FUNCTIONS))
826
- $check_function = false;
827
- $check_file = null;
828
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_HELPER_FILES') || !PODS_HELPER_FILES))
829
- $check_file = false;
830
- if (false !== $check_function && false !== $check_file)
831
- $function_or_file = pods_function_or_file($function_or_file, $check_function, 'helper', $check_file);
832
- else
833
- $function_or_file = false;
834
-
835
- $content = false;
836
- if (!$function_or_file) {
837
- $api = new PodAPI();
838
- $params_helper = array('name' => $helper, 'type' => 'post_save');
839
- if (!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE)
840
- $params_helper = pods_sanitize($params_helper);
841
- $content = $api->load_helper($params_helper);
842
- if (false !== $content && 0 < strlen(trim($content['phpcode'])))
843
- $content = $content['phpcode'];
844
- else
845
- $content = false;
846
- }
847
-
848
- if (false === $content && false !== $function_or_file && isset($function_or_file['function']))
849
- $function_or_file['function']($params, $columns, $this);
850
- elseif (false === $content && false !== $function_or_file && isset($function_or_file['file']))
851
- locate_template($function_or_file['file'], true, true);
852
- elseif (false !== $content) {
853
- if (!defined('PODS_DISABLE_EVAL') || PODS_DISABLE_EVAL)
854
- eval("?>$content");
855
- else
856
- echo $content;
857
- }
858
- }
859
- }
860
-
861
- // Success! Return the id
862
- if (false===$this->use_pod_id) {
863
- return $params->tbl_row_id;
864
- }
865
- return $params->pod_id;
866
- }
867
-
868
- /**
869
- * Duplicate a pod item
870
- *
871
- * $params['datatype'] string The datatype name
872
- * $params['tbl_row_id'] int The item's ID from the wp_pod_tbl_* table
873
- *
874
- * @param array $params An associative array of parameters
875
- * @return int The table row ID
876
- * @since 1.12
877
- */
878
- function duplicate_pod_item($params) {
879
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
880
- $params = pods_sanitize($params);
881
- $params = (object) $params;
882
-
883
- $id = false;
884
- $columns = $this->fields;
885
- if (empty($columns) || $this->dtname != $params->datatype) {
886
- $pod = $this->load_pod(array('name' => $params->datatype));
887
- $columns = $pod['fields'];
888
- if (null === $this->dtname) {
889
- $this->dtname = $pod['name'];
890
- $this->dt = $pod['id'];
891
- $this->fields = $pod['fields'];
892
- }
893
- }
894
- $pod = new Pod($params->datatype, $params->tbl_row_id);
895
- if (!empty($pod->data)) {
896
- $params = array('datatype' => $params->datatype,
897
- 'columns' => array());
898
- foreach ($columns as $column) {
899
- $field = $column['name'];
900
- if ('pick' == $column['coltype']) {
901
- $field = $column . '.id';
902
- if ('wp_taxonomy' == $column['pickval'])
903
- $field = $column . '.term_id';
904
- }
905
- if ('file' == $column['coltype'])
906
- $field = $column . '.ID';
907
- $value = $pod->get_field($field);
908
- if (0 < strlen($value))
909
- $params['columns'][$column['name']] = $value;
910
- }
911
- $params = apply_filters('duplicate_pod_item', $params, $pod->datatype, $pod->get_field('id'));
912
- $id = $this->save_pod_item(pods_sanitize($params));
913
- }
914
- return $id;
915
- }
916
-
917
- /**
918
- * Export a pod item
919
- *
920
- * $params['datatype'] string The datatype name
921
- * $params['tbl_row_id'] int The item's ID from the wp_pod_tbl_* table
922
- *
923
- * @param array $params An associative array of parameters
924
- * @return int The table row ID
925
- * @since 1.12
926
- */
927
- function export_pod_item($params) {
928
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
929
- $params = pods_sanitize($params);
930
- $params = (object) $params;
931
-
932
- $data = false;
933
- $columns = $this->fields;
934
- if (empty($columns) || $this->dtname != $params->datatype) {
935
- $pod = $this->load_pod(array('name' => $params->datatype));
936
- $columns = $pod['fields'];
937
- if (null === $this->dtname) {
938
- $this->dtname = $pod['name'];
939
- $this->dt = $pod['id'];
940
- $this->fields = $pod['fields'];
941
- }
942
- }
943
- $pod = new Pod($params->datatype, $params->tbl_row_id);
944
- if (!empty($pod->data)) {
945
- $data = array();
946
- foreach ($columns as $column) {
947
- $value = $pod->get_field($column['name']);
948
- if (0 < strlen($value))
949
- $data[$column['name']] = $value;
950
- }
951
- $data = apply_filters('export_pod_item', $data, $pod->datatype, $pod->get_field('id'));
952
- }
953
- return $data;
954
- }
955
-
956
- /**
957
- * Reorder a Pod
958
- *
959
- * $params['datatype'] string The datatype name
960
- * $params['field'] string The column name of the field to reorder
961
- * $params['order'] array The key=>value array of items to reorder (key should be an integer)
962
- *
963
- * @param array $params An associative array of parameters
964
- * @since 1.9.0
965
- */
966
- function reorder_pod_item($params) {
967
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
968
- $params = pods_sanitize($params);
969
- $params = (object) $params;
970
-
971
- if (!is_array($params->order)) {
972
- $params->order = explode(',', $params->order);
973
- }
974
- foreach ($params->order as $order => $id) {
975
- pod_query("UPDATE @wp_pod_tbl_{$params->datatype} SET `{$params->field}`={$order} WHERE id={$id}");
976
- }
977
- }
978
-
979
- /**
980
- * Delete all content for a content type
981
- *
982
- * $params['id'] int The datatype ID
983
- * $params['name'] string The datatype name
984
- *
985
- * @param array $params An associative array of parameters
986
- * @since 1.9.0
987
- */
988
- function reset_pod($params) {
989
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
990
- $params = pods_sanitize($params);
991
- $params = (object) $params;
992
-
993
- $pod = $this->load_pod($params);
994
- if (false === $pod)
995
- return false;
996
-
997
- $params->id = $pod['id'];
998
- $params->name = $pod['name'];
999
-
1000
- $fields = array();
1001
- foreach ($pod['fields'] as $field) {
1002
- $fields[] = $field['id'];
1003
- }
1004
- $fields = implode(',',$fields);
1005
- if (!empty($fields))
1006
- pod_query("UPDATE @wp_pod_fields SET sister_field_id = NULL WHERE sister_field_id IN ($fields)");
1007
-
1008
- $sql = "DELETE FROM p, r
1009
- USING @wp_pod_types AS t
1010
- LEFT JOIN @wp_pod AS p ON p.datatype = t.id
1011
- LEFT JOIN @wp_pod_fields AS f ON f.datatype = t.id
1012
- LEFT JOIN @wp_pod_rel AS r ON r.field_id = f.id
1013
- WHERE t.name = '$params->name'";
1014
-
1015
- pod_query($sql);
1016
-
1017
- $sql = "DELETE FROM r
1018
- USING @wp_pod_fields AS f
1019
- INNER JOIN @wp_pod_rel AS r ON r.field_id = f.id
1020
- WHERE f.pickval = '$params->name'";
1021
-
1022
- pod_query($sql);
1023
- pod_query("TRUNCATE `@wp_pod_tbl_$params->name`");
1024
- }
1025
-
1026
- /**
1027
- * Drop a content type and all its content
1028
- *
1029
- * $params['id'] int The datatype ID
1030
- * $params['name'] string The datatype name
1031
- *
1032
- * @param array $params An associative array of parameters
1033
- * @since 1.7.9
1034
- */
1035
- function drop_pod($params) {
1036
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1037
- $params = pods_sanitize($params);
1038
- $params = (object) $params;
1039
-
1040
- $pod = $this->load_pod($params);
1041
- if (false === $pod)
1042
- return false;
1043
-
1044
- $params->id = $pod['id'];
1045
- $params->name = $pod['name'];
1046
-
1047
- pod_query("DELETE FROM @wp_pod_types WHERE id = $params->id LIMIT 1");
1048
-
1049
- $fields = array();
1050
- foreach ($pod['fields'] as $field) {
1051
- $fields[] = $field['id'];
1052
- }
1053
- $fields = implode(',',$fields);
1054
- if (!empty($fields))
1055
- pod_query("UPDATE @wp_pod_fields SET sister_field_id = NULL WHERE sister_field_id IN ($fields)");
1056
-
1057
- $sql = "DELETE FROM @wp_pod,@wp_pod_rel
1058
- USING @wp_pod_fields
1059
- INNER JOIN @wp_pod_rel ON @wp_pod_rel.field_id = @wp_pod_fields.id
1060
- INNER JOIN @wp_pod ON @wp_pod.datatype = @wp_pod_fields.datatype
1061
- WHERE @wp_pod_fields.datatype = $params->id";
1062
-
1063
- pod_query($sql);
1064
- pod_query("DELETE FROM @wp_pod_fields WHERE datatype = $params->id");
1065
- pod_query("DROP TABLE `@wp_pod_tbl_$params->name`");
1066
- }
1067
-
1068
- /**
1069
- * Drop a column within a content type
1070
- *
1071
- * $params['id'] int The column ID
1072
- * $params['dtname'] string The datatype name
1073
- *
1074
- * @param array $params An associative array of parameters
1075
- * @since 1.7.9
1076
- */
1077
- function drop_column($params) {
1078
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1079
- $params = pods_sanitize($params);
1080
- $params = (object) $params;
1081
- $result = pod_query("SELECT name, coltype FROM @wp_pod_fields WHERE id = $params->id LIMIT 1");
1082
- list($field_name, $coltype) = pods_mysql_fetch_array($result);
1083
-
1084
- if ('pick' == $coltype) {
1085
- // Remove any orphans
1086
- $result = pod_query("SELECT id FROM @wp_pod_fields WHERE sister_field_id = $params->id");
1087
- if (0 < pods_mysql_num_rows($result)) {
1088
- while ($row = pods_mysql_fetch_assoc($result)) {
1089
- $related_fields[] = $row['id'];
1090
- }
1091
- $related_fields = implode(',', $related_fields);
1092
- pod_query("DELETE FROM @wp_pod_rel WHERE field_id IN ($related_fields)");
1093
- pod_query("UPDATE @wp_pod_fields SET sister_field_id = NULL WHERE sister_field_id IN ($related_fields)");
1094
- }
1095
- }
1096
- elseif ('file' != $coltype) {
1097
- pod_query("ALTER TABLE `@wp_pod_tbl_$params->dtname` DROP COLUMN `$field_name`");
1098
- }
1099
-
1100
- pod_query("DELETE FROM @wp_pod_fields WHERE id = $params->id LIMIT 1");
1101
- pod_query("DELETE FROM @wp_pod_rel WHERE field_id = $params->id");
1102
- }
1103
-
1104
- /**
1105
- * Drop a Pod Template
1106
- *
1107
- * $params['id'] int The template ID
1108
- * $params['name'] string The template name
1109
- *
1110
- * @param array $params An associative array of parameters
1111
- * @since 1.7.9
1112
- */
1113
- function drop_template($params) {
1114
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1115
- $params = pods_sanitize($params);
1116
- $params = (object) $params;
1117
- $where = empty($params->id) ? "name = '$params->name'" : "id = $params->id";
1118
- pod_query("DELETE FROM @wp_pod_templates WHERE $where LIMIT 1");
1119
- }
1120
-
1121
- /**
1122
- * Drop a Pod Page
1123
- *
1124
- * $params['id'] int The page ID
1125
- * $params['uri'] string The page URI
1126
- *
1127
- * @param array $params An associative array of parameters
1128
- * @since 1.7.9
1129
- */
1130
- function drop_page($params) {
1131
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1132
- $params = pods_sanitize($params);
1133
- $params = (object) $params;
1134
- $where = empty($params->id) ? "uri = '$params->uri'" : "id = $params->id";
1135
- pod_query("DELETE FROM @wp_pod_pages WHERE $where LIMIT 1");
1136
- }
1137
-
1138
- /**
1139
- * Drop a Pod Helper
1140
- *
1141
- * $params['id'] int The helper ID
1142
- * $params['name'] string The helper name
1143
- *
1144
- * @param array $params An associative array of parameters
1145
- * @since 1.7.9
1146
- */
1147
- function drop_helper($params) {
1148
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1149
- $params = pods_sanitize($params);
1150
- $params = (object) $params;
1151
- $where = empty($params->id) ? "name = '$params->name'" : "id = $params->id";
1152
- pod_query("DELETE FROM @wp_pod_helpers WHERE $where LIMIT 1");
1153
- }
1154
-
1155
- /**
1156
- * Drop a single pod item
1157
- *
1158
- * $params['pod_id'] int The item's ID from the wp_pod table
1159
- * $params['tbl_row_id'] int (optional) The item's ID from the wp_pod_tbl_* table (used with datatype parameter)
1160
- * $params['datatype'] string (optional) The datatype name (used with tbl_row_id parameter)
1161
- * $params['datatype_id'] int (optional) The datatype ID (used with tbl_row_id parameter)
1162
- *
1163
- * @param array $params An associative array of parameters
1164
- * @since 1.7.9
1165
- */
1166
- function drop_pod_item($params) {
1167
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1168
- $params = pods_sanitize($params);
1169
- $params = (object) $params;
1170
-
1171
- if (isset($params->tbl_row_id)) {
1172
- if (!empty($params->tbl_row_id) && is_array($params->tbl_row_id)) {
1173
- $new_params = $params;
1174
- foreach ($params->tbl_row_id as $tbl_row_id) {
1175
- $new_params->tbl_row_id = $tbl_row_id;
1176
- $this->drop_pod_item($new_params);
1177
- }
1178
- return;
1179
- }
1180
- if (isset($params->datatype_id)) {
1181
- $select_dt = "p.datatype = '$params->datatype_id'";
1182
- }
1183
- else {
1184
- $select_dt = "t.name = '$params->datatype'";
1185
- }
1186
- $sql = "
1187
- SELECT
1188
- p.id AS pod_id, p.tbl_row_id, t.id, t.name
1189
- FROM
1190
- @wp_pod p
1191
- INNER JOIN
1192
- @wp_pod_types t ON t.id = p.datatype
1193
- WHERE
1194
- p.tbl_row_id = $params->tbl_row_id AND
1195
- $select_dt
1196
- LIMIT
1197
- 1
1198
- ";
1199
- }
1200
- else {
1201
- $sql = "
1202
- SELECT
1203
- p.id AS pod_id, p.tbl_row_id, t.id, t.name
1204
- FROM
1205
- @wp_pod p
1206
- INNER JOIN
1207
- @wp_pod_types t ON t.id = p.datatype
1208
- WHERE
1209
- p.id = $params->pod_id
1210
- LIMIT
1211
- 1
1212
- ";
1213
- }
1214
-
1215
- $result = pod_query($sql);
1216
- $row = pods_mysql_fetch_assoc($result);
1217
- $params->datatype_id = $row['id'];
1218
- $params->datatype = $row['name'];
1219
- $params->pod_id = $row['pod_id'];
1220
- $params->tbl_row_id = $row['tbl_row_id'];
1221
-
1222
- // Get helper code
1223
- $result = pod_query("SELECT pre_drop_helpers, post_drop_helpers FROM @wp_pod_types WHERE id = $params->datatype_id");
1224
- $row = pods_mysql_fetch_assoc($result);
1225
- $params->pre_drop_helpers = explode(',', $row['pre_drop_helpers']);
1226
- $params->post_drop_helpers = explode(',', $row['post_drop_helpers']);
1227
-
1228
- // Plugin hook
1229
- do_action('pods_pre_drop_pod_item', $params);
1230
-
1231
- // Pre-drop helpers
1232
- if (0 < count($params->pre_drop_helpers)) {
1233
- foreach ($params->pre_drop_helpers as $helper) {
1234
- $function_or_file = $helper;
1235
- $check_function = $function_or_file;
1236
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_HELPER_FUNCTIONS') || !PODS_HELPER_FUNCTIONS))
1237
- $check_function = false;
1238
- $check_file = null;
1239
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_HELPER_FILES') || !PODS_HELPER_FILES))
1240
- $check_file = false;
1241
- if (false !== $check_function && false !== $check_file)
1242
- $function_or_file = pods_function_or_file($function_or_file, $check_function, 'helper', $check_file);
1243
- else
1244
- $function_or_file = false;
1245
-
1246
- $content = false;
1247
- if (!$function_or_file) {
1248
- $api = new PodAPI();
1249
- $params_helper = array('name' => $helper, 'type' => 'pre_drop');
1250
- if (!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE)
1251
- $params_helper = pods_sanitize($params_helper);
1252
- $content = $api->load_helper($params_helper);
1253
- if (false !== $content && 0 < strlen(trim($content['phpcode'])))
1254
- $content = $content['phpcode'];
1255
- else
1256
- $content = false;
1257
- }
1258
-
1259
- if (false === $content && false !== $function_or_file && isset($function_or_file['function']))
1260
- $function_or_file['function']($params, $this);
1261
- elseif (false === $content && false !== $function_or_file && isset($function_or_file['file']))
1262
- locate_template($function_or_file['file'], true, true);
1263
- elseif (false !== $content) {
1264
- if (!defined('PODS_DISABLE_EVAL') || PODS_DISABLE_EVAL)
1265
- eval("?>$content");
1266
- else
1267
- echo $content;
1268
- }
1269
- }
1270
- }
1271
-
1272
- pod_query("DELETE FROM `@wp_pod_tbl_$params->datatype` WHERE id = $params->tbl_row_id LIMIT 1");
1273
- pod_query("UPDATE @wp_pod_rel SET sister_pod_id = NULL WHERE sister_pod_id = $params->pod_id");
1274
- pod_query("DELETE FROM @wp_pod WHERE id = $params->pod_id LIMIT 1");
1275
- pod_query("DELETE FROM @wp_pod_rel WHERE pod_id = $params->pod_id");
1276
-
1277
- // Plugin hook
1278
- do_action('pods_post_drop_pod_item', $params);
1279
-
1280
- // Post-drop helpers
1281
- if (0 < count($params->post_drop_helpers)) {
1282
- foreach ($params->post_drop_helpers as $helper) {
1283
- $function_or_file = $helper;
1284
- $check_function = $function_or_file;
1285
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_HELPER_FUNCTIONS') || !PODS_HELPER_FUNCTIONS))
1286
- $check_function = false;
1287
- $check_file = null;
1288
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_HELPER_FILES') || !PODS_HELPER_FILES))
1289
- $check_file = false;
1290
- if (false !== $check_function && false !== $check_file)
1291
- $function_or_file = pods_function_or_file($function_or_file, $check_function, 'helper', $check_file);
1292
- else
1293
- $function_or_file = false;
1294
-
1295
- $content = false;
1296
- if (!$function_or_file) {
1297
- $api = new PodAPI();
1298
- $params_helper = array('name' => $helper, 'type' => 'post_drop');
1299
- if (!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE)
1300
- $params_helper = pods_sanitize($params_helper);
1301
- $content = $api->load_helper($params_helper);
1302
- if (false !== $content && 0 < strlen(trim($content['phpcode'])))
1303
- $content = $content['phpcode'];
1304
- else
1305
- $content = false;
1306
- }
1307
-
1308
- if (false === $content && false !== $function_or_file && isset($function_or_file['function']))
1309
- $function_or_file['function']($params, $this);
1310
- elseif (false === $content && false !== $function_or_file && isset($function_or_file['file']))
1311
- locate_template($function_or_file['file'], true, true);
1312
- elseif (false !== $content) {
1313
- if (!defined('PODS_DISABLE_EVAL') || PODS_DISABLE_EVAL)
1314
- eval("?>$content");
1315
- else
1316
- echo $content;
1317
- }
1318
- }
1319
- }
1320
- }
1321
-
1322
- /**
1323
- * Check if a Pod exists
1324
- *
1325
- * $params['id'] int The datatype ID
1326
- * $params['name'] string The datatype name
1327
- *
1328
- * @param array $params An associative array of parameters
1329
- * @since 1.12
1330
- */
1331
- function pod_exists($params) {
1332
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1333
- $params = pods_sanitize($params);
1334
- $params = (object) $params;
1335
- if (!empty($params->id) || !empty($params->name)) {
1336
- $where = empty($params->id) ? "name = '{$params->name}'" : "id = {$params->id}";
1337
- $result = pod_query("SELECT id, name FROM @wp_pod_types WHERE {$where} LIMIT 1");
1338
- if (0 < pods_mysql_num_rows($result)) {
1339
- $pod = pods_mysql_fetch_assoc($result);
1340
- return $pod;
1341
- }
1342
- }
1343
- return false;
1344
- }
1345
-
1346
- /**
1347
- * Load a content type and all of its fields
1348
- *
1349
- * $params['id'] int The datatype ID
1350
- * $params['name'] string The datatype name
1351
- *
1352
- * @param array $params An associative array of parameters
1353
- * @since 1.7.9
1354
- */
1355
- function load_pod($params) {
1356
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1357
- $params = pods_sanitize($params);
1358
- $params = (object) $params;
1359
- if (!empty($params->id) || !empty($params->name)) {
1360
- $where = empty($params->id) ? "name = '$params->name'" : "id = $params->id";
1361
- $result = pod_query("SELECT * FROM @wp_pod_types WHERE $where LIMIT 1");
1362
- if (0 < pods_mysql_num_rows($result)) {
1363
- $pod = pods_mysql_fetch_assoc($result);
1364
- $pod['fields'] = array();
1365
- $result = pod_query("SELECT id, name, coltype, pickval, required, weight FROM @wp_pod_fields WHERE datatype = {$pod['id']} ORDER BY weight");
1366
- while ($row = pods_mysql_fetch_assoc($result)) {
1367
- $pod['fields'][$row['name']] = $row;
1368
- }
1369
-
1370
- return $pod;
1371
- }
1372
- }
1373
- return false;
1374
- }
1375
-
1376
- /**
1377
- * Load a column
1378
- *
1379
- * $params['id'] int The field ID
1380
- * $params['name'] string The field name
1381
- * $params['datatype'] int The Pod ID
1382
- *
1383
- * @param array $params An associative array of parameters
1384
- * @since 1.7.9
1385
- */
1386
- function load_column($params) {
1387
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1388
- $params = pods_sanitize($params);
1389
- $params = (object) $params;
1390
- if (isset($params->id))
1391
- $params->id = absint($params->id);
1392
- $where = empty($params->id) ? "`name` = '{$params->name}' AND `datatype` = {$params->datatype}" : "`id` = {$params->id}";
1393
- $result = pod_query("SELECT * FROM @wp_pod_fields WHERE {$where} LIMIT 1");
1394
- return @pods_mysql_fetch_assoc($result);
1395
- }
1396
-
1397
- /**
1398
- * Load a Pod Template
1399
- *
1400
- * $params['id'] int The template ID
1401
- * $params['name'] string The template name
1402
- *
1403
- * @param array $params An associative array of parameters
1404
- * @since 1.7.9
1405
- */
1406
- function load_template($params) {
1407
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1408
- $params = pods_sanitize($params);
1409
- $params = (object) $params;
1410
- if (isset($params->id))
1411
- $params->id = absint($params->id);
1412
- $where = empty($params->id) ? "`name` = '{$params->name}'" : "`id` = {$params->id}";
1413
- $result = pod_query("SELECT * FROM @wp_pod_templates WHERE {$where} LIMIT 1");
1414
- return @pods_mysql_fetch_assoc($result);
1415
- }
1416
-
1417
- /**
1418
- * Load a Pod Page
1419
- *
1420
- * $params['id'] int The page ID
1421
- * $params['uri'] string The page URI
1422
- *
1423
- * @param array $params An associative array of parameters
1424
- * @since 1.7.9
1425
- */
1426
- function load_page($params) {
1427
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1428
- $params = pods_sanitize($params);
1429
- $params = (object) $params;
1430
- if (isset($params->id))
1431
- $params->id = absint($params->id);
1432
- $where = empty($params->id) ? "`uri` = '{$params->uri}'" : "`id` = {$params->id}";
1433
- $result = pod_query("SELECT * FROM @wp_pod_pages WHERE {$where} LIMIT 1");
1434
- return @pods_mysql_fetch_assoc($result);
1435
- }
1436
-
1437
- /**
1438
- * Load a Pod Helper
1439
- *
1440
- * $params['id'] int The helper ID
1441
- * $params['name'] string The helper name
1442
- * $params['type'] string The helper type
1443
- *
1444
- * @param array $params An associative array of parameters
1445
- * @since 1.7.9
1446
- */
1447
- function load_helper($params) {
1448
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1449
- $params = pods_sanitize($params);
1450
- $params = (object) $params;
1451
- if (isset($params->id))
1452
- $params->id = absint($params->id);
1453
- $where = empty($params->id) ? "`name` = '{$params->name}'" : "`id` = {$params->id}";
1454
- if (isset($params->type) && !empty($params->type))
1455
- $where .= " AND `helper_type` = '{$params->type}'";
1456
- $result = pod_query("SELECT * FROM @wp_pod_helpers WHERE {$where} LIMIT 1");
1457
- return @pods_mysql_fetch_assoc($result);
1458
- }
1459
-
1460
- /**
1461
- * Load the input form for a pod item
1462
- *
1463
- * $params['datatype'] string The datatype name
1464
- * $params['pod_id'] int The item's pod ID
1465
- * $params['tbl_row_id'] int (optional) The item's ID
1466
- * $params['public_columns'] array An associative array of columns
1467
- *
1468
- * @param array $params An associative array of parameters
1469
- * @since 1.7.9
1470
- */
1471
- function load_pod_item($params) {
1472
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1473
- $params = pods_sanitize($params);
1474
- $params = (object) $params;
1475
-
1476
- $params->tbl_row_id = (int) (isset($params->tbl_row_id)?$params->tbl_row_id:null);
1477
- $params->pod_id = (int) (isset($params->pod_id)?$params->pod_id:null);
1478
- if (empty($params->tbl_row_id)) {
1479
- $params->tbl_row_id = null;
1480
- if (!empty($params->pod_id)) {
1481
- $result = pod_query("SELECT tbl_row_id FROM @wp_pod WHERE id = $params->pod_id LIMIT 1",'Item not found',null,'Item not found');
1482
- $params->tbl_row_id = pods_mysql_result($result, 0);
1483
- }
1484
- }
1485
- $obj = new Pod($params->datatype,$params->tbl_row_id);
1486
- $pod_id = 0;
1487
- if (!empty($params->tbl_row_id) && !empty($obj->data)) {
1488
- $pod_id = $obj->get_pod_id();
1489
- }
1490
- return $obj->showform($pod_id, $params->public_columns = null);
1491
- }
1492
-
1493
- /**
1494
- * Load a bi-directional (sister) column
1495
- *
1496
- * $params['pickval'] string The related PICK pod name
1497
- * $params['datatype'] int The datatype ID
1498
- *
1499
- * @param array $params An associative array of parameters
1500
- * @since 1.7.9
1501
- */
1502
- function load_sister_fields($params) {
1503
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1504
- $params = pods_sanitize($params);
1505
- $params = (object) $params;
1506
-
1507
- if (!empty($params->pickval) && is_string($params->pickval)) {
1508
- $result = pod_query("SELECT id FROM @wp_pod_types WHERE name = '$params->pickval' LIMIT 1");
1509
- if (0 < pods_mysql_num_rows($result)) {
1510
- $sister_datatype = pods_mysql_result($result, 0);
1511
-
1512
- $result = pod_query("SELECT name FROM @wp_pod_types WHERE id = $params->datatype LIMIT 1");
1513
- if (0 < pods_mysql_num_rows($result)) {
1514
- $datatype_name = pods_mysql_result($result, 0);
1515
-
1516
- $result = pod_query("SELECT id, name FROM @wp_pod_fields WHERE datatype = $sister_datatype AND pickval = '$datatype_name'");
1517
- if (0 < pods_mysql_num_rows($result)) {
1518
- while ($row = pods_mysql_fetch_assoc($result)) {
1519
- $sister_fields[] = $row;
1520
- }
1521
- return $sister_fields;
1522
- }
1523
- }
1524
- }
1525
- }
1526
- }
1527
-
1528
- /**
1529
- * Export a package
1530
- *
1531
- * $params['pod'] string Pod Type IDs to export
1532
- * $params['template'] string Template IDs to export
1533
- * $params['podpage'] string Pod Page IDs to export
1534
- * $params['helper'] string Helper IDs to export
1535
- *
1536
- * @param array $params An associative array of parameters
1537
- * @since 1.9.0
1538
- */
1539
- function export_package($params) {
1540
- if (defined('PODS_STRICT_MODE') && PODS_STRICT_MODE)
1541
- $params = pods_sanitize($params);
1542
- $export = array(
1543
- 'meta' => array(
1544
- 'version' => PODS_VERSION,
1545
- 'build' => date('U'),
1546
- )
1547
- );
1548
-
1549
- $pod_ids = $params['pod'];
1550
- $template_ids = $params['template'];
1551
- $pod_page_ids = $params['podpage'];
1552
- $helper_ids = $params['helper'];
1553
-
1554
- // Get pods
1555
- if (!empty($pod_ids)) {
1556
- $result = pod_query("SELECT * FROM @wp_pod_types WHERE id IN ($pod_ids)");
1557
- while ($row = pods_mysql_fetch_assoc($result)) {
1558
- $dt = $row['id'];
1559
- unset($row['id']);
1560
- $export['pods'][$dt] = $row;
1561
- }
1562
-
1563
- // Get pod fields
1564
- $result = pod_query("SELECT * FROM @wp_pod_fields WHERE datatype IN ($pod_ids)");
1565
- while ($row = pods_mysql_fetch_assoc($result)) {
1566
- unset($row['id']);
1567
- $dt = $row['datatype'];
1568
- unset($row['datatype']);
1569
- unset($row['sister_field_id']); // impossible to reference this correctly until all pods / fields have been added
1570
- $export['pods'][$dt]['fields'][] = $row;
1571
- }
1572
- }
1573
-
1574
- // Get templates
1575
- if (!empty($template_ids)) {
1576
- $result = pod_query("SELECT * FROM @wp_pod_templates WHERE id IN ($template_ids)");
1577
- while ($row = pods_mysql_fetch_assoc($result)) {
1578
- unset($row['id']);
1579
- $export['templates'][] = $row;
1580
- }
1581
- }
1582
-
1583
- // Get pod pages
1584
- if (!empty($pod_page_ids)) {
1585
- $result = pod_query("SELECT * FROM @wp_pod_pages WHERE id IN ($pod_page_ids)");
1586
- while ($row = pods_mysql_fetch_assoc($result)) {
1587
- unset($row['id']);
1588
- $export['pod_pages'][] = $row;
1589
- }
1590
- }
1591
-
1592
- // Get helpers
1593
- if (!empty($helper_ids)) {
1594
- $result = pod_query("SELECT * FROM @wp_pod_helpers WHERE id IN ($helper_ids)");
1595
- while ($row = pods_mysql_fetch_assoc($result)) {
1596
- unset($row['id']);
1597
- $export['helpers'][] = $row;
1598
- }
1599
- }
1600
-
1601
- if (1 == count($export))
1602
- return false;
1603
-
1604
- return $export;
1605
- }
1606
-
1607
- /**
1608
- * Replace an existing package
1609
- *
1610
- *
1611
- * @param mixed $data (optional) An associative array containing a package, or the json encoded package
1612
- * @since 1.9.8
1613
- */
1614
- function replace_package($data = false) {
1615
- return $this->import_package($data, true);
1616
- }
1617
-
1618
- /**
1619
- * Import a package
1620
- *
1621
- *
1622
- * @param mixed $data (optional) An associative array containing a package, or the json encoded package
1623
- * @param bool $replace (optional) Replace existing items when found
1624
- * @since 1.9.0
1625
- */
1626
- function import_package($data = false, $replace = false) {
1627
- $output = false;
1628
- if (false===$data || isset($data['action'])) {
1629
- $data = get_option('pods_package');
1630
- $output = true;
1631
- }
1632
- if (!is_array($data)) {
1633
- $json_data = @json_decode($data, true);
1634
- if (!is_array($json_data))
1635
- $json_data = @json_decode(stripslashes($data), true);
1636
- $data = $json_data;
1637
- }
1638
- if (!is_array($data) || empty($data)) {
1639
- return false;
1640
- }
1641
-
1642
- $dbtypes = array(
1643
- 'bool' => 'bool default 0',
1644
- 'date' => 'datetime',
1645
- 'num' => 'decimal(9,2)',
1646
- 'txt' => 'varchar(128)',
1647
- 'slug' => 'varchar(128)',
1648
- 'code' => 'mediumtext',
1649
- 'desc' => 'mediumtext'
1650
- );
1651
- $dbtypes = apply_filters('pods_column_dbtypes', $dbtypes, $this);
1652
-
1653
- $found = array();
1654
-
1655
- if (isset($data['pods'])) {
1656
- $pod_columns = '';
1657
- foreach ($data['pods'] as $pod) {
1658
- $pod = pods_sanitize($pod);
1659
-
1660
- $table_columns = array();
1661
- $pod_fields = $pod['fields'];
1662
- unset($pod['fields']);
1663
-
1664
- if (false !== $replace) {
1665
- $existing = $this->load_pod(array('name' => $pod['name']));
1666
- if (is_array($existing))
1667
- $this->drop_pod(array('id' => $existing['id']));
1668
- }
1669
-
1670
- if (empty($pod_columns))
1671
- $pod_columns = implode("`,`", array_keys($pod));
1672
- // Backward-compatibility (before/after helpers)
1673
- $pod_columns = str_replace('before_helpers', 'pre_save_helpers', $pod_columns);
1674
- $pod_columns = str_replace('after_helpers', 'post_save_helpers', $pod_columns);
1675
-
1676
- $values = implode("','", $pod);
1677
- $dt = pod_query("INSERT INTO @wp_pod_types (`$pod_columns`) VALUES ('$values')");
1678
-
1679
- $tupples = array();
1680
- $field_columns = '';
1681
- foreach ($pod_fields as $fieldval) {
1682
- // Escape the values
1683
- foreach ($fieldval as $k => $v) {
1684
- if (empty($v))
1685
- $v = 'null';
1686
- else
1687
- $v = pods_sanitize($v);
1688
- $fieldval[$k] = $v;
1689
- }
1690
-
1691
- // Store all table columns
1692
- if ('pick' != $fieldval['coltype'] && 'file' != $fieldval['coltype'])
1693
- $table_columns[$fieldval['name']] = $fieldval['coltype'];
1694
-
1695
- $fieldval['datatype'] = $dt;
1696
- if (empty($field_columns))
1697
- $field_columns = implode("`,`", array_keys($fieldval));
1698
- $tupples[] = implode("','", $fieldval);
1699
- }
1700
- $tupples = implode("'),('", $tupples);
1701
- $tupples = str_replace("'null'", 'null', $tupples);
1702
- pod_query("INSERT INTO @wp_pod_fields (`$field_columns`) VALUES ('$tupples')");
1703
-
1704
- // Create the actual table with any non-PICK columns
1705
- $definitions = array("id INT unsigned auto_increment primary key");
1706
- foreach ($table_columns as $colname => $coltype) {
1707
- $definitions[] = "`$colname` {$dbtypes[$coltype]}";
1708
- }
1709
- $definitions = implode(',', $definitions);
1710
- pod_query("CREATE TABLE @wp_pod_tbl_{$pod['name']} ($definitions)");
1711
- if (!isset($found['pods']))
1712
- $found['pods'] = array();
1713
- $found['pods'][] = esc_textarea($pod['name']);
1714
- }
1715
- }
1716
-
1717
- if (isset($data['templates'])) {
1718
- foreach ($data['templates'] as $template) {
1719
- $defaults = array('name' => '', 'code' => '');
1720
- $params = array_merge($defaults, $template);
1721
- if (!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE)
1722
- $params = pods_sanitize($params);
1723
- if (false !== $replace) {
1724
- $existing = $this->load_template(array('name' => $params['name']));
1725
- if (is_array($existing))
1726
- $params['id'] = $existing['id'];
1727
- }
1728
- $this->save_template($params);
1729
- if (!isset($found['templates']))
1730
- $found['templates'] = array();
1731
- $found['templates'][] = esc_textarea($params['name']);
1732
- }
1733
- }
1734
-
1735
- if (isset($data['pod_pages'])) {
1736
- foreach ($data['pod_pages'] as $pod_page) {
1737
- $defaults = array('uri' => '', 'title' => '', 'phpcode' => '', 'precode' => '', 'page_template' => '');
1738
- $params = array_merge($defaults, $pod_page);
1739
- if (!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE)
1740
- $params = pods_sanitize($params);
1741
- if (false !== $replace) {
1742
- $existing = $this->load_page(array('uri' => $params['uri']));
1743
- if (is_array($existing))
1744
- $params['id'] = $existing['id'];
1745
- }
1746
- $this->save_page($params);
1747
- if (!isset($found['pod_pages']))
1748
- $found['pod_pages'] = array();
1749
- $found['pod_pages'][] = esc_textarea($params['uri']);
1750
- }
1751
- }
1752
-
1753
- if (isset($data['helpers'])) {
1754
- foreach ($data['helpers'] as $helper) {
1755
- // backwards compatibility
1756
- if (isset($helper['helper_type'])) {
1757
- if ('before' == $helper['helper_type'])
1758
- $helper['helper_type'] = 'pre_save';
1759
- if ('after' == $helper['helper_type'])
1760
- $helper['helper_type'] = 'post_save';
1761
- }
1762
- $defaults = array('name' => '', 'helper_type' => 'display', 'phpcode' => '');
1763
- $params = array_merge($defaults, $helper);
1764
- if (!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE)
1765
- $params = pods_sanitize($params);
1766
- if (false !== $replace) {
1767
- $existing = $this->load_helper(array('name' => $params['name']));
1768
- if (is_array($existing))
1769
- $params['id'] = $existing['id'];
1770
- }
1771
- $this->save_helper($params);
1772
- if (!isset($found['helpers']))
1773
- $found['helpers'] = array();
1774
- $found['helpers'][] = esc_textarea($params['name']);
1775
- }
1776
- }
1777
- if (true===$output) {
1778
- if (!empty($found)) {
1779
- echo '<br /><div id="message" class="updated fade">';
1780
- echo '<h3 style="margin-top:10px;">Package Imported:</h3>';
1781
- if (isset($found['pods'])) {
1782
- echo '<h4>Pod(s)</h4>';
1783
- echo '<ul class="pretty"><li>' . implode('</li><li>', $found['pods']) . '</li></ul>';
1784
- }
1785
- if (isset($found['templates'])) {
1786
- echo '<h4>Template(s)</h4>';
1787
- echo '<ul class="pretty"><li>' . implode('</li><li>', $found['templates']) . '</li></ul>';
1788
- }
1789
- if (isset($found['pod_pages'])) {
1790
- echo '<h4>Pod Page(s)</h4>';
1791
- echo '<ul class="pretty"><li>' . implode('</li><li>', $found['pod_pages']) . '</li></ul>';
1792
- }
1793
- if (isset($found['helpers'])) {
1794
- echo '<h4>Helper(s)</h4>';
1795
- echo '<ul class="pretty"><li>' . implode('</li><li>', $found['helpers']) . '</li></ul>';
1796
- }
1797
- echo '</div>';
1798
- }
1799
- else
1800
- echo '<e><br /><div id="message" class="error fade"><p>Error: Package not imported, try again.</p></div></e>';
1801
- }
1802
- if (!empty($found))
1803
- return true;
1804
- return false;
1805
- }
1806
-
1807
- /**
1808
- * Validate a package
1809
- *
1810
- *
1811
- * @param mixed $data (optional) An associative array containing a package, or the json encoded package
1812
- * @since 1.9.0
1813
- */
1814
- function validate_package($data = false, $output = false) {
1815
- if (is_array($data)&&isset($data['data'])) {
1816
- $data = $data['data'];
1817
- $output = true;
1818
- }
1819
- if (is_array($data))
1820
- $data = esc_textarea(json_encode($data));
1821
-
1822
- $found = array();
1823
- $warnings = array();
1824
-
1825
- update_option('pods_package', $data);
1826
-
1827
- $json_data = @json_decode($data, true);
1828
- if (!is_array($json_data))
1829
- $json_data = @json_decode(stripslashes($data), true);
1830
-
1831
- if (!is_array($json_data) || empty($json_data)) {
1832
- $warnings[] = "This is not a valid package. Please try again.";
1833
- if (true===$output) {
1834
- echo '<e><br /><div id="message" class="error fade"><p>This is not a valid package. Please try again.</p></div></e>';
1835
- return false;
1836
- }
1837
- else
1838
- return $warnings;
1839
- }
1840
- $data = $json_data;
1841
-
1842
- if (0 < strlen($data['meta']['version']) && false === strpos($data['meta']['version'], '.') && (int) $data['meta']['version'] < 1000) { // older style
1843
- $data['meta']['version'] = implode('.', str_split($data['meta']['version']));
1844
- }
1845
- elseif (0 < strlen($data['meta']['version']) && false === strpos($data['meta']['version'], '.')) { // old style
1846
- $data['meta']['version'] = pods_version_to_point($data['meta']['version']);
1847
- }
1848
-
1849
- if (isset($data['meta']['compatible_from'])) {
1850
- if (0 < strlen($data['meta']['compatible_from']) && false === strpos($data['meta']['compatible_from'], '.')) { // old style
1851
- $data['meta']['compatible_from'] = pods_version_to_point($data['meta']['compatible_from']);
1852
- }
1853
- if (version_compare(PODS_VERSION, $data['meta']['compatible_from'], '<')) {
1854
- $compatible_from = explode('.', $data['meta']['compatible_from']);
1855
- $compatible_from = $compatible_from[0] . '.' . $compatible_from[1];
1856
- $pods_version = explode('.', PODS_VERSION);
1857
- $pods_version = $pods_version[0] . '.' . $pods_version[1];
1858
- if (version_compare($pods_version, $compatible_from, '<'))
1859
- $warnings['version'] = 'This package may only compatible with the newer <strong>Pods ' . pods_version_to_point($data['meta']['compatible_from']) . '+</strong>, but you are currently running the older <strong>Pods ' . PODS_VERSION . '</strong><br />Unless the package author has specified it is compatible, it may not have been tested to work with your installed version of Pods.';
1860
- }
1861
- }
1862
- if (isset($data['meta']['compatible_to'])) {
1863
- if (0 < strlen($data['meta']['compatible_to']) && false === strpos($data['meta']['compatible_to'], '.')) { // old style
1864
- $data['meta']['compatible_to'] = pods_version_to_point($data['meta']['compatible_to']);
1865
- }
1866
- if (version_compare($data['meta']['compatible_to'], PODS_VERSION, '<')) {
1867
- $compatible_to = explode('.', $data['meta']['compatible_to']);
1868
- $compatible_to = $compatible_to[0] . '.' . $compatible_to[1];
1869
- $pods_version = explode('.', PODS_VERSION);
1870
- $pods_version = $pods_version[0] . '.' . $pods_version[1];
1871
- if (version_compare($compatible_to, $pods_version, '<'))
1872
- $warnings['version'] = 'This package may only compatible with the older <strong>Pods ' . $data['meta']['compatible_to'] . '</strong>, but you are currently running the newer <strong>Pods ' . PODS_VERSION . '</strong><br />Unless the package author has specified it is compatible, it may not have been tested to work with your installed version of Pods.';
1873
- }
1874
- }
1875
- if (!isset($data['meta']['compatible_from']) && !isset($data['meta']['compatible_to'])) {
1876
- if (version_compare(PODS_VERSION, $data['meta']['version'], '<')) {
1877
- $compatible_from = explode('.', $data['meta']['version']);
1878
- $compatible_from = $compatible_from[0] . '.' . $compatible_from[1];
1879
- $pods_version = explode('.', PODS_VERSION);
1880
- $pods_version = $pods_version[0] . '.' . $pods_version[1];
1881
- if (version_compare($pods_version, $compatible_from, '<'))
1882
- $warnings['version'] = 'This package was built using the newer <strong>Pods ' . $data['meta']['version'] . '</strong>, but you are currently running the older <strong>Pods ' . PODS_VERSION . '</strong><br />Unless the package author has specified it is compatible, it may not have been tested to work with your installed version of Pods.';
1883
- }
1884
- elseif (version_compare($data['meta']['version'], PODS_VERSION, '<')) {
1885
- $compatible_to = explode('.', $data['meta']['version']);
1886
- $compatible_to = $compatible_to[0] . '.' . $compatible_to[1];
1887
- $pods_version = explode('.', PODS_VERSION);
1888
- $pods_version = $pods_version[0] . '.' . $pods_version[1];
1889
- if (version_compare($compatible_to, $pods_version, '<'))
1890
- $warnings['version'] = 'This package was built using the older <strong>Pods ' . $data['meta']['version'] . '</strong>, but you are currently running the newer <strong>Pods ' . PODS_VERSION . '</strong><br />Unless the package author has specified it is compatible, it may not have been tested to work with your installed version of Pods.';
1891
- }
1892
- }
1893
-
1894
- if (isset($data['pods'])) {
1895
- foreach ($data['pods'] as $pod) {
1896
- $pod = pods_sanitize($pod);
1897
- $existing = $this->load_pod(array('name' => $pod['name']));
1898
- if (is_array($existing)) {
1899
- if (!isset($warnings['pods']))
1900
- $warnings['pods'] = array();
1901
- $warnings['pods'][] = esc_textarea($pod['name']);
1902
- }
1903
- if (!isset($found['pods']))
1904
- $found['pods'] = array();
1905
- $found['pods'][] = esc_textarea($pod['name']);
1906
- }
1907
- }
1908
-
1909
- if (isset($data['templates'])) {
1910
- foreach ($data['templates'] as $template) {
1911
- $template = pods_sanitize($template);
1912
- $existing = $this->load_template(array('name' => $template['name']));
1913
- if (is_array($existing)) {
1914
- if (!isset($warnings['templates']))
1915
- $warnings['templates'] = array();
1916
- $warnings['templates'][] = esc_textarea($template['name']);
1917
- }
1918
- if (!isset($found['templates']))
1919
- $found['templates'] = array();
1920
- $found['templates'][] = esc_textarea($template['name']);
1921
- }
1922
- }
1923
-
1924
- if (isset($data['pod_pages'])) {
1925
- foreach ($data['pod_pages'] as $pod_page) {
1926
- $pod_page = pods_sanitize($pod_page);
1927
- $existing = $this->load_page(array('uri' => $pod_page['uri']));
1928
- if (is_array($existing)) {
1929
- if (!isset($warnings['pod_pages']))
1930
- $warnings['pod_pages'] = array();
1931
- $warnings['pod_pages'][] = esc_textarea($pod_page['uri']);
1932
- }
1933
- if (!isset($found['pod_pages']))
1934
- $found['pod_pages'] = array();
1935
- $found['pod_pages'][] = esc_textarea($pod_page['uri']);
1936
- }
1937
- }
1938
-
1939
- if (isset($data['helpers'])) {
1940
- foreach ($data['helpers'] as $helper) {
1941
- $helper = pods_sanitize($helper);
1942
- $existing = $this->load_helper(array('name' => $helper['name']));
1943
- if (is_array($existing)) {
1944
- if (!isset($warnings['helpers']))
1945
- $warnings['helpers'] = array();
1946
- $warnings['helpers'][] = esc_textarea($helper['name']);
1947
- }
1948
- if (!isset($found['helpers']))
1949
- $found['helpers'] = array();
1950
- $found['helpers'][] = esc_textarea($helper['name']);
1951
- }
1952
- }
1953
-
1954
- if (true===$output) {
1955
- if (!empty($found)) {
1956
- echo '<hr />';
1957
- echo '<h3>Package Contents:</h3>';
1958
- if (isset($warnings['version']))
1959
- echo '<p><em><strong>NOTICE:</strong> ' . $warnings['version'] . '</em></p>';
1960
- if (isset($found['pods'])) {
1961
- echo '<h4>Pod(s)</h4>';
1962
- echo '<ul class="pretty"><li>' . implode('</li><li>', $found['pods']) . '</li></ul>';
1963
- }
1964
- if (isset($found['templates'])) {
1965
- echo '<h4>Template(s)</h4>';
1966
- echo '<ul class="pretty"><li>' . implode('</li><li>', $found['templates']) . '</li></ul>';
1967
- }
1968
- if (isset($found['pod_pages'])) {
1969
- echo '<h4>Pod Page(s)</h4>';
1970
- echo '<ul class="pretty"><li>' . implode('</li><li>', $found['pod_pages']) . '</li></ul>';
1971
- }
1972
- if (isset($found['helpers'])) {
1973
- echo '<h4>Helper(s)</h4>';
1974
- echo '<ul class="pretty"><li>' . implode('</li><li>', $found['helpers']) . '</li></ul>';
1975
- }
1976
- }
1977
- if (0 < count($warnings) && (!isset($warnings['version']) || 1 < count($warnings))) {
1978
- echo '<hr />';
1979
- echo '<h3 class="red">WARNING: There are portions of this package that already exist</h3>';
1980
- if (isset($warnings['pods'])) {
1981
- echo '<h4>Pod(s)</h4>';
1982
- echo '<ul class="pretty"><li>' . implode('</li><li>', $warnings['pods']) . '</li></ul>';
1983
- }
1984
- if (isset($warnings['templates'])) {
1985
- echo '<h4>Template(s)</h4>';
1986
- echo '<ul class="pretty"><li>' . implode('</li><li>', $warnings['templates']) . '</li></ul>';
1987
- }
1988
- if (isset($warnings['pod_pages'])) {
1989
- echo '<h4>Pod Page(s)</h4>';
1990
- echo '<ul class="pretty"><li>' . implode('</li><li>', $warnings['pod_pages']) . '</li></ul>';
1991
- }
1992
- if (isset($warnings['helpers'])) {
1993
- echo '<h4>Helper(s)</h4>';
1994
- echo '<ul class="pretty"><li>' . implode('</li><li>', $warnings['helpers']) . '</li></ul>';
1995
- }
1996
- echo '<p><input type="button" class="button-primary" style="background:#f39400;border-color:#d56500;" onclick="podsImport(\'replace_package\')" value=" Overwrite the existing package (Step 2 of 2) " />&nbsp;&nbsp;&nbsp;<input type="button" class="button-secondary" onclick="podsImportCancel()" value=" Cancel " /></p>';
1997
- return false;
1998
- }
1999
- elseif (!empty($found)) {
2000
- echo '<p><input type="button" class="button-primary" onclick="podsImport(\'import_package\')" value=" Import Package (Step 2 of 2) " />&nbsp;&nbsp;&nbsp;<input type="button" class="button-secondary" onclick="podsImportCancel()" value=" Cancel " /></p>';
2001
- return false;
2002
- }
2003
- echo '<e><br /><div id="message" class="error fade"><p>Error: This package is empty, there is nothing to import.</p></div></e>';
2004
- return false;
2005
- }
2006
- if (0 < count($warnings))
2007
- return $warnings;
2008
- elseif (!empty($found))
2009
- return true;
2010
- return false;
2011
- }
2012
-
2013
- /**
2014
- * Import data
2015
- *
2016
- * @param mixed $data PHP associative array or CSV input
2017
- * @param bool $numeric_mode Use IDs instead of the name field when matching
2018
- * @since 1.7.1
2019
- */
2020
- function import($data, $numeric_mode = false) {
2021
- global $wpdb;
2022
- if ('csv' == $this->format) {
2023
- $data = $this->csv_to_php($data);
2024
- }
2025
-
2026
- pod_query("SET NAMES utf8");
2027
- pod_query("SET CHARACTER SET utf8");
2028
-
2029
- // Get the id/name pairs of all associated pick/file tables
2030
- $pick_values = $file_values = array();
2031
- foreach ($this->fields as $field_name => $field_data) {
2032
- $pickval = $field_data['pickval'];
2033
- if ('file' == $field_data['coltype']) {
2034
- $res = pod_query("SELECT ID as id, guid as name FROM $wpdb->posts WHERE post_type = 'attachment' ORDER BY id");
2035
- while ($item = pods_mysql_fetch_assoc($res)) {
2036
- $file_url = str_replace(get_bloginfo('url'), '', $item['name']);
2037
- $file_values[$field_name][$file_url] = $item['id'];
2038
- $file_values[$field_name][$item['name']] = $item['id'];
2039
- }
2040
- }
2041
- elseif ('pick' == $field_data['coltype']) {
2042
- if ('wp_taxonomy' == $pickval) {
2043
- $res = pod_query("SELECT term_id AS id, name FROM $wpdb->terms ORDER BY id");
2044
- while ($item = pods_mysql_fetch_assoc($res)) {
2045
- $pick_values[$field_name][$item['name']] = $item['id'];
2046
- }
2047
- }
2048
- elseif ('wp_page' == $pickval || 'wp_post' == $pickval) {
2049
- $pickval = str_replace('wp_', '', $pickval);
2050
- $res = pod_query("SELECT ID as id, post_title as name FROM $wpdb->posts WHERE post_type = '$pickval' ORDER BY id");
2051
- while ($item = pods_mysql_fetch_assoc($res)) {
2052
- $pick_values[$field_name][$item['name']] = $item['id'];
2053
- }
2054
- }
2055
- elseif ('wp_user' == $pickval) {
2056
- $res = pod_query("SELECT ID as id, display_name as name FROM $wpdb->users ORDER BY id");
2057
- while ($item = pods_mysql_fetch_assoc($res)) {
2058
- $pick_values[$field_name][$item['name']] = $item['id'];
2059
- }
2060
- }
2061
- else {
2062
- $res = pod_query("SELECT id, name FROM @wp_pod_tbl_{$pickval} ORDER BY id");
2063
- while ($item = pods_mysql_fetch_assoc($res)) {
2064
- $pick_values[$field_name][$item['name']] = $item['id'];
2065
- }
2066
- }
2067
- }
2068
- }
2069
-
2070
- // Loop through the array of items
2071
- $ids = array();
2072
-
2073
- // Test to see if it's an array of arrays
2074
- foreach ($data as $key => $data_row) {
2075
- if(!is_array($data_row)){
2076
- $data = array($data);
2077
- }
2078
- break;
2079
- }
2080
- foreach ($data as $key => $data_row) {
2081
- $columns = array();
2082
-
2083
- // Loop through each field (use $this->fields so only valid columns get parsed)
2084
- foreach ($this->fields as $field_name => $field_data) {
2085
- $field_id = $field_data['id'];
2086
- $coltype = $field_data['coltype'];
2087
- $pickval = $field_data['pickval'];
2088
- $field_value = $data_row[$field_name];
2089
-
2090
- if (null != $field_value && false !== $field_value) {
2091
- if ('pick' == $coltype || 'file' == $coltype) {
2092
- $field_values = is_array($field_value) ? $field_value : array($field_value);
2093
- $pick_value = array();
2094
- foreach ($field_values as $key => $pick_title) {
2095
- if (is_int($pick_title) && false !== $numeric_mode) {
2096
- $pick_value[] = $pick_title;
2097
- }
2098
- elseif (!empty($pick_values[$field_name][$pick_title])) {
2099
- $pick_value[] = $pick_values[$field_name][$pick_title];
2100
- }
2101
- }
2102
- $field_value = implode(',',$pick_value);
2103
- }
2104
- $columns[$field_name] = esc_sql(trim($field_value));
2105
- }
2106
- }
2107
- if (!empty($columns)) {
2108
- $params = array('datatype'=>$this->dtname,'columns'=>$columns);
2109
- $ids[] = $this->save_pod_item($params);
2110
- }
2111
- }
2112
- return $ids;
2113
- }
2114
-
2115
- /**
2116
- * Export data
2117
- *
2118
- * @since 1.7.1
2119
- */
2120
- function export() {
2121
- global $wpdb;
2122
- $data = array();
2123
- $fields = array();
2124
- $pick_values = array();
2125
-
2126
- // Find all pick/file fields
2127
- $result = pod_query("SELECT id, name, coltype, pickval FROM @wp_pod_fields WHERE datatype = {$this->dt} ORDER BY weight");
2128
- while ($row = pods_mysql_fetch_assoc($result)) {
2129
- $field_id = $row['id'];
2130
- $field_name = $row['name'];
2131
- $coltype = $row['coltype'];
2132
- $pickval = $row['pickval'];
2133
-
2134
- // Store all pick/file values into an array
2135
- if ('file' == $coltype) {
2136
- $res = pod_query("SELECT ID AS id, guid AS name FROM $wpdb->posts WHERE post_type = 'attachment' ORDER BY id");
2137
- while ($item = pods_mysql_fetch_assoc($res)) {
2138
- $pick_values[$field_name][$item['id']] = $item['name'];
2139
- }
2140
- }
2141
- elseif ('pick' == $coltype) {
2142
- if ('wp_taxonomy' == $pickval) {
2143
- $res = pod_query("SELECT term_id AS id, name FROM $wpdb->terms ORDER BY id");
2144
- while ($item = pods_mysql_fetch_assoc($res)) {
2145
- $pick_values[$field_name][$item['id']] = $item['name'];
2146
- }
2147
- }
2148
- elseif ('wp_page' == $pickval || 'wp_post' == $pickval) {
2149
- $pickval = str_replace('wp_', '', $pickval);
2150
- $res = pod_query("SELECT ID as id, post_title as name FROM $wpdb->posts WHERE post_type = '$pickval' ORDER BY id");
2151
- while ($item = pods_mysql_fetch_assoc($res)) {
2152
- $pick_values[$field_name][$item['id']] = $item['name'];
2153
- }
2154
- }
2155
- elseif ('wp_user' == $pickval) {
2156
- $res = pod_query("SELECT ID as id, display_name as name FROM $wpdb->users ORDER BY id");
2157
- while ($item = pods_mysql_fetch_assoc($res)) {
2158
- $pick_values[$field_name][$item['id']] = $item['name'];
2159
- }
2160
- }
2161
- else {
2162
- $res = pod_query("SELECT id, name FROM @wp_pod_tbl_{$pickval} ORDER BY id");
2163
- while ($item = pods_mysql_fetch_assoc($res)) {
2164
- $pick_values[$field_name][$item['id']] = $item['name'];
2165
- }
2166
- }
2167
- }
2168
- $fields[$field_id] = $field_name;
2169
- }
2170
-
2171
- // Get all pick rel values
2172
- $sql = "
2173
- SELECT
2174
- p.tbl_row_id, r.field_id, r.tbl_row_id AS item_id
2175
- FROM
2176
- @wp_pod_rel r
2177
- INNER JOIN
2178
- @wp_pod p ON p.id = r.pod_id AND p.datatype = {$this->dt}
2179
- ORDER BY
2180
- p.tbl_row_id
2181
- ";
2182
- $result = pod_query($sql);
2183
- while ($row = pods_mysql_fetch_assoc($result)) {
2184
- $item_id = $row['item_id'];
2185
- $tbl_row_id = $row['tbl_row_id'];
2186
- $field_name = $fields[$row['field_id']];
2187
- $pick_array[$field_name][$tbl_row_id][] = $pick_values[$field_name][$item_id];
2188
- }
2189
-
2190
- // Access the current datatype
2191
- $result = pod_query("SELECT * FROM @wp_pod_tbl_{$this->dtname} ORDER BY id");
2192
- while ($row = pods_mysql_fetch_assoc($result)) {
2193
- $tmp = array();
2194
- $row_id = $row['id'];
2195
-
2196
- foreach ($fields as $junk => $fname) {
2197
- if (isset($pick_array[$fname][$row_id])) {
2198
- $tmp[$fname] = $pick_array[$fname][$row_id];
2199
- }
2200
- else {
2201
- $tmp[$fname] = $row[$fname];
2202
- }
2203
- }
2204
- $data[] = $tmp;
2205
- }
2206
- return $data;
2207
- }
2208
-
2209
- /**
2210
- * Convert CSV to a PHP array
2211
- *
2212
- * @param string $data The CSV input
2213
- * @since 1.7.1
2214
- */
2215
- function csv_to_php($data) {
2216
- $delimiter = ",";
2217
- $expr = "/$delimiter(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))/";
2218
- $data = str_replace("\r\n", "\n", $data);
2219
- $data = str_replace("\r", "\n", $data);
2220
- $lines = explode("\n", $data);
2221
- $field_names = explode($delimiter, array_shift($lines));
2222
- $field_names = preg_replace("/^\"(.*)\"$/s", "$1", $field_names);
2223
- foreach ($lines as $line) {
2224
- // Skip the empty line
2225
- if (empty($line)) continue;
2226
- $fields = preg_split($expr, trim($line));
2227
- $fields = preg_replace("/^\"(.*)\"$/s", "$1", $fields);
2228
- foreach ($field_names as $key => $field) {
2229
- $tmp[$field] = $fields[$key];
2230
- }
2231
- $out[] = $tmp;
2232
- }
2233
- return $out;
2234
- }
2235
-
2236
- /**
2237
- * Resync wp_pod and wp_pod_tbl_* tables
2238
- *
2239
- * wp_pod_tbl_* is assumed the primary source
2240
- * (if not found there, it'll get deleted from wp_pod)
2241
- *
2242
- * This might take a bit!
2243
- *
2244
- * @since 1.10.1
2245
- */
2246
- function fix_wp_pod() {
2247
- $result = pod_query("SELECT id, name FROM @wp_pod_types ORDER BY name");
2248
- while ($row = pods_mysql_fetch_array($result)) {
2249
- $id = (int) $row['id'];
2250
- $name = pods_sanitize($row['name']);
2251
- pod_query("DELETE p FROM `@wp_pod` AS p LEFT JOIN `@wp_pod_tbl_{$name}` AS t ON t.id = p.tbl_row_id WHERE p.datatype = {$id} AND t.id IS NULL");
2252
- pod_query("INSERT INTO `@wp_pod` (tbl_row_id, name, datatype, created, modified, author_id) SELECT t.id AS tbl_row_id, t.name AS name, {$id} AS datatype, '" . current_time('mysql') . "' AS created, '" . current_time('mysql') . "' AS modified, 0 AS author_id FROM `@wp_pod_tbl_{$name}` AS t LEFT JOIN `@wp_pod` AS p ON p.datatype = {$id} AND p.tbl_row_id = t.id WHERE p.id IS NULL");
2253
- }
2254
- }
2255
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/PodCache.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
- class PodCache
3
- {
4
- var $debug = false;
5
- var $cache_enabled = true;
6
- var $form_count = 0;
7
- var $results;
8
-
9
- /**
10
- * PodCache singleton
11
- *
12
- * @since 1.8.3
13
- */
14
- public static function instance()
15
- {
16
- static $instance = null;
17
- if (null == $instance)
18
- {
19
- $instance = new PodCache();
20
- }
21
- return $instance;
22
- }
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/PodInit.php DELETED
@@ -1,412 +0,0 @@
1
- <?php
2
- class PodInit
3
- {
4
- /**
5
- * Constructor - Pods Initialization
6
- *
7
- * @license http://www.gnu.org/licenses/gpl-2.0.html
8
- */
9
- function __construct() {
10
- global $pod_page_exists, $pods;
11
-
12
- // Activate and Install
13
- register_activation_hook(__FILE__, array($this, 'activate'));
14
- add_action('wpmu_new_blog', array($this, 'new_blog'), 10, 6);
15
-
16
- $installed = get_option('pods_version');
17
- if (0 < strlen($installed) && false === strpos($installed, '.'))
18
- $installed = pods_version_to_point($installed);
19
- if (version_compare($installed, PODS_VERSION, '<'))
20
- $this->setup();
21
- elseif (version_compare($installed, PODS_VERSION, '>')) {
22
- delete_option('pods_version');
23
- add_option('pods_version', PODS_VERSION);
24
- }
25
-
26
- add_action('init', array($this, 'init'));
27
- add_action('after_setup_theme', array($this, 'deprecated'));
28
- add_action('admin_menu', array($this, 'admin_menu'), 99);
29
- add_action('template_redirect', array($this, 'template_redirect'));
30
- add_action('delete_attachment', array($this, 'delete_attachment'));
31
- add_shortcode('pods', 'pods_shortcode');
32
-
33
- if (!defined('PODS_DISABLE_POD_PAGE_CHECK')) {
34
- $pod_page_exists = pod_page_exists();
35
-
36
- if (false !== $pod_page_exists) {
37
- add_action('wp_head', array($this, 'wp_head'));
38
- add_filter('redirect_canonical', array($this, 'kill_redirect'));
39
- add_filter('wp_title', array($this, 'wp_title'), 0, 3);
40
- add_filter('body_class', array($this, 'body_class'), 0, 1);
41
- add_filter('status_header', array($this, 'status_header'));
42
- if (defined('PODS_PAGE_PRECODE_TIMING') && false !== PODS_PAGE_PRECODE_TIMING)
43
- add_action('after_setup_theme', array($this, 'precode'));
44
- else
45
- add_action('plugins_loaded', array($this, 'precode'));
46
- add_action('wp', array($this, 'silence_404'));
47
- }
48
- }
49
- }
50
-
51
- function activate () {
52
- global $wpdb;
53
- if (function_exists('is_multisite') && is_multisite() && isset($_GET['networkwide']) && 1 == $_GET['networkwide']) {
54
- $blogids = $wpdb->get_col($wpdb->prepare("SELECT blog_id FROM $wpdb->blogs"));
55
- foreach ($blogids as $blogid)
56
- $this->setup($blogid);
57
- }
58
- else
59
- $this->setup();
60
- }
61
-
62
- function new_blog ($blogid, $user_id, $domain, $path, $site_id, $meta) {
63
- if (function_exists('is_multisite') && is_multisite() && is_plugin_active_for_network('pods/init.php'))
64
- $this->setup($blogid);
65
- }
66
-
67
- function setup ($blogid = null) {
68
- global $wpdb;
69
- if (null !== $blogid && $blogid != $wpdb->blogid) {
70
- $old_blogid = $wpdb->blogid;
71
- switch_to_blog($blogid);
72
- }
73
- // Setup DB tables
74
- $installed = get_option('pods_version');
75
- if (0 < strlen($installed) && false === strpos($installed, '.'))
76
- $installed = pods_version_to_point($installed);
77
- if (0 < strlen($installed)) {
78
- if (version_compare($installed, PODS_VERSION, '<')) {
79
- do_action('pods_update', PODS_VERSION, $installed, $blogid);
80
- if (null === apply_filters('pods_update_run', null, PODS_VERSION, $installed, $blogid) && !isset($_GET['pods_bypass_update']))
81
- include(PODS_DIR . '/sql/update.php');
82
- do_action('pods_update_post', PODS_VERSION, $installed, $blogid);
83
- }
84
- }
85
- else {
86
- do_action('pods_install', PODS_VERSION, $installed, $blogid);
87
- if (null === apply_filters('pods_install_run', null, PODS_VERSION, $installed, $blogid) && !isset($_GET['pods_bypass_install'])) {
88
- $sql = file_get_contents(PODS_DIR . '/sql/dump.sql');
89
- $sql = str_replace("\r", "\n", $sql);
90
- $sql = str_replace("\n\n", "\n", $sql);
91
- $sql = apply_filters('pods_install_sql', $sql, PODS_VERSION, $installed, $blogid);
92
- $charset_collate = 'DEFAULT CHARSET utf8';
93
- if (!empty($wpdb->charset))
94
- $charset_collate = "DEFAULT CHARSET {$wpdb->charset}";
95
- if (!empty($wpdb->collate))
96
- $charset_collate .= " COLLATE {$wpdb->collate}";
97
- if ('DEFAULT CHARSET utf8' != $charset_collate)
98
- $sql = str_replace('DEFAULT CHARSET utf8', $charset_collate, $sql);
99
- $sql = explode(";\n", str_replace('wp_', '@wp_', $sql));
100
- for ($i = 0, $z = count($sql); $i < $z; $i++) {
101
- $sql[$i] = trim($sql[$i]);
102
- if (empty($sql[$i]))
103
- continue;
104
- pod_query($sql[$i], 'Cannot setup SQL tables');
105
- }
106
- }
107
- delete_option('pods_version');
108
- add_option('pods_version', PODS_VERSION);
109
- do_action('pods_install_post', PODS_VERSION, $installed, $blogid);
110
- }
111
- if (null !== $blogid && $blogid != $wpdb->blogid)
112
- switch_to_blog($old_blogid);
113
- }
114
-
115
- function init() {
116
- // Session start
117
- if (((defined('WP_DEBUG') && WP_DEBUG) || false === headers_sent()) && '' == session_id())
118
- @session_start();
119
-
120
- // Load necessary JS
121
- wp_register_script('jqmodal', PODS_URL . '/ui/js/jqmodal.js', array('jquery'));
122
- wp_register_script('pods-ui', PODS_URL . '/ui/js/pods.ui.js', array('jquery', 'jqmodal'));
123
-
124
- $additional_settings = array('pods_disable_file_browser' => 0,
125
- 'pods_files_require_login' => 1,
126
- 'pods_files_require_login_cap' => '',
127
- 'pods_disable_file_upload' => 0,
128
- 'pods_upload_require_login' => 1,
129
- 'pods_upload_require_login_cap' => '',
130
- 'pods_page_precode_timing' => 0);
131
- foreach ($additional_settings as $additional_setting => $setting) {
132
- $setting = get_option($additional_setting, false);
133
- if ( false !== $setting )
134
- $additional_settings[$additional_setting] = $setting;
135
- }
136
- foreach ($additional_settings as $additional_setting => $setting) {
137
- if (0 == $setting)
138
- $setting = false;
139
- elseif (1 == $setting)
140
- $setting = true;
141
- if ( in_array($additional_setting, array('pods_files_require_login', 'pods_upload_require_login') ) ) {
142
- if ( 0 < strlen($additional_settings[$additional_setting.'_cap'] ) )
143
- $setting = $additional_settings[$additional_setting.'_cap'];
144
- }
145
- elseif ( in_array($additional_setting, array('pods_files_require_login_cap', 'pods_upload_require_login_cap') ) )
146
- continue;
147
- if (!defined(strtoupper($additional_setting)))
148
- define(strtoupper($additional_setting), $setting);
149
- }
150
- }
151
-
152
- function precode() {
153
- global $pods, $pod_page_exists;
154
-
155
- $function_or_file = str_replace('*', 'w', $pod_page_exists['uri']);
156
- $check_function = false;
157
- $check_file = 'precode-' . $function_or_file;
158
- if ((!defined('PODS_STRICT_MODE') || !PODS_STRICT_MODE) && (!defined('PODS_PAGE_FILES') || !PODS_PAGE_FILES))
159
- $check_file = false;
160
- if (false !== $check_function && false !== $check_file)
161
- $function_or_file = pods_function_or_file($function_or_file, $check_function, 'page', $check_file);
162
- else
163
- $function_or_file = false;
164
-
165
- $content = false;
166
- if (!$function_or_file && 0 < strlen(trim($pod_page_exists['precode'])))
167
- $content = $pod_page_exists['precode'];
168
-
169
- if (false === $content && false !== $function_or_file && isset($function_or_file['file']))
170
- locate_template($function_or_file['file'], true, true);
171
- elseif (false !== $content) {
172
- if (!defined('PODS_DISABLE_EVAL') || PODS_DISABLE_EVAL)
173
- eval("?>$content");
174
- }
175
-
176
- do_action( 'pods_page_precode', $pod_page_exists, $pods );
177
- do_action( 'pods_page_precode_' . $pod_page_exists[ 'uri' ], $pod_page_exists, $pods );
178
-
179
- if (!is_object($pods) && (404 == $pods || is_wp_error($pods))) {
180
- remove_action('template_redirect', array($this, 'template_redirect'));
181
- remove_action('wp_head', array($this, 'wp_head'));
182
- remove_filter('redirect_canonical', array($this, 'kill_redirect'));
183
- remove_filter('wp_title', array($this, 'wp_title'));
184
- remove_filter('body_class', array($this, 'body_class'));
185
- remove_filter('status_header', array($this, 'status_header'));
186
- remove_action('wp', array($this, 'silence_404'));
187
- }
188
- }
189
-
190
- function admin_menu() {
191
- $submenu = array();
192
- $result = pod_query("SELECT name, label, is_toplevel FROM @wp_pod_types ORDER BY label, name");
193
- while ($row = pods_mysql_fetch_array($result)) {
194
- $name = apply_filters('pods_admin_menu_name', $row['name'], $row);
195
- $label = trim($row['label']);
196
- $label = ('' != $label) ? $label : $name;
197
- $label = apply_filters('pods_admin_menu_label', $label, $row);
198
- $row['name'] = $name;
199
- $row['label'] = $label;
200
- if (pods_access("pod_{$name}")) {
201
- if (1 == $row['is_toplevel']) {
202
- add_object_page($label, $label, 'read', "pods-manage-$name");
203
- add_submenu_page("pods-manage-$name", 'Edit', 'Edit', 'read', "pods-manage-$name", array($this, 'pods_content_page'));
204
- add_submenu_page("pods-manage-$name", 'Add New', 'Add New', 'read', "pods-add-$name", array($this, 'pods_content_page'));
205
- }
206
- else {
207
- $submenu[trim($row['label'].$row['name'])] = $row;
208
- }
209
- }
210
- }
211
- $priv_check = array('manage_pods','manage_templates','manage_pod_pages','manage_helpers','manage_roles','manage_settings','manage_content','manage_packages');
212
- if ((!defined('PODS_DISABLE_ADMIN_MENU') || !PODS_DISABLE_ADMIN_MENU) && (!empty($submenu) || pods_access($priv_check))) {
213
- add_object_page('Pods', 'Pods', 'read', 'pods', null, PODS_URL.'/ui/images/icon16.png');
214
- if (pods_access(array('manage_pods','manage_templates','manage_pod_pages','manage_helpers','manage_roles','manage_settings'))) {
215
- add_submenu_page('pods', 'Setup', 'Setup', 'read', 'pods', array($this, 'pods_setup_page'));
216
- }
217
- if (pods_access('manage_packages')) {
218
- add_submenu_page('pods', 'Package Manager', 'Package Manager', 'read', 'pods-package', array($this, 'pods_packages_page'));
219
- }
220
- if (pods_access('manage_content')) {
221
- add_submenu_page('pods', 'Manage Content', 'Manage Content', 'read', 'pods-manage', array($this, 'pods_content_page'));
222
- }
223
- ksort($submenu);
224
- foreach ($submenu as $item) {
225
- $name = apply_filters('pods_admin_submenu_name', $item['name'], $item);
226
- $label = trim($item['label']);
227
- $label = ('' != $label) ? $label : $name;
228
- $label = apply_filters('pods_admin_submenu_label', $label, $item);
229
- add_submenu_page('pods', "Add $label", "Add $label", 'read', "pod-$name", array($this, 'pods_content_page'));
230
- }
231
- }
232
- }
233
-
234
- function wp_head() {
235
- global $pods;
236
- do_action('pods_wp_head');
237
- if (!defined('PODS_DISABLE_VERSION_OUTPUT') || !PODS_DISABLE_VERSION_OUTPUT) {
238
- ?>
239
- <!-- Pods CMS <?php echo PODS_VERSION; ?> -->
240
- <?php
241
- }
242
- if ((!defined('PODS_DISABLE_META') || !PODS_DISABLE_META) && is_object($pods) && !is_wp_error($pods)) {
243
- if (isset($pods->meta) && is_array($pods->meta)) {
244
- foreach ($pods->meta as $name => $content) {
245
- if ('title' == $name)
246
- continue;
247
- ?>
248
- <meta name="<?php echo esc_attr($name); ?>" content="<?php echo esc_attr($content); ?>" />
249
- <?php
250
- }
251
- }
252
- if (isset($pods->meta_properties) && is_array($pods->meta_properties)) {
253
- foreach ($pods->meta_properties as $property => $content) {
254
- ?>
255
- <meta property="<?php echo esc_attr($property); ?>" content="<?php echo esc_attr($content); ?>" />
256
- <?php
257
- }
258
- }
259
- if (isset($pods->meta_extra) && 0 < strlen($pods->meta_extra))
260
- echo $pods->meta_extra;
261
- }
262
- }
263
-
264
- function kill_redirect() {
265
- return false;
266
- }
267
-
268
- function wp_title($title, $sep = '&raquo;', $seplocation = '') {
269
- global $pods, $pod_page_exists;
270
-
271
- $page_title = $pod_page_exists['title'];
272
-
273
- if (0 < strlen(trim($page_title))) {
274
- if (is_object($pods) && !is_wp_error($pods))
275
- $page_title = preg_replace_callback("/({@(.*?)})/m", array($pods, "parse_magic_tags"), $page_title);
276
- $title = $page_title . " " . $sep . " ";
277
- if ('right' == $seplocation)
278
- $title = " " . $sep . " " . $page_title;
279
- }
280
- else {
281
- $home_path = @parse_url(home_url());
282
- if ( empty( $home_path ) )
283
- $home_path = parse_url( pods_get_current_url() );
284
- if ( !isset( $home_path[ 'path' ] ) )
285
- $home_path[ 'path' ] = '/';
286
- $uri = preg_replace('|^' . preg_quote($home_path['path'], '|') . '|', '', $_SERVER['REQUEST_URI']);
287
- $uri = explode('?', $uri);
288
- $uri = preg_replace("@^([/]?)(.*?)([/]?)$@", "$2", $uri[0]);
289
- $uri = preg_replace("@(-|_)@", " ", $uri);
290
- $uri = explode('/', $uri);
291
-
292
- $title = '';
293
- foreach ($uri as $page_title) {
294
- $title .= ('right' == $seplocation) ? ucwords($page_title) . " $sep " : " $sep " . ucwords($page_title);
295
- }
296
- }
297
- if ((!defined('PODS_DISABLE_META') || !PODS_DISABLE_META) && is_object($pods) && !is_wp_error($pods) && isset($pods->meta) && is_array($pods->meta) && isset($pods->meta['title']))
298
- $title = $pods->meta['title'];
299
- return apply_filters('pods_title', $title, $sep, $seplocation);
300
- }
301
-
302
- function body_class($classes) {
303
- global $pods, $pod_page_exists;
304
- $classes[] = 'pods';
305
- $uri = explode('?',$pod_page_exists['uri']);
306
- $uri = explode('#',$uri[0]);
307
- $classes[] = 'pod-page-'.trim(str_replace('--','-',str_replace('--','-',str_replace('_','-',sanitize_title(str_replace('/','-',str_replace('*','_w_',$uri[0])))))), '-');
308
- if (is_object($pods) && !is_wp_error($pods)) {
309
- $classes[] = 'pod-'.trim(str_replace('--','-',str_replace('_','-',$pods->datatype)), '-');
310
- }
311
- if ((!defined('PODS_DISABLE_BODY_CLASSES') || !PODS_DISABLE_BODY_CLASSES) && is_object($pods) && !is_wp_error($pods) && isset($pods->body_classes))
312
- $classes[] = $pods->body_classes;
313
- return apply_filters('pods_body_class', $classes, $uri);
314
- }
315
-
316
- function status_header() {
317
- return $_SERVER['SERVER_PROTOCOL'] . ' 200 OK';
318
- }
319
-
320
- function silence_404() {
321
- global $wp_query;
322
- $wp_query->query_vars['error'] = '';
323
- $wp_query->is_404 = false;
324
- }
325
-
326
- function template_redirect() {
327
- global $pods, $pod_page_exists;
328
-
329
- if (false !== $pod_page_exists) {
330
- /*
331
- * Create pods.php in your theme directory, and
332
- * style it to suit your needs. Some helpful functions:
333
- *
334
- * get_header()
335
- * pods_content()
336
- * get_sidebar()
337
- * get_footer()
338
- */
339
- $template = $pod_page_exists['page_template'];
340
- $template = apply_filters('pods_page_template', $template, $pod_page_exists);
341
-
342
- $render_function = apply_filters('pods_template_redirect', 'false', $template, $pod_page_exists);
343
-
344
- do_action('pods_page', $template, $pod_page_exists);
345
- if (is_callable($render_function))
346
- call_user_func($render_function);
347
- elseif ((!defined('PODS_DISABLE_DYNAMIC_TEMPLATE') || !PODS_DISABLE_DYNAMIC_TEMPLATE) && is_object($pods) && !is_wp_error($pods) && isset($pods->page_template) && !empty($pods->page_template) && '' != locate_template(array($pods->page_template), true)) {
348
- $template = $pods->page_template;
349
- // found the template and included it, we're good to go!
350
- }
351
- elseif (!empty($pod_page_exists['page_template']) && '' != locate_template(array($pod_page_exists['page_template']), true)) {
352
- $template = $pod_page_exists['page_template'];
353
- // found the template and included it, we're good to go!
354
- }
355
- elseif ('' != locate_template(apply_filters('pods_page_default_templates', array('pods.php')), true)) {
356
- $template = 'pods.php';
357
- // found the template and included it, we're good to go!
358
- }
359
- else {
360
- // templates not found in theme, default output
361
- do_action('pods_page_default', $template, $pod_page_exists);
362
- get_header();
363
- pods_content();
364
- get_sidebar();
365
- get_footer();
366
- }
367
- do_action('pods_page_end', $template, $pod_page_exists);
368
- exit;
369
- }
370
- }
371
-
372
- function delete_attachment($attachment_id) {
373
- $result = pod_query("SELECT id FROM @wp_pod_fields WHERE coltype = 'file'");
374
- if (0 < pods_mysql_num_rows($result)) {
375
- while ($row = pods_mysql_fetch_assoc($result)) {
376
- $field_ids[] = $row['id'];
377
- }
378
- $field_ids = implode(',', $field_ids);
379
-
380
- // Remove all references to the deleted attachment
381
- do_action('pods_delete_attachment', $attachment_id, $field_ids);
382
- pod_query("DELETE FROM @wp_pod_rel WHERE field_id IN ({$field_ids}) AND tbl_row_id = {$attachment_id}");
383
- }
384
- }
385
-
386
- function pods_setup_page() {
387
- if (!wp_script_is('jquery-ui-core', 'queue') && !wp_script_is('jquery-ui-core', 'to_do') && !wp_script_is('jquery-ui-core', 'done'))
388
- wp_print_scripts('jquery-ui-core');
389
- if (!wp_script_is('jquery-ui-sortable', 'queue') && !wp_script_is('jquery-ui-sortable', 'to_do') && !wp_script_is('jquery-ui-sortable', 'done'))
390
- wp_print_scripts('jquery-ui-sortable');
391
- if (null === apply_filters('pods_admin_setup', null))
392
- include PODS_DIR . '/ui/manage.php';
393
- }
394
-
395
- function pods_packages_page() {
396
- if (null === apply_filters('pods_admin_packages', null))
397
- include PODS_DIR . '/ui/manage_packages.php';
398
- }
399
-
400
- function pods_content_page() {
401
- if (!wp_script_is('jquery-ui-core', 'queue') && !wp_script_is('jquery-ui-core', 'to_do') && !wp_script_is('jquery-ui-core', 'done'))
402
- wp_print_scripts('jquery-ui-core');
403
- if (!wp_script_is('jquery-ui-sortable', 'queue') && !wp_script_is('jquery-ui-sortable', 'to_do') && !wp_script_is('jquery-ui-sortable', 'done'))
404
- wp_print_scripts('jquery-ui-sortable');
405
- if (null === apply_filters('pods_admin_content', null))
406
- include PODS_DIR . '/ui/manage_content.php';
407
- }
408
-
409
- function deprecated() {
410
- require_once(PODS_DIR . '/deprecated.php'); // DEPRECATED IN 2.0
411
- }
412
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/Pods.php ADDED
@@ -0,0 +1,3971 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Pods
4
+ */
5
+ class Pods implements Iterator {
6
+
7
+ /**
8
+ * @var bool
9
+ */
10
+ private $iterator = false;
11
+
12
+ /**
13
+ * @var PodsAPI
14
+ */
15
+ public $api;
16
+
17
+ /**
18
+ * @var PodsData
19
+ */
20
+ public $data;
21
+
22
+ /**
23
+ * @var PodsData
24
+ */
25
+ public $alt_data;
26
+
27
+ /**
28
+ * @var array Array of pod item arrays
29
+ */
30
+ public $rows = array();
31
+
32
+ /**
33
+ * @var array Current pod item array
34
+ */
35
+ public $row = array();
36
+
37
+ /**
38
+ * @var int
39
+ */
40
+ private $row_number = -1;
41
+
42
+ /**
43
+ * @var array Override pod item array
44
+ */
45
+ public $row_override = array();
46
+
47
+ /**
48
+ * @var bool
49
+ */
50
+ public $display_errors = true;
51
+
52
+ /**
53
+ * @var array|bool|mixed|null|void
54
+ */
55
+ public $pod_data;
56
+
57
+ /**
58
+ * @var array
59
+ */
60
+ public $params = array();
61
+
62
+ /**
63
+ * @var string
64
+ */
65
+ public $pod = '';
66
+
67
+ /**
68
+ * @var int
69
+ */
70
+ public $pod_id = 0;
71
+
72
+ /**
73
+ * @var array
74
+ */
75
+ public $fields = array();
76
+
77
+ /**
78
+ * @var array
79
+ */
80
+ public $filters = array();
81
+
82
+ /**
83
+ * @var string
84
+ */
85
+ public $detail_page;
86
+
87
+ /**
88
+ * @var int
89
+ */
90
+ public $id = 0;
91
+
92
+ /**
93
+ * @var int
94
+ */
95
+ public $limit = 15;
96
+
97
+ /**
98
+ * @var int
99
+ */
100
+ public $offset = 0;
101
+
102
+ /**
103
+ * @var string
104
+ */
105
+ public $page_var = 'pg';
106
+
107
+ /**
108
+ * @var int|mixed
109
+ */
110
+ public $page = 1;
111
+
112
+ /**
113
+ * @var bool
114
+ */
115
+ public $pagination = true;
116
+
117
+ /**
118
+ * @var bool
119
+ */
120
+ public $search = true;
121
+
122
+ /**
123
+ * @var string
124
+ */
125
+ public $search_var = 'search';
126
+
127
+ /**
128
+ * @var string
129
+ */
130
+ public $search_mode = 'int'; // int | text | text_like
131
+
132
+ /**
133
+ * @var int
134
+ */
135
+ public $total = 0;
136
+
137
+ /**
138
+ * @var int
139
+ */
140
+ public $total_found = 0;
141
+
142
+ /**
143
+ * @var array
144
+ */
145
+ public $ui = array();
146
+
147
+ /**
148
+ * @var mixed SEO related vars for Pod Pages
149
+ */
150
+ public $page_template;
151
+ public $body_classes;
152
+ public $meta = array();
153
+ public $meta_properties = array();
154
+ public $meta_extra = '';
155
+
156
+ /**
157
+ * @var string Last SQL query used by a find()
158
+ */
159
+ public $sql;
160
+
161
+ /**
162
+ * @var
163
+ */
164
+ public $deprecated;
165
+
166
+ public $datatype;
167
+
168
+ public $datatype_id;
169
+
170
+ /**
171
+ * Constructor - Pods Framework core
172
+ *
173
+ * @param string $pod The pod name
174
+ * @param mixed $id (optional) The ID or slug, to load a single record; Provide array of $params to run 'find'
175
+ *
176
+ * @return \Pods
177
+ *
178
+ * @license http://www.gnu.org/licenses/gpl-2.0.html
179
+ * @since 1.0.0
180
+ * @link http://pods.io/docs/pods/
181
+ */
182
+ public function __construct ( $pod = null, $id = null ) {
183
+ if ( null === $pod ) {
184
+ $queried_object = get_queried_object();
185
+
186
+ if ( $queried_object ) {
187
+ $id_lookup = true;
188
+
189
+ // Post Type Singular
190
+ if ( isset( $queried_object->post_type ) ) {
191
+ $pod = $queried_object->post_type;
192
+ }
193
+ // Term Archive
194
+ elseif ( isset( $queried_object->taxonomy ) ) {
195
+ $pod = $queried_object->taxonomy;
196
+ }
197
+ // Author Archive
198
+ elseif ( isset( $queried_object->user_login ) ) {
199
+ $pod = 'user';
200
+ }
201
+ // Post Type Archive
202
+ elseif ( isset( $queried_object->public ) && isset( $queried_object->name ) ) {
203
+ $pod = $queried_object->name;
204
+
205
+ $id_lookup = false;
206
+ }
207
+
208
+ if ( null === $id && $id_lookup ) {
209
+ $id = get_queried_object_id();
210
+ }
211
+ }
212
+ }
213
+
214
+ $this->api = pods_api( $pod );
215
+ $this->api->display_errors =& $this->display_errors;
216
+
217
+ $this->data = pods_data( $this->api, $id, false );
218
+ PodsData::$display_errors =& $this->display_errors;
219
+
220
+ // Set up page variable
221
+ if ( pods_strict( false ) ) {
222
+ $this->page = 1;
223
+ $this->pagination = false;
224
+ $this->search = false;
225
+ }
226
+ else {
227
+ // Get the page variable
228
+ $this->page = pods_var( $this->page_var, 'get' );
229
+ $this->page = ( empty( $this->page ) ? 1 : max( pods_absint( $this->page ), 1 ) );
230
+ }
231
+
232
+ // Set default pagination handling to on/off
233
+ if ( defined( 'PODS_GLOBAL_POD_PAGINATION' ) ) {
234
+ if ( !PODS_GLOBAL_POD_PAGINATION ) {
235
+ $this->page = 1;
236
+ $this->pagination = false;
237
+ }
238
+ else
239
+ $this->pagination = true;
240
+ }
241
+
242
+ // Set default search to on/off
243
+ if ( defined( 'PODS_GLOBAL_POD_SEARCH' ) ) {
244
+ if ( PODS_GLOBAL_POD_SEARCH )
245
+ $this->search = true;
246
+ else
247
+ $this->search = false;
248
+ }
249
+
250
+ // Set default search mode
251
+ $allowed_search_modes = array( 'int', 'text', 'text_like' );
252
+
253
+ if ( defined( 'PODS_GLOBAL_POD_SEARCH_MODE' ) && in_array( PODS_GLOBAL_POD_SEARCH_MODE, $allowed_search_modes ) )
254
+ $this->search_mode = PODS_GLOBAL_POD_SEARCH_MODE;
255
+
256
+ // Sync Settings
257
+ $this->data->page =& $this->page;
258
+ $this->data->limit =& $this->limit;
259
+ $this->data->pagination =& $this->pagination;
260
+ $this->data->search =& $this->search;
261
+ $this->data->search_mode =& $this->search_mode;
262
+
263
+ // Sync Pod Data
264
+ $this->api->pod_data =& $this->data->pod_data;
265
+ $this->pod_data =& $this->api->pod_data;
266
+ $this->api->pod_id =& $this->data->pod_id;
267
+ $this->pod_id =& $this->api->pod_id;
268
+ $this->datatype_id =& $this->pod_id;
269
+ $this->api->pod =& $this->data->pod;
270
+ $this->pod =& $this->api->pod;
271
+ $this->datatype =& $this->pod;
272
+ $this->api->fields =& $this->data->fields;
273
+ $this->fields =& $this->api->fields;
274
+ $this->detail_page =& $this->data->detail_page;
275
+ $this->id =& $this->data->id;
276
+ $this->row =& $this->data->row;
277
+ $this->rows =& $this->data->data;
278
+ $this->row_number =& $this->data->row_number;
279
+ $this->sql =& $this->data->sql;
280
+
281
+ if ( is_array( $id ) || is_object( $id ) )
282
+ $this->find( $id );
283
+ }
284
+
285
+ /**
286
+ * Whether this Pod object is valid or not
287
+ *
288
+ * @return bool
289
+ *
290
+ * @since 2.0
291
+ */
292
+ public function valid () {
293
+ if ( empty( $this->pod_id ) )
294
+ return false;
295
+
296
+ if ( $this->iterator )
297
+ return isset( $this->rows[ $this->row_number ] );
298
+
299
+ return true;
300
+ }
301
+
302
+ /**
303
+ * Check if in Iterator mode
304
+ *
305
+ * @return bool
306
+ *
307
+ * @since 2.3.4
308
+ *
309
+ * @link http://www.php.net/manual/en/class.iterator.php
310
+ */
311
+ public function is_iterator () {
312
+ return $this->iterator;
313
+ }
314
+
315
+ /**
316
+ * Turn off Iterator mode to off
317
+ *
318
+ * @return void
319
+ *
320
+ * @since 2.3.4
321
+ *
322
+ * @link http://www.php.net/manual/en/class.iterator.php
323
+ */
324
+ public function stop_iterator () {
325
+ $this->iterator = false;
326
+
327
+ return;
328
+ }
329
+
330
+ /**
331
+ * Rewind Iterator
332
+ *
333
+ * @return void|boolean
334
+ *
335
+ * @since 2.3.4
336
+ *
337
+ * @link http://www.php.net/manual/en/class.iterator.php
338
+ */
339
+ public function rewind () {
340
+ if ( $this->iterator ) {
341
+ $this->row_number = 0;
342
+
343
+ return;
344
+ }
345
+
346
+ return false;
347
+ }
348
+
349
+ /**
350
+ * Get current Iterator row
351
+ *
352
+ * @return mixed|boolean
353
+ *
354
+ * @since 2.3.4
355
+ *
356
+ * @link http://www.php.net/manual/en/class.iterator.php
357
+ */
358
+ public function current () {
359
+ if ( $this->iterator && $this->fetch() )
360
+ return $this;
361
+
362
+ return false;
363
+ }
364
+
365
+ /**
366
+ * Get current Iterator key
367
+ *
368
+ * @return int|boolean
369
+ *
370
+ * @since 2.3.4
371
+ *
372
+ * @link http://www.php.net/manual/en/class.iterator.php
373
+ */
374
+ public function key () {
375
+ if ( $this->iterator )
376
+ return $this->row_number;
377
+
378
+ return false;
379
+ }
380
+
381
+ /**
382
+ * Move onto the next Iterator row
383
+ *
384
+ * @return void|boolean
385
+ *
386
+ * @since 2.3.4
387
+ *
388
+ * @link http://www.php.net/manual/en/class.iterator.php
389
+ */
390
+ public function next () {
391
+ if ( $this->iterator ) {
392
+ $this->row_number++;
393
+
394
+ return;
395
+ }
396
+
397
+ return false;
398
+ }
399
+
400
+ /**
401
+ * Whether a Pod item exists or not when using fetch() or construct with an ID or slug
402
+ *
403
+ * @return bool
404
+ *
405
+ * @since 2.0
406
+ */
407
+ public function exists () {
408
+ if ( empty( $this->row ) )
409
+ return false;
410
+
411
+ return true;
412
+ }
413
+
414
+ /**
415
+ * Return an array of all rows returned from a find() call.
416
+ *
417
+ * Most of the time, you will want to loop through data using fetch()
418
+ * instead of using this function.
419
+ *
420
+ * @return array|bool An array of all rows returned from a find() call, or false if no items returned
421
+ *
422
+ * @since 2.0
423
+ * @link http://pods.io/docs/data/
424
+ */
425
+ public function data () {
426
+ do_action( 'pods_pods_data', $this );
427
+
428
+ if ( empty( $this->rows ) )
429
+ return false;
430
+
431
+ return (array) $this->rows;
432
+ }
433
+
434
+ /**
435
+ * Return a field input for a specific field
436
+ *
437
+ * @param string|array $field Field name or Field data array
438
+ * @param string $field Input field name to use (overrides default name)
439
+ * @param mixed $value Current value to use
440
+ *
441
+ * @return string Field Input HTML
442
+ *
443
+ * @since 2.3.10
444
+ */
445
+ public function input( $field, $input_name = null, $value = '__null' ) {
446
+
447
+ // Field data override
448
+ if ( is_array( $field ) ) {
449
+ $field_data = $field;
450
+ $field = pods_var_raw( 'name', $field );
451
+ }
452
+ // Get field data from field name
453
+ else {
454
+ $field_data = $this->fields( $field );
455
+ }
456
+
457
+ if ( !empty( $field_data ) ) {
458
+ $field_type = pods_var_raw( 'type', $field_data );
459
+
460
+ if ( empty( $input_name ) ) {
461
+ $input_name = $field;
462
+ }
463
+
464
+ if ( '__null' == $value ) {
465
+ $value = $this->field( array( 'name' => $field, 'in_form' => true ) );
466
+ }
467
+
468
+ return PodsForm::field( $input_name, $value, $field_type, $field_data, $this, $this->id() );
469
+ }
470
+
471
+ return '';
472
+
473
+ }
474
+
475
+ /**
476
+ * Return field array from a Pod, a field's data, or a field option
477
+ *
478
+ * @param null $field
479
+ * @param null $option
480
+ *
481
+ * @return bool|mixed
482
+ *
483
+ * @since 2.0
484
+ */
485
+ public function fields ( $field = null, $option = null ) {
486
+
487
+ $field_data = null;
488
+
489
+ if ( empty( $this->fields ) ) {
490
+ // No fields found
491
+ $field_data = array();
492
+ } elseif ( empty( $field ) ) {
493
+ // Return all fields
494
+ $field_data = (array) $this->fields;
495
+ } elseif ( ! isset( $this->fields[ $field ] ) && ! isset( $this->pod_data['object_fields'][ $field ] ) ) {
496
+ // Field not found
497
+ $field_data = array();
498
+ } elseif ( empty( $option ) ) {
499
+ // Return all field data
500
+ if ( isset( $this->fields[ $field ] ) ) {
501
+ $field_data = $this->fields[ $field ];
502
+ } elseif ( isset( $this->pod_data['object_fields'] ) ) {
503
+ $field_data = $this->pod_data['object_fields'][ $field ];
504
+ }
505
+ } else {
506
+ // Merge options
507
+ if ( isset( $this->fields[ $field ] ) ) {
508
+ $options = array_merge( $this->fields[ $field ], $this->fields[ $field ]['options'] );
509
+ } elseif ( isset( $this->pod_data['object_fields'] ) ) {
510
+ $options = array_merge( $this->pod_data['object_fields'][ $field ], $this->pod_data['object_fields'][ $field ]['options'] );
511
+ }
512
+
513
+ // Get a list of available items from a relationship field
514
+ if ( 'data' == $option && in_array( pods_var_raw( 'type', $options ), PodsForm::tableless_field_types() ) ) {
515
+ $field_data = PodsForm::field_method( 'pick', 'get_field_data', $options );
516
+ } // Return option
517
+ elseif ( isset( $options[ $option ] ) ) {
518
+ $field_data = $options[ $option ];
519
+ }
520
+ }
521
+
522
+ /**
523
+ * Modify the field data before returning
524
+ *
525
+ * @since unknown
526
+ *
527
+ * @param array $field_data The data for the field.
528
+ * @param string|null $field The specific field that data is being return for, if set when method is called or null.
529
+ * @param string|null $option Value of option param when method was called. Can be used to get a list of available items from a relationship field.
530
+ * @param Pods|object $this The current Pods class instance.
531
+ */
532
+ return apply_filters( 'pods_pods_fields', $field_data, $field, $option, $this );
533
+
534
+ }
535
+
536
+ /**
537
+ * Return row array for an item
538
+ *
539
+ * @return array
540
+ *
541
+ * @since 2.0
542
+ */
543
+ public function row () {
544
+ do_action( 'pods_pods_row', $this );
545
+
546
+ if ( !is_array( $this->row ) )
547
+ return false;
548
+
549
+ return (array) $this->row;
550
+ }
551
+
552
+ /**
553
+ * Return the output for a field. If you want the raw value for use in PHP for custom manipulation,
554
+ * you will want to use field() instead. This function will automatically convert arrays into a
555
+ * list of text such as "Rick, John, and Gary"
556
+ *
557
+ * @param string|array $name The field name, or an associative array of parameters
558
+ * @param boolean $single (optional) For tableless fields, to return an array or the first
559
+ *
560
+ * @return string|null|false The output from the field, null if the field doesn't exist, false if no value returned for tableless fields
561
+ * @since 2.0
562
+ * @link http://pods.io/docs/display/
563
+ */
564
+ public function display ( $name, $single = null ) {
565
+ $defaults = array(
566
+ 'name' => $name,
567
+ 'single' => $single,
568
+ 'display' => true,
569
+ 'serial_params' => null
570
+ );
571
+
572
+ if ( is_array( $name ) || is_object( $name ) ) {
573
+ $defaults[ 'name' ] = null;
574
+ $params = (object) array_merge( $defaults, (array) $name );
575
+ }
576
+ elseif ( is_array( $single ) || is_object( $single ) ) {
577
+ $defaults[ 'single' ] = null;
578
+ $params = (object) array_merge( $defaults, (array) $single );
579
+ }
580
+ else
581
+ $params = $defaults;
582
+
583
+ $params = (object) $params;
584
+
585
+ $value = $this->field( $params );
586
+
587
+ if ( is_array( $value ) ) {
588
+ $fields = $this->fields;
589
+
590
+ if ( isset( $this->pod_data[ 'object_fields' ] ) ) {
591
+ $fields = array_merge( $fields, $this->pod_data[ 'object_fields' ] );
592
+ }
593
+
594
+ $serial_params = array(
595
+ 'field' => $params->name,
596
+ 'fields' => $fields
597
+ );
598
+
599
+ if ( !empty( $params->serial_params ) && is_array( $params->serial_params ) )
600
+ $serial_params = array_merge( $serial_params, $params->serial_params );
601
+
602
+ $value = pods_serial_comma( $value, $serial_params );
603
+ }
604
+
605
+ return $value;
606
+ }
607
+
608
+ /**
609
+ * Return the raw output for a field If you want the raw value for use in PHP for custom manipulation,
610
+ * you will want to use field() instead. This function will automatically convert arrays into a
611
+ * list of text such as "Rick, John, and Gary"
612
+ *
613
+ * @param string|array $name The field name, or an associative array of parameters
614
+ * @param boolean $single (optional) For tableless fields, to return an array or the first
615
+ *
616
+ * @return string|null|false The output from the field, null if the field doesn't exist, false if no value returned for tableless fields
617
+ * @since 2.0
618
+ * @link http://pods.io/docs/display/
619
+ */
620
+ public function raw ( $name, $single = null ) {
621
+ $defaults = array(
622
+ 'name' => $name,
623
+ 'single' => $single,
624
+ 'raw' => true
625
+ );
626
+
627
+ if ( is_array( $name ) || is_object( $name ) ) {
628
+ $defaults[ 'name' ] = null;
629
+ $params = (object) array_merge( $defaults, (array) $name );
630
+ }
631
+ elseif ( is_array( $single ) || is_object( $single ) ) {
632
+ $defaults[ 'single' ] = null;
633
+ $params = (object) array_merge( $defaults, (array) $single );
634
+ }
635
+ else
636
+ $params = (object) $defaults;
637
+
638
+ $value = $this->field( $params );
639
+
640
+ return $value;
641
+ }
642
+
643
+ /**
644
+ * Return the value for a field.
645
+ *
646
+ * If you are getting a field for output in a theme, most of the time you will want to use display() instead.
647
+ *
648
+ * This function will return arrays for relationship and file fields.
649
+ *
650
+ * @param string|array $name The field name, or an associative array of parameters
651
+ * @param boolean $single (optional) For tableless fields, to return the whole array or the just the first item, or an associative array of parameters
652
+ * @param boolean $raw (optional) Whether to return the raw value, or to run through the field type's display method, or an associative array of parameters
653
+ *
654
+ * @return mixed|null Value returned depends on the field type, null if the field doesn't exist, false if no value returned for tableless fields
655
+ * @since 2.0
656
+ * @link http://pods.io/docs/field/
657
+ */
658
+ public function field ( $name, $single = null, $raw = false ) {
659
+
660
+ $defaults = array(
661
+ 'name' => $name,
662
+ 'orderby' => null,
663
+ 'single' => $single,
664
+ 'params' => null,
665
+ 'in_form' => false,
666
+ 'raw' => $raw,
667
+ 'raw_display' => false,
668
+ 'display' => false,
669
+ 'get_meta' => false,
670
+ 'output' => null,
671
+ 'deprecated' => false,
672
+ 'args' => array() // extra data to send to field handlers
673
+ );
674
+
675
+ if ( is_array( $name ) || is_object( $name ) ) {
676
+ $defaults[ 'name' ] = null;
677
+ $params = (object) array_merge( $defaults, (array) $name );
678
+ }
679
+ elseif ( is_array( $single ) || is_object( $single ) ) {
680
+ $defaults[ 'single' ] = null;
681
+ $params = (object) array_merge( $defaults, (array) $single );
682
+ }
683
+ elseif ( is_array( $raw ) || is_object( $raw ) ) {
684
+ $defaults[ 'raw' ] = false;
685
+ $params = (object) array_merge( $defaults, (array) $raw );
686
+ }
687
+ else
688
+ $params = (object) $defaults;
689
+
690
+ if ( $params->in_form ) {
691
+ $params->output = 'ids';
692
+ }
693
+ elseif ( null === $params->output ) {
694
+ /**
695
+ * Override the way realted fields are output
696
+ *
697
+ * @param string $output How to output related fields. Default is 'arrays'. Options: id|name|object|array|pod
698
+ * @param array|object $row Current row being outputted.
699
+ * @param array $params Params array passed to field().
700
+ * @param object|Pods $this Current Pods object.
701
+ */
702
+ $params->output = apply_filters( 'pods_pods_field_related_output_type', 'arrays', $this->row, $params, $this );
703
+ }
704
+
705
+ if ( in_array( $params->output, array( 'id', 'name', 'object', 'array', 'pod' ) ) )
706
+ $params->output .= 's';
707
+
708
+ // Support old $orderby variable
709
+ if ( null !== $params->single && is_string( $params->single ) && empty( $params->orderby ) ) {
710
+ if ( ! class_exists( 'Pod' ) || Pod::$deprecated_notice ) {
711
+ pods_deprecated( 'Pods::field', '2.0', 'Use $params[ \'orderby\' ] instead' );
712
+ }
713
+
714
+ $params->orderby = $params->single;
715
+ $params->single = false;
716
+ }
717
+
718
+ if ( null !== $params->single )
719
+ $params->single = (boolean) $params->single;
720
+
721
+ $params->name = trim( $params->name );
722
+ if ( is_array( $params->name ) || strlen( $params->name ) < 1 )
723
+ return null;
724
+
725
+ $params->full_name = $params->name;
726
+
727
+ $value = null;
728
+
729
+ if ( isset( $this->row_override[ $params->name ] ) )
730
+ $value = $this->row_override[ $params->name ];
731
+
732
+ if ( false === $this->row() ) {
733
+ if ( false !== $this->data() )
734
+ $this->fetch();
735
+ else
736
+ return $value;
737
+ }
738
+
739
+ if ( $this->data->field_id == $params->name ) {
740
+ if ( isset( $this->row[ $params->name ] ) )
741
+ return $this->row[ $params->name ];
742
+ elseif ( null !== $value )
743
+ return $value;
744
+
745
+ return 0;
746
+ }
747
+
748
+ $tableless_field_types = PodsForm::tableless_field_types();
749
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
750
+
751
+ $params->traverse = array();
752
+
753
+ if ( in_array( $params->name, array( '_link', 'detail_url' ) ) || ( in_array( $params->name, array( 'permalink', 'the_permalink' ) ) && in_array( $this->pod_data[ 'type' ], array( 'post_type', 'taxonomy', 'media', 'user', 'comment' ) ) ) ) {
754
+ if ( 0 < strlen( $this->detail_page ) )
755
+ $value = get_home_url() . '/' . $this->do_magic_tags( $this->detail_page );
756
+ elseif ( in_array( $this->pod_data[ 'type' ], array( 'post_type', 'media' ) ) )
757
+ $value = get_permalink( $this->id() );
758
+ elseif ( 'taxonomy' == $this->pod_data[ 'type' ] )
759
+ $value = get_term_link( $this->id(), $this->pod_data[ 'name' ] );
760
+ elseif ( 'user' == $this->pod_data[ 'type' ] )
761
+ $value = get_author_posts_url( $this->id() );
762
+ elseif ( 'comment' == $this->pod_data[ 'type' ] )
763
+ $value = get_comment_link( $this->id() );
764
+ }
765
+
766
+ $field_data = $last_field_data = false;
767
+ $field_type = false;
768
+
769
+ $first_field = explode( '.', $params->name );
770
+ $first_field = $first_field[ 0 ];
771
+
772
+ if ( isset( $this->fields[ $first_field ] ) ) {
773
+ $field_data = $this->fields[ $first_field ];
774
+ $field_type = 'field';
775
+ }
776
+ elseif ( !empty( $this->pod_data[ 'object_fields' ] ) ) {
777
+ if ( isset( $this->pod_data[ 'object_fields' ][ $first_field ] ) ) {
778
+ $field_data = $this->pod_data[ 'object_fields' ][ $first_field ];
779
+ $field_type = 'object_field';
780
+ }
781
+ else {
782
+ foreach ( $this->pod_data[ 'object_fields' ] as $object_field => $object_field_opt ) {
783
+ if ( in_array( $first_field, $object_field_opt[ 'alias' ] ) ) {
784
+ if ( $first_field == $params->name )
785
+ $params->name = $object_field;
786
+
787
+ $first_field = $object_field;
788
+ $field_data = $object_field_opt;
789
+ $field_type = 'object_field';
790
+
791
+ break;
792
+ }
793
+ }
794
+ }
795
+ }
796
+
797
+ // Simple fields have no other output options
798
+ if ( 'pick' == $field_data[ 'type' ] && in_array( $field_data[ 'pick_object' ], $simple_tableless_objects ) ) {
799
+ $params->output = 'arrays';
800
+ }
801
+
802
+ if ( empty( $value ) && in_array( $field_data[ 'type' ], $tableless_field_types ) ) {
803
+ $params->raw = true;
804
+
805
+ $value = false;
806
+
807
+ if ( 'arrays' != $params->output && isset( $this->row[ '_' . $params->output . '_' . $params->name ] ) ) {
808
+ $value = $this->row[ '_' . $params->output . '_' . $params->name ];
809
+ }
810
+ elseif ( 'arrays' == $params->output && isset( $this->row[ $params->name ] ) ) {
811
+ $value = $this->row[ $params->name ];
812
+ }
813
+
814
+ if ( false !== $value && !is_array( $value ) && 'pick' == $field_data[ 'type' ] && in_array( $field_data[ 'pick_object' ], $simple_tableless_objects ) )
815
+ $value = PodsForm::field_method( 'pick', 'simple_value', $params->name, $value, $field_data, $this->pod_data, $this->id(), true );
816
+ }
817
+
818
+ if ( empty( $value ) && isset( $this->row[ $params->name ] ) && ( !in_array( $field_data[ 'type' ], $tableless_field_types ) || 'arrays' == $params->output ) ) {
819
+ if ( empty( $field_data ) || in_array( $field_data[ 'type' ], array( 'boolean', 'number', 'currency' ) ) )
820
+ $params->raw = true;
821
+
822
+ if ( null === $params->single ) {
823
+ if ( isset( $this->fields[ $params->name ] ) && !in_array( $this->fields[ $params->name ][ 'type' ], $tableless_field_types ) )
824
+ $params->single = true;
825
+ else
826
+ $params->single = false;
827
+ }
828
+
829
+ $value = $this->row[ $params->name ];
830
+ }
831
+ elseif ( empty( $value ) ) {
832
+ $object_field_found = false;
833
+
834
+ if ( 'object_field' == $field_type ) {
835
+ $object_field_found = true;
836
+
837
+ if ( isset( $this->row[ $first_field ] ) )
838
+ $value = $this->row[ $first_field ];
839
+ elseif ( in_array( $field_data[ 'type' ], $tableless_field_types ) ) {
840
+ $this->fields[ $first_field ] = $field_data;
841
+
842
+ $object_field_found = false;
843
+ }
844
+ else
845
+ return null;
846
+ }
847
+
848
+ if ( 'post_type' == $this->pod_data[ 'type' ] && !isset( $this->fields[ $params->name ] ) ) {
849
+ if ( !isset( $this->fields[ 'post_thumbnail' ] ) && ( 'post_thumbnail' == $params->name || 0 === strpos( $params->name, 'post_thumbnail.' ) ) ) {
850
+ $size = 'thumbnail';
851
+
852
+ if ( 0 === strpos( $params->name, 'post_thumbnail.' ) ) {
853
+ $field_names = explode( '.', $params->name );
854
+
855
+ if ( isset( $field_names[ 1 ] ) )
856
+ $size = $field_names[ 1 ];
857
+ }
858
+
859
+ // Pods will auto-get the thumbnail ID if this isn't an attachment
860
+ $value = pods_image( $this->id(), $size, 0, null, true );
861
+
862
+ $object_field_found = true;
863
+ }
864
+ elseif ( !isset( $this->fields[ 'post_thumbnail_url' ] ) && ( 'post_thumbnail_url' == $params->name || 0 === strpos( $params->name, 'post_thumbnail_url.' ) ) ) {
865
+ $size = 'thumbnail';
866
+
867
+ if ( 0 === strpos( $params->name, 'post_thumbnail_url.' ) ) {
868
+ $field_names = explode( '.', $params->name );
869
+
870
+ if ( isset( $field_names[ 1 ] ) )
871
+ $size = $field_names[ 1 ];
872
+ }
873
+
874
+ // Pods will auto-get the thumbnail ID if this isn't an attachment
875
+ $value = pods_image_url( $this->id(), $size, 0, true );
876
+
877
+ $object_field_found = true;
878
+ }
879
+ elseif ( 0 === strpos( $params->name, 'image_attachment.' ) ) {
880
+ $size = 'thumbnail';
881
+
882
+ $image_id = 0;
883
+
884
+ $field_names = explode( '.', $params->name );
885
+
886
+ if ( isset( $field_names[ 1 ] ) )
887
+ $image_id = $field_names[ 1 ];
888
+
889
+ if ( isset( $field_names[ 2 ] ) )
890
+ $size = $field_names[ 2 ];
891
+
892
+ if ( !empty( $image_id ) ) {
893
+ $value = pods_image( $image_id, $size, 0, null, true );
894
+
895
+ if ( !empty( $value ) )
896
+ $object_field_found = true;
897
+ }
898
+ }
899
+ elseif ( 0 === strpos( $params->name, 'image_attachment_url.' ) ) {
900
+ $size = 'thumbnail';
901
+
902
+ $image_id = 0;
903
+
904
+ $field_names = explode( '.', $params->name );
905
+
906
+ if ( isset( $field_names[ 1 ] ) )
907
+ $image_id = $field_names[ 1 ];
908
+
909
+ if ( isset( $field_names[ 2 ] ) )
910
+ $size = $field_names[ 2 ];
911
+
912
+ if ( !empty( $image_id ) ) {
913
+ $value = pods_image_url( $image_id, $size, 0, true );
914
+
915
+ if ( !empty( $value ) )
916
+ $object_field_found = true;
917
+ }
918
+ }
919
+ }
920
+ elseif ( 'user' == $this->pod_data[ 'type' ] && !isset( $this->fields[ $params->name ] ) ) {
921
+ if ( !isset( $this->fields[ 'avatar' ] ) && ( 'avatar' == $params->name || 0 === strpos( $params->name, 'avatar.' ) ) ) {
922
+ $size = null;
923
+
924
+ if ( 0 === strpos( $params->name, 'avatar.' ) ) {
925
+ $field_names = explode( '.', $params->name );
926
+
927
+ if ( isset( $field_names[ 1 ] ) )
928
+ $size = (int) $field_names[ 1 ];
929
+ }
930
+
931
+ if ( !empty( $size ) )
932
+ $value = get_avatar( $this->id(), $size );
933
+ else
934
+ $value = get_avatar( $this->id() );
935
+
936
+ $object_field_found = true;
937
+ }
938
+ }
939
+ elseif ( 0 === strpos( $params->name, 'image_attachment.' ) ) {
940
+ $size = 'thumbnail';
941
+
942
+ $image_id = 0;
943
+
944
+ $field_names = explode( '.', $params->name );
945
+
946
+ if ( isset( $field_names[ 1 ] ) )
947
+ $image_id = $field_names[ 1 ];
948
+
949
+ if ( isset( $field_names[ 2 ] ) )
950
+ $size = $field_names[ 2 ];
951
+
952
+ if ( !empty( $image_id ) ) {
953
+ $value = pods_image( $image_id, $size, 0, null, true );
954
+
955
+ if ( !empty( $value ) )
956
+ $object_field_found = true;
957
+ }
958
+ }
959
+ elseif ( 0 === strpos( $params->name, 'image_attachment_url.' ) ) {
960
+ $size = 'thumbnail';
961
+
962
+ $image_id = 0;
963
+
964
+ $field_names = explode( '.', $params->name );
965
+
966
+ if ( isset( $field_names[ 1 ] ) )
967
+ $image_id = $field_names[ 1 ];
968
+
969
+ if ( isset( $field_names[ 2 ] ) )
970
+ $size = $field_names[ 2 ];
971
+
972
+ if ( !empty( $image_id ) ) {
973
+ $value = pods_image_url( $image_id, $size, 0, true );
974
+
975
+ if ( !empty( $value ) )
976
+ $object_field_found = true;
977
+ }
978
+ }
979
+
980
+ if ( false === $object_field_found ) {
981
+ $params->traverse = array( $params->name );
982
+
983
+ if ( false !== strpos( $params->name, '.' ) ) {
984
+ $params->traverse = explode( '.', $params->name );
985
+
986
+ $params->name = $params->traverse[ 0 ];
987
+ }
988
+
989
+ if ( isset( $this->fields[ $params->name ] ) && isset( $this->fields[ $params->name ][ 'type' ] ) ) {
990
+ /**
991
+ * Modify value returned by field() after its retrieved, but before its validated or formatted
992
+ *
993
+ * Filter name is set dynamically with name of field: "pods_pods_field_{field_name}"
994
+ *
995
+ * @since unknown
996
+ *
997
+ * @param array|string|null $value Value retrieved.
998
+ * @param array|object $row Current row being outputted.
999
+ * @param array $params Params array passed to field().
1000
+ * @param object|Pods $this Current Pods object.
1001
+ *
1002
+ */
1003
+ $v = apply_filters( 'pods_pods_field_' . $this->fields[ $params->name ][ 'type' ], null, $this->fields[ $params->name ], $this->row, $params, $this );
1004
+
1005
+ if ( null !== $v )
1006
+ return $v;
1007
+ }
1008
+
1009
+ $simple = false;
1010
+ $simple_data = array();
1011
+
1012
+ if ( isset( $this->fields[ $params->name ] ) ) {
1013
+ if ( 'meta' == $this->pod_data[ 'storage' ] ) {
1014
+ if ( !in_array( $this->fields[ $params->name ][ 'type' ], $tableless_field_types ) )
1015
+ $simple = true;
1016
+ }
1017
+
1018
+ if ( in_array( $this->fields[ $params->name ][ 'type' ], $tableless_field_types ) ) {
1019
+ $params->raw = true;
1020
+
1021
+ if ( 'pick' == $this->fields[ $params->name ][ 'type' ] && in_array( $this->fields[ $params->name ][ 'pick_object' ], $simple_tableless_objects ) ) {
1022
+ $simple = true;
1023
+ $params->single = true;
1024
+ }
1025
+ }
1026
+ elseif ( in_array( $this->fields[ $params->name ][ 'type' ], array( 'boolean', 'number', 'currency' ) ) )
1027
+ $params->raw = true;
1028
+ }
1029
+
1030
+ if ( !isset( $this->fields[ $params->name ] ) || !in_array( $this->fields[ $params->name ][ 'type' ], $tableless_field_types ) || $simple ) {
1031
+ if ( null === $params->single ) {
1032
+ if ( isset( $this->fields[ $params->name ] ) && !in_array( $this->fields[ $params->name ][ 'type' ], $tableless_field_types ) )
1033
+ $params->single = true;
1034
+ else
1035
+ $params->single = false;
1036
+ }
1037
+
1038
+ $no_conflict = pods_no_conflict_check( $this->pod_data[ 'type' ] );
1039
+
1040
+ if ( !$no_conflict )
1041
+ pods_no_conflict_on( $this->pod_data[ 'type' ] );
1042
+
1043
+ if ( in_array( $this->pod_data[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
1044
+ $id = $this->id();
1045
+
1046
+ $metadata_type = $this->pod_data['type'];
1047
+
1048
+ if ( in_array( $this->pod_data[ 'type' ], array( 'post_type', 'media' ) ) ) {
1049
+ $metadata_type = 'post';
1050
+
1051
+ // Support for WPML 'duplicated' translation handling
1052
+ if ( did_action( 'wpml_loaded' )
1053
+ && apply_filters( 'wpml_is_translated_post_type', false, $this->pod_data[ 'name' ] ) ) {
1054
+ $master_post_id = (int) apply_filters( 'wpml_master_post_from_duplicate', $id );
1055
+
1056
+ if ( 0 < $master_post_id )
1057
+ $id = $master_post_id;
1058
+ }
1059
+ } elseif ( 'taxonomy' == $this->pod_data[ 'type' ] ) {
1060
+ $metadata_type = 'term';
1061
+ }
1062
+
1063
+ $value = get_metadata( $metadata_type, $id, $params->name, $params->single );
1064
+
1065
+ $single_multi = 'single';
1066
+
1067
+ if ( isset( $this->fields[ $params->name ] ) ) {
1068
+ $single_multi = pods_v( $this->fields[ $params->name ][ 'type' ] . '_format_type', $this->fields[ $params->name ][ 'options' ], 'single' );
1069
+ }
1070
+
1071
+ if ( $simple && !is_array( $value ) && 'single' != $single_multi ) {
1072
+ $value = get_metadata( $metadata_type, $id, $params->name );
1073
+ }
1074
+ }
1075
+ elseif ( 'settings' == $this->pod_data[ 'type' ] )
1076
+ $value = get_option( $this->pod_data[ 'name' ] . '_' . $params->name, null );
1077
+
1078
+ // Handle Simple Relationships
1079
+ if ( $simple ) {
1080
+ if ( null === $params->single )
1081
+ $params->single = false;
1082
+
1083
+
1084
+ $value = PodsForm::field_method( 'pick', 'simple_value', $params->name, $value, $this->fields[ $params->name ], $this->pod_data, $this->id(), true );
1085
+ }
1086
+
1087
+ if ( !$no_conflict )
1088
+ pods_no_conflict_off( $this->pod_data[ 'type' ] );
1089
+ }
1090
+ else {
1091
+ // Dot-traversal
1092
+ $pod = $this->pod;
1093
+ $ids = array( $this->id() );
1094
+ $all_fields = array();
1095
+
1096
+ $lookup = $params->traverse;
1097
+
1098
+ // Get fields matching traversal names
1099
+ if ( !empty( $lookup ) ) {
1100
+ $fields = $this->api->load_fields( array(
1101
+ 'name' => $lookup,
1102
+ 'type' => $tableless_field_types,
1103
+ 'object_fields' => true // @todo support object fields too
1104
+ ) );
1105
+
1106
+ if ( !empty( $fields ) ) {
1107
+ foreach ( $fields as $field ) {
1108
+ if ( !empty( $field ) ) {
1109
+ if ( !isset( $all_fields[ $field[ 'pod' ] ] ) )
1110
+ $all_fields[ $field[ 'pod' ] ] = array();
1111
+
1112
+ $all_fields[ $field[ 'pod' ] ][ $field[ 'name' ] ] = $field;
1113
+ }
1114
+ }
1115
+ }
1116
+
1117
+ if ( !empty( $this->pod_data[ 'object_fields' ] ) ) {
1118
+ foreach ( $this->pod_data[ 'object_fields' ] as $object_field => $object_field_opt ) {
1119
+ if ( in_array( $object_field_opt[ 'type' ], $tableless_field_types ) ) {
1120
+ $all_fields[ $this->pod ][ $object_field ] = $object_field_opt;
1121
+ }
1122
+ }
1123
+ }
1124
+ }
1125
+
1126
+ $last_type = $last_object = $last_pick_val = '';
1127
+ $last_options = array();
1128
+
1129
+ $single_multi = pods_v( $this->fields[ $params->name ][ 'type' ] . '_format_type', $this->fields[ $params->name ][ 'options' ], 'single' );
1130
+
1131
+ if ( 'multi' == $single_multi )
1132
+ $limit = (int) pods_v( $this->fields[ $params->name ][ 'type' ] . '_limit', $this->fields[ $params->name ][ 'options' ], 0 );
1133
+ else
1134
+ $limit = 1;
1135
+
1136
+ $last_limit = 0;
1137
+
1138
+ // Loop through each traversal level
1139
+ foreach ( $params->traverse as $key => $field ) {
1140
+ $last_loop = false;
1141
+
1142
+ if ( count( $params->traverse ) <= ( $key + 1 ) )
1143
+ $last_loop = true;
1144
+
1145
+ $field_exists = isset( $all_fields[ $pod ][ $field ] );
1146
+
1147
+ $simple = false;
1148
+ $last_options = array();
1149
+
1150
+ if ( $field_exists && 'pick' == $all_fields[ $pod ][ $field ][ 'type' ] && in_array( $all_fields[ $pod ][ $field ][ 'pick_object' ], $simple_tableless_objects ) ) {
1151
+ $simple = true;
1152
+ $last_options = $all_fields[ $pod ][ $field ];
1153
+ }
1154
+
1155
+ // Tableless handler
1156
+ if ( $field_exists && ( !in_array( $all_fields[ $pod ][ $field ][ 'type' ], array( 'pick', 'taxonomy' ) ) || !$simple ) ) {
1157
+ $type = $all_fields[ $pod ][ $field ][ 'type' ];
1158
+ $pick_object = $all_fields[ $pod ][ $field ][ 'pick_object' ];
1159
+ $pick_val = $all_fields[ $pod ][ $field ][ 'pick_val' ];
1160
+
1161
+ if ( 'table' == $pick_object ) {
1162
+ $pick_val = pods_v( 'pick_table', $all_fields[ $pod ][ $field ][ 'options' ], $pick_val, true );
1163
+ }
1164
+ elseif ( '__current__' == $pick_val ) {
1165
+ $pick_val = $pod;
1166
+ }
1167
+
1168
+ $last_limit = 0;
1169
+
1170
+ if ( in_array( $type, $tableless_field_types ) ) {
1171
+ $single_multi = pods_v( "{$type}_format_type", $all_fields[ $pod ][ $field ][ 'options' ], 'single' );
1172
+
1173
+ if ( 'multi' == $single_multi ) {
1174
+ $last_limit = (int) pods_v( "{$type}_limit", $all_fields[ $pod ][ $field ][ 'options' ], 0 );
1175
+ }
1176
+ else {
1177
+ $last_limit = 1;
1178
+ }
1179
+ }
1180
+
1181
+ $last_type = $type;
1182
+ $last_object = $pick_object;
1183
+ $last_pick_val = $pick_val;
1184
+ $last_options = $all_fields[ $pod ][ $field ];
1185
+
1186
+ // Temporary hack until there's some better handling here
1187
+ $last_limit = $last_limit * count( $ids );
1188
+
1189
+ // Get related IDs
1190
+ if ( !isset( $all_fields[ $pod ][ $field ][ 'pod_id' ] ) ) {
1191
+ $all_fields[ $pod ][ $field ][ 'pod_id' ] = 0;
1192
+ }
1193
+
1194
+ if ( isset( $all_fields[ $pod ][ $field ][ 'id' ] ) ) {
1195
+ $ids = $this->api->lookup_related_items(
1196
+ $all_fields[ $pod ][ $field ][ 'id' ],
1197
+ $all_fields[ $pod ][ $field ][ 'pod_id' ],
1198
+ $ids,
1199
+ $all_fields[ $pod ][ $field ]
1200
+ );
1201
+ }
1202
+
1203
+ // No items found
1204
+ if ( empty( $ids ) ) {
1205
+ return false;
1206
+ } // @todo This should return array() if not $params->single
1207
+ elseif ( 0 < $last_limit ) {
1208
+ $ids = array_slice( $ids, 0, $last_limit );
1209
+ }
1210
+
1211
+ // Get $pod if related to a Pod
1212
+ if ( !empty( $pick_object ) && ( !empty( $pick_val ) || in_array( $pick_object, array( 'user', 'media', 'comment' ) ) ) ) {
1213
+ if ( 'pod' == $pick_object ) {
1214
+ $pod = $pick_val;
1215
+ }
1216
+ else {
1217
+ $check = $this->api->get_table_info( $pick_object, $pick_val );
1218
+
1219
+ if ( !empty( $check ) && !empty( $check[ 'pod' ] ) ) {
1220
+ $pod = $check[ 'pod' ][ 'name' ];
1221
+ }
1222
+ }
1223
+ }
1224
+ }
1225
+ // Assume last iteration
1226
+ else {
1227
+ // Invalid field
1228
+ if ( 0 == $key ) {
1229
+ return false;
1230
+ }
1231
+
1232
+ $last_loop = true;
1233
+ }
1234
+
1235
+ if ( $last_loop ) {
1236
+ $object_type = $last_object;
1237
+ $object = $last_pick_val;
1238
+
1239
+ if ( in_array( $last_type, PodsForm::file_field_types() ) ) {
1240
+ $object_type = 'media';
1241
+ $object = 'attachment';
1242
+ }
1243
+
1244
+ $data = array();
1245
+
1246
+ $table = $this->api->get_table_info( $object_type, $object, null, null, $last_options );
1247
+
1248
+ $join = $where = array();
1249
+
1250
+ if ( !empty( $table[ 'join' ] ) )
1251
+ $join = (array) $table[ 'join' ];
1252
+
1253
+ if ( !empty( $table[ 'where' ] ) || !empty( $ids ) ) {
1254
+ foreach ( $ids as $id ) {
1255
+ $where[ $id ] = '`t`.`' . $table[ 'field_id' ] . '` = ' . (int) $id;
1256
+ }
1257
+
1258
+ if ( !empty( $where ) ) {
1259
+ $where = array( implode( ' OR ', $where ) );
1260
+ }
1261
+
1262
+ if ( !empty( $table[ 'where' ] ) ) {
1263
+ $where = array_merge( $where, array_values( (array) $table[ 'where' ] ) );
1264
+ }
1265
+ }
1266
+
1267
+ /**
1268
+ * @var $related_obj Pods
1269
+ */
1270
+ $related_obj = false;
1271
+
1272
+ if ( 'pod' == $object_type )
1273
+ $related_obj = pods( $object, null, false );
1274
+ elseif ( !empty( $table[ 'pod' ] ) )
1275
+ $related_obj = pods( $table[ 'pod' ][ 'name' ], null, false );
1276
+
1277
+ if ( !empty( $table[ 'table' ] ) || !empty( $related_obj ) ) {
1278
+ $sql = array(
1279
+ 'select' => '*, `t`.`' . $table[ 'field_id' ] . '` AS `pod_item_id`',
1280
+ 'table' => $table[ 'table' ],
1281
+ 'join' => $join,
1282
+ 'where' => $where,
1283
+ 'orderby' => $params->orderby,
1284
+ 'pagination' => false,
1285
+ 'search' => false,
1286
+ 'limit' => -1,
1287
+ 'expires' => 180 // @todo This could potentially cause issues if someone changes the data within this time and persistent storage is used
1288
+ );
1289
+
1290
+ // Output types
1291
+ if ( in_array( $params->output, array( 'ids', 'objects', 'pods' ) ) )
1292
+ $sql[ 'select' ] = '`t`.`' . $table[ 'field_id' ] . '` AS `pod_item_id`';
1293
+ elseif ( 'names' == $params->output && !empty( $table[ 'field_index' ] ) )
1294
+ $sql[ 'select' ] = '`t`.`' . $table[ 'field_index' ] . '` AS `pod_item_index`, `t`.`' . $table[ 'field_id' ] . '` AS `pod_item_id`';
1295
+
1296
+ if ( !empty( $params->params ) && is_array( $params->params ) ) {
1297
+ $where = $sql[ 'where' ];
1298
+
1299
+ $sql = array_merge( $sql, $params->params );
1300
+
1301
+ if ( isset( $params->params[ 'where' ] ) )
1302
+ $sql[ 'where' ] = array_merge( (array) $where, (array) $params->params['where' ] );
1303
+ }
1304
+
1305
+ if ( empty( $related_obj ) ) {
1306
+ if ( !is_object( $this->alt_data ) )
1307
+ $this->alt_data = pods_data( null, 0, true, true );
1308
+
1309
+ $item_data = $this->alt_data->select( $sql );
1310
+ }
1311
+ else
1312
+ $item_data = $related_obj->find( $sql )->data();
1313
+
1314
+ $items = array();
1315
+
1316
+ if ( !empty( $item_data ) ) {
1317
+ foreach ( $item_data as $item ) {
1318
+ if ( is_array( $item ) )
1319
+ $item = (object) $item;
1320
+
1321
+ if ( empty( $item->pod_item_id ) )
1322
+ continue;
1323
+
1324
+ // Bypass pass field
1325
+ if ( isset( $item->user_pass ) )
1326
+ unset( $item->user_pass );
1327
+
1328
+ // Get Item ID
1329
+ $item_id = $item->pod_item_id;
1330
+
1331
+ // Output types
1332
+ if ( 'ids' == $params->output )
1333
+ $item = (int) $item_id;
1334
+ elseif ( 'names' == $params->output && !empty( $table[ 'field_index' ] ) )
1335
+ $item = $item->pod_item_index;
1336
+ elseif ( 'objects' == $params->output ) {
1337
+ if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
1338
+ $item = get_post( $item_id );
1339
+ elseif ( 'taxonomy' == $object_type )
1340
+ $item = get_term( $item_id, $object );
1341
+ elseif ( 'user' == $object_type ) {
1342
+ $item = get_userdata( $item_id );
1343
+
1344
+ if ( !empty( $item ) ) {
1345
+ // Get other vars
1346
+ $roles = $item->roles;
1347
+ $caps = $item->caps;
1348
+ $allcaps = $item->allcaps;
1349
+
1350
+ $item = $item->data;
1351
+
1352
+ // Set other vars
1353
+ $item->roles = $roles;
1354
+ $item->caps = $caps;
1355
+ $item->allcaps = $allcaps;
1356
+
1357
+ unset( $item->user_pass );
1358
+ }
1359
+ }
1360
+ elseif ( 'comment' == $object_type )
1361
+ $item = get_comment( $item_id );
1362
+ else
1363
+ $item = (object) $item;
1364
+ } elseif ( 'pods' == $params->output ) {
1365
+ if ( in_array( $object_type, array( 'user', 'media' ) ) ) {
1366
+ $item = pods( $object_type, (int) $item_id );
1367
+ } else {
1368
+ $item = pods( $object, (int) $item_id );
1369
+ }
1370
+ }
1371
+ else // arrays
1372
+ $item = get_object_vars( (object) $item );
1373
+
1374
+ // Pass item data into $data
1375
+ $items[ $item_id ] = $item;
1376
+ }
1377
+
1378
+ // Cleanup
1379
+ unset( $item_data );
1380
+
1381
+ // Return all of the data in the order expected
1382
+ if ( empty( $params->orderby ) ) {
1383
+ foreach ( $ids as $id ) {
1384
+ if ( isset( $items[ $id ] ) ) {
1385
+ $data[ $id ] = $items[ $id ];
1386
+ }
1387
+ }
1388
+ } else {
1389
+ // Use order set by orderby
1390
+ foreach ( $items as $id => $v ) {
1391
+ if ( in_array( $id, $ids ) ) {
1392
+ $data[ $id ] = $v;
1393
+ }
1394
+ }
1395
+ }
1396
+ }
1397
+ }
1398
+
1399
+ if ( in_array( $last_type, $tableless_field_types ) || in_array( $last_type, array( 'boolean', 'number', 'currency' ) ) )
1400
+ $params->raw = true;
1401
+
1402
+ if ( empty( $data ) )
1403
+ $value = false;
1404
+ else {
1405
+ $object_type = $table[ 'type' ];
1406
+
1407
+ if ( in_array( $table[ 'type' ], array( 'post_type', 'attachment', 'media' ) ) )
1408
+ $object_type = 'post';
1409
+
1410
+ $no_conflict = true;
1411
+
1412
+ if ( in_array( $object_type, array( 'post', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
1413
+ $no_conflict = pods_no_conflict_check( $object_type );
1414
+
1415
+ if ( !$no_conflict )
1416
+ pods_no_conflict_on( $object_type );
1417
+ }
1418
+
1419
+ // Return entire array
1420
+ if ( false !== $field_exists && ( in_array( $last_type, $tableless_field_types ) && !$simple ) )
1421
+ $value = $data;
1422
+ // Return an array of single column values
1423
+ else {
1424
+ $value = array();
1425
+
1426
+ foreach ( $data as $item_id => $item ) {
1427
+ // $field is 123x123, needs to be _src.123x123
1428
+ $full_field = implode( '.', array_splice( $params->traverse, $key ) );
1429
+
1430
+ if ( is_array( $item ) && isset( $item[ $field ] ) ) {
1431
+ if ( $table[ 'field_id' ] == $field )
1432
+ $value[] = (int) $item[ $field ];
1433
+ else
1434
+ $value[] = $item[ $field ];
1435
+ }
1436
+ elseif ( is_object( $item ) && isset( $item->{$field} ) ) {
1437
+ if ( $table[ 'field_id' ] == $field )
1438
+ $value[] = (int) $item->{$field};
1439
+ else
1440
+ $value[] = $item->{$field};
1441
+ }
1442
+ elseif ( ( ( false !== strpos( $full_field, '_src' ) || 'guid' == $field ) && ( in_array( $table[ 'type' ], array( 'attachment', 'media' ) ) || in_array( $last_type, PodsForm::file_field_types() ) ) ) || ( in_array( $field, array( '_link', 'detail_url' ) ) || in_array( $field, array( 'permalink', 'the_permalink' ) ) && in_array( $last_type, PodsForm::file_field_types() ) ) ) {
1443
+ $size = 'full';
1444
+
1445
+ if ( false === strpos( 'image', get_post_mime_type( $item_id ) ) ) {
1446
+ // No default sizes for non-images. When a size is defined this will be overwritten.
1447
+ $size = null;
1448
+ }
1449
+
1450
+ if ( false !== strpos( $full_field, '_src.' ) && 5 < strlen( $full_field ) )
1451
+ $size = substr( $full_field, 5 );
1452
+ elseif ( false !== strpos( $full_field, '_src_relative.' ) && 14 < strlen( $full_field ) )
1453
+ $size = substr( $full_field, 14 );
1454
+ elseif ( false !== strpos( $full_field, '_src_schemeless.' ) && 16 < strlen( $full_field ) )
1455
+ $size = substr( $full_field, 16 );
1456
+
1457
+ if ( $size ) {
1458
+ $value_url = pods_image_url( $item_id, $size );
1459
+ } else {
1460
+ $value_url = wp_get_attachment_url( $item_id );
1461
+ }
1462
+
1463
+ if ( false !== strpos( $full_field, '_src_relative' ) && !empty( $value_url ) ) {
1464
+ $value_url_parsed = parse_url( $value_url );
1465
+ $value_url = $value_url_parsed[ 'path' ];
1466
+ }
1467
+ elseif ( false !== strpos( $full_field, '_src_schemeless' ) && !empty( $value_url ) )
1468
+ $value_url = str_replace( array( 'http://', 'https://' ), '//', $value_url );
1469
+
1470
+ if ( !empty( $value_url ) )
1471
+ $value[] = $value_url;
1472
+
1473
+ $params->raw_display = true;
1474
+ }
1475
+ elseif ( false !== strpos( $full_field, '_img' ) && ( in_array( $table[ 'type' ], array( 'attachment', 'media' ) ) || in_array( $last_type, PodsForm::file_field_types() ) ) ) {
1476
+ $size = 'full';
1477
+
1478
+ if ( false !== strpos( $full_field, '_img.' ) && 5 < strlen( $full_field ) )
1479
+ $size = substr( $full_field, 5 );
1480
+
1481
+ $value[] = pods_image( $item_id, $size );
1482
+
1483
+ $params->raw_display = true;
1484
+ }
1485
+ elseif ( in_array( $field, array( '_link', 'detail_url' ) ) || in_array( $field, array( 'permalink', 'the_permalink' ) ) ) {
1486
+ if ( 'pod' == $object_type ) {
1487
+ if ( is_object( $related_obj ) ) {
1488
+ $related_obj->fetch( $item_id );
1489
+
1490
+ $value[] = $related_obj->field( 'detail_url' );
1491
+ }
1492
+ else
1493
+ $value[] = '';
1494
+ }
1495
+ elseif ( 'post' == $object_type )
1496
+ $value[] = get_permalink( $item_id );
1497
+ elseif ( 'taxonomy' == $object_type )
1498
+ $value[] = get_term_link( $item_id, $object );
1499
+ elseif ( 'user' == $object_type )
1500
+ $value[] = get_author_posts_url( $item_id );
1501
+ elseif ( 'comment' == $object_type )
1502
+ $value[] = get_comment_link( $item_id );
1503
+ else
1504
+ $value[] = '';
1505
+
1506
+ $params->raw_display = true;
1507
+ }
1508
+ elseif ( in_array( $object_type, array( 'post', 'taxonomy', 'user', 'comment' ) ) ) {
1509
+ $metadata_object_id = $item_id;
1510
+
1511
+ $metadata_type = $object_type;
1512
+
1513
+ if ( 'post' == $object_type ) {
1514
+ // Support for WPML 'duplicated' translation handling
1515
+ if ( did_action( 'wpml_loaded' )
1516
+ && apply_filters( 'wpml_is_translated_post_type', false, $object ) ) {
1517
+ $master_post_id = (int) apply_filters( 'wpml_master_post_from_duplicate', $metadata_object_id );
1518
+
1519
+ if ( 0 < $master_post_id )
1520
+ $metadata_object_id = $master_post_id;
1521
+ }
1522
+ } elseif ( 'taxonomy' == $object_type ) {
1523
+ $metadata_type = 'term';
1524
+ }
1525
+
1526
+ $value[] = get_metadata( $metadata_type, $metadata_object_id, $field, true );
1527
+ }
1528
+ elseif ( 'settings' == $object_type )
1529
+ $value[] = get_option( $object . '_' . $field );
1530
+ }
1531
+ }
1532
+
1533
+ if ( in_array( $object_type, array( 'post', 'taxonomy', 'user', 'comment', 'settings' ) ) && !$no_conflict )
1534
+ pods_no_conflict_off( $object_type );
1535
+
1536
+ // Handle Simple Relationships
1537
+ if ( $simple ) {
1538
+ if ( null === $params->single )
1539
+ $params->single = false;
1540
+
1541
+ $value = PodsForm::field_method( 'pick', 'simple_value', $field, $value, $last_options, $all_fields[ $pod ], 0, true );
1542
+ }
1543
+ elseif ( false === $params->in_form && !empty( $value ) )
1544
+ $value = array_values( $value );
1545
+
1546
+ // Return a single column value
1547
+ if ( false === $params->in_form && 1 == $limit && !empty( $value ) && is_array( $value ) && 1 == count( $value ) )
1548
+ $value = current( $value );
1549
+ }
1550
+
1551
+ if ( $last_options ) {
1552
+ $last_field_data = $last_options;
1553
+ }
1554
+
1555
+ break;
1556
+ }
1557
+ }
1558
+ }
1559
+ }
1560
+ }
1561
+
1562
+ if ( !empty( $params->traverse ) && 1 < count( $params->traverse ) ) {
1563
+ $field_names = implode( '.', $params->traverse );
1564
+
1565
+ $this->row[ $field_names ] = $value;
1566
+ }
1567
+ elseif ( 'arrays' != $params->output && in_array( $field_data[ 'type' ], $tableless_field_types ) ) {
1568
+ $this->row[ '_' . $params->output . '_' . $params->full_name ] = $value;
1569
+ }
1570
+ elseif ( 'arrays' == $params->output || !in_array( $field_data[ 'type' ], $tableless_field_types ) ) {
1571
+ $this->row[ $params->full_name ] = $value;
1572
+ }
1573
+
1574
+ if ( $params->single && is_array( $value ) && 1 == count( $value ) )
1575
+ $value = current( $value );
1576
+
1577
+ if ( ! empty( $last_field_data ) ) {
1578
+ $field_data = $last_field_data;
1579
+ }
1580
+
1581
+ // @todo Expand this into traversed fields too
1582
+ if ( !empty( $field_data ) && ( $params->display || !$params->raw ) && !$params->in_form && !$params->raw_display ) {
1583
+ if ( $params->display || ( ( $params->get_meta || $params->deprecated ) && !in_array( $field_data[ 'type' ], $tableless_field_types ) ) ) {
1584
+ $field_data[ 'options' ] = pods_var_raw( 'options', $field_data, array(), null, true );
1585
+
1586
+ $post_temp = false;
1587
+
1588
+ if ( 'post_type' == pods_v( 'type', $this->pod_data ) && 0 < $this->id() && ( !isset( $GLOBALS[ 'post' ] ) || empty( $GLOBALS[ 'post' ] ) ) ) {
1589
+ global $post_ID, $post;
1590
+
1591
+ $post_temp = true;
1592
+
1593
+ $old_post = $GLOBALS[ 'post' ];
1594
+ $old_ID = $GLOBALS[ 'post_ID' ];
1595
+
1596
+ $post = get_post( $this->id() );
1597
+ $post_ID = $this->id();
1598
+ }
1599
+
1600
+ $filter = pods_var_raw( 'display_filter', $field_data[ 'options' ] );
1601
+
1602
+ if ( 0 < strlen( $filter ) ) {
1603
+ $args = array(
1604
+ $filter,
1605
+ $value
1606
+ );
1607
+
1608
+ $filter_args = pods_var_raw( 'display_filter_args', $field_data[ 'options' ] );
1609
+
1610
+ if ( !empty( $filter_args ) )
1611
+ $args = array_merge( $args, compact( $filter_args ) );
1612
+
1613
+ $value = call_user_func_array( 'apply_filters', $args );
1614
+ }
1615
+ elseif ( 1 == pods_v( 'display_process', $field_data[ 'options' ], 1 ) ) {
1616
+ $value = PodsForm::display(
1617
+ $field_data[ 'type' ],
1618
+ $value,
1619
+ $params->name,
1620
+ array_merge( $field_data, $field_data[ 'options' ] ),
1621
+ $this->pod_data,
1622
+ $this->id()
1623
+ );
1624
+ }
1625
+
1626
+ if ( $post_temp ) {
1627
+ $post = $old_post;
1628
+ $post_ID = $old_ID;
1629
+ }
1630
+ }
1631
+ else {
1632
+ $value = PodsForm::value(
1633
+ $field_data[ 'type' ],
1634
+ $value,
1635
+ $params->name,
1636
+ array_merge( $field_data, $field_data[ 'options' ] ),
1637
+ $this->pod_data,
1638
+ $this->id()
1639
+ );
1640
+ }
1641
+ }
1642
+
1643
+ /**
1644
+ * Modify value returned by field() directly before output.
1645
+ *
1646
+ * Will not run if value was null
1647
+ *
1648
+ * @since unknown
1649
+ *
1650
+ * @param array|string|null $value Value to be returned.
1651
+ * @param array|object $row Current row being outputted.
1652
+ * @param array $params Params array passed to field().
1653
+ * @param object|Pods $this Current Pods object.
1654
+ *
1655
+ */
1656
+ $value = apply_filters( 'pods_pods_field', $value, $this->row, $params, $this );
1657
+
1658
+ return $value;
1659
+ }
1660
+
1661
+ /**
1662
+ * Check if an item field has a specific value in it
1663
+ *
1664
+ * @param string $field Field name
1665
+ * @param mixed $value Value to check
1666
+ * @param int $id (optional) ID of the pod item to check
1667
+ *
1668
+ * @return bool Whether the value was found
1669
+ *
1670
+ * @since 2.3.3
1671
+ */
1672
+ public function has ( $field, $value, $id = null ) {
1673
+ $pod =& $this;
1674
+
1675
+ if ( null === $id )
1676
+ $id = $this->id();
1677
+ elseif ( $id != $this->id() )
1678
+ $pod = pods( $this->pod, $id );
1679
+
1680
+ $this->do_hook( 'has', $field, $value, $id );
1681
+
1682
+ if ( !isset( $this->fields[ $field ] ) )
1683
+ return false;
1684
+
1685
+ // Tableless fields
1686
+ if ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::tableless_field_types() ) ) {
1687
+ if ( !is_array( $value ) )
1688
+ $value = explode( ',', $value );
1689
+
1690
+ if ( 'pick' == $this->fields[ $field ][ 'type' ] && in_array( $this->fields[ $field ][ 'pick_object' ], PodsForm::simple_tableless_objects() ) ) {
1691
+ $current_value = $pod->raw( $field );
1692
+
1693
+ if ( !empty( $current_value ) )
1694
+ $current_value = (array) $current_value;
1695
+
1696
+ foreach ( $current_value as $v ) {
1697
+ if ( in_array( $v, $value ) )
1698
+ return true;
1699
+ }
1700
+ }
1701
+ else {
1702
+ $related_ids = $this->api->lookup_related_items( $this->fields[ $field ][ 'id' ], $this->pod_data[ 'id' ], $id, $this->fields[ $field ], $this->pod_data );
1703
+
1704
+ foreach ( $value as $k => $v ) {
1705
+ if ( !preg_match( '/[^0-9]/', $v ) )
1706
+ $value[ $k ] = (int) $v;
1707
+ // @todo Convert slugs into IDs
1708
+ else {
1709
+
1710
+ }
1711
+ }
1712
+
1713
+ foreach ( $related_ids as $v ) {
1714
+ if ( in_array( $v, $value ) )
1715
+ return true;
1716
+ }
1717
+ }
1718
+ }
1719
+ // Text fields
1720
+ elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::text_field_types() ) ) {
1721
+ $current_value = $pod->raw( $field );
1722
+
1723
+ if ( 0 < strlen( $current_value ) )
1724
+ return stripos( $current_value, $value );
1725
+ }
1726
+ // All other fields
1727
+ else
1728
+ return $this->is( $field, $value, $id );
1729
+
1730
+ return false;
1731
+ }
1732
+
1733
+ /**
1734
+ * Check if an item field is a specific value
1735
+ *
1736
+ * @param string $field Field name
1737
+ * @param mixed $value Value to check
1738
+ * @param int $id (optional) ID of the pod item to check
1739
+ *
1740
+ * @return bool Whether the value was found
1741
+ *
1742
+ * @since 2.3.3
1743
+ */
1744
+ public function is ( $field, $value, $id = null ) {
1745
+ $pod =& $this;
1746
+
1747
+ if ( null === $id )
1748
+ $id = $this->id();
1749
+ elseif ( $id != $this->id() )
1750
+ $pod = pods( $this->pod, $id );
1751
+
1752
+ $this->do_hook( 'is', $field, $value, $id );
1753
+
1754
+ if ( !isset( $this->fields[ $field ] ) )
1755
+ return false;
1756
+
1757
+ // Tableless fields
1758
+ if ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::tableless_field_types() ) ) {
1759
+ if ( !is_array( $value ) )
1760
+ $value = explode( ',', $value );
1761
+
1762
+ $current_value = array();
1763
+
1764
+ if ( 'pick' == $this->fields[ $field ][ 'type' ] && in_array( $this->fields[ $field ][ 'pick_object' ], PodsForm::simple_tableless_objects() ) ) {
1765
+ $current_value = $pod->raw( $field );
1766
+
1767
+ if ( !empty( $current_value ) )
1768
+ $current_value = (array) $current_value;
1769
+
1770
+ foreach ( $current_value as $v ) {
1771
+ if ( in_array( $v, $value ) )
1772
+ return true;
1773
+ }
1774
+ }
1775
+ else {
1776
+ $related_ids = $this->api->lookup_related_items( $this->fields[ $field ][ 'id' ], $this->pod_data[ 'id' ], $id, $this->fields[ $field ], $this->pod_data );
1777
+
1778
+ foreach ( $value as $k => $v ) {
1779
+ if ( !preg_match( '/[^0-9]/', $v ) )
1780
+ $value[ $k ] = (int) $v;
1781
+ // @todo Convert slugs into IDs
1782
+ else {
1783
+
1784
+ }
1785
+ }
1786
+
1787
+ foreach ( $related_ids as $v ) {
1788
+ if ( in_array( $v, $value ) )
1789
+ return true;
1790
+ }
1791
+ }
1792
+
1793
+ if ( !empty( $current_value ) )
1794
+ $current_value = array_filter( array_unique( $current_value ) );
1795
+ else
1796
+ $current_value = array();
1797
+
1798
+ if ( !empty( $value ) )
1799
+ $value = array_filter( array_unique( $value ) );
1800
+ else
1801
+ $value = array();
1802
+
1803
+ sort( $current_value );
1804
+ sort( $value );
1805
+
1806
+ if ( $value === $current_value )
1807
+ return true;
1808
+ }
1809
+ // Number fields
1810
+ elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::number_field_types() ) ) {
1811
+ $current_value = $pod->raw( $field );
1812
+
1813
+ if ( (float) $current_value === (float) $value )
1814
+ return true;
1815
+ }
1816
+ // Date fields
1817
+ elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::date_field_types() ) ) {
1818
+ $current_value = $pod->raw( $field );
1819
+
1820
+ if ( 0 < strlen( $current_value ) ) {
1821
+ if ( strtotime( $current_value ) == strtotime( $value ) )
1822
+ return true;
1823
+ }
1824
+ elseif ( empty( $value ) )
1825
+ return true;
1826
+ }
1827
+ // Text fields
1828
+ elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::text_field_types() ) ) {
1829
+ $current_value = $pod->raw( $field );
1830
+
1831
+ if ( (string) $current_value === (string) $value )
1832
+ return true;
1833
+ }
1834
+ // All other fields
1835
+ else {
1836
+ $current_value = $pod->raw( $field );
1837
+
1838
+ if ( $current_value === $value )
1839
+ return true;
1840
+ }
1841
+
1842
+ return false;
1843
+ }
1844
+
1845
+ /**
1846
+ * Return the item ID
1847
+ *
1848
+ * @return int
1849
+ * @since 2.0
1850
+ */
1851
+ public function id () {
1852
+ if ( isset( $this->data->row ) && isset( $this->data->row[ 'id' ] ) ) {
1853
+ // If we already have data loaded return that ID
1854
+ return $this->data->row[ 'id' ];
1855
+ }
1856
+ return $this->field( $this->data->field_id );
1857
+ }
1858
+
1859
+ /**
1860
+ * Return the previous item ID, loops at the last id to return the first
1861
+ *
1862
+ * @param int $id
1863
+ * @param array $params_override
1864
+ *
1865
+ * @return int
1866
+ * @since 2.0
1867
+ */
1868
+ public function prev_id ( $id = null, $params_override = null ) {
1869
+ if ( null === $id )
1870
+ $id = $this->id();
1871
+
1872
+ $id = (int) $id;
1873
+
1874
+ $params = array(
1875
+ 'select' => "`t`.`{$this->data->field_id}`",
1876
+ 'where' => "`t`.`{$this->data->field_id}` < {$id}",
1877
+ 'orderby' => "`t`.`{$this->data->field_id}` DESC",
1878
+ 'limit' => 1
1879
+ );
1880
+
1881
+ if ( !empty( $params_override ) || !empty( $this->params ) ) {
1882
+ if ( !empty( $params_override ) )
1883
+ $params = $params_override;
1884
+ elseif ( !empty( $this->params ) )
1885
+ $params = $this->params;
1886
+
1887
+ if ( is_object( $params ) ) {
1888
+ $params = get_object_vars( $params );
1889
+ }
1890
+
1891
+ if ( 0 < $id ) {
1892
+ if ( isset( $params[ 'where' ] ) && !empty( $params[ 'where' ] ) ) {
1893
+ $params[ 'where' ] = (array) $params[ 'where' ];
1894
+ $params[ 'where' ][] = "`t`.`{$this->data->field_id}` < {$id}";
1895
+ }
1896
+ else {
1897
+ $params[ 'where' ] = "`t`.`{$this->data->field_id}` < {$id}";
1898
+ }
1899
+ }
1900
+ elseif ( isset( $params[ 'offset' ] ) && 0 < $params[ 'offset' ] )
1901
+ $params[ 'offset' ] -= 1;
1902
+ elseif ( !isset( $params[ 'offset' ] ) && !empty( $this->params ) && 0 < $this->row_number )
1903
+ $params[ 'offset' ] = $this->row_number - 1;
1904
+ else
1905
+ return 0;
1906
+
1907
+ if ( isset( $params[ 'orderby' ] ) && !empty( $params[ 'orderby' ] ) ) {
1908
+ if ( is_array( $params[ 'orderby' ] ) ) {
1909
+ foreach ( $params[ 'orderby' ] as $orderby => $dir ) {
1910
+ $dir = strtoupper( $dir );
1911
+
1912
+ if ( !in_array( $dir, array( 'ASC', 'DESC' ) ) ) {
1913
+ continue;
1914
+ }
1915
+
1916
+ if ( 'ASC' == $dir ) {
1917
+ $params[ 'orderby' ][ $orderby ] = 'DESC';
1918
+ }
1919
+ else {
1920
+ $params[ 'orderby' ][ $orderby ] = 'ASC';
1921
+ }
1922
+ }
1923
+
1924
+ $params[ 'orderby' ][ $this->data->field_id ] = 'DESC';
1925
+ }
1926
+ elseif ( "`t`.`{$this->data->field_id}` DESC" != $params[ 'orderby' ] ) {
1927
+ $params[ 'orderby' ] .= ", `t`.`{$this->data->field_id}` DESC";
1928
+ }
1929
+ }
1930
+
1931
+ $params[ 'select' ] = "`t`.`{$this->data->field_id}`";
1932
+ $params[ 'limit' ] = 1;
1933
+ }
1934
+
1935
+ $pod = pods( $this->pod, $params );
1936
+
1937
+ $new_id = 0;
1938
+
1939
+ if ( $pod->fetch() )
1940
+ $new_id = $pod->id();
1941
+
1942
+ $new_id = $this->do_hook( 'prev_id', $new_id, $id, $pod, $params_override );
1943
+
1944
+ return $new_id;
1945
+ }
1946
+
1947
+ /**
1948
+ * Return the next item ID, loops at the first id to return the last
1949
+ *
1950
+ * @param int $id
1951
+ * @param array $find_params
1952
+ *
1953
+ * @return int
1954
+ * @since 2.0
1955
+ */
1956
+ public function next_id ( $id = null, $params_override = null ) {
1957
+ if ( null === $id )
1958
+ $id = $this->id();
1959
+
1960
+ $id = (int) $id;
1961
+
1962
+ $params = array(
1963
+ 'select' => "`t`.`{$this->data->field_id}`",
1964
+ 'where' => "{$id} < `t`.`{$this->data->field_id}`",
1965
+ 'orderby' => "`t`.`{$this->data->field_id}` ASC",
1966
+ 'limit' => 1
1967
+ );
1968
+
1969
+ if ( !empty( $params_override ) || !empty( $this->params ) ) {
1970
+ if ( !empty( $params_override ) )
1971
+ $params = $params_override;
1972
+ elseif ( !empty( $this->params ) )
1973
+ $params = $this->params;
1974
+
1975
+ if ( is_object( $params ) ) {
1976
+ $params = get_object_vars( $params );
1977
+ }
1978
+
1979
+ if ( 0 < $id ) {
1980
+ if ( isset( $params[ 'where' ] ) && !empty( $params[ 'where' ] ) ) {
1981
+ $params[ 'where' ] = (array) $params[ 'where' ];
1982
+ $params[ 'where' ][] = "{$id} < `t`.`{$this->data->field_id}`";
1983
+ }
1984
+ else {
1985
+ $params[ 'where' ] = "{$id} < `t`.`{$this->data->field_id}`";
1986
+ }
1987
+ }
1988
+ elseif ( !isset( $params[ 'offset' ] ) ) {
1989
+ if ( !empty( $this->params ) && -1 < $this->row_number )
1990
+ $params[ 'offset' ] = $this->row_number + 1;
1991
+ else
1992
+ $params[ 'offset' ] = 1;
1993
+ }
1994
+ else
1995
+ $params[ 'offset' ] += 1;
1996
+
1997
+ $params[ 'select' ] = "`t`.`{$this->data->field_id}`";
1998
+ $params[ 'limit' ] = 1;
1999
+ }
2000
+
2001
+ $pod = pods( $this->pod, $params );
2002
+
2003
+ $new_id = 0;
2004
+
2005
+ if ( $pod->fetch() )
2006
+ $new_id = $pod->id();
2007
+
2008
+ $new_id = $this->do_hook( 'next_id', $new_id, $id, $pod, $params_override );
2009
+
2010
+ return $new_id;
2011
+ }
2012
+
2013
+ /**
2014
+ * Return the first item ID
2015
+ *
2016
+ * @param array $params_override
2017
+ *
2018
+ * @return int
2019
+ * @since 2.3
2020
+ */
2021
+ public function first_id ( $params_override = null ) {
2022
+ $params = array(
2023
+ 'select' => "`t`.`{$this->data->field_id}`",
2024
+ 'orderby' => "`t`.`{$this->data->field_id}` ASC",
2025
+ 'limit' => 1
2026
+ );
2027
+
2028
+ if ( !empty( $params_override ) || !empty( $this->params ) ) {
2029
+ if ( !empty( $params_override ) )
2030
+ $params = $params_override;
2031
+ elseif ( !empty( $this->params ) )
2032
+ $params = $this->params;
2033
+
2034
+ if ( is_object( $params ) ) {
2035
+ $params = get_object_vars( $params );
2036
+ }
2037
+
2038
+ $params[ 'select' ] = "`t`.`{$this->data->field_id}`";
2039
+ $params[ 'offset' ] = 0;
2040
+ $params[ 'limit' ] = 1;
2041
+ }
2042
+
2043
+ $pod = pods( $this->pod, $params );
2044
+
2045
+ $new_id = 0;
2046
+
2047
+ if ( $pod->fetch() )
2048
+ $new_id = $pod->id();
2049
+
2050
+ $new_id = $this->do_hook( 'first_id', $new_id, $pod, $params_override );
2051
+
2052
+ return $new_id;
2053
+ }
2054
+
2055
+ /**
2056
+ * Return the last item ID
2057
+ *
2058
+ * @param array $params_override
2059
+ *
2060
+ * @return int
2061
+ * @since 2.3
2062
+ */
2063
+ public function last_id ( $params_override = null ) {
2064
+ $params = array(
2065
+ 'select' => "`t`.`{$this->data->field_id}`",
2066
+ 'orderby' => "`t`.`{$this->data->field_id}` DESC",
2067
+ 'limit' => 1
2068
+ );
2069
+
2070
+ if ( !empty( $params_override ) || !empty( $this->params ) ) {
2071
+ if ( !empty( $params_override ) )
2072
+ $params = $params_override;
2073
+ elseif ( !empty( $this->params ) )
2074
+ $params = $this->params;
2075
+
2076
+ if ( is_object( $params ) ) {
2077
+ $params = get_object_vars( $params );
2078
+ }
2079
+
2080
+ if ( isset( $params[ 'total_found' ] ) )
2081
+ $params[ 'offset' ] = $params[ 'total_found' ] - 1;
2082
+ else
2083
+ $params[ 'offset' ] = $this->total_found() - 1;
2084
+
2085
+ if ( isset( $params[ 'orderby' ] ) && !empty( $params[ 'orderby' ] ) ) {
2086
+ if ( is_array( $params[ 'orderby' ] ) ) {
2087
+ foreach ( $params[ 'orderby' ] as $orderby => $dir ) {
2088
+ $dir = strtoupper( $dir );
2089
+
2090
+ if ( !in_array( $dir, array( 'ASC', 'DESC' ) ) ) {
2091
+ continue;
2092
+ }
2093
+
2094
+ if ( 'ASC' == $dir ) {
2095
+ $params[ 'orderby' ][ $orderby ] = 'DESC';
2096
+ }
2097
+ else {
2098
+ $params[ 'orderby' ][ $orderby ] = 'ASC';
2099
+ }
2100
+ }
2101
+
2102
+ $params[ 'orderby' ][ $this->data->field_id ] = 'DESC';
2103
+ }
2104
+ elseif ( "`t`.`{$this->data->field_id}` DESC" != $params[ 'orderby' ] ) {
2105
+ $params[ 'orderby' ] .= ", `t`.`{$this->data->field_id}` DESC";
2106
+ }
2107
+ }
2108
+
2109
+ $params[ 'select' ] = "`t`.`{$this->data->field_id}`";
2110
+ $params[ 'limit' ] = 1;
2111
+ }
2112
+
2113
+ $pod = pods( $this->pod, $params );
2114
+
2115
+ $new_id = 0;
2116
+
2117
+ if ( $pod->fetch() )
2118
+ $new_id = $pod->id();
2119
+
2120
+ $new_id = $this->do_hook( 'last_id', $new_id, $pod, $params_override );
2121
+ return $new_id;
2122
+ }
2123
+
2124
+ /**
2125
+ * Return the item name
2126
+ *
2127
+ * @return string
2128
+ * @since 2.0
2129
+ */
2130
+ public function index () {
2131
+ return $this->field( $this->data->field_index );
2132
+ }
2133
+
2134
+ /**
2135
+ * Find items of a pod, much like WP_Query, but with advanced table handling.
2136
+ *
2137
+ * @param array $params An associative array of parameters
2138
+ * @param int $limit (optional) (deprecated) Limit the number of items to find, use -1 to return all items with no limit
2139
+ * @param string $where (optional) (deprecated) SQL WHERE declaration to use
2140
+ * @param string $sql (optional) (deprecated) For advanced use, a custom SQL query to run
2141
+ *
2142
+ * @return \Pods The pod object
2143
+ * @since 2.0
2144
+ * @link http://pods.io/docs/find/
2145
+ */
2146
+ public function find ( $params = null, $limit = 15, $where = null, $sql = null ) {
2147
+
2148
+ $tableless_field_types = PodsForm::tableless_field_types();
2149
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
2150
+
2151
+
2152
+ $this->params = $params;
2153
+
2154
+ $select = '`t`.*';
2155
+
2156
+ if ( !in_array( $this->pod_data[ 'type' ], array( 'pod', 'table' ) ) && 'table' == $this->pod_data[ 'storage' ] )
2157
+ $select .= ', `d`.*';
2158
+
2159
+ if ( empty( $this->data->table ) )
2160
+ return $this;
2161
+
2162
+ $defaults = array(
2163
+ 'table' => $this->data->table,
2164
+ 'select' => $select,
2165
+ 'join' => null,
2166
+
2167
+ 'where' => $where,
2168
+ 'groupby' => null,
2169
+ 'having' => null,
2170
+ 'orderby' => null,
2171
+
2172
+ 'limit' => (int) $limit,
2173
+ 'offset' => null,
2174
+ 'page' => (int) $this->page,
2175
+ 'page_var' => $this->page_var,
2176
+ 'pagination' => (boolean) $this->pagination,
2177
+
2178
+ 'search' => (boolean) $this->search,
2179
+ 'search_var' => $this->search_var,
2180
+ 'search_query' => null,
2181
+ 'search_mode' => $this->search_mode,
2182
+ 'search_across' => false,
2183
+ 'search_across_picks' => false,
2184
+ 'search_across_files' => false,
2185
+
2186
+ 'filters' => $this->filters,
2187
+ 'sql' => $sql,
2188
+
2189
+ 'expires' => null,
2190
+ 'cache_mode' => 'cache'
2191
+ );
2192
+
2193
+ if ( is_array( $params ) )
2194
+ $params = (object) array_merge( $defaults, $params );
2195
+ if ( is_object( $params ) )
2196
+ $params = (object) array_merge( $defaults, get_object_vars( $params ) );
2197
+ else {
2198
+ $defaults[ 'orderby' ] = $params;
2199
+ $params = (object) $defaults;
2200
+ }
2201
+
2202
+ $params = apply_filters( 'pods_pods_find', $params );
2203
+
2204
+ $params->limit = (int) $params->limit;
2205
+
2206
+ if ( 0 == $params->limit )
2207
+ $params->limit = -1;
2208
+
2209
+ $this->limit = (int) $params->limit;
2210
+ $this->offset = (int) $params->offset;
2211
+ $this->page = (int) $params->page;
2212
+ $this->page_var = $params->page_var;
2213
+ $this->pagination = (boolean) $params->pagination;
2214
+ $this->search = (boolean) $params->search;
2215
+ $this->search_var = $params->search_var;
2216
+ $params->join = (array) $params->join;
2217
+
2218
+ if ( empty( $params->search_query ) )
2219
+ $params->search_query = pods_var( $this->search_var, 'get', '' );
2220
+
2221
+ // Allow orderby array ( 'field' => 'asc|desc' )
2222
+ if ( !empty( $params->orderby ) && is_array( $params->orderby ) ) {
2223
+ foreach ( $params->orderby as $k => &$orderby ) {
2224
+ if ( !is_numeric( $k ) ) {
2225
+ $key = '';
2226
+
2227
+ $order = 'ASC';
2228
+
2229
+ if ( 'DESC' == strtoupper( $orderby ) )
2230
+ $order = 'DESC';
2231
+
2232
+ if ( isset( $this->fields[ $k ] ) && in_array( $this->fields[ $k ][ 'type' ], $tableless_field_types ) ) {
2233
+ if ( in_array( $this->fields[ $k ][ 'pick_object' ], $simple_tableless_objects ) ) {
2234
+ if ( 'table' == $this->pod_data[ 'storage' ] ) {
2235
+ if ( !in_array( $this->pod_data[ 'type' ], array( 'pod', 'table' ) ) )
2236
+ $key = "`d`.`{$k}`";
2237
+ else
2238
+ $key = "`t`.`{$k}`";
2239
+ }
2240
+ else
2241
+ $key = "`{$k}`.`meta_value`";
2242
+ }
2243
+ else {
2244
+ $pick_val = $this->fields[ $k ][ 'pick_val' ];
2245
+
2246
+ if ( '__current__' == $pick_val )
2247
+ $pick_val = $this->pod;
2248
+
2249
+ $table = $this->api->get_table_info( $this->fields[ $k ][ 'pick_object' ], $pick_val );
2250
+
2251
+ if ( !empty( $table ) )
2252
+ $key = "`{$k}`.`" . $table[ 'field_index' ] . '`';
2253
+ }
2254
+ }
2255
+
2256
+ if ( empty( $key ) ) {
2257
+ if ( !in_array( $this->pod_data[ 'type' ], array( 'pod', 'table' ) ) ) {
2258
+ if ( isset( $this->pod_data[ 'object_fields' ][ $k ] ) )
2259
+ $key = "`t`.`{$k}`";
2260
+ elseif ( isset( $this->fields[ $k ] ) ) {
2261
+ if ( 'table' == $this->pod_data[ 'storage' ] )
2262
+ $key = "`d`.`{$k}`";
2263
+ else
2264
+ $key = "`{$k}`.`meta_value`";
2265
+ }
2266
+ else {
2267
+ foreach ( $this->pod_data[ 'object_fields' ] as $object_field => $object_field_opt ) {
2268
+ if ( $object_field == $k || in_array( $k, $object_field_opt[ 'alias' ] ) )
2269
+ $key = "`t`.`{$object_field}`";
2270
+ }
2271
+ }
2272
+ }
2273
+ elseif ( isset( $this->fields[ $k ] ) ) {
2274
+ if ( 'table' == $this->pod_data[ 'storage' ] )
2275
+ $key = "`t`.`{$k}`";
2276
+ else
2277
+ $key = "`{$k}`.`meta_value`";
2278
+ }
2279
+
2280
+ if ( empty( $key ) ) {
2281
+ $key = $k;
2282
+
2283
+ if ( false === strpos( $key, ' ' ) && false === strpos( $key, '`' ) )
2284
+ $key = '`' . str_replace( '.', '`.`', $key ) . '`';
2285
+ }
2286
+ }
2287
+
2288
+ $orderby = $key;
2289
+
2290
+ if ( false === strpos( $orderby, ' ' ) )
2291
+ $orderby .= ' ' . $order;
2292
+ }
2293
+ }
2294
+ }
2295
+
2296
+ // Add prefix to $params->orderby if needed
2297
+ if ( !empty( $params->orderby ) ) {
2298
+ if ( !is_array( $params->orderby ) )
2299
+ $params->orderby = array( $params->orderby );
2300
+
2301
+ foreach ( $params->orderby as &$prefix_orderby ) {
2302
+ if ( false === strpos( $prefix_orderby, ',' ) && false === strpos( $prefix_orderby, '(' ) && false === stripos( $prefix_orderby, ' AS ' ) && false === strpos( $prefix_orderby, '`' ) && false === strpos( $prefix_orderby, '.' ) ) {
2303
+ if ( false !== stripos( $prefix_orderby, ' DESC' ) ) {
2304
+ $k = trim( str_ireplace( array( '`', ' DESC' ), '', $prefix_orderby ) );
2305
+ $dir = 'DESC';
2306
+ }
2307
+ else {
2308
+ $k = trim( str_ireplace( array( '`', ' ASC' ), '', $prefix_orderby ) );
2309
+ $dir = 'ASC';
2310
+ }
2311
+
2312
+ $key = $k;
2313
+
2314
+ if ( !in_array( $this->pod_data[ 'type' ], array( 'pod', 'table' ) ) ) {
2315
+ if ( isset( $this->pod_data[ 'object_fields' ][ $k ] ) )
2316
+ $key = "`t`.`{$k}`";
2317
+ elseif ( isset( $this->fields[ $k ] ) ) {
2318
+ if ( 'table' == $this->pod_data[ 'storage' ] )
2319
+ $key = "`d`.`{$k}`";
2320
+ else
2321
+ $key = "`{$k}`.`meta_value`";
2322
+ }
2323
+ else {
2324
+ foreach ( $this->pod_data[ 'object_fields' ] as $object_field => $object_field_opt ) {
2325
+ if ( $object_field == $k || in_array( $k, $object_field_opt[ 'alias' ] ) )
2326
+ $key = "`t`.`{$object_field}`";
2327
+ }
2328
+ }
2329
+ }
2330
+ elseif ( isset( $this->fields[ $k ] ) ) {
2331
+ if ( 'table' == $this->pod_data[ 'storage' ] )
2332
+ $key = "`t`.`{$k}`";
2333
+ else
2334
+ $key = "`{$k}`.`meta_value`";
2335
+ }
2336
+
2337
+ $prefix_orderby = "{$key} {$dir}";
2338
+ }
2339
+ }
2340
+ }
2341
+
2342
+ $this->data->select( $params );
2343
+
2344
+ return $this;
2345
+ }
2346
+
2347
+ /**
2348
+ * Fetch an item from a Pod. If $id is null, it will return the next item in the list after running find().
2349
+ * You can rewind the list back to the start by using reset().
2350
+ *
2351
+ * Providing an $id will fetch a specific item from a Pod, much like a call to pods(), and can handle either an id or slug.
2352
+ *
2353
+ * @see PodsData::fetch
2354
+ *
2355
+ * @param int $id ID or slug of the item to fetch
2356
+ * @param bool $explicit_set Whether to set explicitly (use false when in loop)
2357
+ *
2358
+ * @return array An array of fields from the row
2359
+ *
2360
+ * @since 2.0
2361
+ * @link http://pods.io/docs/fetch/
2362
+ */
2363
+ public function fetch ( $id = null, $explicit_set = true ) {
2364
+ /**
2365
+ * Runs directly before an item is fetched by fetch()
2366
+ *
2367
+ * @since unknown
2368
+ *
2369
+ * @param int|string|null $id Item ID being fetched or null.
2370
+ * @param object|Pods $this Current Pods object.
2371
+ */
2372
+ do_action( 'pods_pods_fetch', $id, $this );
2373
+
2374
+ if ( !empty( $id ) )
2375
+ $this->params = array();
2376
+
2377
+ $this->data->fetch( $id, $explicit_set );
2378
+
2379
+ return $this->row;
2380
+ }
2381
+
2382
+ /**
2383
+ * (Re)set the MySQL result pointer
2384
+ *
2385
+ * @see PodsData::reset
2386
+ *
2387
+ * @param int $row ID of the row to reset to
2388
+ *
2389
+ * @return \Pods The pod object
2390
+ *
2391
+ * @since 2.0
2392
+ * @link http://pods.io/docs/reset/
2393
+ */
2394
+ public function reset ( $row = null ) {
2395
+ /**
2396
+ * Runs directly before the Pods object is reset by reset()
2397
+ *
2398
+ * @since unknown
2399
+ *
2400
+ * @param int|string|null The ID of the row being reset to or null if being reset to the beginningg.
2401
+ * @param object|Pods $this Current Pods object.
2402
+ */
2403
+ do_action( 'pods_pods_reset', $row, $this );
2404
+
2405
+ $this->data->reset( $row );
2406
+
2407
+ return $this;
2408
+ }
2409
+
2410
+ /**
2411
+ * Fetch the total row count returned by the last call to find(), based on the 'limit' parameter set.
2412
+ *
2413
+ * This is different than the total number of rows found in the database, which you can get with total_found().
2414
+ *
2415
+ * @see PodsData::total
2416
+ *
2417
+ * @return int Number of rows returned by find(), based on the 'limit' parameter set
2418
+ * @since 2.0
2419
+ * @link http://pods.io/docs/total/
2420
+ */
2421
+ public function total () {
2422
+ do_action( 'pods_pods_total', $this );
2423
+
2424
+ $this->data->total();
2425
+
2426
+ $this->total =& $this->data->total;
2427
+
2428
+ return $this->total;
2429
+ }
2430
+
2431
+ /**
2432
+ * Fetch the total amount of rows found by the last call to find(), regardless of the 'limit' parameter set.
2433
+ *
2434
+ * This is different than the total number of rows limited by the current call, which you can get with total().
2435
+ *
2436
+ * @see PodsData::total_found
2437
+ *
2438
+ * @return int Number of rows returned by find(), regardless of the 'limit' parameter
2439
+ * @since 2.0
2440
+ * @link http://pods.io/docs/total-found/
2441
+ */
2442
+ public function total_found () {
2443
+ /**
2444
+ * Runs directly before the value of total_found() is determined and returned.
2445
+ *
2446
+ * @since unknown
2447
+ *
2448
+ * @param object|Pods $this Current Pods object.
2449
+ *
2450
+ */
2451
+ do_action( 'pods_pods_total_found', $this );
2452
+
2453
+ $this->data->total_found();
2454
+
2455
+ $this->total_found =& $this->data->total_found;
2456
+
2457
+ return $this->total_found;
2458
+ }
2459
+
2460
+ /**
2461
+ * Fetch the total number of pages, based on total rows found and the last find() limit
2462
+ *
2463
+ * @param null|int $limit Rows per page
2464
+ * @param null|int $offset Offset of rows
2465
+ * @param null|int $total Total rows
2466
+ *
2467
+ * @return int Number of pages
2468
+ * @since 2.3.10
2469
+ */
2470
+ public function total_pages( $limit = null, $offset = null, $total = null ) {
2471
+
2472
+ $this->do_hook( 'total_pages' );
2473
+
2474
+ if ( null === $limit ) {
2475
+ $limit = $this->limit;
2476
+ }
2477
+
2478
+ if ( null === $offset ) {
2479
+ $offset = $this->offset;
2480
+ }
2481
+
2482
+ if ( null === $total ) {
2483
+ $total = $this->total_found();
2484
+ }
2485
+
2486
+ $total_pages = ceil( ( $total - $offset ) / $limit );
2487
+
2488
+ return $total_pages;
2489
+
2490
+ }
2491
+
2492
+ /**
2493
+ * Fetch the zebra switch
2494
+ *
2495
+ * @see PodsData::zebra
2496
+ *
2497
+ * @return bool Zebra state
2498
+ * @since 1.12
2499
+ */
2500
+ public function zebra () {
2501
+ $this->do_hook( 'zebra' );
2502
+
2503
+ return $this->data->zebra();
2504
+ }
2505
+
2506
+ /**
2507
+ * Fetch the nth state
2508
+ *
2509
+ * @see PodsData::nth
2510
+ *
2511
+ * @param int|string $nth The $nth to match on the PodsData::row_number
2512
+ *
2513
+ * @return bool Whether $nth matches
2514
+ * @since 2.3
2515
+ */
2516
+ public function nth ( $nth = null ) {
2517
+ $this->do_hook( 'nth', $nth );
2518
+
2519
+ return $this->data->nth( $nth );
2520
+ }
2521
+
2522
+ /**
2523
+ * Fetch the current position in the loop (starting at 1)
2524
+ *
2525
+ * @see PodsData::position
2526
+ *
2527
+ * @return int Current row number (+1)
2528
+ * @since 2.3
2529
+ */
2530
+ public function position () {
2531
+ $this->do_hook( 'position' );
2532
+
2533
+ return $this->data->position();
2534
+ }
2535
+
2536
+ /**
2537
+ * Add an item to a Pod by giving an array of field data or set a specific field to
2538
+ * a specific value if you're just wanting to add a new item but only set one field.
2539
+ *
2540
+ * You may be looking for save() in most cases where you're setting a specific field.
2541
+ *
2542
+ * @see PodsAPI::save_pod_item
2543
+ *
2544
+ * @param array|string $data Either an associative array of field information or a field name
2545
+ * @param mixed $value (optional) Value of the field, if $data is a field name
2546
+ *
2547
+ * @return int The item ID
2548
+ *
2549
+ * @since 2.0
2550
+ * @link http://pods.io/docs/add/
2551
+ */
2552
+ public function add ( $data = null, $value = null ) {
2553
+ if ( null !== $value )
2554
+ $data = array( $data => $value );
2555
+
2556
+ $data = (array) $this->do_hook( 'add', $data );
2557
+
2558
+ if ( empty( $data ) )
2559
+ return 0;
2560
+
2561
+ $params = array(
2562
+ 'pod' => $this->pod,
2563
+ 'data' => $data,
2564
+ 'allow_custom_fields' => true
2565
+ );
2566
+
2567
+ return $this->api->save_pod_item( $params );
2568
+ }
2569
+
2570
+ /**
2571
+ * Add an item to the values of a relationship field, add a value to a number field (field+1), add time to a date field, or add text to a text field
2572
+ *
2573
+ * @see PodsAPI::save_pod_item
2574
+ *
2575
+ * @param string $field Field name
2576
+ * @param mixed $value ID(s) to add, int|float to add to number field, string for dates (+1 week), or string for text
2577
+ * @param int $id (optional) ID of the pod item to update
2578
+ *
2579
+ * @return int The item ID
2580
+ *
2581
+ * @since 2.3
2582
+ */
2583
+ public function add_to ( $field, $value, $id = null ) {
2584
+ $pod =& $this;
2585
+
2586
+ $fetch = false;
2587
+
2588
+ if ( null === $id ) {
2589
+ $fetch = true;
2590
+
2591
+ $id = $pod->id();
2592
+ }
2593
+ elseif ( $id != $this->id() ) {
2594
+ $pod = pods( $this->pod, $id );
2595
+ }
2596
+
2597
+ $this->do_hook( 'add_to', $field, $value, $id );
2598
+
2599
+ if ( !isset( $this->fields[ $field ] ) )
2600
+ return $id;
2601
+
2602
+ // Tableless fields
2603
+ if ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::tableless_field_types() ) ) {
2604
+ if ( !is_array( $value ) )
2605
+ $value = explode( ',', $value );
2606
+
2607
+ if ( 'pick' == $this->fields[ $field ][ 'type' ] && in_array( $this->fields[ $field ][ 'pick_object' ], PodsForm::simple_tableless_objects() ) ) {
2608
+ $current_value = $pod->raw( $field );
2609
+
2610
+ if ( !empty( $current_value ) || ( !is_array( $current_value ) && 0 < strlen( $current_value ) ) )
2611
+ $current_value = (array) $current_value;
2612
+ else
2613
+ $current_value = array();
2614
+
2615
+ $value = array_merge( $current_value, $value );
2616
+ }
2617
+ else {
2618
+ $related_ids = $this->api->lookup_related_items( $this->fields[ $field ][ 'id' ], $this->pod_data[ 'id' ], $id, $this->fields[ $field ], $this->pod_data );
2619
+
2620
+ foreach ( $value as $k => $v ) {
2621
+ if ( !preg_match( '/[^0-9]/', $v ) )
2622
+ $value[ $k ] = (int) $v;
2623
+ }
2624
+
2625
+ $value = array_merge( $related_ids, $value );
2626
+ }
2627
+
2628
+ if ( !empty( $value ) )
2629
+ $value = array_filter( array_unique( $value ) );
2630
+ else
2631
+ $value = array();
2632
+
2633
+ if ( empty( $value ) )
2634
+ return $id;
2635
+ }
2636
+ // Number fields
2637
+ elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::number_field_types() ) ) {
2638
+ $current_value = (float) $pod->raw( $field );
2639
+
2640
+ $value = ( $current_value + (float) $value );
2641
+ }
2642
+ // Date fields
2643
+ elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::date_field_types() ) ) {
2644
+ $current_value = $pod->raw( $field );
2645
+
2646
+ if ( 0 < strlen( $current_value ) )
2647
+ $value = strtotime( $value, strtotime( $current_value ) );
2648
+ else
2649
+ $value = strtotime( $value );
2650
+ }
2651
+ // Text fields
2652
+ elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::text_field_types() ) ) {
2653
+ $current_value = $pod->raw( $field );
2654
+
2655
+ if ( 0 < strlen( $current_value ) )
2656
+ $value = $current_value . $value;
2657
+ }
2658
+
2659
+ // @todo handle object fields and taxonomies
2660
+
2661
+ $params = array(
2662
+ 'pod' => $this->pod,
2663
+ 'id' => $id,
2664
+ 'data' => array(
2665
+ $field => $value
2666
+ )
2667
+ );
2668
+
2669
+ $id = $this->api->save_pod_item( $params );
2670
+
2671
+ if ( 0 < $id && $fetch ) {
2672
+ // Clear local var cache of field values
2673
+ $pod->data->row = array();
2674
+
2675
+ $pod->fetch( $id, false );
2676
+ }
2677
+
2678
+ return $id;
2679
+ }
2680
+
2681
+ /**
2682
+ * Remove an item from the values of a relationship field, remove a value from a number field (field-1), remove time to a date field
2683
+ *
2684
+ * @see PodsAPI::save_pod_item
2685
+ *
2686
+ * @param string $field Field name
2687
+ * @param mixed $value ID(s) to add, int|float to add to number field, string for dates (-1 week), or string for text
2688
+ * @param int $id (optional) ID of the pod item to update
2689
+ *
2690
+ * @return int The item ID
2691
+ *
2692
+ * @since 2.3.3
2693
+ */
2694
+ public function remove_from( $field, $value = null, $id = null ) {
2695
+ $pod =& $this;
2696
+
2697
+ $fetch = false;
2698
+
2699
+ if ( null === $id ) {
2700
+ $fetch = true;
2701
+
2702
+ $id = $this->id();
2703
+ }
2704
+ elseif ( $id != $this->id() ) {
2705
+ $pod = pods( $this->pod, $id );
2706
+ }
2707
+
2708
+ $this->do_hook( 'remove_from', $field, $value, $id );
2709
+
2710
+ if ( !isset( $this->fields[ $field ] ) ) {
2711
+ return $id;
2712
+ }
2713
+
2714
+ // Tableless fields
2715
+ if ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::tableless_field_types() ) ) {
2716
+ if ( empty( $value ) ) {
2717
+ $value = array();
2718
+ }
2719
+
2720
+ if ( !empty( $value ) ) {
2721
+ if ( !is_array( $value ) ) {
2722
+ $value = explode( ',', $value );
2723
+ }
2724
+
2725
+ if ( 'pick' == $this->fields[ $field ][ 'type' ] && in_array( $this->fields[ $field ][ 'pick_object' ], PodsForm::simple_tableless_objects() ) ) {
2726
+ $current_value = $pod->raw( $field );
2727
+
2728
+ if ( !empty( $current_value ) ) {
2729
+ $current_value = (array) $current_value;
2730
+ }
2731
+
2732
+ foreach ( $current_value as $k => $v ) {
2733
+ if ( in_array( $v, $value ) ) {
2734
+ unset( $current_value[ $k ] );
2735
+ }
2736
+ }
2737
+
2738
+ $value = $current_value;
2739
+ }
2740
+ else {
2741
+ $related_ids = $this->api->lookup_related_items( $this->fields[ $field ][ 'id' ], $this->pod_data[ 'id' ], $id, $this->fields[ $field ], $this->pod_data );
2742
+
2743
+ foreach ( $value as $k => $v ) {
2744
+ if ( !preg_match( '/[^0-9]/', $v ) ) {
2745
+ $value[ $k ] = (int) $v;
2746
+ }
2747
+ // @todo Convert slugs into IDs
2748
+ else {
2749
+
2750
+ }
2751
+ }
2752
+
2753
+ foreach ( $related_ids as $k => $v ) {
2754
+ if ( in_array( $v, $value ) ) {
2755
+ unset( $related_ids[ $k ] );
2756
+ }
2757
+ }
2758
+
2759
+ $value = $related_ids;
2760
+ }
2761
+
2762
+ if ( !empty( $value ) ) {
2763
+ $value = array_filter( array_unique( $value ) );
2764
+ }
2765
+ else {
2766
+ $value = array();
2767
+ }
2768
+ }
2769
+ }
2770
+ // Number fields
2771
+ elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::number_field_types() ) ) {
2772
+ // Date fields don't support empty for removing
2773
+ if ( empty( $value ) ) {
2774
+ return $id;
2775
+ }
2776
+
2777
+ $current_value = (float) $pod->raw( $field );
2778
+
2779
+ $value = ( $current_value - (float) $value );
2780
+ }
2781
+ // Date fields
2782
+ elseif ( in_array( $this->fields[ $field ][ 'type' ], PodsForm::date_field_types() ) ) {
2783
+ // Date fields don't support empty for removing
2784
+ if ( empty( $value ) ) {
2785
+ return $id;
2786
+ }
2787
+
2788
+ $current_value = $pod->raw( $field );
2789
+
2790
+ if ( 0 < strlen( $current_value ) ) {
2791
+ $value = strtotime( $value, strtotime( $current_value ) );
2792
+ }
2793
+ else {
2794
+ $value = strtotime( $value );
2795
+ }
2796
+
2797
+ $value = date_i18n( 'Y-m-d h:i:s', $value );
2798
+ }
2799
+
2800
+ // @todo handle object fields and taxonomies
2801
+
2802
+ $params = array(
2803
+ 'pod' => $this->pod,
2804
+ 'id' => $id,
2805
+ 'data' => array(
2806
+ $field => $value
2807
+ )
2808
+ );
2809
+
2810
+ $id = $this->api->save_pod_item( $params );
2811
+
2812
+ if ( 0 < $id && $fetch ) {
2813
+ // Clear local var cache of field values
2814
+ $pod->data->row = array();
2815
+
2816
+ $pod->fetch( $id, false );
2817
+ }
2818
+
2819
+ return $id;
2820
+
2821
+ }
2822
+
2823
+ /**
2824
+ * Save an item by giving an array of field data or set a specific field to a specific value.
2825
+ *
2826
+ * Though this function has the capacity to add new items, best practice should direct you
2827
+ * to use add() for that instead.
2828
+ *
2829
+ * @see PodsAPI::save_pod_item
2830
+ *
2831
+ * @param array|string $data Either an associative array of field information or a field name
2832
+ * @param mixed $value (optional) Value of the field, if $data is a field name
2833
+ * @param int $id (optional) ID of the pod item to update
2834
+ * @param array $params (optional) Additional params to send to save_pod_item
2835
+ *
2836
+ * @return int The item ID
2837
+ *
2838
+ * @since 2.0
2839
+ * @link http://pods.io/docs/save/
2840
+ */
2841
+ public function save ( $data = null, $value = null, $id = null, $params = null ) {
2842
+ if ( null !== $value )
2843
+ $data = array( $data => $value );
2844
+
2845
+ $fetch = false;
2846
+
2847
+ if ( null === $id || ( $this->row && $id == $this->id() ) ) {
2848
+ $fetch = true;
2849
+
2850
+ if ( null === $id ) {
2851
+ $id = $this->id();
2852
+ }
2853
+ }
2854
+
2855
+ $data = (array) $this->do_hook( 'save', $data, $id );
2856
+
2857
+ if ( empty( $data ) && empty( $params['is_new_item'] ) )
2858
+ return $id;
2859
+
2860
+ $default = array();
2861
+
2862
+ if ( !empty( $params ) && is_array( $params ) )
2863
+ $default = $params;
2864
+
2865
+ $params = array(
2866
+ 'pod' => $this->pod,
2867
+ 'id' => $id,
2868
+ 'data' => $data,
2869
+ 'allow_custom_fields' => true,
2870
+ 'clear_slug_cache' => false
2871
+ );
2872
+
2873
+ if ( !empty( $default ) )
2874
+ $params = array_merge( $params, $default );
2875
+
2876
+ $id = $this->api->save_pod_item( $params );
2877
+
2878
+ if ( 0 < $id && $fetch ) {
2879
+ // Clear local var cache of field values
2880
+ $this->data->row = array();
2881
+
2882
+ $this->fetch( $id, false );
2883
+ }
2884
+
2885
+ if ( !empty( $this->pod_data[ 'field_slug' ] ) ) {
2886
+ if ( 0 < $id && $fetch ) {
2887
+ $slug = $this->field( $this->pod_data[ 'field_slug' ] );
2888
+ }
2889
+ else {
2890
+ $slug = pods( $this->pod, $id )->field( $this->pod_data[ 'field_slug' ] );
2891
+ }
2892
+
2893
+ if ( 0 < strlen( $slug ) ) {
2894
+ pods_cache_clear( $slug, 'pods_items_' . $this->pod );
2895
+ }
2896
+ }
2897
+
2898
+ return $id;
2899
+ }
2900
+
2901
+ /**
2902
+ * Delete an item
2903
+ *
2904
+ * @see PodsAPI::delete_pod_item
2905
+ *
2906
+ * @param int $id ID of the Pod item to delete
2907
+ *
2908
+ * @return bool Whether the item was successfully deleted
2909
+ *
2910
+ * @since 2.0
2911
+ * @link http://pods.io/docs/delete/
2912
+ */
2913
+ public function delete ( $id = null ) {
2914
+ if ( null === $id )
2915
+ $id = $this->id();
2916
+
2917
+ $id = (int) $this->do_hook( 'delete', $id );
2918
+
2919
+ if ( empty( $id ) )
2920
+ return false;
2921
+
2922
+ $params = array(
2923
+ 'pod' => $this->pod,
2924
+ 'id' => $id
2925
+ );
2926
+
2927
+ return $this->api->delete_pod_item( $params );
2928
+ }
2929
+
2930
+ /**
2931
+ * Reset Pod
2932
+ *
2933
+ * @see PodsAPI::reset_pod
2934
+ *
2935
+ * @return bool Whether the Pod was successfully reset
2936
+ *
2937
+ * @since 2.1.1
2938
+ */
2939
+ public function reset_pod () {
2940
+ $params = array( 'id' => $this->pod_id );
2941
+
2942
+ $this->data->id = null;
2943
+ $this->data->row = array();
2944
+ $this->data->data = array();
2945
+
2946
+ $this->data->total = 0;
2947
+ $this->data->total_found = 0;
2948
+
2949
+ return $this->api->reset_pod( $params );
2950
+ }
2951
+
2952
+ /**
2953
+ * Duplicate an item
2954
+ *
2955
+ * @see PodsAPI::duplicate_pod_item
2956
+ *
2957
+ * @param int $id ID of the pod item to duplicate
2958
+ *
2959
+ * @return int|bool ID of the new pod item
2960
+ *
2961
+ * @since 2.0
2962
+ * @link http://pods.io/docs/duplicate/
2963
+ */
2964
+ public function duplicate ( $id = null ) {
2965
+ if ( null === $id )
2966
+ $id = $this->id();
2967
+
2968
+ $id = (int) $this->do_hook( 'duplicate', $id );
2969
+
2970
+ if ( empty( $id ) )
2971
+ return false;
2972
+
2973
+ $params = array(
2974
+ 'pod' => $this->pod,
2975
+ 'id' => $id
2976
+ );
2977
+
2978
+ return $this->api->duplicate_pod_item( $params );
2979
+ }
2980
+
2981
+ /**
2982
+ * Import data / Save multiple rows of data at once
2983
+ *
2984
+ * @see PodsAPI::import
2985
+ *
2986
+ * @param mixed $import_data PHP associative array or CSV input
2987
+ * @param bool $numeric_mode Use IDs instead of the name field when matching
2988
+ * @param string $format Format of import data, options are php or csv
2989
+ *
2990
+ * @return array IDs of imported items
2991
+ *
2992
+ * @since 2.3
2993
+ */
2994
+ public function import ( $import_data, $numeric_mode = false, $format = null ) {
2995
+ return $this->api->import( $import_data, $numeric_mode, $format );
2996
+ }
2997
+
2998
+ /**
2999
+ * Export an item's data
3000
+ *
3001
+ * @see PodsAPI::export_pod_item
3002
+ *
3003
+ * @param array $fields (optional) Fields to export
3004
+ * @param int $id (optional) ID of the pod item to export
3005
+ *
3006
+ * @return array|bool Data array of the exported pod item
3007
+ *
3008
+ * @since 2.0
3009
+ * @link http://pods.io/docs/export/
3010
+ */
3011
+ public function export ( $fields = null, $id = null, $format = null ) {
3012
+ $params = array(
3013
+ 'pod' => $this->pod,
3014
+ 'id' => $id,
3015
+ 'fields' => null,
3016
+ 'depth' => 2,
3017
+ 'flatten' => false
3018
+ );
3019
+
3020
+ if ( is_array( $fields ) && ( isset( $fields[ 'fields' ] ) || isset( $fields[ 'depth' ] ) ) )
3021
+ $params = array_merge( $params, $fields );
3022
+ else
3023
+ $params[ 'fields' ] = $fields;
3024
+
3025
+ if ( isset( $params[ 'fields' ] ) && is_array( $params[ 'fields' ] ) && !in_array( $this->pod_data[ 'field_id' ], $params[ 'fields' ] ) )
3026
+ $params[ 'fields' ] = array_merge( array( $this->pod_data[ 'field_id' ] ), $params[ 'fields' ] );
3027
+
3028
+ if ( null === $params[ 'id' ] )
3029
+ $params[ 'id' ] = $this->id();
3030
+
3031
+ $params = (array) $this->do_hook( 'export', $params );
3032
+
3033
+ if ( empty( $params[ 'id' ] ) )
3034
+ return false;
3035
+
3036
+ $data = $this->api->export_pod_item( $params );
3037
+
3038
+ if ( !empty( $format ) ) {
3039
+ if ( 'json' == $format )
3040
+ $data = json_encode( (array) $data );
3041
+ // @todo more formats
3042
+ }
3043
+
3044
+ return $data;
3045
+ }
3046
+
3047
+ /**
3048
+ * Export data from all items
3049
+ *
3050
+ * @see PodsAPI::export
3051
+ *
3052
+ * @param array $params An associative array of parameters
3053
+ *
3054
+ * @return array Data arrays of all exported pod items
3055
+ *
3056
+ * @since 2.3
3057
+ */
3058
+ public function export_data ( $params = null ) {
3059
+ $defaults = array(
3060
+ 'fields' => null,
3061
+ 'depth' => 2,
3062
+ 'params' => null
3063
+ );
3064
+
3065
+ if ( empty( $params ) )
3066
+ $params = $defaults;
3067
+ else
3068
+ $params = array_merge( $defaults, (array) $params );
3069
+
3070
+ return $this->api->export( $this, $params );
3071
+ }
3072
+
3073
+ /**
3074
+ * Display the pagination controls, types supported by default
3075
+ * are simple, paginate and advanced. The base and format parameters
3076
+ * are used only for the paginate view.
3077
+ *
3078
+ * @var array $params Associative array of parameters
3079
+ *
3080
+ * @return string Pagination HTML
3081
+ * @since 2.0
3082
+ * @link http://pods.io/docs/pagination/
3083
+ */
3084
+ public function pagination( $params = null ) {
3085
+
3086
+ if ( empty( $params ) ) {
3087
+ $params = array();
3088
+ }
3089
+ elseif ( !is_array( $params ) ) {
3090
+ $params = array( 'label' => $params );
3091
+ }
3092
+
3093
+ $this->page_var = pods_var_raw( 'page_var', $params, $this->page_var );
3094
+
3095
+ $url = pods_query_arg( null, null, $this->page_var );
3096
+
3097
+ $append = '?';
3098
+
3099
+ if ( false !== strpos( $url, '?' ) ) {
3100
+ $append = '&';
3101
+ }
3102
+
3103
+ $defaults = array(
3104
+ 'type' => 'advanced',
3105
+ 'label' => __( 'Go to page:', 'pods' ),
3106
+ 'show_label' => true,
3107
+ 'first_text' => __( '&laquo; First', 'pods' ),
3108
+ 'prev_text' => __( '&lsaquo; Previous', 'pods' ),
3109
+ 'next_text' => __( 'Next &rsaquo;', 'pods' ),
3110
+ 'last_text' => __( 'Last &raquo;', 'pods' ),
3111
+ 'prev_next' => true,
3112
+ 'first_last' => true,
3113
+ 'limit' => (int) $this->limit,
3114
+ 'offset' => (int) $this->offset,
3115
+ 'page' => max( 1, (int) $this->page ),
3116
+ 'mid_size' => 2,
3117
+ 'end_size' => 1,
3118
+ 'total_found' => $this->total_found(),
3119
+ 'page_var' => $this->page_var,
3120
+ 'base' => "{$url}{$append}%_%",
3121
+ 'format' => "{$this->page_var}=%#%",
3122
+ 'class' => '',
3123
+ 'link_class' => ''
3124
+ );
3125
+
3126
+ $params = (object) array_merge( $defaults, $params );
3127
+
3128
+ $params->total = $this->total_pages( $params->limit, $params->offset, $params->total_found );
3129
+
3130
+ if ( $params->limit < 1 || $params->total_found < 1 || 1 == $params->total || $params->total_found <= $params->offset ) {
3131
+ return $this->do_hook( 'pagination', $this->do_hook( 'pagination_' . $params->type, '', $params ), $params );
3132
+ }
3133
+
3134
+ $pagination = $params->type;
3135
+
3136
+ if ( !in_array( $params->type, array( 'simple', 'advanced', 'paginate', 'list' ) ) ) {
3137
+ $pagination = 'advanced';
3138
+ }
3139
+
3140
+ ob_start();
3141
+
3142
+ pods_view( PODS_DIR . 'ui/front/pagination/' . $pagination . '.php', compact( array_keys( get_defined_vars() ) ) );
3143
+
3144
+ $output = ob_get_clean();
3145
+
3146
+ return $this->do_hook( 'pagination', $this->do_hook( 'pagination_' . $params->type, $output, $params ), $params );
3147
+
3148
+ }
3149
+
3150
+ /**
3151
+ * Return a filter form for searching a Pod
3152
+ *
3153
+ * @var array|string $params Comma-separated list of fields or array of parameters
3154
+ *
3155
+ * @return string Filters HTML
3156
+ *
3157
+ * @since 2.0
3158
+ * @link http://pods.io/docs/filters/
3159
+ */
3160
+ public function filters ( $params = null ) {
3161
+ $defaults = array(
3162
+ 'fields' => $params,
3163
+ 'label' => '',
3164
+ 'action' => '',
3165
+ 'search' => ''
3166
+ );
3167
+
3168
+ if ( is_array( $params ) )
3169
+ $params = array_merge( $defaults, $params );
3170
+ else
3171
+ $params = $defaults;
3172
+
3173
+ $pod =& $this;
3174
+
3175
+ $params = apply_filters( 'pods_filters_params', $params, $pod );
3176
+
3177
+ $fields = $params[ 'fields' ];
3178
+
3179
+ if ( null !== $fields && !is_array( $fields ) && 0 < strlen( $fields ) )
3180
+ $fields = explode( ',', $fields );
3181
+
3182
+ $object_fields = (array) pods_var_raw( 'object_fields', $this->pod_data, array(), null, true );
3183
+
3184
+ // Force array
3185
+ if ( empty( $fields ) )
3186
+ $fields = array();
3187
+ else {
3188
+ $filter_fields = $fields; // Temporary
3189
+
3190
+ $fields = array();
3191
+
3192
+ foreach ( $filter_fields as $k => $field ) {
3193
+ $name = $k;
3194
+
3195
+ $defaults = array(
3196
+ 'name' => $name
3197
+ );
3198
+
3199
+ if ( !is_array( $field ) ) {
3200
+ $name = $field;
3201
+
3202
+ $field = array(
3203
+ 'name' => $name
3204
+ );
3205
+ }
3206
+
3207
+ $field = array_merge( $defaults, $field );
3208
+
3209
+ $field[ 'name' ] = trim( $field[ 'name' ] );
3210
+
3211
+ if ( pods_var_raw( 'hidden', $field, false, null, true ) )
3212
+ $field[ 'type' ] = 'hidden';
3213
+
3214
+ if ( isset( $object_fields[ $field[ 'name' ] ] ) )
3215
+ $fields[ $field[ 'name' ] ] = array_merge( $object_fields[ $field[ 'name' ] ], $field );
3216
+ elseif ( isset( $this->fields[ $field[ 'name' ] ] ) )
3217
+ $fields[ $field[ 'name' ] ] = array_merge( $this->fields[ $field[ 'name' ] ], $field );
3218
+ }
3219
+
3220
+ unset( $filter_fields ); // Cleanup
3221
+ }
3222
+
3223
+ $this->filters = array_keys( $fields );
3224
+
3225
+ $label = $params[ 'label' ];
3226
+
3227
+ if ( strlen( $label ) < 1 )
3228
+ $label = __( 'Search', 'pods' );
3229
+
3230
+ $action = $params[ 'action' ];
3231
+
3232
+ $search = trim( $params[ 'search' ] );
3233
+
3234
+ if ( strlen( $search ) < 1 )
3235
+ $search = pods_var_raw( $pod->search_var, 'get', '' );
3236
+
3237
+ ob_start();
3238
+
3239
+ pods_view( PODS_DIR . 'ui/front/filters.php', compact( array_keys( get_defined_vars() ) ) );
3240
+
3241
+ $output = ob_get_clean();
3242
+
3243
+ /**
3244
+ * Filter the HTML output of filters()
3245
+ *
3246
+ * @since unknown
3247
+ *
3248
+ * @param string $output
3249
+ * @param array $params Params array passed to filters().
3250
+ * @param object|Pods $this Current Pods object.
3251
+ */
3252
+ return apply_filters( 'pods_pods_filters', $output, $params, $this );
3253
+ }
3254
+
3255
+ /**
3256
+ * Run a helper within a Pod Page or WP Template
3257
+ *
3258
+ * @see Pods_Helpers::helper
3259
+ *
3260
+ * @param string $helper Helper name
3261
+ * @param string $value Value to run the helper on
3262
+ * @param string $name Field name
3263
+ *
3264
+ * @return mixed Anything returned by the helper
3265
+ * @since 2.0
3266
+ */
3267
+ public function helper ( $helper, $value = null, $name = null ) {
3268
+ $params = array(
3269
+ 'helper' => $helper,
3270
+ 'value' => $value,
3271
+ 'name' => $name,
3272
+ 'deprecated' => false
3273
+ );
3274
+
3275
+ if ( class_exists( 'Pods_Templates' ) )
3276
+ $params[ 'deprecated' ] = Pods_Templates::$deprecated;
3277
+
3278
+ if ( is_array( $helper ) )
3279
+ $params = array_merge( $params, $helper );
3280
+
3281
+ if ( class_exists( 'Pods_Helpers' ) )
3282
+ $value = Pods_Helpers::helper( $params, $this );
3283
+ elseif ( function_exists( $params[ 'helper' ] ) )
3284
+ $value = call_user_func( $params[ 'helper' ], $value );
3285
+ else
3286
+ $value = apply_filters( $params[ 'helper' ], $value );
3287
+
3288
+ return $value;
3289
+ }
3290
+
3291
+ /**
3292
+ * Display the page template
3293
+ *
3294
+ * @see Pods_Templates::template
3295
+ *
3296
+ * @param string $template The template name
3297
+ * @param string $code Custom template code to use instead
3298
+ * @param bool $deprecated Whether to use deprecated functionality based on old function usage
3299
+ *
3300
+ * @return mixed Template output
3301
+ *
3302
+ * @since 2.0
3303
+ * @link http://pods.io/docs/template/
3304
+ */
3305
+ public function template ( $template_name, $code = null, $deprecated = false ) {
3306
+ $out = null;
3307
+
3308
+ $obj =& $this;
3309
+
3310
+ if ( !empty( $code ) ) {
3311
+ $code = str_replace( '$this->', '$obj->', $code ); // backwards compatibility
3312
+
3313
+ $code = apply_filters( 'pods_templates_pre_template', $code, $template_name, $this );
3314
+ $code = apply_filters( "pods_templates_pre_template_{$template_name}", $code, $template_name, $this );
3315
+
3316
+ ob_start();
3317
+
3318
+ if ( !empty( $code ) ) {
3319
+ // Only detail templates need $this->id
3320
+ if ( empty( $this->id ) ) {
3321
+ while ( $this->fetch() ) {
3322
+ echo $this->do_magic_tags( $code );
3323
+ }
3324
+ }
3325
+ else
3326
+ echo $this->do_magic_tags( $code );
3327
+ }
3328
+
3329
+ $out = ob_get_clean();
3330
+
3331
+ $out = apply_filters( 'pods_templates_post_template', $out, $code, $template_name, $this );
3332
+ $out = apply_filters( "pods_templates_post_template_{$template_name}", $out, $code, $template_name, $this );
3333
+ }
3334
+ elseif ( class_exists( 'Pods_Templates' ) )
3335
+ $out = Pods_Templates::template( $template_name, $code, $this, $deprecated );
3336
+ elseif ( $template_name == trim( preg_replace( '/[^a-zA-Z0-9_\-\/]/', '', $template_name ), ' /-' ) ) {
3337
+ ob_start();
3338
+
3339
+ $default_templates = array(
3340
+ 'pods/' . $template_name,
3341
+ 'pods-' . $template_name,
3342
+ $template_name
3343
+ );
3344
+
3345
+ $default_templates = apply_filters( 'pods_template_default_templates', $default_templates );
3346
+
3347
+ // Only detail templates need $this->id
3348
+ if ( empty( $this->id ) ) {
3349
+ while ( $this->fetch() ) {
3350
+ pods_template_part( $default_templates, compact( array_keys( get_defined_vars() ) ) );
3351
+ }
3352
+ }
3353
+ else
3354
+ pods_template_part( $default_templates, compact( array_keys( get_defined_vars() ) ) );
3355
+
3356
+ $out = ob_get_clean();
3357
+
3358
+ $out = apply_filters( 'pods_templates_post_template', $out, $code, $template_name, $this );
3359
+ $out = apply_filters( "pods_templates_post_template_{$template_name}", $out, $code, $template_name, $this );
3360
+ }
3361
+
3362
+ return $out;
3363
+ }
3364
+
3365
+ /**
3366
+ * Embed a form to add / edit a pod item from within your theme. Provide an array of $fields to include
3367
+ * and override options where needed. For WP object based Pods, you can pass through the WP object
3368
+ * field names too, such as "post_title" or "post_content" for example.
3369
+ *
3370
+ * @param array $params (optional) Fields to show on the form, defaults to all fields
3371
+ * @param string $label (optional) Save button label, defaults to "Save Changes"
3372
+ * @param string $thank_you (optional) Thank you URL to send to upon success
3373
+ *
3374
+ * @return bool|mixed
3375
+ * @since 2.0
3376
+ * @link http://pods.io/docs/form/
3377
+ */
3378
+ public function form ( $params = null, $label = null, $thank_you = null ) {
3379
+ $defaults = array(
3380
+ 'fields' => $params,
3381
+ 'label' => $label,
3382
+ 'thank_you' => $thank_you,
3383
+ 'fields_only' => false
3384
+ );
3385
+
3386
+ if ( is_array( $params ) )
3387
+ $params = array_merge( $defaults, $params );
3388
+ else
3389
+ $params = $defaults;
3390
+
3391
+ $pod =& $this;
3392
+
3393
+ $params = $this->do_hook( 'form_params', $params );
3394
+
3395
+ $fields = $params[ 'fields' ];
3396
+
3397
+ if ( null !== $fields && !is_array( $fields ) && 0 < strlen( $fields ) )
3398
+ $fields = explode( ',', $fields );
3399
+
3400
+ $object_fields = (array) pods_var_raw( 'object_fields', $this->pod_data, array(), null, true );
3401
+
3402
+ if ( empty( $fields ) ) {
3403
+ // Add core object fields if $fields is empty
3404
+ $fields = array_merge( $object_fields, $this->fields );
3405
+ }
3406
+
3407
+ $form_fields = $fields; // Temporary
3408
+
3409
+ $fields = array();
3410
+
3411
+ foreach ( $form_fields as $k => $field ) {
3412
+ $name = $k;
3413
+
3414
+ $defaults = array(
3415
+ 'name' => $name
3416
+ );
3417
+
3418
+ if ( !is_array( $field ) ) {
3419
+ $name = $field;
3420
+
3421
+ $field = array(
3422
+ 'name' => $name
3423
+ );
3424
+ }
3425
+
3426
+ $field = array_merge( $defaults, $field );
3427
+
3428
+ $field[ 'name' ] = trim( $field[ 'name' ] );
3429
+
3430
+ $default_value = pods_var_raw( 'default', $field );
3431
+ $value = pods_var_raw( 'value', $field );
3432
+
3433
+ if ( empty( $field[ 'name' ] ) )
3434
+ $field[ 'name' ] = trim( $name );
3435
+
3436
+ if ( isset( $object_fields[ $field[ 'name' ] ] ) ) {
3437
+ $field = array_merge( $object_fields[ $field[ 'name' ] ], $field );
3438
+ }
3439
+ elseif ( isset( $this->fields[ $field[ 'name' ] ] ) ) {
3440
+ $field = array_merge( $this->fields[ $field[ 'name' ] ], $field );
3441
+ }
3442
+
3443
+ if ( pods_var_raw( 'hidden', $field, false, null, true ) )
3444
+ $field[ 'type' ] = 'hidden';
3445
+
3446
+ $fields[ $field[ 'name' ] ] = $field;
3447
+
3448
+ if ( empty( $this->id ) && null !== $default_value ) {
3449
+ $this->row_override[ $field[ 'name' ] ] = $default_value;
3450
+ }
3451
+ elseif ( !empty( $this->id ) && null !== $value ) {
3452
+ $this->row[ $field[ 'name' ] ] = $value;
3453
+ }
3454
+ }
3455
+
3456
+ unset( $form_fields ); // Cleanup
3457
+
3458
+ $fields = $this->do_hook( 'form_fields', $fields, $params );
3459
+
3460
+ $label = $params[ 'label' ];
3461
+
3462
+ if ( empty( $label ) )
3463
+ $label = __( 'Save Changes', 'pods' );
3464
+
3465
+ $thank_you = $params[ 'thank_you' ];
3466
+ $fields_only = $params[ 'fields_only' ];
3467
+
3468
+ PodsForm::$form_counter++;
3469
+
3470
+ ob_start();
3471
+
3472
+ if ( empty( $thank_you ) ) {
3473
+ $success = 'success';
3474
+
3475
+ if ( 1 < PodsForm::$form_counter )
3476
+ $success .= PodsForm::$form_counter;
3477
+
3478
+ $thank_you = pods_query_arg( array( 'success*' => null, $success => 1 ) );
3479
+
3480
+ if ( 1 == pods_v( $success, 'get', 0 ) ) {
3481
+ $message = __( 'Form submitted successfully', 'pods' );
3482
+ /**
3483
+ * Change the text of the message that appears on succesful form submission.
3484
+ *
3485
+ * @param string $message
3486
+ *
3487
+ * @returns string the message
3488
+ *
3489
+ * @since 3.0.0
3490
+ */
3491
+ $message = apply_filters( 'pods_pod_form_success_message', $message );
3492
+
3493
+ echo '<div id="message" class="pods-form-front-success">' . $message . '</div>';
3494
+ }
3495
+ }
3496
+
3497
+ pods_view( PODS_DIR . 'ui/front/form.php', compact( array_keys( get_defined_vars() ) ) );
3498
+
3499
+ $output = ob_get_clean();
3500
+
3501
+ if ( empty( $this->id ) )
3502
+ $this->row_override = array();
3503
+
3504
+ return $this->do_hook( 'form', $output, $fields, $label, $thank_you, $this, $this->id() );
3505
+ }
3506
+
3507
+ /**
3508
+ * @param array $fields (optional) Fields to show in the view, defaults to all fields
3509
+ *
3510
+ * @return mixed
3511
+ * @since 2.3.10
3512
+ */
3513
+ public function view( $fields = null ) {
3514
+
3515
+ $pod =& $this;
3516
+
3517
+ // Convert comma separated list of fields to an array
3518
+ if ( null !== $fields && !is_array( $fields ) && 0 < strlen( $fields ) ) {
3519
+ $fields = explode( ',', $fields );
3520
+ }
3521
+
3522
+ $object_fields = (array) pods_v( 'object_fields', $this->pod_data, array(), true );
3523
+
3524
+ if ( empty( $fields ) ) {
3525
+ // Add core object fields if $fields is empty
3526
+ $fields = array_merge( $object_fields, $this->fields );
3527
+ }
3528
+
3529
+ $view_fields = $fields; // Temporary
3530
+
3531
+ $fields = array();
3532
+
3533
+ foreach ( $view_fields as $name => $field ) {
3534
+
3535
+ $defaults = array(
3536
+ 'name' => $name
3537
+ );
3538
+
3539
+ if ( !is_array( $field ) ) {
3540
+ $name = $field;
3541
+
3542
+ $field = array(
3543
+ 'name' => $name
3544
+ );
3545
+ }
3546
+
3547
+ $field = array_merge( $defaults, $field );
3548
+
3549
+ $field[ 'name' ] = trim( $field[ 'name' ] );
3550
+
3551
+ if ( empty( $field[ 'name' ] ) ) {
3552
+ $field[ 'name' ] = trim( $name );
3553
+ }
3554
+
3555
+ if ( isset( $object_fields[ $field[ 'name' ] ] ) )
3556
+ $field = array_merge( $field, $object_fields[ $field[ 'name' ] ] );
3557
+ elseif ( isset( $this->fields[ $field[ 'name' ] ] ) )
3558
+ $field = array_merge( $this->fields[ $field[ 'name' ] ], $field );
3559
+
3560
+ if ( pods_v( 'hidden', $field, false, null, true ) || 'hidden' == $field[ 'type' ] ) {
3561
+ continue;
3562
+ }
3563
+ elseif ( !PodsForm::permission( $field[ 'type' ], $field[ 'name' ], $field[ 'options' ], $fields, $pod, $pod->id() ) ) {
3564
+ continue;
3565
+ }
3566
+
3567
+ $fields[ $field[ 'name' ] ] = $field;
3568
+ }
3569
+
3570
+ unset( $view_fields ); // Cleanup
3571
+
3572
+ $output = pods_view( PODS_DIR . 'ui/front/view.php', compact( array_keys( get_defined_vars() ) ), false, 'cache', true );
3573
+
3574
+ return $this->do_hook( 'view', $output, $fields, $this->id() );
3575
+
3576
+ }
3577
+
3578
+ /**
3579
+ * Replace magic tags with their values
3580
+ *
3581
+ * @param string $code The content to evaluate
3582
+ * @param object $obj The Pods object
3583
+ *
3584
+ * @return string Code with Magic Tags evaluated
3585
+ *
3586
+ * @since 2.0
3587
+ */
3588
+ public function do_magic_tags ( $code ) {
3589
+ return preg_replace_callback( '/({@(.*?)})/m', array( $this, 'process_magic_tags' ), $code );
3590
+ }
3591
+
3592
+ /**
3593
+ * Replace magic tags with their values
3594
+ *
3595
+ * @param string $tag The magic tag to process
3596
+ * @param object $obj The Pods object
3597
+ *
3598
+ * @return string Code with Magic Tags evaluated
3599
+ *
3600
+ * @since 2.0.2
3601
+ */
3602
+ private function process_magic_tags ( $tag ) {
3603
+
3604
+ if ( is_array( $tag ) ) {
3605
+ if ( !isset( $tag[ 2 ] ) && strlen( trim( $tag[ 2 ] ) ) < 1 )
3606
+ return '';
3607
+
3608
+ $tag = $tag[ 2 ];
3609
+ }
3610
+
3611
+ $tag = trim( $tag, ' {@}' );
3612
+ $tag = explode( ',', $tag );
3613
+
3614
+ if ( empty( $tag ) || !isset( $tag[ 0 ] ) || strlen( trim( $tag[ 0 ] ) ) < 1 )
3615
+ return '';
3616
+
3617
+ foreach ( $tag as $k => $v ) {
3618
+ $tag[ $k ] = trim( $v );
3619
+ }
3620
+
3621
+ $field_name = $tag[ 0 ];
3622
+
3623
+ $helper_name = $before = $after = '';
3624
+
3625
+ if ( isset( $tag[ 1 ] ) && !empty( $tag[ 1 ] ) ) {
3626
+ $value = $this->field( $field_name );
3627
+
3628
+ $helper_name = $tag[ 1 ];
3629
+
3630
+ $value = $this->helper( $helper_name, $value, $field_name );
3631
+ }
3632
+ else
3633
+ $value = $this->display( $field_name );
3634
+
3635
+ if ( isset( $tag[ 2 ] ) && !empty( $tag[ 2 ] ) )
3636
+ $before = $tag[ 2 ];
3637
+
3638
+ if ( isset( $tag[ 3 ] ) && !empty( $tag[ 3 ] ) )
3639
+ $after = $tag[ 3 ];
3640
+
3641
+ $value = apply_filters( 'pods_do_magic_tags', $value, $field_name, $helper_name, $before, $after );
3642
+
3643
+ if ( is_array( $value ) )
3644
+ $value = pods_serial_comma( $value, array( 'field' => $field_name, 'fields' => $this->fields ) );
3645
+
3646
+ if ( null !== $value && false !== $value )
3647
+ return $before . $value . $after;
3648
+
3649
+ return '';
3650
+ }
3651
+
3652
+ /**
3653
+ *
3654
+ * Generate UI for Data Management
3655
+ *
3656
+ * @param mixed $options Array or String containing Pod or Options to be used
3657
+ * @param bool $amend Whether to amend the default UI options or replace entirely
3658
+ *
3659
+ * @return PodsUI|void UI object or void if custom UI used
3660
+ *
3661
+ * @since 2.3.10
3662
+ */
3663
+ public function ui ( $options = null, $amend = false ) {
3664
+ $num = '';
3665
+
3666
+ if ( empty( $options ) )
3667
+ $options = array();
3668
+ else {
3669
+ $num = pods_var( 'num', $options, '' );
3670
+
3671
+ if ( empty( $num ) ) {
3672
+ $num = '';
3673
+ }
3674
+ }
3675
+
3676
+ if ( $this->id() != pods_var( 'id' . $num, 'get', null, null, true ) )
3677
+ $this->fetch( pods_var( 'id' . $num, 'get', null, null, true ) );
3678
+
3679
+ if ( !empty( $options ) && !$amend ) {
3680
+ $this->ui = $options;
3681
+
3682
+ return pods_ui( $this );
3683
+ }
3684
+ elseif ( !empty( $options ) || 'custom' != pods_var( 'ui_style', $this->pod_data[ 'options' ], 'post_type', null, true ) ) {
3685
+ $actions_enabled = pods_var_raw( 'ui_actions_enabled', $this->pod_data[ 'options' ] );
3686
+
3687
+ if ( !empty( $actions_enabled ) )
3688
+ $actions_enabled = (array) $actions_enabled;
3689
+ else
3690
+ $actions_enabled = array();
3691
+
3692
+ $available_actions = array(
3693
+ 'add',
3694
+ 'edit',
3695
+ 'duplicate',
3696
+ 'delete',
3697
+ 'reorder',
3698
+ 'export'
3699
+ );
3700
+
3701
+ if ( !empty( $actions_enabled ) ) {
3702
+ $actions_disabled = array(
3703
+ 'view' => 'view'
3704
+ );
3705
+
3706
+ foreach ( $available_actions as $action ) {
3707
+ if ( !in_array( $action, $actions_enabled ) )
3708
+ $actions_disabled[ $action ] = $action;
3709
+ }
3710
+ }
3711
+ else {
3712
+ $actions_disabled = array(
3713
+ 'duplicate' => 'duplicate',
3714
+ 'view' => 'view',
3715
+ 'export' => 'export'
3716
+ );
3717
+
3718
+ if ( 1 == pods_var( 'ui_export', $this->pod_data[ 'options' ], 0 ) )
3719
+ unset( $actions_disabled[ 'export' ] );
3720
+ }
3721
+
3722
+ if ( empty( $options ) ) {
3723
+ $author_restrict = false;
3724
+
3725
+ if ( isset( $this->fields[ 'author' ] ) && 'pick' == $this->fields[ 'author' ][ 'type' ] && 'user' == $this->fields[ 'author' ][ 'pick_object' ] )
3726
+ $author_restrict = 'author.ID';
3727
+
3728
+ if ( !pods_is_admin( array( 'pods', 'pods_content' ) ) ) {
3729
+ if ( !current_user_can( 'pods_add_' . $this->pod ) ) {
3730
+ $actions_disabled[ 'add' ] = 'add';
3731
+
3732
+ if ( 'add' == pods_var( 'action' . $num, 'get' ) )
3733
+ $_GET[ 'action' . $num ] = 'manage';
3734
+ }
3735
+
3736
+ if ( !$author_restrict && !current_user_can( 'pods_edit_' . $this->pod ) && !current_user_can( 'pods_edit_others_' . $this->pod ) )
3737
+ $actions_disabled[ 'edit' ] = 'edit';
3738
+
3739
+ if ( !$author_restrict && !current_user_can( 'pods_delete_' . $this->pod ) && !current_user_can( 'pods_delete_others_' . $this->pod ) )
3740
+ $actions_disabled[ 'delete' ] = 'delete';
3741
+
3742
+ if ( !current_user_can( 'pods_reorder_' . $this->pod ) )
3743
+ $actions_disabled[ 'reorder' ] = 'reorder';
3744
+
3745
+ if ( !current_user_can( 'pods_export_' . $this->pod ) )
3746
+ $actions_disabled[ 'export' ] = 'export';
3747
+ }
3748
+ }
3749
+
3750
+ $_GET[ 'action' . $num ] = pods_var( 'action' . $num, 'get', pods_var( 'action', $options, 'manage' ) );
3751
+
3752
+ $index = $this->pod_data[ 'field_id' ];
3753
+ $label = __( 'ID', 'pods' );
3754
+
3755
+ if ( isset( $this->pod_data[ 'fields' ][ $this->pod_data[ 'field_index' ] ] ) ) {
3756
+ $index = $this->pod_data[ 'field_index' ];
3757
+ $label = $this->pod_data[ 'fields' ][ $this->pod_data[ 'field_index' ] ];
3758
+ }
3759
+
3760
+ $manage = array(
3761
+ $index => $label
3762
+ );
3763
+
3764
+ if ( isset( $this->pod_data[ 'fields' ][ 'modified' ] ) )
3765
+ $manage[ 'modified' ] = $this->pod_data[ 'fields' ][ 'modified' ][ 'label' ];
3766
+
3767
+ $manage_fields = pods_var_raw( 'ui_fields_manage', $this->pod_data[ 'options' ] );
3768
+
3769
+ if ( !empty( $manage_fields ) ) {
3770
+ $manage_new = array();
3771
+
3772
+ foreach ( $manage_fields as $manage_field ) {
3773
+ if ( isset( $this->pod_data[ 'fields' ][ $manage_field ] ) )
3774
+ $manage_new[ $manage_field ] = $this->pod_data[ 'fields' ][ $manage_field ];
3775
+ elseif ( isset( $this->pod_data[ 'object_fields' ][ $manage_field ] ) )
3776
+ $manage_new[ $manage_field ] = $this->pod_data[ 'object_fields' ][ $manage_field ];
3777
+ elseif ( $manage_field == $this->pod_data[ 'field_id' ] ) {
3778
+ $field = array(
3779
+ 'name' => $manage_field,
3780
+ 'label' => 'ID',
3781
+ 'type' => 'number',
3782
+ 'width' => '8%'
3783
+ );
3784
+
3785
+ $manage_new[ $manage_field ] = PodsForm::field_setup( $field, null, $field[ 'type' ] );
3786
+ }
3787
+ }
3788
+
3789
+ if ( !empty( $manage_new ) )
3790
+ $manage = $manage_new;
3791
+ }
3792
+
3793
+ $manage = apply_filters( 'pods_admin_ui_fields_' . $this->pod, apply_filters( 'pods_admin_ui_fields', $manage, $this->pod, $this ), $this->pod, $this );
3794
+
3795
+ $icon = pods_var_raw( 'ui_icon', $this->pod_data[ 'options' ] );
3796
+
3797
+ if ( !empty( $icon ) )
3798
+ $icon = pods_image_url( $icon, '32x32' );
3799
+
3800
+ $filters = pods_var_raw( 'ui_filters', $this->pod_data[ 'options' ] );
3801
+
3802
+ if ( !empty( $filters ) ) {
3803
+ $filters_new = array();
3804
+
3805
+ $filters = (array) $filters;
3806
+
3807
+ foreach ( $filters as $filter_field ) {
3808
+ if ( isset( $this->pod_data[ 'fields' ][ $filter_field ] ) )
3809
+ $filters_new[ $filter_field ] = $this->pod_data[ 'fields' ][ $filter_field ];
3810
+ elseif ( isset( $this->pod_data[ 'object_fields' ][ $filter_field ] ) )
3811
+ $filters_new[ $filter_field ] = $this->pod_data[ 'object_fields' ][ $filter_field ];
3812
+ }
3813
+
3814
+ $filters = $filters_new;
3815
+ }
3816
+
3817
+ $ui = array(
3818
+ 'fields' => array(
3819
+ 'manage' => $manage,
3820
+ 'add' => $this->pod_data[ 'fields' ],
3821
+ 'edit' => $this->pod_data[ 'fields' ],
3822
+ 'duplicate' => $this->pod_data[ 'fields' ]
3823
+ ),
3824
+ 'icon' => $icon,
3825
+ 'actions_disabled' => $actions_disabled
3826
+ );
3827
+
3828
+ if ( !empty( $filters ) ) {
3829
+ $ui[ 'fields' ][ 'search' ] = $filters;
3830
+ $ui[ 'filters' ] = array_keys( $filters );
3831
+ $ui[ 'filters_enhanced' ] = true;
3832
+ }
3833
+
3834
+ $reorder_field = pods_var_raw( 'ui_reorder_field', $this->pod_data[ 'options' ] );
3835
+
3836
+ if ( in_array( 'reorder', $actions_enabled ) && !in_array( 'reorder', $actions_disabled ) && !empty( $reorder_field ) && ( ( !empty( $this->pod_data[ 'object_fields' ] ) && isset( $this->pod_data[ 'object_fields' ][ $reorder_field ] ) ) || isset( $this->pod_data[ 'fields' ][ $reorder_field ] ) ) ) {
3837
+ $ui[ 'reorder' ] = array( 'on' => $reorder_field );
3838
+ $ui[ 'orderby' ] = $reorder_field;
3839
+ $ui[ 'orderby_dir' ] = 'ASC';
3840
+ }
3841
+
3842
+ if ( !empty( $author_restrict ) )
3843
+ $ui[ 'restrict' ] = array( 'author_restrict' => $author_restrict );
3844
+
3845
+ if ( !in_array( 'delete', $ui[ 'actions_disabled' ] ) ) {
3846
+ $ui[ 'actions_bulk' ] = array(
3847
+ 'delete' => array(
3848
+ 'label' => __( 'Delete', 'pods' )
3849
+ // callback not needed, Pods has this built-in for delete
3850
+ )
3851
+ );
3852
+ }
3853
+
3854
+ $detail_url = pods_var( 'detail_url', $this->pod_data[ 'options' ] );
3855
+
3856
+ if ( 0 < strlen( $detail_url ) ) {
3857
+ $ui[ 'actions_custom' ] = array(
3858
+ 'view_url' => array(
3859
+ 'label' => 'View',
3860
+ 'link' => get_site_url() . '/' . $detail_url
3861
+ )
3862
+ );
3863
+ }
3864
+
3865
+ // @todo Customize the Add New / Manage links to point to their correct menu items
3866
+
3867
+ $ui = apply_filters( 'pods_admin_ui_' . $this->pod, apply_filters( 'pods_admin_ui', $ui, $this->pod, $this ), $this->pod, $this );
3868
+
3869
+ // Override UI options
3870
+ foreach ( $options as $option => $value ) {
3871
+ $ui[ $option ] = $value;
3872
+ }
3873
+
3874
+ $this->ui = $ui;
3875
+
3876
+ return pods_ui( $this );
3877
+ }
3878
+
3879
+ do_action( 'pods_admin_ui_custom', $this );
3880
+ do_action( 'pods_admin_ui_custom_' . $this->pod, $this );
3881
+ }
3882
+
3883
+ /**
3884
+ * Handle filters / actions for the class
3885
+ *
3886
+ * @see pods_do_hook
3887
+ *
3888
+ * @return mixed Value filtered
3889
+ *
3890
+ * @since 2.0
3891
+ */
3892
+ private function do_hook () {
3893
+ $args = func_get_args();
3894
+
3895
+ if ( empty( $args ) )
3896
+ return false;
3897
+
3898
+ $name = array_shift( $args );
3899
+
3900
+ return pods_do_hook( 'pods', $name, $args, $this );
3901
+ }
3902
+
3903
+ /**
3904
+ * Handle variables that have been deprecated and PodsData vars
3905
+ *
3906
+ * @var $name
3907
+ *
3908
+ * @return mixed
3909
+ *
3910
+ * @since 2.0
3911
+ */
3912
+ public function __get ( $name ) {
3913
+ $name = (string) $name;
3914
+
3915
+ // PodsData vars
3916
+ if ( 0 === strpos( $name, 'field_' ) && isset( $this->data->{$name} ) ) {
3917
+ return $this->data->{$name};
3918
+ }
3919
+
3920
+ if ( !isset( $this->deprecated ) ) {
3921
+ require_once( PODS_DIR . 'deprecated/classes/Pods.php' );
3922
+ $this->deprecated = new Pods_Deprecated( $this );
3923
+ }
3924
+
3925
+ $var = null;
3926
+
3927
+ if ( isset( $this->deprecated->{$name} ) ) {
3928
+ if ( ! class_exists( 'Pod' ) || Pod::$deprecated_notice ) {
3929
+ pods_deprecated( "Pods->{$name}", '2.0' );
3930
+ }
3931
+
3932
+ $var = $this->deprecated->{$name};
3933
+ }
3934
+ elseif ( ! class_exists( 'Pod' ) || Pod::$deprecated_notice ) {
3935
+ pods_deprecated( "Pods->{$name}", '2.0' );
3936
+ }
3937
+
3938
+ return $var;
3939
+ }
3940
+
3941
+ /**
3942
+ * Handle methods that have been deprecated and any aliasing
3943
+ *
3944
+ * @var $name
3945
+ * @var $args
3946
+ *
3947
+ * @return mixed
3948
+ *
3949
+ * @since 2.0
3950
+ */
3951
+ public function __call ( $name, $args ) {
3952
+ $name = (string) $name;
3953
+
3954
+ // select > find alias
3955
+ if ( 'select' == $name ) {
3956
+ return call_user_func_array( array( $this, 'find' ), $args );
3957
+ }
3958
+
3959
+ if ( !isset( $this->deprecated ) ) {
3960
+ require_once( PODS_DIR . 'deprecated/classes/Pods.php' );
3961
+ $this->deprecated = new Pods_Deprecated( $this );
3962
+ }
3963
+
3964
+ if ( method_exists( $this->deprecated, $name ) ) {
3965
+ return call_user_func_array( array( $this->deprecated, $name ), $args );
3966
+ }
3967
+ elseif ( ! class_exists( 'Pod' ) || Pod::$deprecated_notice ) {
3968
+ pods_deprecated( "Pods::{$name}", '2.0' );
3969
+ }
3970
+ }
3971
+ }
classes/PodsAPI.php ADDED
@@ -0,0 +1,8663 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Pods
4
+ */
5
+ class PodsAPI {
6
+
7
+ /**
8
+ * @var PodsAPI
9
+ */
10
+ static $instance = null;
11
+
12
+ /**
13
+ * @var array PodsAPI
14
+ */
15
+ static $instances = array();
16
+
17
+
18
+ /**
19
+ * @var bool
20
+ */
21
+ public $display_errors = false;
22
+
23
+ /**
24
+ * @var array|bool|mixed|null|void
25
+ */
26
+ public $pod_data;
27
+
28
+ /**
29
+ * @var
30
+ */
31
+ public $pod;
32
+
33
+ /**
34
+ * @var
35
+ */
36
+ public $pod_id;
37
+
38
+ /**
39
+ * @var
40
+ */
41
+ public $fields;
42
+
43
+ /**
44
+ * @var
45
+ * @deprecated 2.0
46
+ */
47
+ public $format = null;
48
+
49
+ /**
50
+ * @var
51
+ */
52
+ private $deprecated;
53
+
54
+ /**
55
+ * @var array
56
+ * @since 2.5
57
+ */
58
+ private $fields_cache = array();
59
+
60
+ /**
61
+ * @var array
62
+ * @since 2.5
63
+ *
64
+ */
65
+ private static $table_info_cache = array();
66
+
67
+ /**
68
+ * @var array
69
+ * @since 2.5
70
+ *
71
+ */
72
+ private static $related_item_cache = array();
73
+
74
+ /**
75
+ * Singleton-ish handling for a basic pods_api() request
76
+ *
77
+ * @param string $pod (optional) The pod name
78
+ * @param string $format (deprecated) Format for import/export, "php" or "csv"
79
+ *
80
+ * @return \PodsAPI
81
+ *
82
+ * @since 2.3.5
83
+ */
84
+ public static function init ( $pod = null, $format = null ) {
85
+ if ( null !== $pod || null !== $format ) {
86
+ if ( ! isset( self::$instances[ $pod ] ) ) {
87
+ // Cache API singleton per Pod
88
+ self::$instances[ $pod ] = new PodsAPI( $pod, $format );
89
+ }
90
+ return self::$instances[ $pod ];
91
+ }
92
+ elseif ( !is_object( self::$instance ) ) {
93
+ self::$instance = new PodsAPI();
94
+ }
95
+
96
+ return self::$instance;
97
+ }
98
+
99
+
100
+ /**
101
+ * Store and retrieve data programatically
102
+ *
103
+ * @param string $pod (optional) The pod name
104
+ * @param string $format (deprecated) Format for import/export, "php" or "csv"
105
+ *
106
+ * @return \PodsAPI
107
+ *
108
+ * @license http://www.gnu.org/licenses/gpl-2.0.html
109
+ * @since 1.7.1
110
+ */
111
+ public function __construct ( $pod = null, $format = null ) {
112
+ if ( null !== $pod && 0 < strlen( (string) $pod ) ) {
113
+ if ( null !== $format ) {
114
+ $this->format = $format;
115
+
116
+ pods_deprecated( 'pods_api( $pod, $format )', '2.0', 'pods_api( $pod )' );
117
+ }
118
+
119
+ $pod = pods_clean_name( $pod );
120
+
121
+ $pod = $this->load_pod( array( 'name' => $pod, 'table_info' => true ), false );
122
+
123
+ if ( !empty( $pod ) ) {
124
+ $this->pod_data = $pod;
125
+ $this->pod = $pod[ 'name' ];
126
+ $this->pod_id = $pod[ 'id' ];
127
+ $this->fields = $pod[ 'fields' ];
128
+ }
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Save a WP object and its meta
134
+ *
135
+ * @param string $object_type Object type: post|taxonomy|user|comment|setting
136
+ * @param array $data All post data to be saved
137
+ * @param array $meta (optional) Associative array of meta keys and values
138
+ * @param bool $strict (optional) Decides whether the previous saved meta should be deleted or not
139
+ * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
140
+ * @param array $fields (optional) The array of fields and their options, for further processing with
141
+ *
142
+ * @return bool|mixed
143
+ *
144
+ * @since 2.0
145
+ */
146
+ public function save_wp_object ( $object_type, $data, $meta = array(), $strict = false, $sanitized = false, $fields = array() ) {
147
+ if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
148
+ $object_type = 'post';
149
+
150
+ if ( 'taxonomy' == $object_type )
151
+ $object_type = 'term';
152
+
153
+ if ( $sanitized ) {
154
+ $data = pods_unsanitize( $data );
155
+ $meta = pods_unsanitize( $meta );
156
+ }
157
+
158
+ if ( in_array( $object_type, array( 'post', 'term', 'user', 'comment' ) ) )
159
+ return call_user_func( array( $this, 'save_' . $object_type ), $data, $meta, $strict, false, $fields );
160
+ elseif ( 'settings' == $object_type ) {
161
+ // Nothing to save
162
+ if ( empty( $meta ) )
163
+ return true;
164
+
165
+ return $this->save_setting( pods_var( 'option_id', $data ), $meta, false );
166
+ }
167
+
168
+ return false;
169
+ }
170
+
171
+ /**
172
+ * Delete a WP object
173
+ *
174
+ * @param string $object_type Object type: post|user|comment
175
+ * @param int $id Object ID
176
+ * @param bool $force_delete (optional) Force deletion instead of trashing (post types only)
177
+ *
178
+ * @return bool|mixed
179
+ *
180
+ * @since 2.0
181
+ */
182
+ public function delete_wp_object ( $object_type, $id, $force_delete = true ) {
183
+ if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
184
+ $object_type = 'post';
185
+
186
+ if ( 'taxonomy' == $object_type )
187
+ $object_type = 'term';
188
+
189
+ if ( empty( $id ) )
190
+ return false;
191
+
192
+ if ( in_array( $object_type, array( 'post' ) ) )
193
+ return wp_delete_post( $id, $force_delete );
194
+
195
+ if ( function_exists( 'wp_delete_' . $object_type ) )
196
+ return call_user_func( 'wp_delete_' . $object_type, $id );
197
+
198
+ return false;
199
+ }
200
+
201
+ /**
202
+ * Save a post and it's meta
203
+ *
204
+ * @param array $post_data All post data to be saved (using wp_insert_post / wp_update_post)
205
+ * @param array $post_meta (optional) All meta to be saved (set value to null to delete)
206
+ * @param bool $strict (optional) Whether to delete previously saved meta not in $post_meta
207
+ * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
208
+ * @param array $fields (optional) The array of fields and their options, for further processing with
209
+ *
210
+ * @return mixed|void
211
+ *
212
+ * @since 2.0
213
+ */
214
+ public function save_post ( $post_data, $post_meta = null, $strict = false, $sanitized = false, $fields = array() ) {
215
+ $conflicted = pods_no_conflict_check( 'post' );
216
+
217
+ if ( !$conflicted )
218
+ pods_no_conflict_on( 'post' );
219
+
220
+ if ( !is_array( $post_data ) || empty( $post_data ) )
221
+ $post_data = array( 'post_title' => '' );
222
+
223
+ if ( !is_array( $post_meta ) )
224
+ $post_meta = array();
225
+
226
+ if ( $sanitized ) {
227
+ $post_data = pods_unsanitize( $post_data );
228
+ $post_meta = pods_unsanitize( $post_meta );
229
+ }
230
+
231
+ if ( !isset( $post_data[ 'ID' ] ) || empty( $post_data[ 'ID' ] ) )
232
+ $post_data[ 'ID' ] = wp_insert_post( $post_data, true );
233
+ elseif ( 2 < count( $post_data ) || !isset( $post_data[ 'post_type' ] ) )
234
+ $post_data[ 'ID' ] = wp_update_post( $post_data, true );
235
+
236
+ if ( is_wp_error( $post_data[ 'ID' ] ) ) {
237
+ if ( !$conflicted )
238
+ pods_no_conflict_off( 'post' );
239
+
240
+ /**
241
+ * @var $post_error WP_Error
242
+ */
243
+ $post_error = $post_data[ 'ID' ];
244
+
245
+ return pods_error( $post_error->get_error_message(), $this );
246
+ }
247
+
248
+ $this->save_post_meta( $post_data[ 'ID' ], $post_meta, $strict, $fields );
249
+
250
+ if ( !$conflicted )
251
+ pods_no_conflict_off( 'post' );
252
+
253
+ return $post_data[ 'ID' ];
254
+ }
255
+
256
+ /**
257
+ * Save a post's meta
258
+ *
259
+ * @param int $id Post ID
260
+ * @param array $post_meta All meta to be saved (set value to null to delete)
261
+ * @param bool $strict Whether to delete previously saved meta not in $post_meta
262
+ * @param array $fields (optional) The array of fields and their options, for further processing with
263
+ *
264
+ * @return int Id of the post with the meta
265
+ *
266
+ * @since 2.0
267
+ */
268
+ public function save_post_meta ( $id, $post_meta = null, $strict = false, $fields = array() ) {
269
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
270
+
271
+ $conflicted = pods_no_conflict_check( 'post' );
272
+
273
+ if ( !$conflicted )
274
+ pods_no_conflict_on( 'post' );
275
+
276
+ if ( !is_array( $post_meta ) )
277
+ $post_meta = array();
278
+
279
+ $id = (int) $id;
280
+
281
+ $meta = get_post_meta( $id );
282
+
283
+ foreach ( $meta as $k => $value ) {
284
+ if ( is_array( $value ) && 1 == count( $value ) )
285
+ $meta[ $k ] = current( $value );
286
+ }
287
+
288
+ foreach ( $post_meta as $meta_key => $meta_value ) {
289
+ if ( null === $meta_value || ( $strict && '' === $post_meta[ $meta_key ] ) ) {
290
+ $old_meta_value = '';
291
+
292
+ if ( isset( $meta[ $meta_key ] ) )
293
+ $old_meta_value = $meta[ $meta_key ];
294
+
295
+ delete_post_meta( $id, $meta_key, $old_meta_value );
296
+ }
297
+ else {
298
+ $simple = false;
299
+
300
+ if ( isset( $fields[ $meta_key ] ) ) {
301
+ $field_data = $fields[ $meta_key ];
302
+
303
+ $simple = ( 'pick' == $field_data[ 'type' ] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
304
+ }
305
+
306
+ if ( $simple ) {
307
+ delete_post_meta( $id, $meta_key );
308
+
309
+ update_post_meta( $id, '_pods_' . $meta_key, $meta_value );
310
+
311
+ if ( ! is_array( $meta_value ) ) {
312
+ $meta_value = array( $meta_value );
313
+ }
314
+
315
+ foreach ( $meta_value as $value ) {
316
+ add_post_meta( $id, $meta_key, $value );
317
+ }
318
+ }
319
+ else {
320
+ update_post_meta( $id, $meta_key, $meta_value );
321
+ }
322
+ }
323
+ }
324
+
325
+ if ( $strict ) {
326
+ foreach ( $meta as $meta_key => $meta_value ) {
327
+ if ( !isset( $post_meta[ $meta_key ] ) )
328
+ delete_post_meta( $id, $meta_key, $meta_value );
329
+ }
330
+ }
331
+
332
+ if ( !$conflicted )
333
+ pods_no_conflict_off( 'post' );
334
+
335
+ return $id;
336
+ }
337
+
338
+ /**
339
+ * Save a user and it's meta
340
+ *
341
+ * @param array $user_data All user data to be saved (using wp_insert_user / wp_update_user)
342
+ * @param array $user_meta (optional) All meta to be saved (set value to null to delete)
343
+ * @param bool $strict (optional) Whether to delete previously saved meta not in $user_meta
344
+ * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
345
+ * @param array $fields (optional) The array of fields and their options, for further processing with
346
+ *
347
+ * @return int Returns user id on success
348
+ *
349
+ * @since 2.0
350
+ */
351
+ public function save_user ( $user_data, $user_meta = null, $strict = false, $sanitized = false, $fields = array() ) {
352
+ if ( !is_array( $user_data ) || empty( $user_data ) )
353
+ return pods_error( __( 'User data is required but is either invalid or empty', 'pods' ), $this );
354
+
355
+ $conflicted = pods_no_conflict_check( 'user' );
356
+
357
+ if ( !$conflicted )
358
+ pods_no_conflict_on( 'user' );
359
+
360
+ if ( !is_array( $user_meta ) )
361
+ $user_meta = array();
362
+
363
+ if ( $sanitized ) {
364
+ $user_data = pods_unsanitize( $user_data );
365
+ $user_meta = pods_unsanitize( $user_meta );
366
+ }
367
+
368
+ // Set role
369
+ if ( isset( $user_meta[ 'role' ] ) ) {
370
+ $user_data[ 'role' ] = $user_meta[ 'role' ];
371
+
372
+ unset( $user_meta[ 'role' ] );
373
+ }
374
+
375
+ if ( !isset( $user_data[ 'ID' ] ) || empty( $user_data[ 'ID' ] ) )
376
+ $user_data[ 'ID' ] = wp_insert_user( $user_data );
377
+ elseif ( 1 < count( $user_data ) )
378
+ wp_update_user( $user_data );
379
+
380
+ if ( is_wp_error( $user_data[ 'ID' ] ) ) {
381
+ if ( !$conflicted )
382
+ pods_no_conflict_off( 'user' );
383
+
384
+ /**
385
+ * @var $user_error WP_Error
386
+ */
387
+ $user_error = $user_data[ 'ID' ];
388
+
389
+ return pods_error( $user_error->get_error_message(), $this );
390
+ }
391
+
392
+ $this->save_user_meta( $user_data[ 'ID' ], $user_meta, $strict, $fields );
393
+
394
+ if ( !$conflicted )
395
+ pods_no_conflict_off( 'user' );
396
+
397
+ return $user_data[ 'ID' ];
398
+ }
399
+
400
+ /**
401
+ * Save a user meta
402
+ *
403
+ * @param int $id User ID
404
+ * @param array $user_meta (optional) All meta to be saved (set value to null to delete)
405
+ * @param bool $strict (optional) Whether to delete previously saved meta not in $user_meta
406
+ * @param array $fields (optional) The array of fields and their options, for further processing with
407
+ *
408
+ * @return int User ID
409
+ *
410
+ * @since 2.0
411
+ *
412
+ */
413
+ public function save_user_meta ( $id, $user_meta = null, $strict = false, $fields = array() ) {
414
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
415
+
416
+ $conflicted = pods_no_conflict_check( 'user' );
417
+
418
+ if ( !$conflicted )
419
+ pods_no_conflict_on( 'user' );
420
+
421
+ if ( !is_array( $user_meta ) )
422
+ $user_meta = array();
423
+
424
+ $id = (int) $id;
425
+
426
+ $meta = get_user_meta( $id );
427
+
428
+ foreach ( $user_meta as $meta_key => $meta_value ) {
429
+ if ( null === $meta_value ) {
430
+ $old_meta_value = '';
431
+
432
+ if ( isset( $meta[ $meta_key ] ) )
433
+ $old_meta_value = $meta[ $meta_key ];
434
+
435
+ delete_user_meta( $id, $meta_key, $old_meta_value );
436
+ }
437
+ else {
438
+ $simple = false;
439
+
440
+ if ( isset( $fields[ $meta_key ] ) ) {
441
+ $field_data = $fields[ $meta_key ];
442
+
443
+ $simple = ( 'pick' == $field_data[ 'type' ] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
444
+ }
445
+
446
+ if ( $simple ) {
447
+ delete_user_meta( $id, $meta_key );
448
+
449
+ if ( ! is_array( $meta_value ) ) {
450
+ $meta_value = array( $meta_value );
451
+ }
452
+
453
+ foreach ( $meta_value as $value ) {
454
+ add_user_meta( $id, $meta_key, $value );
455
+ }
456
+ }
457
+ else {
458
+ update_user_meta( $id, $meta_key, $meta_value );
459
+ }
460
+ }
461
+ }
462
+
463
+ if ( $strict ) {
464
+ foreach ( $meta as $meta_key => $meta_value ) {
465
+ if ( !isset( $user_meta[ $meta_key ] ) )
466
+ delete_user_meta( $id, $meta_key, $user_meta[ $meta_key ] );
467
+ }
468
+ }
469
+
470
+ if ( !$conflicted )
471
+ pods_no_conflict_off( 'user' );
472
+
473
+ return $id;
474
+ }
475
+
476
+ /**
477
+ * Save a comment and it's meta
478
+ *
479
+ * @param array $comment_data All comment data to be saved (using wp_insert_comment / wp_update_comment)
480
+ * @param array $comment_meta (optional) All meta to be saved (set value to null to delete)
481
+ * @param bool $strict (optional) Whether to delete previously saved meta not in $comment_meta
482
+ * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
483
+ * @param array $fields (optional) The array of fields and their options, for further processing with
484
+ *
485
+ * @return int Comment ID
486
+ *
487
+ * @since 2.0
488
+ */
489
+ public function save_comment ( $comment_data, $comment_meta = null, $strict = false, $sanitized = false, $fields = array() ) {
490
+ if ( !is_array( $comment_data ) || empty( $comment_data ) )
491
+ return pods_error( __( 'Comment data is required but is either invalid or empty', 'pods' ), $this );
492
+
493
+ $conflicted = pods_no_conflict_check( 'comment' );
494
+
495
+ if ( !$conflicted )
496
+ pods_no_conflict_on( 'comment' );
497
+
498
+ if ( !is_array( $comment_meta ) )
499
+ $comment_meta = array();
500
+
501
+ if ( $sanitized ) {
502
+ $comment_data = pods_unsanitize( $comment_data );
503
+ $comment_meta = pods_unsanitize( $comment_meta );
504
+ }
505
+
506
+ if ( !isset( $comment_data[ 'comment_ID' ] ) || empty( $comment_data[ 'comment_ID' ] ) )
507
+ $comment_data[ 'comment_ID' ] = wp_insert_comment( pods_slash( $comment_data ) ); // Expects slashed
508
+ elseif ( 1 < count( $comment_data ) )
509
+ wp_update_comment( $comment_data );
510
+
511
+ if ( is_wp_error( $comment_data[ 'comment_ID' ] ) ) {
512
+ if ( !$conflicted )
513
+ pods_no_conflict_off( 'comment' );
514
+
515
+ /**
516
+ * @var $comment_error WP_Error
517
+ */
518
+ $comment_error = $comment_data[ 'comment_ID' ];
519
+
520
+ return pods_error( $comment_error->get_error_message(), $this );
521
+ }
522
+
523
+ $this->save_comment_meta( $comment_data[ 'comment_ID' ], $comment_meta, $strict, $fields );
524
+
525
+ if ( !$conflicted )
526
+ pods_no_conflict_off( 'comment' );
527
+
528
+ return $comment_data[ 'comment_ID' ];
529
+ }
530
+
531
+ /**
532
+ * Save a comment meta
533
+ *
534
+ * @param int $id Comment ID
535
+ * @param array $comment_meta (optional) All meta to be saved (set value to null to delete)
536
+ * @param bool $strict (optional) Whether to delete previously saved meta not in $comment_meta
537
+ * @param array $fields (optional) The array of fields and their options, for further processing with
538
+ *
539
+ * @return int Comment ID
540
+ *
541
+ * @since 2.0
542
+ */
543
+ public function save_comment_meta ( $id, $comment_meta = null, $strict = false, $fields = array() ) {
544
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
545
+
546
+ $conflicted = pods_no_conflict_check( 'comment' );
547
+
548
+ if ( !$conflicted )
549
+ pods_no_conflict_on( 'comment' );
550
+
551
+ if ( !is_array( $comment_meta ) )
552
+ $comment_meta = array();
553
+
554
+ $id = (int) $id;
555
+
556
+ $meta = get_comment_meta( $id );
557
+
558
+ foreach ( $comment_meta as $meta_key => $meta_value ) {
559
+ if ( null === $meta_value ) {
560
+ $old_meta_value = '';
561
+
562
+ if ( isset( $meta[ $meta_key ] ) )
563
+ $old_meta_value = $meta[ $meta_key ];
564
+
565
+ delete_comment_meta( $id, $meta_key, $old_meta_value );
566
+ }
567
+ else {
568
+ $simple = false;
569
+
570
+ if ( isset( $fields[ $meta_key ] ) ) {
571
+ $field_data = $fields[ $meta_key ];
572
+
573
+ $simple = ( 'pick' == $field_data[ 'type' ] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
574
+ }
575
+
576
+ if ( $simple ) {
577
+ delete_comment_meta( $id, $meta_key );
578
+
579
+ if ( ! is_array( $meta_value ) ) {
580
+ $meta_value = array( $meta_value );
581
+ }
582
+
583
+ foreach ( $meta_value as $value ) {
584
+ add_comment_meta( $id, $meta_key, $value );
585
+ }
586
+ }
587
+ else {
588
+ update_comment_meta( $id, $meta_key, $meta_value );
589
+ }
590
+ }
591
+ }
592
+
593
+ if ( $strict ) {
594
+ foreach ( $meta as $meta_key => $meta_value ) {
595
+ if ( !isset( $comment_meta[ $meta_key ] ) )
596
+ delete_comment_meta( (int) $id, $meta_key, $comment_meta[ $meta_key ] );
597
+ }
598
+ }
599
+
600
+ if ( !$conflicted )
601
+ pods_no_conflict_off( 'comment' );
602
+
603
+ return $id;
604
+ }
605
+
606
+ /**
607
+ * Save a taxonomy's term
608
+ *
609
+ * @param array $term_data All term data to be saved (using wp_insert_term / wp_update_term)
610
+ * @param array $term_meta All meta to be saved (set value to null to delete)
611
+ * @param bool $strict (optional) Whether to delete previously saved meta not in $post_meta
612
+ * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
613
+ * @param array $fields (optional) The array of fields and their options, for further processing with
614
+ *
615
+ * @return int Term ID
616
+ *
617
+ * @since 2.0
618
+ */
619
+ public function save_term ( $term_data, $term_meta, $strict = false, $sanitized = false, $fields = array() ) {
620
+ if ( empty( $term_data['taxonomy'] ) ) {
621
+ return 0;
622
+ }
623
+
624
+ $conflicted = pods_no_conflict_check( 'taxonomy' );
625
+
626
+ if ( !is_array( $term_data ) || empty( $term_data ) )
627
+ $term_data = array( 'name' => '' );
628
+
629
+ if ( !$conflicted )
630
+ pods_no_conflict_on( 'taxonomy' );
631
+
632
+ if ( !is_array( $term_meta ) )
633
+ $term_meta = array();
634
+
635
+ if ( $sanitized ) {
636
+ $term_data = pods_unsanitize( $term_data );
637
+ $term_meta = pods_unsanitize( $term_meta );
638
+ }
639
+
640
+ $taxonomy = $term_data['taxonomy'];
641
+
642
+ unset( $term_data['taxonomy'] );
643
+
644
+ if ( empty( $term_data['term_id'] ) ) {
645
+ $term_name = $term_data['name'];
646
+
647
+ unset( $term_data['name'] );
648
+
649
+ $term_data['term_id'] = wp_insert_term( $term_name, $taxonomy, $term_data );
650
+ } elseif ( 2 < count( $term_data ) ) {
651
+ $term_data['term_id'] = wp_update_term( $term_data['term_id'], $taxonomy, $term_data );
652
+ }
653
+
654
+ if ( is_wp_error( $term_data['term_id'] ) ) {
655
+ if ( !$conflicted )
656
+ pods_no_conflict_off( 'taxonomy' );
657
+
658
+ /**
659
+ * @var $term_error WP_Error
660
+ */
661
+ $term_error = $term_data[ 'term_id' ];
662
+
663
+ return pods_error( $term_error->get_error_message(), $this );
664
+ }
665
+ elseif ( is_array( $term_data['term_id'] ) )
666
+ $term_data['term_id'] = $term_data['term_id'][ 'term_id' ];
667
+
668
+ $this->save_term_meta( $term_data['term_id'], $term_meta, $strict, $fields );
669
+
670
+ if ( !$conflicted )
671
+ pods_no_conflict_off( 'taxonomy' );
672
+
673
+ return $term_data['term_id'];
674
+ }
675
+
676
+ /**
677
+ * Save a term's meta
678
+ *
679
+ * @param int $id Term ID
680
+ * @param array $term_meta All meta to be saved (set value to null to delete)
681
+ * @param bool $strict Whether to delete previously saved meta not in $term_meta
682
+ * @param array $fields (optional) The array of fields and their options, for further processing with
683
+ *
684
+ * @return int Id of the term with the meta
685
+ *
686
+ * @since 2.0
687
+ */
688
+ public function save_term_meta ( $id, $term_meta = null, $strict = false, $fields = array() ) {
689
+ if ( ! function_exists( 'get_term_meta' ) ) {
690
+ return $id;
691
+ }
692
+
693
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
694
+
695
+ $conflicted = pods_no_conflict_check( 'taxonomy' );
696
+
697
+ if ( !$conflicted )
698
+ pods_no_conflict_on( 'taxonomy' );
699
+
700
+ if ( !is_array( $term_meta ) )
701
+ $term_meta = array();
702
+
703
+ $id = (int) $id;
704
+
705
+ $meta = get_term_meta( $id );
706
+
707
+ foreach ( $meta as $k => $value ) {
708
+ if ( is_array( $value ) && 1 == count( $value ) )
709
+ $meta[ $k ] = current( $value );
710
+ }
711
+
712
+ foreach ( $term_meta as $meta_key => $meta_value ) {
713
+ if ( null === $meta_value || ( $strict && '' === $term_meta[ $meta_key ] ) ) {
714
+ $old_meta_value = '';
715
+
716
+ if ( isset( $meta[ $meta_key ] ) )
717
+ $old_meta_value = $meta[ $meta_key ];
718
+
719
+ delete_term_meta( $id, $meta_key, $old_meta_value );
720
+ }
721
+ else {
722
+ $simple = false;
723
+
724
+ if ( isset( $fields[ $meta_key ] ) ) {
725
+ $field_data = $fields[ $meta_key ];
726
+
727
+ $simple = ( 'pick' == $field_data[ 'type' ] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
728
+ }
729
+
730
+ if ( $simple ) {
731
+ delete_term_meta( $id, $meta_key );
732
+
733
+ update_term_meta( $id, '_pods_' . $meta_key, $meta_value );
734
+
735
+ if ( ! is_array( $meta_value ) ) {
736
+ $meta_value = array( $meta_value );
737
+ }
738
+
739
+ foreach ( $meta_value as $value ) {
740
+ add_term_meta( $id, $meta_key, $value );
741
+ }
742
+ }
743
+ else {
744
+ update_term_meta( $id, $meta_key, $meta_value );
745
+ }
746
+ }
747
+ }
748
+
749
+ if ( $strict ) {
750
+ foreach ( $meta as $meta_key => $meta_value ) {
751
+ if ( !isset( $term_meta[ $meta_key ] ) )
752
+ delete_term_meta( $id, $meta_key, $meta_value );
753
+ }
754
+ }
755
+
756
+ if ( !$conflicted )
757
+ pods_no_conflict_off( 'taxonomy' );
758
+
759
+ return $id;
760
+ }
761
+
762
+ /**
763
+ * Save a set of options
764
+ *
765
+ * @param string $setting Setting group name
766
+ * @param array $option_data All option data to be saved
767
+ * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before sending.
768
+ *
769
+ * @return bool
770
+ *
771
+ * @since 2.3
772
+ */
773
+ public function save_setting ( $setting, $option_data, $sanitized = false ) {
774
+ if ( !is_array( $option_data ) || empty( $option_data ) )
775
+ return pods_error( __( 'Setting data is required but is either invalid or empty', 'pods' ), $this );
776
+
777
+ $conflicted = pods_no_conflict_check( 'settings' );
778
+
779
+ if ( !$conflicted )
780
+ pods_no_conflict_on( 'settings' );
781
+
782
+ if ( $sanitized )
783
+ $option_data = pods_unsanitize( $option_data );
784
+
785
+ foreach ( $option_data as $option => $value ) {
786
+ if ( !empty( $setting ) )
787
+ $option = $setting . '_' . $option;
788
+
789
+ update_option( $option, $value );
790
+ }
791
+
792
+ if ( !$conflicted )
793
+ pods_no_conflict_off( 'settings' );
794
+
795
+ return true;
796
+ }
797
+
798
+ /**
799
+ * Rename a WP object's type
800
+ *
801
+ * @param string $object_type Object type: post|taxonomy|comment|setting
802
+ * @param string $old_name The old name
803
+ * @param string $new_name The new name
804
+ *
805
+ * @return bool
806
+ *
807
+ * @since 2.0
808
+ */
809
+ public function rename_wp_object_type ( $object_type, $old_name, $new_name ) {
810
+ /**
811
+ * @var $wpdb wpdb
812
+ */
813
+ global $wpdb;
814
+
815
+ if ( 'post_type' == $object_type )
816
+ $object_type = 'post';
817
+
818
+ if ( 'post' == $object_type ) {
819
+ pods_query( "UPDATE `{$wpdb->posts}` SET `post_type` = %s WHERE `post_type` = %s", array(
820
+ $new_name,
821
+ $old_name
822
+ ) );
823
+ }
824
+ elseif ( 'taxonomy' == $object_type ) {
825
+ pods_query( "UPDATE `{$wpdb->term_taxonomy}` SET `taxonomy` = %s WHERE `taxonomy` = %s", array(
826
+ $new_name,
827
+ $old_name
828
+ ) );
829
+ }
830
+ elseif ( 'comment' == $object_type ) {
831
+ pods_query( "UPDATE `{$wpdb->comments}` SET `comment_type` = %s WHERE `comment_type` = %s", array(
832
+ $new_name,
833
+ $old_name
834
+ ) );
835
+ }
836
+ elseif ( 'settings' == $object_type ) {
837
+ pods_query( "UPDATE `{$wpdb->options}` SET `option_name` = REPLACE( `option_name`, %s, %s ) WHERE `option_name` LIKE '" . pods_sanitize_like( $old_name ) . "_%'", array(
838
+ $new_name . '_',
839
+ $old_name . '_'
840
+ ) );
841
+ }
842
+
843
+ return true;
844
+ }
845
+
846
+ /**
847
+ * Get a list of core WP object fields for a specific object
848
+ *
849
+ * @param string $object The pod type to look for, possible values: post_type, user, comment, taxonomy
850
+ * @param array $pod Array of Pod data
851
+ * @param boolean $refresh Whether to force refresh the information
852
+ *
853
+ * @return array Array of fields
854
+ *
855
+ * @since 2.0
856
+ */
857
+ public function get_wp_object_fields ( $object = 'post_type', $pod = null, $refresh = false ) {
858
+ $pod_name = pods_var_raw( 'name', $pod, $object, null, true );
859
+
860
+ if ( 'media' == $pod_name ) {
861
+ $object = 'post_type';
862
+ $pod_name = 'attachment';
863
+ }
864
+
865
+ $fields = false;
866
+
867
+ if ( pods_api_cache() )
868
+ $fields = pods_transient_get( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ) );
869
+
870
+ if ( false !== $fields && !$refresh )
871
+ return $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
872
+
873
+ $fields = array();
874
+
875
+ if ( 'post_type' == $object ) {
876
+ $fields = array(
877
+ 'ID' => array(
878
+ 'name' => 'ID',
879
+ 'label' => 'ID',
880
+ 'type' => 'number',
881
+ 'alias' => array( 'id' ),
882
+ 'options' => array(
883
+ 'number_format' => '9999.99'
884
+ )
885
+ ),
886
+ 'post_title' => array(
887
+ 'name' => 'post_title',
888
+ 'label' => 'Title',
889
+ 'type' => 'text',
890
+ 'alias' => array( 'title', 'name' ),
891
+ 'options' => array(
892
+ 'display_filter' => 'the_title',
893
+ 'display_filter_args' => array( 'post_ID' )
894
+ )
895
+ ),
896
+ 'post_content' => array(
897
+ 'name' => 'post_content',
898
+ 'label' => 'Content',
899
+ 'type' => 'wysiwyg',
900
+ 'alias' => array( 'content' ),
901
+ 'options' => array(
902
+ 'wysiwyg_allowed_html_tags' => '',
903
+ 'display_filter' => 'the_content',
904
+ 'pre_save' => 0
905
+ )
906
+ ),
907
+ 'post_excerpt' => array(
908
+ 'name' => 'post_excerpt',
909
+ 'label' => 'Excerpt',
910
+ 'type' => 'paragraph',
911
+ 'alias' => array( 'excerpt' ),
912
+ 'options' => array(
913
+ 'paragraph_allow_html' => 1,
914
+ 'paragraph_allowed_html_tags' => '',
915
+ 'display_filter' => 'the_excerpt',
916
+ 'pre_save' => 0
917
+ )
918
+ ),
919
+ 'post_author' => array(
920
+ 'name' => 'post_author',
921
+ 'label' => 'Author',
922
+ 'type' => 'pick',
923
+ 'alias' => array( 'author' ),
924
+ 'pick_object' => 'user',
925
+ 'options' => array(
926
+ 'pick_format_type' => 'single',
927
+ 'pick_format_single' => 'autocomplete',
928
+ 'default_value' => '{@user.ID}'
929
+ )
930
+ ),
931
+ 'post_date' => array(
932
+ 'name' => 'post_date',
933
+ 'label' => 'Publish Date',
934
+ 'type' => 'datetime',
935
+ 'alias' => array( 'created', 'date' )
936
+ ),
937
+ 'post_date_gmt' => array(
938
+ 'name' => 'post_date_gmt',
939
+ 'label' => 'Publish Date (GMT)',
940
+ 'type' => 'datetime',
941
+ 'alias' => array(),
942
+ 'hidden' => true
943
+ ),
944
+ 'post_status' => array(
945
+ 'name' => 'post_status',
946
+ 'label' => 'Status',
947
+ 'type' => 'pick',
948
+ 'pick_object' => 'post-status',
949
+ 'default' => $this->do_hook( 'default_status_' . $pod_name, pods_var( 'default_status', pods_var_raw( 'options', $pod ), 'draft', null, true ), $pod ),
950
+ 'alias' => array( 'status' )
951
+ ),
952
+ 'comment_status' => array(
953
+ 'name' => 'comment_status',
954
+ 'label' => 'Comment Status',
955
+ 'type' => 'text',
956
+ 'default' => get_option( 'default_comment_status', 'open' ),
957
+ 'alias' => array(),
958
+ 'data' => array(
959
+ 'open' => __( 'Open', 'pods' ),
960
+ 'closed' => __( 'Closed', 'pods' )
961
+ )
962
+ ),
963
+ 'ping_status' => array(
964
+ 'name' => 'ping_status',
965
+ 'label' => 'Ping Status',
966
+ 'default' => get_option( 'default_ping_status', 'open' ),
967
+ 'type' => 'text',
968
+ 'alias' => array(),
969
+ 'data' => array(
970
+ 'open' => __( 'Open', 'pods' ),
971
+ 'closed' => __( 'Closed', 'pods' )
972
+ )
973
+ ),
974
+ 'post_password' => array(
975
+ 'name' => 'post_password',
976
+ 'label' => 'Password',
977
+ 'type' => 'text',
978
+ 'alias' => array()
979
+ ),
980
+ 'post_name' => array(
981
+ 'name' => 'post_name',
982
+ 'label' => 'Permalink',
983
+ 'type' => 'slug',
984
+ 'alias' => array( 'slug', 'permalink' )
985
+ ),
986
+ 'to_ping' => array(
987
+ 'name' => 'to_ping',
988
+ 'label' => 'To Ping',
989
+ 'type' => 'text',
990
+ 'alias' => array(),
991
+ 'hidden' => true
992
+ ),
993
+ 'pinged' => array(
994
+ 'name' => 'pinged',
995
+ 'label' => 'Pinged',
996
+ 'type' => 'text',
997
+ 'alias' => array(),
998
+ 'hidden' => true
999
+ ),
1000
+ 'post_modified' => array(
1001
+ 'name' => 'post_modified',
1002
+ 'label' => 'Last Modified Date',
1003
+ 'type' => 'datetime',
1004
+ 'alias' => array( 'modified' ),
1005
+ 'hidden' => true
1006
+ ),
1007
+ 'post_modified_gmt' => array(
1008
+ 'name' => 'post_modified_gmt',
1009
+ 'label' => 'Last Modified Date (GMT)',
1010
+ 'type' => 'datetime',
1011
+ 'alias' => array(),
1012
+ 'hidden' => true
1013
+ ),
1014
+ 'post_content_filtered' => array(
1015
+ 'name' => 'post_content_filtered',
1016
+ 'label' => 'Content (filtered)',
1017
+ 'type' => 'paragraph',
1018
+ 'alias' => array(),
1019
+ 'hidden' => true,
1020
+ 'options' => array(
1021
+ 'paragraph_allow_html' => 1,
1022
+ 'paragraph_oembed' => 1,
1023
+ 'paragraph_wptexturize' => 1,
1024
+ 'paragraph_convert_chars' => 1,
1025
+ 'paragraph_wpautop' => 1,
1026
+ 'paragraph_allow_shortcode' => 1,
1027
+ 'paragraph_allowed_html_tags' => ''
1028
+ )
1029
+ ),
1030
+ 'post_parent' => array(
1031
+ 'name' => 'post_parent',
1032
+ 'label' => 'Parent',
1033
+ 'type' => 'pick',
1034
+ 'pick_object' => 'post_type',
1035
+ 'pick_val' => '__current__',
1036
+ 'alias' => array( 'parent' ),
1037
+ 'data' => array(),
1038
+ 'hidden' => true
1039
+ ),
1040
+ 'guid' => array(
1041
+ 'name' => 'guid',
1042
+ 'label' => 'GUID',
1043
+ 'type' => 'text',
1044
+ 'alias' => array(),
1045
+ 'hidden' => true
1046
+ ),
1047
+ 'menu_order' => array(
1048
+ 'name' => 'menu_order',
1049
+ 'label' => 'Menu Order',
1050
+ 'type' => 'number',
1051
+ 'alias' => array(),
1052
+ 'options' => array(
1053
+ 'number_format' => '9999.99'
1054
+ )
1055
+ ),
1056
+ 'post_type' => array(
1057
+ 'name' => 'post_type',
1058
+ 'label' => 'Type',
1059
+ 'type' => 'text',
1060
+ 'alias' => array( 'type' ),
1061
+ 'hidden' => true
1062
+ ),
1063
+ 'post_mime_type' => array(
1064
+ 'name' => 'post_mime_type',
1065
+ 'label' => 'Mime Type',
1066
+ 'type' => 'text',
1067
+ 'alias' => array(),
1068
+ 'hidden' => true
1069
+ ),
1070
+ 'comment_count' => array(
1071
+ 'name' => 'comment_count',
1072
+ 'label' => 'Comment Count',
1073
+ 'type' => 'number',
1074
+ 'alias' => array(),
1075
+ 'hidden' => true
1076
+ )
1077
+ );
1078
+
1079
+ if ( !empty( $pod ) ) {
1080
+ $taxonomies = get_object_taxonomies( $pod_name, 'objects' );
1081
+
1082
+ foreach ( $taxonomies as $taxonomy ) {
1083
+ $fields[ $taxonomy->name ] = array(
1084
+ 'name' => $taxonomy->name,
1085
+ 'label' => $taxonomy->labels->name,
1086
+ 'type' => 'taxonomy',
1087
+ 'pick_object' => 'taxonomy',
1088
+ 'pick_val' => $taxonomy->name,
1089
+ 'alias' => array(),
1090
+ 'hidden' => true,
1091
+ 'options' => array(
1092
+ 'taxonomy_format_type' => 'multi'
1093
+ )
1094
+ );
1095
+ }
1096
+ }
1097
+ }
1098
+ elseif ( 'user' == $object ) {
1099
+ $fields = array(
1100
+ 'ID' => array(
1101
+ 'name' => 'ID',
1102
+ 'label' => 'ID',
1103
+ 'type' => 'number',
1104
+ 'alias' => array( 'id' ),
1105
+ 'options' => array(
1106
+ 'number_format' => '9999.99'
1107
+ )
1108
+ ),
1109
+ 'user_login' => array(
1110
+ 'name' => 'user_login',
1111
+ 'label' => 'Title',
1112
+ 'type' => 'text',
1113
+ 'alias' => array( 'login' ),
1114
+ 'options' => array(
1115
+ 'required' => 1
1116
+ )
1117
+ ),
1118
+ 'user_nicename' => array(
1119
+ 'name' => 'user_nicename',
1120
+ 'label' => 'Permalink',
1121
+ 'type' => 'slug',
1122
+ 'alias' => array( 'nicename', 'slug', 'permalink' )
1123
+ ),
1124
+ 'display_name' => array(
1125
+ 'name' => 'display_name',
1126
+ 'label' => 'Display Name',
1127
+ 'type' => 'text',
1128
+ 'alias' => array( 'title', 'name' )
1129
+ ),
1130
+ 'user_pass' => array(
1131
+ 'name' => 'user_pass',
1132
+ 'label' => 'Password',
1133
+ 'type' => 'text',
1134
+ 'alias' => array( 'password', 'pass' ),
1135
+ 'options' => array(
1136
+ 'required' => 1,
1137
+ 'text_format_type' => 'password'
1138
+ )
1139
+ ),
1140
+ 'user_email' => array(
1141
+ 'name' => 'user_email',
1142
+ 'label' => 'E-mail',
1143
+ 'type' => 'text',
1144
+ 'alias' => array( 'email' ),
1145
+ 'options' => array(
1146
+ 'required' => 1,
1147
+ 'text_format_type' => 'email'
1148
+ )
1149
+ ),
1150
+ 'user_url' => array(
1151
+ 'name' => 'user_url',
1152
+ 'label' => 'URL',
1153
+ 'type' => 'text',
1154
+ 'alias' => array( 'url', 'website' ),
1155
+ 'options' => array(
1156
+ 'required' => 0,
1157
+ 'text_format_type' => 'website',
1158
+ 'text_format_website' => 'normal'
1159
+ )
1160
+ ),
1161
+ 'user_registered' => array(
1162
+ 'name' => 'user_registered',
1163
+ 'label' => 'Registration Date',
1164
+ 'type' => 'date',
1165
+ 'alias' => array( 'created', 'date', 'registered' ),
1166
+ 'options' => array(
1167
+ 'date_format_type' => 'datetime'
1168
+ )
1169
+ )
1170
+ );
1171
+ }
1172
+ elseif ( 'comment' == $object ) {
1173
+ $fields = array(
1174
+ 'comment_ID' => array(
1175
+ 'name' => 'comment_ID',
1176
+ 'label' => 'ID',
1177
+ 'type' => 'number',
1178
+ 'alias' => array( 'id', 'ID', 'comment_id' ),
1179
+ 'options' => array(
1180
+ 'number_format' => '9999.99'
1181
+ )
1182
+ ),
1183
+ 'comment_content' => array(
1184
+ 'name' => 'comment_content',
1185
+ 'label' => 'Content',
1186
+ 'type' => 'wysiwyg',
1187
+ 'alias' => array( 'content' )
1188
+ ),
1189
+ 'comment_approved' => array(
1190
+ 'name' => 'comment_approved',
1191
+ 'label' => 'Approved',
1192
+ 'type' => 'number',
1193
+ 'alias' => array( 'approved' ),
1194
+ 'options' => array(
1195
+ 'number_format' => '9999.99'
1196
+ )
1197
+ ),
1198
+ 'comment_post_ID' => array(
1199
+ 'name' => 'comment_post_ID',
1200
+ 'label' => 'Post',
1201
+ 'type' => 'pick',
1202
+ 'alias' => array( 'post', 'post_id' ),
1203
+ 'data' => array()
1204
+ ),
1205
+ 'user_id' => array(
1206
+ 'name' => 'user_id',
1207
+ 'label' => 'Author',
1208
+ 'type' => 'pick',
1209
+ 'alias' => array( 'author' ),
1210
+ 'pick_object' => 'user',
1211
+ 'data' => array()
1212
+ ),
1213
+ 'comment_date' => array(
1214
+ 'name' => 'comment_date',
1215
+ 'label' => 'Date',
1216
+ 'type' => 'date',
1217
+ 'alias' => array( 'created', 'date' ),
1218
+ 'options' => array(
1219
+ 'date_format_type' => 'datetime'
1220
+ )
1221
+ ),
1222
+ 'comment_author' => array(
1223
+ 'name' => 'comment_author',
1224
+ 'label' => 'Author',
1225
+ 'type' => 'text',
1226
+ 'alias' => array( 'author' )
1227
+ ),
1228
+ 'comment_author_email' => array(
1229
+ 'name' => 'comment_author_email',
1230
+ 'label' => 'Author E-mail',
1231
+ 'type' => 'email',
1232
+ 'alias' => array( 'author_email' )
1233
+ ),
1234
+ 'comment_author_url' => array(
1235
+ 'name' => 'comment_author_url',
1236
+ 'label' => 'Author URL',
1237
+ 'type' => 'text',
1238
+ 'alias' => array( 'author_url' )
1239
+ ),
1240
+ 'comment_author_IP' => array(
1241
+ 'name' => 'comment_author_IP',
1242
+ 'label' => 'Author IP',
1243
+ 'type' => 'text',
1244
+ 'alias' => array( 'author_IP' )
1245
+ ),
1246
+ 'comment_type' => array(
1247
+ 'name' => 'comment_type',
1248
+ 'label' => 'Type',
1249
+ 'type' => 'text',
1250
+ 'alias' => array( 'type' ),
1251
+ 'hidden' => true
1252
+ ),
1253
+ 'comment_parent' => array(
1254
+ 'name' => 'comment_parent',
1255
+ 'label' => 'Parent',
1256
+ 'type' => 'pick',
1257
+ 'pick_object' => 'comment',
1258
+ 'pick_val' => '__current__',
1259
+ 'alias' => array( 'parent' ),
1260
+ 'data' => array(),
1261
+ 'hidden' => true
1262
+ )
1263
+ );
1264
+ }
1265
+ elseif ( 'taxonomy' == $object ) {
1266
+ $fields = array(
1267
+ 'term_id' => array(
1268
+ 'name' => 'term_id',
1269
+ 'label' => 'ID',
1270
+ 'type' => 'number',
1271
+ 'alias' => array( 'id', 'ID' ),
1272
+ 'options' => array(
1273
+ 'number_format' => '9999.99'
1274
+ )
1275
+ ),
1276
+ 'name' => array(
1277
+ 'name' => 'name',
1278
+ 'label' => 'Title',
1279
+ 'type' => 'text',
1280
+ 'alias' => array( 'title' )
1281
+ ),
1282
+ 'slug' => array(
1283
+ 'name' => 'slug',
1284
+ 'label' => 'Permalink',
1285
+ 'type' => 'slug',
1286
+ 'alias' => array( 'permalink' )
1287
+ ),
1288
+ 'description' => array(
1289
+ 'name' => 'description',
1290
+ 'label' => 'Description',
1291
+ 'type' => 'wysiwyg',
1292
+ 'alias' => array( 'content' )
1293
+ ),
1294
+ 'taxonomy' => array(
1295
+ 'name' => 'taxonomy',
1296
+ 'label' => 'Taxonomy',
1297
+ 'type' => 'text',
1298
+ 'alias' => array()
1299
+ ),
1300
+ 'parent' => array(
1301
+ 'name' => 'parent',
1302
+ 'label' => 'Parent',
1303
+ 'type' => 'pick',
1304
+ 'pick_object' => 'taxonomy',
1305
+ 'pick_val' => '__current__',
1306
+ 'alias' => array( 'parent' ),
1307
+ 'data' => array(),
1308
+ 'hidden' => true
1309
+ ),
1310
+ 'term_taxonomy_id' => array(
1311
+ 'name' => 'term_taxonomy_id',
1312
+ 'label' => 'Term Taxonomy ID',
1313
+ 'type' => 'number',
1314
+ 'alias' => array(),
1315
+ 'hidden' => true,
1316
+ 'options' => array(
1317
+ 'number_format' => '9999.99'
1318
+ )
1319
+ ),
1320
+ 'term_group' => array(
1321
+ 'name' => 'term_group',
1322
+ 'label' => 'Term Group',
1323
+ 'type' => 'number',
1324
+ 'alias' => array( 'group' ),
1325
+ 'hidden' => true,
1326
+ 'options' => array(
1327
+ 'number_format' => '9999.99'
1328
+ )
1329
+ ),
1330
+ 'count' => array(
1331
+ 'name' => 'count',
1332
+ 'label' => 'Count',
1333
+ 'type' => 'number',
1334
+ 'alias' => array(),
1335
+ 'hidden' => true,
1336
+ 'options' => array(
1337
+ 'number_format' => '9999.99'
1338
+ )
1339
+ )
1340
+ );
1341
+ }
1342
+
1343
+ $fields = $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
1344
+
1345
+ foreach ( $fields as $field => $options ) {
1346
+ if ( !isset( $options[ 'alias' ] ) )
1347
+ $options[ 'alias' ] = array();
1348
+ else
1349
+ $options[ 'alias' ] = (array) $options[ 'alias' ];
1350
+
1351
+ if ( !isset( $options[ 'name' ] ) )
1352
+ $options[ 'name' ] = $field;
1353
+
1354
+ $fields[ $field ] = $options;
1355
+ }
1356
+
1357
+ $fields = PodsForm::fields_setup( $fields );
1358
+
1359
+ if ( did_action( 'init' ) && pods_api_cache() )
1360
+ pods_transient_set( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ), $fields );
1361
+
1362
+ return $fields;
1363
+ }
1364
+
1365
+ /**
1366
+ *
1367
+ * @see PodsAPI::save_pod
1368
+ *
1369
+ * Add a Pod via the Wizard
1370
+ *
1371
+ * $params['create_extend'] string Create or Extend a Content Type
1372
+ * $params['create_pod_type'] string Pod Type (for Creating)
1373
+ * $params['create_name'] string Pod Name (for Creating)
1374
+ * $params['create_label_plural'] string Plural Label (for Creating)
1375
+ * $params['create_label_singular'] string Singular Label (for Creating)
1376
+ * $params['create_storage'] string Storage Type (for Creating Post Types)
1377
+ * $params['create_storage_taxonomy'] string Storage Type (for Creating Taxonomies)
1378
+ * $params['extend_pod_type'] string Pod Type (for Extending)
1379
+ * $params['extend_post_type'] string Post Type (for Extending Post Types)
1380
+ * $params['extend_taxonomy'] string Taxonomy (for Extending Taxonomies)
1381
+ * $params['extend_storage'] string Storage Type (for Extending Post Types / Users / Comments)
1382
+ *
1383
+ * @param array $params An associative array of parameters
1384
+ *
1385
+ * @return bool|int Pod ID
1386
+ * @since 2.0
1387
+ */
1388
+ public function add_pod ( $params ) {
1389
+ $defaults = array(
1390
+ 'create_extend' => 'create',
1391
+ 'create_pod_type' => 'post_type',
1392
+
1393
+ 'create_name' => '',
1394
+ 'create_label_singular' => '',
1395
+ 'create_label_plural' => '',
1396
+ 'create_storage' => 'meta',
1397
+ 'create_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' ),
1398
+
1399
+ 'create_setting_name' => '',
1400
+ 'create_label_title' => '',
1401
+ 'create_label_menu' => '',
1402
+ 'create_menu_location' => 'settings',
1403
+
1404
+ 'extend_pod_type' => 'post_type',
1405
+ 'extend_post_type' => 'post',
1406
+ 'extend_taxonomy' => 'category',
1407
+ 'extend_table' => '',
1408
+ 'extend_storage' => 'meta',
1409
+ 'extend_storage_taxonomy' => ( function_exists( 'get_term_meta' ) ? 'meta' : 'table' ),
1410
+ );
1411
+
1412
+ $params = (object) array_merge( $defaults, (array) $params );
1413
+
1414
+ if ( empty( $params->create_extend ) || !in_array( $params->create_extend, array( 'create', 'extend' ) ) )
1415
+ return pods_error( __( 'Please choose whether to Create or Extend a Content Type', 'pods' ), $this );
1416
+
1417
+ $pod_params = array(
1418
+ 'name' => '',
1419
+ 'label' => '',
1420
+ 'type' => '',
1421
+ 'storage' => 'table',
1422
+ 'object' => '',
1423
+ 'options' => array()
1424
+ );
1425
+
1426
+ if ( 'create' == $params->create_extend ) {
1427
+ $label = ucwords( str_replace( '_', ' ', $params->create_name ) );
1428
+
1429
+ if ( !empty( $params->create_label_singular ) )
1430
+ $label = $params->create_label_singular;
1431
+
1432
+ $pod_params[ 'name' ] = $params->create_name;
1433
+ $pod_params[ 'label' ] = ( !empty( $params->create_label_plural ) ? $params->create_label_plural : $label );
1434
+ $pod_params[ 'type' ] = $params->create_pod_type;
1435
+ $pod_params[ 'options' ] = array(
1436
+ 'label_singular' => ( !empty( $params->create_label_singular ) ? $params->create_label_singular : $pod_params[ 'label' ] ),
1437
+ 'public' => 1,
1438
+ 'show_ui' => 1
1439
+ );
1440
+
1441
+ // Auto-generate name if not provided
1442
+ if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'options' ][ 'label_singular' ] ) )
1443
+ $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'options' ][ 'label_singular' ] );
1444
+
1445
+ if ( 'post_type' == $pod_params[ 'type' ] ) {
1446
+ if ( empty( $pod_params[ 'name' ] ) )
1447
+ return pods_error( 'Please enter a Name for this Pod', $this );
1448
+
1449
+ $pod_params[ 'storage' ] = $params->create_storage;
1450
+
1451
+ if ( pods_tableless() )
1452
+ $pod_params[ 'storage' ] = 'meta';
1453
+ }
1454
+ elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1455
+ if ( empty( $pod_params[ 'name' ] ) )
1456
+ return pods_error( 'Please enter a Name for this Pod', $this );
1457
+
1458
+ $pod_params[ 'storage' ] = $params->create_storage_taxonomy;
1459
+
1460
+ if ( pods_tableless() )
1461
+ $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1462
+
1463
+ $pod_params['options']['hierarchical'] = 1;
1464
+ }
1465
+ elseif ( 'pod' == $pod_params[ 'type' ] ) {
1466
+ if ( empty( $pod_params[ 'name' ] ) )
1467
+ return pods_error( 'Please enter a Name for this Pod', $this );
1468
+
1469
+ if ( pods_tableless() ) {
1470
+ $pod_params[ 'type' ] = 'post_type';
1471
+ $pod_params[ 'storage' ] = 'meta';
1472
+ }
1473
+ }
1474
+ elseif ( 'settings' == $pod_params[ 'type' ] ) {
1475
+ $pod_params[ 'name' ] = $params->create_setting_name;
1476
+ $pod_params[ 'label' ] = ( !empty( $params->create_label_title ) ? $params->create_label_title : ucwords( str_replace( '_', ' ', $params->create_setting_name ) ) );
1477
+ $pod_params[ 'options' ] = array(
1478
+ 'menu_name' => ( !empty( $params->create_label_menu ) ? $params->create_label_menu : $pod_params[ 'label' ] ),
1479
+ 'menu_location' => $params->create_menu_location
1480
+ );
1481
+ $pod_params[ 'storage' ] = 'none';
1482
+
1483
+ // Auto-generate name if not provided
1484
+ if ( empty( $pod_params[ 'name' ] ) && !empty( $pod_params[ 'label' ] ) )
1485
+ $pod_params[ 'name' ] = pods_clean_name( $pod_params[ 'label' ] );
1486
+
1487
+ if ( empty( $pod_params[ 'name' ] ) )
1488
+ return pods_error( 'Please enter a Name for this Pod', $this );
1489
+ }
1490
+ }
1491
+ elseif ( 'extend' == $params->create_extend ) {
1492
+ $pod_params[ 'type' ] = $params->extend_pod_type;
1493
+
1494
+ if ( 'post_type' == $pod_params[ 'type' ] ) {
1495
+ $pod_params[ 'storage' ] = $params->extend_storage;
1496
+
1497
+ if ( pods_tableless() )
1498
+ $pod_params[ 'storage' ] = 'meta';
1499
+
1500
+ $pod_params[ 'name' ] = $params->extend_post_type;
1501
+ }
1502
+ elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1503
+ $pod_params[ 'storage' ] = $params->extend_storage_taxonomy;
1504
+
1505
+ if ( pods_tableless() )
1506
+ $pod_params[ 'storage' ] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1507
+
1508
+ $pod_params[ 'name' ] = $params->extend_taxonomy;
1509
+ }
1510
+ elseif ( 'table' == $pod_params[ 'type' ] ) {
1511
+ $pod_params[ 'storage' ] = 'table';
1512
+ $pod_params[ 'name' ] = $params->extend_table;
1513
+ }
1514
+ else {
1515
+ $pod_params[ 'storage' ] = $params->extend_storage;
1516
+
1517
+ if ( pods_tableless() )
1518
+ $pod_params[ 'storage' ] = 'meta';
1519
+
1520
+ $pod_params[ 'name' ] = $params->extend_pod_type;
1521
+ }
1522
+
1523
+ $pod_params[ 'label' ] = ucwords( str_replace( '_', ' ', $pod_params[ 'name' ] ) );
1524
+ $pod_params[ 'object' ] = $pod_params[ 'name' ];
1525
+ }
1526
+
1527
+ if ( empty( $pod_params[ 'object' ] ) ) {
1528
+ if ( 'post_type' == $pod_params[ 'type' ] ) {
1529
+ $check = get_post_type_object( $pod_params[ 'name' ] );
1530
+
1531
+ if ( !empty( $check ) )
1532
+ return pods_error( sprintf( __( 'Post Type %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1533
+
1534
+ $pod_params[ 'options' ][ 'supports_title' ] = 1;
1535
+ $pod_params[ 'options' ][ 'supports_editor' ] = 1;
1536
+ }
1537
+ elseif ( 'taxonomy' == $pod_params[ 'type' ] ) {
1538
+ $check = get_taxonomy( $pod_params[ 'name' ] );
1539
+
1540
+ if ( !empty( $check ) )
1541
+ return pods_error( sprintf( __( 'Taxonomy %s already exists, try extending it instead', 'pods' ), $pod_params[ 'name' ] ), $this );
1542
+ }
1543
+ }
1544
+
1545
+ if ( !empty( $pod_params ) )
1546
+ return $this->save_pod( $pod_params );
1547
+
1548
+ return false;
1549
+ }
1550
+
1551
+ /**
1552
+ * Add or edit a Pod
1553
+ *
1554
+ * $params['id'] int The Pod ID
1555
+ * $params['name'] string The Pod name
1556
+ * $params['label'] string The Pod label
1557
+ * $params['type'] string The Pod type
1558
+ * $params['object'] string The object being extended (if any)
1559
+ * $params['storage'] string The Pod storage
1560
+ * $params['options'] array Options
1561
+ *
1562
+ * @param array $params An associative array of parameters
1563
+ * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
1564
+ * @param bool|int $db (optional) Whether to save into the DB or just return Pod array.
1565
+ *
1566
+ * @return int Pod ID
1567
+ * @since 1.7.9
1568
+ */
1569
+ public function save_pod ( $params, $sanitized = false, $db = true ) {
1570
+ $tableless_field_types = PodsForm::tableless_field_types();
1571
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
1572
+
1573
+ $load_params = (object) $params;
1574
+
1575
+ if ( isset( $load_params->id ) && isset( $load_params->name ) )
1576
+ unset( $load_params->name );
1577
+
1578
+ if ( isset( $load_params->old_name ) )
1579
+ $load_params->name = $load_params->old_name;
1580
+
1581
+ $load_params->table_info = true;
1582
+
1583
+ $pod = $this->load_pod( $load_params, false );
1584
+
1585
+ $params = (object) $params;
1586
+
1587
+ if ( false === $sanitized )
1588
+ $params = pods_sanitize( $params );
1589
+
1590
+ $old_id = $old_name = $old_storage = null;
1591
+
1592
+ $old_fields = $old_options = array();
1593
+
1594
+ if ( isset( $params->name ) && ! isset( $params->object ) ) {
1595
+ $params->name = pods_clean_name( $params->name );
1596
+ }
1597
+
1598
+ if ( !empty( $pod ) ) {
1599
+ if ( isset( $params->id ) && 0 < $params->id )
1600
+ $old_id = $params->id;
1601
+
1602
+ $params->id = $pod[ 'id' ];
1603
+
1604
+ $old_name = $pod[ 'name' ];
1605
+ $old_storage = $pod[ 'storage' ];
1606
+ $old_fields = $pod[ 'fields' ];
1607
+ $old_options = $pod[ 'options' ];
1608
+
1609
+ if ( !isset( $params->name ) && empty( $params->name ) )
1610
+ $params->name = $pod[ 'name' ];
1611
+
1612
+ if ( $old_name != $params->name && false !== $this->pod_exists( array( 'name' => $params->name ) ) )
1613
+ return pods_error( sprintf( __( 'Pod %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1614
+
1615
+ if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'user', 'comment', 'media' ) ) && in_array( $pod[ 'object' ], array( 'user', 'comment', 'media' ) ) )
1616
+ return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1617
+
1618
+ if ( $old_name != $params->name && in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && !empty( $pod[ 'object' ] ) && $pod[ 'object' ] == $old_name )
1619
+ return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1620
+
1621
+ if ( $old_id != $params->id ) {
1622
+ if ( $params->type == $pod[ 'type' ] && isset( $params->object ) && $params->object == $pod[ 'object' ] )
1623
+ return pods_error( sprintf( __( 'Pod using %s already exists, you can not reuse an object across multiple pods', 'pods' ), $params->object ), $this );
1624
+ else
1625
+ return pods_error( sprintf( __( 'Pod %s already exists', 'pods' ), $params->name ), $this );
1626
+ }
1627
+ }
1628
+ elseif ( in_array( $params->name, array( 'order','orderby','post_type' ) ) && 'post_type' == pods_var( 'type', $params ) ) {
1629
+ return pods_error( sprintf( 'There are certain names that a Custom Post Types cannot be named and unfortunately, %s is one of them.', $params->name ), $this );
1630
+ }
1631
+ else {
1632
+ $pod = array(
1633
+ 'id' => 0,
1634
+ 'name' => $params->name,
1635
+ 'label' => $params->name,
1636
+ 'description' => '',
1637
+ 'type' => 'pod',
1638
+ 'storage' => 'table',
1639
+ 'object' => '',
1640
+ 'alias' => '',
1641
+ 'options' => array(),
1642
+ 'fields' => array()
1643
+ );
1644
+ }
1645
+
1646
+ // Blank out fields and options for AJAX calls (everything should be sent to it for a full overwrite)
1647
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1648
+ $pod[ 'fields' ] = array();
1649
+ $pod[ 'options' ] = array();
1650
+ }
1651
+
1652
+ // Setup options
1653
+ $options = get_object_vars( $params );
1654
+
1655
+ if ( isset( $options[ 'method' ] ) )
1656
+ unset( $options[ 'method' ] );
1657
+
1658
+ $options_ignore = array(
1659
+ 'object_type',
1660
+ 'object_name',
1661
+ 'table',
1662
+ 'meta_table',
1663
+ 'pod_table',
1664
+ 'field_id',
1665
+ 'field_index',
1666
+ 'field_slug',
1667
+ 'field_type',
1668
+ 'field_parent',
1669
+ 'field_parent_select',
1670
+ 'meta_field_id',
1671
+ 'meta_field_index',
1672
+ 'meta_field_value',
1673
+ 'pod_field_id',
1674
+ 'pod_field_index',
1675
+ 'object_fields',
1676
+ 'join',
1677
+ 'where',
1678
+ 'where_default',
1679
+ 'orderby',
1680
+ 'pod',
1681
+ 'recurse',
1682
+ 'table_info',
1683
+ 'attributes',
1684
+ 'group',
1685
+ 'grouped',
1686
+ 'developer_mode',
1687
+ 'dependency',
1688
+ 'depends-on',
1689
+ 'excludes-on'
1690
+ );
1691
+
1692
+ foreach ( $options_ignore as $ignore ) {
1693
+ if ( isset( $options[ $ignore ] ) )
1694
+ unset( $options[ $ignore ] );
1695
+ }
1696
+
1697
+ $exclude = array(
1698
+ 'id',
1699
+ 'name',
1700
+ 'label',
1701
+ 'description',
1702
+ 'type',
1703
+ 'storage',
1704
+ 'object',
1705
+ 'alias',
1706
+ 'options',
1707
+ 'fields'
1708
+ );
1709
+
1710
+ foreach ( $exclude as $k => $exclude_field ) {
1711
+ $aliases = array( $exclude_field );
1712
+
1713
+ if ( is_array( $exclude_field ) ) {
1714
+ $aliases = array_merge( array( $k ), $exclude_field );
1715
+ $exclude_field = $k;
1716
+ }
1717
+
1718
+ foreach ( $aliases as $alias ) {
1719
+ if ( isset( $options[ $alias ] ) ) {
1720
+ $pod[ $exclude_field ] = pods_trim( $options[ $alias ] );
1721
+
1722
+ unset( $options[ $alias ] );
1723
+ }
1724
+ }
1725
+ }
1726
+
1727
+ if ( pods_tableless() && !in_array( $pod[ 'type' ], array( 'settings', 'table' ) ) ) {
1728
+ if ( 'pod' == $pod[ 'type' ] )
1729
+ $pod[ 'type' ] = 'post_type';
1730
+
1731
+ if ( 'table' == $pod[ 'storage' ] ) {
1732
+ if ( 'taxonomy' == $pod[ 'type' ] && ! function_exists( 'get_term_meta' ) )
1733
+ $pod[ 'storage' ] = 'none';
1734
+ else
1735
+ $pod[ 'storage' ] = 'meta';
1736
+ }
1737
+ }
1738
+
1739
+ $pod[ 'options' ][ 'type' ] = $pod[ 'type' ];
1740
+ $pod[ 'options' ][ 'storage' ] = $pod[ 'storage' ];
1741
+ $pod[ 'options' ][ 'object' ] = $pod[ 'object' ];
1742
+ $pod[ 'options' ][ 'alias' ] = $pod[ 'alias' ];
1743
+
1744
+ $pod[ 'options' ] = array_merge( $pod[ 'options' ], $options );
1745
+
1746
+ /**
1747
+ * @var WP_Query
1748
+ */
1749
+ global $wp_query;
1750
+
1751
+ $reserved_query_vars = array(
1752
+ 'post_type',
1753
+ 'taxonomy',
1754
+ 'output'
1755
+ );
1756
+
1757
+ if ( is_object( $wp_query ) ) {
1758
+ $reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) );
1759
+ }
1760
+
1761
+ if ( isset( $pod[ 'options' ][ 'query_var_string' ] ) ) {
1762
+ if ( in_array( $pod[ 'options' ][ 'query_var_string' ], $reserved_query_vars ) ) {
1763
+ $pod[ 'options' ][ 'query_var_string' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var_string' ];
1764
+ }
1765
+ }
1766
+
1767
+ if ( isset( $pod[ 'options' ][ 'query_var' ] ) ) {
1768
+ if ( in_array( $pod[ 'options' ][ 'query_var' ], $reserved_query_vars ) ) {
1769
+ $pod[ 'options' ][ 'query_var' ] = $pod[ 'options' ][ 'type' ] . '_' . $pod[ 'options' ][ 'query_var' ];
1770
+ }
1771
+ }
1772
+
1773
+ if ( strlen( $pod[ 'label' ] ) < 1 )
1774
+ $pod[ 'label' ] = $pod[ 'name' ];
1775
+
1776
+ if ( 'post_type' == $pod[ 'type' ] ) {
1777
+ // Max length for post types are 20 characters
1778
+ $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 20 );
1779
+ }
1780
+ elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1781
+ // Max length for taxonomies are 32 characters
1782
+ $pod[ 'name' ] = substr( $pod[ 'name' ], 0, 32 );
1783
+ }
1784
+
1785
+ $params->id = $pod[ 'id' ];
1786
+ $params->name = $pod[ 'name' ];
1787
+
1788
+ if ( null !== $old_name && $old_name != $params->name && empty( $pod[ 'object' ] ) ) {
1789
+ if ( 'post_type' == $pod[ 'type' ] ) {
1790
+ $check = get_post_type_object( $params->name );
1791
+
1792
+ if ( !empty( $check ) )
1793
+ return pods_error( sprintf( __( 'Post Type %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1794
+ }
1795
+ elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1796
+ $check = get_taxonomy( $params->name );
1797
+
1798
+ if ( !empty( $check ) )
1799
+ return pods_error( sprintf( __( 'Taxonomy %s already exists, you cannot rename %s to that', 'pods' ), $params->name, $old_name ), $this );
1800
+ }
1801
+ }
1802
+
1803
+ $field_table_operation = true;
1804
+
1805
+ // Add new pod
1806
+ if ( empty( $params->id ) ) {
1807
+ if ( strlen( $params->name ) < 1 )
1808
+ return pods_error( __( 'Pod name cannot be empty', 'pods' ), $this );
1809
+
1810
+ $post_data = array(
1811
+ 'post_name' => $pod[ 'name' ],
1812
+ 'post_title' => $pod[ 'label' ],
1813
+ 'post_content' => $pod[ 'description' ],
1814
+ 'post_type' => '_pods_pod',
1815
+ 'post_status' => 'publish'
1816
+ );
1817
+
1818
+ if ( 'pod' == $pod[ 'type' ] && ( !is_array( $pod[ 'fields' ] ) || empty( $pod[ 'fields' ] ) ) ) {
1819
+ $pod[ 'fields' ] = array();
1820
+
1821
+ $pod[ 'fields' ][ 'name' ] = array(
1822
+ 'name' => 'name',
1823
+ 'label' => 'Name',
1824
+ 'type' => 'text',
1825
+ 'options' => array(
1826
+ 'required' => '1'
1827
+ )
1828
+ );
1829
+
1830
+ $pod[ 'fields' ][ 'created' ] = array(
1831
+ 'name' => 'created',
1832
+ 'label' => 'Date Created',
1833
+ 'type' => 'datetime',
1834
+ 'options' => array(
1835
+ 'datetime_format' => 'ymd_slash',
1836
+ 'datetime_time_type' => '12',
1837
+ 'datetime_time_format' => 'h_mm_ss_A'
1838
+ )
1839
+ );
1840
+
1841
+ $pod[ 'fields' ][ 'modified' ] = array(
1842
+ 'name' => 'modified',
1843
+ 'label' => 'Date Modified',
1844
+ 'type' => 'datetime',
1845
+ 'options' => array(
1846
+ 'datetime_format' => 'ymd_slash',
1847
+ 'datetime_time_type' => '12',
1848
+ 'datetime_time_format' => 'h_mm_ss_A'
1849
+ )
1850
+ );
1851
+
1852
+ $pod[ 'fields' ][ 'author' ] = array(
1853
+ 'name' => 'author',
1854
+ 'label' => 'Author',
1855
+ 'type' => 'pick',
1856
+ 'pick_object' => 'user',
1857
+ 'options' => array(
1858
+ 'pick_format_type' => 'single',
1859
+ 'pick_format_single' => 'autocomplete',
1860
+ 'default_value' => '{@user.ID}'
1861
+ )
1862
+ );
1863
+
1864
+ $pod[ 'fields' ][ 'permalink' ] = array(
1865
+ 'name' => 'permalink',
1866
+ 'label' => 'Permalink',
1867
+ 'type' => 'slug',
1868
+ 'description' => 'Leave blank to auto-generate from Name'
1869
+ );
1870
+
1871
+ if ( !isset( $pod[ 'options' ][ 'pod_index' ] ) )
1872
+ $pod[ 'options' ][ 'pod_index' ] = 'name';
1873
+ }
1874
+
1875
+ $pod = $this->do_hook( 'save_pod_default_pod', $pod, $params, $sanitized, $db );
1876
+
1877
+ $field_table_operation = false;
1878
+ }
1879
+ else {
1880
+ $post_data = array(
1881
+ 'ID' => $pod[ 'id' ],
1882
+ 'post_name' => $pod[ 'name' ],
1883
+ 'post_title' => $pod[ 'label' ],
1884
+ 'post_content' => $pod[ 'description' ],
1885
+ 'post_status' => 'publish'
1886
+ );
1887
+ }
1888
+
1889
+ if ( true === $db ) {
1890
+ if ( !has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) )
1891
+ add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
1892
+
1893
+ $conflicted = false;
1894
+
1895
+ // Headway compatibility fix
1896
+ if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
1897
+ remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1898
+
1899
+ $conflicted = true;
1900
+ }
1901
+
1902
+ $params->id = $this->save_wp_object( 'post', $post_data, $pod[ 'options' ], true, true );
1903
+
1904
+ if ( $conflicted )
1905
+ add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
1906
+
1907
+ if ( false === $params->id )
1908
+ return pods_error( __( 'Cannot save Pod', 'pods' ), $this );
1909
+ }
1910
+ elseif ( empty( $params->id ) )
1911
+ $params->id = (int) $db;
1912
+
1913
+ $pod[ 'id' ] = $params->id;
1914
+
1915
+ // Setup / update tables
1916
+ if ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $old_storage != $pod[ 'storage' ] && $db ) {
1917
+ $definitions = array( "`id` BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY" );
1918
+
1919
+ $defined_fields = array();
1920
+
1921
+ foreach ( $pod[ 'fields' ] as $field ) {
1922
+ if ( !is_array( $field ) || !isset( $field[ 'name' ] ) || in_array( $field[ 'name' ], $defined_fields ) )
1923
+ continue;
1924
+
1925
+ $defined_fields[] = $field[ 'name' ];
1926
+
1927
+ if ( !in_array( $field[ 'type' ], $tableless_field_types ) || ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) ) {
1928
+ $definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, pods_var_raw( 'options', $field, array() ) ) );
1929
+
1930
+ if ( 0 < strlen( $definition ) )
1931
+ $definitions[] = "`{$field['name']}` " . $definition;
1932
+ }
1933
+ }
1934
+
1935
+ pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`" );
1936
+
1937
+ $result = pods_query( "CREATE TABLE `@wp_pods_{$params->name}` (" . implode( ', ', $definitions ) . ") DEFAULT CHARSET utf8", $this );
1938
+
1939
+ if ( empty( $result ) )
1940
+ return pods_error( __( 'Cannot add Database Table for Pod', 'pods' ), $this );
1941
+
1942
+ }
1943
+ elseif ( 'table' != $pod[ 'type' ] && 'table' == $pod[ 'storage' ] && $pod[ 'storage' ] == $old_storage && null !== $old_name && $old_name != $params->name && $db ) {
1944
+ $result = pods_query( "ALTER TABLE `@wp_pods_{$old_name}` RENAME `@wp_pods_{$params->name}`", $this );
1945
+
1946
+ if ( empty( $result ) )
1947
+ return pods_error( __( 'Cannot update Database Table for Pod', 'pods' ), $this );
1948
+ }
1949
+
1950
+ /**
1951
+ * @var $wpdb wpdb
1952
+ */
1953
+ global $wpdb;
1954
+
1955
+ if ( null !== $old_name && $old_name != $params->name && $db ) {
1956
+ // Rename items in the DB pointed at the old WP Object names
1957
+ if ( 'post_type' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1958
+ $this->rename_wp_object_type( 'post', $old_name, $params->name );
1959
+ }
1960
+ elseif ( 'taxonomy' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1961
+ $this->rename_wp_object_type( 'taxonomy', $old_name, $params->name );
1962
+ }
1963
+ elseif ( 'comment' == $pod[ 'type' ] && empty( $pod[ 'object' ] ) ) {
1964
+ $this->rename_wp_object_type( 'comment', $old_name, $params->name );
1965
+ }
1966
+ elseif ( 'settings' == $pod[ 'type' ] ) {
1967
+ $this->rename_wp_object_type( 'settings', $old_name, $params->name );
1968
+ }
1969
+
1970
+ // Sync any related fields if the name has changed
1971
+ $fields = pods_query( "
1972
+ SELECT `p`.`ID`
1973
+ FROM `{$wpdb->posts}` AS `p`
1974
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
1975
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm2` ON `pm2`.`post_id` = `p`.`ID`
1976
+ WHERE
1977
+ `p`.`post_type` = '_pods_field'
1978
+ AND `pm`.`meta_key` = 'pick_object'
1979
+ AND (
1980
+ `pm`.`meta_value` = 'pod'
1981
+ OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "'
1982
+ )
1983
+ AND `pm2`.`meta_key` = 'pick_val'
1984
+ AND `pm2`.`meta_value` = '{$old_name}'
1985
+ " );
1986
+
1987
+ if ( !empty( $fields ) ) {
1988
+ foreach ( $fields as $field ) {
1989
+ update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
1990
+ update_post_meta( $field->ID, 'pick_val', $params->name );
1991
+ }
1992
+ }
1993
+
1994
+ $fields = pods_query( "
1995
+ SELECT `p`.`ID`
1996
+ FROM `{$wpdb->posts}` AS `p`
1997
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
1998
+ WHERE
1999
+ `p`.`post_type` = '_pods_field'
2000
+ AND `pm`.`meta_key` = 'pick_object'
2001
+ AND (
2002
+ `pm`.`meta_value` = 'pod-{$old_name}'
2003
+ OR `pm`.`meta_value` = '" . $pod[ 'type' ] . "-{$old_name}'
2004
+ )
2005
+ " );
2006
+
2007
+ if ( !empty( $fields ) ) {
2008
+ foreach ( $fields as $field ) {
2009
+ update_post_meta( $field->ID, 'pick_object', $pod[ 'type' ] );
2010
+ update_post_meta( $field->ID, 'pick_val', $params->name );
2011
+ }
2012
+ }
2013
+ }
2014
+
2015
+ // Sync built-in options for post types and taxonomies
2016
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && empty( $pod[ 'object' ] ) && $db ) {
2017
+ // Build list of 'built_in' for later
2018
+ $built_in = array();
2019
+
2020
+ foreach ( $pod[ 'options' ] as $key => $val ) {
2021
+ if ( false === strpos( $key, 'built_in_' ) )
2022
+ continue;
2023
+ elseif ( false !== strpos( $key, 'built_in_post_types_' ) )
2024
+ $built_in_type = 'post_type';
2025
+ elseif ( false !== strpos( $key, 'built_in_taxonomies_' ) )
2026
+ $built_in_type = 'taxonomy';
2027
+ else
2028
+ continue;
2029
+
2030
+ if ( $built_in_type == $pod[ 'type' ] )
2031
+ continue;
2032
+
2033
+ if ( !isset( $built_in[ $built_in_type ] ) )
2034
+ $built_in[ $built_in_type ] = array();
2035
+
2036
+ $built_in_object = str_replace( array( 'built_in_post_types_', 'built_in_taxonomies_' ), '', $key );
2037
+
2038
+ $built_in[ $built_in_type ][ $built_in_object ] = (int) $val;
2039
+ }
2040
+
2041
+ $lookup_option = $lookup_built_in = false;
2042
+
2043
+ $lookup_name = $pod[ 'name' ];
2044
+
2045
+ if ( 'post_type' == $pod[ 'type' ] ) {
2046
+ $lookup_option = 'built_in_post_types_' . $lookup_name;
2047
+ $lookup_built_in = 'taxonomy';
2048
+ }
2049
+ elseif ( 'taxonomy' == $pod[ 'type' ] ) {
2050
+ $lookup_option = 'built_in_taxonomies_' . $lookup_name;
2051
+ $lookup_built_in = 'post_type';
2052
+ }
2053
+
2054
+ if ( !empty( $lookup_option ) && !empty( $lookup_built_in ) && isset( $built_in[ $lookup_built_in ] ) ) {
2055
+ foreach ( $built_in[ $lookup_built_in ] as $built_in_object => $val ) {
2056
+ $search_val = 1;
2057
+
2058
+ if ( 1 == $val )
2059
+ $search_val = 0;
2060
+
2061
+ $query = "SELECT p.ID FROM {$wpdb->posts} AS p
2062
+ LEFT JOIN {$wpdb->postmeta} AS pm ON pm.post_id = p.ID AND pm.meta_key = '{$lookup_option}'
2063
+ LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm2.post_id = p.ID AND pm2.meta_key = 'type' AND pm2.meta_value = '{$lookup_built_in}'
2064
+ LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm3.post_id = p.ID AND pm3.meta_key = 'object' AND pm3.meta_value = ''
2065
+ WHERE p.post_type = '_pods_pod' AND p.post_name = '{$built_in_object}'
2066
+ AND pm2.meta_id IS NOT NULL
2067
+ AND ( pm.meta_id IS NULL OR pm.meta_value = {$search_val} )";
2068
+
2069
+ $results = pods_query( $query );
2070
+
2071
+ if ( !empty( $results ) ) {
2072
+ foreach ( $results as $the_pod ) {
2073
+ delete_post_meta( $the_pod->ID, $lookup_option );
2074
+
2075
+ add_post_meta( $the_pod->ID, $lookup_option, $val );
2076
+ }
2077
+ }
2078
+ }
2079
+ }
2080
+ }
2081
+
2082
+ $saved = array();
2083
+ $errors = array();
2084
+
2085
+ $field_index_change = false;
2086
+ $field_index_id = 0;
2087
+
2088
+ $id_required = false;
2089
+
2090
+ $field_index = pods_var( 'pod_index', $pod[ 'options' ], 'id', null, true );
2091
+
2092
+ if ( 'pod' == $pod[ 'type' ] && !empty( $pod[ 'fields' ] ) && isset( $pod[ 'fields' ][ $field_index ] ) )
2093
+ $field_index_id = $pod[ 'fields' ][ $field_index ];
2094
+
2095
+ if ( isset( $params->fields ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
2096
+ $fields = array();
2097
+
2098
+ if ( isset( $params->fields ) ) {
2099
+ $params->fields = (array) $params->fields;
2100
+
2101
+ $weight = 0;
2102
+
2103
+ foreach ( $params->fields as $field ) {
2104
+ if ( !is_array( $field ) || !isset( $field[ 'name' ] ) )
2105
+ continue;
2106
+
2107
+ if ( !isset( $field[ 'weight' ] ) ) {
2108
+ $field[ 'weight' ] = $weight;
2109
+
2110
+ $weight++;
2111
+ }
2112
+
2113
+ $fields[ $field[ 'name' ] ] = $field;
2114
+ }
2115
+ }
2116
+
2117
+ $weight = 0;
2118
+
2119
+ $saved_field_ids = array();
2120
+
2121
+ foreach ( $pod[ 'fields' ] as $k => $field ) {
2122
+ if ( !empty( $old_id ) && ( !is_array( $field ) || !isset( $field[ 'name' ] ) || !isset( $fields[ $field[ 'name' ] ] ) ) ) {
2123
+ // Iterative change handling for setup-edit.php
2124
+ if ( !is_array( $field ) && isset( $old_fields[ $k ] ) )
2125
+ $saved[ $old_fields[ $k ][ 'name' ] ] = true;
2126
+
2127
+ continue;
2128
+ }
2129
+
2130
+ if ( !empty( $old_id ) )
2131
+ $field = array_merge( $field, $fields[ $field[ 'name' ] ] );
2132
+
2133
+ $field[ 'pod' ] = $pod;
2134
+
2135
+ if ( !isset( $field[ 'weight' ] ) ) {
2136
+ $field[ 'weight' ] = $weight;
2137
+
2138
+ $weight++;
2139
+ }
2140
+
2141
+ if ( 0 < $field_index_id && pods_var( 'id', $field ) == $field_index_id )
2142
+ $field_index_change = $field[ 'name' ];
2143
+
2144
+ if ( 0 < pods_var( 'id', $field ) )
2145
+ $id_required = true;
2146
+
2147
+ if ( $id_required )
2148
+ $field[ 'id_required' ] = true;
2149
+
2150
+ $field_data = $field;
2151
+
2152
+ $field = $this->save_field( $field_data, $field_table_operation, true, $db );
2153
+
2154
+ if ( true !== $db ) {
2155
+ $pod[ 'fields' ][ $k ] = $field;
2156
+ $saved_field_ids[] = $field[ 'id' ];
2157
+ }
2158
+ else {
2159
+ if ( !empty( $field ) && 0 < $field ) {
2160
+ $saved[ $field_data[ 'name' ] ] = true;
2161
+ $saved_field_ids[] = $field;
2162
+ }
2163
+ else
2164
+ $errors[] = sprintf( __( 'Cannot save the %s field', 'pods' ), $field_data[ 'name' ] );
2165
+ }
2166
+ }
2167
+
2168
+ if ( true === $db ) {
2169
+ foreach ( $old_fields as $field ) {
2170
+ if ( isset( $pod[ 'fields' ][ $field[ 'name' ] ] ) || isset( $saved[ $field[ 'name' ] ] ) || in_array( $field[ 'id' ], $saved_field_ids ) )
2171
+ continue;
2172
+
2173
+ if ( $field[ 'id' ] == $field_index_id )
2174
+ $field_index_change = 'id';
2175
+ elseif ( $field[ 'name' ] == $field_index )
2176
+ $field_index_change = 'id';
2177
+
2178
+ $this->delete_field( array(
2179
+ 'id' => (int) $field[ 'id' ],
2180
+ 'name' => $field[ 'name' ],
2181
+ 'pod' => $pod
2182
+ ), $field_table_operation );
2183
+ }
2184
+ }
2185
+
2186
+ // Update field index if the name has changed or the field has been removed
2187
+ if ( false !== $field_index_change && true === $db )
2188
+ update_post_meta( $pod[ 'id' ], 'pod_index', $field_index_change );
2189
+ }
2190
+
2191
+ if ( !empty( $errors ) )
2192
+ return pods_error( $errors, $this );
2193
+
2194
+ $this->cache_flush_pods( $pod );
2195
+
2196
+ $refresh_pod = $this->load_pod( array( 'name' => $pod['name'] ), false );
2197
+
2198
+ if ( $refresh_pod ) {
2199
+ $pod = $refresh_pod;
2200
+ }
2201
+
2202
+ if ( 'post_type' == $pod['type'] ) {
2203
+ PodsMeta::$post_types[ $pod['id'] ] = $pod;
2204
+ } elseif ( 'taxonomy' == $pod['type'] ) {
2205
+ PodsMeta::$taxonomies[ $pod['id'] ] = $pod;
2206
+ } elseif ( 'media' == $pod['type'] ) {
2207
+ PodsMeta::$media[ $pod['id'] ] = $pod;
2208
+ } elseif ( 'user' == $pod['type'] ) {
2209
+ PodsMeta::$user[ $pod['id'] ] = $pod;
2210
+ } elseif ( 'comment' == $pod['type'] ) {
2211
+ PodsMeta::$comment[ $pod['id'] ] = $pod;
2212
+ }
2213
+
2214
+ // Register Post Types / Taxonomies post-registration from PodsInit
2215
+ if ( !empty( PodsInit::$content_types_registered ) && in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && empty( $pod[ 'object' ] ) ) {
2216
+ global $pods_init;
2217
+
2218
+ $pods_init->setup_content_types( true );
2219
+ }
2220
+
2221
+ if ( true === $db )
2222
+ return $pod[ 'id' ];
2223
+ else
2224
+ return $pod;
2225
+ }
2226
+
2227
+ /**
2228
+ * Add or edit a field within a Pod
2229
+ *
2230
+ * $params['id'] int Field ID (id OR pod_id+pod+name required)
2231
+ * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required)
2232
+ * $params['pod'] string Pod name (id OR pod_id+pod+name required)
2233
+ * $params['name'] string Field name (id OR pod_id+pod+name required)
2234
+ * $params['label'] string (optional) Field label
2235
+ * $params['type'] string (optional) Field type (avatar, boolean, code, color, currency, date, datetime, email, file, number, paragraph, password, phone, pick, slug, text, time, website, wysiwyg)
2236
+ * $params['pick_object'] string (optional) Related Object (for relationships)
2237
+ * $params['pick_val'] string (optional) Related Object name (for relationships)
2238
+ * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships)
2239
+ * $params['weight'] int (optional) Order in which the field appears
2240
+ * $params['options'] array (optional) Options
2241
+ *
2242
+ * @param array $params An associative array of parameters
2243
+ * @param bool $table_operation (optional) Whether or not to handle table operations
2244
+ * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2245
+ * @param bool|int $db (optional) Whether to save into the DB or just return field array.
2246
+ *
2247
+ * @return int|array The field ID or field array (if !$db)
2248
+ * @since 1.7.9
2249
+ */
2250
+ public function save_field ( $params, $table_operation = true, $sanitized = false, $db = true ) {
2251
+ /**
2252
+ * @var $wpdb wpdb
2253
+ */
2254
+ global $wpdb;
2255
+
2256
+ if ( true !== $db )
2257
+ $table_operation = false;
2258
+
2259
+ $tableless_field_types = PodsForm::tableless_field_types();
2260
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
2261
+
2262
+ $params = (object) $params;
2263
+
2264
+ if ( false === $sanitized )
2265
+ $params = pods_sanitize( $params );
2266
+
2267
+ if ( isset( $params->pod_id ) )
2268
+ $params->pod_id = pods_absint( $params->pod_id );
2269
+
2270
+ if ( true !== $db )
2271
+ $params->pod_id = (int) $db;
2272
+
2273
+ $pod = null;
2274
+ $save_pod = false;
2275
+ $id_required = false;
2276
+
2277
+ if ( isset( $params->id_required ) ) {
2278
+ unset( $params->id_required );
2279
+
2280
+ $id_required = true;
2281
+ }
2282
+
2283
+ if ( ( !isset( $params->pod ) || empty( $params->pod ) ) && ( !isset( $params->pod_id ) || empty( $params->pod_id ) ) )
2284
+ return pods_error( __( 'Pod ID or name is required', 'pods' ), $this );
2285
+
2286
+ if ( isset( $params->pod ) && is_array( $params->pod ) ) {
2287
+ $pod = $params->pod;
2288
+
2289
+ $save_pod = true;
2290
+ }
2291
+ elseif ( ( !isset( $params->pod_id ) || empty( $params->pod_id ) ) && ( true === $db || 0 < $db ) )
2292
+ $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
2293
+ elseif ( !isset( $params->pod ) && ( true === $db || 0 < $db ) )
2294
+ $pod = $this->load_pod( array( 'id' => $params->pod_id, 'table_info' => true ) );
2295
+ elseif ( true === $db || 0 < $db )
2296
+ $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
2297
+
2298
+ if ( empty( $pod ) && true === $db )
2299
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
2300
+
2301
+ $params->pod_id = $pod[ 'id' ];
2302
+ $params->pod = $pod[ 'name' ];
2303
+ $params->pod_data = $pod;
2304
+
2305
+ $params->name = pods_clean_name( $params->name, true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
2306
+
2307
+ if ( !isset( $params->id ) )
2308
+ $params->id = 0;
2309
+
2310
+ if ( empty( $params->name ) )
2311
+ return pods_error( 'Pod field name is required', $this );
2312
+
2313
+ $field = $this->load_field( $params );
2314
+
2315
+ unset( $params->pod_data );
2316
+
2317
+ $old_id = $old_name = $old_type = $old_definition = $old_simple = $old_options = $old_sister_id = null;
2318
+
2319
+ if ( !empty( $field ) ) {
2320
+ $old_id = pods_var( 'id', $field );
2321
+ $old_name = pods_clean_name( $field[ 'name' ], true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
2322
+ $old_type = $field[ 'type' ];
2323
+ $old_options = $field[ 'options' ];
2324
+ $old_sister_id = (int) pods_var( 'sister_id', $old_options, 0 );
2325
+
2326
+ $old_simple = ( 'pick' == $old_type && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
2327
+
2328
+ if ( isset( $params->name ) && !empty( $params->name ) )
2329
+ $field[ 'name' ] = $params->name;
2330
+
2331
+ if ( $old_name != $field[ 'name' ] && false !== $this->field_exists( $params ) )
2332
+ return pods_error( sprintf( __( 'Field %s already exists, you cannot rename %s to that', 'pods' ), $field[ 'name' ], $old_name ), $this );
2333
+
2334
+ if ( ( $id_required || !empty( $params->id ) ) && ( empty( $old_id ) || $old_id != $params->id ) )
2335
+ return pods_error( sprintf( __( 'Field %s already exists', 'pods' ), $field[ 'name' ] ), $this );
2336
+
2337
+ if ( empty( $params->id ) )
2338
+ $params->id = $old_id;
2339
+
2340
+ if ( !in_array( $old_type, $tableless_field_types ) || $old_simple ) {
2341
+ $definition = $this->get_field_definition( $old_type, array_merge( $field, $old_options ) );
2342
+
2343
+ if ( 0 < strlen( $definition ) )
2344
+ $old_definition = "`{$old_name}` " . $definition;
2345
+ }
2346
+ }
2347
+ else {
2348
+ $field = array(
2349
+ 'id' => 0,
2350
+ 'pod_id' => $params->pod_id,
2351
+ 'name' => $params->name,
2352
+ 'label' => $params->name,
2353
+ 'description' => '',
2354
+ 'type' => 'text',
2355
+ 'pick_object' => '',
2356
+ 'pick_val' => '',
2357
+ 'sister_id' => '',
2358
+ 'weight' => null,
2359
+ 'options' => array()
2360
+ );
2361
+ }
2362
+
2363
+ // Setup options
2364
+ $options = get_object_vars( $params );
2365
+
2366
+ $options_ignore = array(
2367
+ 'method',
2368
+ 'table_info',
2369
+ 'attributes',
2370
+ 'group',
2371
+ 'grouped',
2372
+ 'developer_mode',
2373
+ 'dependency',
2374
+ 'depends-on',
2375
+ 'excludes-on'
2376
+ );
2377
+
2378
+ foreach ( $options_ignore as $ignore ) {
2379
+ if ( isset( $options[ $ignore ] ) )
2380
+ unset( $options[ $ignore ] );
2381
+ }
2382
+
2383
+ if ( isset( $options[ 'method' ] ) )
2384
+ unset( $options[ 'method' ] );
2385
+ elseif ( isset( $options[ 'table_info' ] ) )
2386
+ unset( $options[ 'table_info' ] );
2387
+
2388
+ $exclude = array(
2389
+ 'id',
2390
+ 'pod_id',
2391
+ 'pod',
2392
+ 'name',
2393
+ 'label',
2394
+ 'description',
2395
+ 'type',
2396
+ 'pick_object',
2397
+ 'pick_val',
2398
+ 'sister_id',
2399
+ 'weight',
2400
+ 'options'
2401
+ );
2402
+
2403
+ foreach ( $exclude as $k => $exclude_field ) {
2404
+ $aliases = array( $exclude_field );
2405
+
2406
+ if ( is_array( $exclude_field ) ) {
2407
+ $aliases = array_merge( array( $k ), $exclude_field );
2408
+ $exclude_field = $k;
2409
+ }
2410
+
2411
+ foreach ( $aliases as $alias ) {
2412
+ if ( isset( $options[ $alias ] ) ) {
2413
+ $field[ $exclude_field ] = pods_trim( $options[ $alias ] );
2414
+
2415
+ unset( $options[ $alias ] );
2416
+ }
2417
+ }
2418
+ }
2419
+
2420
+ if ( strlen( $field[ 'label' ] ) < 1 )
2421
+ $field[ 'label' ] = $field[ 'name' ];
2422
+
2423
+ $field[ 'options' ][ 'type' ] = $field[ 'type' ];
2424
+
2425
+ if ( in_array( $field[ 'options' ][ 'type' ], $tableless_field_types ) ) {
2426
+ // Clean up special drop-down in field editor and save out pick_val
2427
+ $field[ 'pick_object' ] = pods_var( 'pick_object', $field, '', null, true );
2428
+
2429
+ if ( 0 === strpos( $field[ 'pick_object' ], 'pod-' ) ) {
2430
+ $field[ 'pick_val' ] = pods_str_replace( 'pod-', '', $field[ 'pick_object' ], 1 );
2431
+ $field[ 'pick_object' ] = 'pod';
2432
+ }
2433
+ elseif ( 0 === strpos( $field[ 'pick_object' ], 'post_type-' ) ) {
2434
+ $field[ 'pick_val' ] = pods_str_replace( 'post_type-', '', $field[ 'pick_object' ], 1 );
2435
+ $field[ 'pick_object' ] = 'post_type';
2436
+ }
2437
+ elseif ( 0 === strpos( $field[ 'pick_object' ], 'taxonomy-' ) ) {
2438
+ $field[ 'pick_val' ] = pods_str_replace( 'taxonomy-', '', $field[ 'pick_object' ], 1 );
2439
+ $field[ 'pick_object' ] = 'taxonomy';
2440
+ }
2441
+ elseif ( 'table' == $field[ 'pick_object' ] && 0 < strlen( pods_var_raw( 'pick_table', $field[ 'options' ] ) ) ) {
2442
+ $field[ 'pick_val' ] = $field[ 'options' ][ 'pick_table' ];
2443
+ $field[ 'pick_object' ] = 'table';
2444
+ }
2445
+ elseif ( false === strpos( $field[ 'pick_object' ], '-' ) && !in_array( $field[ 'pick_object' ], array( 'pod', 'post_type', 'taxonomy' ) ) ) {
2446
+ $field[ 'pick_val' ] = '';
2447
+ }
2448
+ elseif ( 'custom-simple' == $field[ 'pick_object' ] ) {
2449
+ $field[ 'pick_val' ] = '';
2450
+ }
2451
+
2452
+ $field[ 'options' ][ 'pick_object' ] = $field[ 'pick_object' ];
2453
+ $field[ 'options' ][ 'pick_val' ] = $field[ 'pick_val' ];
2454
+ $field[ 'options' ][ 'sister_id' ] = pods_var( 'sister_id', $field );
2455
+
2456
+ unset( $field[ 'pick_object' ] );
2457
+ unset( $field[ 'pick_val' ] );
2458
+
2459
+ if ( isset( $field[ 'sister_id' ] ) )
2460
+ unset( $field[ 'sister_id' ] );
2461
+ }
2462
+
2463
+ $field[ 'options' ] = array_merge( $field[ 'options' ], $options );
2464
+
2465
+ $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
2466
+
2467
+ if ( 0 < $old_id && defined( 'PODS_FIELD_STRICT' ) && !PODS_FIELD_STRICT )
2468
+ $params->id = $field[ 'id' ] = $old_id;
2469
+
2470
+ // Add new field
2471
+ if ( !isset( $params->id ) || empty( $params->id ) || empty( $field ) ) {
2472
+ if ( $table_operation && in_array( $field[ 'name' ], array( 'created', 'modified' ) ) && !in_array( $field[ 'type' ], array( 'date', 'datetime' ) ) && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2473
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2474
+
2475
+ if ( $table_operation && 'author' == $field[ 'name' ] && 'pick' != $field[ 'type' ] && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2476
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2477
+
2478
+ if ( in_array( $field[ 'name' ], array( 'id', 'ID' ) ) )
2479
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2480
+
2481
+ foreach ( $object_fields as $object_field => $object_field_opt ) {
2482
+ if ( $object_field == $field[ 'name' ] || in_array( $field[ 'name' ], $object_field_opt[ 'alias' ] ) )
2483
+ return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name. Also consider what WordPress and Pods provide you built-in.', 'pods' ), $field[ 'name' ] ), $this );
2484
+ }
2485
+
2486
+ if ( in_array( $field[ 'name' ], array( 'rss' ) ) ) // Reserved post_name values that can't be used as field names
2487
+ $field[ 'name' ] .= '2';
2488
+
2489
+ if ( 'slug' == $field[ 'type' ] && true === $db ) {
2490
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy', 'user' ) ) )
2491
+ return pods_error( __( 'This pod already has an internal WordPress permalink field', 'pods' ), $this );
2492
+
2493
+ $slug_field = get_posts( array(
2494
+ 'post_type' => '_pods_field',
2495
+ 'orderby' => 'menu_order',
2496
+ 'order' => 'ASC',
2497
+ 'posts_per_page' => 1,
2498
+ 'post_parent' => $field[ 'pod_id' ],
2499
+ 'meta_query' => array(
2500
+ array(
2501
+ 'key' => 'type',
2502
+ 'value' => 'slug'
2503
+ )
2504
+ )
2505
+ ) );
2506
+
2507
+ if ( !empty( $slug_field ) )
2508
+ return pods_error( __( 'This pod already has a permalink field', 'pods' ), $this );
2509
+ }
2510
+
2511
+ // Sink the new field to the bottom of the list
2512
+ if ( null === $field[ 'weight' ] ) {
2513
+ $field[ 'weight' ] = 0;
2514
+
2515
+ $bottom_most_field = get_posts( array(
2516
+ 'post_type' => '_pods_field',
2517
+ 'orderby' => 'menu_order',
2518
+ 'order' => 'DESC',
2519
+ 'posts_per_page' => 1,
2520
+ 'post_parent' => $field[ 'pod_id' ]
2521
+ ) );
2522
+
2523
+ if ( !empty( $bottom_most_field ) )
2524
+ $field[ 'weight' ] = pods_absint( $bottom_most_field[ 0 ]->menu_order ) + 1;
2525
+ }
2526
+
2527
+ $field[ 'weight' ] = pods_absint( $field[ 'weight' ] );
2528
+
2529
+ $post_data = array(
2530
+ 'post_name' => $field[ 'name' ],
2531
+ 'post_title' => $field[ 'label' ],
2532
+ 'post_content' => $field[ 'description' ],
2533
+ 'post_type' => '_pods_field',
2534
+ 'post_parent' => $field[ 'pod_id' ],
2535
+ 'post_status' => 'publish',
2536
+ 'menu_order' => $field[ 'weight' ]
2537
+ );
2538
+ }
2539
+ else {
2540
+ if ( in_array( $field[ 'name' ], array( 'id', 'ID' ) ) ) {
2541
+ if ( null !== $old_name )
2542
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2543
+ else
2544
+ return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field[ 'name' ] ), $this );
2545
+ }
2546
+
2547
+ if ( null !== $old_name && $field[ 'name' ] != $old_name && in_array( $field[ 'name' ], array( 'created', 'modified' ) ) && !in_array( $field[ 'type' ], array( 'date', 'datetime' ) ) && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2548
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2549
+
2550
+ if ( null !== $old_name && $field[ 'name' ] != $old_name && 'author' == $field[ 'name' ] && 'pick' != $field[ 'type' ] && ( !defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) )
2551
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2552
+
2553
+ foreach ( $object_fields as $object_field => $object_field_opt ) {
2554
+ if ( $object_field != $field[ 'name' ] && !in_array( $field[ 'name' ], $object_field_opt[ 'alias' ] ) )
2555
+ continue;
2556
+
2557
+ if ( null !== $old_name )
2558
+ return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field[ 'name' ] ), $this );
2559
+ else
2560
+ return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field[ 'name' ] ), $this );
2561
+ }
2562
+
2563
+ $post_data = array(
2564
+ 'ID' => $field[ 'id' ],
2565
+ 'post_name' => $field[ 'name' ],
2566
+ 'post_title' => $field[ 'label' ],
2567
+ 'post_content' => $field[ 'description' ]
2568
+ );
2569
+
2570
+ if ( null !== $field[ 'weight' ] ) {
2571
+ $field[ 'weight' ] = pods_absint( $field[ 'weight' ] );
2572
+
2573
+ $post_data[ 'menu_order' ] = $field[ 'weight' ];
2574
+ }
2575
+ }
2576
+
2577
+ if ( true === $db ) {
2578
+ if ( !has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) )
2579
+ add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
2580
+
2581
+ $conflicted = false;
2582
+
2583
+ // Headway compatibility fix
2584
+ if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
2585
+ remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2586
+
2587
+ $conflicted = true;
2588
+ }
2589
+
2590
+ // Store the old field name
2591
+ if ( $old_name && $old_name != $post_data['post_name'] ) {
2592
+ $field['options']['old_name'] = $old_name;
2593
+ }
2594
+
2595
+ $params->id = $this->save_wp_object( 'post', $post_data, $field[ 'options' ], true, true );
2596
+
2597
+ if ( $conflicted )
2598
+ add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2599
+
2600
+ if ( false === $params->id )
2601
+ return pods_error( __( 'Cannot save Field', 'pods' ), $this );
2602
+ }
2603
+ else
2604
+ $params->id = $field[ 'name' ];
2605
+
2606
+ $field[ 'id' ] = $params->id;
2607
+
2608
+ $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field[ 'options' ] ), $simple_tableless_objects ) );
2609
+
2610
+ $definition = false;
2611
+
2612
+ if ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) {
2613
+ $field_definition = $this->get_field_definition( $field[ 'type' ], array_merge( $field, $field[ 'options' ] ) );
2614
+
2615
+ if ( 0 < strlen( $field_definition ) )
2616
+ $definition = '`' . $field[ 'name' ] . '` ' . $field_definition;
2617
+ }
2618
+
2619
+ $sister_id = (int) pods_var( 'sister_id', $field[ 'options' ], 0 );
2620
+
2621
+ if ( $table_operation && 'table' == $pod[ 'storage' ] && !pods_tableless() ) {
2622
+ if ( !empty( $old_id ) ) {
2623
+ if ( ( $field[ 'type' ] != $old_type || $old_simple != $simple ) && empty( $definition ) )
2624
+ pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$old_name}`", false );
2625
+ elseif ( 0 < strlen( $definition ) ) {
2626
+ if ( $old_name != $field[ 'name' ] || $old_simple != $simple ) {
2627
+ $test = false;
2628
+
2629
+ if ( 0 < strlen( $old_definition ) )
2630
+ $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2631
+
2632
+ // If the old field doesn't exist, continue to add a new field
2633
+ if ( false === $test )
2634
+ pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2635
+ }
2636
+ elseif ( null !== $old_definition && $definition != $old_definition ) {
2637
+ $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2638
+
2639
+ // If the old field doesn't exist, continue to add a new field
2640
+ if ( false === $test )
2641
+ pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2642
+ }
2643
+ }
2644
+ }
2645
+ elseif ( 0 < strlen( $definition ) ) {
2646
+ $test = false;
2647
+
2648
+ if ( 0 < strlen( $old_definition ) )
2649
+ $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `" . $field[ 'name' ] . "` {$definition}", false );
2650
+
2651
+ // If the old field doesn't exist, continue to add a new field
2652
+ if ( false === $test )
2653
+ pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2654
+ }
2655
+ }
2656
+
2657
+ if ( !empty( $old_id ) && 'meta' == $pod[ 'storage' ] && $old_name != $field[ 'name' ] && $pod[ 'meta_table' ] != $pod[ 'table' ] ) {
2658
+ $prepare = array(
2659
+ $field[ 'name' ],
2660
+ $old_name
2661
+ );
2662
+
2663
+ // Users don't have a type
2664
+ if ( !empty( $pod[ 'field_type' ] ) )
2665
+ $prepare[] = $pod[ 'name' ];
2666
+
2667
+ pods_query( "
2668
+ UPDATE `{$pod[ 'meta_table' ]}` AS `m`
2669
+ LEFT JOIN `{$pod[ 'table' ]}` AS `t`
2670
+ ON `t`.`{$pod[ 'field_id' ]}` = `m`.`{$pod[ 'meta_field_id' ]}`
2671
+ SET
2672
+ `m`.`{$pod[ 'meta_field_index' ]}` = %s
2673
+ WHERE
2674
+ `m`.`{$pod[ 'meta_field_index' ]}` = %s
2675
+ " . ( !empty( $pod[ 'field_type' ] ) ? " AND `t`.`{$pod[ 'field_type' ]}` = %s" : "" ),
2676
+ $prepare
2677
+ );
2678
+ }
2679
+
2680
+ if ( $field[ 'type' ] != $old_type && in_array( $old_type, $tableless_field_types ) ) {
2681
+ delete_post_meta( $old_sister_id, 'sister_id' );
2682
+
2683
+ if ( true === $db ) {
2684
+ pods_query( "
2685
+ DELETE pm
2686
+ FROM {$wpdb->postmeta} AS pm
2687
+ LEFT JOIN {$wpdb->posts} AS p
2688
+ ON p.post_type = '_pods_field'
2689
+ AND p.ID = pm.post_id
2690
+ WHERE
2691
+ p.ID IS NOT NULL
2692
+ AND pm.meta_key = 'sister_id'
2693
+ AND pm.meta_value = %d
2694
+ ", array(
2695
+ $params->id
2696
+ )
2697
+ );
2698
+
2699
+ if ( !pods_tableless() ) {
2700
+ pods_query( "DELETE FROM @wp_podsrel WHERE `field_id` = {$params->id}", false );
2701
+
2702
+ pods_query( "
2703
+ UPDATE `@wp_podsrel`
2704
+ SET `related_field_id` = 0
2705
+ WHERE `field_id` = %d
2706
+ ", array(
2707
+ $old_sister_id
2708
+ )
2709
+ );
2710
+ }
2711
+ }
2712
+ }
2713
+ elseif ( 0 < $sister_id ) {
2714
+ update_post_meta( $sister_id, 'sister_id', $params->id );
2715
+
2716
+ if ( true === $db && ( !pods_tableless() ) ) {
2717
+ pods_query( "
2718
+ UPDATE `@wp_podsrel`
2719
+ SET `related_field_id` = %d
2720
+ WHERE `field_id` = %d
2721
+ ",
2722
+ array(
2723
+ $params->id,
2724
+ $sister_id
2725
+ )
2726
+ );
2727
+ }
2728
+ }
2729
+ elseif ( 0 < $old_sister_id ) {
2730
+ delete_post_meta( $old_sister_id, 'sister_id' );
2731
+
2732
+ if ( true === $db && ( !pods_tableless() ) ) {
2733
+ pods_query( "
2734
+ UPDATE `@wp_podsrel`
2735
+ SET `related_field_id` = 0
2736
+ WHERE `field_id` = %d
2737
+ ", array(
2738
+ $old_sister_id
2739
+ )
2740
+ );
2741
+ }
2742
+ }
2743
+
2744
+ if ( !empty( $old_id ) && $old_name != $field[ 'name' ] && true === $db ) {
2745
+ pods_query( "
2746
+ UPDATE `@wp_postmeta`
2747
+ SET `meta_value` = %s
2748
+ WHERE
2749
+ `post_id` = %d
2750
+ AND `meta_key` = 'pod_index'
2751
+ AND `meta_value` = %s
2752
+ ", array(
2753
+ $field[ 'name' ],
2754
+ $pod[ 'id' ],
2755
+ $old_name
2756
+ )
2757
+ );
2758
+ }
2759
+
2760
+ if ( !$save_pod )
2761
+ $this->cache_flush_pods( $pod );
2762
+ else {
2763
+ pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
2764
+
2765
+ if ( !empty( $old_id ) && $old_name != $field[ 'name' ] )
2766
+ pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $old_name );
2767
+ }
2768
+
2769
+ if ( true === $db )
2770
+ return $params->id;
2771
+ else
2772
+ return $field;
2773
+ }
2774
+
2775
+ /**
2776
+ * Fix Pod / Field post_name to ensure they are exactly as saved (allow multiple posts w/ same post_name)
2777
+ *
2778
+ * @param string $slug Unique slug value
2779
+ * @param int $post_ID Post ID
2780
+ * @param string $post_status Post Status
2781
+ * @param string $post_type Post Type
2782
+ * @param int $post_parent Post Parent ID
2783
+ * @param string $original_slug Original slug value
2784
+ *
2785
+ * @return string Final slug value
2786
+ *
2787
+ * @since 2.3.3
2788
+ */
2789
+ public function save_slug_fix ( $slug, $post_ID, $post_status, $post_type, $post_parent = 0, $original_slug = null ) {
2790
+ if ( in_array( $post_type, array( '_pods_field', '_pods_pod' ) ) && false !== strpos( $slug, '-' ) )
2791
+ $slug = $original_slug;
2792
+
2793
+ return $slug;
2794
+ }
2795
+
2796
+ /**
2797
+ * Add or Edit a Pods Object
2798
+ *
2799
+ * $params['id'] int The Object ID
2800
+ * $params['name'] string The Object name
2801
+ * $params['type'] string The Object type
2802
+ * $params['options'] Associative array of Object options
2803
+ *
2804
+ * @param array|object $params An associative array of parameters
2805
+ * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will sanitize them if false.
2806
+ *
2807
+ * @return int The Object ID
2808
+ * @since 2.0
2809
+ */
2810
+ public function save_object ( $params, $sanitized = false ) {
2811
+ $params = (object) $params;
2812
+
2813
+ if ( false === $sanitized )
2814
+ $params = pods_sanitize( $params );
2815
+
2816
+ if ( !isset( $params->name ) || empty( $params->name ) )
2817
+ return pods_error( __( 'Name must be given to save an Object', 'pods' ), $this );
2818
+
2819
+ if ( !isset( $params->type ) || empty( $params->type ) )
2820
+ return pods_error( __( 'Type must be given to save an Object', 'pods' ), $this );
2821
+
2822
+ $object = array(
2823
+ 'id' => 0,
2824
+ 'name' => $params->name,
2825
+ 'type' => $params->type,
2826
+ 'code' => '',
2827
+ 'options' => array()
2828
+ );
2829
+
2830
+ // Setup options
2831
+ $options = get_object_vars( $params );
2832
+
2833
+ if ( isset( $options[ 'method' ] ) )
2834
+ unset( $options[ 'method' ] );
2835
+
2836
+ $exclude = array(
2837
+ 'id',
2838
+ 'name',
2839
+ 'helper_type',
2840
+ 'code',
2841
+ 'options',
2842
+ 'status'
2843
+ );
2844
+
2845
+ foreach ( $exclude as $k => $exclude_field ) {
2846
+ $aliases = array( $exclude_field );
2847
+
2848
+ if ( is_array( $exclude_field ) ) {
2849
+ $aliases = array_merge( array( $k ), $exclude_field );
2850
+ $exclude_field = $k;
2851
+ }
2852
+
2853
+ foreach ( $aliases as $alias ) {
2854
+ if ( isset( $options[ $alias ] ) ) {
2855
+ $object[ $exclude_field ] = pods_trim( $options[ $alias ] );
2856
+
2857
+ unset( $options[ $alias ] );
2858
+ }
2859
+ }
2860
+ }
2861
+
2862
+ if ( 'helper' == $object[ 'type' ] )
2863
+ $object[ 'options' ][ 'helper_type' ] = $object[ 'helper_type' ];
2864
+
2865
+ if ( isset( $object[ 'options' ][ 'code' ] ) )
2866
+ unset( $object[ 'options' ][ 'code' ] );
2867
+
2868
+ $object[ 'options' ] = array_merge( $object[ 'options' ], $options );
2869
+
2870
+ $post_data = array(
2871
+ 'post_name' => pods_clean_name( $object[ 'name' ], true),
2872
+ 'post_title' => $object[ 'name' ],
2873
+ 'post_content' => $object[ 'code' ],
2874
+ 'post_type' => '_pods_' . $object[ 'type' ],
2875
+ 'post_status' => 'publish'
2876
+ );
2877
+
2878
+ if ( !empty( $object[ 'id' ] ) )
2879
+ $post_data[ 'ID' ] = $object[ 'id' ];
2880
+
2881
+ if ( null !== pods_var( 'status', $object, null, null, true ) )
2882
+ $post_data[ 'post_status' ] = pods_var( 'status', $object, null, null, true );
2883
+
2884
+ remove_filter( 'content_save_pre', 'balanceTags', 50 );
2885
+
2886
+ $post_data = pods_sanitize( $post_data );
2887
+
2888
+ $params->id = $this->save_post( $post_data, $object[ 'options' ], true, true );
2889
+
2890
+ pods_transient_clear( 'pods_objects_' . $params->type );
2891
+ pods_transient_clear( 'pods_objects_' . $params->type . '_get' );
2892
+
2893
+ return $params->id;
2894
+ }
2895
+
2896
+ /**
2897
+ * @see PodsAPI::save_object
2898
+ *
2899
+ * Add or edit a Pod Template
2900
+ *
2901
+ * $params['id'] int The template ID
2902
+ * $params['name'] string The template name
2903
+ * $params['code'] string The template code
2904
+ *
2905
+ * @param array|object $params An associative array of parameters
2906
+ * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2907
+ *
2908
+ * @return int The Template ID
2909
+ *
2910
+ * @since 1.7.9
2911
+ */
2912
+ public function save_template ( $params, $sanitized = false ) {
2913
+ $params = (object) $params;
2914
+
2915
+ $params->type = 'template';
2916
+
2917
+ return $this->save_object( $params, $sanitized );
2918
+ }
2919
+
2920
+ /**
2921
+ * @see PodsAPI::save_object
2922
+ *
2923
+ * Add or edit a Pod Page
2924
+ *
2925
+ * $params['id'] int The page ID
2926
+ * $params['name'] string The page URI
2927
+ * $params['code'] string The page code
2928
+ *
2929
+ * @param array|object $params An associative array of parameters
2930
+ * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2931
+ *
2932
+ * @return int The page ID
2933
+ * @since 1.7.9
2934
+ */
2935
+ public function save_page ( $params, $sanitized = false ) {
2936
+ $params = (object) $params;
2937
+
2938
+ if ( !isset( $params->name ) ) {
2939
+ $params->name = $params->uri;
2940
+ unset( $params->uri );
2941
+ }
2942
+
2943
+ if ( isset( $params->phpcode ) ) {
2944
+ $params->code = $params->phpcode;
2945
+ unset( $params->phpcode );
2946
+ }
2947
+
2948
+ $params->name = trim( $params->name, '/' );
2949
+ $params->type = 'page';
2950
+
2951
+ return $this->save_object( $params, $sanitized );
2952
+ }
2953
+
2954
+ /**
2955
+ * @see PodsAPI::save_object
2956
+ *
2957
+ * Add or edit a Pod Helper
2958
+ *
2959
+ * $params['id'] int The helper ID
2960
+ * $params['name'] string The helper name
2961
+ * $params['helper_type'] string The helper type ("pre_save", "display", etc)
2962
+ * $params['code'] string The helper code
2963
+ *
2964
+ * @param array $params An associative array of parameters
2965
+ * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, will sanitize them if false.
2966
+ *
2967
+ * @return int The helper ID
2968
+ * @since 1.7.9
2969
+ */
2970
+ public function save_helper ( $params, $sanitized = false ) {
2971
+ $params = (object) $params;
2972
+
2973
+ if ( isset( $params->phpcode ) ) {
2974
+ $params->code = $params->phpcode;
2975
+ unset( $params->phpcode );
2976
+ }
2977
+
2978
+ if ( isset( $params->type ) ) {
2979
+ $params->helper_type = $params->type;
2980
+ unset( $params->type );
2981
+ }
2982
+
2983
+ $params->type = 'helper';
2984
+
2985
+ return $this->save_object( $params, $sanitized );
2986
+ }
2987
+
2988
+ /**
2989
+ * Add or edit a single pod item
2990
+ *
2991
+ * $params['pod'] string The Pod name (pod or pod_id is required)
2992
+ * $params['pod_id'] string The Pod ID (pod or pod_id is required)
2993
+ * $params['id'] int|array The item ID, or an array of item IDs to save data for
2994
+ * $params['data'] array (optional) Associative array of field names + values
2995
+ * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
2996
+ * $params['track_changed_fields'] bool Set to true to enable tracking of saved fields via PodsAPI::get_changed_fields()
2997
+ * $params['error_mode'] string Throw an 'exception', 'exit' with the message, return 'false', or return 'wp_error'
2998
+ *
2999
+ * @param array|object $params An associative array of parameters
3000
+ *
3001
+ * @return int|array The item ID, or an array of item IDs (if `id` is an array if IDs)
3002
+ *
3003
+ * @since 1.7.9
3004
+ */
3005
+ public function save_pod_item ( $params ) {
3006
+
3007
+ global $wpdb;
3008
+
3009
+ $params = (object) pods_str_replace( '@wp_', '{prefix}', $params );
3010
+
3011
+ $tableless_field_types = PodsForm::tableless_field_types();
3012
+ $repeatable_field_types = PodsForm::repeatable_field_types();
3013
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
3014
+
3015
+ $error_mode = $this->display_errors;
3016
+
3017
+ if ( ! empty( $params->error_mode ) ) {
3018
+ $error_mode = $params->error_mode;
3019
+ }
3020
+
3021
+ // @deprecated 2.0
3022
+ if ( isset( $params->datatype ) ) {
3023
+ pods_deprecated( '$params->pod instead of $params->datatype', '2.0' );
3024
+
3025
+ $params->pod = $params->datatype;
3026
+
3027
+ unset( $params->datatype );
3028
+
3029
+ if ( isset( $params->pod_id ) ) {
3030
+ pods_deprecated( '$params->id instead of $params->pod_id', '2.0' );
3031
+
3032
+ $params->id = $params->pod_id;
3033
+
3034
+ unset( $params->pod_id );
3035
+ }
3036
+
3037
+ if ( isset( $params->data ) && !empty( $params->data ) && is_array( $params->data ) ) {
3038
+ $check = current( $params->data );
3039
+
3040
+ if ( is_array( $check ) ) {
3041
+ pods_deprecated( 'PodsAPI::save_pod_items', '2.0' );
3042
+
3043
+ return $this->save_pod_items( $params, $params->data );
3044
+ }
3045
+ }
3046
+ }
3047
+
3048
+ // @deprecated 2.0
3049
+ if ( isset( $params->tbl_row_id ) ) {
3050
+ pods_deprecated( '$params->id instead of $params->tbl_row_id', '2.0' );
3051
+
3052
+ $params->id = $params->tbl_row_id;
3053
+
3054
+ unset( $params->tbl_row_id );
3055
+ }
3056
+
3057
+ // @deprecated 2.0
3058
+ if ( isset( $params->columns ) ) {
3059
+ pods_deprecated( '$params->data instead of $params->columns', '2.0' );
3060
+
3061
+ $params->data = $params->columns;
3062
+
3063
+ unset( $params->columns );
3064
+ }
3065
+
3066
+ if ( !isset( $params->pod ) )
3067
+ $params->pod = false;
3068
+ if ( isset( $params->pod_id ) )
3069
+ $params->pod_id = pods_absint( $params->pod_id );
3070
+ else
3071
+ $params->pod_id = 0;
3072
+
3073
+ if ( isset( $params->id ) )
3074
+ $params->id = pods_absint( $params->id );
3075
+ else
3076
+ $params->id = 0;
3077
+
3078
+ if ( !isset( $params->from ) )
3079
+ $params->from = 'save';
3080
+
3081
+ if ( !isset( $params->location ) )
3082
+ $params->location = null;
3083
+
3084
+ if ( !isset( $params->track_changed_fields ) )
3085
+ $params->track_changed_fields = false;
3086
+
3087
+ /**
3088
+ * Override $params['track_changed_fields']
3089
+ *
3090
+ * Use for globally setting field change tracking.
3091
+ *
3092
+ * @param bool
3093
+ *
3094
+ * @since 2.3.19
3095
+ */
3096
+ $track_changed_fields = apply_filters( 'pods_api_save_pod_item_track_changed_fields_' . $params->pod, (boolean) $params->track_changed_fields, $params );
3097
+
3098
+ $changed_fields = array();
3099
+
3100
+ if ( !isset( $params->clear_slug_cache ) ) {
3101
+ $params->clear_slug_cache = true;
3102
+ }
3103
+
3104
+ // Support for bulk edit
3105
+ if ( isset( $params->id ) && !empty( $params->id ) && is_array( $params->id ) ) {
3106
+ $ids = array();
3107
+ $new_params = $params;
3108
+
3109
+ foreach ( $params->id as $id ) {
3110
+ $new_params->id = $id;
3111
+
3112
+ $ids[] = $this->save_pod_item( $new_params );
3113
+ }
3114
+
3115
+ return $ids;
3116
+ }
3117
+
3118
+ // Allow Helpers to know what's going on, are we adding or saving?
3119
+ $is_new_item = false;
3120
+
3121
+ if ( empty( $params->id ) )
3122
+ $is_new_item = true;
3123
+
3124
+ if ( isset( $params->is_new_item ) )
3125
+ $is_new_item = (boolean) $params->is_new_item;
3126
+
3127
+ // Allow Helpers to bypass subsequent helpers in recursive save_pod_item calls
3128
+ $bypass_helpers = false;
3129
+
3130
+ if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
3131
+ $bypass_helpers = true;
3132
+
3133
+ // Allow Custom Fields not defined by Pods to be saved
3134
+ $allow_custom_fields = false;
3135
+
3136
+ if ( isset( $params->allow_custom_fields ) && false !== $params->allow_custom_fields )
3137
+ $allow_custom_fields = true;
3138
+
3139
+ // Get array of Pods
3140
+ $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
3141
+
3142
+ if ( false === $pod )
3143
+ return pods_error( __( 'Pod not found', 'pods' ), $error_mode );
3144
+
3145
+ $params->pod = $pod[ 'name' ];
3146
+ $params->pod_id = $pod[ 'id' ];
3147
+
3148
+ if ( 'settings' == $pod[ 'type' ] )
3149
+ $params->id = $pod[ 'id' ];
3150
+
3151
+ $fields = $pod[ 'fields' ];
3152
+
3153
+ $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
3154
+
3155
+ $fields_active = array();
3156
+ $custom_data = array();
3157
+
3158
+ // Find the active fields (loop through $params->data to retain order)
3159
+ if ( !empty( $params->data ) && is_array( $params->data ) ) {
3160
+ $custom_fields = array();
3161
+
3162
+ foreach ( $params->data as $field => $value ) {
3163
+ if ( isset( $object_fields[ $field ] ) ) {
3164
+ $object_fields[ $field ][ 'value' ] = $value;
3165
+ $fields_active[] = $field;
3166
+ }
3167
+ elseif ( isset( $fields[ $field ] ) ) {
3168
+ if ( 'save' == $params->from || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3169
+ $fields[ $field ][ 'value' ] = $value;
3170
+ $fields_active[] = $field;
3171
+ }
3172
+ elseif ( !pods_has_permissions( $fields[ $field ][ 'options' ] ) && pods_var( 'hidden', $fields[ $field ][ 'options' ], false ) ) {
3173
+ $fields[ $field ][ 'value' ] = $value;
3174
+ $fields_active[] = $field;
3175
+ }
3176
+ }
3177
+ else {
3178
+ $found = false;
3179
+
3180
+ foreach ( $object_fields as $object_field => $object_field_opt ) {
3181
+ if ( in_array( $field, $object_field_opt[ 'alias' ] ) ) {
3182
+ $object_fields[ $object_field ][ 'value' ] = $value;
3183
+ $fields_active[] = $object_field;
3184
+
3185
+ $found = true;
3186
+
3187
+ break;
3188
+ }
3189
+ }
3190
+
3191
+ if ( $allow_custom_fields && !$found )
3192
+ $custom_fields[] = $field;
3193
+ }
3194
+ }
3195
+
3196
+ if ( $allow_custom_fields && !empty( $custom_fields ) ) {
3197
+ foreach ( $custom_fields as $field ) {
3198
+ $custom_data[ $field ] = $params->data[ $field ];
3199
+ }
3200
+ }
3201
+
3202
+ unset( $params->data );
3203
+ }
3204
+
3205
+ if ( empty( $params->id ) && !in_array( 'created', $fields_active ) && isset( $fields[ 'created' ] ) && in_array( $fields[ 'created' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3206
+ $fields[ 'created' ][ 'value' ] = current_time( 'mysql' );
3207
+ $fields_active[] = 'created';
3208
+ }
3209
+
3210
+ if ( !in_array( 'modified', $fields_active ) && isset( $fields[ 'modified' ] ) && in_array( $fields[ 'modified' ][ 'type' ], array( 'date', 'datetime' ) ) ) {
3211
+ $fields[ 'modified' ][ 'value' ] = current_time( 'mysql' );
3212
+ $fields_active[] = 'modified';
3213
+ }
3214
+
3215
+ if ( in_array( $pod[ 'type' ], array( 'pod', 'table' ) ) && empty( $params->id ) && !empty( $pod[ 'pod_field_index' ] ) && in_array( $pod[ 'pod_field_index' ], $fields_active ) && !in_array( $pod[ 'pod_field_slug' ], $fields_active ) && isset( $fields[ $pod[ 'pod_field_slug' ] ] ) ) {
3216
+ $fields[ $pod[ 'pod_field_slug' ] ][ 'value' ] = ''; // this will get picked up by slug pre_save method
3217
+ $fields_active[] = $pod[ 'pod_field_slug' ];
3218
+ }
3219
+
3220
+ // Handle hidden fields
3221
+ if ( empty( $params->id ) ) {
3222
+ foreach ( $fields as $field => $field_data ) {
3223
+ if ( in_array( $field, $fields_active ) )
3224
+ continue;
3225
+
3226
+ if ( in_array( $params->from, array( 'save', 'process_form' ) ) || true === PodsForm::permission( $fields[ $field ][ 'type' ], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3227
+ $value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data[ 'type' ], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id );
3228
+
3229
+ if ( null !== $value && '' !== $value && false !== $value ) {
3230
+ $fields[ $field ][ 'value' ] = $value;
3231
+ $fields_active[] = $field;
3232
+ }
3233
+ }
3234
+ }
3235
+
3236
+ // Set default field values for object fields
3237
+ if ( !empty( $object_fields ) ) {
3238
+ foreach ( $object_fields as $field => $field_data ) {
3239
+ if ( in_array( $field, $fields_active ) ) {
3240
+ continue;
3241
+ }
3242
+ elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3243
+ continue;
3244
+ }
3245
+
3246
+ $value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data[ 'type' ], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id );
3247
+
3248
+ if ( null !== $value && '' !== $value && false !== $value ) {
3249
+ $object_fields[ $field ][ 'value' ] = $value;
3250
+ $fields_active[] = $field;
3251
+ }
3252
+ }
3253
+ }
3254
+
3255
+ // Set default field values for Pod fields
3256
+ foreach ( $fields as $field => $field_data ) {
3257
+ if ( in_array( $field, $fields_active ) ) {
3258
+ continue;
3259
+ }
3260
+ elseif ( !isset( $field_data[ 'default' ] ) || strlen( $field_data[ 'default' ] ) < 1 ) {
3261
+ continue;
3262
+ }
3263
+
3264
+ $value = PodsForm::default_value( pods_var_raw( $field, 'post' ), $field_data[ 'type' ], $field, pods_var_raw( 'options', $field_data, $field_data, null, true ), $pod, $params->id );
3265
+
3266
+ if ( null !== $value && '' !== $value && false !== $value ) {
3267
+ $fields[ $field ][ 'value' ] = $value;
3268
+ $fields_active[] = $field;
3269
+ }
3270
+ }
3271
+ }
3272
+
3273
+ $columns =& $fields; // @deprecated 2.0
3274
+ $active_columns =& $fields_active; // @deprecated 2.0
3275
+ $params->tbl_row_id =& $params->id; // @deprecated 2.0
3276
+
3277
+ $pre_save_helpers = $post_save_helpers = array();
3278
+
3279
+ $pieces = array(
3280
+ 'fields',
3281
+ 'params',
3282
+ 'pod',
3283
+ 'fields_active',
3284
+ 'object_fields',
3285
+ 'custom_fields',
3286
+ 'custom_data',
3287
+ 'track_changed_fields',
3288
+ 'changed_fields'
3289
+ );
3290
+
3291
+ if ( false === $bypass_helpers ) {
3292
+ // Plugin hooks
3293
+ $hooked = $this->do_hook( 'pre_save_pod_item', compact( $pieces ), $is_new_item, $params->id );
3294
+
3295
+ if ( is_array( $hooked ) && !empty( $hooked ) )
3296
+ extract( $hooked );
3297
+
3298
+ $hooked = $this->do_hook( "pre_save_pod_item_{$params->pod}", compact( $pieces ), $is_new_item, $params->id );
3299
+
3300
+ if ( is_array( $hooked ) && !empty( $hooked ) )
3301
+ extract( $hooked );
3302
+
3303
+ if ( $is_new_item ) {
3304
+ $hooked = $this->do_hook( 'pre_create_pod_item', compact( $pieces ) );
3305
+
3306
+ if ( is_array( $hooked ) && !empty( $hooked ) )
3307
+ extract( $hooked );
3308
+
3309
+ $hooked = $this->do_hook( "pre_create_pod_item_{$params->pod}", compact( $pieces ) );
3310
+
3311
+ if ( is_array( $hooked ) && !empty( $hooked ) )
3312
+ extract( $hooked );
3313
+ }
3314
+ else {
3315
+ $hooked = $this->do_hook( 'pre_edit_pod_item', compact( $pieces ), $params->id );
3316
+
3317
+ if ( is_array( $hooked ) && !empty( $hooked ) )
3318
+ extract( $hooked );
3319
+
3320
+ $hooked = $this->do_hook( "pre_edit_pod_item_{$params->pod}", compact( $pieces ), $params->id );
3321
+
3322
+ if ( is_array( $hooked ) && !empty( $hooked ) )
3323
+ extract( $hooked );
3324
+ }
3325
+
3326
+ // Call any pre-save helpers (if not bypassed)
3327
+ if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3328
+ if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
3329
+ $helpers = array( 'pre_save_helpers', 'post_save_helpers' );
3330
+
3331
+ foreach ( $helpers as $helper ) {
3332
+ if ( isset( $pod[ 'options' ][ $helper ] ) && !empty( $pod[ 'options' ][ $helper ] ) )
3333
+ ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
3334
+ }
3335
+ }
3336
+
3337
+ if ( !empty( $pre_save_helpers ) ) {
3338
+ pods_deprecated( sprintf( __( 'Pre-save helpers are deprecated, use the action pods_pre_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3339
+
3340
+ foreach ( $pre_save_helpers as $helper ) {
3341
+ $helper = $this->load_helper( array( 'name' => $helper ) );
3342
+
3343
+ if ( false !== $helper )
3344
+ eval( '?>' . $helper[ 'code' ] );
3345
+ }
3346
+ }
3347
+ }
3348
+ }
3349
+
3350
+ if ( $track_changed_fields ) {
3351
+ $changed_fields = $this->get_changed_fields( compact( $pieces ) );
3352
+ }
3353
+
3354
+ $table_data = $table_formats = $update_values = $rel_fields = $rel_field_ids = array();
3355
+
3356
+ $object_type = $pod[ 'type' ];
3357
+
3358
+ $object_ID = 'ID';
3359
+
3360
+ if ( 'comment' == $object_type )
3361
+ $object_ID = 'comment_ID';
3362
+ elseif ( 'taxonomy' == $object_type )
3363
+ $object_ID = 'term_id';
3364
+
3365
+ $object_data = $object_meta = $post_term_data = array();
3366
+
3367
+ if ( 'settings' == $object_type )
3368
+ $object_data[ 'option_id' ] = $pod[ 'name' ];
3369
+ elseif ( !empty( $params->id ) )
3370
+ $object_data[ $object_ID ] = $params->id;
3371
+
3372
+ $fields_active = array_unique( $fields_active );
3373
+
3374
+ // Loop through each active field, validating and preparing the table data
3375
+ foreach ( $fields_active as $field ) {
3376
+ if ( isset( $object_fields[ $field ] ) )
3377
+ $field_data = $object_fields[ $field ];
3378
+ elseif ( isset( $fields[ $field ] ) )
3379
+ $field_data = $fields[ $field ];
3380
+ else
3381
+ continue;
3382
+
3383
+ $value = $field_data[ 'value' ];
3384
+ $type = $field_data[ 'type' ];
3385
+ $options = pods_var( 'options', $field_data, array() );
3386
+
3387
+ // WPML AJAX compatibility
3388
+ if ( is_admin() && isset( $_GET[ 'page' ] ) && false !== strpos( $_GET[ 'page' ], '/menu/languages.php' ) && isset( $_POST[ 'icl_ajx_action' ] ) && isset( $_POST[ '_icl_nonce' ] ) && wp_verify_nonce( $_POST[ '_icl_nonce' ], $_POST[ 'icl_ajx_action' ] . '_nonce' ) )
3389
+ $options[ 'unique' ] = $fields[ $field ][ 'options' ][ 'unique' ] = $options[ 'required' ] = $fields[ $field ][ 'options' ][ 'required' ] = 0;
3390
+ else {
3391
+ // Validate value
3392
+ $validate = $this->handle_field_validation( $value, $field, $object_fields, $fields, $pod, $params );
3393
+
3394
+ if ( false === $validate )
3395
+ $validate = sprintf( __( 'There was an issue validating the field %s', 'pods' ), $field_data[ 'label' ] );
3396
+ elseif ( true !== $validate )
3397
+ $validate = (array) $validate;
3398
+
3399
+ if ( !is_bool( $validate ) && !empty( $validate ) )
3400
+ return pods_error( $validate, $error_mode );
3401
+ }
3402
+
3403
+ $value = PodsForm::pre_save( $field_data[ 'type' ], $value, $params->id, $field, array_merge( $field_data, $options ), array_merge( $fields, $object_fields ), $pod, $params );
3404
+
3405
+ $field_data[ 'value' ] = $value;
3406
+
3407
+ if ( isset( $object_fields[ $field ] ) ) {
3408
+ if ( 'taxonomy' == $object_fields[ $field ][ 'type' ] ) {
3409
+ $post_term_data[ $field ] = $value;
3410
+ }
3411
+ else {
3412
+ $object_data[ $field ] = $value;
3413
+ }
3414
+ }
3415
+ else {
3416
+ $simple = ( 'pick' == $type && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
3417
+ $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field_data, $field, $fields, $pod, $params );
3418
+
3419
+ // Handle Simple Relationships
3420
+ if ( $simple ) {
3421
+ if ( !is_array( $value ) )
3422
+ $value = explode( ',', $value );
3423
+
3424
+ $pick_limit = (int) pods_var_raw( 'pick_limit', $options, 0 );
3425
+
3426
+ if ( 'single' == pods_var_raw( 'pick_format_type', $options ) )
3427
+ $pick_limit = 1;
3428
+
3429
+ if ( 'custom-simple' == pods_var( 'pick_object', $field_data ) ) {
3430
+ $custom = pods_var_raw( 'pick_custom', $options, '' );
3431
+
3432
+ $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $field_data[ 'name' ], $value, array_merge( $field_data, $options ), $pod, $params->id );
3433
+
3434
+ if ( empty( $value ) || empty( $custom ) )
3435
+ $value = '';
3436
+ elseif ( !empty( $custom ) ) {
3437
+ if ( !is_array( $custom ) ) {
3438
+ $custom = explode( "\n", $custom );
3439
+
3440
+ $custom_values = array();
3441
+
3442
+ foreach ( $custom as $c => $cv ) {
3443
+ if ( 0 < strlen( $cv ) ) {
3444
+ $custom_label = explode( '|', $cv );
3445
+
3446
+ if ( !isset( $custom_label[ 1 ] ) )
3447
+ $custom_label[ 1 ] = $custom_label[ 0 ];
3448
+
3449
+ $custom_label[ 0 ] = trim( (string) $custom_label[ 0 ] );
3450
+ $custom_label[ 1 ] = trim( (string) $custom_label[ 1 ] );
3451
+ $custom_values[ $custom_label[ 0 ] ] = $custom_label[ 1 ];
3452
+ }
3453
+ }
3454
+ }
3455
+ else
3456
+ $custom_values = $custom;
3457
+
3458
+ $values = array();
3459
+
3460
+ foreach ( $value as $k => $v ) {
3461
+ $v = pods_unsanitize( $v );
3462
+
3463
+ if ( isset( $custom_values[ $v ] ) )
3464
+ $values[ $k ] = $v;
3465
+ }
3466
+
3467
+ $value = $values;
3468
+ }
3469
+ }
3470
+
3471
+ if ( 0 < $pick_limit && !empty( $value ) )
3472
+ $value = array_slice( $value, 0, $pick_limit );
3473
+
3474
+ // Don't save an empty array, just make it an empty string
3475
+ if ( empty( $value ) )
3476
+ $value = '';
3477
+ elseif ( is_array( $value ) ) {
3478
+ // If there's just one item, don't save as an array, save the string
3479
+ if ( 1 == $pick_limit || 1 == count( $value ) )
3480
+ $value = implode( '', $value );
3481
+ // If storage is set to table, json encode, otherwise WP will serialize automatically
3482
+ elseif ( 'table' == pods_var( 'storage', $pod ) )
3483
+ $value = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $value, JSON_UNESCAPED_UNICODE ) : json_encode( $value );
3484
+ }
3485
+ }
3486
+
3487
+ // Prepare all table / meta data
3488
+ if ( !in_array( $type, $tableless_field_types ) || $simple ) {
3489
+ if ( in_array( $type, $repeatable_field_types ) && 1 == pods_var( $type . '_repeatable', $field_data, 0 ) ) {
3490
+ // Don't save an empty array, just make it an empty string
3491
+ if ( empty( $value ) )
3492
+ $value = '';
3493
+ elseif ( is_array( $value ) ) {
3494
+ // If there's just one item, don't save as an array, save the string
3495
+ if ( 1 == count( $value ) )
3496
+ $value = implode( '', $value );
3497
+ // If storage is set to table, json encode, otherwise WP will serialize automatically
3498
+ elseif ( 'table' == pods_var( 'storage', $pod ) )
3499
+ $value = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $value, JSON_UNESCAPED_UNICODE ) : json_encode( $value );
3500
+ }
3501
+ }
3502
+
3503
+ $table_data[ $field ] = str_replace( array( '{prefix}', '@wp_' ), array( '{/prefix/}', '{prefix}' ), $value ); // Fix for pods_query
3504
+ $table_formats[] = PodsForm::prepare( $type, $options );
3505
+
3506
+ $object_meta[ $field ] = $value;
3507
+ }
3508
+ // Store relational field data to be looped through later
3509
+ else {
3510
+ // Convert values from a comma-separated string into an array
3511
+ if ( !is_array( $value ) )
3512
+ $value = explode( ',', $value );
3513
+
3514
+ $rel_fields[ $type ][ $field ] = $value;
3515
+ $rel_field_ids[] = $field_data[ 'id' ];
3516
+ }
3517
+ }
3518
+ }
3519
+
3520
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) ) {
3521
+ $object_name = $pod[ 'name' ];
3522
+
3523
+ if ( !empty( $pod[ 'object' ] ) )
3524
+ $object_name = $pod[ 'object' ];
3525
+
3526
+ $object_name_field = 'post_type';
3527
+
3528
+ if ( 'taxonomy' == $pod['type'] ) {
3529
+ $object_name_field = 'taxonomy';
3530
+ }
3531
+
3532
+ $object_data[ $object_name_field ] = $object_name;
3533
+ }
3534
+
3535
+ if ( ( 'meta' == $pod[ 'storage' ] || 'settings' == $pod[ 'type' ] || ( 'taxonomy' == $pod[ 'type' ] && 'none' == $pod[ 'storage' ] ) ) && !in_array( $pod[ 'type' ], array( 'pod', 'table', '' ) ) ) {
3536
+ if ( $allow_custom_fields && !empty( $custom_data ) )
3537
+ $object_meta = array_merge( $custom_data, $object_meta );
3538
+
3539
+ $fields_to_send = array_flip( array_keys( $object_meta ) );
3540
+
3541
+ foreach ( $fields_to_send as $field => $field_data ) {
3542
+ if ( isset( $object_fields[ $field ] ) ) {
3543
+ $field_data = $object_fields[ $field ];
3544
+ }
3545
+ elseif ( isset( $fields[ $field ] ) ) {
3546
+ $field_data = $fields[ $field ];
3547
+ }
3548
+ else {
3549
+ unset( $fields_to_send[ $field ] );
3550
+ }
3551
+
3552
+ $fields_to_send[ $field ] = $field_data;
3553
+ }
3554
+
3555
+ $params->id = $this->save_wp_object( $object_type, $object_data, $object_meta, false, true, $fields_to_send );
3556
+
3557
+ if ( !empty( $params->id ) && 'settings' == $object_type )
3558
+ $params->id = $pod[ 'id' ];
3559
+ }
3560
+ else {
3561
+ if ( ! in_array( $pod[ 'type' ], array( 'pod', 'table', '' ) ) ) {
3562
+ $params->id = $this->save_wp_object( $object_type, $object_data, array(), false, true );
3563
+ }
3564
+
3565
+ if ( 'table' == $pod[ 'storage' ] ) {
3566
+ // Every row should have an id set here, otherwise Pods with nothing
3567
+ // but relationship fields won't get properly ID'd
3568
+ if ( empty( $params->id ) )
3569
+ $params->id = 0;
3570
+
3571
+ $table_data = array( 'id' => $params->id ) + $table_data;
3572
+ array_unshift( $table_formats, '%d' );
3573
+
3574
+ if ( !empty( $table_data ) ) {
3575
+ $sql = pods_data()->insert_on_duplicate( "@wp_pods_{$params->pod}", $table_data, $table_formats );
3576
+
3577
+ $id = pods_query( $sql, 'Cannot add/save table row' );
3578
+
3579
+ if ( empty( $params->id ) )
3580
+ $params->id = $id;
3581
+ }
3582
+ }
3583
+ }
3584
+
3585
+ $params->id = (int) $params->id;
3586
+
3587
+ // Save terms for taxonomies associated to a post type
3588
+ if ( 0 < $params->id && 'post_type' == $pod[ 'type' ] && !empty( $post_term_data ) ) {
3589
+ foreach ( $post_term_data as $post_taxonomy => $post_terms ) {
3590
+ $post_terms = (array) $post_terms;
3591
+
3592
+ foreach ( $post_terms as $k => $v ) {
3593
+ if ( ! preg_match( '/[^0-9]/', $v ) ) {
3594
+ $v = (int) $v;
3595
+ }
3596
+
3597
+ $post_terms[ $k ] = $v;
3598
+ }
3599
+
3600
+ wp_set_object_terms( $params->id, $post_terms, $post_taxonomy );
3601
+ }
3602
+ }
3603
+
3604
+ $no_conflict = pods_no_conflict_check( $pod[ 'type' ] );
3605
+
3606
+ if ( !$no_conflict )
3607
+ pods_no_conflict_on( $pod[ 'type' ] );
3608
+
3609
+ // Save relationship / file data
3610
+ if ( !empty( $rel_fields ) ) {
3611
+ foreach ( $rel_fields as $type => $data ) {
3612
+ // Only handle tableless fields
3613
+ if ( !in_array( $type, $tableless_field_types ) ) {
3614
+ continue;
3615
+ }
3616
+
3617
+ foreach ( $data as $field => $values ) {
3618
+ $pick_val = pods_var( 'pick_val', $fields[ $field ] );
3619
+
3620
+ if ( 'table' == pods_var( 'pick_object', $fields[ $field ] ) ) {
3621
+ $pick_val = pods_var( 'pick_table', $fields[ $field ][ 'options' ], $pick_val, null, true );
3622
+ }
3623
+
3624
+ if ( '__current__' == $pick_val ) {
3625
+ if ( is_object( $pod ) ) {
3626
+ $pick_val = $pod->pod;
3627
+ }
3628
+ elseif ( is_array( $pod ) ) {
3629
+ $pick_val = $pod[ 'name' ];
3630
+ }
3631
+ elseif ( 0 < strlen( $pod ) ) {
3632
+ $pick_val = $pod;
3633
+ }
3634
+ }
3635
+
3636
+ $fields[ $field ][ 'options' ][ 'table_info' ] = pods_api()->get_table_info( pods_var( 'pick_object', $fields[ $field ] ), $pick_val, null, null, $fields[ $field ][ 'options' ] );
3637
+
3638
+ if ( isset( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ] ) && !empty( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ] ) && isset( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ][ 'name' ] ) ) {
3639
+ $search_data = pods( $fields[ $field ][ 'options' ][ 'table_info' ][ 'pod' ][ 'name' ] );
3640
+
3641
+ $data_mode = 'pods';
3642
+ }
3643
+ else {
3644
+ $search_data = pods_data();
3645
+ $search_data->table( $fields[ $field ][ 'options' ][ 'table_info' ] );
3646
+
3647
+ $data_mode = 'data';
3648
+ }
3649
+
3650
+ $find_rel_params = array(
3651
+ 'select' => "`t`.`{$search_data->field_id}`",
3652
+ 'where' => "`t`.`{$search_data->field_slug}` = %s OR `t`.`{$search_data->field_index}` = %s",
3653
+ 'limit' => 1,
3654
+ 'pagination' => false,
3655
+ 'search' => false
3656
+ );
3657
+
3658
+ if ( empty( $search_data->field_slug ) && !empty( $search_data->field_index ) ) {
3659
+ $find_rel_params[ 'where' ] = "`t`.`{$search_data->field_index}` = %s";
3660
+ }
3661
+ elseif ( empty( $search_data->field_slug ) && empty( $search_data->field_index ) ) {
3662
+ $find_rel_params = false;
3663
+ }
3664
+
3665
+ $related_limit = (int) pods_var_raw( $type . '_limit', $fields[ $field ][ 'options' ], 0 );
3666
+
3667
+ if ( 'single' == pods_var_raw( $type . '_format_type', $fields[ $field ][ 'options' ] ) ) {
3668
+ $related_limit = 1;
3669
+ }
3670
+
3671
+ // Enforce integers / unique values for IDs
3672
+ $value_ids = array();
3673
+
3674
+ $is_file_field = in_array( $type, PodsForm::file_field_types() );
3675
+ $is_taggable = ( in_array( $type, PodsForm::tableless_field_types() ) && 1 == pods_v( $type . '_taggable', $fields[ $field ][ 'options' ] ) );
3676
+
3677
+ // @todo Handle simple relationships eventually
3678
+ foreach ( $values as $v ) {
3679
+ if ( !empty( $v ) ) {
3680
+ if ( !is_array( $v ) ) {
3681
+ if ( !preg_match( '/[^0-9]/', $v ) ) {
3682
+ $v = (int) $v;
3683
+ }
3684
+ // File handling
3685
+ elseif ( $is_file_field ) {
3686
+ // Get ID from GUID
3687
+ $v = pods_image_id_from_field( $v );
3688
+
3689
+ // If file not found, add it
3690
+ if ( empty( $v ) ) {
3691
+ $v = pods_attachment_import( $v );
3692
+ }
3693
+ }
3694
+ // Reference by slug
3695
+ else {
3696
+ $v_data = false;
3697
+
3698
+ if ( false !== $find_rel_params ) {
3699
+ $rel_params = $find_rel_params;
3700
+ $rel_params[ 'where' ] = $wpdb->prepare( $rel_params[ 'where' ], array( $v, $v ) );
3701
+
3702
+ $search_data->select( $rel_params );
3703
+
3704
+ $v_data = $search_data->fetch( $v );
3705
+ }
3706
+
3707
+ if ( !empty( $v_data ) && isset( $v_data[ $search_data->field_id ] ) ) {
3708
+ $v = (int) $v_data[ $search_data->field_id ];
3709
+ }
3710
+ // Allow tagging for Pods objects
3711
+ elseif ( $is_taggable && 'pods' == $data_mode ) {
3712
+ $tag_data = array(
3713
+ $search_data->field_index => $v
3714
+ );
3715
+
3716
+ if ( 'post_type' == $search_data->pod_data[ 'type' ] ) {
3717
+ $tag_data[ 'post_status' ] = 'publish';
3718
+ }
3719
+
3720
+ /**
3721
+ * Filter for changing tag before adding new item.
3722
+ *
3723
+ * @param array $tag_data Fields for creating new item.
3724
+ * @param int $v Field ID of tag.
3725
+ * @param obj $search_data Search object for tag.
3726
+ * @param string $field Table info for field.
3727
+ * @param array $pieces Field array.
3728
+ *
3729
+ * @since 2.3.19
3730
+ */
3731
+ $tag_data = apply_filters( 'pods_api_save_pod_item_taggable_data', $tag_data, $v, $search_data, $field, compact( $pieces ) );
3732
+
3733
+ // Save $v to a new item on related object
3734
+ $v = $search_data->add( $tag_data );
3735
+
3736
+ // @todo Support non-Pods for tagging
3737
+ }
3738
+ }
3739
+ }
3740
+ elseif ( $is_file_field && isset( $v[ 'id' ] ) ) {
3741
+ $v = (int) $v[ 'id' ];
3742
+ }
3743
+ else {
3744
+ continue;
3745
+ }
3746
+
3747
+ if ( !empty( $v ) && !in_array( $v, $value_ids ) ) {
3748
+ $value_ids[] = $v;
3749
+ }
3750
+ }
3751
+ }
3752
+
3753
+ $value_ids = array_unique( array_filter( $value_ids ) );
3754
+
3755
+ // Filter unique values not equal to false in case of a multidimensional array
3756
+ $filtered_values = $this->array_filter_walker( $values );
3757
+ $serialized_values = array_map( 'serialize', $filtered_values );
3758
+ $unique_serialized_values = array_unique( $serialized_values );
3759
+
3760
+ $values = array_map( 'unserialize', $unique_serialized_values );
3761
+
3762
+ // Limit values
3763
+ if ( 0 < $related_limit && !empty( $value_ids ) ) {
3764
+ $value_ids = array_slice( $value_ids, 0, $related_limit );
3765
+ $values = array_slice( $values, 0, $related_limit );
3766
+ }
3767
+
3768
+ // Get current values
3769
+ if ( 'pick' == $type && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ] ) )
3770
+ $related_ids = PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'current_ids' ];
3771
+ else
3772
+ $related_ids = $this->lookup_related_items( $fields[ $field ][ 'id' ], $pod[ 'id' ], $params->id, $fields[ $field ], $pod );
3773
+
3774
+ // Get ids to remove
3775
+ $remove_ids = array_diff( $related_ids, $value_ids );
3776
+
3777
+ // Delete relationships
3778
+ if ( !empty( $remove_ids ) )
3779
+ $this->delete_relationships( $params->id, $remove_ids, $pod, $fields[ $field ] );
3780
+
3781
+ // Save relationships
3782
+ if ( !empty( $value_ids ) )
3783
+ $this->save_relationships( $params->id, $value_ids, $pod, $fields[ $field ] );
3784
+
3785
+ $field_save_values = $value_ids;
3786
+
3787
+ if ( 'file' === $type ) {
3788
+ $field_save_values = $values;
3789
+ }
3790
+
3791
+ // Run save function for field type (where needed)
3792
+ PodsForm::save( $type, $field_save_values, $params->id, $field, array_merge( $fields[ $field ], $fields[ $field ][ 'options' ] ), array_merge( $fields, $object_fields ), $pod, $params );
3793
+ }
3794
+
3795
+ // Unset data no longer needed
3796
+ if ( 'pick' == $type ) {
3797
+ foreach ( $data as $field => $values ) {
3798
+ if ( isset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] ) ) {
3799
+ unset( PodsField_Pick::$related_data[ PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ][ 'related_field' ][ 'id' ] ] );
3800
+ unset( PodsField_Pick::$related_data[ $fields[ $field ][ 'id' ] ] );
3801
+ }
3802
+ }
3803
+ }
3804
+ }
3805
+ }
3806
+
3807
+ if ( !$no_conflict )
3808
+ pods_no_conflict_off( $pod[ 'type' ] );
3809
+
3810
+ // Clear cache
3811
+ pods_cache_clear( $params->id, 'pods_items_' . $pod[ 'name' ] );
3812
+
3813
+ if ( $params->clear_slug_cache && !empty( $pod[ 'field_slug' ] ) ) {
3814
+ $slug = pods( $pod[ 'name' ], $params->id )->field( $pod[ 'field_slug' ] );
3815
+
3816
+ if ( 0 < strlen( $slug ) ) {
3817
+ pods_cache_clear( $slug, 'pods_items_' . $pod[ 'name' ] );
3818
+ }
3819
+ }
3820
+
3821
+ // Clear WP meta cache
3822
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
3823
+ $meta_type = $pod[ 'type' ];
3824
+
3825
+ if ( 'post_type' == $meta_type )
3826
+ $meta_type = 'post';
3827
+
3828
+ wp_cache_delete( $params->id, $meta_type . '_meta' );
3829
+ wp_cache_delete( $params->id, 'pods_' . $meta_type . '_meta' );
3830
+ }
3831
+
3832
+ if ( false === $bypass_helpers ) {
3833
+ $pieces = compact( $pieces );
3834
+
3835
+ // Plugin hooks
3836
+ $this->do_hook( 'post_save_pod_item', $pieces, $is_new_item, $params->id );
3837
+ $this->do_hook( "post_save_pod_item_{$params->pod}", $pieces, $is_new_item, $params->id );
3838
+
3839
+ if ( $is_new_item ) {
3840
+ $this->do_hook( 'post_create_pod_item', $pieces, $params->id );
3841
+ $this->do_hook( "post_create_pod_item_{$params->pod}", $pieces, $params->id );
3842
+ }
3843
+ else {
3844
+ $this->do_hook( 'post_edit_pod_item', $pieces, $params->id );
3845
+ $this->do_hook( "post_edit_pod_item_{$params->pod}", $pieces, $params->id );
3846
+ }
3847
+
3848
+ // Call any post-save helpers (if not bypassed)
3849
+ if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
3850
+ if ( !empty( $post_save_helpers ) ) {
3851
+ pods_deprecated( sprintf( __( 'Post-save helpers are deprecated, use the action pods_post_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3852
+
3853
+ foreach ( $post_save_helpers as $helper ) {
3854
+ $helper = $this->load_helper( array( 'name' => $helper ) );
3855
+
3856
+ if ( false !== $helper && ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) )
3857
+ eval( '?>' . $helper[ 'code' ] );
3858
+ }
3859
+ }
3860
+ }
3861
+ }
3862
+
3863
+ // Success! Return the id
3864
+ return $params->id;
3865
+
3866
+ }
3867
+
3868
+ /**
3869
+ * @see PodsAPI::save_pod_item
3870
+ * Add multiple pod items
3871
+ *
3872
+ * $params['pod'] string The Pod name (pod or pod_id is required)
3873
+ * $params['pod_id'] string The Pod ID (pod or pod_id is required)
3874
+ * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
3875
+ *
3876
+ * $data['id'] int The item ID (optional)
3877
+ * $data['data'] array An associative array of field names + values
3878
+ *
3879
+ * @param array|object $params An associative array of parameters, data excluded
3880
+ * @param array $data An associative array of pod ids and field names + values (arrays of field data)
3881
+ *
3882
+ * @return int The item ID
3883
+ * @since 2.0
3884
+ */
3885
+ public function save_pod_items ( $params, $data ) {
3886
+ $params = (object) $params;
3887
+
3888
+ $ids = array();
3889
+
3890
+ foreach ( $data as $fields ) {
3891
+ $params->data = $fields;
3892
+
3893
+ if ( isset( $fields[ 'id' ] ) && isset( $fields[ 'data' ] ) ) {
3894
+ $params->id = $fields[ 'id' ];
3895
+ $params->data = $fields[ 'data' ];
3896
+ }
3897
+
3898
+ $ids[] = $this->save_pod_item( $params );
3899
+ }
3900
+
3901
+ return $ids;
3902
+ }
3903
+
3904
+ /**
3905
+ * Get the fields that have changed during a save
3906
+ *
3907
+ * @param array $pieces Pieces array from save_pod_item
3908
+ *
3909
+ * @return array Array of fields and values that have changed
3910
+ */
3911
+ public function get_changed_fields( $pieces ) {
3912
+
3913
+ $fields = $pieces[ 'fields' ];
3914
+ $fields_active = $pieces[ 'fields_active' ];
3915
+
3916
+ $fields_changed = array();
3917
+
3918
+ if ( 0 < $pieces[ 'params' ]->id ) {
3919
+ $pod = pods( $pieces[ 'params' ]->pod, $pieces[ 'params' ]->id );
3920
+
3921
+ foreach ( $fields_active as $field ) {
3922
+ if ( isset( $fields[ $field ] ) && $pod->raw( $field ) != $fields[ $field ][ 'value' ] ) {
3923
+ $fields_changed[ $field ] = $fields[ $field ][ 'value' ];
3924
+ }
3925
+ }
3926
+ }
3927
+
3928
+ return $fields_changed;
3929
+
3930
+ }
3931
+
3932
+ /**
3933
+ * Save relationships
3934
+ *
3935
+ * @param int $id ID of item
3936
+ * @param int|array $related_id ID or IDs to save
3937
+ * @param array $pod Pod data
3938
+ * @param array $field Field data
3939
+ */
3940
+ public function save_relationships ( $id, $related_ids, $pod, $field ) {
3941
+ // Get current values
3942
+ if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ] ) )
3943
+ $current_ids = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'current_ids' ];
3944
+ else
3945
+ $current_ids = $this->lookup_related_items( $field[ 'id' ], $pod[ 'id' ], $id, $field, $pod );
3946
+
3947
+ if ( isset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] ) ) {
3948
+ // Delete relationship from cache
3949
+ unset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] );
3950
+ }
3951
+
3952
+ if ( !is_array( $related_ids ) )
3953
+ $related_ids = implode( ',', $related_ids );
3954
+
3955
+ foreach ( $related_ids as $k => $related_id ) {
3956
+ $related_ids[ $k ] = (int) $related_id;
3957
+ }
3958
+
3959
+ $related_ids = array_unique( array_filter( $related_ids ) );
3960
+
3961
+ $related_limit = (int) pods_var_raw( $field[ 'type' ] . '_limit', $field[ 'options' ], 0 );
3962
+
3963
+ if ( 'single' == pods_var_raw( $field[ 'type' ] . '_format_type', $field[ 'options' ] ) )
3964
+ $related_limit = 1;
3965
+
3966
+ // Limit values
3967
+ if ( 0 < $related_limit && !empty( $related_ids ) )
3968
+ $related_ids = array_slice( $related_ids, 0, $related_limit );
3969
+
3970
+ // Post Types, Media, Users, and Comments (meta-based)
3971
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
3972
+ $object_type = $pod[ 'type' ];
3973
+
3974
+ if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
3975
+ $object_type = 'post';
3976
+ elseif ( 'taxonomy' == $object_type )
3977
+ $object_type = 'term';
3978
+
3979
+ delete_metadata( $object_type, $id, $field[ 'name' ] );
3980
+
3981
+ if ( !empty( $related_ids ) ) {
3982
+ update_metadata( $object_type, $id, '_pods_' . $field[ 'name' ], $related_ids );
3983
+
3984
+ foreach ( $related_ids as $related_id ) {
3985
+ add_metadata( $object_type, $id, $field[ 'name' ], $related_id );
3986
+ }
3987
+ }
3988
+ else
3989
+ delete_metadata( $object_type, $id, '_pods_' . $field[ 'name' ] );
3990
+ }
3991
+ // Custom Settings Pages (options-based)
3992
+ elseif ( 'settings' == $pod[ 'type' ] ) {
3993
+ if ( !empty( $related_ids ) )
3994
+ update_option( $pod[ 'name' ] . '_' . $field[ 'name' ], $related_ids );
3995
+ else
3996
+ delete_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
3997
+ }
3998
+
3999
+ $related_pod_id = $related_field_id = 0;
4000
+
4001
+ if ( 'pick' == $field[ 'type' ] && isset( PodsField_Pick::$related_data[ $field[ 'id' ] ] ) && !empty( PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ] ) ) {
4002
+ $related_pod_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_pod' ][ 'id' ];
4003
+ $related_field_id = PodsField_Pick::$related_data[ $field[ 'id' ] ][ 'related_field' ][ 'id' ];
4004
+ }
4005
+
4006
+ // Relationships table
4007
+ if ( !pods_tableless() ) {
4008
+ $related_weight = 0;
4009
+
4010
+ foreach ( $related_ids as $related_id ) {
4011
+ if ( in_array( $related_id, $current_ids ) ) {
4012
+ pods_query( "
4013
+ UPDATE `@wp_podsrel`
4014
+ SET
4015
+ `pod_id` = %d,
4016
+ `field_id` = %d,
4017
+ `item_id` = %d,
4018
+ `related_pod_id` = %d,
4019
+ `related_field_id` = %d,
4020
+ `related_item_id` = %d,
4021
+ `weight` = %d
4022
+ WHERE
4023
+ `pod_id` = %d
4024
+ AND `field_id` = %d
4025
+ AND `item_id` = %d
4026
+ AND `related_item_id` = %d
4027
+ ", array(
4028
+ $pod[ 'id' ],
4029
+ $field[ 'id' ],
4030
+ $id,
4031
+ $related_pod_id,
4032
+ $related_field_id,
4033
+ $related_id,
4034
+ $related_weight,
4035
+
4036
+ $pod[ 'id' ],
4037
+ $field[ 'id' ],
4038
+ $id,
4039
+ $related_id,
4040
+ ) );
4041
+ }
4042
+ else {
4043
+ pods_query( "
4044
+ INSERT INTO `@wp_podsrel`
4045
+ (
4046
+ `pod_id`,
4047
+ `field_id`,
4048
+ `item_id`,
4049
+ `related_pod_id`,
4050
+ `related_field_id`,
4051
+ `related_item_id`,
4052
+ `weight`
4053
+ )
4054
+ VALUES ( %d, %d, %d, %d, %d, %d, %d )
4055
+ ", array(
4056
+ $pod[ 'id' ],
4057
+ $field[ 'id' ],
4058
+ $id,
4059
+ $related_pod_id,
4060
+ $related_field_id,
4061
+ $related_id,
4062
+ $related_weight
4063
+ ) );
4064
+ }
4065
+
4066
+ $related_weight++;
4067
+ }
4068
+ }
4069
+ }
4070
+
4071
+ /**
4072
+ * Duplicate a Pod
4073
+ *
4074
+ * $params['id'] int The Pod ID
4075
+ * $params['name'] string The Pod name
4076
+ * $params['new_name'] string The new Pod name
4077
+ *
4078
+ * @param array $params An associative array of parameters
4079
+ * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4080
+ *
4081
+ * @return int New Pod ID
4082
+ * @since 2.3
4083
+ */
4084
+ public function duplicate_pod ( $params, $strict = false ) {
4085
+ if ( !is_object( $params ) && !is_array( $params ) ) {
4086
+ if ( is_numeric( $params ) )
4087
+ $params = array( 'id' => $params );
4088
+ else
4089
+ $params = array( 'name' => $params );
4090
+
4091
+ $params = (object) pods_sanitize( $params );
4092
+ }
4093
+ else
4094
+ $params = (object) pods_sanitize( $params );
4095
+
4096
+ $params->table_info = false;
4097
+
4098
+ $pod = $this->load_pod( $params, $strict );
4099
+
4100
+ if ( empty( $pod ) ) {
4101
+ if ( false !== $strict )
4102
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
4103
+
4104
+ return false;
4105
+ }
4106
+ elseif ( in_array( $pod[ 'type' ], array( 'media', 'user', 'comment' ) ) ) {
4107
+ if ( false !== $strict )
4108
+ return pods_error( __( 'Pod not allowed to be duplicated', 'pods' ), $this );
4109
+
4110
+ return false;
4111
+ }
4112
+ elseif ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && 0 < strlen( $pod[ 'object' ] ) ) {
4113
+ $pod[ 'object' ] = '';
4114
+ }
4115
+
4116
+ unset( $pod[ 'id' ] );
4117
+
4118
+ if ( isset( $params->new_name ) )
4119
+ $pod[ 'name' ] = $params->new_name;
4120
+
4121
+ $try = 1;
4122
+
4123
+ $check_name = $pod[ 'name' ];
4124
+ $new_label = $pod[ 'label' ];
4125
+
4126
+ while ( $this->load_pod( array( 'name' => $check_name, 'table_info' => false ), false ) ) {
4127
+ $try++;
4128
+
4129
+ $check_name = $pod[ 'name' ] . $try;
4130
+ $new_label = $pod[ 'label' ] . $try;
4131
+ }
4132
+
4133
+ $pod[ 'name' ] = $check_name;
4134
+ $pod[ 'label' ] = $new_label;
4135
+
4136
+ foreach ( $pod[ 'fields' ] as $field => $field_data ) {
4137
+ unset( $pod[ 'fields' ][ $field ][ 'id' ] );
4138
+ }
4139
+
4140
+ return $this->save_pod( $pod );
4141
+ }
4142
+
4143
+ /**
4144
+ * Duplicate a Field
4145
+ *
4146
+ * $params['pod_id'] int The Pod ID
4147
+ * $params['pod'] string The Pod name
4148
+ * $params['id'] int The Field ID
4149
+ * $params['name'] string The Field name
4150
+ * $params['new_name'] string The new Field name
4151
+ *
4152
+ * @param array $params An associative array of parameters
4153
+ * @param bool $strict (optional) Makes sure a field exists, if it doesn't throws an error
4154
+ *
4155
+ * @return int New Field ID
4156
+ * @since 2.3.10
4157
+ */
4158
+ public function duplicate_field( $params, $strict = false ) {
4159
+
4160
+ if ( !is_object( $params ) && !is_array( $params ) ) {
4161
+ if ( is_numeric( $params ) ) {
4162
+ $params = array( 'id' => $params );
4163
+ }
4164
+ else {
4165
+ $params = array( 'name' => $params );
4166
+ }
4167
+ }
4168
+
4169
+ $params = (object) pods_sanitize( $params );
4170
+
4171
+ $params->table_info = false;
4172
+
4173
+ $field = $this->load_field( $params, $strict );
4174
+
4175
+ if ( empty( $field ) ) {
4176
+ if ( false !== $strict ) {
4177
+ return pods_error( __( 'Field not found', 'pods' ), $this );
4178
+ }
4179
+
4180
+ return false;
4181
+ }
4182
+
4183
+ unset( $field[ 'id' ] );
4184
+
4185
+ if ( isset( $params->new_name ) ) {
4186
+ $field[ 'name' ] = $params->new_name;
4187
+ }
4188
+
4189
+ $try = 1;
4190
+
4191
+ $check_name = $field[ 'name' ];
4192
+ $new_label = $field[ 'label' ];
4193
+
4194
+ while ( $this->load_field( array( 'pod_id' => $field[ 'pod_id' ], 'name' => $check_name, 'table_info' => false ), false ) ) {
4195
+ $try++;
4196
+
4197
+ $check_name = $field[ 'name' ] . $try;
4198
+ $new_label = $field[ 'label' ] . $try;
4199
+ }
4200
+
4201
+ $field[ 'name' ] = $check_name;
4202
+ $field[ 'label' ] = $new_label;
4203
+
4204
+ return $this->save_field( $field );
4205
+
4206
+ }
4207
+
4208
+ /**
4209
+ * @see PodsAPI::save_pod_item
4210
+ *
4211
+ * Duplicate a pod item
4212
+ *
4213
+ * $params['pod'] string The Pod name
4214
+ * $params['id'] int The item's ID from the wp_pods_* table
4215
+ *
4216
+ * @param array $params An associative array of parameters
4217
+ *
4218
+ * @return int The table row ID
4219
+ *
4220
+ * @since 1.12
4221
+ */
4222
+ public function duplicate_pod_item ( $params ) {
4223
+
4224
+ $params = (object) pods_sanitize( $params );
4225
+
4226
+ $load_pod_params = array(
4227
+ 'name' => $params->pod,
4228
+ 'table_info' => false,
4229
+ );
4230
+
4231
+ $pod = $this->load_pod( $load_pod_params );
4232
+
4233
+ if ( false === $pod ) {
4234
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
4235
+ }
4236
+
4237
+ $pod = pods( $params->pod, $params->id );
4238
+
4239
+ $params->pod = $pod->pod;
4240
+ $params->pod_id = $pod->pod_id;
4241
+
4242
+ $fields = (array) pods_var_raw( 'fields', $pod->pod_data, array(), null, true );
4243
+ $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4244
+
4245
+ if ( ! empty( $object_fields ) ) {
4246
+ $fields = array_merge( $object_fields, $fields );
4247
+ }
4248
+
4249
+ $save_params = array(
4250
+ 'pod' => $params->pod,
4251
+ 'data' => array()
4252
+ );
4253
+
4254
+ $ignore_fields = array(
4255
+ $pod->pod_data['field_id'],
4256
+ $pod->pod_data['field_slug'],
4257
+ );
4258
+
4259
+ if ( in_array( $pod->pod_data['type'], array( 'post_type', 'media' ) ) ) {
4260
+ $ignore_fields = array(
4261
+ 'ID',
4262
+ 'post_name',
4263
+ 'post_date',
4264
+ 'post_date_gmt',
4265
+ 'post_modified',
4266
+ 'post_modified_gmt',
4267
+ 'guid',
4268
+ );
4269
+ } elseif ( 'term' == $pod->pod_data['type'] ) {
4270
+ $ignore_fields = array(
4271
+ 'term_id',
4272
+ 'term_taxonomy_id',
4273
+ 'slug',
4274
+ );
4275
+ } elseif ( 'user' == $pod->pod_data['type'] ) {
4276
+ $ignore_fields = array(
4277
+ 'ID',
4278
+ 'user_nicename',
4279
+ );
4280
+ } elseif ( 'comment' == $pod->pod_data['type'] ) {
4281
+ $ignore_fields = array(
4282
+ 'comment_ID',
4283
+ );
4284
+ } elseif ( 'settings' == $pod->pod_data['type'] ) {
4285
+ return pods_error( __( 'Settings do not support duplication.', 'pods' ), $this );
4286
+ }
4287
+
4288
+ /**
4289
+ * Filter the fields to ignore during duplication
4290
+ *
4291
+ * @since 2.6.6
4292
+ *
4293
+ * @param array $ignore_fields Fields to ignore and not save during duplication
4294
+ * @param Pods $pod Pod object
4295
+ * @param array $fields Fields on the pod to duplicate
4296
+ * @param object $params Params passed into duplicate_pod_item()
4297
+ */
4298
+ $ignore_fields = apply_filters( 'pods_api_duplicate_pod_item_ignore_fields', $ignore_fields, $pod, $fields, $params );
4299
+
4300
+ foreach ( $fields as $field ) {
4301
+ if ( in_array( $field['name'], $ignore_fields ) ) {
4302
+ continue;
4303
+ }
4304
+
4305
+ $field = array(
4306
+ 'name' => $field['name'],
4307
+ 'output' => 'ids'
4308
+ );
4309
+
4310
+ $value = $pod->field( $field );
4311
+
4312
+ // @todo Add post type compatibility to set unique post_title
4313
+ // @todo Add term compatibility to set unique name
4314
+ // @todo Add user compatibility to set unique user_login/user_email
4315
+
4316
+ if ( ! empty( $value ) || ( ! is_array( $value ) && 0 < strlen( $value ) ) ) {
4317
+ $save_params['data'][ $field['name'] ] = $value;
4318
+ }
4319
+ }
4320
+
4321
+ $save_params = $this->do_hook( 'duplicate_pod_item', $save_params, $pod->pod, $pod->id(), $params );
4322
+
4323
+ $id = $this->save_pod_item( $save_params );
4324
+
4325
+ return $id;
4326
+
4327
+ }
4328
+
4329
+ /**
4330
+ * @see pods()
4331
+ *
4332
+ * Export a pod item
4333
+ *
4334
+ * $params['pod'] string The Pod name
4335
+ * $params['id'] int The item's ID from the wp_pods_* table
4336
+ * $params['fields'] array The fields to export
4337
+ * $params['depth'] int How many levels deep to export data
4338
+ *
4339
+ * @param array $params An associative array of parameters
4340
+ * @param object $pod (optional) Pods object
4341
+ *
4342
+ * @return int The table row ID
4343
+ * @since 1.12
4344
+ */
4345
+ public function export_pod_item ( $params, $pod = null ) {
4346
+ if ( !is_object( $pod ) || 'Pods' != get_class( $pod ) ) {
4347
+ if ( empty( $params ) )
4348
+ return false;
4349
+
4350
+ $params = (object) pods_sanitize( $params );
4351
+
4352
+ $pod = pods( $params->pod, $params->id, false );
4353
+
4354
+ if ( empty( $pod ) )
4355
+ return false;
4356
+ }
4357
+
4358
+ $fields = (array) pods_var_raw( 'fields', $params, array(), null, true );
4359
+ $depth = (int) pods_var_raw( 'depth', $params, 2, null, true );
4360
+ $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4361
+ $flatten = (boolean) pods_var( 'flatten', $params, false, null, true );
4362
+
4363
+ if ( empty( $fields ) ) {
4364
+ $fields = $pod->fields;
4365
+ $fields = array_merge( $fields, $object_fields );
4366
+ }
4367
+
4368
+ $data = $this->export_pod_item_level( $pod, $fields, $depth, $flatten );
4369
+
4370
+ $data = $this->do_hook( 'export_pod_item', $data, $pod->pod, $pod->id(), $pod, $fields, $depth, $flatten );
4371
+
4372
+ return $data;
4373
+ }
4374
+
4375
+ /**
4376
+ * Export a pod item by depth level
4377
+ *
4378
+ * @param Pods $pod Pods object
4379
+ * @param array $fields Fields to export
4380
+ * @param int $depth Depth limit
4381
+ * @param boolean $flatten Whether to flatten arrays for display
4382
+ * @param int $current_depth Current depth level
4383
+ *
4384
+ * @return array Data array
4385
+ *
4386
+ * @since 2.3
4387
+ */
4388
+ private function export_pod_item_level ( $pod, $fields, $depth, $flatten = false, $current_depth = 1 ) {
4389
+ $tableless_field_types = PodsForm::tableless_field_types();
4390
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
4391
+
4392
+ $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4393
+
4394
+ $export_fields = array();
4395
+
4396
+ foreach ( $fields as $k => $field ) {
4397
+ if ( !is_array( $field ) ) {
4398
+ $field = array(
4399
+ 'id' => 0,
4400
+ 'name' => $field
4401
+ );
4402
+ }
4403
+
4404
+ if ( isset( $pod->fields[ $field[ 'name' ] ] ) ) {
4405
+ $field = $pod->fields[ $field[ 'name' ] ];
4406
+ $field[ 'lookup_name' ] = $field[ 'name' ];
4407
+
4408
+ if ( in_array( $field[ 'type' ], $tableless_field_types ) && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4409
+ if ( 'pick' == $field[ 'type' ] ) {
4410
+ if ( empty( $field[ 'table_info' ] ) )
4411
+ $field[ 'table_info' ] = $this->get_table_info( pods_var_raw( 'pick_object', $field ), pods_var_raw( 'pick_val', $field ), null, null, $field );
4412
+
4413
+ if ( !empty( $field[ 'table_info' ] ) )
4414
+ $field[ 'lookup_name' ] .= '.' . $field[ 'table_info' ][ 'field_id' ];
4415
+ }
4416
+ elseif ( in_array( $field[ 'type' ], PodsForm::file_field_types() ) )
4417
+ $field[ 'lookup_name' ] .= '.guid';
4418
+ }
4419
+
4420
+ $export_fields[ $field[ 'name' ] ] = $field;
4421
+ }
4422
+ elseif ( isset( $object_fields[ $field[ 'name' ] ] ) ) {
4423
+ $field = $object_fields[ $field[ 'name' ] ];
4424
+ $field[ 'lookup_name' ] = $field[ 'name' ];
4425
+
4426
+ $export_fields[ $field[ 'name' ] ] = $field;
4427
+ }
4428
+ elseif ( $field[ 'name' ] == $pod->pod_data[ 'field_id' ] ) {
4429
+ $field[ 'type' ] = 'number';
4430
+ $field[ 'lookup_name' ] = $field[ 'name' ];
4431
+
4432
+ $export_fields[ $field[ 'name' ] ] = $field;
4433
+ }
4434
+ }
4435
+
4436
+ $data = array();
4437
+
4438
+ foreach ( $export_fields as $field ) {
4439
+ // Return IDs (or guid for files) if only one level deep
4440
+ if ( 1 == $depth )
4441
+ $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'lookup_name' ], 'output' => 'arrays' ) );
4442
+ // Recurse depth levels for pick fields if $depth allows
4443
+ elseif ( ( -1 == $depth || $current_depth < $depth ) && 'pick' == $field[ 'type' ] && !in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
4444
+ $related_data = array();
4445
+
4446
+ $related_ids = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'ids' ) );
4447
+
4448
+ if ( !empty( $related_ids ) ) {
4449
+ $related_ids = (array) $related_ids;
4450
+
4451
+ $pick_object = pods_var_raw( 'pick_object', $field );
4452
+
4453
+ $related_pod = pods( pods_var_raw( 'pick_val', $field ), null, false );
4454
+
4455
+ // If this isn't a Pod, return data exactly as Pods does normally
4456
+ if ( empty( $related_pod ) || ( 'pod' != $pick_object && $pick_object != $related_pod->pod_data[ 'type' ] ) || $related_pod->pod == $pod->pod )
4457
+ $related_data = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4458
+ else {
4459
+ $related_object_fields = (array) pods_var_raw( 'object_fields', $related_pod->pod_data, array(), null, true );
4460
+
4461
+ $related_fields = array_merge( $related_pod->fields, $related_object_fields );
4462
+
4463
+ foreach ( $related_ids as $related_id ) {
4464
+ if ( $related_pod->fetch( $related_id ) ) {
4465
+ $related_item = $this->export_pod_item_level( $related_pod, $related_fields, $depth, $flatten, ( $current_depth + 1 ) );
4466
+
4467
+ $related_data[ $related_id ] = $this->do_hook( 'export_pod_item_level', $related_item, $related_pod->pod, $related_pod->id(), $related_pod, $related_fields, $depth, $flatten, ( $current_depth + 1 ) );
4468
+ }
4469
+ }
4470
+
4471
+ if ( $flatten && !empty( $related_data ) )
4472
+ $related_data = pods_serial_comma( array_values( $related_data ), array( 'and' => '', 'field_index' => $related_pod->pod_data[ 'field_index' ] ) );
4473
+ }
4474
+ }
4475
+
4476
+ $data[ $field[ 'name' ] ] = $related_data;
4477
+ }
4478
+ // Return data exactly as Pods does normally
4479
+ else
4480
+ $data[ $field[ 'name' ] ] = $pod->field( array( 'name' => $field[ 'name' ], 'output' => 'arrays' ) );
4481
+
4482
+ if ( $flatten && is_array( $data[ $field[ 'name' ] ] ) )
4483
+ $data[ $field[ 'name' ] ] = pods_serial_comma( $data[ $field[ 'name' ] ], array( 'field' => $field[ 'name' ], 'fields' => $export_fields, 'and' => '' ) );
4484
+ }
4485
+
4486
+ $data[ 'id' ] = (int) $pod->id();
4487
+ return $data;
4488
+ }
4489
+
4490
+ /**
4491
+ * Reorder a Pod
4492
+ *
4493
+ * $params['pod'] string The Pod name
4494
+ * $params['field'] string The field name of the field to reorder
4495
+ * $params['order'] array The key => value array of items to reorder (key should be an integer)
4496
+ *
4497
+ * @param array $params An associative array of parameters
4498
+ *
4499
+ * @return bool
4500
+ *
4501
+ * @since 1.9.0
4502
+ */
4503
+ public function reorder_pod_item ( $params ) {
4504
+ $params = (object) pods_sanitize( $params );
4505
+
4506
+ // @deprecated 2.0
4507
+ if ( isset( $params->datatype ) ) {
4508
+ pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
4509
+
4510
+ $params->pod = $params->datatype;
4511
+
4512
+ unset( $params->datatype );
4513
+ }
4514
+
4515
+ if ( null === pods_var_raw( 'pod', $params, null, null, true ) )
4516
+ return pods_error( __( '$params->pod is required', 'pods' ), $this );
4517
+
4518
+ if ( !is_array( $params->order ) )
4519
+ $params->order = explode( ',', $params->order );
4520
+
4521
+ $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
4522
+
4523
+ $params->name = $pod[ 'name' ];
4524
+
4525
+ if ( false === $pod )
4526
+ return pods_error( __( 'Pod is required', 'pods' ), $this );
4527
+
4528
+ foreach ( $params->order as $order => $id ) {
4529
+ if ( isset( $pod[ 'fields' ][ $params->field ] ) || isset( $pod[ 'object_fields' ][ $params->field ] ) ) {
4530
+ if ( 'table' == $pod[ 'storage' ] && ( !pods_tableless() ) ) {
4531
+ if ( isset( $pod[ 'fields' ][ $params->field ] ) )
4532
+ pods_query( "UPDATE `@wp_pods_{$params->name}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `id` = " . pods_absint( $id ) . " LIMIT 1" );
4533
+ else
4534
+ pods_query( "UPDATE `{$pod['table']}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `{$pod['field_id']}` = " . pods_absint( $id ) . " LIMIT 1" );
4535
+ }
4536
+ else
4537
+ $this->save_pod_item( array( 'pod' => $params->pod, 'pod_id' => $params->pod_id, 'id' => $id, 'data' => array( $params->field => pods_absint( $order ) ) ) );
4538
+ }
4539
+ }
4540
+
4541
+ return true;
4542
+ }
4543
+
4544
+ /**
4545
+ *
4546
+ * Delete all content for a Pod
4547
+ *
4548
+ * $params['id'] int The Pod ID
4549
+ * $params['name'] string The Pod name
4550
+ *
4551
+ * @param array $params An associative array of parameters
4552
+ * @param array $pod Pod data
4553
+ *
4554
+ * @return bool
4555
+ *
4556
+ * @uses pods_query
4557
+ * @uses pods_cache_clear
4558
+ *
4559
+ * @since 1.9.0
4560
+ */
4561
+ public function reset_pod ( $params, $pod = false ) {
4562
+ $params = (object) pods_sanitize( $params );
4563
+
4564
+ $params->table_info = true;
4565
+
4566
+ if ( empty( $pod ) )
4567
+ $pod = $this->load_pod( $params );
4568
+
4569
+ if ( false === $pod )
4570
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
4571
+
4572
+ $params->id = $pod[ 'id' ];
4573
+ $params->name = $pod[ 'name' ];
4574
+
4575
+ if ( !pods_tableless() ) {
4576
+ if ( 'table' == $pod[ 'storage' ] ) {
4577
+ try {
4578
+ pods_query( "TRUNCATE `@wp_pods_{$params->name}`", false );
4579
+ }
4580
+ catch ( Exception $e ) {
4581
+ // Allow pod to be reset if the table doesn't exist
4582
+ if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4583
+ return pods_error( $e->getMessage(), $this );
4584
+ }
4585
+ }
4586
+
4587
+ pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4588
+ }
4589
+
4590
+ // @todo Delete relationships from tableless relationships
4591
+
4592
+ // Delete all posts/revisions from this post type
4593
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'media' ) ) ) {
4594
+ $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4595
+
4596
+ $sql = "
4597
+ DELETE `t`, `r`, `m`
4598
+ FROM `{$pod['table']}` AS `t`
4599
+ LEFT JOIN `{$pod['meta_table']}` AS `m`
4600
+ ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4601
+ LEFT JOIN `{$pod['table']}` AS `r`
4602
+ ON `r`.`post_parent` = `t`.`{$pod['field_id']}` AND `r`.`post_status` = 'inherit'
4603
+ WHERE `t`.`{$pod['field_type']}` = '{$type}'
4604
+ ";
4605
+
4606
+ pods_query( $sql, false );
4607
+ }
4608
+ // Delete all terms from this taxonomy
4609
+ elseif ( 'taxonomy' == $pod[ 'type' ] ) {
4610
+ if ( function_exists( 'get_term_meta' ) ) {
4611
+ $sql = "
4612
+ DELETE `t`, `m`, `tt`, `tr`
4613
+ FROM `{$pod['table']}` AS `t`
4614
+ LEFT JOIN `{$pod['meta_table']}` AS `m`
4615
+ ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4616
+ " . $pod['join']['tt'] . "
4617
+ " . $pod['join']['tr'] . "
4618
+ WHERE " . implode( ' AND ', $pod['where'] ) . "
4619
+ ";
4620
+ } else {
4621
+ $sql = "
4622
+ DELETE `t`, `tt`, `tr`
4623
+ FROM `{$pod['table']}` AS `t`
4624
+ " . $pod['join']['tt'] . "
4625
+ " . $pod['join']['tr'] . "
4626
+ WHERE " . implode( ' AND ', $pod['where'] ) . "
4627
+ ";
4628
+ }
4629
+
4630
+ pods_query( $sql, false );
4631
+ }
4632
+ // Delete all users except the current one
4633
+ elseif ( 'user' == $pod[ 'type' ] ) {
4634
+ $sql = "
4635
+ DELETE `t`, `m`
4636
+ FROM `{$pod['table']}` AS `t`
4637
+ LEFT JOIN `{$pod['meta_table']}` AS `m`
4638
+ ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4639
+ WHERE `t`.`{$pod['field_id']}` != " . (int) get_current_user_id() . "
4640
+ ";
4641
+
4642
+ pods_query( $sql, false );
4643
+ }
4644
+ // Delete all comments
4645
+ elseif ( 'comment' == $pod[ 'type' ] ) {
4646
+ $type = pods_var( 'object', $pod, $pod[ 'name' ], null, true );
4647
+
4648
+ $sql = "
4649
+ DELETE `t`, `m`
4650
+ FROM `{$pod['table']}` AS `t`
4651
+ LEFT JOIN `{$pod['meta_table']}` AS `m`
4652
+ ON `m`.`{$pod['meta_field_id']}` = `t`.`{$pod['field_id']}`
4653
+ WHERE `t`.`{$pod['field_type']}` = '{$type}'
4654
+ ";
4655
+
4656
+ pods_query( $sql, false );
4657
+ }
4658
+
4659
+ pods_cache_clear( true ); // only way to reliably clear out cached data across an entire group
4660
+
4661
+ return true;
4662
+ }
4663
+
4664
+ /**
4665
+ * Delete a Pod and all its content
4666
+ *
4667
+ * $params['id'] int The Pod ID
4668
+ * $params['name'] string The Pod name
4669
+ *
4670
+ * @param array $params An associative array of parameters
4671
+ * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4672
+ * @param bool $delete_all (optional) Whether to delete all content from a WP object
4673
+ *
4674
+ * @uses PodsAPI::load_pod
4675
+ * @uses wp_delete_post
4676
+ * @uses pods_query
4677
+ *
4678
+ * @return bool
4679
+ * @since 1.7.9
4680
+ */
4681
+ public function delete_pod ( $params, $strict = false, $delete_all = false ) {
4682
+ /**
4683
+ * @var $wpdb wpdb
4684
+ */
4685
+ global $wpdb;
4686
+
4687
+ if ( !is_object( $params ) && !is_array( $params ) ) {
4688
+ if ( is_numeric( $params ) )
4689
+ $params = array( 'id' => $params );
4690
+ else
4691
+ $params = array( 'name' => $params );
4692
+
4693
+ $params = (object) pods_sanitize( $params );
4694
+ }
4695
+ else
4696
+ $params = (object) pods_sanitize( $params );
4697
+
4698
+ $params->table_info = false;
4699
+
4700
+ $pod = $this->load_pod( $params, $strict );
4701
+
4702
+ if ( empty( $pod ) ) {
4703
+ if ( false !== $strict )
4704
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
4705
+
4706
+ return false;
4707
+ }
4708
+
4709
+ $params->id = (int) $pod[ 'id' ];
4710
+ $params->name = $pod[ 'name' ];
4711
+
4712
+ foreach ( $pod[ 'fields' ] as $field ) {
4713
+ $field[ 'pod' ] = $pod;
4714
+
4715
+ $this->delete_field( $field, false );
4716
+ }
4717
+
4718
+ // Only delete the post once the fields are taken care of, it's not required anymore
4719
+ $success = wp_delete_post( $params->id );
4720
+
4721
+ if ( !$success )
4722
+ return pods_error( __( 'Pod unable to be deleted', 'pods' ), $this );
4723
+
4724
+ // Reset content
4725
+ if ( $delete_all )
4726
+ $this->reset_pod( $params, $pod );
4727
+
4728
+ if ( !pods_tableless() ) {
4729
+ if ( 'table' == $pod[ 'storage' ] ) {
4730
+ try {
4731
+ pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`", false );
4732
+ }
4733
+ catch ( Exception $e ) {
4734
+ // Allow pod to be deleted if the table doesn't exist
4735
+ if ( false === strpos( $e->getMessage(), 'Unknown table' ) )
4736
+ return pods_error( $e->getMessage(), $this );
4737
+ }
4738
+ }
4739
+
4740
+ pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
4741
+ }
4742
+
4743
+ // @todo Delete relationships from tableless relationships
4744
+
4745
+ // Delete any relationship references
4746
+ $sql = "
4747
+ DELETE `pm`
4748
+ FROM `{$wpdb->postmeta}` AS `pm`
4749
+ LEFT JOIN `{$wpdb->posts}` AS `p`
4750
+ ON `p`.`post_type` = '_pods_field'
4751
+ AND `p`.`ID` = `pm`.`post_id`
4752
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm2`
4753
+ ON `pm2`.`meta_key` = 'pick_object'
4754
+ AND `pm2`.`meta_value` = 'pod'
4755
+ AND `pm2`.`post_id` = `pm`.`post_id`
4756
+ WHERE
4757
+ `p`.`ID` IS NOT NULL
4758
+ AND `pm2`.`meta_id` IS NOT NULL
4759
+ AND `pm`.`meta_key` = 'pick_val'
4760
+ AND `pm`.`meta_value` = '{$params->name}'
4761
+ ";
4762
+
4763
+ pods_query( $sql );
4764
+
4765
+ $this->cache_flush_pods( $pod );
4766
+
4767
+ return true;
4768
+ }
4769
+
4770
+ /**
4771
+ * Drop a field within a Pod
4772
+ *
4773
+ * $params['id'] int The field ID
4774
+ * $params['name'] int The field name
4775
+ * $params['pod'] string The Pod name
4776
+ * $params['pod_id'] string The Pod name
4777
+ *
4778
+ * @param array $params An associative array of parameters
4779
+ * @param bool $table_operation Whether or not to handle table operations
4780
+ *
4781
+ * @uses PodsAPI::load_field
4782
+ * @uses wp_delete_post
4783
+ * @uses pods_query
4784
+ *
4785
+ * @return bool
4786
+ * @since 1.7.9
4787
+ */
4788
+ public function delete_field ( $params, $table_operation = true ) {
4789
+ /**
4790
+ * @var $wpdb wpdb
4791
+ */
4792
+ global $wpdb;
4793
+
4794
+ $tableless_field_types = PodsForm::tableless_field_types();
4795
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
4796
+
4797
+ $params = (object) pods_sanitize( $params );
4798
+
4799
+ if ( !isset( $params->pod ) )
4800
+ $params->pod = '';
4801
+
4802
+ if ( !isset( $params->pod_id ) )
4803
+ $params->pod_id = 0;
4804
+
4805
+ $pod = $params->pod;
4806
+
4807
+ $save_pod = false;
4808
+
4809
+ if ( !is_array( $pod ) )
4810
+ $pod = $this->load_pod( array( 'name' => $pod, 'id' => $params->pod_id, 'table_info' => false ) );
4811
+ else
4812
+ $save_pod = true;
4813
+
4814
+ if ( empty( $pod ) )
4815
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
4816
+
4817
+ $params->pod_id = $pod[ 'id' ];
4818
+ $params->pod = $pod[ 'name' ];
4819
+
4820
+ if ( !isset( $params->name ) )
4821
+ $params->name = '';
4822
+
4823
+ if ( !isset( $params->id ) )
4824
+ $params->id = 0;
4825
+
4826
+ $field = $this->load_field( array( 'name' => $params->name, 'id' => $params->id, 'pod' => $params->pod, 'pod_id' => $params->pod_id ) );
4827
+
4828
+ if ( false === $field )
4829
+ return pods_error( __( 'Field not found', 'pods' ), $this );
4830
+
4831
+ $params->id = $field[ 'id' ];
4832
+ $params->name = $field[ 'name' ];
4833
+
4834
+ $simple = ( 'pick' == $field[ 'type' ] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
4835
+ $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field, $pod, $params );
4836
+
4837
+ if ( $table_operation && 'table' == $pod[ 'storage' ] && ( !in_array( $field[ 'type' ], $tableless_field_types ) || $simple ) )
4838
+ pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$params->name}`", false );
4839
+
4840
+ $success = wp_delete_post( $params->id );
4841
+
4842
+ if ( !$success )
4843
+ return pods_error( __( 'Field unable to be deleted', 'pods' ), $this );
4844
+
4845
+ $wpdb->query( $wpdb->prepare( "DELETE pm FROM {$wpdb->postmeta} AS pm
4846
+ LEFT JOIN {$wpdb->posts} AS p
4847
+ ON p.post_type = '_pods_field' AND p.ID = pm.post_id
4848
+ WHERE p.ID IS NOT NULL AND pm.meta_key = 'sister_id' AND pm.meta_value = %d", $params->id ) );
4849
+
4850
+ if ( ( !pods_tableless() ) && $table_operation ) {
4851
+ pods_query( "DELETE FROM `@wp_podsrel` WHERE (`pod_id` = {$params->pod_id} AND `field_id` = {$params->id}) OR (`related_pod_id` = {$params->pod_id} AND `related_field_id` = {$params->id})", false );
4852
+ }
4853
+
4854
+ // @todo Delete tableless relationship meta
4855
+
4856
+ if ( true === $save_pod )
4857
+ $this->cache_flush_pods( $pod );
4858
+
4859
+ return true;
4860
+ }
4861
+
4862
+ /**
4863
+ * Drop a Pod Object
4864
+ *
4865
+ * $params['id'] int The object ID
4866
+ * $params['name'] string The object name
4867
+ * $params['type'] string The object type
4868
+ *
4869
+ * @param array|object $params An associative array of parameters
4870
+ *
4871
+ * @uses wp_delete_post
4872
+ *
4873
+ * @return bool
4874
+ * @since 2.0
4875
+ */
4876
+ public function delete_object ( $params ) {
4877
+ $params = (object) $params;
4878
+ $object = $this->load_object( $params );
4879
+
4880
+ if ( empty( $object ) )
4881
+ return pods_error( sprintf( __( "%s Object not found", 'pods' ), ucwords( $params->type ) ), $this );
4882
+
4883
+ $success = wp_delete_post( $params->id );
4884
+
4885
+ if ( !$success )
4886
+ return pods_error( sprintf( __( "%s Object not deleted", 'pods' ), ucwords( $params->type ) ), $this );
4887
+
4888
+ pods_transient_clear( 'pods_objects_' . $params->type );
4889
+
4890
+ return true;
4891
+ }
4892
+
4893
+ /**
4894
+ * @see PodsAPI::delete_object
4895
+ *
4896
+ * Drop a Pod Template
4897
+ *
4898
+ * $params['id'] int The template ID
4899
+ * $params['name'] string The template name
4900
+ *
4901
+ * @param array $params An associative array of parameters
4902
+ *
4903
+ * @return bool
4904
+ * @since 1.7.9
4905
+ */
4906
+ public function delete_template ( $params ) {
4907
+ $params = (object) $params;
4908
+ $params->type = 'template';
4909
+ return $this->delete_object( $params );
4910
+ }
4911
+
4912
+ /**
4913
+ * @see PodsAPI::delete_object
4914
+ *
4915
+ * Drop a Pod Page
4916
+ *
4917
+ * $params['id'] int The page ID
4918
+ * $params['uri'] string The page URI
4919
+ *
4920
+ * @param array $params An associative array of parameters
4921
+ *
4922
+ * @return bool
4923
+ * @since 1.7.9
4924
+ */
4925
+ public function delete_page ( $params ) {
4926
+ $params = (object) $params;
4927
+ if ( isset( $params->uri ) ) {
4928
+ $params->name = $params->uri;
4929
+ unset( $params->uri );
4930
+ }
4931
+ if ( isset( $params->name ) )
4932
+ $params->name = trim( $params->name, '/' );
4933
+ $params->type = 'page';
4934
+ return $this->delete_object( $params );
4935
+ }
4936
+
4937
+ /**
4938
+ * @see PodsAPI::delete_object
4939
+ *
4940
+ * Drop a Pod Helper
4941
+ *
4942
+ * $params['id'] int The helper ID
4943
+ * $params['name'] string The helper name
4944
+ *
4945
+ * @param array $params An associative array of parameters
4946
+ *
4947
+ * @return bool
4948
+ * @since 1.7.9
4949
+ */
4950
+ public function delete_helper ( $params ) {
4951
+ $params = (object) $params;
4952
+ $params->type = 'helper';
4953
+ return $this->delete_object( $params );
4954
+ }
4955
+
4956
+ /**
4957
+ * Drop a single pod item
4958
+ *
4959
+ * $params['id'] int (optional) The item's ID from the wp_pod_* table (used with datatype parameter)
4960
+ * $params['pod'] string (optional) The Pod name (used with id parameter)
4961
+ * $params['pod_id'] int (optional) The Pod ID (used with id parameter)
4962
+ * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
4963
+ *
4964
+ * @param array $params An associative array of parameters
4965
+ * @param bool $wp Whether to run WP object delete action
4966
+ *
4967
+ * @return bool
4968
+ * @since 1.7.9
4969
+ */
4970
+ public function delete_pod_item ( $params, $wp = true ) {
4971
+ $params = (object) pods_sanitize( $params );
4972
+
4973
+ // @deprecated 2.0
4974
+ if ( isset( $params->datatype_id ) || isset( $params->datatype ) || isset( $params->tbl_row_id ) ) {
4975
+ if ( isset( $params->tbl_row_id ) ) {
4976
+ pods_deprecated( __( '$params->id instead of $params->tbl_row_id', 'pods' ), '2.0' );
4977
+ $params->id = $params->tbl_row_id;
4978
+ unset( $params->tbl_row_id );
4979
+ }
4980
+
4981
+ if ( isset( $params->pod_id ) ) {
4982
+ pods_deprecated( __( '$params->id instead of $params->pod_id', 'pods' ), '2.0' );
4983
+ $params->id = $params->pod_id;
4984
+ unset( $params->pod_id );
4985
+ }
4986
+
4987
+ if ( isset( $params->dataype_id ) ) {
4988
+ pods_deprecated( __( '$params->pod_id instead of $params->datatype_id', 'pods' ), '2.0' );
4989
+ $params->pod_id = $params->dataype_id;
4990
+ unset( $params->dataype_id );
4991
+ }
4992
+
4993
+ if ( isset( $params->datatype ) ) {
4994
+ pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
4995
+ $params->pod = $params->datatype;
4996
+ unset( $params->datatype );
4997
+ }
4998
+ }
4999
+
5000
+ if ( !isset( $params->id ) )
5001
+ return pods_error( __( 'Pod Item not found', 'pods' ), $this );
5002
+
5003
+ $params->id = pods_absint( $params->id );
5004
+
5005
+ if ( !isset( $params->pod ) )
5006
+ $params->pod = '';
5007
+
5008
+ if ( !isset( $params->pod_id ) )
5009
+ $params->pod_id = 0;
5010
+
5011
+ $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false ) );
5012
+
5013
+ if ( false === $pod )
5014
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
5015
+
5016
+ $params->pod_id = $pod[ 'id' ];
5017
+ $params->pod = $pod[ 'name' ];
5018
+
5019
+ // Allow Helpers to bypass subsequent helpers in recursive delete_pod_item calls
5020
+ $bypass_helpers = false;
5021
+
5022
+ if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers )
5023
+ $bypass_helpers = true;
5024
+
5025
+ $pre_delete_helpers = $post_delete_helpers = array();
5026
+
5027
+ if ( false === $bypass_helpers ) {
5028
+ // Plugin hook
5029
+ $this->do_hook( 'pre_delete_pod_item', $params, $pod );
5030
+ $this->do_hook( "pre_delete_pod_item_{$params->pod}", $params, $pod );
5031
+
5032
+ // Call any pre-save helpers (if not bypassed)
5033
+ if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
5034
+ if ( !empty( $pod[ 'options' ] ) && is_array( $pod[ 'options' ] ) ) {
5035
+ $helpers = array( 'pre_delete_helpers', 'post_delete_helpers' );
5036
+
5037
+ foreach ( $helpers as $helper ) {
5038
+ if ( isset( $pod[ 'options' ][ $helper ] ) && !empty( $pod[ 'options' ][ $helper ] ) )
5039
+ ${$helper} = explode( ',', $pod[ 'options' ][ $helper ] );
5040
+ }
5041
+ }
5042
+
5043
+ if ( !empty( $pre_delete_helpers ) ) {
5044
+ pods_deprecated( sprintf( __( 'Pre-delete helpers are deprecated, use the action pods_pre_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
5045
+
5046
+ foreach ( $pre_delete_helpers as $helper ) {
5047
+ $helper = $this->load_helper( array( 'name' => $helper ) );
5048
+
5049
+ if ( false !== $helper )
5050
+ eval( '?>' . $helper[ 'code' ] );
5051
+ }
5052
+ }
5053
+ }
5054
+ }
5055
+
5056
+ // Delete object from relationship fields
5057
+ $this->delete_object_from_relationships( $params->id, $pod );
5058
+
5059
+ if ( 'table' == $pod[ 'storage' ] )
5060
+ pods_query( "DELETE FROM `@wp_pods_{$params->pod}` WHERE `id` = {$params->id} LIMIT 1" );
5061
+
5062
+ if ( $wp ) {
5063
+ if ( 'taxonomy' == $pod['type'] ) {
5064
+ $taxonomy = $pod['name'];
5065
+
5066
+ if ( ! empty( $pod['object'] ) ) {
5067
+ $taxonomy = $pod['object'];
5068
+ }
5069
+
5070
+ wp_delete_term( $params->id, $taxonomy );
5071
+ } elseif ( ! in_array( $pod['type'], array( 'pod', 'table', '', 'taxonomy' ) ) ) {
5072
+ $this->delete_wp_object( $pod['type'], $params->id );
5073
+ }
5074
+ }
5075
+
5076
+ if ( false === $bypass_helpers ) {
5077
+ // Plugin hook
5078
+ $this->do_hook( 'post_delete_pod_item', $params, $pod );
5079
+ $this->do_hook( "post_delete_pod_item_{$params->pod}", $params, $pod );
5080
+
5081
+ // Call any post-save helpers (if not bypassed)
5082
+ if ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) {
5083
+ if ( !empty( $post_delete_helpers ) ) {
5084
+ pods_deprecated( sprintf( __( 'Post-delete helpers are deprecated, use the action pods_post_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
5085
+
5086
+ foreach ( $post_delete_helpers as $helper ) {
5087
+ $helper = $this->load_helper( array( 'name' => $helper ) );
5088
+
5089
+ if ( false !== $helper )
5090
+ eval( '?>' . $helper[ 'code' ] );
5091
+ }
5092
+ }
5093
+ }
5094
+ }
5095
+
5096
+ pods_cache_clear( $params->id, 'pods_items_' . $params->pod );
5097
+
5098
+ return true;
5099
+ }
5100
+
5101
+ /**
5102
+ * Delete an object from tableless fields
5103
+ *
5104
+ * @param int $id
5105
+ * @param string $type
5106
+ * @param string $name
5107
+ *
5108
+ * @return bool
5109
+ *
5110
+ * @since 2.3
5111
+ */
5112
+ public function delete_object_from_relationships ( $id, $object, $name = null ) {
5113
+ /**
5114
+ * @var $pods_init \PodsInit
5115
+ */
5116
+ global $pods_init;
5117
+
5118
+ $pod = false;
5119
+
5120
+ // Run any bidirectional delete operations
5121
+ if ( is_array( $object ) )
5122
+ $pod = $object;
5123
+ elseif ( is_object( $pods_init ) )
5124
+ $pod = PodsInit::$meta->get_object( $object, $name );
5125
+
5126
+ if ( !empty( $pod ) ) {
5127
+ $object = $pod[ 'type' ];
5128
+ $name = $pod[ 'name' ];
5129
+
5130
+ foreach ( $pod[ 'fields' ] as $field ) {
5131
+ PodsForm::delete( $field[ 'type' ], $id, $field[ 'name' ], array_merge( $field, $field[ 'options' ] ), $pod );
5132
+ }
5133
+ }
5134
+
5135
+ // Lookup related fields (non-bidirectional)
5136
+ $params = array(
5137
+ 'where' => array(
5138
+ array(
5139
+ 'key' => 'type',
5140
+ 'value' => 'pick'
5141
+ ),
5142
+ array(
5143
+ 'key' => 'pick_object',
5144
+ 'value' => $object
5145
+ )
5146
+ )
5147
+ );
5148
+
5149
+ if ( !empty( $name ) && $name != $object ) {
5150
+ $params[ 'where' ][] = array(
5151
+ 'key' => 'pick_val',
5152
+ 'value' => $name
5153
+ );
5154
+ }
5155
+
5156
+ $fields = $this->load_fields( $params, false );
5157
+
5158
+ if ( !empty( $pod ) && 'media' == $pod[ 'type' ] ) {
5159
+ $params[ 'where' ] = array(
5160
+ array(
5161
+ 'key' => 'type',
5162
+ 'value' => 'file'
5163
+ )
5164
+ );
5165
+
5166
+ $fields = array_merge( $fields, $this->load_fields( $params, false ) );
5167
+ }
5168
+
5169
+ if ( is_array( $fields ) && !empty( $fields ) ) {
5170
+ foreach ( $fields as $related_field ) {
5171
+ $related_pod = $this->load_pod( array( 'id' => $related_field[ 'pod_id' ], 'fields' => false ), false );
5172
+
5173
+ if ( empty( $related_pod ) )
5174
+ continue;
5175
+
5176
+ $related_from = $this->lookup_related_items_from( $related_field[ 'id' ], $related_pod[ 'id' ], $id, $related_field, $related_pod );
5177
+
5178
+ $this->delete_relationships( $related_from, $id, $related_pod, $related_field );
5179
+ }
5180
+ }
5181
+
5182
+ if ( !empty( $pod ) && !pods_tableless() ) {
5183
+ pods_query( "
5184
+ DELETE FROM `@wp_podsrel`
5185
+ WHERE
5186
+ (
5187
+ `pod_id` = %d
5188
+ AND `item_id` = %d
5189
+ )
5190
+ OR (
5191
+ `related_pod_id` = %d
5192
+ AND `related_item_id` = %d
5193
+ )
5194
+ ", array(
5195
+ $pod[ 'id' ],
5196
+ $id,
5197
+
5198
+ $pod[ 'id' ],
5199
+ $id
5200
+ ) );
5201
+ }
5202
+
5203
+ return true;
5204
+ }
5205
+
5206
+ /**
5207
+ * Delete relationships
5208
+ *
5209
+ * @param int|array $related_id IDs for items to save
5210
+ * @param int|array $id ID or IDs to remove
5211
+ * @param array $related_pod Pod data
5212
+ * @param array $related_field Field data
5213
+ *
5214
+ * @return void
5215
+ *
5216
+ * @since 2.3
5217
+ */
5218
+ public function delete_relationships ( $related_id, $id, $related_pod, $related_field ) {
5219
+ if ( is_array( $related_id ) ) {
5220
+ foreach ( $related_id as $rid ) {
5221
+ $this->delete_relationships( $rid, $id, $related_pod, $related_field );
5222
+ }
5223
+
5224
+ return;
5225
+ }
5226
+
5227
+ if ( is_array( $id ) ) {
5228
+ foreach ( $id as $rid ) {
5229
+ $this->delete_relationships( $related_id, $rid, $related_pod, $related_field );
5230
+ }
5231
+
5232
+ return;
5233
+ }
5234
+
5235
+ $id = (int) $id;
5236
+
5237
+ if ( empty( $id ) )
5238
+ return;
5239
+
5240
+ $related_ids = $this->lookup_related_items( $related_field[ 'id' ], $related_pod[ 'id' ], $related_id, $related_field, $related_pod );
5241
+
5242
+ if ( empty( $related_ids ) )
5243
+ return;
5244
+ elseif ( !in_array( $id, $related_ids ) )
5245
+ return;
5246
+
5247
+ if ( isset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] ) ) {
5248
+ // Delete relationship from cache
5249
+ unset( self::$related_item_cache[ $related_pod[ 'id' ] ][ $related_field[ 'id' ] ] );
5250
+ }
5251
+ unset( $related_ids[ array_search( $id, $related_ids ) ] );
5252
+
5253
+ $no_conflict = pods_no_conflict_check( $related_pod[ 'type' ] );
5254
+
5255
+ if ( !$no_conflict )
5256
+ pods_no_conflict_on( $related_pod[ 'type' ] );
5257
+
5258
+ // Post Types, Media, Users, and Comments (meta-based)
5259
+ if ( in_array( $related_pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
5260
+ $object_type = $related_pod[ 'type' ];
5261
+
5262
+ if ( in_array( $object_type, array( 'post_type', 'media' ) ) )
5263
+ $object_type = 'post';
5264
+ elseif ( 'taxonomy' == $object_type )
5265
+ $object_type = 'term';
5266
+
5267
+ delete_metadata( $object_type, $related_id, $related_field[ 'name' ] );
5268
+
5269
+ if ( !empty( $related_ids ) ) {
5270
+ update_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ], $related_ids );
5271
+
5272
+ foreach ( $related_ids as $rel_id ) {
5273
+ add_metadata( $object_type, $related_id, $related_field[ 'name' ], $rel_id );
5274
+ }
5275
+ }
5276
+ else
5277
+ delete_metadata( $object_type, $related_id, '_pods_' . $related_field[ 'name' ] );
5278
+ }
5279
+ // Custom Settings Pages (options-based)
5280
+ elseif ( 'settings' == $related_pod[ 'type' ] ) {
5281
+ if ( !empty( $related_ids ) )
5282
+ update_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ], $related_ids );
5283
+ else
5284
+ delete_option( $related_pod[ 'name' ] . '_' . $related_field[ 'name' ] );
5285
+ }
5286
+
5287
+ // Relationships table
5288
+ if ( !pods_tableless() ) {
5289
+ pods_query( "
5290
+ DELETE FROM `@wp_podsrel`
5291
+ WHERE
5292
+ (
5293
+ `pod_id` = %d
5294
+ AND `field_id` = %d
5295
+ AND `item_id` = %d
5296
+ AND `related_item_id` = %d
5297
+ )
5298
+ OR (
5299
+ `related_pod_id` = %d
5300
+ AND `related_field_id` = %d
5301
+ AND `related_item_id` = %d
5302
+ AND `item_id` = %d
5303
+ )
5304
+ ", array(
5305
+ $related_pod[ 'id' ],
5306
+ $related_field[ 'id' ],
5307
+ $related_id,
5308
+ $id,
5309
+
5310
+ $related_pod[ 'id' ],
5311
+ $related_field[ 'id' ],
5312
+ $related_id,
5313
+ $id
5314
+ ) );
5315
+ }
5316
+
5317
+ if ( !$no_conflict )
5318
+ pods_no_conflict_off( $related_pod[ 'type' ] );
5319
+ }
5320
+
5321
+ /**
5322
+ * Check if a Pod exists
5323
+ *
5324
+ * $params['id'] int Pod ID
5325
+ * $params['name'] string Pod name
5326
+ *
5327
+ * @param array $params An associative array of parameters
5328
+ *
5329
+ * @return bool True if exists
5330
+ *
5331
+ * @since 1.12
5332
+ */
5333
+ public function pod_exists ( $params, $type = null ) {
5334
+ if ( is_string( $params ) )
5335
+ $params = array( 'name' => $params );
5336
+
5337
+ $params = (object) pods_sanitize( $params );
5338
+
5339
+ if ( !empty( $params->id ) || !empty( $params->name ) ) {
5340
+ if ( !isset( $params->name ) )
5341
+ $pod = get_post( $dummy = (int) $params->id );
5342
+ else {
5343
+ $pod = get_posts( array(
5344
+ 'name' => $params->name,
5345
+ 'post_type' => '_pods_pod',
5346
+ 'posts_per_page' => 1
5347
+ ) );
5348
+ }
5349
+
5350
+ if ( !empty( $pod ) && ( empty( $type ) || $type == get_post_meta( $pod->ID, 'type', true ) ) )
5351
+ return true;
5352
+ }
5353
+
5354
+ return false;
5355
+ }
5356
+
5357
+ /**
5358
+ * Get number of pods for a specific pod type
5359
+ *
5360
+ * @param string $type Type to get count
5361
+ *
5362
+ * @return int Total number of pods for a type
5363
+ *
5364
+ * @since 2.6.6
5365
+ */
5366
+ public function get_pod_type_count( $type ) {
5367
+
5368
+ $args = array(
5369
+ 'post_type' => '_pods_pod',
5370
+ 'posts_per_page' => - 1,
5371
+ 'nopaging' => true,
5372
+ 'fields' => 'ids',
5373
+ 'meta_query' => array(
5374
+ array(
5375
+ 'key' => 'type',
5376
+ 'value' => $type,
5377
+ ),
5378
+ ),
5379
+ );
5380
+
5381
+ $posts = get_posts( $args );
5382
+
5383
+ $total = count( $posts );
5384
+
5385
+ return $total;
5386
+
5387
+ }
5388
+
5389
+ /**
5390
+ * Load a Pod and all of its fields
5391
+ *
5392
+ * $params['id'] int The Pod ID
5393
+ * $params['name'] string The Pod name
5394
+ * $params['fields'] bool Whether to load fields (default is true)
5395
+ * $params['bypass_cache'] boolean Bypass the cache when getting data
5396
+ *
5397
+ * @param array|object $params An associative array of parameters or pod name as a string
5398
+ * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work
5399
+ *
5400
+ * @return array|bool|mixed|void
5401
+ * @since 1.7.9
5402
+ */
5403
+ public function load_pod ( $params, $strict = true ) {
5404
+
5405
+ /**
5406
+ * @var $sitepress SitePress
5407
+ * @var $wpdb wpdb
5408
+ */
5409
+ global $wpdb;
5410
+
5411
+ $current_language = false;
5412
+ $load_fields = true;
5413
+ $bypass_cache = false;
5414
+
5415
+ // Get current language data
5416
+ $lang_data = self::get_current_language();
5417
+
5418
+ if ( $lang_data ) {
5419
+ if ( ! empty( $lang_data['language'] ) ) {
5420
+ $current_language = $lang_data['language'];
5421
+ }
5422
+ }
5423
+
5424
+ if ( !is_array( $params ) && !is_object( $params ) )
5425
+ $params = array( 'name' => $params, 'table_info' => false, 'fields' => true );
5426
+
5427
+ if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && isset( $params->fields ) && !$params->fields )
5428
+ $load_fields = false;
5429
+ elseif ( is_array( $params ) && isset( $params[ 'fields' ] ) && !$params[ 'fields' ] )
5430
+ $load_fields = false;
5431
+
5432
+ $table_info = false;
5433
+
5434
+ if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->table_info ) )
5435
+ $table_info = true;
5436
+ elseif ( is_array( $params ) && ! empty( $params[ 'table_info' ] ) )
5437
+ $table_info = true;
5438
+
5439
+ $transient = 'pods_' . $wpdb->prefix . '_pod';
5440
+
5441
+ if ( !empty( $current_language ) )
5442
+ $transient .= '_' . $current_language;
5443
+
5444
+ if ( !$load_fields )
5445
+ $transient .= '_nofields';
5446
+
5447
+ if ( $table_info )
5448
+ $transient .= '_tableinfo';
5449
+
5450
+ $check_pod = $params;
5451
+
5452
+ if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->pod ) ) {
5453
+ $check_pod = $params->pod;
5454
+ } elseif ( is_array( $params ) && ! empty( $params['pod'] ) ) {
5455
+ $check_pod = $params['pod'];
5456
+ }
5457
+
5458
+ if ( is_object( $check_pod ) && ( is_a( $check_pod, 'WP_Post' ) || isset( $check_pod->post_name ) ) ) {
5459
+ $pod = false;
5460
+
5461
+ if ( pods_api_cache() )
5462
+ $pod = pods_transient_get( $transient . '_' . $check_pod->post_name );
5463
+
5464
+ if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5465
+ // @todo Is this needed anymore for WPML?
5466
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) )
5467
+ && did_action( 'wpml_loaded' )
5468
+ && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
5469
+ $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) );
5470
+ }
5471
+
5472
+ return $pod;
5473
+ }
5474
+
5475
+ $_pod = get_object_vars( $check_pod );
5476
+ }
5477
+ else {
5478
+ $params = (object) pods_sanitize( $params );
5479
+
5480
+ if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) ) {
5481
+ if ( $strict ) {
5482
+ return pods_error( 'Either Pod ID or Name are required', $this );
5483
+ }
5484
+
5485
+ return false;
5486
+ }
5487
+
5488
+ if ( ! empty( $params->bypass_cache ) ) {
5489
+ $bypass_cache = true;
5490
+ }
5491
+
5492
+ if ( isset( $params->name ) ) {
5493
+ $pod = false;
5494
+
5495
+ if ( '_pods_pod' == $params->name ) {
5496
+ $pod = array(
5497
+ 'id' => 0,
5498
+ 'name' => $params->name,
5499
+ 'label' => __( 'Pods', 'pods' ),
5500
+ 'type' => 'post_type',
5501
+ 'storage' => 'meta',
5502
+ 'options' => array(
5503
+ 'label_singular' => __( 'Pod', 'pods' )
5504
+ ),
5505
+ 'fields' => array()
5506
+ );
5507
+ }
5508
+ elseif ( '_pods_field' == $params->name ) {
5509
+ $pod = array(
5510
+ 'id' => 0,
5511
+ 'name' => $params->name,
5512
+ 'label' => __( 'Pod Fields', 'pods' ),
5513
+ 'type' => 'post_type',
5514
+ 'storage' => 'meta',
5515
+ 'options' => array(
5516
+ 'label_singular' => __( 'Pod Field', 'pods' )
5517
+ ),
5518
+ 'fields' => array()
5519
+ );
5520
+ }
5521
+ elseif ( ! $bypass_cache & pods_api_cache() )
5522
+ $pod = pods_transient_get( $transient . '_' . $params->name );
5523
+
5524
+ if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5525
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) && did_action( 'wpml_loaded' )
5526
+ && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) )
5527
+ $pod = array_merge( $pod, $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ) );
5528
+
5529
+ return $pod;
5530
+ }
5531
+ }
5532
+
5533
+ if ( !isset( $params->name ) )
5534
+ $pod = get_post( $dummy = (int) $params->id );
5535
+ else {
5536
+ $pod = get_posts( array(
5537
+ 'name' => $params->name,
5538
+ 'post_type' => '_pods_pod',
5539
+ 'posts_per_page' => 1
5540
+ ) );
5541
+ }
5542
+
5543
+ if ( empty( $pod ) ) {
5544
+ if ( $strict )
5545
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
5546
+
5547
+ return false;
5548
+ }
5549
+
5550
+ if ( is_array( $pod ) )
5551
+ $pod = $pod[ 0 ];
5552
+
5553
+ $_pod = get_object_vars( $pod );
5554
+ }
5555
+
5556
+ $pod = false;
5557
+
5558
+ if ( ! $bypass_cache || pods_api_cache() )
5559
+ $pod = pods_transient_get( $transient . '_' . $_pod[ 'post_name' ] );
5560
+
5561
+ if ( false !== $pod && ( ! $table_info || isset( $pod[ 'table' ] ) ) ) {
5562
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) )
5563
+ && did_action( 'wpml_loaded' )
5564
+ && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
5565
+ $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) );
5566
+ }
5567
+
5568
+ return $pod;
5569
+ }
5570
+
5571
+ $pod = array(
5572
+ 'id' => $_pod[ 'ID' ],
5573
+ 'name' => $_pod[ 'post_name' ],
5574
+ 'label' => $_pod[ 'post_title' ],
5575
+ 'description' => $_pod[ 'post_content' ]
5576
+ );
5577
+
5578
+ if ( strlen( $pod[ 'label' ] ) < 1 )
5579
+ $pod[ 'label' ] = $pod[ 'name' ];
5580
+
5581
+ // @todo update with a method to put all options in
5582
+ $defaults = array(
5583
+ 'show_in_menu' => 1,
5584
+ 'type' => 'post_type',
5585
+ 'storage' => 'meta',
5586
+ 'object' => '',
5587
+ 'alias' => ''
5588
+ );
5589
+
5590
+ if ( $bypass_cache ) {
5591
+ wp_cache_delete( $pod['id'], 'post_meta' );
5592
+
5593
+ update_postmeta_cache( array( $pod['id'] ) );
5594
+ }
5595
+
5596
+ $pod[ 'options' ] = get_post_meta( $pod[ 'id' ] );
5597
+
5598
+ foreach ( $pod[ 'options' ] as $option => $value ) {
5599
+ if ( is_array( $value ) ) {
5600
+ foreach ( $value as $k => $v ) {
5601
+ if ( !is_array( $v ) )
5602
+ $value[ $k ] = maybe_unserialize( $v );
5603
+ }
5604
+
5605
+ if ( 1 == count( $value ) )
5606
+ $value = current( $value );
5607
+ }
5608
+ else
5609
+ $value = maybe_unserialize( $value );
5610
+
5611
+ $pod[ 'options' ][ $option ] = $value;
5612
+ }
5613
+
5614
+ $pod[ 'options' ] = array_merge( $defaults, $pod[ 'options' ] );
5615
+
5616
+ $pod[ 'type' ] = $pod[ 'options' ][ 'type' ];
5617
+ $pod[ 'storage' ] = $pod[ 'options' ][ 'storage' ];
5618
+ $pod[ 'object' ] = $pod[ 'options' ][ 'object' ];
5619
+ $pod[ 'alias' ] = $pod[ 'options' ][ 'alias' ];
5620
+
5621
+ unset( $pod[ 'options' ][ 'type' ] );
5622
+ unset( $pod[ 'options' ][ 'storage' ] );
5623
+ unset( $pod[ 'options' ][ 'object' ] );
5624
+ unset( $pod[ 'options' ][ 'alias' ] );
5625
+
5626
+ if ( $table_info )
5627
+ $pod = array_merge( $this->get_table_info( $pod[ 'type' ], $pod[ 'object' ], $pod[ 'name' ], $pod ), $pod );
5628
+
5629
+ // Override old 'none' storage type
5630
+ if ( 'taxonomy' == $pod['type'] && 'none' == $pod['storage'] && function_exists( 'get_term_meta' ) ) {
5631
+ $pod[ 'storage' ] = 'meta';
5632
+ }
5633
+
5634
+ if ( isset( $pod[ 'pod' ] ) )
5635
+ unset( $pod[ 'pod' ] );
5636
+
5637
+ $pod[ 'fields' ] = array();
5638
+
5639
+ $pod[ 'object_fields' ] = array();
5640
+
5641
+ if ( 'pod' != $pod[ 'type' ] )
5642
+ $pod[ 'object_fields' ] = $this->get_wp_object_fields( $pod[ 'type' ], $pod );
5643
+
5644
+ $fields = get_posts( array(
5645
+ 'post_type' => '_pods_field',
5646
+ 'posts_per_page' => -1,
5647
+ 'nopaging' => true,
5648
+ 'post_parent' => $pod[ 'id' ],
5649
+ 'orderby' => 'menu_order',
5650
+ 'order' => 'ASC'
5651
+ ) );
5652
+
5653
+ if ( !empty( $fields ) ) {
5654
+ foreach ( $fields as $field ) {
5655
+ $field->pod = $pod[ 'name' ];
5656
+ $field->table_info = $table_info;
5657
+ $field->bypass_cache = $bypass_cache;
5658
+
5659
+ if ( $load_fields ) {
5660
+ $field = $this->load_field( $field );
5661
+
5662
+ $field = PodsForm::field_setup( $field, null, $field[ 'type' ] );
5663
+ }
5664
+ else {
5665
+ if ( $bypass_cache ) {
5666
+ wp_cache_delete( $field->ID, 'post_meta' );
5667
+
5668
+ update_postmeta_cache( array( $field->ID ) );
5669
+ }
5670
+
5671
+ $field = array(
5672
+ 'id' => $field->ID,
5673
+ 'name' => $field->post_name,
5674
+ 'label' => $field->post_title,
5675
+ 'type' => get_post_meta( $field->ID, 'type', true )
5676
+ );
5677
+ }
5678
+
5679
+ $pod[ 'fields' ][ $field[ 'name' ] ] = $field;
5680
+ }
5681
+ }
5682
+
5683
+ if ( did_action( 'init' ) && pods_api_cache() )
5684
+ pods_transient_set( $transient . '_' . $pod[ 'name' ], $pod );
5685
+
5686
+ return $pod;
5687
+ }
5688
+
5689
+ /**
5690
+ * Load a list of Pods based on filters specified.
5691
+ *
5692
+ * $params['type'] string/array Pod Type(s) to filter by
5693
+ * $params['object'] string/array Pod Object(s) to filter by
5694
+ * $params['options'] array Pod Option(s) key=>value array to filter by
5695
+ * $params['orderby'] string ORDER BY clause of query
5696
+ * $params['limit'] string Number of Pods to return
5697
+ * $params['where'] string WHERE clause of query
5698
+ * $params['ids'] string|array IDs of Objects
5699
+ * $params['count'] boolean Return only a count of Pods
5700
+ * $params['names'] boolean Return only an array of name => label
5701
+ * $params['ids'] boolean Return only an array of ID => label
5702
+ * $params['fields'] boolean Return pod fields with Pods (default is true)
5703
+ * $params['key_names'] boolean Return pods keyed by name
5704
+ * $params['bypass_cache'] boolean Bypass the cache when getting data
5705
+ *
5706
+ * @param array $params An associative array of parameters
5707
+ *
5708
+ * @return array|mixed
5709
+ *
5710
+ * @uses PodsAPI::load_pod
5711
+ *
5712
+ * @since 2.0
5713
+ */
5714
+ public function load_pods ( $params = null ) {
5715
+
5716
+ $current_language = false;
5717
+
5718
+ // Get current language data
5719
+ $lang_data = self::get_current_language();
5720
+
5721
+ if ( $lang_data ) {
5722
+ if ( ! empty( $lang_data['language'] ) ) {
5723
+ $current_language = $lang_data['language'];
5724
+ }
5725
+ }
5726
+
5727
+ $params = (object) pods_sanitize( $params );
5728
+
5729
+ $order = 'ASC';
5730
+ $orderby = 'menu_order title';
5731
+ $limit = -1;
5732
+ $ids = false;
5733
+
5734
+ $meta_query = array();
5735
+ $cache_key = '';
5736
+
5737
+ $bypass_cache = false;
5738
+
5739
+ if ( ! empty( $params->bypass_cache ) ) {
5740
+ $bypass_cache = true;
5741
+ }
5742
+
5743
+ if ( isset( $params->type ) && !empty( $params->type ) ) {
5744
+ if ( !is_array( $params->type ) )
5745
+ $params->type = array( trim( $params->type ) );
5746
+
5747
+ sort( $params->type );
5748
+
5749
+ $meta_query[] = array(
5750
+ 'key' => 'type',
5751
+ 'value' => $params->type,
5752
+ 'compare' => 'IN'
5753
+ );
5754
+
5755
+ if ( 0 < count( $params->type ) )
5756
+ $cache_key .= '_type_' . trim( implode( '_', $params->type ) );
5757
+ }
5758
+
5759
+ if ( isset( $params->object ) && !empty( $params->object ) ) {
5760
+ if ( !is_array( $params->object ) )
5761
+ $params->object = array( $params->object );
5762
+
5763
+ $params->object = pods_trim( $params->object );
5764
+
5765
+ sort( $params->object );
5766
+
5767
+ $meta_query[] = array(
5768
+ 'key' => 'object',
5769
+ 'value' => $params->object,
5770
+ 'compare' => 'IN'
5771
+ );
5772
+
5773
+ if ( 1 == count( $params->object ) )
5774
+ $cache_key .= '_object_' . trim( implode( '', $params->object ) );
5775
+ }
5776
+
5777
+ if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
5778
+ foreach ( $params->options as $option => $value ) {
5779
+ if ( !is_array( $value ) )
5780
+ $value = array( $value );
5781
+
5782
+ $value = pods_trim( $value );
5783
+
5784
+ sort( $value );
5785
+
5786
+ $meta_query[] = array(
5787
+ 'key' => $option,
5788
+ 'value' => pods_sanitize( $value ),
5789
+ 'compare' => 'IN'
5790
+ );
5791
+ }
5792
+
5793
+ $cache_key = '';
5794
+ }
5795
+
5796
+ if ( isset( $params->where ) && is_array( $params->where ) )
5797
+ $meta_query = array_merge( $meta_query, (array) $params->where );
5798
+
5799
+ if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
5800
+ $order = strtoupper( $params->order );
5801
+
5802
+ if ( isset( $params->orderby ) && !empty( $params->orderby ) )
5803
+ $orderby = strtoupper( $params->orderby );
5804
+
5805
+ if ( isset( $params->limit ) && !empty( $params->limit ) )
5806
+ $limit = pods_absint( $params->limit );
5807
+
5808
+ if ( isset( $params->ids ) && !empty( $params->ids ) ) {
5809
+ $ids = $params->ids;
5810
+
5811
+ if ( !is_array( $ids ) )
5812
+ $ids = explode( ',', $ids );
5813
+ }
5814
+
5815
+ if ( empty( $ids ) )
5816
+ $ids = false;
5817
+
5818
+ $pre_key = '';
5819
+
5820
+ if ( !empty( $current_language ) )
5821
+ $pre_key .= '_' . $current_language;
5822
+
5823
+ if ( isset( $params->count ) && $params->count )
5824
+ $pre_key .= '_count';
5825
+
5826
+ if ( isset( $params->ids ) && $params->ids && !empty( $ids ) )
5827
+ $pre_key .= '_ids_' . implode( '_', $ids );
5828
+
5829
+ if ( isset( $params->names ) && $params->names )
5830
+ $pre_key .= '_names';
5831
+ elseif ( isset( $params->names_ids ) && $params->names_ids )
5832
+ $pre_key .= '_names_ids';
5833
+
5834
+ if ( isset( $params->key_names ) && $params->key_names )
5835
+ $pre_key .= '_namekeys';
5836
+
5837
+ if ( isset( $params->fields ) && !$params->fields )
5838
+ $pre_key .= '_nofields';
5839
+
5840
+ if ( isset( $params->table_info ) && $params->table_info )
5841
+ $pre_key .= '_tableinfo';
5842
+
5843
+
5844
+ $pre_key .= '_get';
5845
+
5846
+ if ( empty( $cache_key ) )
5847
+ $cache_key = 'pods' . $pre_key . '_all';
5848
+ else
5849
+ $cache_key = 'pods' . $pre_key . $cache_key;
5850
+
5851
+ if ( ! $bypass_cache && pods_api_cache() && !empty( $cache_key ) && ( 'pods' . ( !empty( $current_language ) ? '_' . $current_language : '' ) . '_get_all' != $cache_key || empty( $meta_query ) ) && $limit < 1 && ( empty( $orderby ) || 'menu_order title' == $orderby ) && empty( $ids ) ) {
5852
+ $the_pods = pods_transient_get( $cache_key );
5853
+
5854
+ if ( false === $the_pods )
5855
+ $the_pods = pods_cache_get( $cache_key, 'pods' );
5856
+
5857
+ if ( !is_array( $the_pods ) && 'none' == $the_pods )
5858
+ return array();
5859
+ elseif ( false !== $the_pods )
5860
+ return $the_pods;
5861
+ }
5862
+
5863
+ $the_pods = array();
5864
+
5865
+ $args = array(
5866
+ 'post_type' => '_pods_pod',
5867
+ 'nopaging' => true,
5868
+ 'posts_per_page' => $limit,
5869
+ 'order' => $order,
5870
+ 'orderby' => $orderby,
5871
+ 'meta_query' => $meta_query,
5872
+ );
5873
+
5874
+ // Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
5875
+ if ( false != $ids ) {
5876
+ $args[ 'post__in' ] = $ids;
5877
+ }
5878
+
5879
+ $_pods = get_posts( $args );
5880
+
5881
+ $export_ignore = array(
5882
+ 'object_type',
5883
+ 'object_name',
5884
+ 'table',
5885
+ 'meta_table',
5886
+ 'pod_table',
5887
+ 'field_id',
5888
+ 'field_index',
5889
+ 'field_slug',
5890
+ 'field_type',
5891
+ 'field_parent',
5892
+ 'field_parent_select',
5893
+ 'meta_field_id',
5894
+ 'meta_field_index',
5895
+ 'meta_field_value',
5896
+ 'pod_field_id',
5897
+ 'pod_field_index',
5898
+ 'object_fields',
5899
+ 'join',
5900
+ 'where',
5901
+ 'where_default',
5902
+ 'orderby',
5903
+ 'pod',
5904
+ 'recurse',
5905
+ 'table_info',
5906
+ 'attributes',
5907
+ 'group',
5908
+ 'grouped',
5909
+ 'developer_mode',
5910
+ 'dependency',
5911
+ 'depends-on',
5912
+ 'excludes-on'
5913
+ );
5914
+
5915
+ $total_fields = 0;
5916
+
5917
+ if ( isset( $params->count ) && $params->count )
5918
+ $the_pods = count( $_pods );
5919
+ else {
5920
+ foreach ( $_pods as $pod ) {
5921
+ if ( isset( $params->names ) && $params->names )
5922
+ $the_pods[ $pod->post_name ] = $pod->post_title;
5923
+ elseif ( isset( $params->names_ids ) && $params->names_ids )
5924
+ $the_pods[ $pod->ID ] = $pod->post_name;
5925
+ else {
5926
+ if ( isset( $params->fields ) && !$params->fields )
5927
+ $pod->fields = false;
5928
+
5929
+ $pod = $this->load_pod( array( 'pod' => $pod, 'table_info' => ! empty( $params->table_info ), 'bypass_cache' => $bypass_cache ) );
5930
+
5931
+ // Remove extra data not needed
5932
+ if ( pods_var( 'export', $params, false ) && ( !isset( $params->fields ) || $params->fields ) ) {
5933
+ foreach ( $export_ignore as $ignore ) {
5934
+ if ( isset( $pod[ $ignore ] ) )
5935
+ unset( $pod[ $ignore ] );
5936
+ }
5937
+
5938
+ foreach ( $pod[ 'fields' ] as $field => $field_data ) {
5939
+ if ( isset( $pod[ 'fields' ][ $field ][ 'table_info' ] ) )
5940
+ unset( $pod[ 'fields' ][ $field ][ 'table_info' ] );
5941
+ }
5942
+ }
5943
+
5944
+ $total_fields += count( $pod[ 'fields' ] );
5945
+
5946
+ if ( isset( $params->key_names ) && $params->key_names )
5947
+ $the_pods[ $pod[ 'name' ] ] = $pod;
5948
+ else
5949
+ $the_pods[ $pod[ 'id' ] ] = $pod;
5950
+ }
5951
+ }
5952
+ }
5953
+
5954
+ if ( ( !function_exists( 'pll_current_language' ) || ( isset( $params->refresh ) && $params->refresh ) ) && !empty( $cache_key ) && ( 'pods' != $cache_key || empty( $meta_query ) ) && $limit < 1 && ( empty( $orderby ) || 'menu_order title' == $orderby ) && empty( $ids ) ) {
5955
+ // Too many Pods can cause issues with the DB when caching is not enabled
5956
+ if ( 15 < count( $the_pods ) || 75 < count( $total_fields ) ) {
5957
+ pods_transient_clear( $cache_key );
5958
+
5959
+ if ( pods_api_cache() ) {
5960
+ if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
5961
+ pods_cache_set( $cache_key, 'none', 'pods' );
5962
+ else
5963
+ pods_cache_set( $cache_key, $the_pods, 'pods' );
5964
+ }
5965
+ }
5966
+ else {
5967
+ pods_cache_clear( $cache_key, 'pods' );
5968
+
5969
+ if ( pods_api_cache() ) {
5970
+ if ( empty( $the_pods ) && ( !isset( $params->count ) || !$params->count ) )
5971
+ pods_transient_set( $cache_key, 'none' );
5972
+ else
5973
+ pods_transient_set( $cache_key, $the_pods );
5974
+ }
5975
+ }
5976
+ }
5977
+
5978
+ return $the_pods;
5979
+ }
5980
+
5981
+ /**
5982
+ * Check if a Pod's field exists
5983
+ *
5984
+ * $params['pod_id'] int The Pod ID
5985
+ * $params['id'] int The field ID
5986
+ * $params['name'] string The field name
5987
+ *
5988
+ * @param array $params An associative array of parameters
5989
+ *
5990
+ * @return bool
5991
+ *
5992
+ * @since 1.12
5993
+ */
5994
+ public function field_exists ( $params ) {
5995
+ $params = (object) pods_sanitize( $params );
5996
+
5997
+ if ( ( !empty( $params->id ) || !empty( $params->name ) ) && isset( $params->pod_id ) && !empty( $params->pod_id ) ) {
5998
+ if ( !isset( $params->name ) )
5999
+ $field = get_post( $dummy = (int) $params->id );
6000
+ else {
6001
+ $field = get_posts( array(
6002
+ 'name' => $params->name,
6003
+ 'post_type' => '_pods_field',
6004
+ 'posts_per_page' => 1,
6005
+ 'post_parent' => $params->pod_id
6006
+ ) );
6007
+ }
6008
+
6009
+ if ( !empty( $field ) )
6010
+ return true;
6011
+ }
6012
+
6013
+ return false;
6014
+ }
6015
+
6016
+ /**
6017
+ * Load a field
6018
+ *
6019
+ * $params['pod_id'] int The Pod ID
6020
+ * $params['pod'] string The Pod name
6021
+ * $params['id'] int The field ID
6022
+ * $params['name'] string The field name
6023
+ * $params['table_info'] boolean Whether to lookup a pick field's table info
6024
+ * $params['bypass_cache'] boolean Bypass the cache when getting data
6025
+ *
6026
+ * @param array $params An associative array of parameters
6027
+ * @param boolean $strict Whether to require a field exist or not when loading the info
6028
+ *
6029
+ * @return array|bool Array with field data, false if field not found
6030
+ * @since 1.7.9
6031
+ */
6032
+ public function load_field ( $params, $strict = false ) {
6033
+ $params = (object) $params;
6034
+
6035
+ if ( !isset( $params->table_info ) )
6036
+ $params->table_info = false;
6037
+
6038
+ $bypass_cache = false;
6039
+
6040
+ if ( ! empty( $params->bypass_cache ) )
6041
+ $bypass_cache = true;
6042
+
6043
+ $pod = array();
6044
+ $field = array();
6045
+
6046
+ if ( isset( $params->post_title ) )
6047
+ $_field = $params;
6048
+ elseif ( isset( $params->id ) && !empty( $params->id ) )
6049
+ $_field = get_post( $dumb = (int) $params->id );
6050
+ else {
6051
+ if ( !isset( $params->pod ) )
6052
+ $params->pod = '';
6053
+
6054
+ if ( !isset( $params->pod_id ) )
6055
+ $params->pod_id = 0;
6056
+
6057
+ if ( isset( $params->pod_data ) )
6058
+ $pod = $params->pod_data;
6059
+ else {
6060
+ $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false, 'bypass_cache' => $bypass_cache ), false );
6061
+
6062
+ if ( false === $pod ) {
6063
+ if ( $strict )
6064
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
6065
+
6066
+ return false;
6067
+ }
6068
+ }
6069
+
6070
+ $params->pod_id = $pod[ 'id' ];
6071
+ $params->pod = $pod[ 'name' ];
6072
+
6073
+ if ( empty( $params->name ) && empty( $params->pod ) && empty( $params->pod_id ) )
6074
+ return pods_error( __( 'Either Field Name or Field ID / Pod ID are required', 'pods' ), $this );
6075
+
6076
+ $params->name = pods_clean_name( $params->name, true, ( 'meta' == $pod[ 'storage' ] ? false : true ) );
6077
+
6078
+ if ( isset( $pod[ 'fields' ][ $params->name ] ) && isset( $pod[ 'fields' ][ $params->name ][ 'id' ] ) )
6079
+ return $pod[ 'fields' ][ $params->name ];
6080
+
6081
+ $field = false;
6082
+
6083
+ if ( ! $bypass_cache && pods_api_cache() )
6084
+ $field = pods_transient_get( 'pods_field_' . $params->pod . '_' . $params->name );
6085
+
6086
+ if ( empty( $field ) ) {
6087
+ $field = get_posts( array(
6088
+ 'name' => $params->name,
6089
+ 'post_type' => '_pods_field',
6090
+ 'posts_per_page' => 1,
6091
+ 'post_parent' => $params->pod_id
6092
+ ) );
6093
+
6094
+ if ( empty( $field ) ) {
6095
+ if ( $strict )
6096
+ return pods_error( __( 'Field not found', 'pods' ), $this );
6097
+
6098
+ return false;
6099
+ }
6100
+
6101
+ $_field = $field[ 0 ];
6102
+
6103
+ $field = array();
6104
+ }
6105
+ }
6106
+
6107
+ if ( empty( $_field ) ) {
6108
+ if ( $strict )
6109
+ return pods_error( __( 'Field not found', 'pods' ), $this );
6110
+
6111
+ return false;
6112
+ }
6113
+
6114
+ $_field = get_object_vars( $_field );
6115
+
6116
+ if ( !isset( $pod[ 'name' ] ) && !isset( $_field[ 'pod' ] ) ) {
6117
+ if ( 0 < $_field[ 'post_parent' ] )
6118
+ $pod = $this->load_pod( array( 'id' => $_field[ 'post_parent' ], 'table_info' => false ), false );
6119
+
6120
+ if ( empty( $pod ) ) {
6121
+ if ( $strict )
6122
+ return pods_error( __( 'Pod for field not found', 'pods' ), $this );
6123
+
6124
+ return false;
6125
+ }
6126
+ }
6127
+
6128
+ if ( empty( $field ) ) {
6129
+ if ( ! $bypass_cache && pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
6130
+ $field = pods_transient_get( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $_field[ 'post_name' ] );
6131
+
6132
+ if ( empty( $field ) ) {
6133
+ $defaults = array(
6134
+ 'type' => 'text'
6135
+ );
6136
+
6137
+ $field = array(
6138
+ 'id' => $_field[ 'ID' ],
6139
+ 'name' => $_field[ 'post_name' ],
6140
+ 'label' => $_field[ 'post_title' ],
6141
+ 'description' => $_field[ 'post_content' ],
6142
+ 'weight' => $_field[ 'menu_order' ],
6143
+ 'pod_id' => $_field[ 'post_parent' ],
6144
+ 'pick_object' => '',
6145
+ 'pick_val' => '',
6146
+ 'sister_id' => '',
6147
+ 'table_info' => array()
6148
+ );
6149
+
6150
+ if ( isset( $pod[ 'name' ] ) )
6151
+ $field[ 'pod' ] = $pod[ 'name' ];
6152
+ elseif ( isset( $_field[ 'pod' ] ) )
6153
+ $field[ 'pod' ] = $_field[ 'pod' ];
6154
+
6155
+ if ( $bypass_cache ) {
6156
+ wp_cache_delete( $field['id'], 'post_meta' );
6157
+
6158
+ update_postmeta_cache( array( $field['id'] ) );
6159
+ }
6160
+
6161
+ $field[ 'options' ] = get_post_meta( $field[ 'id' ] );
6162
+
6163
+ $options_ignore = array(
6164
+ 'method',
6165
+ 'table_info',
6166
+ 'attributes',
6167
+ 'group',
6168
+ 'grouped',
6169
+ 'developer_mode',
6170
+ 'dependency',
6171
+ 'depends-on',
6172
+ 'excludes-on'
6173
+ );
6174
+
6175
+ foreach ( $options_ignore as $ignore ) {
6176
+ if ( isset( $field[ 'options' ][ $ignore ] ) )
6177
+ unset( $field[ 'options' ][ $ignore ] );
6178
+ }
6179
+
6180
+ foreach ( $field[ 'options' ] as $option => $value ) {
6181
+ if ( is_array( $value ) ) {
6182
+ foreach ( $value as $k => $v ) {
6183
+ if ( !is_array( $v ) )
6184
+ $value[ $k ] = maybe_unserialize( $v );
6185
+ }
6186
+
6187
+ if ( 1 == count( $value ) )
6188
+ $value = current( $value );
6189
+ }
6190
+ else
6191
+ $value = maybe_unserialize( $value );
6192
+
6193
+ $field[ 'options' ][ $option ] = $value;
6194
+ }
6195
+
6196
+ $field[ 'options' ] = array_merge( $defaults, $field[ 'options' ] );
6197
+
6198
+ $field[ 'type' ] = $field[ 'options' ][ 'type' ];
6199
+
6200
+ unset( $field[ 'options' ][ 'type' ] );
6201
+
6202
+ if ( isset( $field[ 'options' ][ 'pick_object' ] ) ) {
6203
+ $field[ 'pick_object' ] = $field[ 'options' ][ 'pick_object' ];
6204
+
6205
+ unset( $field[ 'options' ][ 'pick_object' ] );
6206
+ }
6207
+
6208
+ if ( isset( $field[ 'options' ][ 'pick_val' ] ) ) {
6209
+ $field[ 'pick_val' ] = $field[ 'options' ][ 'pick_val' ];
6210
+
6211
+ unset( $field[ 'options' ][ 'pick_val' ] );
6212
+ }
6213
+
6214
+ if ( isset( $field[ 'options' ][ 'sister_id' ] ) ) {
6215
+ $field[ 'sister_id' ] = $field[ 'options' ][ 'sister_id' ];
6216
+
6217
+ unset( $field[ 'options' ][ 'sister_id' ] );
6218
+ }
6219
+
6220
+ if ( isset( $field[ 'options' ][ 'sister_field_id' ] ) )
6221
+ unset( $field[ 'options' ][ 'sister_field_id' ] );
6222
+
6223
+ if ( pods_api_cache() && ( isset( $pod[ 'name' ] ) || isset( $_field[ 'pod' ] ) ) )
6224
+ pods_transient_set( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $field[ 'name' ], $field );
6225
+ }
6226
+ }
6227
+
6228
+ $field[ 'table_info' ] = array();
6229
+
6230
+ if ( 'pick' == $field[ 'type' ] && $params->table_info )
6231
+ $field[ 'table_info' ] = $this->get_table_info( $field[ 'pick_object' ], $field[ 'pick_val' ], null, null, $field );
6232
+
6233
+ return $field;
6234
+ }
6235
+
6236
+ /**
6237
+ * Load fields by Pod, ID, Name, and/or Type
6238
+ *
6239
+ * $params['pod_id'] int The Pod ID
6240
+ * $params['pod'] string The Pod name
6241
+ * $params['id'] array The field IDs
6242
+ * $params['name'] array The field names
6243
+ * $params['type'] array The field types
6244
+ * $params['options'] array Field Option(s) key=>value array to filter by
6245
+ * $params['where'] string WHERE clause of query
6246
+ *
6247
+ * @param array $params An associative array of parameters
6248
+ * @param bool $strict Whether to require a field exist or not when loading the info
6249
+ *
6250
+ * @return array Array of field data.
6251
+ *
6252
+ * @since 1.7.9
6253
+ */
6254
+ public function load_fields ( $params, $strict = false ) {
6255
+ // @todo Get away from using md5/serialize, I'm sure we can cache specific parts
6256
+ $cache_key = md5( serialize( $params ) );
6257
+ if ( isset( $this->fields_cache[ $cache_key ] ) ) {
6258
+ return $this->fields_cache[ $cache_key ];
6259
+ }
6260
+
6261
+ $params = (object) pods_sanitize( $params );
6262
+
6263
+ if ( !isset( $params->pod ) || empty( $params->pod ) )
6264
+ $params->pod = '';
6265
+
6266
+ if ( !isset( $params->pod_id ) || empty( $params->pod_id ) )
6267
+ $params->pod_id = 0;
6268
+
6269
+ if ( !isset( $params->name ) || empty( $params->name ) )
6270
+ $params->name = array();
6271
+ else
6272
+ $params->name = (array) $params->name;
6273
+
6274
+ if ( !isset( $params->id ) || empty( $params->id ) )
6275
+ $params->id = array();
6276
+ else {
6277
+ $params->id = (array) $params->id;
6278
+
6279
+ foreach ( $params->id as &$id ) {
6280
+ $id = pods_absint( $id );
6281
+ }
6282
+ }
6283
+
6284
+ if ( !isset( $params->type ) || empty( $params->type ) )
6285
+ $params->type = array();
6286
+ else
6287
+ $params->type = (array) $params->type;
6288
+
6289
+ $fields = array();
6290
+
6291
+ if ( !empty( $params->pod ) || !empty( $params->pod_id ) ) {
6292
+ $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => true ), false );
6293
+
6294
+ if ( false === $pod ) {
6295
+ if ( $strict )
6296
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
6297
+
6298
+ return $fields;
6299
+ }
6300
+
6301
+ $pod[ 'fields' ] = array_merge( pods_var_raw( 'object_fields', $pod, array() ), $pod[ 'fields' ] );
6302
+
6303
+ foreach ( $pod[ 'fields' ] as $field ) {
6304
+ if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6305
+ $fields[ $field[ 'name' ] ] = $field;
6306
+ elseif ( in_array( $fields[ 'name' ], $params->name ) || in_array( $fields[ 'id' ], $params->id ) || in_array( $fields[ 'type' ], $params->type ) )
6307
+ $fields[ $field[ 'name' ] ] = $field;
6308
+ }
6309
+ }
6310
+ elseif ( ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) || ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) ) ) {
6311
+ $order = 'ASC';
6312
+ $orderby = 'menu_order title';
6313
+ $limit = -1;
6314
+ $ids = false;
6315
+
6316
+ $meta_query = array();
6317
+
6318
+ if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6319
+ foreach ( $params->options as $option => $value ) {
6320
+ if ( !is_array( $value ) )
6321
+ $value = array( $value );
6322
+
6323
+ $value = pods_trim( $value );
6324
+
6325
+ sort( $value );
6326
+
6327
+ $meta_query[] = array(
6328
+ 'key' => $option,
6329
+ 'value' => pods_sanitize( $value ),
6330
+ 'compare' => 'IN'
6331
+ );
6332
+ }
6333
+ }
6334
+
6335
+ if ( isset( $params->where ) && !empty( $params->where ) && is_array( $params->where ) )
6336
+ $meta_query = array_merge( $meta_query, (array) $params->where );
6337
+
6338
+ $args = array(
6339
+ 'post_type' => '_pods_field',
6340
+ 'nopaging' => true,
6341
+ 'posts_per_page' => $limit,
6342
+ 'order' => $order,
6343
+ 'orderby' => $orderby,
6344
+ 'meta_query' => $meta_query,
6345
+ );
6346
+
6347
+ // Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6348
+ if ( false != $ids ) {
6349
+ $args[ 'post__in' ] = $ids;
6350
+ }
6351
+
6352
+ $fields = array();
6353
+
6354
+ $_fields = get_posts( $args );
6355
+
6356
+ foreach ( $_fields as $field ) {
6357
+ $field = $this->load_field( $field, false );
6358
+
6359
+ if ( !empty( $field ) )
6360
+ $fields[ $field[ 'id' ] ] = $field;
6361
+ }
6362
+ }
6363
+ else {
6364
+ if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) )
6365
+ return pods_error( __( 'Either Field Name / Field ID / Field Type, or Pod Name / Pod ID are required', 'pods' ), $this );
6366
+
6367
+ $lookup = array();
6368
+
6369
+ if ( !empty( $params->name ) ) {
6370
+ $fields = implode( "', '", $params->name );
6371
+
6372
+ $lookup[] = "`post_name` IN ( '{$fields}' )";
6373
+ }
6374
+
6375
+ if ( !empty( $params->id ) ) {
6376
+ $fields = implode( ", ", $params->id );
6377
+
6378
+ $lookup[] = "`ID` IN ( {$fields} )";
6379
+ }
6380
+
6381
+ $lookup = implode( ' AND ', $lookup );
6382
+
6383
+ $result = pods_query( "SELECT `ID`, `post_name`, `post_parent` FROM `@wp_posts` WHERE `post_type` = '_pods_field' AND ( {$lookup} )" );
6384
+
6385
+ $fields = array();
6386
+
6387
+ if ( !empty( $result ) ) {
6388
+ foreach ( $result as $field ) {
6389
+ $field = $this->load_field( array(
6390
+ 'id' => $field->ID,
6391
+ 'name' => $field->post_name,
6392
+ 'pod_id' => $field->post_parent
6393
+ ), false );
6394
+
6395
+ if ( !empty( $field ) && ( empty( $params->type ) || in_array( $field[ 'type' ], $params->type ) ) )
6396
+ $fields[ $field[ 'id' ] ] = $field;
6397
+ }
6398
+ }
6399
+ }
6400
+ if ( isset( $cache_key ) ) {
6401
+ $this->fields_cache[ $cache_key ] = $fields;
6402
+ }
6403
+ return $fields;
6404
+ }
6405
+
6406
+ /**
6407
+ * Load a Pods Object
6408
+ *
6409
+ * $params['id'] int The Object ID
6410
+ * $params['name'] string The Object name
6411
+ * $params['type'] string The Object type
6412
+ *
6413
+ * @param array|object $params An associative array of parameters
6414
+ * @param bool $strict
6415
+ *
6416
+ * @return array|bool
6417
+ * @since 2.0
6418
+ */
6419
+ public function load_object ( $params, $strict = false ) {
6420
+ if ( is_object( $params ) && isset( $params->post_title ) )
6421
+ $_object = get_object_vars( $params );
6422
+ else {
6423
+ $params = (object) pods_sanitize( $params );
6424
+
6425
+ if ( !isset( $params->type ) || empty( $params->type ) )
6426
+ return pods_error( __( 'Object type is required', 'pods' ), $this );
6427
+
6428
+ if ( ( !isset( $params->id ) || empty( $params->id ) ) && ( !isset( $params->name ) || empty( $params->name ) ) )
6429
+ return pods_error( __( 'Either Object ID or Name are required', 'pods' ), $this );
6430
+
6431
+ /**
6432
+ * @var $wpdb wpdb
6433
+ */
6434
+ global $wpdb;
6435
+
6436
+ if ( isset( $params->name ) )
6437
+ $_object = pods_by_title( $params->name, ARRAY_A, '_pods_' . $params->type, 'publish' );
6438
+ else {
6439
+ $object = $params->id;
6440
+
6441
+ $_object = get_post( $object, ARRAY_A );
6442
+ }
6443
+
6444
+ if ( empty( $_object ) ) {
6445
+ if ( $strict )
6446
+ return pods_error( __( 'Object not found', 'pods' ), $this );
6447
+
6448
+ return false;
6449
+ }
6450
+ }
6451
+
6452
+ $object = array(
6453
+ 'id' => $_object[ 'ID' ],
6454
+ 'name' => $_object[ 'post_title' ],
6455
+ 'code' => $_object[ 'post_content' ],
6456
+ 'type' => str_replace( '_pods_', '', $_object[ 'post_type' ] ),
6457
+ 'slug' => $_object[ 'post_name' ]
6458
+ );
6459
+
6460
+ $object[ 'options' ] = get_post_meta( $object[ 'id' ] );
6461
+
6462
+ foreach ( $object[ 'options' ] as $option => &$value ) {
6463
+ if ( is_array( $value ) && 1 == count( $value ) )
6464
+ $value = current( $value );
6465
+ }
6466
+
6467
+ return $object;
6468
+ }
6469
+
6470
+ /**
6471
+ * Load Multiple Pods Objects
6472
+ *
6473
+ * $params['type'] string The Object type
6474
+ * $params['options'] array Pod Option(s) key=>value array to filter by
6475
+ * $params['orderby'] string ORDER BY clause of query
6476
+ * $params['limit'] string Number of objects to return
6477
+ * $params['where'] string WHERE clause of query
6478
+ * $params['ids'] string|array IDs of Objects
6479
+ *
6480
+ * @param array|object $params An associative array of parameters
6481
+ *
6482
+ * @return array
6483
+ * @since 2.0
6484
+ */
6485
+ public function load_objects ( $params ) {
6486
+ $params = (object) pods_sanitize( $params );
6487
+
6488
+ if ( !isset( $params->type ) || empty( $params->type ) )
6489
+ return pods_error( __( 'Pods Object type is required', 'pods' ), $this );
6490
+
6491
+ $order = 'ASC';
6492
+ $orderby = 'menu_order';
6493
+ $limit = -1;
6494
+ $ids = false;
6495
+
6496
+ $meta_query = array();
6497
+ $cache_key = '';
6498
+
6499
+ if ( isset( $params->options ) && !empty( $params->options ) && is_array( $params->options ) ) {
6500
+ foreach ( $params->options as $option => $value ) {
6501
+ if ( !is_array( $value ) )
6502
+ $value = array( $value );
6503
+
6504
+ $value = pods_trim( $value );
6505
+
6506
+ sort( $value );
6507
+
6508
+ $meta_query[] = array(
6509
+ 'key' => $option,
6510
+ 'value' => pods_sanitize( $value ),
6511
+ 'compare' => 'IN'
6512
+ );
6513
+ }
6514
+ }
6515
+
6516
+ if ( isset( $params->where ) && is_array( $params->where ) )
6517
+ $meta_query = array_merge( $meta_query, (array) $params->where );
6518
+
6519
+ if ( isset( $params->order ) && !empty( $params->order ) && in_array( strtoupper( $params->order ), array( 'ASC', 'DESC' ) ) )
6520
+ $order = strtoupper( $params->order );
6521
+
6522
+ if ( isset( $params->orderby ) && !empty( $params->orderby ) )
6523
+ $orderby = strtoupper( $params->orderby );
6524
+
6525
+ if ( isset( $params->limit ) && !empty( $params->limit ) )
6526
+ $limit = pods_absint( $params->limit );
6527
+
6528
+ if ( isset( $params->ids ) && !empty( $params->ids ) ) {
6529
+ $ids = $params->ids;
6530
+
6531
+ if ( !is_array( $ids ) )
6532
+ $ids = explode( ',', $ids );
6533
+ }
6534
+
6535
+ if ( empty( $ids ) )
6536
+ $ids = false;
6537
+
6538
+ if ( pods_api_cache() && empty( $meta_query ) && empty( $limit ) && ( empty( $orderby ) || 'menu_order' == $orderby ) && empty( $ids ) ) {
6539
+ $cache_key = 'pods_objects_' . $params->type;
6540
+
6541
+ $the_objects = pods_transient_get( $cache_key );
6542
+
6543
+ if ( false !== $the_objects )
6544
+ return $the_objects;
6545
+ }
6546
+
6547
+ $the_objects = array();
6548
+
6549
+ $args = array(
6550
+ 'post_type' => '_pods_' . $params->type,
6551
+ 'nopaging' => true,
6552
+ 'posts_per_page' => $limit,
6553
+ 'order' => $order,
6554
+ 'orderby' => $orderby,
6555
+ 'meta_query' => $meta_query,
6556
+ );
6557
+
6558
+ // Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6559
+ if ( false != $ids ) {
6560
+ $args[ 'post__in' ] = $ids;
6561
+ }
6562
+
6563
+ $objects = get_posts( $args );
6564
+
6565
+ foreach ( $objects as $object ) {
6566
+ $object = $this->load_object( $object );
6567
+
6568
+ $the_objects[ $object[ 'name' ] ] = $object;
6569
+ }
6570
+
6571
+ if ( pods_api_cache() && !empty( $cache_key ) )
6572
+ pods_transient_set( $cache_key, $the_objects );
6573
+
6574
+ return $the_objects;
6575
+ }
6576
+
6577
+ /**
6578
+ * @see PodsAPI::load_object
6579
+ *
6580
+ * Load a Pod Template
6581
+ *
6582
+ * $params['id'] int The template ID
6583
+ * $params['name'] string The template name
6584
+ *
6585
+ * @param array $params An associative array of parameters
6586
+ *
6587
+ * @return array|bool
6588
+ * @since 1.7.9
6589
+ */
6590
+ public function load_template ( $params ) {
6591
+ if ( !class_exists( 'Pods_Templates' ) )
6592
+ return false;
6593
+
6594
+ $params = (object) $params;
6595
+ $params->type = 'template';
6596
+ return $this->load_object( $params );
6597
+ }
6598
+
6599
+ /**
6600
+ * @see PodsAPI::load_objects
6601
+ *
6602
+ * Load Multiple Pod Templates
6603
+ *
6604
+ * $params['where'] string The WHERE clause of query
6605
+ * $params['options'] array Pod Option(s) key=>value array to filter by
6606
+ * $params['orderby'] string ORDER BY clause of query
6607
+ * $params['limit'] string Number of templates to return
6608
+ *
6609
+ * @param array $params (optional) An associative array of parameters
6610
+ *
6611
+ * @return array
6612
+ *
6613
+ * @since 2.0
6614
+ */
6615
+ public function load_templates ( $params = null ) {
6616
+ if ( !class_exists( 'Pods_Templates' ) )
6617
+ return array();
6618
+
6619
+ $params = (object) $params;
6620
+ $params->type = 'template';
6621
+ return $this->load_objects( $params );
6622
+ }
6623
+
6624
+ /**
6625
+ * @see PodsAPI::load_object
6626
+ *
6627
+ * Load a Pod Page
6628
+ *
6629
+ * $params['id'] int The page ID
6630
+ * $params['name'] string The page URI
6631
+ *
6632
+ * @param array $params An associative array of parameters
6633
+ *
6634
+ * @return array|bool
6635
+ *
6636
+ * @since 1.7.9
6637
+ */
6638
+ public function load_page ( $params ) {
6639
+ if ( !class_exists( 'Pods_Pages' ) )
6640
+ return false;
6641
+
6642
+ $params = (object) $params;
6643
+ if ( !isset( $params->name ) && isset( $params->uri ) ) {
6644
+ $params->name = $params->uri;
6645
+ unset( $params->uri );
6646
+ }
6647
+ $params->type = 'page';
6648
+ return $this->load_object( $params );
6649
+ }
6650
+
6651
+ /**
6652
+ * @see PodsAPI::load_objects
6653
+ *
6654
+ * Load Multiple Pod Pages
6655
+ *
6656
+ * $params['where'] string The WHERE clause of query
6657
+ * $params['options'] array Pod Option(s) key=>value array to filter by
6658
+ * $params['orderby'] string ORDER BY clause of query
6659
+ * $params['limit'] string Number of pages to return
6660
+ *
6661
+ * @param array $params (optional) An associative array of parameters
6662
+ *
6663
+ * @return array
6664
+ *
6665
+ * @since 2.0
6666
+ */
6667
+ public function load_pages ( $params = null ) {
6668
+ if ( !class_exists( 'Pods_Pages' ) )
6669
+ return array();
6670
+
6671
+ $params = (object) $params;
6672
+ $params->type = 'page';
6673
+ return $this->load_objects( $params );
6674
+ }
6675
+
6676
+ /**
6677
+ * @see PodsAPI::load_object
6678
+ *
6679
+ * Load a Pod Helper
6680
+ *
6681
+ * $params['id'] int The helper ID
6682
+ * $params['name'] string The helper name
6683
+ *
6684
+ * @param array $params An associative array of parameters
6685
+ *
6686
+ * @return array|bool
6687
+ *
6688
+ * @since 1.7.9
6689
+ */
6690
+ public function load_helper ( $params ) {
6691
+ if ( !class_exists( 'Pods_Helpers' ) )
6692
+ return false;
6693
+
6694
+ $params = (object) $params;
6695
+ $params->type = 'helper';
6696
+ return $this->load_object( $params );
6697
+ }
6698
+
6699
+ /**
6700
+ * @see PodsAPI::load_objects
6701
+ *
6702
+ * Load Multiple Pod Helpers
6703
+ *
6704
+ * $params['where'] string The WHERE clause of query
6705
+ * $params['options'] array Pod Option(s) key=>value array to filter by
6706
+ * $params['orderby'] string ORDER BY clause of query
6707
+ * $params['limit'] string Number of pages to return
6708
+ *
6709
+ * @param array $params (optional) An associative array of parameters
6710
+ *
6711
+ * @return array
6712
+ *
6713
+ * @since 2.0
6714
+ */
6715
+ public function load_helpers ( $params = null ) {
6716
+ if ( !class_exists( 'Pods_Helpers' ) )
6717
+ return array();
6718
+
6719
+ $params = (object) $params;
6720
+ $params->type = 'helper';
6721
+ return $this->load_objects( $params );
6722
+ }
6723
+
6724
+ /**
6725
+ * Load the pod item object
6726
+ *
6727
+ * $params['pod'] string The datatype name
6728
+ * $params['id'] int (optional) The item's ID
6729
+ *
6730
+ * @param array $params An associative array of parameters
6731
+ *
6732
+ * @return bool|\Pods
6733
+ *
6734
+ * @uses pods()
6735
+ *
6736
+ * @since 2.0
6737
+ */
6738
+ public function load_pod_item ( $params ) {
6739
+ $params = (object) pods_sanitize( $params );
6740
+
6741
+ if ( !isset( $params->pod ) || empty( $params->pod ) )
6742
+ return pods_error( __( 'Pod name required', 'pods' ), $this );
6743
+ if ( !isset( $params->id ) || empty( $params->id ) )
6744
+ return pods_error( __( 'Item ID required', 'pods' ), $this );
6745
+
6746
+ $pod = false;
6747
+
6748
+ if ( pods_api_cache() )
6749
+ $pod = pods_cache_get( $params->id, 'pods_item_object_' . $params->pod );
6750
+
6751
+ if ( false !== $pod )
6752
+ return $pod;
6753
+
6754
+ $pod = pods( $params->pod, $params->id );
6755
+
6756
+ if ( pods_api_cache() )
6757
+ pods_cache_set( $params->id, $pod, 'pods_item_object_' . $params->pod );
6758
+
6759
+ return $pod;
6760
+ }
6761
+
6762
+ /**
6763
+ * Load potential sister fields for a specific field
6764
+ *
6765
+ * $params['pod'] int The Pod name
6766
+ * $params['related_pod'] string The related Pod name
6767
+ *
6768
+ * @param array $params An associative array of parameters
6769
+ * @param array $pod (optional) Array of Pod data to use (to avoid lookup)
6770
+ *
6771
+ * @return array|bool
6772
+ *
6773
+ * @since 1.7.9
6774
+ *
6775
+ * @uses PodsAPI::load_pod
6776
+ */
6777
+ public function load_sister_fields ( $params, $pod = null ) {
6778
+ $params = (object) pods_sanitize( $params );
6779
+
6780
+ if ( empty( $pod ) ) {
6781
+ $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => false ), false );
6782
+
6783
+ if ( false === $pod )
6784
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
6785
+ }
6786
+
6787
+ $params->pod_id = $pod[ 'id' ];
6788
+ $params->pod = $pod[ 'name' ];
6789
+
6790
+ $type = false;
6791
+
6792
+ if ( 0 === strpos( $params->related_pod, 'pod-' ) ) {
6793
+ $params->related_pod = pods_str_replace( 'pod-', '', $params->related_pod, 1 );
6794
+ $type = 'pod';
6795
+ }
6796
+ elseif ( 0 === strpos( $params->related_pod, 'post_type-' ) ) {
6797
+ $params->related_pod = pods_str_replace( 'post_type-', '', $params->related_pod, 1 );
6798
+ $type = 'post_type';
6799
+ }
6800
+ elseif ( 0 === strpos( $params->related_pod, 'taxonomy-' ) ) {
6801
+ $params->related_pod = pods_str_replace( 'taxonomy-', '', $params->related_pod, 1 );
6802
+ $type = 'taxonomy';
6803
+ }
6804
+
6805
+ $related_pod = $this->load_pod( array( 'name' => $params->related_pod, 'table_info' => false ), false );
6806
+
6807
+ if ( false === $related_pod || ( false !== $type && 'pod' != $type && $type != $related_pod[ 'type' ] ) )
6808
+ return pods_error( __( 'Related Pod not found', 'pods' ), $this );
6809
+
6810
+ $params->related_pod_id = $related_pod[ 'id' ];
6811
+ $params->related_pod = $related_pod[ 'name' ];
6812
+
6813
+ $sister_fields = array();
6814
+
6815
+ foreach ( $related_pod[ 'fields' ] as $field ) {
6816
+ if ( 'pick' == $field[ 'type' ] && in_array( $field[ 'pick_object' ], array( $pod[ 'type' ], 'pod' ) ) && ( $params->pod == $field[ 'pick_object' ] || $params->pod == $field[ 'pick_val' ] ) )
6817
+ $sister_fields[ $field[ 'id' ] ] = esc_html( $field[ 'label' ] . ' (' . $field[ 'name' ] . ')' );
6818
+ }
6819
+
6820
+ return $sister_fields;
6821
+ }
6822
+
6823
+ /**
6824
+ * Takes a sql field such as tinyint and returns the pods field type, such as num.
6825
+ *
6826
+ * @param string $sql_field The SQL field to look for
6827
+ *
6828
+ * @return string The field type
6829
+ *
6830
+ * @since 2.0
6831
+ */
6832
+ public static function detect_pod_field_from_sql_data_type ( $sql_field ) {
6833
+ $sql_field = strtolower( $sql_field );
6834
+
6835
+ $field_to_field_map = array(
6836
+ 'tinyint' => 'number',
6837
+ 'smallint' => 'number',
6838
+ 'mediumint' => 'number',
6839
+ 'int' => 'number',
6840
+ 'bigint' => 'number',
6841
+ 'float' => 'number',
6842
+ 'double' => 'number',
6843
+ 'decimal' => 'number',
6844
+ 'date' => 'date',
6845
+ 'datetime' => 'datetime',
6846
+ 'timestamp' => 'datetime',
6847
+ 'time' => 'time',
6848
+ 'year' => 'date',
6849
+ 'varchar' => 'text',
6850
+ 'text' => 'paragraph',
6851
+ 'mediumtext' => 'paragraph',
6852
+ 'longtext' => 'paragraph'
6853
+ );
6854
+
6855
+ return ( array_key_exists( $sql_field, $field_to_field_map ) ) ? $field_to_field_map[ $sql_field ] : 'paragraph';
6856
+ }
6857
+
6858
+ /**
6859
+ * Gets all field types
6860
+ *
6861
+ * @return array Array of field types
6862
+ *
6863
+ * @uses PodsForm::field_loader
6864
+ *
6865
+ * @since 2.0
6866
+ * @deprecated
6867
+ */
6868
+ public function get_field_types () {
6869
+ return PodsForm::field_types();
6870
+ }
6871
+
6872
+ /**
6873
+ * Gets the schema definition of a field.
6874
+ *
6875
+ * @param string $type Field type to look for
6876
+ * @param array $options (optional) Options of the field to pass to the schema function.
6877
+ *
6878
+ * @return array|bool|mixed|null
6879
+ *
6880
+ * @since 2.0
6881
+ */
6882
+ private function get_field_definition ( $type, $options = null ) {
6883
+ $definition = PodsForm::field_method( $type, 'schema', $options );
6884
+
6885
+ return $this->do_hook( 'field_definition', $definition, $type, $options );
6886
+ }
6887
+
6888
+ /**
6889
+ * @see PodsForm:validate
6890
+ *
6891
+ * Validates the value of a field.
6892
+ *
6893
+ * @param mixed $value The value to validate
6894
+ * @param string $field Field to use for validation
6895
+ * @param array $object_fields Fields of the object we're validating
6896
+ * @param array $fields Array of all fields data
6897
+ * @param array|Pods $pod Array of pod data (or Pods object)
6898
+ * @param array|object $params Extra parameters to pass to the validation function of the field.
6899
+ *
6900
+ * @return array|bool
6901
+ *
6902
+ * @uses PodsForm::validate
6903
+ *
6904
+ * @since 2.0
6905
+ */
6906
+ public function handle_field_validation ( &$value, $field, $object_fields, $fields, $pod, $params ) {
6907
+ $tableless_field_types = PodsForm::tableless_field_types();
6908
+
6909
+ $fields = array_merge( $fields, $object_fields );
6910
+
6911
+ $options = $fields[ $field ];
6912
+
6913
+ $id = ( is_object( $params ) ? $params->id : ( is_object( $pod ) ? $pod->id() : 0 ) );
6914
+
6915
+ if ( is_object( $pod ) )
6916
+ $pod = $pod->pod_data;
6917
+
6918
+ $type = $options[ 'type' ];
6919
+ $label = $options[ 'label' ];
6920
+ $label = empty( $label ) ? $field : $label;
6921
+
6922
+ // Verify required fields
6923
+ if ( 1 == pods_var( 'required', $options[ 'options' ], 0 ) && 'slug' != $type ) {
6924
+ if ( '' == $value || null === $value || array() === $value )
6925
+ return pods_error( sprintf( __( '%s is empty', 'pods' ), $label ), $this );
6926
+
6927
+ if ( 'multi' == pods_var( 'pick_format_type', $options[ 'options' ] ) && 'autocomplete' != pods_var( 'pick_format_multi', $options[ 'options' ] ) ) {
6928
+ $has_value = false;
6929
+
6930
+ $check_value = (array) $value;
6931
+
6932
+ foreach ( $check_value as $val ) {
6933
+ if ( '' != $val && null !== $val && 0 !== $val && '0' !== $val ) {
6934
+ $has_value = true;
6935
+
6936
+ continue;
6937
+ }
6938
+ }
6939
+
6940
+ if ( !$has_value )
6941
+ return pods_error( sprintf( __( '%s is required', 'pods' ), $label ), $this );
6942
+ }
6943
+
6944
+ }
6945
+
6946
+ // @todo move this to after pre-save preparations
6947
+ // Verify unique fields
6948
+ if ( 1 == pods_var( 'unique', $options[ 'options' ], 0 ) && '' !== $value && null !== $value && array() !== $value ) {
6949
+ if ( empty( $pod ) )
6950
+ return false;
6951
+
6952
+ if ( !in_array( $type, $tableless_field_types ) ) {
6953
+ $exclude = '';
6954
+
6955
+ if ( !empty( $id ) )
6956
+ $exclude = "AND `id` != {$id}";
6957
+
6958
+ $check = false;
6959
+
6960
+ $check_value = pods_sanitize( $value );
6961
+
6962
+ // @todo handle meta-based fields
6963
+ // Trigger an error if not unique
6964
+ if ( 'table' == $pod[ 'storage' ] )
6965
+ $check = pods_query( "SELECT `id` FROM `@wp_pods_" . $pod[ 'name' ] . "` WHERE `{$field}` = '{$check_value}' {$exclude} LIMIT 1", $this );
6966
+
6967
+ if ( !empty( $check ) )
6968
+ return pods_error( sprintf( __( '%s needs to be unique', 'pods' ), $label ), $this );
6969
+ }
6970
+ else {
6971
+ // @todo handle tableless check
6972
+ }
6973
+ }
6974
+
6975
+ $validate = PodsForm::validate( $options[ 'type' ], $value, $field, array_merge( $options, pods_var( 'options', $options, array() ) ), $fields, $pod, $id, $params );
6976
+
6977
+ $validate = $this->do_hook( 'field_validation', $validate, $value, $field, $object_fields, $fields, $pod, $params );
6978
+
6979
+ return $validate;
6980
+ }
6981
+
6982
+ /**
6983
+ * Find items related to a parent field
6984
+ *
6985
+ * @param int $field_id The Field ID
6986
+ * @param int $pod_id The Pod ID
6987
+ * @param mixed $ids A comma-separated string (or array) of item IDs
6988
+ * @param array $field Field data array
6989
+ * @param array $pod Pod data array
6990
+ *
6991
+ * @return array
6992
+ *
6993
+ * @since 2.0
6994
+ *
6995
+ * @uses pods_query()
6996
+ */
6997
+ public function lookup_related_items ( $field_id, $pod_id, $ids, $field = null, $pod = null ) {
6998
+ $related_ids = array();
6999
+
7000
+ if ( !is_array( $ids ) )
7001
+ $ids = explode( ',', $ids );
7002
+
7003
+ foreach ( $ids as $k => $id ) {
7004
+ $ids[ $k ] = (int) $id;
7005
+ }
7006
+
7007
+ $ids = array_unique( array_filter( $ids ) );
7008
+
7009
+ $idstring = implode( ',', $ids );
7010
+ if ( 0 != $pod_id && 0 != $field_id && isset( self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] ) ) {
7011
+ // Check cache first, no point in running the same query multiple times
7012
+ return self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ];
7013
+ }
7014
+
7015
+ $tableless_field_types = PodsForm::tableless_field_types();
7016
+
7017
+ $field_type = pods_v( 'type', $field );
7018
+
7019
+ if ( empty( $ids ) || !in_array( $field_type, $tableless_field_types ) )
7020
+ return array();
7021
+
7022
+ $related_pick_limit = 0;
7023
+
7024
+ if ( empty( $field ) ) {
7025
+ $field = $this->load_field( array( 'id' => $field_id ) );
7026
+ }
7027
+
7028
+ if ( !empty( $field ) ) {
7029
+ $options = (array) pods_var_raw( 'options', $field, $field, null, true );
7030
+
7031
+ $related_pick_limit = (int) pods_v( $field_type . '_limit', $options, 0 );
7032
+
7033
+ if ( 'single' == pods_var_raw( $field_type . '_format_type', $options ) )
7034
+ $related_pick_limit = 1;
7035
+
7036
+ // Temporary hack until there's some better handling here
7037
+ $related_pick_limit = $related_pick_limit * count( $ids );
7038
+ }
7039
+
7040
+ if ( 'taxonomy' == $field_type ) {
7041
+ $related = wp_get_object_terms( $ids, pods_v( 'name', $field ), array( 'fields' => 'ids' ) );
7042
+
7043
+ if ( !is_wp_error( $related ) ) {
7044
+ $related_ids = $related;
7045
+ }
7046
+ }
7047
+ elseif ( !pods_tableless() ) {
7048
+ $ids = implode( ', ', $ids );
7049
+
7050
+ $field_id = (int) $field_id;
7051
+ $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
7052
+
7053
+ $related_where = "
7054
+ `field_id` = {$field_id}
7055
+ AND `item_id` IN ( {$ids} )
7056
+ ";
7057
+
7058
+ $sql = "
7059
+ SELECT item_id, related_item_id, related_field_id
7060
+ FROM `@wp_podsrel`
7061
+ WHERE
7062
+ {$related_where}
7063
+ ORDER BY `weight`
7064
+ ";
7065
+
7066
+ $relationships = pods_query( $sql );
7067
+
7068
+ if ( !empty( $relationships ) ) {
7069
+ foreach ( $relationships as $relation ) {
7070
+ if ( !in_array( $relation->related_item_id, $related_ids ) )
7071
+ $related_ids[] = (int) $relation->related_item_id;
7072
+ elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->item_id, $related_ids ) )
7073
+ $related_ids[] = (int) $relation->item_id;
7074
+ }
7075
+ }
7076
+ }
7077
+ else {
7078
+ if ( !is_array( $pod ) )
7079
+ $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
7080
+
7081
+ if ( !empty( $pod ) && in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
7082
+ $meta_type = $pod[ 'type' ];
7083
+
7084
+ if ( in_array( $meta_type, array( 'post_type', 'media' ) ) )
7085
+ $meta_type = 'post';
7086
+ elseif ( 'taxonomy' == $meta_type )
7087
+ $meta_type = 'term';
7088
+
7089
+ $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7090
+
7091
+ if ( !$no_conflict )
7092
+ pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7093
+
7094
+ foreach ( $ids as $id ) {
7095
+ if ( 'settings' == $meta_type ) {
7096
+ $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
7097
+
7098
+ if ( empty( $related_id ) )
7099
+ $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
7100
+
7101
+ if ( is_array( $related_id ) && !empty( $related_id ) ) {
7102
+ foreach ( $related_id as $related ) {
7103
+ if ( is_array( $related ) && !empty( $related ) ) {
7104
+ if ( isset( $related[ 'id' ] ) )
7105
+ $related_ids[] = (int) $related[ 'id' ];
7106
+ else {
7107
+ foreach ( $related as $r ) {
7108
+ $related_ids[] = (int) $r;
7109
+ }
7110
+ }
7111
+ }
7112
+ else
7113
+ $related_ids[] = (int) $related;
7114
+ }
7115
+ }
7116
+ }
7117
+ else {
7118
+ $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
7119
+
7120
+ if ( empty( $related_id ) )
7121
+ $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
7122
+
7123
+ if ( is_array( $related_id ) && !empty( $related_id ) ) {
7124
+ foreach ( $related_id as $related ) {
7125
+ if ( is_array( $related ) && !empty( $related ) ) {
7126
+ if ( isset( $related[ 'id' ] ) )
7127
+ $related_ids[] = (int) $related[ 'id' ];
7128
+ else {
7129
+ foreach ( $related as $r ) {
7130
+ if ( isset( $related[ 'id' ] ) )
7131
+ $related_ids[] = (int) $r[ 'id' ];
7132
+ else
7133
+ $related_ids[] = (int) $r;
7134
+ }
7135
+ }
7136
+ }
7137
+ else
7138
+ $related_ids[] = (int) $related;
7139
+ }
7140
+ }
7141
+ }
7142
+ }
7143
+
7144
+ if ( !$no_conflict )
7145
+ pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7146
+ }
7147
+ }
7148
+
7149
+ if ( is_array( $related_ids ) ) {
7150
+ $related_ids = array_unique( array_filter( $related_ids ) );
7151
+
7152
+ if ( 0 < $related_pick_limit && !empty( $related_ids ) )
7153
+ $related_ids = array_slice( $related_ids, 0, $related_pick_limit );
7154
+ }
7155
+ if ( 0 != $pod_id && 0 != $field_id && ! empty( $related_ids ) ) {
7156
+ // Only cache if $pod_id and $field_id were passed
7157
+ self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] = $related_ids;
7158
+ }
7159
+
7160
+ return $related_ids;
7161
+ }
7162
+
7163
+ /**
7164
+ * Find related items related to an item
7165
+ *
7166
+ * @param int $field_id The Field ID
7167
+ * @param int $pod_id The Pod ID
7168
+ * @param int $id Item ID to get related IDs from
7169
+ * @param array $field Field data array
7170
+ * @param array $pod Pod data array
7171
+ *
7172
+ * @return array|bool
7173
+ *
7174
+ * @since 2.3
7175
+ *
7176
+ * @uses pods_query()
7177
+ */
7178
+ public function lookup_related_items_from ( $field_id, $pod_id, $id, $field = null, $pod = null ) {
7179
+ $related_ids = false;
7180
+
7181
+ $id = (int) $id;
7182
+
7183
+ $tableless_field_types = PodsForm::tableless_field_types();
7184
+
7185
+ if ( empty( $id ) || !in_array( pods_v( 'type', $field ), $tableless_field_types ) )
7186
+ return false;
7187
+
7188
+ $related_pick_limit = 0;
7189
+
7190
+ if ( !empty( $field ) ) {
7191
+ $options = (array) pods_var_raw( 'options', $field, $field, null, true );
7192
+
7193
+ $related_pick_limit = (int) pods_v( 'pick_limit', $options, 0 );
7194
+
7195
+ if ( 'single' == pods_var_raw( 'pick_format_type', $options ) )
7196
+ $related_pick_limit = 1;
7197
+ }
7198
+
7199
+ if ( !pods_tableless() ) {
7200
+ $field_id = (int) $field_id;
7201
+ $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
7202
+
7203
+ $related_where = "
7204
+ `field_id` = {$field_id}
7205
+ AND `related_item_id` = {$id}
7206
+ ";
7207
+
7208
+ $sql = "
7209
+ SELECT *
7210
+ FROM `@wp_podsrel`
7211
+ WHERE
7212
+ {$related_where}
7213
+ ORDER BY `weight`
7214
+ ";
7215
+
7216
+ $relationships = pods_query( $sql );
7217
+
7218
+ if ( !empty( $relationships ) ) {
7219
+ $related_ids = array();
7220
+
7221
+ foreach ( $relationships as $relation ) {
7222
+ if ( $field_id == $relation->field_id && !in_array( $relation->item_id, $related_ids ) )
7223
+ $related_ids[] = (int) $relation->item_id;
7224
+ elseif ( 0 < $sister_id && $field_id == $relation->related_field_id && !in_array( $relation->related_item_id, $related_ids ) )
7225
+ $related_ids[] = (int) $relation->related_item_id;
7226
+ }
7227
+ }
7228
+ }
7229
+ else {
7230
+ // @todo handle meta-based lookups
7231
+ return false;
7232
+
7233
+ if ( !is_array( $pod ) )
7234
+ $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
7235
+
7236
+ if ( !empty( $pod ) && in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'settings' ) ) ) {
7237
+ $related_ids = array();
7238
+
7239
+ $meta_type = $pod[ 'type' ];
7240
+
7241
+ if ( in_array( $meta_type, array( 'post_type', 'media' ) ) )
7242
+ $meta_type = 'post';
7243
+ elseif ( 'taxonomy' == $meta_type )
7244
+ $meta_type = 'term';
7245
+
7246
+ $no_conflict = pods_no_conflict_check( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7247
+
7248
+ if ( !$no_conflict )
7249
+ pods_no_conflict_on( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7250
+
7251
+ if ( 'settings' == $meta_type ) {
7252
+ $related_id = get_option( '_pods_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
7253
+
7254
+ if ( empty( $related_id ) )
7255
+ $related_id = get_option( $pod[ 'name' ] . '_' . $field[ 'name' ] );
7256
+
7257
+ if ( is_array( $related_id ) && !empty( $related_id ) ) {
7258
+ foreach ( $related_id as $related ) {
7259
+ if ( is_array( $related ) && !empty( $related ) ) {
7260
+ if ( isset( $related[ 'id' ] ) )
7261
+ $related_ids[] = (int) $related[ 'id' ];
7262
+ else {
7263
+ foreach ( $related as $r ) {
7264
+ $related_ids[] = (int) $r;
7265
+ }
7266
+ }
7267
+ }
7268
+ else
7269
+ $related_ids[] = (int) $related;
7270
+ }
7271
+ }
7272
+ }
7273
+ else {
7274
+ $related_id = get_metadata( $meta_type, $id, '_pods_' . $field[ 'name' ], true );
7275
+
7276
+ if ( empty( $related_id ) )
7277
+ $related_id = get_metadata( $meta_type, $id, $field[ 'name' ] );
7278
+
7279
+ if ( is_array( $related_id ) && !empty( $related_id ) ) {
7280
+ foreach ( $related_id as $related ) {
7281
+ if ( is_array( $related ) && !empty( $related ) ) {
7282
+ if ( isset( $related[ 'id' ] ) )
7283
+ $related_ids[] = (int) $related[ 'id' ];
7284
+ else {
7285
+ foreach ( $related as $r ) {
7286
+ if ( isset( $related[ 'id' ] ) )
7287
+ $related_ids[] = (int) $r[ 'id' ];
7288
+ else
7289
+ $related_ids[] = (int) $r;
7290
+ }
7291
+ }
7292
+ }
7293
+ else
7294
+ $related_ids[] = (int) $related;
7295
+ }
7296
+ }
7297
+ }
7298
+
7299
+ if ( !$no_conflict )
7300
+ pods_no_conflict_off( ( 'term' == $meta_type ? 'taxonomy' : $meta_type ) );
7301
+ }
7302
+ }
7303
+
7304
+ if ( is_array( $related_ids ) )
7305
+ $related_ids = array_unique( array_filter( $related_ids ) );
7306
+
7307
+ return $related_ids;
7308
+ }
7309
+
7310
+ /**
7311
+ *
7312
+ * Load the information about an objects MySQL table
7313
+ *
7314
+ * @param $object_type
7315
+ * @param string $object The object to look for
7316
+ * @param null $name (optional) Name of the pod to load
7317
+ * @param array $pod (optional) Array with pod information
7318
+ *
7319
+ * @return array
7320
+ *
7321
+ * @since 2.5
7322
+ */
7323
+ public function get_table_info_load ( $object_type, $object, $name = null, $pod = null ) {
7324
+
7325
+ $info = array();
7326
+
7327
+ if ( 'pod' == $object_type && null === $pod ) {
7328
+ if ( empty( $name ) ) {
7329
+ $prefix = 'pod-';
7330
+
7331
+ // Make sure we actually have the prefix before trying anything with the name
7332
+ if ( 0 === strpos( $object_type, $prefix ) )
7333
+ $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7334
+ }
7335
+
7336
+ if ( empty( $name ) && !empty( $object ) )
7337
+ $name = $object;
7338
+
7339
+ $pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7340
+
7341
+ if ( !empty( $pod ) ) {
7342
+ $object_type = $pod[ 'type' ];
7343
+ $name = $pod[ 'name' ];
7344
+ $object = $pod[ 'object' ];
7345
+
7346
+ $info[ 'pod' ] = $pod;
7347
+ }
7348
+ }
7349
+ elseif ( null === $pod ) {
7350
+ if ( empty( $name ) ) {
7351
+ $prefix = $object_type . '-';
7352
+
7353
+ // Make sure we actually have the prefix before trying anything with the name
7354
+ if ( 0 === strpos( $object_type, $prefix ) )
7355
+ $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7356
+ }
7357
+
7358
+ if ( empty( $name ) && !empty( $object ) )
7359
+ $name = $object;
7360
+
7361
+ if ( !empty( $name ) ) {
7362
+ $pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
7363
+
7364
+ if ( !empty( $pod ) && ( null === $object_type || $object_type == $pod[ 'type' ] ) ) {
7365
+ $object_type = $pod[ 'type' ];
7366
+ $name = $pod[ 'name' ];
7367
+ $object = $pod[ 'object' ];
7368
+
7369
+ $info[ 'pod' ] = $pod;
7370
+ }
7371
+ }
7372
+ }
7373
+ elseif ( !empty( $pod ) )
7374
+ $info[ 'pod' ] = $pod;
7375
+
7376
+ if ( 0 === strpos( $object_type, 'pod' ) ) {
7377
+ if ( empty( $name ) ) {
7378
+ $prefix = 'pod-';
7379
+
7380
+ // Make sure we actually have the prefix before trying anything with the name
7381
+ if ( 0 === strpos( $object_type, $prefix ) )
7382
+ $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7383
+ }
7384
+
7385
+ $info[ 'type' ] = 'pod';
7386
+ global $wpdb;
7387
+
7388
+ $info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object );
7389
+
7390
+ if ( is_array( $info[ 'pod' ] ) && 'pod' == pods_v( 'type', $info[ 'pod' ] ) ) {
7391
+ $info[ 'pod_field_index' ] = $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_v( 'pod_index', $info[ 'pod' ][ 'options' ], 'id', true );
7392
+
7393
+ $slug_field = get_posts( array(
7394
+ 'post_type' => '_pods_field',
7395
+ 'posts_per_page' => 1,
7396
+ 'nopaging' => true,
7397
+ 'post_parent' => $info[ 'pod' ][ 'id' ],
7398
+ 'orderby' => 'menu_order',
7399
+ 'order' => 'ASC',
7400
+ 'meta_query' => array(
7401
+ array(
7402
+ 'key' => 'type',
7403
+ 'value' => 'slug',
7404
+ )
7405
+ )
7406
+ ) );
7407
+
7408
+ if ( !empty( $slug_field ) ) {
7409
+ $slug_field = $slug_field[ 0 ];
7410
+
7411
+ $info[ 'field_slug' ] = $info[ 'pod_field_slug' ] = $slug_field->post_name;
7412
+ }
7413
+
7414
+ if ( 1 == pods_v( 'hierarchical', $info[ 'pod' ][ 'options' ], 0 ) ) {
7415
+ $parent_field = pods_v( 'pod_parent', $info[ 'pod' ][ 'options' ], 'id', true );
7416
+
7417
+ if ( !empty( $parent_field ) && isset( $info[ 'pod' ][ 'fields' ][ $parent_field ] ) ) {
7418
+ $info[ 'object_hierarchical' ] = true;
7419
+
7420
+ $info[ 'pod_field_parent' ] = $info[ 'field_parent' ] = $parent_field . '_select';
7421
+ $info[ 'field_parent_select' ] = '`' . $parent_field . '`.`id` AS `' . $info[ 'field_parent' ] . '`';
7422
+ }
7423
+ }
7424
+ }
7425
+ }
7426
+ return $info;
7427
+ }
7428
+
7429
+ /**
7430
+ * Get information about an objects MySQL table
7431
+ *
7432
+ * @param string $object_type
7433
+ * @param string $object The object to look for
7434
+ * @param null $name (optional) Name of the pod to load
7435
+ * @param array $pod (optional) Array with pod information
7436
+ * @param array $field (optional) Array with field information
7437
+ *
7438
+ * @return array|bool
7439
+ *
7440
+ * @since 2.0
7441
+ */
7442
+ public function get_table_info ( $object_type, $object, $name = null, $pod = null, $field = null ) {
7443
+
7444
+ /**
7445
+ * @var $wpdb wpdb
7446
+ * @var $sitepress SitePress
7447
+ * @var $polylang object
7448
+ */
7449
+ /*
7450
+ * @todo wpml-comp Remove global object usage
7451
+ */
7452
+ global $wpdb, $sitepress, $polylang;
7453
+
7454
+ // @todo Handle $object arrays for Post Types, Taxonomies, Comments (table pulled from first object in array)
7455
+
7456
+ $info = array(
7457
+ //'select' => '`t`.*',
7458
+ 'object_type' => $object_type,
7459
+ 'type' => null,
7460
+ 'object_name' => $object,
7461
+ 'object_hierarchical' => false,
7462
+
7463
+ 'table' => $object,
7464
+ 'meta_table' => $object,
7465
+ 'pod_table' => $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object ),
7466
+
7467
+ 'field_id' => 'id',
7468
+ 'field_index' => 'name',
7469
+ 'field_slug' => null,
7470
+ 'field_type' => null,
7471
+ 'field_parent' => null,
7472
+ 'field_parent_select' => null,
7473
+
7474
+ 'meta_field_id' => 'id',
7475
+ 'meta_field_index' => 'name',
7476
+ 'meta_field_value' => 'name',
7477
+
7478
+ 'pod_field_id' => 'id',
7479
+ 'pod_field_index' => 'name',
7480
+ 'pod_field_slug' => null,
7481
+ 'pod_field_parent' => null,
7482
+
7483
+ 'join' => array(),
7484
+
7485
+ 'where' => null,
7486
+ 'where_default' => null,
7487
+
7488
+ 'orderby' => null,
7489
+
7490
+ 'pod' => null,
7491
+ 'recurse' => false
7492
+ );
7493
+
7494
+ if ( empty( $object_type ) ) {
7495
+ $object_type = 'post_type';
7496
+ $object = 'post';
7497
+ }
7498
+ elseif ( empty( $object ) && in_array( $object_type, array( 'user', 'media', 'comment' ) ) ) {
7499
+ $object = $object_type;
7500
+ }
7501
+
7502
+ $pod_name = $pod;
7503
+
7504
+ if ( is_array( $pod_name ) )
7505
+ $pod_name = pods_var_raw( 'name', $pod_name, ( version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $pod_name, JSON_UNESCAPED_UNICODE ) : json_encode( $pod_name ) ), null, true );
7506
+ else {
7507
+ $pod_name = $object;
7508
+ }
7509
+
7510
+ $field_name = $field;
7511
+
7512
+ if ( is_array( $field_name ) )
7513
+ $field_name = pods_var_raw( 'name', $field_name, ( version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $pod_name, JSON_UNESCAPED_UNICODE ) : json_encode( $field_name ) ), null, true );
7514
+
7515
+ $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7516
+
7517
+ $current_language = false;
7518
+ $current_language_t_id = $current_language_tt_id = 0;
7519
+
7520
+ // Get current language data
7521
+ $lang_data = self::get_current_language();
7522
+
7523
+ if ( $lang_data ) {
7524
+ if ( ! empty( $lang_data['language'] ) ) {
7525
+ $current_language = $lang_data['language'];
7526
+ }
7527
+
7528
+ if ( ! empty( $lang_data['t_id'] ) ) {
7529
+ $current_language_t_id = $lang_data['t_id'];
7530
+ }
7531
+
7532
+ if ( ! empty( $lang_data['tt_id'] ) ) {
7533
+ $current_language_tt_id = $lang_data['tt_id'];
7534
+ }
7535
+
7536
+ if ( ! empty( $lang_data['tl_t_id'] ) ) {
7537
+ $current_language_tl_t_id = $lang_data['tl_t_id'];
7538
+ }
7539
+
7540
+ if ( ! empty( $lang_data['tl_tt_id'] ) ) {
7541
+ $current_language_tl_tt_id = $lang_data['tl_tt_id'];
7542
+ }
7543
+ }
7544
+
7545
+ if ( !empty( $current_language ) )
7546
+ $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . $current_language . '_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
7547
+
7548
+ $_info = false;
7549
+
7550
+ if ( isset( self::$table_info_cache[ $transient ] ) ) {
7551
+ // Prefer info from the object internal cache
7552
+ $_info = self::$table_info_cache[ $transient ];
7553
+ } elseif ( pods_api_cache() ) {
7554
+ $_info = pods_transient_get( $transient );
7555
+ if ( false === $_info && ! did_action( 'init' ) ) {
7556
+ $_info = pods_transient_get( $transient . '_pre_init' );
7557
+ }
7558
+ }
7559
+
7560
+ if ( false !== $_info && is_array( $_info ) ) {
7561
+ // Data was cached, use that
7562
+ $info = $_info;
7563
+ } else {
7564
+ // Data not cached, load it up
7565
+ $_info = $this->get_table_info_load( $object_type, $object, $name, $pod );
7566
+ if ( isset( $_info[ 'type' ] ) ) {
7567
+ // Allow function to override $object_type
7568
+ $object_type = $_info[ 'type' ];
7569
+ }
7570
+ $info = array_merge( $info, $_info );
7571
+ }
7572
+
7573
+ if ( 0 === strpos( $object_type, 'post_type' ) || 'media' == $object_type || in_array( pods_var_raw( 'type', $info[ 'pod' ] ), array( 'post_type', 'media' ) ) ) {
7574
+ $info[ 'table' ] = $wpdb->posts;
7575
+ $info[ 'meta_table' ] = $wpdb->postmeta;
7576
+
7577
+ $info[ 'field_id' ] = 'ID';
7578
+ $info[ 'field_index' ] = 'post_title';
7579
+ $info[ 'field_slug' ] = 'post_name';
7580
+ $info[ 'field_type' ] = 'post_type';
7581
+ $info[ 'field_parent' ] = 'post_parent';
7582
+ $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7583
+
7584
+ $info[ 'meta_field_id' ] = 'post_id';
7585
+ $info[ 'meta_field_index' ] = 'meta_key';
7586
+ $info[ 'meta_field_value' ] = 'meta_value';
7587
+
7588
+ if ( 'media' == $object_type )
7589
+ $object = 'attachment';
7590
+
7591
+ if ( empty( $name ) ) {
7592
+ $prefix = 'post_type-';
7593
+
7594
+ // Make sure we actually have the prefix before trying anything with the name
7595
+ if ( 0 === strpos( $object_type, $prefix ) )
7596
+ $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7597
+ }
7598
+
7599
+ if ( 'media' != $object_type )
7600
+ $object_type = 'post_type';
7601
+
7602
+ $post_type = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7603
+
7604
+ if ( 'attachment' == $post_type || 'media' == $object_type )
7605
+ $info[ 'pod_table' ] = $wpdb->prefix . 'pods_media';
7606
+ else
7607
+ $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $post_type, true, false );
7608
+
7609
+ $post_type_object = get_post_type_object( $post_type );
7610
+
7611
+ if ( is_object( $post_type_object ) && $post_type_object->hierarchical )
7612
+ $info[ 'object_hierarchical' ] = true;
7613
+
7614
+ // Post Status default
7615
+ $post_status = array( 'publish' );
7616
+
7617
+ // Pick field post_status option
7618
+ if ( ! empty( $field['pick_post_status'] ) ) {
7619
+ $post_status = (array) $field['pick_post_status'];
7620
+ }
7621
+
7622
+ /**
7623
+ * Default Post Status to query for.
7624
+ *
7625
+ * Use to change "default" post status from publish to any other status or statuses.
7626
+ *
7627
+ * @param array $post_status List of post statuses. Default is 'publish' or field setting (if available)
7628
+ * @param string $post_type Post type of current object
7629
+ * @param array $info Array of information about the object.
7630
+ * @param string $object Type of object
7631
+ * @param string $name Name of pod to load
7632
+ * @param array $pod Array with Pod information. Result of PodsAPI::load_pod()
7633
+ * @param array $field Array with field information
7634
+ *
7635
+ * @since unknown
7636
+ */
7637
+ $post_status = apply_filters( 'pods_api_get_table_info_default_post_status', $post_status, $post_type, $info, $object_type, $object, $name, $pod, $field );
7638
+
7639
+ $info[ 'where' ] = array(
7640
+ //'post_status' => '`t`.`post_status` IN ( "inherit", "publish" )', // @todo Figure out what statuses Attachments can be
7641
+ 'post_type' => '`t`.`' . $info[ 'field_type' ] . '` = "' . $post_type . '"'
7642
+ );
7643
+
7644
+ if ( 'post_type' == $object_type )
7645
+ $info[ 'where_default' ] = '`t`.`post_status` IN ( "' . implode( '", "', $post_status ) . '" )';
7646
+
7647
+ $info[ 'orderby' ] = '`t`.`menu_order`, `t`.`' . $info[ 'field_index' ] . '`, `t`.`post_date`';
7648
+
7649
+ /*
7650
+ * @todo wpml-comp Check if WPML filters can be applied afterwards
7651
+ */
7652
+ // WPML support
7653
+ if ( did_action( 'wpml_loaded' ) && !empty( $current_language ) && apply_filters( 'wpml_is_translated_post_type', false, $post_type ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' )) {
7654
+ $info[ 'join' ][ 'wpml_translations' ] = "
7655
+ LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7656
+ ON `wpml_translations`.`element_id` = `t`.`ID`
7657
+ AND `wpml_translations`.`element_type` = 'post_{$post_type}'
7658
+ AND `wpml_translations`.`language_code` = '{$current_language}'
7659
+ ";
7660
+
7661
+ $info[ 'join' ][ 'wpml_languages' ] = "
7662
+ LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7663
+ ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7664
+ ";
7665
+
7666
+ $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7667
+ }
7668
+ // Polylang support
7669
+ elseif( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && !empty( $current_language ) && function_exists( 'pll_is_translated_post_type' ) && pll_is_translated_post_type( $post_type ) ) {
7670
+ $info[ 'join' ][ 'polylang_languages' ] = "
7671
+ LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
7672
+ ON `polylang_languages`.`object_id` = `t`.`ID`
7673
+ AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tt_id}
7674
+ ";
7675
+
7676
+ $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`object_id` IS NOT NULL";
7677
+ }
7678
+
7679
+ $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7680
+ }
7681
+ elseif ( 0 === strpos( $object_type, 'taxonomy' ) || in_array( $object_type, array( 'nav_menu', 'post_format' ) ) || 'taxonomy' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7682
+ $info[ 'table' ] = $info[ 'meta_table' ] = $wpdb->terms;
7683
+
7684
+ $info[ 'join' ][ 'tt' ] = "LEFT JOIN `{$wpdb->term_taxonomy}` AS `tt` ON `tt`.`term_id` = `t`.`term_id`";
7685
+ $info[ 'join' ][ 'tr' ] = "LEFT JOIN `{$wpdb->term_relationships}` AS `tr` ON `tr`.`term_taxonomy_id` = `tt`.`term_taxonomy_id`";
7686
+ $info[ 'field_id' ] = $info[ 'meta_field_id' ] = 'term_id';
7687
+ $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = 'name';
7688
+ $info[ 'field_slug' ] = 'slug';
7689
+ $info[ 'field_type' ] = 'taxonomy';
7690
+ $info[ 'field_parent' ] = 'parent';
7691
+ $info[ 'field_parent_select' ] = '`tt`.`' . $info[ 'field_parent' ] . '`';
7692
+
7693
+ if ( ! empty( $wpdb->termmeta ) ) {
7694
+ $info[ 'meta_table' ] = $wpdb->termmeta;
7695
+
7696
+ $info[ 'meta_field_id' ] = 'term_id';
7697
+ $info[ 'meta_field_index' ] = 'meta_key';
7698
+ $info[ 'meta_field_value' ] = 'meta_value';
7699
+ }
7700
+
7701
+ if ( 'nav_menu' == $object_type )
7702
+ $object = 'nav_menu';
7703
+ elseif ( 'post_format' == $object_type )
7704
+ $object = 'post_format';
7705
+
7706
+ if ( empty( $name ) ) {
7707
+ $prefix = 'taxonomy-';
7708
+
7709
+ // Make sure we actually have the prefix before trying anything with the name
7710
+ if ( 0 === strpos( $object_type, $prefix ) )
7711
+ $name = substr( $object_type, strlen( $prefix ), strlen( $object_type ) );
7712
+ }
7713
+
7714
+ if ( !in_array( $object_type, array( 'nav_menu', 'post_format' ) ) )
7715
+ $object_type = 'taxonomy';
7716
+
7717
+ $taxonomy = pods_sanitize( ( empty( $object ) ? $name : $object ) );
7718
+
7719
+ $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . pods_clean_name( $taxonomy, true, false );
7720
+
7721
+ $taxonomy_object = get_taxonomy( $taxonomy );
7722
+
7723
+ if ( is_object( $taxonomy_object ) && $taxonomy_object->hierarchical )
7724
+ $info[ 'object_hierarchical' ] = true;
7725
+
7726
+ $info[ 'where' ] = array(
7727
+ 'tt.taxonomy' => '`tt`.`' . $info[ 'field_type' ] . '` = "' . $taxonomy . '"'
7728
+ );
7729
+
7730
+ /*
7731
+ * @todo wpml-comp WPML API call for is_translated_taxononomy
7732
+ * @todo wpml-comp Check if WPML filters can be applied afterwards
7733
+ */
7734
+ // WPML Support
7735
+ if ( is_object( $sitepress ) && !empty( $current_language ) && $sitepress->is_translated_taxonomy( $taxonomy ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
7736
+ $info[ 'join' ][ 'wpml_translations' ] = "
7737
+ LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
7738
+ ON `wpml_translations`.`element_id` = `tt`.`term_taxonomy_id`
7739
+ AND `wpml_translations`.`element_type` = 'tax_{$taxonomy}'
7740
+ AND `wpml_translations`.`language_code` = '{$current_language}'
7741
+ ";
7742
+
7743
+ $info[ 'join' ][ 'wpml_languages' ] = "
7744
+ LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
7745
+ ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
7746
+ ";
7747
+
7748
+ $info[ 'where' ][ 'wpml_languages' ] = "`wpml_languages`.`code` IS NOT NULL";
7749
+ }
7750
+ // Polylang support
7751
+ elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && !empty( $current_language ) && !empty( $current_language_tl_tt_id ) && function_exists( 'pll_is_translated_taxonomy' ) && pll_is_translated_taxonomy( $taxonomy ) ) {
7752
+ $info[ 'join' ][ 'polylang_languages' ] = "
7753
+ LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
7754
+ ON `polylang_languages`.`object_id` = `t`.`term_id`
7755
+ AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tl_tt_id}
7756
+ ";
7757
+
7758
+ $info[ 'where' ][ 'polylang_languages' ] = "`polylang_languages`.`object_id` IS NOT NULL";
7759
+ }
7760
+
7761
+ $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7762
+ }
7763
+ elseif ( 'user' == $object_type || 'user' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7764
+ $info[ 'table' ] = $wpdb->users;
7765
+ $info[ 'meta_table' ] = $wpdb->usermeta;
7766
+ $info[ 'pod_table' ] = $wpdb->prefix . 'pods_user';
7767
+
7768
+ $info[ 'field_id' ] = 'ID';
7769
+ $info[ 'field_index' ] = 'display_name';
7770
+ $info[ 'field_slug' ] = 'user_nicename';
7771
+
7772
+ $info[ 'meta_field_id' ] = 'user_id';
7773
+ $info[ 'meta_field_index' ] = 'meta_key';
7774
+ $info[ 'meta_field_value' ] = 'meta_value';
7775
+
7776
+ $info[ 'where' ] = array(
7777
+ 'user_status' => '`t`.`user_status` = 0'
7778
+ );
7779
+
7780
+ $info[ 'object_fields' ] = $this->get_wp_object_fields( $object_type, $info[ 'pod' ] );
7781
+ }
7782
+ elseif ( 'comment' == $object_type || 'comment' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7783
+ //$info[ 'object_hierarchical' ] = true;
7784
+
7785
+ $info[ 'table' ] = $wpdb->comments;
7786
+ $info[ 'meta_table' ] = $wpdb->commentmeta;
7787
+ $info[ 'pod_table' ] = $wpdb->prefix . 'pods_comment';
7788
+
7789
+ $info[ 'field_id' ] = 'comment_ID';
7790
+ $info[ 'field_index' ] = 'comment_date';
7791
+ $info[ 'field_type' ] = 'comment_type';
7792
+ $info[ 'field_parent' ] = 'comment_parent';
7793
+ $info[ 'field_parent_select' ] = '`t`.`' . $info[ 'field_parent' ] . '`';
7794
+
7795
+ $info[ 'meta_field_id' ] = 'comment_id';
7796
+ $info[ 'meta_field_index' ] = 'meta_key';
7797
+ $info[ 'meta_field_value' ] = 'meta_value';
7798
+
7799
+ $object = 'comment';
7800
+
7801
+ $comment_type = ( empty( $object ) ? $name : $object );
7802
+
7803
+ $comment_type_clause = '`t`.`' . $info[ 'field_type' ] . '` = "' . $comment_type . '"';
7804
+
7805
+ if ( 'comment' == $comment_type ) {
7806
+ $comment_type_clause = '( ' . $comment_type_clause . ' OR `t`.`' . $info[ 'field_type' ] . '` = "" )';
7807
+ }
7808
+
7809
+ $info[ 'where' ] = array(
7810
+ 'comment_approved' => '`t`.`comment_approved` = 1',
7811
+ 'comment_type' => $comment_type_clause
7812
+ );
7813
+
7814
+ $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` DESC, `t`.`' . $info[ 'field_id' ] . '`';
7815
+ }
7816
+ elseif ( in_array( $object_type, array( 'option', 'settings' ) ) || 'settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7817
+ $info[ 'table' ] = $wpdb->options;
7818
+ $info[ 'meta_table' ] = $wpdb->options;
7819
+
7820
+ $info[ 'field_id' ] = 'option_id';
7821
+ $info[ 'field_index' ] = 'option_name';
7822
+
7823
+ $info[ 'meta_field_id' ] = 'option_id';
7824
+ $info[ 'meta_field_index' ] = 'option_name';
7825
+ $info[ 'meta_field_value' ] = 'option_value';
7826
+
7827
+ $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7828
+ }
7829
+ elseif ( is_multisite() && ( in_array( $object_type, array( 'site_option', 'site_settings' ) ) || 'site_settings' == pods_var_raw( 'type', $info[ 'pod' ] ) ) ) {
7830
+ $info[ 'table' ] = $wpdb->sitemeta;
7831
+ $info[ 'meta_table' ] = $wpdb->sitemeta;
7832
+
7833
+ $info[ 'field_id' ] = 'site_id';
7834
+ $info[ 'field_index' ] = 'meta_key';
7835
+
7836
+ $info[ 'meta_field_id' ] = 'site_id';
7837
+ $info[ 'meta_field_index' ] = 'meta_key';
7838
+ $info[ 'meta_field_value' ] = 'meta_value';
7839
+
7840
+ $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC';
7841
+ }
7842
+ elseif ( is_multisite() && 'network' == $object_type ) { // Network = Site
7843
+ $info[ 'table' ] = $wpdb->site;
7844
+ $info[ 'meta_table' ] = $wpdb->sitemeta;
7845
+
7846
+ $info[ 'field_id' ] = 'id';
7847
+ $info[ 'field_index' ] = 'domain';
7848
+
7849
+ $info[ 'meta_field_id' ] = 'site_id';
7850
+ $info[ 'meta_field_index' ] = 'meta_key';
7851
+ $info[ 'meta_field_value' ] = 'meta_value';
7852
+
7853
+ $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
7854
+ }
7855
+ elseif ( is_multisite() && 'site' == $object_type ) { // Site = Blog
7856
+ $info[ 'table' ] = $wpdb->blogs;
7857
+
7858
+ $info[ 'field_id' ] = 'blog_id';
7859
+ $info[ 'field_index' ] = 'domain';
7860
+ $info[ 'field_type' ] = 'site_id';
7861
+
7862
+ $info[ 'where' ] = array(
7863
+ 'archived' => '`t`.`archived` = 0',
7864
+ 'spam' => '`t`.`spam` = 0',
7865
+ 'deleted' => '`t`.`deleted` = 0',
7866
+ 'site_id' => '`t`.`' . $info[ 'field_type' ] . '` = ' . (int) get_current_site()->id
7867
+ );
7868
+
7869
+ $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '` ASC, `t`.`path` ASC, `t`.`' . $info[ 'field_id' ] . '`';
7870
+ }
7871
+ elseif ( 'table' == $object_type || 'table' == pods_var_raw( 'type', $info[ 'pod' ] ) ) {
7872
+ $info[ 'table' ] = ( empty( $object ) ? $name : $object );
7873
+ $info[ 'pod_table' ] = $wpdb->prefix . 'pods_' . $info[ 'table' ];
7874
+
7875
+ if ( !empty( $field ) && is_array( $field ) ) {
7876
+ $info[ 'table' ] = pods_var_raw( 'pick_table', pods_var_raw( 'options', $field, $field ) );
7877
+ $info[ 'field_id' ] = pods_var_raw( 'pick_table_id', pods_var_raw( 'options', $field, $field ) );
7878
+ $info[ 'field_index' ] = $info[ 'meta_field_index' ] = $info[ 'meta_field_value' ] = pods_var_raw( 'pick_table_index', pods_var_raw( 'options', $field, $field ) );
7879
+ }
7880
+ }
7881
+
7882
+ $info[ 'table' ] = pods_clean_name( $info[ 'table' ], false, false );
7883
+ $info[ 'meta_table' ] = pods_clean_name( $info[ 'meta_table' ], false, false );
7884
+ $info[ 'pod_table' ] = pods_clean_name( $info[ 'pod_table' ], false, false );
7885
+
7886
+ $info[ 'field_id' ] = pods_clean_name( $info[ 'field_id' ], false, false );
7887
+ $info[ 'field_index' ] = pods_clean_name( $info[ 'field_index' ], false, false );
7888
+ $info[ 'field_slug' ] = pods_clean_name( $info[ 'field_slug' ], false, false );
7889
+
7890
+ $info[ 'meta_field_id' ] = pods_clean_name( $info[ 'meta_field_id' ], false, false );
7891
+ $info[ 'meta_field_index' ] = pods_clean_name( $info[ 'meta_field_index' ], false, false );
7892
+ $info[ 'meta_field_value' ] = pods_clean_name( $info[ 'meta_field_value' ], false, false );
7893
+
7894
+ if ( empty( $info[ 'orderby' ] ) )
7895
+ $info[ 'orderby' ] = '`t`.`' . $info[ 'field_index' ] . '`, `t`.`' . $info[ 'field_id' ] . '`';
7896
+
7897
+ if ( 'table' == pods_var_raw( 'storage', $info[ 'pod' ] ) && !in_array( $object_type, array( 'pod', 'table' ) ) ) {
7898
+ $info[ 'join' ][ 'd' ] = 'LEFT JOIN `' . $info[ 'pod_table' ] . '` AS `d` ON `d`.`id` = `t`.`' . $info[ 'field_id' ] . '`';
7899
+ //$info[ 'select' ] .= ', `d`.*';
7900
+ }
7901
+
7902
+ if ( !empty( $info[ 'pod' ] ) && is_array( $info[ 'pod' ] ) )
7903
+ $info[ 'recurse' ] = true;
7904
+
7905
+ $info[ 'type' ] = $object_type;
7906
+ $info[ 'object_name' ] = $object;
7907
+
7908
+ if ( pods_api_cache() ) {
7909
+ if ( ! did_action( 'init' ) ) {
7910
+ $transient .= '_pre_init';
7911
+ }
7912
+ pods_transient_set( $transient, $info );
7913
+ }
7914
+
7915
+
7916
+ self::$table_info_cache[ $transient ] = apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this );
7917
+
7918
+ return self::$table_info_cache[ $transient ];
7919
+ }
7920
+
7921
+ /**
7922
+ * Export a package
7923
+ *
7924
+ * $params['pod'] string Pod Type IDs to export
7925
+ * $params['template'] string Template IDs to export
7926
+ * $params['podpage'] string Pod Page IDs to export
7927
+ * $params['helper'] string Helper IDs to export
7928
+ *
7929
+ * @param array $params An associative array of parameters
7930
+ *
7931
+ * @return array|bool
7932
+ *
7933
+ * @since 1.9.0
7934
+ * @deprecated 2.0
7935
+ */
7936
+ public function export_package ( $params ) {
7937
+ if ( class_exists( 'Pods_Migrate_Packages' ) )
7938
+ return Pods_Migrate_Packages::export( $params );
7939
+
7940
+ return false;
7941
+ }
7942
+
7943
+ /**
7944
+ * Replace an existing package
7945
+ *
7946
+ * @param mixed $data (optional) An associative array containing a package, or the json encoded package
7947
+ *
7948
+ * @return bool
7949
+ *
7950
+ * @since 1.9.8
7951
+ * @deprecated 2.0
7952
+ */
7953
+ public function replace_package ( $data = false ) {
7954
+ return $this->import_package( $data, true );
7955
+ }
7956
+
7957
+ /**
7958
+ * Import a package
7959
+ *
7960
+ * @param mixed $data (optional) An associative array containing a package, or the json encoded package
7961
+ * @param bool $replace (optional) Replace existing items when found
7962
+ *
7963
+ * @return bool
7964
+ *
7965
+ * @since 1.9.0
7966
+ * @deprecated 2.0
7967
+ */
7968
+ public function import_package ( $data = false, $replace = false ) {
7969
+ if ( class_exists( 'Pods_Migrate_Packages' ) )
7970
+ return Pods_Migrate_Packages::import( $data, $replace );
7971
+
7972
+ return false;
7973
+ }
7974
+
7975
+ /**
7976
+ * Validate a package
7977
+ *
7978
+ * @param array|string $data (optional) An associative array containing a package, or the json encoded package
7979
+ * @param bool $output (optional)
7980
+ *
7981
+ * @return array|bool
7982
+ *
7983
+ * @since 1.9.0
7984
+ * @deprecated 2.0
7985
+ */
7986
+ public function validate_package ( $data = false, $output = false ) {
7987
+ return true;
7988
+ }
7989
+
7990
+ /**
7991
+ * Import data from an array or a CSV file.
7992
+ *
7993
+ * @param mixed $import_data PHP associative array or CSV input
7994
+ * @param bool $numeric_mode Use IDs instead of the name field when matching
7995
+ * @param string $format Format of import data, options are php or csv
7996
+ *
7997
+ * @return array IDs of imported items
7998
+ *
7999
+ * @since 1.7.1
8000
+ * @todo This needs some love and use of table_info etc for relationships
8001
+ */
8002
+ public function import ( $import_data, $numeric_mode = false, $format = null ) {
8003
+ /**
8004
+ * @var $wpdb wpdb
8005
+ */
8006
+ global $wpdb;
8007
+
8008
+ if ( null === $format && null !== $this->format )
8009
+ $format = $this->format;
8010
+
8011
+ if ( 'csv' == $format && !is_array( $import_data ) ) {
8012
+ $data = pods_migrate( 'sv', ',' )->parse( $import_data );
8013
+
8014
+ $import_data = $data[ 'items' ];
8015
+ }
8016
+
8017
+ pods_query( "SET NAMES utf8" );
8018
+ pods_query( "SET CHARACTER SET utf8" );
8019
+
8020
+ // Loop through the array of items
8021
+ $ids = array();
8022
+
8023
+ // Test to see if it's an array of arrays
8024
+ if ( !is_array( @current( $import_data ) ) )
8025
+ $import_data = array( $import_data );
8026
+
8027
+ $pod = $this->load_pod( array( 'name' => $this->pod ) );
8028
+
8029
+ if ( false === $pod )
8030
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
8031
+
8032
+ $fields = array_merge( $pod[ 'fields' ], $pod[ 'object_fields' ] );
8033
+
8034
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
8035
+
8036
+ foreach ( $import_data as $key => $data_row ) {
8037
+ $data = array();
8038
+
8039
+ // Loop through each field (use $fields so only valid fields get parsed)
8040
+ foreach ( $fields as $field_name => $field_data ) {
8041
+ if ( !isset( $data_row[ $field_name ] ) && !isset( $data_row[ $field_data[ 'label' ] ] ) )
8042
+ continue;
8043
+
8044
+ $field_id = $field_data[ 'id' ];
8045
+ $type = $field_data[ 'type' ];
8046
+ $pick_object = isset( $field_data[ 'pick_object' ] ) ? $field_data[ 'pick_object' ] : '';
8047
+ $pick_val = isset( $field_data[ 'pick_val' ] ) ? $field_data[ 'pick_val' ] : '';
8048
+
8049
+ if ( isset( $data_row[ $field_name] ) )
8050
+ $field_value = $data_row[ $field_name ];
8051
+ else
8052
+ $field_value = $data_row[ $field_data[ 'label' ] ];
8053
+
8054
+ if ( null !== $field_value && false !== $field_value && '' !== $field_value ) {
8055
+ if ( 'pick' == $type || in_array( $type, PodsForm::file_field_types() ) ) {
8056
+ $field_values = is_array( $field_value ) ? $field_value : array( $field_value );
8057
+ $pick_values = array();
8058
+
8059
+ foreach ( $field_values as $pick_value ) {
8060
+ if ( in_array( $type, PodsForm::file_field_types() ) || 'media' == $pick_object ) {
8061
+ $where = "`guid` = '" . pods_sanitize( $pick_value ) . "'";
8062
+
8063
+ if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8064
+ $where = "`ID` = " . pods_absint( $pick_value );
8065
+
8066
+ $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = 'attachment' AND {$where} ORDER BY `ID`", $this );
8067
+
8068
+ if ( !empty( $result ) )
8069
+ $pick_values[] = $result[ 0 ]->id;
8070
+ }
8071
+ // @todo This could and should be abstracted better and simplified
8072
+ elseif ( 'pick' == $type ) {
8073
+ $related_pod = false;
8074
+
8075
+ if ( 'pod' == $pick_object )
8076
+ $related_pod = $this->load_pod( array( 'name' => $pick_val, 'table_info' => true ), false );
8077
+
8078
+ if ( empty( $related_pod ) ) {
8079
+ $related_pod = array(
8080
+ 'id' => 0,
8081
+ 'type' => $pick_object
8082
+ );
8083
+ }
8084
+
8085
+ if ( in_array( 'taxonomy', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8086
+ $where = "`t`.`name` = '" . pods_sanitize( $pick_value ) . "'";
8087
+
8088
+ if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8089
+ $where = "`tt`.`term_id` = " . pods_absint( $pick_value );
8090
+
8091
+ $result = pods_query( "SELECT `t`.`term_id` AS `id` FROM `{$wpdb->term_taxonomy}` AS `tt` LEFT JOIN `{$wpdb->terms}` AS `t` ON `t`.`term_id` = `tt`.`term_id` WHERE `taxonomy` = '{$pick_val}' AND {$where} ORDER BY `t`.`term_id`", $this );
8092
+
8093
+ if ( !empty( $result ) )
8094
+ $pick_values[] = $result[ 0 ]->id;
8095
+ }
8096
+ elseif ( in_array( 'post_type', array( $pick_object, $related_pod[ 'type' ] ) ) || in_array( 'media', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8097
+ $where = "`post_title` = '" . pods_sanitize( $pick_value ) . "'";
8098
+
8099
+ if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8100
+ $where = "`ID` = " . pods_absint( $pick_value );
8101
+
8102
+ $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->posts}` WHERE `post_type` = '{$pick_val}' AND {$where} ORDER BY `ID`", $this );
8103
+
8104
+ if ( !empty( $result ) )
8105
+ $pick_values[] = $result[ 0 ]->id;
8106
+ }
8107
+ elseif ( in_array( 'user', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8108
+ $where = "`user_login` = '" . pods_sanitize( $pick_value ) . "'";
8109
+
8110
+ if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8111
+ $where = "`ID` = " . pods_absint( $pick_value );
8112
+
8113
+ $result = pods_query( "SELECT `ID` AS `id` FROM `{$wpdb->users}` WHERE {$where} ORDER BY `ID`", $this );
8114
+
8115
+ if ( !empty( $result ) )
8116
+ $pick_values[] = $result[ 0 ]->id;
8117
+ }
8118
+ elseif ( in_array( 'comment', array( $pick_object, $related_pod[ 'type' ] ) ) ) {
8119
+ $where = "`comment_ID` = " . pods_absint( $pick_value );
8120
+
8121
+ $result = pods_query( "SELECT `comment_ID` AS `id` FROM `{$wpdb->comments}` WHERE {$where} ORDER BY `ID`", $this );
8122
+
8123
+ if ( !empty( $result ) )
8124
+ $pick_values[] = $result[ 0 ]->id;
8125
+ }
8126
+ elseif ( in_array( $pick_object, $simple_tableless_objects ) )
8127
+ $pick_values[] = $pick_value;
8128
+ elseif ( !empty( $related_pod[ 'id' ] ) ) {
8129
+ $where = "`" . $related_pod[ 'field_index' ] . "` = '" . pods_sanitize( $pick_value ) . "'";
8130
+
8131
+ if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode )
8132
+ $where = "`" . $related_pod[ 'field_id' ] . "` = " . pods_absint( $pick_value );
8133
+
8134
+ $result = pods_query( "SELECT `" . $related_pod[ 'field_id' ] . "` AS `id` FROM `" . $related_pod[ 'table' ] . "` WHERE {$where} ORDER BY `" . $related_pod[ 'field_id' ] . "`", $this );
8135
+
8136
+ if ( !empty( $result ) )
8137
+ $pick_values[] = $result[ 0 ]->id;
8138
+ }
8139
+ }
8140
+ }
8141
+
8142
+ $field_value = implode( ',', $pick_values );
8143
+ }
8144
+
8145
+ $data[ $field_name ] = $field_value;
8146
+ }
8147
+ }
8148
+
8149
+ if ( !empty( $data ) ) {
8150
+ $params = array(
8151
+ 'pod' => $this->pod,
8152
+ 'data' => $data
8153
+ );
8154
+
8155
+ $ids[] = $this->save_pod_item( $params );
8156
+ }
8157
+ }
8158
+
8159
+ return $ids;
8160
+ }
8161
+
8162
+ /**
8163
+ * Export data from a Pod
8164
+ *
8165
+ * @param string|object $pod The pod name or Pods object
8166
+ * @param array $params An associative array of parameters
8167
+ *
8168
+ * @return array Data arrays of all exported pod items
8169
+ * @since 1.7.1
8170
+ */
8171
+ public function export ( $pod = null, $params = null ) {
8172
+
8173
+ if ( empty( $pod ) ) {
8174
+ $pod = $this->pod;
8175
+ }
8176
+
8177
+ $find = array(
8178
+ 'limit' => -1,
8179
+ 'search' => false,
8180
+ 'pagination' => false
8181
+ );
8182
+
8183
+ if ( !empty( $params ) && isset( $params[ 'params' ] ) ) {
8184
+ $find = array_merge( $find, (array) $params[ 'params' ] );
8185
+
8186
+ unset( $params[ 'params' ] );
8187
+
8188
+ $pod = pods( $pod, $find );
8189
+ }
8190
+ elseif ( !is_object( $pod ) ) {
8191
+ $pod = pods( $pod, $find );
8192
+ }
8193
+
8194
+ $data = array();
8195
+
8196
+ while ( $pod->fetch() ) {
8197
+ $data[ $pod->id() ] = $this->export_pod_item( $params, $pod );
8198
+ }
8199
+
8200
+ $data = $this->do_hook( 'export', $data, $pod->pod, $pod );
8201
+
8202
+ return $data;
8203
+ }
8204
+
8205
+ /**
8206
+ * Convert CSV to a PHP array
8207
+ *
8208
+ * @param string $data The CSV input
8209
+ *
8210
+ * @return array
8211
+ * @since 1.7.1
8212
+ *
8213
+ * @deprecated 2.3.5
8214
+ */
8215
+ public function csv_to_php ( $data, $delimiter = ',' ) {
8216
+ pods_deprecated( "PodsAPI->csv_to_php", '2.3.5' );
8217
+
8218
+ $data = pods_migrate( 'sv', $delimiter, $data )->parse();
8219
+
8220
+ return $data[ 'items' ];
8221
+ }
8222
+
8223
+ /**
8224
+ * Clear Pod-related cache
8225
+ *
8226
+ * @param array $pod
8227
+ *
8228
+ * @return void
8229
+ *
8230
+ * @since 2.0
8231
+ */
8232
+ public function cache_flush_pods ( $pod = null ) {
8233
+ /**
8234
+ * @var $wpdb wpdb
8235
+ */
8236
+ global $wpdb;
8237
+
8238
+ pods_transient_clear( 'pods' );
8239
+ pods_transient_clear( 'pods_components' );
8240
+
8241
+ if ( null !== $pod && is_array( $pod ) ) {
8242
+ pods_transient_clear( 'pods_pod_' . $pod[ 'name' ] );
8243
+ pods_cache_clear( $pod[ 'name' ], 'pods-class' );
8244
+
8245
+ foreach ( $pod[ 'fields' ] as $field ) {
8246
+ pods_transient_clear( 'pods_field_' . $pod[ 'name' ] . '_' . $field[ 'name' ] );
8247
+ }
8248
+
8249
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) )
8250
+ pods_transient_clear( 'pods_wp_cpt_ct' );
8251
+ }
8252
+ else
8253
+ pods_transient_clear( 'pods_wp_cpt_ct' );
8254
+
8255
+ // Delete transients in the database
8256
+ $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_pods%'" );
8257
+ $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_timeout_pods%'" );
8258
+
8259
+ // Delete Pods Options Cache in the database
8260
+ $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_pods_option_%'" );
8261
+
8262
+ pods_cache_clear( true );
8263
+
8264
+ pods_transient_set( 'pods_flush_rewrites', 1 );
8265
+
8266
+ do_action( 'pods_cache_flushed' );
8267
+ }
8268
+
8269
+ /**
8270
+ * Process a Pod-based form
8271
+ *
8272
+ * @param mixed $params
8273
+ * @param object $obj Pod object
8274
+ * @param array $fields Fields being submitted in form ( key => settings )
8275
+ * @param string $thank_you URL to send to upon success
8276
+ *
8277
+ * @return mixed
8278
+ *
8279
+ * @since 2.0
8280
+ */
8281
+ public function process_form ( $params, $obj = null, $fields = null, $thank_you = null ) {
8282
+ $this->display_errors = false;
8283
+
8284
+ $form = null;
8285
+
8286
+ $nonce = pods_var( '_pods_nonce', $params );
8287
+ $pod = pods_var( '_pods_pod', $params );
8288
+ $id = pods_var( '_pods_id', $params );
8289
+ $uri = pods_var( '_pods_uri', $params );
8290
+ $form = pods_var( '_pods_form', $params );
8291
+ $location = pods_var( '_pods_location', $params );
8292
+
8293
+ if ( is_object( $obj ) ) {
8294
+ $pod = $obj->pod;
8295
+ $id = $obj->id();
8296
+ }
8297
+
8298
+ if ( ! empty( $fields ) ) {
8299
+ $fields = array_keys( $fields );
8300
+ $form = implode( ',', $fields );
8301
+ }
8302
+ else
8303
+ $fields = explode( ',', $form );
8304
+
8305
+ if ( empty( $nonce ) || empty( $pod ) || empty( $uri ) || empty( $fields ) )
8306
+ return pods_error( __( 'Invalid submission', 'pods' ), $this );
8307
+
8308
+ $uid = @session_id();
8309
+
8310
+ if ( is_user_logged_in() )
8311
+ $uid = 'user_' . get_current_user_id();
8312
+
8313
+ $field_hash = wp_create_nonce( 'pods_fields_' . $form );
8314
+
8315
+ $action = 'pods_form_' . $pod . '_' . $uid . '_' . $id . '_' . $uri . '_' . $field_hash;
8316
+
8317
+ if ( empty( $uid ) )
8318
+ return pods_error( __( 'Access denied for your session, please refresh and try again.', 'pods' ), $this );
8319
+
8320
+ if ( false === wp_verify_nonce( $nonce, $action ) )
8321
+ return pods_error( __( 'Access denied, please refresh and try again.', 'pods' ), $this );
8322
+
8323
+ $data = array();
8324
+
8325
+ foreach ( $fields as $field ) {
8326
+ $data[ $field ] = pods_var_raw( 'pods_field_' . $field, $params, '' );
8327
+ }
8328
+
8329
+ $params = array(
8330
+ 'pod' => $pod,
8331
+ 'id' => $id,
8332
+ 'data' => $data,
8333
+ 'from' => 'process_form',
8334
+ 'location' => $location
8335
+ );
8336
+
8337
+ $id = $this->save_pod_item( $params );
8338
+
8339
+ // Always return $id for AJAX requests.
8340
+ if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) {
8341
+ if ( 0 < $id && ! empty( $thank_you ) ) {
8342
+ $thank_you = str_replace( 'X_ID_X', $id, $thank_you );
8343
+
8344
+ pods_redirect( $thank_you );
8345
+ }
8346
+ }
8347
+
8348
+ return $id;
8349
+ }
8350
+
8351
+ /**
8352
+ * Get current language information from Multilingual plugins
8353
+ *
8354
+ * @since 2.6.6
8355
+ *
8356
+ * @return array
8357
+ */
8358
+ public static function get_current_language() {
8359
+
8360
+ /**
8361
+ * @var $sitepress SitePress object
8362
+ * @var $polylang object
8363
+ */
8364
+ /*
8365
+ * @todo wpml-comp Remove global object usage
8366
+ */
8367
+ global $sitepress, $polylang;
8368
+
8369
+ $lang_data = false;
8370
+ $translator = false;
8371
+ $current_language = false;
8372
+
8373
+ // Multilingual support
8374
+ if ( did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
8375
+ // WPML support
8376
+ $translator = 'WPML';
8377
+
8378
+ // Get the global current language (if set)
8379
+ $wpml_language = apply_filters( 'wpml_current_language', null );
8380
+ $current_language = ( $wpml_language != 'all' ) ? $wpml_language : '';
8381
+
8382
+ } elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && function_exists( 'pll_current_language' ) ) {
8383
+ // Polylang support
8384
+ $translator = 'PLL';
8385
+
8386
+ // Get the global current language (if set)
8387
+ $current_language = pll_current_language( 'slug' );
8388
+ }
8389
+
8390
+ /**
8391
+ * Admin functions that overwrite the current language
8392
+ *
8393
+ * @since 2.6.6
8394
+ */
8395
+ if ( is_admin() && ! empty( $translator ) ) {
8396
+ if ( $translator == 'PLL' ) {
8397
+ /**
8398
+ * Polylang support
8399
+ * Get the current user's perferred language.
8400
+ * This is a user meta setting that will overwrite the language returned from pll_current_language()
8401
+ * @see polylang/admin/admin-base.php -> init_user()
8402
+ */
8403
+ $current_language = get_user_meta( get_current_user_id(), 'pll_filter_content', true );
8404
+ }
8405
+
8406
+ // Get current language based on the object language if available
8407
+ if ( function_exists( 'get_current_screen' ) ) {
8408
+ $current_screen = get_current_screen();
8409
+
8410
+ /**
8411
+ * Overwrite the current language if needed for post types
8412
+ */
8413
+ if ( isset( $current_screen->base ) && ( $current_screen->base == 'post' || $current_screen->base == 'edit' ) ) {
8414
+ if ( ! empty( $_GET['post'] ) ) {
8415
+ /**
8416
+ * WPML support
8417
+ * In WPML the current language is always set to default on an edit screen
8418
+ * We need to overwrite this when the current object is not-translatable to enable relationships with different languages
8419
+ */
8420
+ if ( $translator == 'WPML'
8421
+ && ! apply_filters( 'wpml_is_translated_post_type', false, ( get_post_type( $_GET['post'] ) ) )
8422
+ ) {
8423
+ // Overwrite the current language to nothing if this is a NOT-translatable post_type
8424
+ $current_language = '';
8425
+ }
8426
+
8427
+ /**
8428
+ * Polylang support (1.5.4+)
8429
+ * In polylang the preferred language could be anything.
8430
+ * We only want the related objects if they are not translatable OR the same language as the current object
8431
+ */
8432
+ if ( $translator == 'PLL'
8433
+ && function_exists( 'pll_get_post_language' )
8434
+ && pll_is_translated_post_type( get_post_type( $_GET['post'] ) )
8435
+ ) {
8436
+ // Overwrite the current language if this is a translateable post_type
8437
+ $current_language = pll_get_post_language( (int) $_GET['post'] );
8438
+ }
8439
+ }
8440
+
8441
+ /**
8442
+ * Polylang support (1.0.1+)
8443
+ * In polylang the preferred language could be anything.
8444
+ * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language
8445
+ */
8446
+ if ( $translator == 'PLL'
8447
+ && ! empty( $_GET['new_lang'] )
8448
+ && ! empty( $_GET['post_type'] )
8449
+ && pll_is_translated_post_type( sanitize_text_field( $_GET['post_type'] ) )
8450
+ ) {
8451
+ $current_language = $_GET['new_lang'];
8452
+ }
8453
+
8454
+ /**
8455
+ * Overwrite the current language if needed for taxonomies
8456
+ */
8457
+ } elseif ( isset( $current_screen->base ) && ( $current_screen->base == 'term' || $current_screen->base == 'edit-tags' ) ) {
8458
+ // @todo MAYBE: Similar function like get_post_type for taxonomies so we don't need to check for $_GET['taxonomy']
8459
+ if ( ! empty( $_GET['taxonomy'] ) ) {
8460
+ /*
8461
+ * @todo wpml-comp API call for taxonomy needed!
8462
+ * Suggested API call:
8463
+ * add_filter( 'wpml_is_translated_taxonomy', $_GET['taxonomy'], 10, 2 );
8464
+ */
8465
+ /**
8466
+ * WPML support
8467
+ * In WPML the current language is always set to default on an edit screen
8468
+ * We need to overwrite this when the current object is not-translatable to enable relationships with different languages
8469
+ */
8470
+ if ( $translator == 'WPML'
8471
+ && method_exists( $sitepress, 'is_translated_taxonomy')
8472
+ && ! $sitepress->is_translated_taxonomy( $_GET['taxonomy'] )
8473
+ ) {
8474
+ // Overwrite the current language to nothing if this is a NOT-translatable taxonomy
8475
+ $current_language = '';
8476
+ }
8477
+
8478
+ /**
8479
+ * Polylang support (1.5.4+)
8480
+ * In polylang the preferred language could be anything.
8481
+ * We only want the related objects if they are not translatable OR the same language as the current object
8482
+ */
8483
+ if ( $translator == 'PLL'
8484
+ && ! empty( $_GET['tag_ID'] )
8485
+ && function_exists( 'pll_get_term_language' )
8486
+ && pll_is_translated_taxonomy( sanitize_text_field( $_GET['taxonomy'] ) )
8487
+ ) {
8488
+ // Overwrite the current language if this is a translatable taxonomy
8489
+ $current_language = pll_get_term_language( (int) $_GET['tag_ID'] );
8490
+ }
8491
+ }
8492
+
8493
+ /**
8494
+ * Polylang support (1.0.1+)
8495
+ * In polylang the preferred language could be anything.
8496
+ * When we're adding a new object and language is set we only want the related objects if they are not translatable OR the same language
8497
+ */
8498
+ if ( $translator == 'PLL'
8499
+ && ! empty( $_GET['new_lang'] )
8500
+ && ! empty( $_GET['taxonomy'] )
8501
+ && pll_is_translated_taxonomy( sanitize_text_field( $_GET['taxonomy'] ) )
8502
+ ) {
8503
+ $current_language = $_GET['new_lang'];
8504
+ }
8505
+ }
8506
+ }
8507
+ }
8508
+
8509
+ $current_language = pods_sanitize( sanitize_text_field( $current_language ) );
8510
+
8511
+ if ( ! empty( $current_language ) ) {
8512
+ // We need to return language data
8513
+ $lang_data = array(
8514
+ 'language' => $current_language,
8515
+ 't_id' => 0,
8516
+ 'tt_id' => 0,
8517
+ 'term' => null,
8518
+ );
8519
+
8520
+ /**
8521
+ * Polylang support
8522
+ * Get the language taxonomy object for the current language
8523
+ */
8524
+ if ( $translator == 'PLL' ) {
8525
+ $current_language_t = false;
8526
+
8527
+ // Get the language term object
8528
+ if ( function_exists( 'PLL' ) && isset( PLL()->model ) && method_exists( PLL()->model, 'get_language' ) ) {
8529
+ // Polylang 1.8 and newer
8530
+ $current_language_t = PLL()->model->get_language( $current_language );
8531
+ } elseif ( is_object( $polylang ) && isset( $polylang->model ) && method_exists( $polylang->model, 'get_language' ) ) {
8532
+ // Polylang 1.2 - 1.7.x
8533
+ $current_language_t = $polylang->model->get_language( $current_language );
8534
+ } elseif ( is_object( $polylang ) && method_exists( $polylang, 'get_language' ) ) {
8535
+ // Polylang 1.1.x and older
8536
+ $current_language_t = $polylang->get_language( $current_language );
8537
+ }
8538
+
8539
+ // If the language object exists, add it!
8540
+ if ( $current_language_t && ! empty( $current_language_t->term_id ) ) {
8541
+ $lang_data['t_id'] = (int) $current_language_t->term_id;
8542
+ $lang_data['tt_id'] = (int) $current_language_t->term_taxonomy_id;
8543
+ $lang_data['tl_t_id'] = (int) $current_language_t->tl_term_id;
8544
+ $lang_data['tl_tt_id'] = (int) $current_language_t->tl_term_taxonomy_id;
8545
+ $lang_data['term'] = $current_language_t;
8546
+ }
8547
+ }
8548
+ }
8549
+
8550
+ /**
8551
+ * Override language data used by Pods.
8552
+ *
8553
+ * @since 2.6.6
8554
+ *
8555
+ * @param array|false $lang_data {
8556
+ * Language data
8557
+ *
8558
+ * @type string $language Language slug
8559
+ * @type int $t_id Language term_id
8560
+ * @type int $tt_id Language term_taxonomy_id
8561
+ * @type WP_Term $term Language term object
8562
+ * }
8563
+ * @param string|boolean $translator Language plugin used
8564
+ */
8565
+ $lang_data = apply_filters( 'pods_get_current_language', $lang_data, $translator );
8566
+
8567
+ return $lang_data;
8568
+
8569
+ }
8570
+
8571
+ /**
8572
+ * Handle filters / actions for the class
8573
+ *
8574
+ * @since 2.0
8575
+ */
8576
+ private function do_hook () {
8577
+ $args = func_get_args();
8578
+ if ( empty( $args ) )
8579
+ return false;
8580
+ $name = array_shift( $args );
8581
+ return pods_do_hook( "api", $name, $args, $this );
8582
+ }
8583
+
8584
+ /**
8585
+ * Handle variables that have been deprecated
8586
+ *
8587
+ * @since 2.0
8588
+ */
8589
+ public function __get ( $name ) {
8590
+ $name = (string) $name;
8591
+
8592
+ if ( !isset( $this->deprecated ) ) {
8593
+ require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8594
+ $this->deprecated = new PodsAPI_Deprecated( $this );
8595
+ }
8596
+
8597
+ $var = null;
8598
+
8599
+ if ( isset( $this->deprecated->{$name} ) ) {
8600
+ pods_deprecated( "PodsAPI->{$name}", '2.0' );
8601
+
8602
+ $var = $this->deprecated->{$name};
8603
+ }
8604
+ else
8605
+ pods_deprecated( "PodsAPI->{$name}", '2.0' );
8606
+
8607
+ return $var;
8608
+ }
8609
+
8610
+ /**
8611
+ * Handle methods that have been deprecated
8612
+ *
8613
+ * @since 2.0
8614
+ */
8615
+ public function __call ( $name, $args ) {
8616
+ $name = (string) $name;
8617
+
8618
+ if ( !isset( $this->deprecated ) ) {
8619
+ require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
8620
+ $this->deprecated = new PodsAPI_Deprecated( $this );
8621
+ }
8622
+
8623
+ if ( method_exists( $this->deprecated, $name ) )
8624
+ return call_user_func_array( array( $this->deprecated, $name ), $args );
8625
+ else
8626
+ pods_deprecated( "PodsAPI::{$name}", '2.0' );
8627
+ }
8628
+
8629
+ /**
8630
+ * Filter an array of arrays without causing PHP notices/warnings.
8631
+ *
8632
+ * @param array $values
8633
+ *
8634
+ * @return array
8635
+ *
8636
+ * @since 2.6.10
8637
+ */
8638
+ private function array_filter_walker( $values = array() ) {
8639
+
8640
+ $values = (array) $values;
8641
+
8642
+ foreach ( $values as $k => $v ){
8643
+ if ( is_object( $v ) ) {
8644
+ // Skip objects
8645
+ continue;
8646
+ } elseif ( is_array( $v ) ){
8647
+ if ( empty( $v ) ) {
8648
+ // Filter values with empty arrays
8649
+ unset( $values[ $k ] );
8650
+ }
8651
+ } else {
8652
+ if ( ! $v ) {
8653
+ // Filter empty values
8654
+ unset( $values[ $k ] );
8655
+ }
8656
+ }
8657
+ }
8658
+
8659
+ return $values;
8660
+
8661
+ }
8662
+
8663
+ }
classes/PodsAdmin.php ADDED
@@ -0,0 +1,2843 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Pods
4
+ */
5
+ class PodsAdmin {
6
+
7
+ /**
8
+ * @var PodsAdmin
9
+ */
10
+ static $instance = null;
11
+
12
+ /**
13
+ * Singleton handling for a basic pods_admin() request
14
+ *
15
+ * @return \PodsAdmin
16
+ *
17
+ * @since 2.3.5
18
+ */
19
+ public static function init () {
20
+ if ( !is_object( self::$instance ) )
21
+ self::$instance = new PodsAdmin();
22
+
23
+ return self::$instance;
24
+ }
25
+
26
+ /**
27
+ * Setup and Handle Admin functionality
28
+ *
29
+ * @return \PodsAdmin
30
+ *
31
+ * @license http://www.gnu.org/licenses/gpl-2.0.html
32
+ * @since 2.0
33
+ */
34
+ public function __construct () {
35
+ // Scripts / Stylesheets
36
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_head' ), 20 );
37
+
38
+ // AJAX $_POST fix
39
+ add_action( 'admin_init', array( $this, 'admin_init' ), 9 );
40
+
41
+ // Menus
42
+ add_action( 'admin_menu', array( $this, 'admin_menu' ), 99 );
43
+
44
+ // AJAX for Admin
45
+ add_action( 'wp_ajax_pods_admin', array( $this, 'admin_ajax' ) );
46
+ add_action( 'wp_ajax_nopriv_pods_admin', array( $this, 'admin_ajax' ) );
47
+
48
+ // Add Media Bar button for Shortcode
49
+ add_action( 'media_buttons', array( $this, 'media_button' ), 12 );
50
+
51
+ // Add the Pods capabilities
52
+ add_filter( 'members_get_capabilities', array( $this, 'admin_capabilities' ) );
53
+
54
+ add_action( 'admin_head-media-upload-popup', array( $this, 'register_media_assets' ) );
55
+
56
+ $this->rest_admin();
57
+
58
+ }
59
+
60
+ /**
61
+ * Init the admin area
62
+ *
63
+ * @since 2.0
64
+ */
65
+ public function admin_init () {
66
+ // Fix for plugins that *don't do it right* so we don't cause issues for users
67
+ if ( defined( 'DOING_AJAX' ) && !empty( $_POST ) ) {
68
+ $pods_admin_ajax_actions = array(
69
+ 'pods_admin',
70
+ 'pods_relationship',
71
+ 'pods_upload',
72
+ 'pods_admin_components'
73
+ );
74
+
75
+ /**
76
+ * Admin AJAX Callbacks
77
+ *
78
+ * @since unknown
79
+ *
80
+ * @param array $pods_admin_ajax_actions Array of actions to handle
81
+ */
82
+ $pods_admin_ajax_actions = apply_filters( 'pods_admin_ajax_actions', $pods_admin_ajax_actions );
83
+
84
+ if ( in_array( pods_var( 'action', 'get' ), $pods_admin_ajax_actions ) || in_array( pods_var( 'action', 'post' ), $pods_admin_ajax_actions ) ) {
85
+ foreach ( $_POST as $key => $value ) {
86
+ if ( 'action' == $key || 0 === strpos( $key, '_podsfix_' ) )
87
+ continue;
88
+
89
+ unset( $_POST[ $key ] );
90
+
91
+ $_POST[ '_podsfix_' . $key ] = $value;
92
+ }
93
+ }
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Attach requirements to admin header
99
+ *
100
+ * @since 2.0
101
+ */
102
+ public function admin_head () {
103
+ wp_register_style( 'pods-admin', PODS_URL . 'ui/css/pods-admin.css', array(), PODS_VERSION );
104
+
105
+ wp_register_style( 'pods-font', PODS_URL . 'ui/css/pods-font.css', array(), PODS_VERSION );
106
+
107
+ wp_register_script( 'pods-floatmenu', PODS_URL . 'ui/js/floatmenu.js', array(), PODS_VERSION );
108
+
109
+ wp_register_script( 'pods-admin-importer', PODS_URL . 'ui/js/admin-importer.js', array(), PODS_VERSION );
110
+
111
+ wp_register_style( 'pods-manage', PODS_URL . 'ui/css/pods-manage.css', array(), PODS_VERSION );
112
+
113
+ wp_register_style( 'pods-wizard', PODS_URL . 'ui/css/pods-wizard.css', array(), PODS_VERSION );
114
+
115
+ wp_register_script( 'pods-upgrade', PODS_URL . 'ui/js/jquery.pods.upgrade.js', array(), PODS_VERSION );
116
+
117
+ wp_register_script( 'pods-migrate', PODS_URL . 'ui/js/jquery.pods.migrate.js', array(), PODS_VERSION );
118
+
119
+ if ( isset( $_GET[ 'page' ] ) ) {
120
+ $page = $_GET[ 'page' ];
121
+ if ( 'pods' == $page || ( false !== strpos( $page, 'pods-' ) && 0 === strpos( $page, 'pods-' ) ) ) {
122
+ ?>
123
+ <script type="text/javascript">
124
+ var PODS_URL = "<?php echo esc_js( PODS_URL ); ?>";
125
+ </script>
126
+ <?php
127
+ wp_enqueue_script( 'jquery' );
128
+ wp_enqueue_script( 'jquery-ui-core' );
129
+ wp_enqueue_script( 'jquery-ui-sortable' );
130
+
131
+ wp_enqueue_style( 'jquery-ui' );
132
+
133
+ wp_enqueue_script( 'pods-floatmenu' );
134
+
135
+ wp_enqueue_style( 'jquery-qtip2' );
136
+ wp_enqueue_script( 'jquery-qtip2' );
137
+ wp_enqueue_script( 'pods-qtip-init' );
138
+
139
+ wp_enqueue_script( 'pods' );
140
+
141
+ if ( 0 === strpos( $page, 'pods-manage-' ) || 0 === strpos( $page, 'pods-add-new-' ) )
142
+ wp_enqueue_script( 'post' );
143
+ elseif ( 0 === strpos( $page, 'pods-settings-' ) ) {
144
+ wp_enqueue_script( 'post' );
145
+ wp_enqueue_style( 'pods-admin' );
146
+ }
147
+ else
148
+ wp_enqueue_style( 'pods-admin' );
149
+
150
+ if ( 'pods-advanced' == $page ) {
151
+ wp_register_style( 'pods-advanced', PODS_URL . 'ui/css/pods-advanced.css', array(), '1.0' );
152
+ wp_enqueue_style( 'pods-advanced' );
153
+
154
+ wp_enqueue_script( 'jquery-ui-effects-core', PODS_URL . 'ui/js/jquery-ui/jquery.effects.core.js', array( 'jquery' ), '1.8.8' );
155
+ wp_enqueue_script( 'jquery-ui-effects-fade', PODS_URL . 'ui/js/jquery-ui/jquery.effects.fade.js', array( 'jquery' ), '1.8.8' );
156
+ wp_enqueue_script( 'jquery-ui-dialog' );
157
+
158
+ wp_register_script( 'pods-advanced', PODS_URL . 'ui/js/advanced.js', array(), PODS_VERSION );
159
+ wp_enqueue_script( 'pods-advanced' );
160
+ }
161
+ elseif ( 'pods-packages' == $page )
162
+ wp_enqueue_style( 'pods-wizard' );
163
+ elseif ( 'pods-wizard' == $page || 'pods-upgrade' == $page || ( in_array( $page, array( 'pods', 'pods-add-new' ) ) && in_array( pods_var( 'action', 'get', 'manage' ), array( 'add', 'manage' ) ) ) ) {
164
+ wp_enqueue_style( 'pods-wizard' );
165
+
166
+ if ( 'pods-upgrade' == $page )
167
+ wp_enqueue_script( 'pods-upgrade' );
168
+ }
169
+ }
170
+ }
171
+
172
+ wp_enqueue_style( 'pods-font' );
173
+ }
174
+
175
+ /**
176
+ * Build the admin menus
177
+ *
178
+ * @since 2.0
179
+ */
180
+ public function admin_menu () {
181
+ $advanced_content_types = PodsMeta::$advanced_content_types;
182
+ $taxonomies = PodsMeta::$taxonomies;
183
+ $settings = PodsMeta::$settings;
184
+
185
+ $all_pods = pods_api()->load_pods( array( 'count' => true ) );
186
+
187
+ if ( !PodsInit::$upgrade_needed || ( pods_is_admin() && 1 == pods_var( 'pods_upgrade_bypass' ) ) ) {
188
+ $submenu_items = array();
189
+
190
+ if ( !empty( $advanced_content_types ) ) {
191
+ $submenu = array();
192
+
193
+ $pods_pages = 0;
194
+
195
+ foreach ( (array) $advanced_content_types as $pod ) {
196
+ if ( !isset( $pod[ 'name' ] ) || !isset( $pod[ 'options' ] ) || empty( $pod[ 'fields' ] ) )
197
+ continue;
198
+ elseif ( !pods_is_admin( array( 'pods', 'pods_content', 'pods_add_' . $pod[ 'name' ], 'pods_edit_' . $pod[ 'name' ], 'pods_delete_' . $pod[ 'name' ] ) ) )
199
+ continue;
200
+
201
+ if ( 1 == pods_var( 'show_in_menu', $pod[ 'options' ], 0 ) ) {
202
+ $page_title = pods_var_raw( 'label', $pod, ucwords( str_replace( '_', ' ', $pod[ 'name' ] ) ), null, true );
203
+ $page_title = apply_filters( 'pods_admin_menu_page_title', $page_title, $pod );
204
+
205
+ $menu_label = pods_var_raw( 'menu_name', $pod[ 'options' ], $page_title, null, true );
206
+ $menu_label = apply_filters( 'pods_admin_menu_label', $menu_label, $pod );
207
+
208
+ $singular_label = pods_var_raw( 'label_singular', $pod[ 'options' ], pods_var_raw( 'label', $pod, ucwords( str_replace( '_', ' ', $pod[ 'name' ] ) ), null, true ), null, true );
209
+ $plural_label = pods_var_raw( 'label', $pod, ucwords( str_replace( '_', ' ', $pod[ 'name' ] ) ), null, true );
210
+
211
+ $menu_location = pods_var( 'menu_location', $pod[ 'options' ], 'objects' );
212
+ $menu_location_custom = pods_var( 'menu_location_custom', $pod[ 'options' ], '' );
213
+
214
+ $menu_position = pods_var_raw( 'menu_position', $pod[ 'options' ], '', null, true );
215
+ $menu_icon = pods_evaluate_tags( pods_var_raw( 'menu_icon', $pod[ 'options' ], '', null, true ), true );
216
+
217
+ if ( empty( $menu_position ) )
218
+ $menu_position = null;
219
+
220
+ $parent_page = null;
221
+
222
+ if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $pod[ 'name' ], 'pods_delete_' . $pod[ 'name' ] ) ) ) {
223
+ if ( !empty( $menu_location_custom ) ) {
224
+ if ( !isset( $submenu_items[ $menu_location_custom ] ) )
225
+ $submenu_items[ $menu_location_custom ] = array();
226
+
227
+ $submenu_items[ $menu_location_custom ][] = array( $menu_location_custom, $page_title, $menu_label, 'read', 'pods-manage-' . $pod[ 'name' ], array( $this, 'admin_content' ) );
228
+
229
+ continue;
230
+ }
231
+ else {
232
+ $pods_pages++;
233
+
234
+ $parent_page = $page = 'pods-manage-' . $pod[ 'name' ];
235
+
236
+ if ( empty( $menu_position ) )
237
+ $menu_position = null;
238
+ add_menu_page( $page_title, $menu_label, 'read', $parent_page, '', $menu_icon, $menu_position );
239
+
240
+ $all_title = $plural_label;
241
+ $all_label = __( 'All', 'pods' ) . ' ' . $plural_label;
242
+
243
+ if ( $page == pods_var( 'page', 'get' ) ) {
244
+ if ( 'edit' == pods_var( 'action', 'get', 'manage' ) )
245
+ $all_title = __( 'Edit', 'pods' ) . ' ' . $singular_label;
246
+ elseif ( 'add' == pods_var( 'action', 'get', 'manage' ) )
247
+ $all_title = __( 'Add New', 'pods' ) . ' ' . $singular_label;
248
+ }
249
+
250
+ add_submenu_page( $parent_page, $all_title, $all_label, 'read', $page, array( $this, 'admin_content' ) );
251
+ }
252
+ }
253
+
254
+ if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_add_' . $pod[ 'name' ] ) ) ) {
255
+ $page = 'pods-add-new-' . $pod[ 'name' ];
256
+
257
+ if ( null === $parent_page ) {
258
+ $pods_pages++;
259
+
260
+ $parent_page = $page;
261
+
262
+ if ( empty( $menu_position ) )
263
+ $menu_position = null;
264
+ add_menu_page( $page_title, $menu_label, 'read', $parent_page, '', $menu_icon, $menu_position );
265
+ }
266
+
267
+ $add_title = __( 'Add New', 'pods' ) . ' ' . $singular_label;
268
+ $add_label = __( 'Add New', 'pods' );
269
+
270
+ add_submenu_page( $parent_page, $add_title, $add_label, 'read', $page, array( $this, 'admin_content' ) );
271
+ }
272
+ }
273
+ else
274
+ $submenu[] = $pod;
275
+ }
276
+
277
+ $submenu = apply_filters( 'pods_admin_menu_secondary_content', $submenu );
278
+
279
+ if ( !empty( $submenu ) && ( !defined( 'PODS_DISABLE_CONTENT_MENU' ) || !PODS_DISABLE_CONTENT_MENU ) ) {
280
+ $parent_page = null;
281
+
282
+ foreach ( $submenu as $item ) {
283
+ $singular_label = pods_var_raw( 'label_singular', $item[ 'options' ], pods_var_raw( 'label', $item, ucwords( str_replace( '_', ' ', $item[ 'name' ] ) ), null, true ), null, true );
284
+ $plural_label = pods_var_raw( 'label', $item, ucwords( str_replace( '_', ' ', $item[ 'name' ] ) ), null, true );
285
+
286
+ if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $item[ 'name' ], 'pods_delete_' . $item[ 'name' ] ) ) ) {
287
+ $page = 'pods-manage-' . $item[ 'name' ];
288
+
289
+ if ( null === $parent_page ) {
290
+ $parent_page = $page;
291
+
292
+ add_menu_page( 'Pods', 'Pods', 'read', $parent_page, null, 'dashicons-pods', '58.5' );
293
+ }
294
+
295
+ $all_title = $plural_label;
296
+ $all_label = __( 'Manage', 'pods' ) . ' ' . $plural_label;
297
+
298
+ if ( $page == pods_var( 'page', 'get' ) ) {
299
+ if ( 'edit' == pods_var( 'action', 'get', 'manage' ) )
300
+ $all_title = __( 'Edit', 'pods' ) . ' ' . $singular_label;
301
+ elseif ( 'add' == pods_var( 'action', 'get', 'manage' ) )
302
+ $all_title = __( 'Add New', 'pods' ) . ' ' . $singular_label;
303
+ }
304
+
305
+ add_submenu_page( $parent_page, $all_title, $all_label, 'read', $page, array( $this, 'admin_content' ) );
306
+ }
307
+ elseif ( current_user_can( 'pods_add_' . $item[ 'name' ] ) ) {
308
+ $page = 'pods-add-new-' . $item[ 'name' ];
309
+
310
+ if ( null === $parent_page ) {
311
+ $parent_page = $page;
312
+
313
+ add_menu_page( 'Pods', 'Pods', 'read', $parent_page, null, 'dashicons-pods', '58.5' );
314
+ }
315
+
316
+ $add_title = __( 'Add New', 'pods' ) . ' ' . $singular_label;
317
+ $add_label = __( 'Manage', 'pods' ) . ' ' . $plural_label;
318
+
319
+ add_submenu_page( $parent_page, $add_title, $add_label, 'read', $page, array( $this, 'admin_content' ) );
320
+ }
321
+ }
322
+ }
323
+ }
324
+
325
+ if ( !empty( $taxonomies ) ) {
326
+ foreach ( (array) $taxonomies as $pod ) {
327
+ // Default taxonomy capability
328
+ $capability = 'manage_categories';
329
+
330
+ if ( ! empty( $pod[ 'options' ][ 'capability_type' ] ) ) {
331
+ if ( 'custom' == $pod[ 'options' ][ 'capability_type' ] && ! empty( $pod[ 'options' ][ 'capability_type_custom' ] ) ) {
332
+ $capability = 'manage_' . (string) $pod[ 'options' ][ 'capability_type_custom' ] . '_terms';
333
+ }
334
+ }
335
+
336
+ if ( !pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $pod[ 'name' ], $capability ) ) )
337
+ continue;
338
+
339
+ // Check UI settings
340
+ if ( 1 != pods_var( 'show_ui', $pod[ 'options' ], 0 ) || 1 != pods_var( 'show_in_menu', $pod[ 'options' ], 0 ) )
341
+ continue;
342
+
343
+ $page_title = pods_var_raw( 'label', $pod, ucwords( str_replace( '_', ' ', $pod[ 'name' ] ) ), null, true );
344
+ $page_title = apply_filters( 'pods_admin_menu_page_title', $page_title, $pod );
345
+
346
+ $menu_label = pods_var_raw( 'menu_name', $pod[ 'options' ], $page_title, null, true );
347
+ $menu_label = apply_filters( 'pods_admin_menu_label', $menu_label, $pod );
348
+
349
+ $menu_position = pods_var_raw( 'menu_position', $pod[ 'options' ], '', null, true );
350
+ $menu_icon = pods_evaluate_tags( pods_var_raw( 'menu_icon', $pod[ 'options' ], '', null, true ), true );
351
+
352
+ if ( empty( $menu_position ) )
353
+ $menu_position = null;
354
+
355
+ $menu_slug = 'edit-tags.php?taxonomy=' . $pod[ 'name' ];
356
+ $menu_location = pods_var( 'menu_location', $pod[ 'options' ], 'default' );
357
+ $menu_location_custom = pods_var( 'menu_location_custom', $pod[ 'options' ], '' );
358
+
359
+ if ( 'default' == $menu_location )
360
+ continue;
361
+
362
+ $taxonomy_data = get_taxonomy( $pod[ 'name' ] );
363
+
364
+ foreach ( (array) $taxonomy_data->object_type as $post_type ) {
365
+ if ( 'post' == $post_type )
366
+ remove_submenu_page( 'edit.php', 'edit-tags.php?taxonomy=' . $pod[ 'name' ] );
367
+ elseif ( 'attachment' == $post_type )
368
+ remove_submenu_page( 'upload.php', 'edit-tags.php?taxonomy=' . $pod[ 'name' ] . '&amp;post_type=' . $post_type );
369
+ else
370
+ remove_submenu_page( 'edit.php?post_type=' . $post_type, 'edit-tags.php?taxonomy=' . $pod[ 'name' ] . '&amp;post_type=' . $post_type );
371
+ }
372
+
373
+ if ( 'settings' == $menu_location )
374
+ add_options_page( $page_title, $menu_label, 'read', $menu_slug );
375
+ elseif ( 'appearances' == $menu_location )
376
+ add_theme_page( $page_title, $menu_label, 'read', $menu_slug );
377
+ elseif ( 'objects' == $menu_location ) {
378
+ if ( empty( $menu_position ) )
379
+ $menu_position = null;
380
+ add_menu_page( $page_title, $menu_label, 'read', $menu_slug, '', $menu_icon, $menu_position );
381
+ }
382
+ elseif ( 'top' == $menu_location )
383
+ add_menu_page( $page_title, $menu_label, 'read', $menu_slug, '', $menu_icon, $menu_position );
384
+ elseif ( 'submenu' == $menu_location && !empty( $menu_location_custom ) ) {
385
+ if ( !isset( $submenu_items[ $menu_location_custom ] ) )
386
+ $submenu_items[ $menu_location_custom ] = array();
387
+
388
+ $submenu_items[ $menu_location_custom ][] = array( $menu_location_custom, $page_title, $menu_label, 'read', $menu_slug, '' );
389
+ }
390
+ }
391
+ }
392
+
393
+ if ( !empty( $settings ) ) {
394
+ foreach ( (array) $settings as $pod ) {
395
+ if ( !pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $pod[ 'name' ] ) ) )
396
+ continue;
397
+
398
+ $page_title = pods_var_raw( 'label', $pod, ucwords( str_replace( '_', ' ', $pod[ 'name' ] ) ), null, true );
399
+ $page_title = apply_filters( 'pods_admin_menu_page_title', $page_title, $pod );
400
+
401
+ $menu_label = pods_var_raw( 'menu_name', $pod[ 'options' ], $page_title, null, true );
402
+ $menu_label = apply_filters( 'pods_admin_menu_label', $menu_label, $pod );
403
+
404
+ $menu_position = pods_var_raw( 'menu_position', $pod[ 'options' ], '', null, true );
405
+ $menu_icon = pods_evaluate_tags( pods_var_raw( 'menu_icon', $pod[ 'options' ], '', null, true ), true );
406
+
407
+ if ( empty( $menu_position ) )
408
+ $menu_position = null;
409
+
410
+ $menu_slug = 'pods-settings-' . $pod[ 'name' ];
411
+ $menu_location = pods_var( 'menu_location', $pod[ 'options' ], 'settings' );
412
+ $menu_location_custom = pods_var( 'menu_location_custom', $pod[ 'options' ], '' );
413
+
414
+ if ( 'settings' == $menu_location )
415
+ add_options_page( $page_title, $menu_label, 'read', $menu_slug, array( $this, 'admin_content_settings' ) );
416
+ elseif ( 'appearances' == $menu_location )
417
+ add_theme_page( $page_title, $menu_label, 'read', $menu_slug, array( $this, 'admin_content_settings' ) );
418
+ elseif ( 'objects' == $menu_location ) {
419
+ if ( empty( $menu_position ) )
420
+ $menu_position = null;
421
+ add_menu_page( $page_title, $menu_label, 'read', $menu_slug, array( $this, 'admin_content_settings' ), $menu_icon, $menu_position );
422
+ }
423
+ elseif ( 'top' == $menu_location )
424
+ add_menu_page( $page_title, $menu_label, 'read', $menu_slug, array( $this, 'admin_content_settings' ), $menu_icon, $menu_position );
425
+ elseif ( 'submenu' == $menu_location && !empty( $menu_location_custom ) ) {
426
+ if ( !isset( $submenu_items[ $menu_location_custom ] ) )
427
+ $submenu_items[ $menu_location_custom ] = array();
428
+
429
+ $submenu_items[ $menu_location_custom ][] = array( $menu_location_custom, $page_title, $menu_label, 'read', $menu_slug, array( $this, 'admin_content_settings' ) );
430
+ }
431
+ }
432
+ }
433
+
434
+ foreach ( $submenu_items as $items ) {
435
+ foreach ( $items as $item ) {
436
+ call_user_func_array( 'add_submenu_page', $item );
437
+ }
438
+ }
439
+
440
+ $admin_menus = array(
441
+ 'pods' => array(
442
+ 'label' => __( 'Edit Pods', 'pods' ),
443
+ 'function' => array( $this, 'admin_setup' ),
444
+ 'access' => 'pods'
445
+ ),
446
+ 'pods-add-new' => array(
447
+ 'label' => __( 'Add New', 'pods' ),
448
+ 'function' => array( $this, 'admin_setup' ),
449
+ 'access' => 'pods'
450
+ ),
451
+ 'pods-components' => array(
452
+ 'label' => __( 'Components', 'pods' ),
453
+ 'function' => array( $this, 'admin_components' ),
454
+ 'access' => 'pods_components'
455
+ ),
456
+ 'pods-settings' => array(
457
+ 'label' => __( 'Settings', 'pods' ),
458
+ 'function' => array( $this, 'admin_settings' ),
459
+ 'access' => 'pods_settings'
460
+ ),
461
+ 'pods-help' => array(
462
+ 'label' => __( 'Help', 'pods' ),
463
+ 'function' => array( $this, 'admin_help' )
464
+ )
465
+ );
466
+
467
+ if ( empty( $all_pods ) )
468
+ unset( $admin_menus[ 'pods' ] );
469
+
470
+ add_filter( 'parent_file' , array( $this, 'parent_file' ) );
471
+ }
472
+ else {
473
+ $admin_menus = array(
474
+ 'pods-upgrade' => array(
475
+ 'label' => __( 'Upgrade', 'pods' ),
476
+ 'function' => array( $this, 'admin_upgrade' ),
477
+ 'access' => 'manage_options'
478
+ ),
479
+ 'pods-settings' => array(
480
+ 'label' => __( 'Settings', 'pods' ),
481
+ 'function' => array( $this, 'admin_settings' ),
482
+ 'access' => 'pods_settings'
483
+ ),
484
+ 'pods-help' => array(
485
+ 'label' => __( 'Help', 'pods' ),
486
+ 'function' => array( $this, 'admin_help' )
487
+ )
488
+ );
489
+
490
+ add_action( 'admin_notices', array( $this, 'upgrade_notice' ) );
491
+ }
492
+
493
+ /**
494
+ * Add or change Pods Admin menu items
495
+ *
496
+ * @params array $admin_menus The submenu items in Pods Admin menu.
497
+ *
498
+ * @since unknown
499
+ */
500
+ $admin_menus = apply_filters( 'pods_admin_menu', $admin_menus );
501
+
502
+ $parent = false;
503
+
504
+ // PODS_LIGHT disables all Pods components so remove the components menu
505
+ if ( defined( 'PODS_LIGHT' ) && true == PODS_LIGHT ) {
506
+ unset( $admin_menus['pods-components'] );
507
+ }
508
+
509
+ if ( !empty( $admin_menus ) && ( !defined( 'PODS_DISABLE_ADMIN_MENU' ) || !PODS_DISABLE_ADMIN_MENU ) ) {
510
+ foreach ( $admin_menus as $page => $menu_item ) {
511
+ if ( !pods_is_admin( pods_var_raw( 'access', $menu_item ) ) )
512
+ continue;
513
+
514
+ // Don't just show the help page
515
+ if ( false === $parent && 'pods-help' == $page )
516
+ continue;
517
+
518
+ if ( !isset( $menu_item[ 'label' ] ) )
519
+ $menu_item[ 'label' ] = $page;
520
+
521
+ if ( false === $parent ) {
522
+ $parent = $page;
523
+
524
+ $menu = __( 'Pods Admin', 'pods' );
525
+
526
+ if ( 'pods-upgrade' == $parent )
527
+ $menu = __( 'Pods Upgrade', 'pods' );
528
+
529
+ add_menu_page( $menu, $menu, 'read', $parent, null, 'dashicons-pods' );
530
+ }
531
+
532
+ add_submenu_page( $parent, $menu_item[ 'label' ], $menu_item[ 'label' ], 'read', $page, $menu_item[ 'function' ] );
533
+
534
+ if ( 'pods-components' == $page && is_object( PodsInit::$components ) )
535
+ PodsInit::$components->menu( $parent );
536
+ }
537
+ }
538
+ }
539
+
540
+ /**
541
+ * Set the correct parent_file to highlight the correct top level menu
542
+ *
543
+ * @param $parent_file The parent file
544
+ *
545
+ * @return mixed|string
546
+ *
547
+ * @since unknown
548
+ */
549
+ public function parent_file ( $parent_file ) {
550
+ global $current_screen;
551
+
552
+ if ( isset( $current_screen ) && ! empty( $current_screen->taxonomy ) ) {
553
+ $taxonomies = PodsMeta::$taxonomies;
554
+ if ( !empty( $taxonomies ) ) {
555
+ foreach ( (array) $taxonomies as $pod ) {
556
+ if ( $current_screen->taxonomy !== $pod[ 'name' ] )
557
+ continue;
558
+
559
+ $menu_slug = 'edit-tags.php?taxonomy=' . $pod[ 'name' ];
560
+ $menu_location = pods_var( 'menu_location', $pod[ 'options' ], 'default' );
561
+ $menu_location_custom = pods_var( 'menu_location_custom', $pod[ 'options' ], '' );
562
+
563
+ if ( 'settings' == $menu_location )
564
+ $parent_file = 'options-general.php';
565
+ elseif ( 'appearances' == $menu_location )
566
+ $parent_file = 'themes.php';
567
+ elseif ( 'objects' == $menu_location )
568
+ $parent_file = $menu_slug;
569
+ elseif ( 'top' == $menu_location )
570
+ $parent_file = $menu_slug;
571
+ elseif ( 'submenu' == $menu_location && !empty( $menu_location_custom ) ) {
572
+ $parent_file = $menu_location_custom;
573
+ }
574
+
575
+ break;
576
+ }
577
+ }
578
+ }
579
+
580
+ if ( isset( $current_screen ) && ! empty( $current_screen->post_type ) && is_object( PodsInit::$components ) ) {
581
+ global $submenu_file;
582
+ $components = PodsInit::$components->components;
583
+ foreach ( $components as $component => $component_data ) {
584
+ if ( ! empty( $component_data[ 'MenuPage' ] ) && $parent_file === $component_data[ 'MenuPage' ] ) {
585
+ $parent_file = 'pods';
586
+ $submenu_file = $component_data[ 'MenuPage' ];
587
+ }
588
+ }
589
+ }
590
+
591
+ return $parent_file;
592
+ }
593
+
594
+ public function upgrade_notice () {
595
+ echo '<div class="error fade"><p>';
596
+ echo sprintf(
597
+ __( '<strong>NOTICE:</strong> Pods %s requires your action to complete the upgrade. Please run the <a href="%s">Upgrade Wizard</a>.', 'pods' ),
598
+ esc_html( PODS_VERSION ),
599
+ esc_url( admin_url( 'admin.php?page=pods-upgrade' ) )
600
+ );
601
+ echo '</p></div>';
602
+ }
603
+
604
+ /**
605
+ * Create PodsUI content for the administration pages
606
+ */
607
+ public function admin_content () {
608
+ $pod_name = str_replace( array( 'pods-manage-', 'pods-add-new-' ), '', $_GET[ 'page' ] );
609
+
610
+ $pod = pods( $pod_name, pods_var( 'id', 'get', null, null, true ) );
611
+
612
+ if ( false !== strpos( $_GET[ 'page' ], 'pods-add-new-' ) )
613
+ $_GET[ 'action' ] = pods_var( 'action', 'get', 'add' );
614
+
615
+ $pod->ui();
616
+ }
617
+
618
+ /**
619
+ * Create PodsUI content for the settings administration pages
620
+ */
621
+ public function admin_content_settings () {
622
+ $pod_name = str_replace( 'pods-settings-', '', $_GET[ 'page' ] );
623
+
624
+ $pod = pods( $pod_name );
625
+
626
+ if ( 'custom' != pods_var( 'ui_style', $pod->pod_data[ 'options' ], 'settings', null, true ) ) {
627
+ $actions_disabled = array(
628
+ 'manage' => 'manage',
629
+ 'add' => 'add',
630
+ 'delete' => 'delete',
631
+ 'duplicate' => 'duplicate',
632
+ 'view' => 'view',
633
+ 'export' => 'export'
634
+ );
635
+
636
+ $_GET[ 'action' ] = 'edit';
637
+
638
+ $page_title = pods_var_raw( 'label', $pod->pod_data, ucwords( str_replace( '_', ' ', $pod->pod_data[ 'name' ] ) ), null, true );
639
+
640
+ $ui = array(
641
+ 'pod' => $pod,
642
+ 'fields' => array(
643
+ 'edit' => $pod->pod_data[ 'fields' ]
644
+ ),
645
+ 'header' => array(
646
+ 'edit' => $page_title
647
+ ),
648
+ 'label' => array(
649
+ 'edit' => __( 'Save Changes', 'pods' )
650
+ ),
651
+ 'style' => pods_var( 'ui_style', $pod->pod_data[ 'options' ], 'settings', null, true ),
652
+ 'icon' => pods_evaluate_tags( pods_var_raw( 'menu_icon', $pod->pod_data[ 'options' ] ), true ),
653
+ 'actions_disabled' => $actions_disabled
654
+ );
655
+
656
+ $ui = apply_filters( 'pods_admin_ui_' . $pod->pod, apply_filters( 'pods_admin_ui', $ui, $pod->pod, $pod ), $pod->pod, $pod );
657
+
658
+ // Force disabled actions, do not pass go, do not collect $two_hundred
659
+ $ui[ 'actions_disabled' ] = $actions_disabled;
660
+
661
+ pods_ui( $ui );
662
+ }
663
+ else {
664
+ do_action( 'pods_admin_ui_custom', $pod );
665
+ do_action( 'pods_admin_ui_custom_' . $pod->pod, $pod );
666
+ }
667
+ }
668
+
669
+ /**
670
+ * Add media button for Pods shortcode
671
+ *
672
+ * @param $context
673
+ *
674
+ * @return string
675
+ */
676
+ public function media_button ( $context = null ) {
677
+ // If shortcodes are disabled don't show the button
678
+ if ( defined( 'PODS_DISABLE_SHORTCODE' ) && PODS_DISABLE_SHORTCODE ) {
679
+ return '';
680
+ }
681
+
682
+ /**
683
+ * Filter to remove Pods shortcode button from the post editor.
684
+ *
685
+ * @param bool. Set to false to block the shortcode button from appearing.
686
+ * @param string $context
687
+ *
688
+ * @since 2.3.19
689
+ */
690
+ if ( !apply_filters( 'pods_admin_media_button', true, $context ) ) {
691
+ return '';
692
+ }
693
+
694
+ $current_page = basename( $_SERVER[ 'PHP_SELF' ] );
695
+ $current_page = explode( '?', $current_page );
696
+ $current_page = explode( '#', $current_page[ 0 ] );
697
+ $current_page = $current_page[ 0 ];
698
+
699
+ // Only show the button on post type pages
700
+ if ( !in_array( $current_page, array( 'post-new.php', 'post.php' ) ) )
701
+ return '';
702
+
703
+ add_action( 'admin_footer', array( $this, 'mce_popup' ) );
704
+
705
+ echo '<a href="#TB_inline?width=640&inlineId=pods_shortcode_form" class="thickbox button" id="add_pod_button" title="Pods Shortcode"><img style="padding: 0px 6px 0px 0px; margin: -3px 0px 0px;" src="' . PODS_URL . 'ui/images/icon16.png" alt="' . __('Pods Shortcode' ,'pods') . '" />' . __('Pods Shortcode' ,'pods') . '</a>';
706
+ }
707
+
708
+ /**
709
+ * Enqueue assets for Media Library Popup
710
+ */
711
+ public function register_media_assets () {
712
+ if ( 'pods_media_attachment' == pods_var( 'inlineId', 'get' ) )
713
+ wp_enqueue_style( 'pods-attach' );
714
+ }
715
+
716
+ /**
717
+ * Output Pods shortcode popup window
718
+ */
719
+ public function mce_popup () {
720
+ pods_view( PODS_DIR . 'ui/admin/shortcode.php', compact( array_keys( get_defined_vars() ) ) );
721
+ }
722
+
723
+ /**
724
+ * Handle main Pods Setup area for managing Pods and Fields
725
+ */
726
+ public function admin_setup () {
727
+ $pods = pods_api()->load_pods( array( 'fields' => false ) );
728
+
729
+ $view = pods_var( 'view', 'get', 'all', null, true );
730
+
731
+ if ( empty( $pods ) && !isset( $_GET[ 'action' ] ) )
732
+ $_GET[ 'action' ] = 'add';
733
+
734
+ if ( 'pods-add-new' == $_GET[ 'page' ] ) {
735
+ if ( isset( $_GET[ 'action' ] ) && 'add' != $_GET[ 'action' ] )
736
+ pods_redirect( pods_query_arg( array( 'page' => 'pods', 'action' => $_GET[ 'action' ] ) ) );
737
+ else
738
+ $_GET[ 'action' ] = 'add';
739
+ }
740
+ elseif ( isset( $_GET[ 'action' ] ) && 'add' == $_GET[ 'action' ] )
741
+ pods_redirect( pods_query_arg( array( 'page' => 'pods-add-new', 'action' => '' ) ) );
742
+
743
+ $types = array(
744
+ 'post_type' => __( 'Post Type (extended)', 'pods' ),
745
+ 'taxonomy' => __( 'Taxonomy (extended)', 'pods' ),
746
+ 'cpt' => __( 'Custom Post Type', 'pods' ),
747
+ 'ct' => __( 'Custom Taxonomy', 'pods' ),
748
+ 'user' => __( 'User (extended)', 'pods' ),
749
+ 'media' => __( 'Media (extended)', 'pods' ),
750
+ 'comment' => __( 'Comments (extended)', 'pods' ),
751
+ 'pod' => __( 'Advanced Content Type', 'pods' ),
752
+ 'settings' => __( 'Custom Settings Page', 'pods' )
753
+ );
754
+
755
+ $row = false;
756
+
757
+ $pod_types_found = array();
758
+
759
+ $fields = array(
760
+ 'label' => array( 'label' => __( 'Label', 'pods' ) ),
761
+ 'name' => array( 'label' => __( 'Name', 'pods' ) ),
762
+ 'type' => array( 'label' => __( 'Type', 'pods' ) ),
763
+ 'storage' => array(
764
+ 'label' => __( 'Storage Type', 'pods' ),
765
+ 'width' => '10%'
766
+ ),
767
+ 'field_count' => array(
768
+ 'label' => __( 'Number of Fields', 'pods' ),
769
+ 'width' => '8%'
770
+ )
771
+ );
772
+
773
+ $total_fields = 0;
774
+
775
+ foreach ( $pods as $k => $pod ) {
776
+ if ( isset( $types[ $pod[ 'type' ] ] ) ) {
777
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'taxonomy' ) ) ) {
778
+ if ( empty( $pod[ 'object' ] ) ) {
779
+ if ( 'post_type' == $pod[ 'type' ] )
780
+ $pod[ 'type' ] = 'cpt';
781
+ else
782
+ $pod[ 'type' ] = 'ct';
783
+ }
784
+ }
785
+
786
+ if ( !isset( $pod_types_found[ $pod[ 'type' ] ] ) )
787
+ $pod_types_found[ $pod[ 'type' ] ] = 1;
788
+ else
789
+ $pod_types_found[ $pod[ 'type' ] ]++;
790
+
791
+ if ( 'all' != $view && $view != $pod[ 'type' ] ) {
792
+ unset( $pods[ $k ] );
793
+
794
+ continue;
795
+ }
796
+
797
+ $pod[ 'real_type' ] = $pod[ 'type' ];
798
+ $pod[ 'type' ] = $types[ $pod[ 'type' ] ];
799
+ }
800
+ elseif ( 'all' != $view )
801
+ continue;
802
+
803
+ $pod[ 'storage' ] = ucwords( $pod[ 'storage' ] );
804
+
805
+ if ( $pod[ 'id' ] == pods_var( 'id' ) && 'delete' != pods_var( 'action' ) )
806
+ $row = $pod;
807
+
808
+ $pod = array(
809
+ 'id' => $pod[ 'id' ],
810
+ 'label' => pods_var_raw( 'label', $pod ),
811
+ 'name' => pods_var_raw( 'name', $pod ),
812
+ 'object' => pods_var_raw( 'object', $pod ),
813
+ 'type' => pods_var_raw( 'type', $pod ),
814
+ 'real_type' => pods_var_raw( 'real_type', $pod ),
815
+ 'storage' => pods_var_raw( 'storage', $pod ),
816
+ 'field_count' => count( $pod[ 'fields' ] )
817
+ );
818
+
819
+ $total_fields += $pod[ 'field_count' ];
820
+
821
+ $pods[ $k ] = $pod;
822
+ }
823
+
824
+ if ( false === $row && 0 < pods_var( 'id' ) && 'delete' != pods_var( 'action' ) ) {
825
+ pods_message( 'Pod not found', 'error' );
826
+
827
+ unset( $_GET[ 'id' ] );
828
+ unset( $_GET[ 'action' ] );
829
+ }
830
+
831
+ $ui = array(
832
+ 'data' => $pods,
833
+ 'row' => $row,
834
+ 'total' => count( $pods ),
835
+ 'total_found' => count( $pods ),
836
+ 'items' => 'Pods',
837
+ 'item' => 'Pod',
838
+ 'fields' => array(
839
+ 'manage' => $fields
840
+ ),
841
+ 'actions_disabled' => array( 'view', 'export' ),
842
+ 'actions_custom' => array(
843
+ 'add' => array( $this, 'admin_setup_add' ),
844
+ 'edit' => array( $this, 'admin_setup_edit' ),
845
+ 'duplicate' => array(
846
+ 'callback' => array( $this, 'admin_setup_duplicate' ),
847
+ 'restrict_callback' => array( $this, 'admin_setup_duplicate_restrict' )
848
+ ),
849
+ 'reset' => array(
850
+ 'label' => __( 'Delete All Items', 'pods' ),
851
+ 'confirm' => __( 'Are you sure you want to delete all items from this Pod? If this is an extended Pod, it will remove the original items extended too.', 'pods' ),
852
+ 'callback' => array( $this, 'admin_setup_reset' ),
853
+ 'restrict_callback' => array( $this, 'admin_setup_reset_restrict' ),
854
+ 'nonce' => true
855
+ ),
856
+ 'delete' => array( $this, 'admin_setup_delete' )
857
+ ),
858
+ 'action_links' => array(
859
+ 'add' => pods_query_arg( array( 'page' => 'pods-add-new', 'action' => '', 'id' => '', 'do' => '' ) )
860
+ ),
861
+ 'search' => false,
862
+ 'searchable' => false,
863
+ 'sortable' => true,
864
+ 'pagination' => false,
865
+ 'extra' => array(
866
+ 'total' => ', ' . number_format_i18n( $total_fields ) . ' ' . _n( 'field', 'fields', $total_fields, 'pods' )
867
+ )
868
+ );
869
+
870
+ if ( 1 < count( $pod_types_found ) ) {
871
+ $ui[ 'views' ] = array( 'all' => __( 'All', 'pods' ) );
872
+ $ui[ 'view' ] = $view;
873
+ $ui[ 'heading' ] = array( 'views' => __( 'Type', 'pods' ) );
874
+ $ui[ 'filters_enhanced' ] = true;
875
+
876
+ foreach ( $pod_types_found as $pod_type => $number_found ) {
877
+ $ui[ 'views' ][ $pod_type ] = $types[ $pod_type ];
878
+ }
879
+ }
880
+
881
+ pods_ui( $ui );
882
+ }
883
+
884
+ /**
885
+ * Get the add page of an object
886
+ *
887
+ * @param $obj
888
+ */
889
+ public function admin_setup_add ( $obj ) {
890
+ pods_view( PODS_DIR . 'ui/admin/setup-add.php', compact( array_keys( get_defined_vars() ) ) );
891
+ }
892
+
893
+ /**
894
+ * Get the edit page of an object
895
+ *
896
+ * @param $duplicate
897
+ * @param $obj
898
+ */
899
+ public function admin_setup_edit ( $duplicate, $obj ) {
900
+ pods_view( PODS_DIR . 'ui/admin/setup-edit.php', compact( array_keys( get_defined_vars() ) ) );
901
+ }
902
+
903
+ /**
904
+ * Get list of Pod option tabs
905
+ *
906
+ * @return array
907
+ */
908
+ public function admin_setup_edit_tabs ( $pod ) {
909
+ $fields = true;
910
+ $labels = false;
911
+ $admin_ui = false;
912
+ $advanced = false;
913
+
914
+ if ( 'post_type' == pods_var( 'type', $pod ) && strlen( pods_var( 'object', $pod ) ) < 1 ) {
915
+ $labels = true;
916
+ $admin_ui = true;
917
+ $advanced = true;
918
+ }
919
+ elseif ( 'taxonomy' == pods_var( 'type', $pod ) && strlen( pods_var( 'object', $pod ) ) < 1 ) {
920
+ $labels = true;
921
+ $admin_ui = true;
922
+ $advanced = true;
923
+ }
924
+ elseif ( 'pod' == pods_var( 'type', $pod ) ) {
925
+ $labels = true;
926
+ $admin_ui = true;
927
+ $advanced = true;
928
+ }
929
+ elseif ( 'settings' == pods_var( 'type', $pod ) ) {
930
+ $labels = true;
931
+ $admin_ui = true;
932
+ }
933
+
934
+ if ( ! function_exists( 'get_term_meta' ) && 'none' == pods_var( 'storage', $pod, 'none', null, true ) && 'taxonomy' == pods_var( 'type', $pod ) )
935
+ $fields = false;
936
+
937
+ $tabs = array();
938
+
939
+ if ( $fields )
940
+ $tabs[ 'manage-fields' ] = __( 'Manage Fields', 'pods' );
941
+
942
+ if ( $labels )
943
+ $tabs[ 'labels' ] = __( 'Labels', 'pods' );
944
+
945
+ if ( $admin_ui )
946
+ $tabs[ 'admin-ui' ] = __( 'Admin UI', 'pods' );
947
+
948
+ if ( $advanced )
949
+ $tabs[ 'advanced' ] = __( 'Advanced Options', 'pods' );
950
+
951
+ if ( 'taxonomy' == pods_var( 'type', $pod ) && !$fields )
952
+ $tabs[ 'extra-fields' ] = __( 'Extra Fields', 'pods' );
953
+
954
+ $addtl_args = compact( array( 'fields', 'labels', 'admin_ui', 'advanced' ) );
955
+
956
+ /**
957
+ * Add or modify tabs in Pods editor for a specific Pod
958
+ *
959
+ * @params array $tabs Tabs to set.
960
+ * @params object $pod Current Pods object
961
+ * @params array $addtl_args Additional args.
962
+ *
963
+ * @since unknown
964
+ */
965
+ $tabs = apply_filters( 'pods_admin_setup_edit_tabs_' . $pod[ 'type' ] . '_' . $pod[ 'name' ], $tabs, $pod, $addtl_args );
966
+
967
+ /**
968
+ * Add or modify tabs for any Pod in Pods editor of a specific post type.
969
+ */
970
+ $tabs = apply_filters( 'pods_admin_setup_edit_tabs_' . $pod[ 'type' ], $tabs, $pod, $addtl_args );
971
+
972
+ /**
973
+ * Add or modify tabs in Pods editor for all pods.
974
+ */
975
+ $tabs = apply_filters( 'pods_admin_setup_edit_tabs', $tabs, $pod, $addtl_args );
976
+
977
+ return $tabs;
978
+ }
979
+
980
+ /**
981
+ * Get list of Pod options
982
+ *
983
+ * @return array
984
+ */
985
+ public function admin_setup_edit_options ( $pod ) {
986
+ $options = array();
987
+
988
+ // @todo fill this in
989
+ $options[ 'labels' ] = array(
990
+ 'temporary' => 'This has the fields hardcoded' // :(
991
+ );
992
+
993
+ if ( 'post_type' == $pod[ 'type' ] ) {
994
+ $options[ 'admin-ui' ] = array(
995
+ 'description' => array(
996
+ 'label' => __( 'Post Type Description', 'pods' ),
997
+ 'help' => __( 'A short descriptive summary of what the post type is.', 'pods' ),
998
+ 'type' => 'text',
999
+ 'default' => ''
1000
+ ),
1001
+ 'show_ui' => array(
1002
+ 'label' => __( 'Show Admin UI', 'pods' ),
1003
+ 'help' => __( 'Whether to generate a default UI for managing this post type in the admin.', 'pods' ),
1004
+ 'type' => 'boolean',
1005
+ 'default' => pods_var_raw( 'public', $pod, true ),
1006
+ 'boolean_yes_label' => ''
1007
+ ),
1008
+ 'show_in_menu' => array(
1009
+ 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ),
1010
+ 'help' => __( 'Whether to show the post type in the admin menu.', 'pods' ),
1011
+ 'type' => 'boolean',
1012
+ 'default' => pods_var_raw( 'public', $pod, true ),
1013
+ 'dependency' => true,
1014
+ 'boolean_yes_label' => ''
1015
+ ),
1016
+ 'menu_location_custom' => array(
1017
+ 'label' => __( 'Parent Menu ID (optional)', 'pods' ),
1018
+ 'help' => __( 'help', 'pods' ),
1019
+ 'type' => 'text',
1020
+ 'depends-on' => array( 'show_in_menu' => true )
1021
+ ),
1022
+ 'menu_name' => array(
1023
+ 'label' => __( 'Menu Name', 'pods' ),
1024
+ 'help' => __( 'help', 'pods' ),
1025
+ 'type' => 'text',
1026
+ 'default' => '',
1027
+ 'depends-on' => array( 'show_in_menu' => true )
1028
+ ),
1029
+ 'menu_position' => array(
1030
+ 'label' => __( 'Menu Position', 'pods' ),
1031
+ 'help' => __( 'help', 'pods' ),
1032
+ 'type' => 'number',
1033
+ 'number_decimals' => 2,
1034
+ 'number_format' => '9999.99',
1035
+ 'number_format_soft' => 1,
1036
+ 'default' => 0,
1037
+ 'depends-on' => array( 'show_in_menu' => true )
1038
+ ),
1039
+ 'menu_icon' => array(
1040
+ 'label' => __( 'Menu Icon', 'pods' ),
1041
+ 'help' => __( 'URL or Dashicon name for the menu icon. You may specify the path to the icon using one of the <a href="http://pods.io/docs/build/special-magic-tags/#site-tags" target="_blank">site tag</a> type <a href="http://pods.io/docs/build/special-magic-tags/" target="_blank">special magic tags</a>. For example, for a file in your theme directory, use "{@template-url}/path/to/image.png". You may also use the name of a <a href="https://developer.wordpress.org/resource/dashicons/" target="_blank">Dashicon</a>. For example, to use the empty star icon, use "dashicons-star-empty".', 'pods' ),
1042
+ 'type' => 'text',
1043
+ 'default' => '',
1044
+ 'depends-on' => array( 'show_in_menu' => true )
1045
+ ),
1046
+ 'show_in_nav_menus' => array(
1047
+ 'label' => __( 'Show in Navigation Menus', 'pods' ),
1048
+ 'help' => __( 'help', 'pods' ),
1049
+ 'type' => 'boolean',
1050
+ 'default' => true,
1051
+ 'boolean_yes_label' => ''
1052
+ ),
1053
+ 'show_in_admin_bar' => array(
1054
+ 'label' => __( 'Show in Admin Bar "New" Menu', 'pods' ),
1055
+ 'help' => __( 'help', 'pods' ),
1056
+ 'type' => 'boolean',
1057
+ 'default' => true,
1058
+ 'boolean_yes_label' => ''
1059
+ )
1060
+ );
1061
+
1062
+ $options[ 'advanced' ] = array(
1063
+ 'public' => array(
1064
+ 'label' => __( 'Public', 'pods' ),
1065
+ 'help' => __( 'help', 'pods' ),
1066
+ 'type' => 'boolean',
1067
+ 'default' => true,
1068
+ 'boolean_yes_label' => ''
1069
+ ),
1070
+ 'publicly_queryable' => array(
1071
+ 'label' => __( 'Publicly Queryable', 'pods' ),
1072
+ 'help' => __( 'help', 'pods' ),
1073
+ 'type' => 'boolean',
1074
+ 'default' => pods_var_raw( 'public', $pod, true ),
1075
+ 'boolean_yes_label' => ''
1076
+ ),
1077
+ 'exclude_from_search' => array(
1078
+ 'label' => __( 'Exclude from Search', 'pods' ),
1079
+ 'help' => __( 'help', 'pods' ),
1080
+ 'type' => 'boolean',
1081
+ 'default' => !pods_var_raw( 'public', $pod, true ),
1082
+ 'boolean_yes_label' => ''
1083
+ ),
1084
+ 'capability_type' => array(
1085
+ 'label' => __( 'User Capability', 'pods' ),
1086
+ 'help' => __( 'Uses these capabilties for access to this post type: edit_{capability}, read_{capability}, and delete_{capability}', 'pods' ),
1087
+ 'type' => 'pick',
1088
+ 'default' => 'post',
1089
+ 'data' => array(
1090
+ 'post' => 'post',
1091
+ 'page' => 'page',
1092
+ 'custom' => __( 'Custom Capability', 'pods' )
1093
+ ),
1094
+ 'dependency' => true
1095
+ ),
1096
+ 'capability_type_custom' => array(
1097
+ 'label' => __( 'Custom User Capability', 'pods' ),
1098
+ 'help' => __( 'help', 'pods' ),
1099
+ 'type' => 'text',
1100
+ 'default' => pods_var_raw( 'name', $pod ),
1101
+ 'depends-on' => array( 'capability_type' => 'custom' )
1102
+ ),
1103
+ 'capability_type_extra' => array(
1104
+ 'label' => __( 'Additional User Capabilities', 'pods' ),
1105
+ 'help' => __( 'Enables additional capabilities for this Post Type including: delete_{capability}s, delete_private_{capability}s, delete_published_{capability}s, delete_others_{capability}s, edit_private_{capability}s, and edit_published_{capability}s', 'pods' ),
1106
+ 'type' => 'boolean',
1107
+ 'default' => true,
1108
+ 'boolean_yes_label' => ''
1109
+ ),
1110
+ 'has_archive' => array(
1111
+ 'label' => __( 'Enable Archive Page', 'pods' ),
1112
+ 'help' => __( 'If enabled, creates an archive page with list of of items in this custom post type. Functions like a category page for posts. Can be controlled with a template in your theme called "archive-{$post-type}.php".', 'pods' ),
1113
+ 'type' => 'boolean',
1114
+ 'default' => false,
1115
+ 'dependency' => true,
1116
+ 'boolean_yes_label' => ''
1117
+ ),
1118
+ 'has_archive_slug' => array(
1119
+ 'label' => __( 'Archive Page Slug Override', 'pods' ),
1120
+ 'help' => __( 'If archive page is enabled, you can override the slug used by WordPress, which defaults to the name of the post type.', 'pods' ),
1121
+ 'type' => 'text',
1122
+ 'default' => '',
1123
+ 'depends-on' => array( 'has_archive' => true )
1124
+ ),
1125
+ 'hierarchical' => array(
1126
+ 'label' => __( 'Hierarchical', 'pods' ),
1127
+ 'help' => __( 'Allows for parent/ child relationships between items, just like with Pages. Note: To edit relationships in the post editor, you must enable "Page Attributes" in the "Supports" section below.', 'pods' ),
1128
+ 'type' => 'boolean',
1129
+ 'default' => false,
1130
+ 'dependency' => true,
1131
+ 'boolean_yes_label' => ''
1132
+ ),
1133
+ 'label_parent_item_colon' => array(
1134
+ 'label' => __( '<strong>Label: </strong> Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1135
+ 'help' => __( 'help', 'pods' ),
1136
+ 'type' => 'text',
1137
+ 'default' => '',
1138
+ 'depends-on' => array( 'hierarchical' => true )
1139
+ ),
1140
+ 'label_parent' => array(
1141
+ 'label' => __( '<strong>Label: </strong> Parent', 'pods' ),
1142
+ 'help' => __( 'help', 'pods' ),
1143
+ 'type' => 'text',
1144
+ 'default' => '',
1145
+ 'depends-on' => array( 'hierarchical' => true )
1146
+ ),
1147
+ 'rewrite' => array(
1148
+ 'label' => __( 'Rewrite', 'pods' ),
1149
+ 'help' => __( 'Allows you to use pretty permalinks, if set in WordPress Settings->Permalinks. If not enabled, your links will be in the form of "example.com/?pod_name=post_slug" regardless of your permalink settings.', 'pods' ),
1150
+ 'type' => 'boolean',
1151
+ 'default' => true,
1152
+ 'dependency' => true,
1153
+ 'boolean_yes_label' => ''
1154
+ ),
1155
+ 'rewrite_custom_slug' => array(
1156
+ 'label' => __( 'Custom Rewrite Slug', 'pods' ),
1157
+ 'help' => __( 'Changes the first segment of the URL, which by default is the name of the Pod. For example, if your Pod is called "foo", if this field is left blank, your link will be "example.com/foo/post_slug", but if you were to enter "bar" your link will be "example.com/bar/post_slug".', 'pods' ),
1158
+ 'type' => 'text',
1159
+ 'default' => '',
1160
+ 'depends-on' => array( 'rewrite' => true )
1161
+ ),
1162
+ 'rewrite_with_front' => array(
1163
+ 'label' => __( 'Rewrite with Front', 'pods' ),
1164
+ 'help' => __( 'Allows permalinks to be prepended with your front base (example: if your permalink structure is /blog/, then your links will be: Unchecked->/news/, Checked->/blog/news/)', 'pods' ),
1165
+ 'type' => 'boolean',
1166
+ 'default' => true,
1167
+ 'depends-on' => array( 'rewrite' => true ),
1168
+ 'boolean_yes_label' => ''
1169
+ ),
1170
+ 'rewrite_feeds' => array(
1171
+ 'label' => __( 'Rewrite Feeds', 'pods' ),
1172
+ 'help' => __( 'help', 'pods' ),
1173
+ 'type' => 'boolean',
1174
+ 'default' => false,
1175
+ 'depends-on' => array( 'rewrite' => true ),
1176
+ 'boolean_yes_label' => ''
1177
+ ),
1178
+ 'rewrite_pages' => array(
1179
+ 'label' => __( 'Rewrite Pages', 'pods' ),
1180
+ 'help' => __( 'help', 'pods' ),
1181
+ 'type' => 'boolean',
1182
+ 'default' => true,
1183
+ 'depends-on' => array( 'rewrite' => true ),
1184
+ 'boolean_yes_label' => ''
1185
+ ),
1186
+ 'query_var' => array(
1187
+ 'label' => __( 'Query Var', 'pods' ),
1188
+ 'help' => __( 'The Query Var is used in the URL and underneath the WordPress Rewrite API to tell WordPress what page or post type you are on. For a list of reserved Query Vars, read <a href="http://codex.wordpress.org/WordPress_Query_Vars">WordPress Query Vars</a> from the WordPress Codex.', 'pods' ),
1189
+ 'type' => 'boolean',
1190
+ 'default' => true,
1191
+ 'boolean_yes_label' => ''
1192
+ ),
1193
+ 'can_export' => array(
1194
+ 'label' => __( 'Exportable', 'pods' ),
1195
+ 'help' => __( 'help', 'pods' ),
1196
+ 'type' => 'boolean',
1197
+ 'default' => true,
1198
+ 'boolean_yes_label' => ''
1199
+ ),
1200
+ 'default_status' => array(
1201
+ 'label' => __( 'Default Status', 'pods' ),
1202
+ 'help' => __( 'help', 'pods' ),
1203
+ 'type' => 'pick',
1204
+ 'pick_object' => 'post-status',
1205
+ 'default' => apply_filters( 'pods_api_default_status_' . pods_var_raw( 'name', $pod, 'post_type', null, true ), 'draft', $pod )
1206
+ )
1207
+ );
1208
+ }
1209
+ elseif ( 'taxonomy' == $pod[ 'type' ] ) {
1210
+ $options[ 'admin-ui' ] = array(
1211
+ 'show_ui' => array(
1212
+ 'label' => __( 'Show Admin UI', 'pods' ),
1213
+ 'help' => __( 'Whether to generate a default UI for managing this taxonomy.', 'pods' ),
1214
+ 'type' => 'boolean',
1215
+ 'default' => pods_var_raw( 'public', $pod, true ),
1216
+ 'dependency' => true,
1217
+ 'boolean_yes_label' => ''
1218
+ ),
1219
+ 'show_in_menu' => array(
1220
+ 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ),
1221
+ 'help' => __( 'Whether to show the taxonomy in the admin menu.', 'pods' ),
1222
+ 'type' => 'boolean',
1223
+ 'default' => pods_var_raw( 'public', $pod, true ),
1224
+ 'dependency' => true,
1225
+ 'depends-on' => array( 'show_ui' => true ),
1226
+ 'boolean_yes_label' => ''
1227
+ ),
1228
+ 'menu_name' => array(
1229
+ 'label' => __( 'Menu Name', 'pods' ),
1230
+ 'help' => __( 'help', 'pods' ),
1231
+ 'type' => 'text',
1232
+ 'default' => '',
1233
+ 'depends-on' => array( 'show_ui' => true )
1234
+ ),
1235
+ 'menu_location' => array(
1236
+ 'label' => __( 'Menu Location', 'pods' ),
1237
+ 'help' => __( 'help', 'pods' ),
1238
+ 'type' => 'pick',
1239
+ 'default' => 'default',
1240
+ 'depends-on' => array( 'show_ui' => true ),
1241
+ 'data' => array(
1242
+ 'default' => __( 'Default - Add to associated Post Type(s) menus', 'pods' ),
1243
+ 'settings' => __( 'Add to Settings menu', 'pods' ),
1244
+ 'appearances' => __( 'Add to Appearances menu', 'pods' ),
1245
+ 'objects' => __( 'Make a top-level menu item', 'pods' ),
1246
+ 'top' => __( 'Make a new top-level menu item below Settings', 'pods' ),
1247
+ 'submenu' => __( 'Add a submenu item to another menu', 'pods' )
1248
+ ),
1249
+ 'dependency' => true
1250
+ ),
1251
+ 'menu_location_custom' => array(
1252
+ 'label' => __( 'Custom Menu Location', 'pods' ),
1253
+ 'help' => __( 'help', 'pods' ),
1254
+ 'type' => 'text',
1255
+ 'depends-on' => array( 'menu_location' => 'submenu' )
1256
+ ),
1257
+ 'menu_position' => array(
1258
+ 'label' => __( 'Menu Position', 'pods' ),
1259
+ 'help' => __( 'help', 'pods' ),
1260
+ 'type' => 'number',
1261
+ 'number_decimals' => 2,
1262
+ 'number_format' => '9999.99',
1263
+ 'number_format_soft' => 1,
1264
+ 'default' => 0,
1265
+ 'depends-on' => array( 'menu_location' => array( 'objects', 'top' ) )
1266
+ ),
1267
+ 'menu_icon' => array(
1268
+ 'label' => __( 'Menu Icon URL', 'pods' ),
1269
+ 'help' => __( 'help', 'pods' ),
1270
+ 'type' => 'text',
1271
+ 'default' => '',
1272
+ 'depends-on' => array( 'menu_location' => array( 'objects', 'top' ) )
1273
+ ),
1274
+ 'show_in_nav_menus' => array(
1275
+ 'label' => __( 'Show in Navigation Menus', 'pods' ),
1276
+ 'help' => __( 'help', 'pods' ),
1277
+ 'type' => 'boolean',
1278
+ 'default' => pods_var_raw( 'public', $pod, true ),
1279
+ 'boolean_yes_label' => ''
1280
+ ),
1281
+ 'show_tagcloud' => array(
1282
+ 'label' => __( 'Allow in Tagcloud Widget', 'pods' ),
1283
+ 'help' => __( 'help', 'pods' ),
1284
+ 'type' => 'boolean',
1285
+ 'default' => pods_var_raw( 'show_ui', $pod, pods_var_raw( 'public', $pod, true ) ),
1286
+ 'boolean_yes_label' => ''
1287
+ )
1288
+ );
1289
+
1290
+ if ( pods_version_check( 'wp', '3.5' ) ) {
1291
+ $options[ 'admin-ui' ][ 'show_admin_column' ] = array(
1292
+ 'label' => __( 'Show Taxonomy column on Post Types', 'pods' ),
1293
+ 'help' => __( 'Whether to add a column for this taxonomy on the associated post types manage screens', 'pods' ),
1294
+ 'type' => 'boolean',
1295
+ 'default' => false,
1296
+ 'boolean_yes_label' => ''
1297
+ );
1298
+ }
1299
+
1300
+ // Integration for Single Value Taxonomy UI
1301
+ if ( function_exists( 'tax_single_value_meta_box' ) ) {
1302
+ $options[ 'admin-ui' ][ 'single_value' ] = array(
1303
+ 'label' => __( 'Single Value Taxonomy', 'pods' ),
1304
+ 'help' => __( 'Use a drop-down for the input instead of the WordPress default', 'pods' ),
1305
+ 'type' => 'boolean',
1306
+ 'default' => false,
1307
+ 'boolean_yes_label' => ''
1308
+ );
1309
+
1310
+ $options[ 'admin-ui' ][ 'single_value_required' ] = array(
1311
+ 'label' => __( 'Single Value Taxonomy - Required', 'pods' ),
1312
+ 'help' => __( 'A term will be selected by default in the Post Editor, not optional', 'pods' ),
1313
+ 'type' => 'boolean',
1314
+ 'default' => false,
1315
+ 'boolean_yes_label' => ''
1316
+ );
1317
+ }
1318
+
1319
+ $options[ 'advanced' ] = array(
1320
+ 'public' => array(
1321
+ 'label' => __( 'Public', 'pods' ),
1322
+ 'help' => __( 'help', 'pods' ),
1323
+ 'type' => 'boolean',
1324
+ 'default' => true,
1325
+ 'boolean_yes_label' => ''
1326
+ ),
1327
+ 'hierarchical' => array(
1328
+ 'label' => __( 'Hierarchical', 'pods' ),
1329
+ 'help' => __( 'help', 'pods' ),
1330
+ 'type' => 'boolean',
1331
+ 'default' => true,
1332
+ 'dependency' => true,
1333
+ 'boolean_yes_label' => ''
1334
+ ),
1335
+ 'label_parent_item_colon' => array(
1336
+ 'label' => __( '<strong>Label: </strong> Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1337
+ 'help' => __( 'help', 'pods' ),
1338
+ 'type' => 'text',
1339
+ 'default' => '',
1340
+ 'depends-on' => array( 'hierarchical' => true )
1341
+ ),
1342
+ 'label_parent' => array(
1343
+ 'label' => __( '<strong>Label: </strong> Parent', 'pods' ),
1344
+ 'help' => __( 'help', 'pods' ),
1345
+ 'type' => 'text',
1346
+ 'default' => '',
1347
+ 'depends-on' => array( 'hierarchical' => true )
1348
+ ),
1349
+ 'label_no_terms' => array(
1350
+ 'label' => __( '<strong>Label: </strong> No <span class="pods-slugged" data-sluggable="label">Items</span>', 'pods' ),
1351
+ 'help' => __( 'help', 'pods' ),
1352
+ 'type' => 'text',
1353
+ 'default' => '',
1354
+ 'depends-on' => array( 'hierarchical' => true )
1355
+ ),
1356
+ 'rewrite' => array(
1357
+ 'label' => __( 'Rewrite', 'pods' ),
1358
+ 'help' => __( 'help', 'pods' ),
1359
+ 'type' => 'boolean',
1360
+ 'default' => true,
1361
+ 'dependency' => true,
1362
+ 'boolean_yes_label' => ''
1363
+ ),
1364
+ 'rewrite_custom_slug' => array(
1365
+ 'label' => __( 'Custom Rewrite Slug', 'pods' ),
1366
+ 'help' => __( 'help', 'pods' ),
1367
+ 'type' => 'text',
1368
+ 'default' => '',
1369
+ 'depends-on' => array( 'rewrite' => true )
1370
+ ),
1371
+ 'rewrite_with_front' => array(
1372
+ 'label' => __( 'Allow Front Prepend', 'pods' ),
1373
+ 'help' => __( 'Allows permalinks to be prepended with front base (example: if your permalink structure is /blog/, then your links will be: Checked->/news/, Unchecked->/blog/news/)', 'pods' ),
1374
+ 'type' => 'boolean',
1375
+ 'default' => true,
1376
+ 'boolean_yes_label' => '',
1377
+ 'depends-on' => array( 'rewrite' => true )
1378
+ ),
1379
+ 'rewrite_hierarchical' => array(
1380
+ 'label' => __( 'Hierarchical Permalinks', 'pods' ),
1381
+ 'help' => __( 'help', 'pods' ),
1382
+ 'type' => 'boolean',
1383
+ 'default' => true,
1384
+ 'boolean_yes_label' => '',
1385
+ 'depends-on' => array( 'rewrite' => true )
1386
+ ),
1387
+ 'capability_type' => array(
1388
+ 'label' => __( 'User Capability', 'pods' ),
1389
+ 'help' => __( 'Uses WordPress term capabilities by default', 'pods' ),
1390
+ 'type' => 'pick',
1391
+ 'default' => 'default',
1392
+ 'data' => array(
1393
+ 'default' => 'Default',
1394
+ 'custom' => __( 'Custom Capability', 'pods' )
1395
+ ),
1396
+ 'dependency' => true
1397
+ ),
1398
+ 'capability_type_custom' => array(
1399
+ 'label' => __( 'Custom User Capability', 'pods' ),
1400
+ 'help' => __( 'Enables additional capabilities for this Taxonomy including: manage_{capability}_terms, edit_{capability}_terms, assign_{capability}_terms, and delete_{capability}_terms', 'pods' ),
1401
+ 'type' => 'text',
1402
+ 'default' => pods_v( 'name', $pod ),
1403
+ 'depends-on' => array( 'capability_type' => 'custom' )
1404
+ ),
1405
+ 'query_var' => array(
1406
+ 'label' => __( 'Query Var', 'pods' ),
1407
+ 'help' => __( 'help', 'pods' ),
1408
+ 'type' => 'boolean',
1409
+ 'default' => false,
1410
+ 'boolean_yes_label' => ''
1411
+ ),
1412
+ 'query_var' => array(
1413
+ 'label' => __( 'Query Var', 'pods' ),
1414
+ 'help' => __( 'help', 'pods' ),
1415
+ 'type' => 'boolean',
1416
+ 'default' => false,
1417
+ 'dependency' => true,
1418
+ 'boolean_yes_label' => ''
1419
+ ),
1420
+ 'query_var_string' => array(
1421
+ 'label' => __( 'Custom Query Var Name', 'pods' ),
1422
+ 'help' => __( 'help', 'pods' ),
1423
+ 'type' => 'text',
1424
+ 'default' => '',
1425
+ 'depends-on' => array( 'query_var' => true )
1426
+ ),
1427
+ 'sort' => array(
1428
+ 'label' => __( 'Remember order saved on Post Types', 'pods' ),
1429
+ 'help' => __( 'help', 'pods' ),
1430
+ 'type' => 'boolean',
1431
+ 'default' => false,
1432
+ 'boolean_yes_label' => ''
1433
+ ),
1434
+ 'update_count_callback' => array(
1435
+ 'label' => __( 'Function to call when updating counts', 'pods' ),
1436
+ 'help' => __( 'help', 'pods' ),
1437
+ 'type' => 'text',
1438
+ 'default' => ''
1439
+ ),
1440
+ );
1441
+ }
1442
+ elseif ( 'settings' == $pod[ 'type' ] ) {
1443
+ $options[ 'admin-ui' ] = array(
1444
+ 'ui_style' => array(
1445
+ 'label' => __( 'Admin UI Style', 'pods' ),
1446
+ 'help' => __( 'help', 'pods' ),
1447
+ 'type' => 'pick',
1448
+ 'default' => 'settings',
1449
+ 'data' => array(
1450
+ 'settings' => __( 'Normal Settings Form', 'pods' ),
1451
+ 'post_type' => __( 'Post Type UI', 'pods' ),
1452
+ 'custom' => __( 'Custom (hook into pods_admin_ui_custom or pods_admin_ui_custom_{podname} action)', 'pods' )
1453
+ ),
1454
+ 'dependency' => true
1455
+ ),
1456
+ 'menu_location' => array(
1457
+ 'label' => __( 'Menu Location', 'pods' ),
1458
+ 'help' => __( 'help', 'pods' ),
1459
+ 'type' => 'pick',
1460
+ 'default' => 'settings',
1461
+ 'data' => array(
1462
+ 'settings' => __( 'Add to Settings menu', 'pods' ),
1463
+ 'appearances' => __( 'Add to Appearances menu', 'pods' ),
1464
+ 'top' => __( 'Make a new top-level menu item below Settings', 'pods' ),
1465
+ 'submenu' => __( 'Add a submenu item to another menu', 'pods' )
1466
+ ),
1467
+ 'dependency' => true
1468
+ ),
1469
+ 'menu_location_custom' => array(
1470
+ 'label' => __( 'Custom Menu Location', 'pods' ),
1471
+ 'help' => __( 'help', 'pods' ),
1472
+ 'type' => 'text',
1473
+ 'depends-on' => array( 'menu_location' => 'submenu' )
1474
+ ),
1475
+ 'menu_position' => array(
1476
+ 'label' => __( 'Menu Position', 'pods' ),
1477
+ 'help' => __( 'help', 'pods' ),
1478
+ 'type' => 'number',
1479
+ 'number_decimals' => 2,
1480
+ 'number_format' => '9999.99',
1481
+ 'number_format_soft' => 1,
1482
+ 'default' => 0,
1483
+ 'depends-on' => array( 'menu_location' => 'top' )
1484
+ ),
1485
+ 'menu_icon' => array(
1486
+ 'label' => __( 'Menu Icon URL', 'pods' ),
1487
+ 'help' => __( 'help', 'pods' ),
1488
+ 'type' => 'text',
1489
+ 'default' => '',
1490
+ 'depends-on' => array( 'menu_location' => 'top' )
1491
+ )
1492
+ );
1493
+
1494
+ // @todo fill this in
1495
+ $options[ 'advanced' ] = array(
1496
+ 'temporary' => 'This type has the fields hardcoded' // :(
1497
+ );
1498
+ }
1499
+ elseif ( 'pod' == $pod[ 'type' ] ) {
1500
+ $options[ 'admin-ui' ] = array(
1501
+ 'ui_style' => array(
1502
+ 'label' => __( 'Admin UI Style', 'pods' ),
1503
+ 'help' => __( 'help', 'pods' ),
1504
+ 'type' => 'pick',
1505
+ 'default' => 'settings',
1506
+ 'data' => array(
1507
+ 'post_type' => __( 'Normal (Looks like the Post Type UI)', 'pods' ),
1508
+ 'custom' => __( 'Custom (hook into pods_admin_ui_custom or pods_admin_ui_custom_{podname} action)', 'pods' )
1509
+ ),
1510
+ 'dependency' => true
1511
+ ),
1512
+ 'show_in_menu' => array(
1513
+ 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ),
1514
+ 'help' => __( 'help', 'pods' ),
1515
+ 'type' => 'boolean',
1516
+ 'default' => false,
1517
+ 'boolean_yes_label' => '',
1518
+ 'dependency' => true
1519
+ ),
1520
+ 'menu_location_custom' => array(
1521
+ 'label' => __( 'Parent Menu ID (optional)', 'pods' ),
1522
+ 'help' => __( 'help', 'pods' ),
1523
+ 'type' => 'text',
1524
+ 'depends-on' => array( 'show_in_menu' => true )
1525
+ ),
1526
+ 'menu_position' => array(
1527
+ 'label' => __( 'Menu Position', 'pods' ),
1528
+ 'help' => __( 'help', 'pods' ),
1529
+ 'type' => 'number',
1530
+ 'number_decimals' => 2,
1531
+ 'number_format' => '9999.99',
1532
+ 'number_format_soft' => 1,
1533
+ 'default' => 0,
1534
+ 'depends-on' => array( 'show_in_menu' => true )
1535
+ ),
1536
+ 'menu_icon' => array(
1537
+ 'label' => __( 'Menu Icon URL', 'pods' ),
1538
+ 'help' => __( 'This is the icon shown to the left of the menu text for this content type.', 'pods' ),
1539
+ 'type' => 'text',
1540
+ 'default' => '',
1541
+ 'depends-on' => array( 'show_in_menu' => true )
1542
+ ),
1543
+ 'ui_icon' => array(
1544
+ 'label' => __( 'Header Icon', 'pods' ),
1545
+ 'help' => __( 'This is the icon shown to the left of the heading text at the top of the manage pages for this content type.', 'pods' ),
1546
+ 'type' => 'file',
1547
+ 'default' => '',
1548
+ 'file_edit_title' => 0,
1549
+ 'depends-on' => array( 'show_in_menu' => true )
1550
+ ),
1551
+ 'ui_actions_enabled' => array(
1552
+ 'label' => __( 'Actions Available', 'pods' ),
1553
+ 'help' => __( 'help', 'pods' ),
1554
+ 'type' => 'pick',
1555
+ 'default' => ( 1 == pods_var( 'ui_export', $pod ) ? array( 'add', 'edit', 'duplicate', 'delete', 'export' ) : array( 'add', 'edit', 'duplicate', 'delete' ) ),
1556
+ 'data' => array(
1557
+ 'add' => __( 'Add New', 'pods' ),
1558
+ 'edit' => __( 'Edit', 'pods' ),
1559
+ 'duplicate' => __( 'Duplicate', 'pods' ),
1560
+ 'delete' => __( 'Delete', 'pods' ),
1561
+ 'reorder' => __( 'Reorder', 'pods' ),
1562
+ 'export' => __( 'Export', 'pods' )
1563
+ ),
1564
+ 'pick_format_type' => 'multi',
1565
+ 'dependency' => true
1566
+ ),
1567
+ 'ui_reorder_field' => array(
1568
+ 'label' => __( 'Reorder Field', 'pods' ),
1569
+ 'help' => __( 'This is the field that will be reordered on, it should be numeric.', 'pods' ),
1570
+ 'type' => 'text',
1571
+ 'default' => 'menu_order',
1572
+ 'depends-on' => array( 'ui_actions_enabled' => 'reorder' )
1573
+ ),
1574
+ 'ui_fields_manage' => array(
1575
+ 'label' => __( 'Admin Table Columns', 'pods' ),
1576
+ 'help' => __( 'help', 'pods' ),
1577
+ 'type' => 'pick',
1578
+ 'default' => array(),
1579
+ 'data' => array(),
1580
+ 'pick_format_type' => 'multi'
1581
+ ),
1582
+ 'ui_filters' => array(
1583
+ 'label' => __( 'Search Filters', 'pods' ),
1584
+ 'help' => __( 'help', 'pods' ),
1585
+ 'type' => 'pick',
1586
+ 'default' => array(),
1587
+ 'data' => array(),
1588
+ 'pick_format_type' => 'multi'
1589
+ )
1590
+ );
1591
+
1592
+ if ( !empty( $pod[ 'fields' ] ) ) {
1593
+ if ( isset( $pod[ 'fields' ][ pods_var_raw( 'pod_index', $pod, 'name' ) ] ) )
1594
+ $options[ 'admin-ui' ][ 'ui_fields_manage' ][ 'default' ][] = pods_var_raw( 'pod_index', $pod, 'name' );
1595
+
1596
+ if ( isset( $pod[ 'fields' ][ 'modified' ] ) )
1597
+ $options[ 'admin-ui' ][ 'ui_fields_manage' ][ 'default' ][] = 'modified';
1598
+
1599
+ foreach ( $pod[ 'fields' ] as $field ) {
1600
+ $type = '';
1601
+
1602
+ if ( isset( $field_types[ $field[ 'type' ] ] ) )
1603
+ $type = ' <small>(' . $field_types[ $field[ 'type' ] ][ 'label' ] . ')</small>';
1604
+
1605
+ $options[ 'admin-ui' ][ 'ui_fields_manage' ][ 'data' ][ $field[ 'name' ] ] = $field[ 'label' ] . $type;
1606
+ $options[ 'admin-ui' ][ 'ui_filters' ][ 'data' ][ $field[ 'name' ] ] = $field[ 'label' ] . $type;
1607
+ }
1608
+
1609
+ $options[ 'admin-ui' ][ 'ui_fields_manage' ][ 'data' ][ 'id' ] = 'ID';
1610
+ }
1611
+ else {
1612
+ unset( $options[ 'admin-ui' ][ 'ui_fields_manage' ] );
1613
+ unset( $options[ 'admin-ui' ][ 'ui_filters' ] );
1614
+ }
1615
+
1616
+ // @todo fill this in
1617
+ $options[ 'advanced' ] = array(
1618
+ 'temporary' => 'This type has the fields hardcoded' // :(
1619
+ );
1620
+ }
1621
+
1622
+ /**
1623
+ * Add admin fields to the Pods editor for a specific Pod
1624
+ *
1625
+ * @params array $options The Options fields
1626
+ * @params object $pod Current Pods object
1627
+ *
1628
+ * @since unkown
1629
+ */
1630
+ $options = apply_filters( 'pods_admin_setup_edit_options_' . $pod[ 'type' ] . '_' . $pod[ 'name' ], $options, $pod );
1631
+
1632
+ /**
1633
+ * Add admin fields to the Pods editor for any Pod of a specific content type.
1634
+ */
1635
+ $options = apply_filters( 'pods_admin_setup_edit_options_' . $pod[ 'type' ], $options, $pod );
1636
+
1637
+ /**
1638
+ * Add admin fields to the Pods editor for all Pods
1639
+ */
1640
+ $options = apply_filters( 'pods_admin_setup_edit_options', $options, $pod );
1641
+
1642
+ return $options;
1643
+ }
1644
+
1645
+ /**
1646
+ * Get list of Pod field option tabs
1647
+ *
1648
+ * @return array
1649
+ */
1650
+ public function admin_setup_edit_field_tabs ( $pod ) {
1651
+ $core_tabs = array(
1652
+ 'basic' => __( 'Basic', 'pods' ),
1653
+ 'additional-field' => __( 'Additional Field Options', 'pods' ),
1654
+ 'advanced' => __( 'Advanced', 'pods' )
1655
+ );
1656
+
1657
+ /**
1658
+ * Field option tabs
1659
+ *
1660
+ * Use to add new tabs, default tabs are added after this filter (IE you can't remove/modify them with this, kthanksbye).
1661
+ *
1662
+ * @since unknown
1663
+ *
1664
+ * @param array $tabs Tabs to add, starts empty
1665
+ * @param object|Pod Current Pods object
1666
+ */
1667
+ $tabs = apply_filters( 'pods_admin_setup_edit_field_tabs', array(), $pod );
1668
+
1669
+ $tabs = array_merge( $core_tabs, $tabs );
1670
+
1671
+ return $tabs;
1672
+ }
1673
+
1674
+ /**
1675
+ * Get list of Pod field options
1676
+ *
1677
+ * @return array
1678
+ */
1679
+ public function admin_setup_edit_field_options ( $pod ) {
1680
+ $options = array();
1681
+
1682
+ $options[ 'additional-field' ] = array();
1683
+
1684
+ $field_types = PodsForm::field_types();
1685
+
1686
+ foreach ( $field_types as $type => $field_type_data ) {
1687
+ /**
1688
+ * @var $field_type PodsField
1689
+ */
1690
+ $field_type = PodsForm::field_loader( $type, $field_type_data[ 'file' ] );
1691
+
1692
+ $field_type_vars = get_class_vars( get_class( $field_type ) );
1693
+
1694
+ if ( !isset( $field_type_vars[ 'pod_types' ] ) )
1695
+ $field_type_vars[ 'pod_types' ] = true;
1696
+
1697
+ $options[ 'additional-field' ][ $type ] = array();
1698
+
1699
+ // Only show supported field types
1700
+ if ( true !== $field_type_vars[ 'pod_types' ] ) {
1701
+ if ( empty( $field_type_vars[ 'pod_types' ] ) )
1702
+ continue;
1703
+ elseif ( is_array( $field_type_vars[ 'pod_types' ] ) && !in_array( pods_var( 'type', $pod ), $field_type_vars[ 'pod_types' ] ) )
1704
+ continue;
1705
+ elseif ( !is_array( $field_type_vars[ 'pod_types' ] ) && pods_var( 'type', $pod ) != $field_type_vars[ 'pod_types' ] )
1706
+ continue;
1707
+ }
1708
+
1709
+ $options[ 'additional-field' ][ $type ] = PodsForm::ui_options( $type );
1710
+ }
1711
+
1712
+ $input_helpers = array(
1713
+ '' => '-- Select --'
1714
+ );
1715
+
1716
+ if ( class_exists( 'Pods_Helpers' ) ) {
1717
+ $helpers = pods_api()->load_helpers( array( 'options' => array( 'helper_type' => 'input' ) ) );
1718
+
1719
+ foreach ( $helpers as $helper ) {
1720
+ $input_helpers[ $helper[ 'name' ] ] = $helper[ 'name' ];
1721
+ }
1722
+ }
1723
+
1724
+ $options[ 'advanced' ] = array(
1725
+ __( 'Visual', 'pods' ) => array(
1726
+ 'class' => array(
1727
+ 'name' => 'class',
1728
+ 'label' => __( 'Additional CSS Classes', 'pods' ),
1729
+ 'help' => __( 'help', 'pods' ),
1730
+ 'type' => 'text',
1731
+ 'default' => ''
1732
+ ),
1733
+ 'input_helper' => array(
1734
+ 'name' => 'input_helper',
1735
+ 'label' => __( 'Input Helper', 'pods' ),
1736
+ 'help' => __( 'help', 'pods' ),
1737
+ 'type' => 'pick',
1738
+ 'default' => '',
1739
+ 'data' => $input_helpers
1740
+ )
1741
+ ),
1742
+ __( 'Values', 'pods' ) => array(
1743
+ 'default_value' => array(
1744
+ 'name' => 'default_value',
1745
+ 'label' => __( 'Default Value', 'pods' ),
1746
+ 'help' => __( 'help', 'pods' ),
1747
+ 'type' => 'text',
1748
+ 'default' => '',
1749
+ 'options' => array(
1750
+ 'text_max_length' => -1
1751
+ )
1752
+ ),
1753
+ 'default_value_parameter' => array(
1754
+ 'name' => 'default_value_parameter',
1755
+ 'label' => __( 'Set Default Value via Parameter', 'pods' ),
1756
+ 'help' => __( 'help', 'pods' ),
1757
+ 'type' => 'text',
1758
+ 'default' => ''
1759
+ )
1760
+ ),
1761
+ __( 'Visibility', 'pods' ) => array(
1762
+ 'restrict_access' => array(
1763
+ 'name' => 'restrict_access',
1764
+ 'label' => __( 'Restrict Access', 'pods' ),
1765
+ 'group' => array(
1766
+ 'admin_only' => array(
1767
+ 'name' => 'admin_only',
1768
+ 'label' => __( 'Restrict access to Admins?', 'pods' ),
1769
+ 'default' => 0,
1770
+ 'type' => 'boolean',
1771
+ 'dependency' => true,
1772
+ 'help' => __( 'This field will only be able to be edited by users with the ability to manage_options or delete_users, or super admins of a WordPress Multisite network', 'pods' )
1773
+ ),
1774
+ 'restrict_role' => array(
1775
+ 'name' => 'restrict_role',
1776
+ 'label' => __( 'Restrict access by Role?', 'pods' ),
1777
+ 'default' => 0,
1778
+ 'type' => 'boolean',
1779
+ 'dependency' => true
1780
+ ),
1781
+ 'restrict_capability' => array(
1782
+ 'name' => 'restrict_capability',
1783
+ 'label' => __( 'Restrict access by Capability?', 'pods' ),
1784
+ 'default' => 0,
1785
+ 'type' => 'boolean',
1786
+ 'dependency' => true
1787
+ ),
1788
+ 'hidden' => array(
1789
+ 'name' => 'hidden',
1790
+ 'label' => __( 'Hide field from UI', 'pods' ),
1791
+ 'default' => 0,
1792
+ 'type' => 'boolean',
1793
+ 'help' => __( 'This option is overriden by access restrictions. If the user does not have access to edit this field, it will be hidden. If no access restrictions are set, this field will always be hidden.', 'pods' )
1794
+ ),
1795
+ 'read_only' => array(
1796
+ 'name' => 'read_only',
1797
+ 'label' => __( 'Make field "Read Only" in UI', 'pods' ),
1798
+ 'default' => 0,
1799
+ 'type' => 'boolean',
1800
+ 'help' => __( 'This option is overriden by access restrictions. If the user does not have access to edit this field, it will be read only. If no access restrictions are set, this field will always be read only.', 'pods' ),
1801
+ 'depends-on' => array(
1802
+ 'type' => array(
1803
+ 'boolean',
1804
+ 'color',
1805
+ 'currency',
1806
+ 'date',
1807
+ 'datetime',
1808
+ 'email',
1809
+ 'number',
1810
+ 'paragraph',
1811
+ 'password',
1812
+ 'phone',
1813
+ 'slug',
1814
+ 'text',
1815
+ 'time',
1816
+ 'website'
1817
+ )
1818
+ )
1819
+ )
1820
+ )
1821
+ ),
1822
+ 'roles_allowed' => array(
1823
+ 'name' => 'roles_allowed',
1824
+ 'label' => __( 'Role(s) Allowed', 'pods' ),
1825
+ 'help' => __( 'help', 'pods' ),
1826
+ 'type' => 'pick',
1827
+ 'pick_object' => 'role',
1828
+ 'pick_format_type' => 'multi',
1829
+ 'default' => 'administrator',
1830
+ 'depends-on' => array(
1831
+ 'restrict_role' => true
1832
+ )
1833
+ ),
1834
+ 'capability_allowed' => array(
1835
+ 'name' => 'capability_allowed',
1836
+ 'label' => __( 'Capability Allowed', 'pods' ),
1837
+ 'help' => __( 'Comma-separated list of cababilities, for example add_podname_item, please see the Roles and Capabilities component for the complete list and a way to add your own.', 'pods' ),
1838
+ 'type' => 'text',
1839
+ 'default' => '',
1840
+ 'depends-on' => array(
1841
+ 'restrict_capability' => true
1842
+ )
1843
+ )
1844
+ /*,
1845
+ 'search' => array(
1846
+ 'label' => __( 'Include in searches', 'pods' ),
1847
+ 'help' => __( 'help', 'pods' ),
1848
+ 'default' => 1,
1849
+ 'type' => 'boolean',
1850
+ )*/
1851
+ )
1852
+ /*,
1853
+ __( 'Validation', 'pods' ) => array(
1854
+ 'regex_validation' => array(
1855
+ 'label' => __( 'RegEx Validation', 'pods' ),
1856
+ 'help' => __( 'help', 'pods' ),
1857
+ 'type' => 'text',
1858
+ 'default' => ''
1859
+ ),
1860
+ 'message_regex' => array(
1861
+ 'label' => __( 'Message if field does not pass RegEx', 'pods' ),
1862
+ 'help' => __( 'help', 'pods' ),
1863
+ 'type' => 'text',
1864
+ 'default' => ''
1865
+ ),
1866
+ 'message_required' => array(
1867
+ 'label' => __( 'Message if field is blank', 'pods' ),
1868
+ 'help' => __( 'help', 'pods' ),
1869
+ 'type' => 'text',
1870
+ 'default' => '',
1871
+ 'depends-on' => array( 'required' => true )
1872
+ ),
1873
+ 'message_unique' => array(
1874
+ 'label' => __( 'Message if field is not unique', 'pods' ),
1875
+ 'help' => __( 'help', 'pods' ),
1876
+ 'type' => 'text',
1877
+ 'default' => '',
1878
+ 'depends-on' => array( 'unique' => true )
1879
+ )
1880
+ )*/
1881
+ );
1882
+
1883
+ if ( !class_exists( 'Pods_Helpers' ) )
1884
+ unset( $options[ 'advanced' ][ 'input_helper' ] );
1885
+
1886
+ /**
1887
+ * Modify tabs and their contents for field options
1888
+ *
1889
+ * @since unknown
1890
+ *
1891
+ * @param array $options Tabs, indexed by label
1892
+ * @param object|Pods Pods object for the Pod this UI is for.
1893
+ */
1894
+ $options = apply_filters( 'pods_admin_setup_edit_field_options', $options, $pod );
1895
+
1896
+ return $options;
1897
+ }
1898
+
1899
+ /**
1900
+ * Duplicate a pod
1901
+ *
1902
+ * @param $id
1903
+ * @param $obj
1904
+ *
1905
+ * @return mixed
1906
+ */
1907
+ public function admin_setup_duplicate ( $obj ) {
1908
+ $new_id = pods_api()->duplicate_pod( array( 'id' => $obj->id ) );
1909
+
1910
+ if ( 0 < $new_id )
1911
+ pods_redirect( pods_query_arg( array( 'action' => 'edit', 'id' => $new_id, 'do' => 'duplicate' ) ) );
1912
+ }
1913
+
1914
+ /**
1915
+ * Restrict Duplicate action to custom types, not extended
1916
+ *
1917
+ * @param bool $restricted
1918
+ * @param array $restrict
1919
+ * @param string $action
1920
+ * @param array $row
1921
+ * @param PodsUI $obj
1922
+ *
1923
+ * @since 2.3.10
1924
+ *
1925
+ * @return bool
1926
+ */
1927
+ public function admin_setup_duplicate_restrict( $restricted, $restrict, $action, $row, $obj ) {
1928
+
1929
+ if ( in_array( $row[ 'real_type' ], array( 'user', 'media', 'comment' ) ) ) {
1930
+ $restricted = true;
1931
+ }
1932
+
1933
+ return $restricted;
1934
+
1935
+ }
1936
+
1937
+ /**
1938
+ * Reset a pod
1939
+ *
1940
+ * @param $obj
1941
+ *
1942
+ * @return mixed
1943
+ */
1944
+ public function admin_setup_reset ( $obj, $id ) {
1945
+ $pod = pods_api()->load_pod( array( 'id' => $id ), false );
1946
+
1947
+ if ( empty( $pod ) )
1948
+ return $obj->error( __( 'Pod not found.', 'pods' ) );
1949
+
1950
+ pods_api()->reset_pod( array( 'id' => $id ) );
1951
+
1952
+ $obj->message( __( 'Pod reset successfully.', 'pods' ) );
1953
+
1954
+ $obj->manage();
1955
+ }
1956
+
1957
+ /**
1958
+ * Restrict Reset action from users and media
1959
+ *
1960
+ * @param bool $restricted
1961
+ * @param array $restrict
1962
+ * @param string $action
1963
+ * @param array $row
1964
+ * @param PodsUI $obj
1965
+ *
1966
+ * @since 2.3.10
1967
+ */
1968
+ public function admin_setup_reset_restrict( $restricted, $restrict, $action, $row, $obj ) {
1969
+
1970
+ if ( in_array( $row[ 'real_type' ], array( 'user', 'media' ) ) ) {
1971
+ $restricted = true;
1972
+ }
1973
+
1974
+ return $restricted;
1975
+
1976
+ }
1977
+
1978
+ /**
1979
+ * Delete a pod
1980
+ *
1981
+ * @param $id
1982
+ * @param $obj
1983
+ *
1984
+ * @return mixed
1985
+ */
1986
+ public function admin_setup_delete ( $id, $obj ) {
1987
+ $pod = pods_api()->load_pod( array( 'id' => $id ), false );
1988
+
1989
+ if ( empty( $pod ) )
1990
+ return $obj->error( __( 'Pod not found.', 'pods' ) );
1991
+
1992
+ pods_api()->delete_pod( array( 'id' => $id ) );
1993
+
1994
+ unset( $obj->data[ $pod[ 'id' ] ] );
1995
+
1996
+ $obj->total = count( $obj->data );
1997
+ $obj->total_found = count( $obj->data );
1998
+
1999
+ $obj->message( __( 'Pod deleted successfully.', 'pods' ) );
2000
+ }
2001
+
2002
+ /**
2003
+ * Get advanced administration view.
2004
+ */
2005
+ public function admin_advanced () {
2006
+ pods_view( PODS_DIR . 'ui/admin/advanced.php', compact( array_keys( get_defined_vars() ) ) );
2007
+ }
2008
+
2009
+ /**
2010
+ * Get settings administration view
2011
+ */
2012
+ public function admin_settings () {
2013
+ pods_view( PODS_DIR . 'ui/admin/settings.php', compact( array_keys( get_defined_vars() ) ) );
2014
+ }
2015
+
2016
+ /**
2017
+ * Get components administration UI
2018
+ */
2019
+ public function admin_components () {
2020
+ if ( ! is_object( PodsInit::$components ) )
2021
+ return;
2022
+
2023
+ $components = PodsInit::$components->components;
2024
+
2025
+ $view = pods_var( 'view', 'get', 'all', null, true );
2026
+
2027
+ $recommended = array(
2028
+ 'advanced-relationships',
2029
+ 'advanced-content-types',
2030
+ 'migrate-packages',
2031
+ 'roles-and-capabilities',
2032
+ 'pages',
2033
+ 'table-storage',
2034
+ 'templates'
2035
+ );
2036
+
2037
+ foreach ( $components as $component => &$component_data ) {
2038
+ if ( !in_array( $view, array( 'all', 'recommended', 'dev' ) ) && ( !isset( $component_data[ 'Category' ] ) || $view != sanitize_title( $component_data[ 'Category' ] ) ) ) {
2039
+ unset( $components[ $component ] );
2040
+
2041
+ continue;
2042
+ }
2043
+ elseif ( 'recommended' == $view && !in_array( $component_data[ 'ID' ], $recommended ) ) {
2044
+ unset( $components[ $component ] );
2045
+
2046
+ continue;
2047
+ }
2048
+ elseif ( 'dev' == $view && pods_developer() && !pods_var_raw( 'DeveloperMode', $component_data, false ) ) {
2049
+ unset( $components[ $component ] );
2050
+
2051
+ continue;
2052
+ }
2053
+ elseif ( pods_var_raw( 'DeveloperMode', $component_data, false ) && !pods_developer() ) {
2054
+ unset( $components[ $component ] );
2055
+
2056
+ continue;
2057
+ }
2058
+ elseif ( !pods_var_raw( 'TablelessMode', $component_data, false ) && pods_tableless() ) {
2059
+ unset( $components[ $component ] );
2060
+
2061
+ continue;
2062
+ }
2063
+
2064
+ $component_data[ 'Name' ] = strip_tags( $component_data[ 'Name' ] );
2065
+
2066
+ if ( pods_var_raw( 'DeveloperMode', $component_data, false ) )
2067
+ $component_data[ 'Name' ] .= ' <em style="font-weight: normal; color:#333;">(Developer Preview)</em>';
2068
+
2069
+ $meta = array();
2070
+
2071
+ if ( !empty( $component_data[ 'Version' ] ) )
2072
+ $meta[] = 'Version ' . $component_data[ 'Version' ];
2073
+
2074
+ if ( empty( $component_data[ 'Author' ] ) ) {
2075
+ $component_data[ 'Author' ] = 'Pods Framework Team';
2076
+ $component_data[ 'AuthorURI' ] = 'http://pods.io/';
2077
+ }
2078
+
2079
+ if ( !empty( $component_data[ 'AuthorURI' ] ) )
2080
+ $component_data[ 'Author' ] = '<a href="' . $component_data[ 'AuthorURI' ] . '">' . $component_data[ 'Author' ] . '</a>';
2081
+
2082
+ $meta[] = sprintf( __( 'by %s', 'pods' ), $component_data[ 'Author' ] );
2083
+
2084
+ if ( !empty( $component_data[ 'URI' ] ) )
2085
+ $meta[] = '<a href="' . $component_data[ 'URI' ] . '">' . __( 'Visit component site', 'pods' ) . '</a>';
2086
+
2087
+ $component_data[ 'Description' ] = wpautop( trim( make_clickable( strip_tags( $component_data[ 'Description' ], 'em,strong' ) ) ) );
2088
+
2089
+ if ( !empty( $meta ) )
2090
+ $component_data[ 'Description' ] .= '<div class="pods-component-meta" ' . ( !empty( $component_data[ 'Description' ] ) ? ' style="padding:8px 0 4px;"' : '' ) . '>' . implode( '&nbsp;&nbsp;|&nbsp;&nbsp;', $meta ) . '</div>';
2091
+
2092
+ $component_data = array(
2093
+ 'id' => $component_data[ 'ID' ],
2094
+ 'name' => $component_data[ 'Name' ],
2095
+ 'category' => $component_data[ 'Category' ],
2096
+ 'version' => '',
2097
+ 'description' => $component_data[ 'Description' ],
2098
+ 'mustuse' => pods_var_raw( 'MustUse', $component_data, false ),
2099
+ 'toggle' => 0
2100
+ );
2101
+
2102
+ if ( !empty( $component_data[ 'category' ] ) ) {
2103
+ $category_url = pods_query_arg( array( 'view' => sanitize_title( $component_data[ 'category' ] ), 'pg' => '', 'page' => $_GET[ 'page' ] ) );
2104
+
2105
+ $component_data[ 'category' ] = '<a href="' . esc_url( $category_url ) . '">' . $component_data[ 'category' ] . '</a>';
2106
+ }
2107
+
2108
+ if ( isset( PodsInit::$components->settings[ 'components' ][ $component_data[ 'id' ] ] ) && 0 != PodsInit::$components->settings[ 'components' ][ $component_data[ 'id' ] ] )
2109
+ $component_data[ 'toggle' ] = 1;
2110
+ elseif ( $component_data[ 'mustuse' ] )
2111
+ $component_data[ 'toggle' ] = 1;
2112
+ }
2113
+
2114
+ $ui = array(
2115
+ 'data' => $components,
2116
+ 'total' => count( $components ),
2117
+ 'total_found' => count( $components ),
2118
+ 'items' => 'Components',
2119
+ 'item' => 'Component',
2120
+ 'fields' => array(
2121
+ 'manage' => array(
2122
+ 'name' => array(
2123
+ 'label' => __( 'Name', 'pods' ),
2124
+ 'width' => '30%',
2125
+ 'type' => 'text',
2126
+ 'options' => array(
2127
+ 'text_allow_html' => true
2128
+ )
2129
+ ),
2130
+ 'category' => array(
2131
+ 'label' => __( 'Category', 'pods' ),
2132
+ 'width' => '10%',
2133
+ 'type' => 'text',
2134
+ 'options' => array(
2135
+ 'text_allow_html' => true
2136
+ )
2137
+ ),
2138
+ 'description' => array(
2139
+ 'label' => __( 'Description', 'pods' ),
2140
+ 'width' => '60%',
2141
+ 'type' => 'text',
2142
+ 'options' => array(
2143
+ 'text_allow_html' => true,
2144
+ 'text_allowed_html_tags' => 'strong em a ul ol li b i br div'
2145
+ )
2146
+ )
2147
+ )
2148
+ ),
2149
+ 'actions_disabled' => array( 'duplicate', 'view', 'export', 'add', 'edit', 'delete' ),
2150
+ 'actions_custom' => array(
2151
+ 'toggle' => array(
2152
+ 'callback' => array( $this, 'admin_components_toggle' ),
2153
+ 'nonce' => true
2154
+ )
2155
+ ),
2156
+ 'filters_enhanced' => true,
2157
+ 'views' => array(
2158
+ 'all' => __( 'All', 'pods' ),
2159
+ //'recommended' => __( 'Recommended', 'pods' ),
2160
+ 'field-types' => __( 'Field Types', 'pods' ),
2161
+ 'tools' => __( 'Tools', 'pods' ),
2162
+ 'integration' => __( 'Integration', 'pods' ),
2163
+ 'migration' => __( 'Migration', 'pods' ),
2164
+ 'advanced' => __( 'Advanced', 'pods' )
2165
+ ),
2166
+ 'view' => $view,
2167
+ 'heading' => array(
2168
+ 'views' => __( 'Category', 'pods' )
2169
+ ),
2170
+ 'search' => false,
2171
+ 'searchable' => false,
2172
+ 'sortable' => false,
2173
+ 'pagination' => false
2174
+ );
2175
+
2176
+ if ( pods_developer() )
2177
+ $ui[ 'views' ][ 'dev' ] = __( 'Developer Preview', 'pods' );
2178
+
2179
+ pods_ui( $ui );
2180
+ }
2181
+
2182
+ /**
2183
+ * Toggle a component on or off
2184
+ *
2185
+ * @param PodsUI $ui
2186
+ *
2187
+ * @return bool
2188
+ */
2189
+ public function admin_components_toggle ( PodsUI $ui ) {
2190
+ $component = $_GET[ 'id' ];
2191
+
2192
+ if ( !empty( PodsInit::$components->components[ $component ][ 'PluginDependency' ] ) ) {
2193
+ $dependency = explode( '|', PodsInit::$components->components[ $component ][ 'PluginDependency' ] );
2194
+
2195
+ if ( !pods_is_plugin_active( $dependency[ 1 ] ) ) {
2196
+ $website = 'http://wordpress.org/extend/plugins/' . dirname( $dependency[ 1 ] ) . '/';
2197
+
2198
+ if ( isset( $dependency[ 2 ] ) )
2199
+ $website = $dependency[ 2 ];
2200
+
2201
+ if ( !empty( $website ) )
2202
+ $website = ' ' . sprintf( __( 'You can find it at %s', 'pods' ), '<a href="' . $website . '" target="_blank">' . $website . '</a>' );
2203
+
2204
+ $message = sprintf( __( 'The %s component requires that you have the <strong>%s</strong> plugin installed and activated.', 'pods' ), PodsInit::$components->components[ $component ][ 'Name' ], $dependency[ 0 ] ) . $website;
2205
+
2206
+ $ui->error( $message );
2207
+
2208
+ $ui->manage();
2209
+
2210
+ return;
2211
+ }
2212
+ }
2213
+
2214
+ if ( !empty( PodsInit::$components->components[ $component ][ 'ThemeDependency' ] ) ) {
2215
+ $dependency = explode( '|', PodsInit::$components->components[ $component ][ 'ThemeDependency' ] );
2216
+
2217
+ if ( strtolower( $dependency[ 1 ] ) != strtolower( get_template() ) && strtolower( $dependency[ 1 ] ) != strtolower( get_stylesheet() ) ) {
2218
+ $website = '';
2219
+
2220
+ if ( isset( $dependency[ 2 ] ) )
2221
+ $website = ' ' . sprintf( __( 'You can find it at %s', 'pods' ), '<a href="' . $dependency[ 2 ] . '" target="_blank">' . $dependency[ 2 ] . '</a>' );
2222
+
2223
+ $message = sprintf( __( 'The %s component requires that you have the <strong>%s</strong> theme installed and activated.', 'pods' ), PodsInit::$components->components[ $component ][ 'Name' ], $dependency[ 0 ] ) . $website;
2224
+
2225
+ $ui->error( $message );
2226
+
2227
+ $ui->manage();
2228
+
2229
+ return;
2230
+ }
2231
+ }
2232
+
2233
+ if ( !empty( PodsInit::$components->components[ $component ][ 'MustUse' ] ) ) {
2234
+ $message = sprintf( __( 'The %s component can not be disabled from here. You must deactivate the plugin or theme that added it.', 'pods' ), PodsInit::$components->components[ $component ][ 'Name' ] );
2235
+
2236
+ $ui->error( $message );
2237
+
2238
+ $ui->manage();
2239
+
2240
+ return;
2241
+ }
2242
+
2243
+ if ( '1' == pods_v( 'toggled' ) ) {
2244
+ $toggle = PodsInit::$components->toggle( $component );
2245
+
2246
+ if ( true === $toggle )
2247
+ $ui->message( PodsInit::$components->components[ $component ][ 'Name' ] . ' ' . __( 'Component enabled', 'pods' ) );
2248
+ elseif ( false === $toggle )
2249
+ $ui->message( PodsInit::$components->components[ $component ][ 'Name' ] . ' ' . __( 'Component disabled', 'pods' ) );
2250
+
2251
+ $components = PodsInit::$components->components;
2252
+
2253
+ foreach ( $components as $component => &$component_data ) {
2254
+ $toggle = 0;
2255
+
2256
+ if ( isset( PodsInit::$components->settings[ 'components' ][ $component_data[ 'ID' ] ] ) ) {
2257
+ if ( 0 != PodsInit::$components->settings[ 'components' ][ $component_data[ 'ID' ] ] )
2258
+ $toggle = 1;
2259
+ }
2260
+ if ( true === $component_data[ 'DeveloperMode' ] ) {
2261
+ if ( !pods_developer() ) {
2262
+ unset( $components[ $component ] );
2263
+ continue;
2264
+ }
2265
+ }
2266
+
2267
+ $component_data = array(
2268
+ 'id' => $component_data[ 'ID' ],
2269
+ 'name' => $component_data[ 'Name' ],
2270
+ 'description' => make_clickable( $component_data[ 'Description' ] ),
2271
+ 'version' => $component_data[ 'Version' ],
2272
+ 'author' => $component_data[ 'Author' ],
2273
+ 'toggle' => $toggle
2274
+ );
2275
+ }
2276
+
2277
+ $ui->data = $components;
2278
+
2279
+ pods_transient_clear( 'pods_components' );
2280
+
2281
+ $url = pods_query_arg( array( 'toggled' => null ) );
2282
+
2283
+ pods_redirect( $url );
2284
+ }
2285
+ elseif ( 1 == pods_var( 'toggle' ) )
2286
+ $ui->message( PodsInit::$components->components[ $component ][ 'Name' ] . ' ' . __( 'Component enabled', 'pods' ) );
2287
+ else
2288
+ $ui->message( PodsInit::$components->components[ $component ][ 'Name' ] . ' ' . __( 'Component disabled', 'pods' ) );
2289
+
2290
+ $ui->manage();
2291
+ }
2292
+
2293
+ /**
2294
+ * Get the admin upgrade page
2295
+ */
2296
+ public function admin_upgrade () {
2297
+ foreach ( PodsInit::$upgrades as $old_version => $new_version ) {
2298
+ if ( version_compare( $old_version, PodsInit::$version_last, '<=' ) && version_compare( PodsInit::$version_last, $new_version, '<' ) ) {
2299
+ $new_version = str_replace( '.', '_', $new_version );
2300
+
2301
+ pods_view( PODS_DIR . 'ui/admin/upgrade/upgrade_' . $new_version . '.php', compact( array_keys( get_defined_vars() ) ) );
2302
+
2303
+ break;
2304
+ }
2305
+ }
2306
+ }
2307
+
2308
+ /**
2309
+ * Get the admin help page
2310
+ */
2311
+ public function admin_help () {
2312
+ pods_view( PODS_DIR . 'ui/admin/help.php', compact( array_keys( get_defined_vars() ) ) );
2313
+ }
2314
+
2315
+ /**
2316
+ * Add pods specific capabilities.
2317
+ *
2318
+ * @param $capabilities List of extra capabilities to add
2319
+ *
2320
+ * @return array
2321
+ */
2322
+ public function admin_capabilities ( $capabilities ) {
2323
+ $pods = pods_api()->load_pods( array( 'type' => array( 'settings', 'post_type', 'taxonomy' ), 'fields' => false, 'table_info' => false ) );
2324
+ $other_pods = pods_api()->load_pods( array( 'type' => array( 'pod', 'table' ), 'table_info' => false ) );
2325
+
2326
+ $pods = array_merge( $pods, $other_pods );
2327
+
2328
+ $capabilities[] = 'pods';
2329
+ $capabilities[] = 'pods_content';
2330
+ $capabilities[] = 'pods_settings';
2331
+ $capabilities[] = 'pods_components';
2332
+
2333
+ foreach ( $pods as $pod ) {
2334
+ if ( 'settings' == $pod[ 'type' ] ) {
2335
+ $capabilities[] = 'pods_edit_' . $pod[ 'name' ];
2336
+ }
2337
+ elseif ( 'post_type' == $pod[ 'type' ] ) {
2338
+ $capability_type = pods_var( 'capability_type_custom', $pod[ 'options' ], pods_var_raw( 'name', $pod ) );
2339
+
2340
+ if ( 'custom' == pods_var( 'capability_type', $pod[ 'options' ] ) && 0 < strlen( $capability_type ) ) {
2341
+ $capabilities[] = 'read_' . $capability_type;
2342
+ $capabilities[] = 'edit_' . $capability_type;
2343
+ $capabilities[] = 'delete_' . $capability_type;
2344
+
2345
+ if ( 1 == pods_var( 'capability_type_extra', $pod[ 'options' ], 1 ) ) {
2346
+ $capability_type_plural = $capability_type . 's';
2347
+
2348
+ $capabilities[] = 'read_private_' . $capability_type_plural;
2349
+ $capabilities[] = 'edit_' . $capability_type_plural;
2350
+ $capabilities[] = 'edit_others_' . $capability_type_plural;
2351
+ $capabilities[] = 'edit_private_' . $capability_type_plural;
2352
+ $capabilities[] = 'edit_published_' . $capability_type_plural;
2353
+ $capabilities[] = 'publish_' . $capability_type_plural;
2354
+ $capabilities[] = 'delete_' . $capability_type_plural;
2355
+ $capabilities[] = 'delete_private_' . $capability_type_plural;
2356
+ $capabilities[] = 'delete_published_' . $capability_type_plural;
2357
+ $capabilities[] = 'delete_others_' . $capability_type_plural;
2358
+ }
2359
+ }
2360
+ }
2361
+ elseif ( 'taxonomy' == $pod[ 'type' ] ) {
2362
+ if ( 'custom' == pods_var( 'capability_type', $pod[ 'options' ], 'terms' ) ) {
2363
+ $capability_type = pods_var( 'capability_type_custom', $pod[ 'options' ], pods_var_raw( 'name', $pod ) . 's' );
2364
+
2365
+ $capability_type .= '_term';
2366
+ $capability_type_plural = $capability_type . 's';
2367
+
2368
+ // Singular
2369
+ $capabilities[] = 'edit_' . $capability_type;
2370
+ $capabilities[] = 'delete_' . $capability_type;
2371
+ $capabilities[] = 'assign_' . $capability_type;
2372
+ // Plural
2373
+ $capabilities[] = 'manage_' . $capability_type_plural;
2374
+ $capabilities[] = 'edit_' . $capability_type_plural;
2375
+ $capabilities[] = 'delete_' . $capability_type_plural;
2376
+ $capabilities[] = 'assign_' . $capability_type_plural;
2377
+ }
2378
+ }
2379
+ else {
2380
+ $capabilities[] = 'pods_add_' . $pod[ 'name' ];
2381
+ $capabilities[] = 'pods_edit_' . $pod[ 'name' ];
2382
+
2383
+ if ( isset( $pod[ 'fields' ][ 'author' ] ) && 'pick' == $pod[ 'fields' ][ 'author' ][ 'type' ] && 'user' == $pod[ 'fields' ][ 'author' ][ 'pick_object' ] )
2384
+ $capabilities[] = 'pods_edit_others_' . $pod[ 'name' ];
2385
+
2386
+ $capabilities[] = 'pods_delete_' . $pod[ 'name' ];
2387
+
2388
+ if ( isset( $pod[ 'fields' ][ 'author' ] ) && 'pick' == $pod[ 'fields' ][ 'author' ][ 'type' ] && 'user' == $pod[ 'fields' ][ 'author' ][ 'pick_object' ] )
2389
+ $capabilities[] = 'pods_delete_others_' . $pod[ 'name' ];
2390
+
2391
+ $actions_enabled = pods_var_raw( 'ui_actions_enabled', $pod[ 'options' ] );
2392
+
2393
+ if ( !empty( $actions_enabled ) )
2394
+ $actions_enabled = (array) $actions_enabled;
2395
+ else
2396
+ $actions_enabled = array();
2397
+
2398
+ $available_actions = array(
2399
+ 'add',
2400
+ 'edit',
2401
+ 'duplicate',
2402
+ 'delete',
2403
+ 'reorder',
2404
+ 'export'
2405
+ );
2406
+
2407
+ if ( !empty( $actions_enabled ) ) {
2408
+ $actions_disabled = array(
2409
+ 'view' => 'view'
2410
+ );
2411
+
2412
+ foreach ( $available_actions as $action ) {
2413
+ if ( !in_array( $action, $actions_enabled ) )
2414
+ $actions_disabled[ $action ] = $action;
2415
+ }
2416
+
2417
+ if ( !in_array( 'export', $actions_disabled ) )
2418
+ $capabilities[] = 'pods_export_' . $pod[ 'name' ];
2419
+
2420
+ if ( !in_array( 'reorder', $actions_disabled ) )
2421
+ $capabilities[] = 'pods_reorder_' . $pod[ 'name' ];
2422
+ }
2423
+ elseif ( 1 == pods_var( 'ui_export', $pod[ 'options' ], 0 ) )
2424
+ $capabilities[] = 'pods_export_' . $pod[ 'name' ];
2425
+ }
2426
+ }
2427
+
2428
+ return $capabilities;
2429
+ }
2430
+
2431
+ /**
2432
+ * Handle ajax calls for the administration
2433
+ */
2434
+ public function admin_ajax () {
2435
+ if ( false === headers_sent() ) {
2436
+ pods_session_start();
2437
+
2438
+ header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ) );
2439
+ }
2440
+
2441
+ // Sanitize input
2442
+ $params = pods_unslash( (array) $_POST );
2443
+
2444
+ foreach ( $params as $key => $value ) {
2445
+ if ( 'action' == $key )
2446
+ continue;
2447
+
2448
+ // Fixup $_POST data
2449
+ $_POST[ str_replace( '_podsfix_', '', $key ) ] = $_POST[ $key ];
2450
+
2451
+ // Fixup $params with unslashed data
2452
+ $params[ str_replace( '_podsfix_', '', $key ) ] = $value;
2453
+
2454
+ // Unset the _podsfix_* keys
2455
+ unset( $params[ $key ] );
2456
+ }
2457
+
2458
+ $params = (object) $params;
2459
+
2460
+ $methods = array(
2461
+ 'add_pod' => array( 'priv' => true ),
2462
+ 'save_pod' => array( 'priv' => true ),
2463
+ 'load_sister_fields' => array( 'priv' => true ),
2464
+ 'process_form' => array( 'custom_nonce' => true ), // priv handled through nonce
2465
+ 'upgrade' => array( 'priv' => true ),
2466
+ 'migrate' => array( 'priv' => true )
2467
+ );
2468
+
2469
+ /**
2470
+ * AJAX Callbacks in field editor
2471
+ *
2472
+ * @since unknown
2473
+ *
2474
+ * @param array $method Callback method map
2475
+ * @param object|PodsAdmin Class object
2476
+ */
2477
+ $methods = apply_filters( 'pods_admin_ajax_methods', $methods, $this );
2478
+
2479
+ if ( !isset( $params->method ) || !isset( $methods[ $params->method ] ) )
2480
+ pods_error( 'Invalid AJAX request', $this );
2481
+
2482
+ $defaults = array(
2483
+ 'priv' => null,
2484
+ 'name' => $params->method,
2485
+ 'custom_nonce' => null
2486
+ );
2487
+
2488
+ $method = (object) array_merge( $defaults, (array) $methods[ $params->method ] );
2489
+
2490
+ if ( true !== $method->custom_nonce && ( !isset( $params->_wpnonce ) || false === wp_verify_nonce( $params->_wpnonce, 'pods-' . $params->method ) ) )
2491
+ pods_error( __( 'Unauthorized request', 'pods' ), $this );
2492
+
2493
+ // Cleaning up $params
2494
+ unset( $params->action );
2495
+ unset( $params->method );
2496
+
2497
+ if ( true !== $method->custom_nonce )
2498
+ unset( $params->_wpnonce );
2499
+
2500
+ // Check permissions (convert to array to support multiple)
2501
+ if ( !empty( $method->priv ) && !pods_is_admin( array( 'pods' ) ) && true !== $method->priv && !pods_is_admin( $method->priv ) )
2502
+ pods_error( __( 'Access denied', 'pods' ), $this );
2503
+
2504
+ $params->method = $method->name;
2505
+
2506
+ $params = apply_filters( 'pods_api_' . $method->name, $params, $method );
2507
+
2508
+ $api = pods_api();
2509
+
2510
+ $api->display_errors = false;
2511
+
2512
+ if ( 'upgrade' == $method->name )
2513
+ $output = (string) pods_upgrade( $params->version )->ajax( $params );
2514
+ elseif ( 'migrate' == $method->name )
2515
+ $output = (string) apply_filters( 'pods_api_migrate_run', $params );
2516
+ else {
2517
+ if ( !method_exists( $api, $method->name ) )
2518
+ pods_error( 'API method does not exist', $this );
2519
+ elseif ( 'save_pod' == $method->name ) {
2520
+ if ( isset( $params->field_data_json ) && is_array( $params->field_data_json ) ) {
2521
+ $params->fields = $params->field_data_json;
2522
+
2523
+ unset( $params->field_data_json );
2524
+
2525
+ foreach ( $params->fields as $k => $v ) {
2526
+ if ( empty( $v ) )
2527
+ unset( $params->fields[ $k ] );
2528
+ elseif ( !is_array( $v ) )
2529
+ $params->fields[ $k ] = (array) @json_decode( $v, true );
2530
+ }
2531
+ }
2532
+ }
2533
+
2534
+ // Dynamically call the API method
2535
+ $params = (array) $params;
2536
+
2537
+ $output = call_user_func( array( $api, $method->name ), $params );
2538
+ }
2539
+
2540
+ // Output in json format
2541
+ if ( false !== $output ) {
2542
+
2543
+ /**
2544
+ * Pods Admin AJAX request was successful
2545
+ *
2546
+ * @since 2.6.8
2547
+ *
2548
+ * @param array $params AJAX parameters
2549
+ * @param array|object|string $output Output for AJAX request
2550
+ */
2551
+ do_action( "pods_admin_ajax_success_{$method->name}", $params, $output );
2552
+
2553
+ if ( is_array( $output ) || is_object( $output ) )
2554
+ wp_send_json( $output );
2555
+ else
2556
+ echo $output;
2557
+ }
2558
+ else
2559
+ pods_error( 'There was a problem with your request.' );
2560
+
2561
+ die(); // KBAI!
2562
+ }
2563
+
2564
+ /**
2565
+ * Profiles the Pods configuration
2566
+ *
2567
+ * @param null|string|array $pod. Optional. Which Pod(s) to get configuration for. Can be a the name of one Pod, or an array of names of Pods, or null, which is the default, to profile all Pods.
2568
+ * @param bool $full_field_info Optional. If true all info about each field is returned. If false, which is the default only name and type, will be returned.
2569
+ *
2570
+ * @return array
2571
+ *
2572
+ * @since 3.0.0
2573
+ */
2574
+ function configuration( $pod = null, $full_field_info = false ){
2575
+ $api = pods_api();
2576
+
2577
+ if ( is_null( $pod ) ) {
2578
+ $the_pods = $api->load_pods();
2579
+ }
2580
+ elseif( is_array( $pod ) ) {
2581
+ foreach ( $pod as $p ) {
2582
+ $the_pods[] = $api->load_pod( $p );
2583
+ }
2584
+ }
2585
+ else {
2586
+ $the_pods[] = $api->load_pod( $pod );
2587
+ }
2588
+
2589
+ foreach( $the_pods as $pod ) {
2590
+ $configuration[ $pod[ 'name' ] ] = array(
2591
+ 'name' => $pod['name'],
2592
+ 'ID' => $pod[ 'id' ],
2593
+ 'storage' => $pod[ 'storage' ],
2594
+ 'fields' => $pod[ 'fields' ],
2595
+ );
2596
+ }
2597
+
2598
+ if ( ! $full_field_info ) {
2599
+ foreach ( $the_pods as $pod ) {
2600
+ $fields = $configuration[ $pod['name'] ][ 'fields' ];
2601
+ unset( $configuration[ $pod['name'] ][ 'fields' ] );
2602
+ foreach ( $fields as $field ) {
2603
+ $info = array (
2604
+ 'name' => $field[ 'name' ],
2605
+ 'type' => $field[ 'type' ],
2606
+ );
2607
+
2608
+ if ( $info[ 'type' ] === 'pick' ) {
2609
+ $info[ 'pick_object' ] = $field[ 'pick_object' ];
2610
+ if ( isset ( $field[ 'pick_val' ] ) && $field[ 'pick_val' ] !== '' ) {
2611
+ $info[ 'pick_val' ] = $field[ 'pick_val' ];
2612
+ }
2613
+ }
2614
+
2615
+ if ( is_array( $info ) ) {
2616
+ $configuration[ $pod[ 'name' ] ][ 'fields' ][ $field[ 'name' ] ] = $info;
2617
+ }
2618
+
2619
+ unset( $info );
2620
+
2621
+ }
2622
+
2623
+ }
2624
+
2625
+ }
2626
+
2627
+ if ( is_array ( $configuration ) ) {
2628
+ return $configuration;
2629
+
2630
+ }
2631
+
2632
+ }
2633
+
2634
+ /**
2635
+ * Build UI for extending REST API, if makes sense to do so.
2636
+ *
2637
+ * @since 2.6.0
2638
+ *
2639
+ * @access protected
2640
+ */
2641
+ protected function rest_admin() {
2642
+ if( function_exists( 'register_rest_field' ) ) {
2643
+ add_filter( 'pods_admin_setup_edit_field_options', array( $this, 'add_rest_fields_to_field_editor' ), 12, 2 );
2644
+ add_filter( 'pods_admin_setup_edit_field_tabs', array( $this, 'add_rest_field_tab' ), 12 );
2645
+ }
2646
+
2647
+ add_filter( 'pods_admin_setup_edit_tabs', array( $this, 'add_rest_settings_tab' ), 12, 2 );
2648
+ add_filter( 'pods_admin_setup_edit_options', array( $this, 'add_rest_settings_tab_fields' ), 12, 2 );
2649
+
2650
+ }
2651
+
2652
+ /**
2653
+ * Check if Pod type <em>could</em> extend core REST API response
2654
+ *
2655
+ * @since 2.5.6
2656
+ *
2657
+ * @access protected
2658
+ *
2659
+ * @param array $pod
2660
+ *
2661
+ * @return bool
2662
+ */
2663
+ protected function restable_pod( $pod ) {
2664
+ $type = $pod[ 'type' ];
2665
+ if( in_array( $type, array(
2666
+ 'post_type',
2667
+ 'user',
2668
+ 'taxonomy'
2669
+ )
2670
+ )
2671
+ ) {
2672
+ return true;
2673
+
2674
+ }
2675
+
2676
+ }
2677
+
2678
+
2679
+ /**
2680
+ * Add a rest api tab.
2681
+ *
2682
+ * @since 2.6.0
2683
+ *
2684
+ * @param array $tabs
2685
+ * @param array $pod
2686
+ *
2687
+ * @return array
2688
+ */
2689
+ public function add_rest_settings_tab( $tabs, $pod ) {
2690
+
2691
+ $tabs[ 'rest-api' ] = __( 'REST API', 'pods' );
2692
+
2693
+ return $tabs;
2694
+
2695
+ }
2696
+
2697
+ /**
2698
+ * Populate REST API tab.
2699
+ *
2700
+ * @since 0.1.0
2701
+ *
2702
+ * @param array $options
2703
+ * @param array $pod
2704
+ *
2705
+ * @return array
2706
+ */
2707
+ public function add_rest_settings_tab_fields( $options, $pod ) {
2708
+ if ( ! function_exists( 'register_rest_field' ) ) {
2709
+ $options[ 'rest-api' ] = array(
2710
+ 'no_dependencies' => array(
2711
+ 'label' => __( sprintf( 'Pods REST API support requires WordPress 4.3.1 or later and the %s or later.', '<a href="http://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/" target="_blank">WordPress REST API 2.0-beta9</a>' ), 'pods' ),
2712
+ 'help' => __( sprintf( 'See %s for more information.', '<a href="http://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/" target="_blank">http://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/</a>'), 'pods' ),
2713
+ 'type' => 'html',
2714
+ ),
2715
+ );
2716
+ } elseif ( $this->restable_pod( $pod ) ) {
2717
+ $options[ 'rest-api' ] = array(
2718
+ 'rest_enable' => array(
2719
+ 'label' => __( 'Enable', 'pods' ),
2720
+ 'help' => __( 'Add REST API support for this Pod.', 'pods' ),
2721
+ 'type' => 'boolean',
2722
+ 'default' => '',
2723
+ 'dependency' => true,
2724
+ ),
2725
+ 'rest_base' => array(
2726
+ 'label' => __( 'REST Base', 'pods' ),
2727
+ 'help' => __( 'This will form the url for the route.', 'pods' ),
2728
+ 'type' => 'text',
2729
+ 'default' => pods_v( 'name', $pod ),
2730
+ 'boolean_yes_label' => '',
2731
+ 'depends-on' => array( 'rest_enable' => true ),
2732
+ ),
2733
+ 'read_all' => array(
2734
+ 'label' => __( 'Show All Fields?', 'pods' ),
2735
+ 'help' => __( 'Show all fields in REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ),
2736
+ 'type' => 'boolean',
2737
+ 'default' => '',
2738
+ 'boolean_yes_label' => '',
2739
+ 'depends-on' => array( 'rest_enable' => true ),
2740
+ ),
2741
+ 'write_all' => array(
2742
+ 'label' => __( 'Allow All Fields To Be Updated?', 'pods' ),
2743
+ 'help' => __( 'Allow all fields to be updated via the REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ),
2744
+ 'type' => 'boolean',
2745
+ 'default' => pods_v( 'name', $pod ),
2746
+ 'boolean_yes_label' => '',
2747
+ 'depends-on' => array( 'rest_enable' => true ),
2748
+ )
2749
+
2750
+ );
2751
+
2752
+ } else {
2753
+ $options[ 'rest-api' ] = array(
2754
+ 'not_restable' => array(
2755
+ 'label' => __( 'Pods REST API support covers post type, taxonomy and user Pods.', 'pods' ),
2756
+ 'help' => __( sprintf( 'See %s for more information.', '<a href="http://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/" target="_blank">http://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/"</a>'), 'pods' ),
2757
+ 'type' => 'html',
2758
+ ),
2759
+ );
2760
+
2761
+ }
2762
+
2763
+
2764
+ return $options;
2765
+
2766
+ }
2767
+
2768
+ /**
2769
+ * Add a REST API section to advanced tab of field editor.
2770
+ *
2771
+ * @since 2.5.6
2772
+ *
2773
+ * @param array $options
2774
+ * @param array $pod
2775
+ *
2776
+ * @return array
2777
+ */
2778
+ public function add_rest_fields_to_field_editor( $options, $pod ) {
2779
+
2780
+ if( $this->restable_pod( $pod ) ) {
2781
+ $options[ 'rest' ][ __( 'Read/ Write', 'pods' ) ] =
2782
+ array(
2783
+ 'rest_read' => array(
2784
+ 'label' => __( 'Read via REST API?', 'pods' ),
2785
+ 'help' => __( 'Should this field be readable via the REST API? You must enable REST API support for this Pod.', 'pods' ),
2786
+ 'type' => 'boolean',
2787
+ 'default' => '',
2788
+ ),
2789
+ 'rest_write' => array(
2790
+ 'label' => __( 'Write via REST API?', 'pods' ),
2791
+ 'help' => __( 'Should this field be readable via the REST API? You must enable REST API support for this Pod.', 'pods' ),
2792
+ 'type' => 'boolean',
2793
+ 'default' => '',
2794
+ ),
2795
+ );
2796
+ $options[ 'rest' ][ __( 'Relationship Field Options', 'pods' ) ] =
2797
+ array(
2798
+ 'rest_pick_response' => array(
2799
+ 'label' => __( 'Response Type', 'pods' ),
2800
+ 'help' => __( 'Should this field be readable via the REST API? You must enable REST API support for this Pod.', 'pods' ),
2801
+ 'type' => 'pick',
2802
+ 'default' => 'array',
2803
+ 'depends-on' => array( 'type' => 'pick' ),
2804
+ 'data' => array(
2805
+ 'array' => __( 'Full', 'pods' ),
2806
+ 'id' => __( 'ID only', 'pods' ),
2807
+ 'name' => __( 'Name', 'pods' )
2808
+
2809
+ ),
2810
+ ),
2811
+ 'rest_pick_depth' => array(
2812
+ 'label' => __( 'Depth', 'pods' ),
2813
+ 'help' => __( 'How far to traverse relationships in response', 'pods' ),
2814
+ 'type' => 'number',
2815
+ 'default' => '2',
2816
+ 'depends-on' => array( 'type' => 'pick' ),
2817
+
2818
+ )
2819
+
2820
+ );
2821
+
2822
+
2823
+ }
2824
+
2825
+ return $options;
2826
+
2827
+ }
2828
+
2829
+ /**
2830
+ * Add REST field tab
2831
+ *
2832
+ * @since 2.5.6
2833
+ *
2834
+ * @param array $tabs
2835
+ *
2836
+ * @return array
2837
+ */
2838
+ public function add_rest_field_tab( $tabs ) {
2839
+ $tabs[ 'rest' ] = __( 'REST API', 'pods' );
2840
+ return $tabs;
2841
+ }
2842
+
2843
+ }
classes/PodsArray.php ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Pods
4
+ */
5
+ class PodsArray implements ArrayAccess {
6
+
7
+ /**
8
+ * @var array|mixed
9
+ */
10
+ private $__container = array();
11
+
12
+ /**
13
+ * Alternative to get_object_vars to access an object as an array with simple functionality and accepts arrays to
14
+ * add additional functionality. Additional functionality includes validation and setting default data.
15
+ *
16
+ * @param mixed $container Object (or existing Array)
17
+ *
18
+ * @return \PodsArray
19
+ *
20
+ * @license http://www.gnu.org/licenses/gpl-2.0.html
21
+ * @since 2.0
22
+ */
23
+ public function __construct ( $container ) {
24
+ if ( is_array( $container ) || is_object( $container ) )
25
+ $this->__container = &$container;
26
+ }
27
+
28
+ /**
29
+ * Set value from array usage $object['offset'] = 'value';
30
+ *
31
+ * @param mixed $offset Used to set index of Array or Variable name on Object
32
+ * @param mixed $value Value to be set
33
+ *
34
+ * @return mixed|void
35
+ * @since 2.0
36
+ */
37
+ public function offsetSet ( $offset, $value ) {
38
+ if ( is_array( $this->__container ) )
39
+ $this->__container[ $offset ] = $value;
40
+ else
41
+ $this->__container->$offset = $value;
42
+ return $value;
43
+ }
44
+
45
+ /**
46
+ * Get value from array usage $object['offset'];
47
+ *
48
+ * @param mixed $offset Used to get value of Array or Variable on Object
49
+ *
50
+ * @return mixed|null
51
+ * @since 2.0
52
+ */
53
+ public function offsetGet ( $offset ) {
54
+ if ( is_array( $this->__container ) ) {
55
+ if ( isset( $this->__container[ $offset ] ) )
56
+ return $this->__container[ $offset ];
57
+ return null;
58
+ }
59
+ if ( isset( $this->__container->$offset ) )
60
+ return $this->__container->$offset;
61
+ return null;
62
+ }
63
+
64
+ /**
65
+ * Get value from array usage $object['offset'];
66
+ *
67
+ * @param mixed $offset Used to get value of Array or Variable on Object
68
+ *
69
+ * @return bool
70
+ * @since 2.0
71
+ */
72
+ public function offsetExists ( $offset ) {
73
+ if ( is_array( $this->__container ) )
74
+ return isset( $this->__container[ $offset ] );
75
+ return isset( $this->__container->$offset );
76
+ }
77
+
78
+ /**
79
+ * Get value from array usage $object['offset'];
80
+ *
81
+ * @param mixed $offset Used to unset index of Array or Variable on Object
82
+ *
83
+ * @since 2.0
84
+ */
85
+ public function offsetUnset ( $offset ) {
86
+ if ( is_array( $this->__container ) )
87
+ unset( $this->__container[ $offset ] );
88
+ else
89
+ unset( $this->__container->$offset );
90
+ }
91
+
92
+ /**
93
+ * Validate value on a specific type and set default (if empty)
94
+ *
95
+ * @param mixed $offset Used to get value of Array or Variable on Object
96
+ * @param mixed $default Used to set default value if it doesn't exist
97
+ * @param string $type Used to force a specific type of variable (allowed: array, object, integer, absint, boolean)
98
+ * @param mixed $extra Used in advanced types of variables
99
+ *
100
+ * @return array|bool|int|mixed|null|number|object
101
+ * @since 2.0
102
+ */
103
+ public function validate ( $offset, $default = null, $type = null, $extra = null ) {
104
+ if ( !$this->offsetExists( $offset ) )
105
+ $this->offsetSet( $offset, $default );
106
+
107
+ $value = $this->offsetGet( $offset );
108
+
109
+ if ( empty( $value ) && null !== $default && false !== $value )
110
+ $value = $default;
111
+ if ( 'array' == $type || 'array_merge' == $type ) {
112
+ if ( !is_array( $value ) )
113
+ $value = explode( ',', $value );
114
+
115
+ if ( 'array_merge' == $type && $value !== $default )
116
+ $value = array_merge( $default, $value );
117
+ }
118
+ elseif ( 'object' == $type || 'object_merge' == $type ) {
119
+ if ( !is_object( $value ) ) {
120
+ if ( !is_array( $value ) )
121
+ $value = explode( ',', $value );
122
+ $value = (object) $value;
123
+ }
124
+
125
+ if ( 'object_merge' == $type && $value !== $default )
126
+ $value = (object) array_merge( (array) $default, (array) $value );
127
+ }
128
+ elseif ( 'integer' == $type || 'int' == $type || 'absint' == $type ) {
129
+ if ( !is_numeric( trim( $value ) ) )
130
+ $value = 0;
131
+ else
132
+ $value = intval( $value );
133
+
134
+ if ( 'absint' == $type )
135
+ $value = abs( $value );
136
+ }
137
+ elseif ( 'boolean' == $type || 'bool' == $type )
138
+ $value = (boolean) $value;
139
+ elseif ( 'in_array' == $type && is_array( $default ) ) {
140
+ if ( is_array( $value ) ) {
141
+ foreach ( $value as $k => $v ) {
142
+ if ( !in_array( $v, $extra ) )
143
+ unset( $value[ $k ] );
144
+ }
145
+ }
146
+ elseif ( !in_array( $value, $extra ) )
147
+ $value = $default;
148
+ }
149
+ elseif ( 'isset' == $type && is_array( $default ) ) {
150
+ if ( is_array( $value ) ) {
151
+ foreach ( $value as $k => $v ) {
152
+ if ( !isset( $extra[ $v ] ) )
153
+ unset( $value[ $k ] );
154
+ }
155
+ }
156
+ elseif ( !isset( $extra[ $value ] ) )
157
+ $value = $default;
158
+ }
159
+
160
+ $this->offsetSet( $offset, $value );
161
+
162
+ return $value;
163
+ }
164
+
165
+ /**
166
+ * Dump the PodsArray object to array
167
+ *
168
+ * @return array Array version of the object
169
+ *
170
+ * @since 2.0
171
+ */
172
+ public function dump () {
173
+ if ( is_array( $this->__container ) )
174
+ return $this->__container;
175
+ return get_object_vars( $this->__container );
176
+ }
177
+
178
+ /**
179
+ * Mapping >> offsetSet
180
+ *
181
+ * @since 2.0
182
+ */
183
+ public function __set ( $offset, $value ) {
184
+ return $this->offsetSet( $offset, $value );
185
+ }
186
+
187
+ /**
188
+ * Mapping >> offsetGet
189
+ *
190
+ * @since 2.0
191
+ */
192
+ public function __get ( $offset ) {
193
+ return $this->offsetGet( $offset );
194
+ }
195
+
196
+ /**
197
+ * Mapping >> offsetExists
198
+ *
199
+ * @since 2.0
200
+ */
201
+ public function __isset ( $offset ) {
202
+ return $this->offsetExists( $offset );
203
+ }
204
+
205
+ /**
206
+ * Mapping >> offsetUnset
207
+ *
208
+ * @since 2.0
209
+ */
210
+ public function __unset ( $offset ) {
211
+ $this->offsetUnset( $offset );
212
+ }
213
+ }
classes/PodsComponent.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The base component class, all components should extend this.
4
+ *
5
+ * @package Pods
6
+ */
7
+ class PodsComponent {
8
+
9
+ /**
10
+ * Do things like register/enqueue scripts and stylesheets
11
+ *
12
+ * @return \PodsComponent
13
+ *
14
+ * @since 2.0
15
+ */
16
+ public function __construct () {
17
+
18
+ }
19
+
20
+ /**
21
+ * Add options and set defaults for component settings, shows in admin area
22
+ *
23
+ * @return array $options
24
+ *
25
+ * @since 2.0
26
+ public function options () {
27
+ $options = array(
28
+ 'option_name' => array(
29
+ 'label' => 'Option Label',
30
+ 'depends-on' => array( 'another_option' => 'specific-value' ),
31
+ 'default' => 'default-value',
32
+ 'type' => 'field_type',
33
+ 'data' => array(
34
+ 'value1' => 'Label 1',
35
+
36
+ // Group your options together
37
+ 'Option Group' => array(
38
+ 'gvalue1' => 'Option Label 1',
39
+ 'gvalue2' => 'Option Label 2'
40
+ ),
41
+
42
+ // below is only if the option_name above is the "{$fieldtype}_format_type"
43
+ 'value2' => array(
44
+ 'label' => 'Label 2',
45
+ 'regex' => '[a-zA-Z]' // Uses JS regex validation for the value saved if this option selected
46
+ )
47
+ ),
48
+
49
+ // below is only for a boolean group
50
+ 'group' => array(
51
+ 'option_boolean1' => array(
52
+ 'label' => 'Option boolean 1?',
53
+ 'default' => 1,
54
+ 'type' => 'boolean'
55
+ ),
56
+ 'option_boolean2' => array(
57
+ 'label' => 'Option boolean 2?',
58
+ 'default' => 0,
59
+ 'type' => 'boolean'
60
+ )
61
+ )
62
+ )
63
+ );
64
+
65
+ return $options;
66
+ }
67
+ */
68
+
69
+ /**
70
+ * Handler to run code based on $options
71
+ *
72
+ * @param $options
73
+ *
74
+ * @since 2.0
75
+ */
76
+ public function handler ( $options ) {
77
+ // run code based on $options set
78
+ }
79
+
80
+ /**
81
+ * Build admin area
82
+ *
83
+ * @param $options
84
+ *
85
+ * @since 2.0
86
+ public function admin ( $options ) {
87
+ // run code based on $options set
88
+ }
89
+ */
90
+ }
classes/PodsComponents.php ADDED
@@ -0,0 +1,742 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Component managing class
4
+ *
5
+ * @package Pods
6
+ */
7
+ class PodsComponents {
8
+
9
+ /**
10
+ * @var PodsComponents
11
+ */
12
+ static $instance = null;
13
+
14
+ /**
15
+ * Root of Components directory
16
+ *
17
+ * @var string
18
+ *
19
+ * @private
20
+ * @since 2.0
21
+ */
22
+ private $components_dir = null;
23
+
24
+ /**
25
+ * Available components
26
+ *
27
+ * @var array
28
+ *
29
+ * @since 2.0
30
+ */
31
+ public $components = array();
32
+
33
+ /**
34
+ * Components settings
35
+ *
36
+ * @var array
37
+ *
38
+ * @since 2.0
39
+ */
40
+ public $settings = array();
41
+
42
+ /**
43
+ * Singleton handling for a basic pods_components() request
44
+ *
45
+ * @return \PodsComponents
46
+ *
47
+ * @since 2.3.5
48
+ */
49
+ public static function init () {
50
+ if ( !is_object( self::$instance ) )
51
+ self::$instance = new PodsComponents();
52
+
53
+ return self::$instance;
54
+ }
55
+
56
+ /**
57
+ * Setup actions and get options
58
+ *
59
+ * @return \PodsComponents
60
+ *
61
+ * @since 2.0
62
+ */
63
+ public function __construct () {
64
+ $this->components_dir = realpath( apply_filters( 'pods_components_dir', PODS_DIR . 'components' ) ) . '/';
65
+
66
+ $settings = get_option( 'pods_component_settings', '' );
67
+
68
+ if ( !empty( $settings ) )
69
+ $this->settings = (array) json_decode( $settings, true );
70
+
71
+ if ( !isset( $this->settings[ 'components' ] ) )
72
+ $this->settings[ 'components' ] = array();
73
+
74
+ // Get components (give it access to theme)
75
+ add_action( 'setup_theme', array( $this, 'get_components' ), 11 );
76
+
77
+ // Load in components
78
+ add_action( 'setup_theme', array( $this, 'load' ), 12 );
79
+
80
+ // AJAX handling
81
+ if ( is_admin() ) {
82
+ add_action( 'wp_ajax_pods_admin_components', array( $this, 'admin_ajax' ) );
83
+ add_action( 'wp_ajax_nopriv_pods_admin_components', array( $this, 'admin_ajax' ) );
84
+
85
+ // Add the Pods Components capabilities
86
+ add_filter( 'members_get_capabilities', array( $this, 'admin_capabilities' ) );
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Add menu item
92
+ *
93
+ * @param string $parent The parent slug.
94
+ *
95
+ * @since 2.0
96
+ *
97
+ * @uses add_submenu_page
98
+ */
99
+ public function menu ( $parent ) {
100
+ global $submenu;
101
+
102
+ $custom_component_menus = array();
103
+
104
+ $pods_component_menu_items = array();
105
+
106
+ foreach ( $this->components as $component => $component_data ) {
107
+ $component_data[ 'MustUse' ] = apply_filters( 'pods_component_require_' . $component_data[ 'ID' ], $component_data[ 'MustUse' ], $component_data );
108
+
109
+ if ( empty( $component_data[ 'MustUse' ] ) && ( !isset( $this->settings[ 'components' ][ $component ] ) || 0 == $this->settings[ 'components' ][ $component ] ) )
110
+ continue;
111
+
112
+ if ( !empty( $component_data[ 'Hide' ] ) )
113
+ continue;
114
+
115
+ if ( !empty( $component_data[ 'DeveloperMode' ] ) && !pods_developer() )
116
+ continue;
117
+
118
+ if ( empty( $component_data[ 'TablelessMode' ] ) && pods_tableless() )
119
+ continue;
120
+
121
+ if ( empty( $component_data[ 'MenuPage' ] ) ) {
122
+ if ( !isset( $component_data[ 'object' ] ) )
123
+ continue;
124
+ elseif ( !method_exists( $component_data[ 'object' ], 'admin' ) && !method_exists( $component_data[ 'object' ], 'options' ) )
125
+ continue;
126
+ }
127
+
128
+ if ( false === $component_data[ 'External' ] )
129
+ $component_data[ 'File' ] = realpath( $this->components_dir . $component_data[ 'File' ] );
130
+
131
+ if ( !file_exists( $component_data[ 'File' ] ) ) {
132
+ pods_message( 'Pods Component not found: ' . $component_data[ 'File' ] );
133
+
134
+ pods_transient_clear( 'pods_components' );
135
+
136
+ continue;
137
+ }
138
+
139
+ $capability = 'pods_component_' . str_replace( '-', '_', sanitize_title( $component ) );
140
+
141
+ if ( 0 < strlen( $component_data[ 'Capability' ] ) )
142
+ $capability = $component_data[ 'Capability' ];
143
+
144
+ if ( !pods_is_admin( array( 'pods', 'pods_components', $capability ) ) )
145
+ continue;
146
+
147
+ $menu_page = 'pods-component-' . $component;
148
+
149
+ if ( !empty( $component_data[ 'MenuPage' ] ) )
150
+ $custom_component_menus[ $menu_page ] = $component_data;
151
+
152
+ $pods_component_menu_items[ $component_data[ 'MenuName' ] ] = array(
153
+ 'menu_page' => $menu_page,
154
+ 'page_title' => $component_data[ 'Name' ],
155
+ 'capability' => 'read',
156
+ 'callback' => array( $this, 'admin_handler' )
157
+ );
158
+
159
+ if ( isset( $component_data[ 'object' ] ) && method_exists( $component_data[ 'object' ], 'admin_assets' ) ) {
160
+ $pods_component_menu_items[ $component_data[ 'MenuName' ] ][ 'assets' ] = array( $component_data[ 'object' ], 'admin_assets' );
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Add or change the items in the Pods Components Submenu.
166
+ *
167
+ * Can also be used to change which menu components is a submenu of or change title of menu.
168
+ *
169
+ * @params array $pods_component_menu_items {
170
+ * An array of arguments for add_submenu_page
171
+ *
172
+ * @param string $parent_slug The slug name for the parent menu (or the file name of a standard WordPress admin page)
173
+ * @param string $page_title The text to be displayed in the title tags of the page when the menu is selected
174
+ * @param $menu_title The text to be used for the menu
175
+ * @param $capability The capability required for this menu to be displayed to the user.
176
+ * @param $menu_slug The slug name to refer to this menu by (should be unique for this menu)
177
+ * @param $function The function to be called to output the content for this page.
178
+ * }
179
+ *
180
+ * @returns array Array of submenu pages to be passed to add_submenu_page()
181
+ *
182
+ * @since 2.4.1
183
+ */
184
+ $pods_component_menu_items = apply_filters( 'pods_admin_components_menu', $pods_component_menu_items );
185
+
186
+ ksort( $pods_component_menu_items );
187
+
188
+ foreach ( $pods_component_menu_items as $menu_title => $menu_data ) {
189
+ if ( !is_callable( $menu_data[ 'callback' ] ) ) {
190
+ continue;
191
+ }
192
+
193
+ $page = add_submenu_page(
194
+ $parent,
195
+ strip_tags( $menu_data[ 'page_title' ] ),
196
+ '- ' . strip_tags( $menu_title ),
197
+ pods_v( 'capability', $menu_data, 'read', true ),
198
+ $menu_data[ 'menu_page' ],
199
+ $menu_data[ 'callback' ]
200
+ );
201
+
202
+ if ( isset( $menu_data[ 'assets' ] ) && is_callable( $menu_data[ 'assets' ] ) ) {
203
+ add_action( 'admin_print_styles-' . $page, $menu_data[ 'assets' ] );
204
+ }
205
+ }
206
+
207
+ if ( !empty( $custom_component_menus ) ) {
208
+ foreach ( $custom_component_menus as $menu_page => $component_data ) {
209
+ if ( isset( $submenu[ $parent ] ) ) {
210
+ foreach ( $submenu[ $parent ] as $sub => &$menu ) {
211
+ if ( $menu[ 2 ] == $menu_page ) {
212
+ $menu_page = $component_data[ 'MenuPage' ];
213
+
214
+ /*if ( !empty( $component_data[ 'MenuAddPage' ] ) ) {
215
+ if ( false !== strpos( $_SERVER[ 'REQUEST_URI' ], $component_data[ 'MenuAddPage' ] ) )
216
+ $menu_page = $component_data[ 'MenuAddPage' ];
217
+ }*/
218
+
219
+ $menu[ 2 ] = $menu_page;
220
+
221
+ $page = current( explode( '?', $menu[ 2 ] ) );
222
+
223
+ if ( isset( $component_data[ 'object' ] ) && method_exists( $component_data[ 'object' ], 'admin_assets' ) )
224
+ add_action( 'admin_print_styles-' . $page, array( $component_data[ 'object' ], 'admin_assets' ) );
225
+
226
+ break;
227
+ }
228
+ }
229
+ }
230
+ }
231
+ }
232
+ }
233
+
234
+ /**
235
+ * Load activated components and init component
236
+ *
237
+ * @since 2.0
238
+ */
239
+ public function load () {
240
+ do_action( 'pods_components_load' );
241
+
242
+ foreach ( (array) $this->components as $component => $component_data ) {
243
+ $component_data[ 'MustUse' ] = apply_filters( 'pods_component_require_' . $component_data[ 'ID' ], $component_data[ 'MustUse' ], $component_data );
244
+
245
+ if ( false === $component_data[ 'MustUse' ] && ( !isset( $this->settings[ 'components' ][ $component ] ) || 0 == $this->settings[ 'components' ][ $component ] ) )
246
+ continue;
247
+
248
+ if ( !empty( $component_data[ 'PluginDependency' ] ) ) {
249
+ $dependency = explode( '|', $component_data[ 'PluginDependency' ] );
250
+
251
+ if ( !pods_is_plugin_active( $dependency[ 1 ] ) )
252
+ continue;
253
+ }
254
+
255
+ if ( !empty( $component_data[ 'ThemeDependency' ] ) ) {
256
+ $dependency = explode( '|', $component_data[ 'ThemeDependency' ] );
257
+
258
+ if ( strtolower( $dependency[ 1 ] ) != strtolower( get_template() ) && strtolower( $dependency[ 1 ] ) != strtolower( get_stylesheet() ) )
259
+ continue;
260
+ }
261
+
262
+ if ( false === $component_data[ 'External' ] )
263
+ $component_data[ 'File' ] = realpath( $this->components_dir . $component_data[ 'File' ] );
264
+
265
+ if ( empty( $component_data[ 'File' ] ) ) {
266
+ pods_transient_clear( 'pods_components' );
267
+
268
+ continue;
269
+ }
270
+
271
+ if ( !file_exists( $component_data[ 'File' ] ) ) {
272
+ pods_message( 'Pods Component not found: ' . $component_data[ 'File' ] );
273
+
274
+ pods_transient_clear( 'pods_components' );
275
+
276
+ continue;
277
+ }
278
+
279
+ include_once $component_data[ 'File' ];
280
+
281
+ if ( ( !empty( $component_data[ 'Class' ] ) && class_exists( $component_data[ 'Class' ] ) ) || isset( $component_data[ 'object' ] ) ) {
282
+ if ( !isset( $this->components[ $component ][ 'object' ] ) )
283
+ $this->components[ $component ][ 'object' ] = new $component_data[ 'Class' ];
284
+
285
+ if ( method_exists( $this->components[ $component ][ 'object' ], 'options' ) ) {
286
+ if ( isset( $this->settings[ 'components' ][ $component ] ) )
287
+ $this->components[ $component ][ 'options' ] = $this->components[ $component ][ 'object' ]->options( $this->settings[ 'components' ][ $component ] );
288
+ else
289
+ $this->components[ $component ][ 'options' ] = $this->components[ $component ][ 'object' ]->options( array() );
290
+
291
+ $this->options( $component, $this->components[ $component ][ 'options' ] );
292
+ }
293
+ else
294
+ $this->options( $component, array() );
295
+
296
+ if ( method_exists( $this->components[ $component ][ 'object' ], 'handler' ) )
297
+ $this->components[ $component ][ 'object' ]->handler( $this->settings[ 'components' ][ $component ] );
298
+ }
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Get list of components available
304
+ *
305
+ * @since 2.0
306
+ */
307
+ public function get_components () {
308
+ $components = pods_transient_get( 'pods_components' );
309
+
310
+ if ( 1 == pods_var( 'pods_debug_components', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) )
311
+ $components = array();
312
+
313
+ if ( PodsInit::$version != PODS_VERSION || !is_array( $components ) || empty( $components ) || ( is_admin() && isset( $_GET[ 'page' ] ) && 'pods-components' == $_GET[ 'page' ] && 1 !== pods_transient_get( 'pods_components_refresh' ) ) ) {
314
+ do_action( 'pods_components_get' );
315
+
316
+ $component_dir = @opendir( untrailingslashit( $this->components_dir ) );
317
+ $component_files = array();
318
+
319
+ if ( false !== $component_dir ) {
320
+ while ( false !== ( $file = readdir( $component_dir ) ) ) {
321
+ if ( '.' == substr( $file, 0, 1 ) )
322
+ continue;
323
+ elseif ( is_dir( $this->components_dir . $file ) ) {
324
+ $component_subdir = @opendir( $this->components_dir . $file );
325
+
326
+ if ( $component_subdir ) {
327
+ while ( false !== ( $subfile = readdir( $component_subdir ) ) ) {
328
+ if ( '.' == substr( $subfile, 0, 1 ) )
329
+ continue;
330
+ elseif ( '.php' == substr( $subfile, -4 ) )
331
+ $component_files[] = str_replace( '\\', '/', $file . '/' . $subfile );
332
+ }
333
+
334
+ closedir( $component_subdir );
335
+ }
336
+ }
337
+ elseif ( '.php' == substr( $file, -4 ) )
338
+ $component_files[] = $file;
339
+ }
340
+
341
+ closedir( $component_dir );
342
+ }
343
+
344
+ $default_headers = array(
345
+ 'ID' => 'ID',
346
+ 'Name' => 'Name',
347
+ 'ShortName' => 'Short Name',
348
+ 'PluginName' => 'Plugin Name',
349
+ 'ComponentName' => 'Component Name',
350
+ 'URI' => 'URI',
351
+ 'MenuName' => 'Menu Name',
352
+ 'MenuPage' => 'Menu Page',
353
+ 'MenuAddPage' => 'Menu Add Page',
354
+ 'MustUse' => 'Must Use',
355
+ 'Description' => 'Description',
356
+ 'Version' => 'Version',
357
+ 'Category' => 'Category',
358
+ 'Author' => 'Author',
359
+ 'AuthorURI' => 'Author URI',
360
+ 'Class' => 'Class',
361
+ 'Hide' => 'Hide',
362
+ 'PluginDependency' => 'Plugin Dependency',
363
+ 'ThemeDependency' => 'Theme Dependency',
364
+ 'DeveloperMode' => 'Developer Mode',
365
+ 'TablelessMode' => 'Tableless Mode',
366
+ 'Capability' => 'Capability',
367
+ 'Plugin' => 'Plugin'
368
+ );
369
+
370
+ $component_files = apply_filters( 'pods_components_register', $component_files );
371
+
372
+ $components = array();
373
+
374
+ foreach ( $component_files as $component_file ) {
375
+ $external = false;
376
+
377
+ if ( is_array( $component_file ) && isset( $component_file[ 'File' ] ) ) {
378
+ $component = $component_file = $component_file[ 'File' ];
379
+
380
+ $external = true;
381
+ }
382
+ else
383
+ $component = $this->components_dir . $component_file;
384
+
385
+ if ( !is_readable( $component ) )
386
+ continue;
387
+
388
+ $component_data = get_file_data( $component, $default_headers, 'pods_component' );
389
+
390
+ if ( ( empty( $component_data[ 'Name' ] ) && empty( $component_data[ 'ComponentName' ] ) && empty( $component_data[ 'PluginName' ] ) ) || 'yes' == $component_data[ 'Hide' ] )
391
+ continue;
392
+
393
+ if ( isset( $component_data[ 'Plugin' ] ) && pods_is_plugin_active( $component_data[ 'Plugin' ] ) )
394
+ continue;
395
+
396
+ if ( empty( $component_data[ 'Name' ] ) ) {
397
+ if ( !empty( $component_data[ 'ComponentName' ] ) )
398
+ $component_data[ 'Name' ] = $component_data[ 'ComponentName' ];
399
+ elseif ( !empty( $component_data[ 'PluginName' ] ) )
400
+ $component_data[ 'Name' ] = $component_data[ 'PluginName' ];
401
+ }
402
+
403
+ if ( empty( $component_data[ 'ShortName' ] ) )
404
+ $component_data[ 'ShortName' ] = $component_data[ 'Name' ];
405
+
406
+ if ( empty( $component_data[ 'MenuName' ] ) )
407
+ $component_data[ 'MenuName' ] = $component_data[ 'Name' ];
408
+
409
+ if ( empty( $component_data[ 'Class' ] ) )
410
+ $component_data[ 'Class' ] = 'Pods_' . pods_js_name( basename( $component, '.php' ), false );
411
+
412
+ if ( empty( $component_data[ 'ID' ] ) )
413
+ $component_data[ 'ID' ] = $component_data[ 'Name' ];
414
+
415
+ $component_data[ 'ID' ] = sanitize_title( $component_data[ 'ID' ] );
416
+
417
+ if ( 'on' == strtolower( $component_data[ 'DeveloperMode' ] ) || 1 == $component_data[ 'DeveloperMode' ] )
418
+ $component_data[ 'DeveloperMode' ] = true;
419
+ else
420
+ $component_data[ 'DeveloperMode' ] = false;
421
+
422
+ if ( 'on' == strtolower( $component_data[ 'TablelessMode' ] ) || 1 == $component_data[ 'TablelessMode' ] )
423
+ $component_data[ 'TablelessMode' ] = true;
424
+ else
425
+ $component_data[ 'TablelessMode' ] = false;
426
+
427
+ $component_data[ 'External' ] = (boolean) $external;
428
+
429
+ if ( 'on' == strtolower($component_data[ 'MustUse' ] ) || '1' == $component_data[ 'MustUse' ] )
430
+ $component_data[ 'MustUse' ] = true;
431
+ elseif ( 'off' == strtolower($component_data[ 'MustUse' ] ) || '0' == $component_data[ 'MustUse' ] )
432
+ $component_data[ 'MustUse' ] = false;
433
+ else
434
+ $component_data[ 'MustUse' ] = $component_data[ 'External' ];
435
+
436
+ $component_data[ 'File' ] = $component_file;
437
+
438
+ $components[ $component_data[ 'ID' ] ] = $component_data;
439
+ }
440
+
441
+ ksort( $components );
442
+
443
+ pods_transient_set( 'pods_components_refresh', 1, ( 60 * 60 * 12 ) );
444
+
445
+ pods_transient_set( 'pods_components', $components );
446
+ }
447
+
448
+ if ( 1 == pods_var( 'pods_debug_components', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) )
449
+ pods_debug( $components );
450
+
451
+ $this->components = $components;
452
+
453
+ return $this->components;
454
+ }
455
+
456
+ /**
457
+ * Set component options
458
+ *
459
+ * @param $component
460
+ * @param $options
461
+ *
462
+ * @since 2.0
463
+ */
464
+ public function options ( $component, $options ) {
465
+ if ( !isset( $this->settings[ 'components' ][ $component ] ) || !is_array( $this->settings[ 'components' ][ $component ] ) )
466
+ $this->settings[ 'components' ][ $component ] = array();
467
+
468
+ foreach ( $options as $option => $data ) {
469
+ if ( !isset( $this->settings[ 'components' ][ $component ][ $option ] ) && isset( $data[ 'default' ] ) )
470
+ $this->settings[ 'components' ][ $component ][ $option ] = $data[ 'default' ];
471
+ }
472
+ }
473
+
474
+ /**
475
+ * Call component specific admin functions
476
+ *
477
+ * @since 2.0
478
+ */
479
+ public function admin_handler () {
480
+ $component = str_replace( 'pods-component-', '', $_GET[ 'page' ] );
481
+
482
+ if ( isset( $this->components[ $component ] ) && isset( $this->components[ $component ][ 'object' ] ) && is_object( $this->components[ $component ][ 'object' ] ) ) {
483
+ // Component init
484
+ if ( method_exists( $this->components[ $component ][ 'object' ], 'init' ) )
485
+ $this->components[ $component ][ 'object' ]->init( $this->settings[ 'components' ][ $component ], $component );
486
+
487
+ // Component Admin handler
488
+ if ( method_exists( $this->components[ $component ][ 'object' ], 'admin' ) )
489
+ $this->components[ $component ][ 'object' ]->admin( $this->settings[ 'components' ][ $component ], $component );
490
+ // Built-in Admin Handler
491
+ elseif ( method_exists( $this->components[ $component ][ 'object' ], 'options' ) )
492
+ $this->admin( $this->components[ $component ][ 'object' ]->options( $this->settings[ 'components' ][ $component ] ), $this->settings[ 'components' ][ $component ], $component );
493
+ }
494
+ }
495
+
496
+ public function admin ( $options, $settings, $component ) {
497
+ if ( !isset( $this->components[ $component ] ) )
498
+ wp_die( 'Invalid Component', '', array( 'back_link' => true ) );
499
+
500
+ $component_label = $this->components[ $component ][ 'Name' ];
501
+
502
+ include PODS_DIR . 'ui/admin/components-admin.php';
503
+ }
504
+
505
+ /**
506
+ * Check if a component is active or not
507
+ *
508
+ * @param string $component The component name to check if active
509
+ *
510
+ * @return bool
511
+ *
512
+ * @since 2.7
513
+ */
514
+ public function is_component_active( $component ) {
515
+
516
+ $active = false;
517
+
518
+ if ( isset( $this->components[ $component ] ) && isset( $this->settings[ 'components' ][ $component ] ) && 0 !== $this->settings[ 'components' ][ $component ] ) {
519
+ $active = true;
520
+ }
521
+
522
+ return $active;
523
+
524
+ }
525
+
526
+ /**
527
+ * Activate a component
528
+ *
529
+ * @param string $component The component name to activate
530
+ *
531
+ * @return boolean Whether the component was activated.
532
+ *
533
+ * @since 2.7
534
+ */
535
+ public function activate_component( $component ) {
536
+
537
+ $activated = false;
538
+
539
+ if ( ! $this->is_component_active( $component ) ) {
540
+ if ( empty( $this->components ) ) {
541
+ // Setup components
542
+ PodsInit::$components->get_components();
543
+ }
544
+
545
+ if ( isset( $this->components[ $component ] ) ) {
546
+ $this->settings['components'][ $component ] = array();
547
+
548
+ $settings = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $this->settings, JSON_UNESCAPED_UNICODE ) : json_encode( $this->settings );
549
+
550
+ update_option( 'pods_component_settings', $settings );
551
+
552
+ $activated = true;
553
+ }
554
+ } else {
555
+ $activated = true;
556
+ }
557
+
558
+ return $activated;
559
+
560
+ }
561
+
562
+ /**
563
+ * Deactivate a component
564
+ *
565
+ * @param string $component The component name to deactivate
566
+ *
567
+ * @since 2.7
568
+ */
569
+ public function deactivate_component( $component ) {
570
+
571
+ if ( $this->is_component_active( $component ) ) {
572
+ if ( isset( $this->components[ $component ] ) ) {
573
+ $this->settings[ 'components' ][ $component ] = 0;
574
+
575
+ $settings = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $this->settings, JSON_UNESCAPED_UNICODE ) : json_encode( $this->settings );
576
+
577
+ update_option( 'pods_component_settings', $settings );
578
+ }
579
+ }
580
+
581
+ }
582
+
583
+ /**
584
+ * Toggle a component on or off
585
+ *
586
+ * @param string $component The component name to toggle
587
+ *
588
+ * @return bool
589
+ *
590
+ * @since 2.0
591
+ */
592
+ public function toggle ( $component ) {
593
+
594
+ $toggle = null;
595
+
596
+ $toggle_mode = (int) pods_v( 'toggle', 'get' );
597
+
598
+ if ( 1 == $toggle_mode ) {
599
+ $this->activate_component( $component );
600
+ $toggle = true;
601
+ } else {
602
+ $this->deactivate_component( $component );
603
+ $toggle = false;
604
+ }
605
+
606
+ return $toggle;
607
+
608
+ }
609
+
610
+ /**
611
+ * Add pods specific capabilities.
612
+ *
613
+ * @param $capabilities List of extra capabilities to add
614
+ *
615
+ * @return array
616
+ */
617
+ public function admin_capabilities ( $capabilities ) {
618
+ foreach ( $this->components as $component => $component_data ) {
619
+ if ( !empty( $component_data[ 'Hide' ] ) )
620
+ continue;
621
+
622
+ if ( true === (boolean) pods_var( 'DeveloperMode', $component_data, false ) && !pods_developer() )
623
+ continue;
624
+
625
+ if ( true === (boolean) pods_var( 'TablelessMode', $component_data, false ) && !pods_developer() )
626
+ continue;
627
+
628
+ if ( empty( $component_data[ 'MenuPage' ] ) && ( !isset( $component_data[ 'object' ] ) || !method_exists( $component_data[ 'object' ], 'admin' ) ) )
629
+ continue;
630
+
631
+ $capability = 'pods_component_' . str_replace( '-', '_', sanitize_title( str_replace( ' and ', ' ', strip_tags( $component_data[ 'Name' ] ) ) ) );
632
+
633
+ if ( 0 < strlen ( $component_data[ 'Capability' ] ) )
634
+ $capability = $component_data[ 'Capability' ];
635
+
636
+ if ( !in_array( $capability, $capabilities ) )
637
+ $capabilities[] = $capability;
638
+ }
639
+
640
+ return $capabilities;
641
+ }
642
+
643
+ /**
644
+ * Handle admin ajax
645
+ *
646
+ * @since 2.0
647
+ */
648
+ public function admin_ajax () {
649
+ if ( false === headers_sent() ) {
650
+ pods_session_start();
651
+
652
+ header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ) );
653
+ }
654
+
655
+ // Sanitize input
656
+ $params = pods_unslash( (array) $_POST );
657
+
658
+ foreach ( $params as $key => $value ) {
659
+ if ( 'action' == $key )
660
+ continue;
661
+
662
+ unset( $params[ $key ] );
663
+
664
+ $params[ str_replace( '_podsfix_', '', $key ) ] = $value;
665
+ }
666
+
667
+ $params = (object) $params;
668
+
669
+ $component = $params->component;
670
+ $method = $params->method;
671
+
672
+ if ( !isset( $component ) || !isset( $this->components[ $component ] ) || !isset( $this->settings[ 'components' ][ $component ] ) )
673
+ pods_error( 'Invalid AJAX request', $this );
674
+
675
+ if ( !isset( $params->_wpnonce ) || false === wp_verify_nonce( $params->_wpnonce, 'pods-component-' . $component . '-' . $method ) )
676
+ pods_error( 'Unauthorized request', $this );
677
+
678
+ // Cleaning up $params
679
+ unset( $params->action );
680
+ unset( $params->component );
681
+ unset( $params->method );
682
+ unset( $params->_wpnonce );
683
+
684
+ $params = (object) apply_filters( 'pods_component_ajax_' . $component . '_' . $method, $params, $component, $method );
685
+
686
+ $output = false;
687
+
688
+ // Component init
689
+ if ( isset( $this->components[ $component ][ 'object' ] ) && method_exists( $this->components[ $component ][ 'object' ], 'init' ) )
690
+ $this->components[ $component ][ 'object' ]->init( $this->settings[ 'components' ][ $component ], $component );
691
+
692
+ // Handle internal methods
693
+ if ( isset( $this->components[ $component ][ 'object' ] ) && !method_exists( $this->components[ $component ][ 'object' ], 'ajax_' . $method ) && method_exists( $this, 'admin_ajax_' . $method ) )
694
+ $output = call_user_func( array( $this, 'admin_ajax_' . $method ), $component, $params );
695
+ // Make sure method exists
696
+ elseif ( !isset( $this->components[ $component ][ 'object' ] ) || !method_exists( $this->components[ $component ][ 'object' ], 'ajax_' . $method ) )
697
+ pods_error( 'API method does not exist', $this );
698
+ // Dynamically call the component method
699
+ else
700
+ $output = call_user_func( array( $this->components[ $component ][ 'object' ], 'ajax_' . $method ), $params );
701
+
702
+ if ( !is_bool( $output ) )
703
+ echo $output;
704
+
705
+ die(); // KBAI!
706
+ }
707
+
708
+ public function admin_ajax_settings ( $component, $params ) {
709
+ if ( !isset( $this->components[ $component ] ) )
710
+ wp_die( 'Invalid Component', '', array( 'back_link' => true ) );
711
+ elseif ( !method_exists( $this->components[ $component ][ 'object' ], 'options' ) )
712
+ pods_error( 'Component options method does not exist', $this );
713
+
714
+ $options = $this->components[ $component ][ 'object' ]->options( $this->settings[ 'components' ][ $component ] );
715
+
716
+ if ( empty( $this->settings[ 'components' ][ $component ] ) )
717
+ $this->settings[ 'components' ][ $component ] = array();
718
+
719
+ foreach ( $options as $field_name => $field_option ) {
720
+ $field_option = PodsForm::field_setup( $field_option, null, $field_option[ 'type' ] );
721
+
722
+ if ( !is_array( $field_option[ 'group' ] ) ) {
723
+ $field_value = pods_var_raw( 'pods_setting_' . $field_name, $params );
724
+
725
+ $this->settings[ 'components' ][ $component ][ $field_name ] = $field_value;
726
+ }
727
+ else {
728
+ foreach ( $field_option[ 'group' ] as $field_group_name => $field_group_option ) {
729
+ $field_value = pods_var_raw( 'pods_setting_' . $field_group_name, $params );
730
+
731
+ $this->settings[ 'components' ][ $component ][ $field_group_name ] = $field_value;
732
+ }
733
+ }
734
+ }
735
+
736
+ $settings = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $this->settings, JSON_UNESCAPED_UNICODE ) : json_encode( $this->settings );
737
+
738
+ update_option( 'pods_component_settings', $settings );
739
+
740
+ return '1';
741
+ }
742
+ }
classes/PodsData.php ADDED
@@ -0,0 +1,3099 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Pods
4
+ */
5
+ class PodsData {
6
+
7
+ /**
8
+ * @var PodsData
9
+ */
10
+ static $instance = null;
11
+
12
+ /**
13
+ * @var string
14
+ */
15
+ static protected $prefix = 'pods_';
16
+
17
+ /**
18
+ * @var array
19
+ */
20
+ static protected $field_types = array();
21
+
22
+ /**
23
+ * @var bool
24
+ */
25
+ public static $display_errors = true;
26
+
27
+ /**
28
+ * @var PodsAPI
29
+ */
30
+ public $api = null;
31
+
32
+ /**
33
+ * @var null
34
+ */
35
+ public $select = null;
36
+
37
+ /**
38
+ * @var null
39
+ */
40
+ public $table = null;
41
+
42
+ /**
43
+ * @var null
44
+ */
45
+ public $pod = null;
46
+
47
+ /**
48
+ * @var array|bool|mixed|null|void
49
+ */
50
+ public $pod_data = null;
51
+
52
+ /**
53
+ * @var int
54
+ */
55
+ public $id = 0;
56
+
57
+ /**
58
+ * @var string
59
+ */
60
+ public $field_id = 'id';
61
+
62
+ /**
63
+ * @var string
64
+ */
65
+ public $field_index = 'name';
66
+
67
+ /**
68
+ * @var string
69
+ */
70
+ public $field_slug = '';
71
+
72
+ /**
73
+ * @var string
74
+ */
75
+ public $join = '';
76
+
77
+ /**
78
+ * @var array
79
+ */
80
+ public $where = array();
81
+
82
+ /**
83
+ * @var array
84
+ */
85
+ public $where_default = array();
86
+
87
+ /**
88
+ * @var string
89
+ */
90
+ public $orderby = '';
91
+
92
+ /**
93
+ * @var array
94
+ */
95
+ public $fields = array();
96
+
97
+ /**
98
+ * @var array
99
+ */
100
+ public $aliases = array();
101
+
102
+ /**
103
+ * @var
104
+ */
105
+ public $detail_page;
106
+
107
+ // data
108
+ /**
109
+ * @var int
110
+ */
111
+ public $row_number = -1;
112
+
113
+ /**
114
+ * @var
115
+ */
116
+ public $data;
117
+
118
+ /**
119
+ * @var
120
+ */
121
+ public $row;
122
+
123
+ /**
124
+ * @var
125
+ */
126
+ public $insert_id;
127
+
128
+ /**
129
+ * @var
130
+ */
131
+ public $total;
132
+
133
+ /**
134
+ * @var
135
+ */
136
+ public $total_found;
137
+
138
+ /**
139
+ * @var bool
140
+ */
141
+ public $total_found_calculated;
142
+
143
+ // pagination
144
+ /**
145
+ * @var string
146
+ */
147
+ public $page_var = 'pg';
148
+
149
+ /**
150
+ * @var int
151
+ */
152
+ public $page = 1;
153
+
154
+ /**
155
+ * @var int
156
+ */
157
+ public $limit = 15;
158
+
159
+ /**
160
+ * @var bool
161
+ */
162
+ public $pagination = true;
163
+
164
+ // search
165
+ /**
166
+ * @var bool
167
+ */
168
+ public $search = true;
169
+
170
+ /**
171
+ * @var string
172
+ */
173
+ public $search_var = 'search';
174
+
175
+ /**
176
+ * @var string
177
+ */
178
+ public $search_mode = 'int'; // int | text | text_like
179
+ /**
180
+ * @var string
181
+ */
182
+ public $search_query = '';
183
+
184
+ /**
185
+ * @var array
186
+ */
187
+ public $search_fields = array();
188
+
189
+ /**
190
+ * @var string
191
+ */
192
+ public $search_where = array();
193
+
194
+ /**
195
+ * @var array
196
+ */
197
+ public $filters = array();
198
+
199
+ /**
200
+ * Holds Traversal information about Pods
201
+ *
202
+ * @var array
203
+ */
204
+ public $traversal = array();
205
+
206
+ /**
207
+ * Holds custom Traversals to be included
208
+ *
209
+ * @var array
210
+ */
211
+ public $traverse = array();
212
+
213
+ /**
214
+ * Last select() query SQL
215
+ *
216
+ * @var string
217
+ */
218
+ public $sql = false;
219
+
220
+ /**
221
+ * Last total sql
222
+ *
223
+ * @var string
224
+ */
225
+ public $total_sql = false;
226
+
227
+ /**
228
+ * Singleton handling for a basic pods_data() request
229
+ *
230
+ * @param string $pod Pod name
231
+ * @param integer $id Pod Item ID
232
+ * @param bool $strict If true throws an error if a pod is not found.
233
+ *
234
+ * @return \PodsData
235
+ *
236
+ * @since 2.3.5
237
+ */
238
+ public static function init ( $pod = null, $id = 0, $strict = true ) {
239
+ if ( ( true !== $pod && null !== $pod ) || 0 != $id )
240
+ return new PodsData( $pod, $id, $strict );
241
+ elseif ( !is_object( self::$instance ) )
242
+ self::$instance = new PodsData();
243
+ else {
244
+ $vars = get_class_vars( __CLASS__ );
245
+
246
+ foreach ( $vars as $var => $default ) {
247
+ if ( 'api' == $var )
248
+ continue;
249
+
250
+ self::$instance->{$var} = $default;
251
+ }
252
+ }
253
+
254
+ return self::$instance;
255
+ }
256
+
257
+ /**
258
+ * Data Abstraction Class for Pods
259
+ *
260
+ * @param string $pod Pod name
261
+ * @param integer $id Pod Item ID
262
+ * @param bool $strict If true throws an error if a pod is not found.
263
+ *
264
+ * @return \PodsData
265
+ *
266
+ * @license http://www.gnu.org/licenses/gpl-2.0.html
267
+ * @since 2.0
268
+ */
269
+ public function __construct ( $pod = null, $id = 0, $strict = true ) {
270
+ global $wpdb;
271
+
272
+ if ( is_object( $pod ) && 'PodsAPI' == get_class( $pod ) ) {
273
+ $this->api = $pod;
274
+ $pod = $this->api->pod;
275
+ }
276
+ else
277
+ $this->api = pods_api( $pod );
278
+
279
+ $this->api->display_errors =& self::$display_errors;
280
+
281
+ if ( !empty( $pod ) ) {
282
+ $this->pod_data =& $this->api->pod_data;
283
+
284
+ if ( false === $this->pod_data ) {
285
+ if ( true === $strict )
286
+ return pods_error( 'Pod not found', $this );
287
+ else
288
+ return $this;
289
+ }
290
+
291
+ $this->pod_id = $this->pod_data[ 'id' ];
292
+ $this->pod = $this->pod_data[ 'name' ];
293
+ $this->fields = $this->pod_data[ 'fields' ];
294
+
295
+ if ( isset( $this->pod_data[ 'options' ][ 'detail_url' ] ) )
296
+ $this->detail_page = $this->pod_data[ 'options' ][ 'detail_url' ];
297
+
298
+ if ( isset( $this->pod_data[ 'select' ] ) )
299
+ $this->select = $this->pod_data[ 'select' ];
300
+
301
+ if ( isset( $this->pod_data[ 'table' ] ) )
302
+ $this->table = $this->pod_data[ 'table' ];
303
+
304
+ if ( isset( $this->pod_data[ 'join' ] ) )
305
+ $this->join = $this->pod_data[ 'join' ];
306
+
307
+ if ( isset( $this->pod_data[ 'field_id' ] ) )
308
+ $this->field_id = $this->pod_data[ 'field_id' ];
309
+
310
+ if ( isset( $this->pod_data[ 'field_index' ] ) )
311
+ $this->field_index = $this->pod_data[ 'field_index' ];
312
+
313
+ if ( isset( $this->pod_data[ 'field_slug' ] ) )
314
+ $this->field_slug = $this->pod_data[ 'field_slug' ];
315
+
316
+ if ( isset( $this->pod_data[ 'where' ] ) )
317
+ $this->where = $this->pod_data[ 'where' ];
318
+
319
+ if ( isset( $this->pod_data[ 'where_default' ] ) )
320
+ $this->where_default = $this->pod_data[ 'where_default' ];
321
+
322
+ if ( isset( $this->pod_data[ 'orderby' ] ) )
323
+ $this->orderby = $this->pod_data[ 'orderby' ];
324
+
325
+ if ( 'settings' == $this->pod_data[ 'type' ] ) {
326
+ $this->id = $this->pod_data[ 'id' ];
327
+
328
+ $this->fetch( $this->id );
329
+ }
330
+ elseif ( null !== $id && !is_array( $id ) && !is_object( $id ) ) {
331
+ $this->id = $id;
332
+
333
+ $this->fetch( $this->id );
334
+ }
335
+ }
336
+ }
337
+
338
+ /**
339
+ * Handle tables like they are Pods (for traversal in select/build)
340
+ *
341
+ * @param array|string $table
342
+ * @param string $object
343
+ */
344
+ public function table ( $table, $object = '' ) {
345
+ global $wpdb;
346
+
347
+ if ( !is_array( $table ) ) {
348
+ $object_type = '';
349
+
350
+ if ( $wpdb->users == $table )
351
+ $object_type = 'user';
352
+ elseif ( $wpdb->posts == $table )
353
+ $object_type = 'post_type';
354
+ elseif ( $wpdb->terms == $table )
355
+ $object_type = 'taxonomy';
356
+ elseif ( $wpdb->options == $table )
357
+ $object_type = 'settings';
358
+ }
359
+
360
+ if ( !empty( $object_type ) )
361
+ $table = $this->api->get_table_info( $object_type, $object );
362
+
363
+ if ( !empty( $table ) && is_array( $table ) ) {
364
+ $table[ 'id' ] = pods_var( 'id', $table[ 'pod' ], 0, null, true );
365
+ $table[ 'name' ] = pods_var( 'name', $table[ 'pod' ], $table[ 'object_type' ], null, true );
366
+ $table[ 'type' ] = pods_var_raw( 'type', $table[ 'pod' ], $table[ 'object_type' ], null, true );
367
+
368
+ $default_storage = 'meta';
369
+
370
+ if ( 'taxonomy' == $table[ 'type' ] && ! function_exists( 'get_term_meta' ) ) {
371
+ $default_storage = 'none';
372
+ }
373
+
374
+ $table[ 'storage' ] = pods_var_raw( 'storage', $table[ 'pod' ], $default_storage, null, true );
375
+ $table[ 'fields' ] = pods_var_raw( 'fields', $table[ 'pod' ], array() );
376
+ $table[ 'object_fields' ] = pods_var_raw( 'object_fields', $table[ 'pod' ], $this->api->get_wp_object_fields( $table[ 'object_type' ] ), null, true );
377
+
378
+ $this->pod_data = $table;
379
+ $this->pod_id = $this->pod_data[ 'id' ];
380
+ $this->pod = $this->pod_data[ 'name' ];
381
+ $this->fields = $this->pod_data[ 'fields' ];
382
+
383
+ if ( isset( $this->pod_data[ 'select' ] ) )
384
+ $this->select = $this->pod_data[ 'select' ];
385
+
386
+ if ( isset( $this->pod_data[ 'table' ] ) )
387
+ $this->table = $this->pod_data[ 'table' ];
388
+
389
+ if ( isset( $this->pod_data[ 'join' ] ) )
390
+ $this->join = $this->pod_data[ 'join' ];
391
+
392
+ if ( isset( $this->pod_data[ 'field_id' ] ) )
393
+ $this->field_id = $this->pod_data[ 'field_id' ];
394
+
395
+ if ( isset( $this->pod_data[ 'field_index' ] ) )
396
+ $this->field_index = $this->pod_data[ 'field_index' ];
397
+
398
+ if ( isset( $this->pod_data[ 'field_slug' ] ) )
399
+ $this->field_slug = $this->pod_data[ 'field_slug' ];
400
+
401
+ if ( isset( $this->pod_data[ 'where' ] ) )
402
+ $this->where = $this->pod_data[ 'where' ];
403
+
404
+ if ( isset( $this->pod_data[ 'where_default' ] ) )
405
+ $this->where_default = $this->pod_data[ 'where_default' ];
406
+
407
+ if ( isset( $this->pod_data[ 'orderby' ] ) )
408
+ $this->orderby = $this->pod_data[ 'orderby' ];
409
+ }
410
+ }
411
+
412
+ /**
413
+ * Insert an item, eventually mapping to WPDB::insert
414
+ *
415
+ * @param string $table Table name
416
+ * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
417
+ * @param array $format (optional) An array of formats to be mapped to each of the value in $data.
418
+ *
419
+ * @return int|bool The ID of the item
420
+ *
421
+ * @uses wpdb::insert
422
+ *
423
+ * @since 2.0
424
+ */
425
+ public function insert ( $table, $data, $format = null ) {
426
+ /**
427
+ * @var $wpdb wpdb
428
+ */
429
+ global $wpdb;
430
+
431
+ if ( strlen( $table ) < 1 || empty( $data ) || !is_array( $data ) )
432
+ return false;
433
+
434
+ if ( empty( $format ) ) {
435
+ $format = array();
436
+
437
+ foreach ( $data as $field ) {
438
+ if ( isset( self::$field_types[ $field ] ) )
439
+ $format[] = self::$field_types[ $field ];
440
+ elseif ( isset( $wpdb->field_types[ $field ] ) )
441
+ $format[] = $wpdb->field_types[ $field ];
442
+ else
443
+ break;
444
+ }
445
+ }
446
+
447
+ list( $table, $data, $format ) = $this->do_hook( 'insert', array( $table, $data, $format ) );
448
+
449
+ $result = $wpdb->insert( $table, $data, $format );
450
+ $this->insert_id = $wpdb->insert_id;
451
+
452
+ if ( false !== $result )
453
+ return $this->insert_id;
454
+
455
+ return false;
456
+ }
457
+
458
+ /**
459
+ * @static
460
+ *
461
+ * Insert into a table, if unique key exists just update values.
462
+ *
463
+ * Data must be a key value pair array, keys act as table rows.
464
+ *
465
+ * Returns the prepared query from wpdb or false for errors
466
+ *
467
+ * @param string $table Name of the table to update
468
+ * @param array $data column => value pairs
469
+ * @param array $formats For $wpdb->prepare, uses sprintf formatting
470
+ *
471
+ * @return mixed Sanitized query string
472
+ *
473
+ * @uses wpdb::prepare
474
+ *
475
+ * @since 2.0
476
+ */
477
+ public static function insert_on_duplicate ( $table, $data, $formats = array() ) {
478
+ /**
479
+ * @var $wpdb wpdb
480
+ */
481
+ global $wpdb;
482
+
483
+ $columns = array_keys( $data );
484
+
485
+ $update = array();
486
+ $values = array();
487
+
488
+ foreach ( $columns as $column ) {
489
+ $update[] = "`{$column}` = VALUES( `{$column}` )";
490
+ $values[] = "%s";
491
+ }
492
+
493
+ if ( empty( $formats ) )
494
+ $formats = $values;
495
+
496
+ $columns_data = implode( '`, `', $columns );
497
+ $formats = implode( ", ", $formats );
498
+ $update = implode( ', ', $update );
499
+
500
+ $sql = "INSERT INTO `{$table}` ( `{$columns_data}` ) VALUES ( {$formats} ) ON DUPLICATE KEY UPDATE {$update}";
501
+
502
+ return $wpdb->prepare( $sql, $data );
503
+ }
504
+
505
+ /**
506
+ * Update an item, eventually mapping to WPDB::update
507
+ *
508
+ * @param string $table Table name
509
+ * @param array $data Data to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
510
+ * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw".
511
+ * @param array $format (optional) An array of formats to be mapped to each of the values in $data.
512
+ * @param array $where_format (optional) An array of formats to be mapped to each of the values in $where.
513
+ *
514
+ * @return bool
515
+ * @since 2.0
516
+ */
517
+ public function update ( $table, $data, $where, $format = null, $where_format = null ) {
518
+ /**
519
+ * @var $wpdb wpdb
520
+ */
521
+ global $wpdb;
522
+
523
+ if ( strlen( $table ) < 1 || empty( $data ) || !is_array( $data ) )
524
+ return false;
525
+
526
+ if ( empty( $format ) ) {
527
+ $format = array();
528
+
529
+ foreach ( $data as $field ) {
530
+ if ( isset( self::$field_types[ $field ] ) )
531
+ $form = self::$field_types[ $field ];
532
+ elseif ( isset( $wpdb->field_types[ $field ] ) )
533
+ $form = $wpdb->field_types[ $field ];
534
+ else
535
+ $form = '%s';
536
+
537
+ $format[] = $form;
538
+ }
539
+ }
540
+
541
+ if ( empty( $where_format ) ) {
542
+ $where_format = array();
543
+
544
+ foreach ( (array) array_keys( $where ) as $field ) {
545
+ if ( isset( self::$field_types[ $field ] ) )
546
+ $form = self::$field_types[ $field ];
547
+ elseif ( isset( $wpdb->field_types[ $field ] ) )
548
+ $form = $wpdb->field_types[ $field ];
549
+ else
550
+ $form = '%s';
551
+
552
+ $where_format[] = $form;
553
+ }
554
+ }
555
+
556
+ list( $table, $data, $where, $format, $where_format ) = $this->do_hook( 'update', array(
557
+ $table,
558
+ $data,
559
+ $where,
560
+ $format,
561
+ $where_format
562
+ ) );
563
+
564
+ $result = $wpdb->update( $table, $data, $where, $format, $where_format );
565
+
566
+ if ( false !== $result )
567
+ return true;
568
+
569
+ return false;
570
+ }
571
+
572
+ /**
573
+ * Delete an item
574
+ *
575
+ * @param string $table Table name
576
+ * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw".
577
+ * @param array $where_format (optional) An array of formats to be mapped to each of the values in $where.
578
+ *
579
+ * @return array|bool|mixed|null|void
580
+ *
581
+ * @uses PodsData::query
582
+ * @uses PodsData::prepare
583
+ *
584
+ * @since 2.0
585
+ */
586
+ public function delete ( $table, $where, $where_format = null ) {
587
+ /**
588
+ * @var $wpdb wpdb
589
+ */
590
+ global $wpdb;
591
+
592
+ if ( strlen( $table ) < 1 || empty( $where ) || !is_array( $where ) )
593
+ return false;
594
+
595
+ $wheres = array();
596
+ $where_formats = $where_format = (array) $where_format;
597
+
598
+ foreach ( (array) array_keys( $where ) as $field ) {
599
+ if ( !empty( $where_format ) )
600
+ $form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[ 0 ];
601
+ elseif ( isset( self::$field_types[ $field ] ) )
602
+ $form = self::$field_types[ $field ];
603
+ elseif ( isset( $wpdb->field_types[ $field ] ) )
604
+ $form = $wpdb->field_types[ $field ];
605
+ else
606
+ $form = '%s';
607
+
608
+ $wheres[] = "`{$field}` = {$form}";
609
+ }
610
+
611
+ $sql = "DELETE FROM `$table` WHERE " . implode( ' AND ', $wheres );
612
+
613
+ list( $sql, $where ) = $this->do_hook( 'delete', array(
614
+ $sql,
615
+ array_values( $where )
616
+ ), $table, $where, $where_format, $wheres );
617
+
618
+ return $this->query( self::prepare( $sql, $where ) );
619
+ }
620
+
621
+ /**
622
+ * Select items, eventually building dynamic query
623
+ *
624
+ * @param array $params
625
+ *
626
+ * @return array|bool|mixed
627
+ * @since 2.0
628
+ */
629
+ public function select ( $params ) {
630
+ global $wpdb;
631
+
632
+ $cache_key = $results = false;
633
+
634
+ $params = apply_filters( 'pods_data_pre_select_params', $params );
635
+
636
+ // Debug purposes
637
+ if ( 1 == pods_v( 'pods_debug_params', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) )
638
+ pods_debug( $params );
639
+
640
+ // Get from cache if enabled
641
+ if ( null !== pods_v( 'expires', $params, null, false ) ) {
642
+ $cache_key = md5( (string) $this->pod . serialize( $params ) );
643
+
644
+ $results = pods_view_get( $cache_key, pods_v( 'cache_mode', $params, 'cache', true ), 'pods_data_select' );
645
+
646
+ if ( empty( $results ) )
647
+ $results = false;
648
+ }
649
+
650
+ if ( empty( $results ) ) {
651
+ // Build
652
+ $this->sql = $this->build( $params );
653
+
654
+ // Debug purposes
655
+ if ( ( 1 == pods_v( 'pods_debug_sql', 'get', 0 ) || 1 == pods_v( 'pods_debug_sql_all', 'get', 0 ) ) && pods_is_admin( array( 'pods' ) ) )
656
+ echo '<textarea cols="100" rows="24">' . esc_textarea( str_replace( array( '@wp_users', '@wp_' ), array( $wpdb->users, $wpdb->prefix ), $this->sql ) ) . '</textarea>';
657
+
658
+ if ( empty( $this->sql ) )
659
+ return array();
660
+
661
+ // Get Data
662
+ $results = pods_query( $this->sql, $this );
663
+
664
+ // Cache if enabled
665
+ if ( false !== $cache_key )
666
+ pods_view_set( $cache_key, $results, pods_v( 'expires', $params, 0, false ), pods_v( 'cache_mode', $params, 'cache', true ), 'pods_data_select' );
667
+ }
668
+
669
+ $results = apply_filters( 'pods_data_select', $results, $params, $this );
670
+
671
+ $this->data = $results;
672
+
673
+ $this->row_number = -1;
674
+ $this->row = null;
675
+
676
+ // Fill in empty field data (if none provided)
677
+ if ( ( !isset( $this->fields ) || empty( $this->fields ) ) && !empty( $this->data ) ) {
678
+ $this->fields = array();
679
+ $data = (array) @current( $this->data );
680
+
681
+ foreach ( $data as $data_key => $data_value ) {
682
+ $this->fields[ $data_key ] = array( 'label' => ucwords( str_replace( '-', ' ', str_replace( '_', ' ', $data_key ) ) ) );
683
+ if ( isset( $this->pod_data[ 'object_fields' ][ $data_key ] ) ) {
684
+ $this->fields[ $data_key ] = $this->pod_data[ 'object_fields' ][ $data_key ];
685
+ }
686
+ }
687
+
688
+ $this->fields = PodsForm::fields_setup( $this->fields );
689
+ }
690
+
691
+ $this->total_found_calculated = false;
692
+
693
+ $this->total = 0;
694
+
695
+ if ( ! empty( $this->data ) ) {
696
+ $this->total = count( (array) $this->data );
697
+ }
698
+
699
+ return $this->data;
700
+ }
701
+
702
+ public function calculate_totals () {
703
+ /**
704
+ * @var $wpdb wpdb
705
+ */
706
+ global $wpdb;
707
+
708
+ // Set totals
709
+ if ( false !== $this->total_sql )
710
+ $total = @current( $wpdb->get_col( $this->get_sql( $this->total_sql ) ) );
711
+ else
712
+ $total = @current( $wpdb->get_col( "SELECT FOUND_ROWS()" ) );
713
+
714
+ $total = $this->do_hook( 'select_total', $total );
715
+ $this->total_found = 0;
716
+ $this->total_found_calculated = true;
717
+
718
+ if ( is_numeric( $total ) )
719
+ $this->total_found = $total;
720
+ }
721
+
722
+ /**
723
+ * Build/Rewrite dynamic SQL and handle search/filter/sort
724
+ *
725
+ * @param array $params
726
+ *
727
+ * @return bool|mixed|string
728
+ * @since 2.0
729
+ */
730
+ public function build ( $params ) {
731
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
732
+ $file_field_types = PodsForm::file_field_types();
733
+
734
+ $defaults = array(
735
+ 'select' => '*',
736
+ 'calc_rows' => false,
737
+ 'distinct' => true,
738
+ 'table' => null,
739
+ 'join' => null,
740
+ 'where' => null,
741
+ 'groupby' => null,
742
+ 'having' => null,
743
+ 'orderby' => null,
744
+ 'limit' => -1,
745
+ 'offset' => null,
746
+
747
+ 'id' => null,
748
+ 'index' => null,
749
+
750
+ 'page' => 1,
751
+ 'pagination' => $this->pagination,
752
+ 'search' => $this->search,
753
+ 'search_query' => null,
754
+ 'search_mode' => null,
755
+ 'search_across' => false,
756
+ 'search_across_picks' => false,
757
+ 'search_across_files' => false,
758
+ 'filters' => array(),
759
+
760
+ 'fields' => array(),
761
+ 'object_fields' => array(),
762
+ 'pod_table_prefix' => null,
763
+
764
+ 'traverse' => array(),
765
+
766
+ 'sql' => null,
767
+
768
+ 'strict' => false
769
+ );
770
+
771
+ $params = (object) array_merge( $defaults, (array) $params );
772
+
773
+ if ( 0 < strlen( $params->sql ) )
774
+ return $params->sql;
775
+
776
+ $pod = false;
777
+
778
+ if ( is_array( $this->pod_data ) ) {
779
+ $pod = $this->pod_data;
780
+ }
781
+
782
+ // Validate
783
+ $params->page = pods_absint( $params->page );
784
+
785
+ $params->pagination = (boolean) $params->pagination;
786
+
787
+ if ( 0 == $params->page || !$params->pagination )
788
+ $params->page = 1;
789
+
790
+ $params->limit = (int) $params->limit;
791
+
792
+ if ( 0 == $params->limit )
793
+ $params->limit = -1;
794
+
795
+ $this->limit = $params->limit;
796
+
797
+ $offset = ( $params->limit * ( $params->page - 1 ) );
798
+
799
+ if ( 0 < (int) $params->offset )
800
+ $params->offset += $offset;
801
+ else
802
+ $params->offset = $offset;
803
+
804
+ if ( !$params->pagination || -1 == $params->limit ) {
805
+ $params->page = 1;
806
+ $params->offset = 0;
807
+ }
808
+
809
+ if ( ( empty( $params->fields ) || !is_array( $params->fields ) ) && !empty( $pod ) && isset( $this->fields ) && !empty( $this->fields ) )
810
+ $params->fields = $this->fields;
811
+
812
+ if ( ( empty( $params->object_fields ) || !is_array( $params->object_fields ) ) && !empty( $pod ) && isset( $pod[ 'object_fields' ] ) && !empty( $pod[ 'object_fields' ] ) )
813
+ $params->object_fields = $pod[ 'object_fields' ];
814
+
815
+ if ( empty( $params->filters ) && $params->search )
816
+ $params->filters = array_keys( $params->fields );
817
+ elseif ( empty( $params->filters ) )
818
+ $params->filters = array();
819
+
820
+ if ( empty( $params->index ) )
821
+ $params->index = $this->field_index;
822
+
823
+ if ( empty( $params->id ) )
824
+ $params->id = $this->field_id;
825
+
826
+ if ( empty( $params->table ) && !empty( $pod ) && isset( $this->table ) && !empty( $this->table ) )
827
+ $params->table = $this->table;
828
+
829
+ if ( empty( $params->pod_table_prefix ) )
830
+ $params->pod_table_prefix = 't';
831
+
832
+ if ( !empty( $pod ) && !in_array( $pod[ 'type' ], array( 'pod', 'table' ) ) && 'table' == $pod[ 'storage' ] )
833
+ $params->pod_table_prefix = 'd';
834
+
835
+ $params->meta_fields = false;
836
+
837
+ if ( !empty( $pod ) && !in_array( $pod[ 'type' ], array( 'pod', 'table' ) ) && ( 'meta' == $pod[ 'storage' ] || ( 'none' == $pod[ 'storage' ] && function_exists( 'get_term_meta' ) ) ) )
838
+ $params->meta_fields = true;
839
+
840
+ if ( empty( $params->table ) )
841
+ return false;
842
+
843
+ if ( false === strpos( $params->table, '(' ) && false === strpos( $params->table, '`' ) )
844
+ $params->table = '`' . $params->table . '`';
845
+
846
+ if ( !empty( $params->join ) )
847
+ $params->join = array_merge( (array) $this->join, (array) $params->join );
848
+ elseif ( false === $params->strict )
849
+ $params->join = $this->join;
850
+
851
+ $params->where_defaulted = false;
852
+ $params->where_default = $this->where_default;
853
+
854
+ if ( false === $params->strict ) {
855
+ // Set default where
856
+ if ( !empty( $this->where_default ) && empty( $params->where ) ) {
857
+ $params->where = array_values( (array) $this->where_default );
858
+
859
+ $params->where_defaulted = true;
860
+ }
861
+
862
+ if ( !empty( $this->where ) ) {
863
+ if ( is_array( $params->where ) && isset( $params->where[ 'relation' ] ) && 'OR' == strtoupper( $params->where[ 'relation' ] ) ) {
864
+ $params->where = array_merge( array( $params->where ), array_values( (array) $this->where ) );
865
+ }
866
+ else {
867
+ $params->where = array_merge( (array) $params->where, array_values( (array) $this->where ) );
868
+ }
869
+ }
870
+ }
871
+
872
+ // Allow where array ( 'field' => 'value' ) and WP_Query meta_query syntax
873
+ if ( ! empty( $params->where ) ) {
874
+ $params->where = $this->query_fields( (array) $params->where, $pod, $params );
875
+ }
876
+
877
+ if ( empty( $params->where ) ) {
878
+ $params->where = array();
879
+ } else {
880
+ $params->where = (array) $params->where;
881
+ }
882
+
883
+ // Allow having array ( 'field' => 'value' ) and WP_Query meta_query syntax
884
+ if ( ! empty( $params->having ) ) {
885
+ $params->having = $this->query_fields( (array) $params->having, $pod, $params );
886
+ }
887
+
888
+ if ( empty( $params->having ) ) {
889
+ $params->having = array();
890
+ } else {
891
+ $params->having = (array) $params->having;
892
+ }
893
+
894
+ if ( !empty( $params->orderby ) ) {
895
+ if ( 'post_type' == $pod[ 'type' ] && 'meta' == $pod[ 'storage' ] && is_array( $params->orderby ) ) {
896
+
897
+ foreach ( $params->orderby as $i => $orderby ) {
898
+ if ( strpos( $orderby, '.meta_value_num' ) ) {
899
+ $params->orderby[ $i ] = 'CAST(' . str_replace( '.meta_value_num', '.meta_value', $orderby ) . ' AS DECIMAL)';
900
+ } elseif ( strpos( $orderby, '.meta_value_date' ) ) {
901
+ $params->orderby[ $i ] = 'CAST(' . str_replace( '.meta_value_date', '.meta_value', $orderby ) . ' AS DATE)';
902
+ }
903
+
904
+ }
905
+
906
+ }
907
+
908
+ $params->orderby = (array) $params->orderby;
909
+ } else {
910
+ $params->orderby = array();
911
+ }
912
+
913
+
914
+ if ( false === $params->strict && !empty( $this->orderby ) )
915
+ $params->orderby = array_merge( $params->orderby, (array) $this->orderby );
916
+
917
+ if ( !empty( $params->traverse ) )
918
+ $this->traverse = $params->traverse;
919
+
920
+ $allowed_search_modes = array( 'int', 'text', 'text_like' );
921
+
922
+ if ( !empty( $params->search_mode ) && in_array( $params->search_mode, $allowed_search_modes ) )
923
+ $this->search_mode = $params->search_mode;
924
+
925
+ $params->search = (boolean) $params->search;
926
+
927
+ if ( 1 == pods_v( 'pods_debug_params_all', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) )
928
+ pods_debug( $params );
929
+
930
+ $params->field_table_alias = 't';
931
+
932
+ // Get Aliases for future reference
933
+ $selectsfound = '';
934
+
935
+ if ( !empty( $params->select ) ) {
936
+ if ( is_array( $params->select ) )
937
+ $selectsfound = implode( ', ', $params->select );
938
+ else
939
+ $selectsfound = $params->select;
940
+ }
941
+
942
+ // Pull Aliases from SQL query too
943
+ if ( null !== $params->sql ) {
944
+ $temp_sql = ' ' . trim( str_replace( array( "\n", "\r" ), ' ', $params->sql ) );
945
+ $temp_sql = preg_replace( array(
946
+ '/\sSELECT\sSQL_CALC_FOUND_ROWS\s/i',
947
+ '/\sSELECT\s/i'
948
+ ),
949
+ array(
950
+ ' SELECT ',
951
+ ' SELECT SQL_CALC_FOUND_ROWS '
952
+ ),
953
+ $temp_sql );
954
+ preg_match( '/\sSELECT SQL_CALC_FOUND_ROWS\s(.*)\sFROM/i', $temp_sql, $selectmatches );
955
+ if ( isset( $selectmatches[ 1 ] ) && !empty( $selectmatches[ 1 ] ) && false !== stripos( $selectmatches[ 1 ], ' AS ' ) )
956
+ $selectsfound .= ( !empty( $selectsfound ) ? ', ' : '' ) . $selectmatches[ 1 ];
957
+ }
958
+
959
+ // Build Alias list
960
+ $this->aliases = array();
961
+
962
+ if ( !empty( $selectsfound ) && false !== stripos( $selectsfound, ' AS ' ) ) {
963
+ $theselects = array_filter( explode( ', ', $selectsfound ) );
964
+
965
+ if ( empty( $theselects ) )
966
+ $theselects = array_filter( explode( ',', $selectsfound ) );
967
+
968
+ foreach ( $theselects as $selected ) {
969
+ $selected = trim( $selected );
970
+
971
+ if ( strlen( $selected ) < 1 )
972
+ continue;
973
+
974
+ $selectfield = explode( ' AS ', str_replace( ' as ', ' AS ', $selected ) );
975
+
976
+ if ( 2 == count( $selectfield ) ) {
977
+ $field = trim( trim( $selectfield[ 1 ] ), '`' );
978
+ $real_field = trim( trim( $selectfield[ 0 ] ), '`' );
979
+ $this->aliases[ $field ] = $real_field;
980
+ }
981
+ }
982
+ }
983
+
984
+ // Search
985
+ if ( !empty( $params->search ) && !empty( $params->fields ) ) {
986
+ if ( false !== $params->search_query && 0 < strlen( $params->search_query ) ) {
987
+ $where = $having = array();
988
+
989
+ if ( false !== $params->search_across ) {
990
+ foreach ( $params->fields as $key => $field ) {
991
+ if ( is_array( $field ) ) {
992
+ $attributes = $field;
993
+ $field = pods_v( 'name', $field, $key, true );
994
+ }
995
+ else {
996
+ $attributes = array(
997
+ 'type' => '',
998
+ 'options' => array()
999
+ );
1000
+ }
1001
+
1002
+ if ( isset( $attributes[ 'options' ][ 'search' ] ) && !$attributes[ 'options' ][ 'search' ] )
1003
+ continue;
1004
+
1005
+ if ( in_array( $attributes[ 'type' ], array( 'date', 'time', 'datetime', 'number', 'decimal', 'currency', 'phone', 'password', 'boolean' ) ) )
1006
+ continue;
1007
+
1008
+ $fieldfield = '`' . $field . '`';
1009
+
1010
+ if ( 'pick' == $attributes[ 'type' ] && !in_array( pods_v( 'pick_object', $attributes ), $simple_tableless_objects ) ) {
1011
+ if ( false === $params->search_across_picks )
1012
+ continue;
1013
+ else {
1014
+ if ( empty( $attributes[ 'table_info' ] ) )
1015
+ $attributes[ 'table_info' ] = $this->api->get_table_info( pods_v( 'pick_object', $attributes ), pods_v( 'pick_val', $attributes ) );
1016
+
1017
+ if ( empty( $attributes[ 'table_info' ][ 'field_index' ] ) )
1018
+ continue;
1019
+
1020
+ $fieldfield = $fieldfield . '.`' . $attributes[ 'table_info' ][ 'field_index' ] . '`';
1021
+ }
1022
+ }
1023
+ elseif ( in_array( $attributes[ 'type' ], $file_field_types ) ) {
1024
+ if ( false === $params->search_across_files )
1025
+ continue;
1026
+ else
1027
+ $fieldfield = $fieldfield . '.`post_title`';
1028
+ }
1029
+ elseif ( isset( $params->fields[ $field ] ) ) {
1030
+ if ( $params->meta_fields )
1031
+ $fieldfield = $fieldfield . '.`meta_value`';
1032
+ else
1033
+ $fieldfield = '`' . $params->pod_table_prefix . '`.' . $fieldfield;
1034
+ }
1035
+ elseif ( !empty( $params->object_fields ) && !isset( $params->object_fields[ $field ] ) && 'meta' == $pod['storage'] )
1036
+ $fieldfield = $fieldfield . '.`meta_value`';
1037
+ else
1038
+ $fieldfield = '`t`.' . $fieldfield;
1039
+
1040
+ if ( isset( $this->aliases[ $field ] ) )
1041
+ $fieldfield = '`' . $this->aliases[ $field ] . '`';
1042
+
1043
+ if ( !empty( $attributes[ 'real_name' ] ) )
1044
+ $fieldfield = $attributes[ 'real_name' ];
1045
+
1046
+ if ( isset( $attributes[ 'group_related' ] ) && false !== $attributes[ 'group_related' ] )
1047
+ $having[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'";
1048
+ else
1049
+ $where[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'";
1050
+ }
1051
+ }
1052
+ elseif ( !empty( $params->index ) ) {
1053
+ $attributes = array();
1054
+
1055
+ $fieldfield = '`t`.`' . $params->index . '`';
1056
+
1057
+ if ( isset( $params->fields[ $params->index ] ) ) {
1058
+ if ( $params->meta_fields )
1059
+ $fieldfield = '`' . $params->index . '`.`' . $params->pod_table_prefix . '`';
1060
+ else
1061
+ $fieldfield = '`' . $params->pod_table_prefix . '`.`' . $params->index . '`';
1062
+ }
1063
+ elseif ( !empty( $params->object_fields ) && !isset( $params->object_fields[ $params->index ] ) && 'meta' == $pod['storage'] )
1064
+ $fieldfield = '`' . $params->index . '`.`meta_value`';
1065
+
1066
+ if ( isset( $attributes[ 'real_name' ] ) && false !== $attributes[ 'real_name' ] && !empty( $attributes[ 'real_name' ] ) )
1067
+ $fieldfield = $attributes[ 'real_name' ];
1068
+
1069
+ if ( isset( $attributes[ 'group_related' ] ) && false !== $attributes[ 'group_related' ] )
1070
+ $having[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'";
1071
+ else
1072
+ $where[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'";
1073
+ }
1074
+
1075
+ if ( !empty( $where ) )
1076
+ $params->where[] = '( ' . implode( ' OR ', $where ) . ' )';
1077
+
1078
+ if ( !empty( $having ) )
1079
+ $params->having[] = '( ' . implode( ' OR ', $having ) . ' )';
1080
+ }
1081
+
1082
+ // Filter
1083
+ foreach ( $params->filters as $filter ) {
1084
+ $where = $having = array();
1085
+
1086
+ if ( !isset( $params->fields[ $filter ] ) )
1087
+ continue;
1088
+
1089
+ $attributes = $params->fields[ $filter ];
1090
+ $field = pods_v( 'name', $attributes, $filter, true );
1091
+
1092
+ $filterfield = '`' . $field . '`';
1093
+
1094
+ if ( 'pick' == $attributes[ 'type' ] && !in_array( pods_v( 'pick_object', $attributes ), $simple_tableless_objects ) ) {
1095
+ if ( empty( $attributes[ 'table_info' ] ) )
1096
+ $attributes[ 'table_info' ] = $this->api->get_table_info( pods_v( 'pick_object', $attributes ), pods_v( 'pick_val', $attributes ) );
1097
+
1098
+ if ( empty( $attributes[ 'table_info' ][ 'field_index' ] ) )
1099
+ continue;
1100
+
1101
+ $filterfield = $filterfield . '.`' . $attributes[ 'table_info' ][ 'field_index' ] . '`';
1102
+ }
1103
+ elseif ( in_array( $attributes[ 'type' ], $file_field_types ) )
1104
+ $filterfield = $filterfield . '.`post_title`';
1105
+ elseif ( isset( $params->fields[ $field ] ) ) {
1106
+ if ( $params->meta_fields && 'meta' == $pod['storage'] )
1107
+ $filterfield = $filterfield . '.`meta_value`';
1108
+ else
1109
+ $filterfield = '`' . $params->pod_table_prefix . '`.' . $filterfield;
1110
+ }
1111
+ elseif ( !empty( $params->object_fields ) && !isset( $params->object_fields[ $field ] ) && 'meta' == $pod['storage'] )
1112
+ $filterfield = $filterfield . '.`meta_value`';
1113
+ else
1114
+ $filterfield = '`t`.' . $filterfield;
1115
+
1116
+ if ( isset( $this->aliases[ $field ] ) )
1117
+ $filterfield = '`' . $this->aliases[ $field ] . '`';
1118
+
1119
+ if ( !empty( $attributes[ 'real_name' ] ) )
1120
+ $filterfield = $attributes[ 'real_name' ];
1121
+
1122
+ if ( 'pick' == $attributes[ 'type' ] ) {
1123
+ $filter_value = pods_v( 'filter_' . $field, 'get' );
1124
+
1125
+ if ( !is_array( $filter_value ) )
1126
+ $filter_value = (array) $filter_value;
1127
+
1128
+ foreach ( $filter_value as $filter_v ) {
1129
+ if ( in_array( pods_v( 'pick_object', $attributes ), $simple_tableless_objects ) ) {
1130
+ if ( strlen( $filter_v ) < 1 )
1131
+ continue;
1132
+
1133
+ if ( isset( $attributes[ 'group_related' ] ) && false !== $attributes[ 'group_related' ] ) {
1134
+ $having[] = "( {$filterfield} = '" . pods_sanitize( $filter_v ) . "'"
1135
+ . " OR {$filterfield} LIKE '%\"" . pods_sanitize_like( $filter_v ) . "\"%' )";
1136
+ }
1137
+ else {
1138
+ $where[] = "( {$filterfield} = '" . pods_sanitize( $filter_v ) . "'"
1139
+ . " OR {$filterfield} LIKE '%\"" . pods_sanitize_like( $filter_v ) . "\"%' )";
1140
+ }
1141
+ }
1142
+ else {
1143
+ $filter_v = (int) $filter_v;
1144
+
1145
+ if ( empty( $filter_v ) || empty( $attributes[ 'table_info' ] ) || empty( $attributes[ 'table_info' ][ 'field_id' ] ) )
1146
+ continue;
1147
+
1148
+ $filterfield = '`' . $field . '`.`' . $attributes[ 'table_info' ][ 'field_id' ] . '`';
1149
+
1150
+ if ( isset( $attributes[ 'group_related' ] ) && false !== $attributes[ 'group_related' ] )
1151
+ $having[] = "{$filterfield} = " . $filter_v;
1152
+ else
1153
+ $where[] = "{$filterfield} = " . $filter_v;
1154
+ }
1155
+ }
1156
+ }
1157
+ elseif ( in_array( $attributes[ 'type' ], array( 'date', 'datetime' ) ) ) {
1158
+ $start_value = pods_v( 'filter_' . $field . '_start', 'get', false );
1159
+ $end_value = pods_v( 'filter_' . $field . '_end', 'get', false );
1160
+
1161
+ if ( empty( $start_value ) && empty( $end_value ) )
1162
+ continue;
1163
+
1164
+ if ( !empty( $start_value ) )
1165
+ $start = date_i18n( 'Y-m-d', strtotime( $start_value ) ) . ( 'datetime' == $attributes[ 'type' ] ? ' 00:00:00' : '' );
1166
+ else
1167
+ $start = date_i18n( 'Y-m-d' ) . ( 'datetime' == $attributes[ 'type' ] ) ? ' 00:00:00' : '';
1168
+
1169
+ if ( !empty( $end_value ) )
1170
+ $end = date_i18n( 'Y-m-d', strtotime( $end_value ) ) . ( 'datetime' == $attributes[ 'type' ] ? ' 23:59:59' : '' );
1171
+ else
1172
+ $end = date_i18n( 'Y-m-d' ) . ( 'datetime' == $attributes[ 'type' ] ) ? ' 23:59:59' : '';
1173
+
1174
+ if ( isset( $attributes[ 'date_ongoing' ] ) && true === $attributes[ 'date_ongoing' ] ) {
1175
+ $date_ongoing = '`' . $attributes[ 'date_ongoing' ] . '`';
1176
+
1177
+ if ( isset( $this->aliases[ $date_ongoing ] ) )
1178
+ $date_ongoing = '`' . $this->aliases[ $date_ongoing ] . '`';
1179
+
1180
+ if ( isset( $attributes[ 'group_related' ] ) && false !== $attributes[ 'group_related' ] )
1181
+ $having[] = "(({$filterfield} <= '$start' OR ({$filterfield} >= '$start' AND {$filterfield} <= '$end')) AND ({$date_ongoing} >= '$start' OR ({$date_ongoing} >= '$start' AND {$date_ongoing} <= '$end')))";
1182
+ else
1183
+ $where[] = "(({$filterfield} <= '$start' OR ({$filterfield} >= '$start' AND {$filterfield} <= '$end')) AND ({$date_ongoing} >= '$start' OR ({$date_ongoing} >= '$start' AND {$date_ongoing} <= '$end')))";
1184
+ }
1185
+ else {
1186
+ if ( isset( $attributes[ 'group_related' ] ) && false !== $attributes[ 'group_related' ] )
1187
+ $having[] = "({$filterfield} BETWEEN '$start' AND '$end')";
1188
+ else
1189
+ $where[] = "({$filterfield} BETWEEN '$start' AND '$end')";
1190
+ }
1191
+ }
1192
+ else {
1193
+ $filter_value = pods_v( 'filter_' . $field, 'get', '' );
1194
+
1195
+ if ( strlen( $filter_value ) < 1 )
1196
+ continue;
1197
+
1198
+ if ( isset( $attributes[ 'group_related' ] ) && false !== $attributes[ 'group_related' ] )
1199
+ $having[] = "{$filterfield} LIKE '%" . pods_sanitize_like( $filter_value ) . "%'";
1200
+ else
1201
+ $where[] = "{$filterfield} LIKE '%" . pods_sanitize_like( $filter_value ) . "%'";
1202
+ }
1203
+
1204
+ if ( !empty( $where ) )
1205
+ $params->where[] = implode( ' AND ', $where );
1206
+
1207
+ if ( !empty( $having ) )
1208
+ $params->having[] = implode( ' AND ', $having );
1209
+ }
1210
+ }
1211
+
1212
+ // Traverse the Rabbit Hole
1213
+ if ( !empty( $this->pod ) ) {
1214
+ $haystack = implode( ' ', (array) $params->select )
1215
+ . ' ' . implode( ' ', (array) $params->where )
1216
+ . ' ' . implode( ' ', (array) $params->groupby )
1217
+ . ' ' . implode( ' ', (array) $params->having )
1218
+ . ' ' . implode( ' ', (array) $params->orderby );
1219
+ $haystack = preg_replace( '/\s/', ' ', $haystack );
1220
+ $haystack = preg_replace( '/\w\(/', ' ', $haystack );
1221
+ $haystack = str_replace( array( '(', ')', ' ', '\\\'', "\\\"" ), ' ', $haystack );
1222
+
1223
+ preg_match_all( '/`?[\w\-]+`?(?:\\.`?[\w\-]+`?)+(?=[^"\']*(?:"[^"]*"[^"]*|\'[^\']*\'[^\']*)*$)/', $haystack, $found, PREG_PATTERN_ORDER );
1224
+
1225
+ $found = (array) @current( $found );
1226
+ $find = $replace = $traverse = array();
1227
+
1228
+ foreach ( $found as $key => $value ) {
1229
+ $value = str_replace( '`', '', $value );
1230
+ $value = explode( '.', $value );
1231
+ $dot = $last_value = array_pop( $value );
1232
+
1233
+ if ( 't' == $value[ 0 ] )
1234
+ continue;
1235
+ elseif ( array_key_exists( $value[ 0 ], $params->join ) )
1236
+ // Don't traverse for tables we are already going to join
1237
+ continue;
1238
+ elseif ( 1 == count( $value ) && '' == preg_replace( '/[0-9]*/', '', $value[ 0 ] ) && '' == preg_replace( '/[0-9]*/', '', $last_value ) )
1239
+ continue;
1240
+
1241
+ $found_value = str_replace( '`', '', $found[ $key ] );
1242
+ $found_value = '([`]{1}|\b)' . str_replace( '.', '[`]*\.[`]*', $found_value ) . '([`]{1}|\b)';
1243
+ $found_value = '/' . $found_value . '(?=[^"\']*(?:"[^"]*"[^"]*|\'[^\']*\'[^\']*)*$)/';
1244
+
1245
+ if ( in_array( $found_value, $find ) ) {
1246
+ continue;
1247
+ }
1248
+
1249
+ $find[ $key ] = $found_value;
1250
+
1251
+ if ( '*' != $dot )
1252
+ $dot = '`' . $dot . '`';
1253
+
1254
+ $replace[ $key ] = '`' . implode( '_', $value ) . '`.' . $dot;
1255
+
1256
+ $value[] = $last_value;
1257
+
1258
+ if ( !in_array( $value, $traverse ) )
1259
+ $traverse[ $key ] = $value;
1260
+ }
1261
+
1262
+ if ( !empty( $this->traverse ) ) {
1263
+ foreach ( (array) $this->traverse as $key => $traverse ) {
1264
+ $traverse = str_replace( '`', '', $traverse );
1265
+ $already_found = false;
1266
+
1267
+ foreach ( $traverse as $traversal ) {
1268
+ if ( is_array( $traversal ) )
1269
+ $traversal = implode( '.', $traversal );
1270
+
1271
+ if ( $traversal == $traverse ) {
1272
+ $already_found = true;
1273
+ break;
1274
+ }
1275
+ }
1276
+
1277
+ if ( !$already_found )
1278
+ $traverse[ 'traverse_' . $key ] = explode( '.', $traverse );
1279
+ }
1280
+ }
1281
+
1282
+ $joins = array();
1283
+
1284
+ if ( !empty( $find ) ) {
1285
+ // See: "#3294 OrderBy Failing on PHP7" Non-zero array keys
1286
+ // here in PHP 7 cause odd behavior so just strip the keys
1287
+ $find = array_values( $find );
1288
+ $replace = array_values( $replace );
1289
+
1290
+ $params->select = preg_replace( $find, $replace, $params->select );
1291
+ $params->where = preg_replace( $find, $replace, $params->where );
1292
+ $params->groupby = preg_replace( $find, $replace, $params->groupby );
1293
+ $params->having = preg_replace( $find, $replace, $params->having );
1294
+ $params->orderby = preg_replace( $find, $replace, $params->orderby );
1295
+
1296
+ if ( !empty( $traverse ) )
1297
+ $joins = $this->traverse( $traverse, $params->fields, $params );
1298
+ elseif ( false !== $params->search )
1299
+ $joins = $this->traverse( null, $params->fields, $params );
1300
+ }
1301
+ }
1302
+
1303
+ // Traversal Search
1304
+ if ( !empty( $params->search ) && !empty( $this->search_where ) )
1305
+ $params->where = array_merge( (array) $this->search_where, $params->where );
1306
+
1307
+ if ( !empty( $params->join ) && !empty( $joins ) )
1308
+ $params->join = array_merge( $joins, (array) $params->join );
1309
+ elseif ( !empty( $joins ) )
1310
+ $params->join = $joins;
1311
+
1312
+ // Build
1313
+ if ( null === $params->sql ) {
1314
+ $sql = "
1315
+ SELECT
1316
+ " . ( $params->calc_rows ? 'SQL_CALC_FOUND_ROWS' : '' ) . "
1317
+ " . ( $params->distinct ? 'DISTINCT' : '' ) . "
1318
+ " . ( !empty( $params->select ) ? ( is_array( $params->select ) ? implode( ', ', $params->select ) : $params->select ) : '*' ) . "
1319
+ FROM {$params->table} AS `t`
1320
+ " . ( !empty( $params->join ) ? ( is_array( $params->join ) ? implode( "\n ", $params->join ) : $params->join ) : '' ) . "
1321
+ " . ( !empty( $params->where ) ? 'WHERE ' . ( is_array( $params->where ) ? implode( ' AND ', $params->where ) : $params->where ) : '' ) . "
1322
+ " . ( !empty( $params->groupby ) ? 'GROUP BY ' . ( is_array( $params->groupby ) ? implode( ', ', $params->groupby ) : $params->groupby ) : '' ) . "
1323
+ " . ( !empty( $params->having ) ? 'HAVING ' . ( is_array( $params->having ) ? implode( ' AND ', $params->having ) : $params->having ) : '' ) . "
1324
+ " . ( !empty( $params->orderby ) ? 'ORDER BY ' . ( is_array( $params->orderby ) ? implode( ', ', $params->orderby ) : $params->orderby ) : '' ) . "
1325
+ " . ( ( 0 < $params->page && 0 < $params->limit ) ? 'LIMIT ' . $params->offset . ', ' . ( $params->limit ) : '' ) . "
1326
+ ";
1327
+
1328
+ if ( !$params->calc_rows ) {
1329
+ // Handle COUNT() SELECT
1330
+ $total_sql_select = "COUNT( " . ( $params->distinct ? 'DISTINCT `t`.`' . $params->id . '`' : '*' ) . " )";
1331
+
1332
+ // If 'having' is set, we have to select all so it has access to anything it needs
1333
+ if ( ! empty( $params->having ) ) {
1334
+ $total_sql_select .= ', ' . ( !empty( $params->select ) ? ( is_array( $params->select ) ? implode( ', ', $params->select ) : $params->select ) : '*' );
1335
+ }
1336
+
1337
+ $this->total_sql = "
1338
+ SELECT {$total_sql_select}
1339
+ FROM {$params->table} AS `t`
1340
+ " . ( !empty( $params->join ) ? ( is_array( $params->join ) ? implode( "\n ", $params->join ) : $params->join ) : '' ) . "
1341
+ " . ( !empty( $params->where ) ? 'WHERE ' . ( is_array( $params->where ) ? implode( ' AND ', $params->where ) : $params->where ) : '' ) . "
1342
+ " . ( !empty( $params->groupby ) ? 'GROUP BY ' . ( is_array( $params->groupby ) ? implode( ', ', $params->groupby ) : $params->groupby ) : '' ) . "
1343
+ " . ( !empty( $params->having ) ? 'HAVING ' . ( is_array( $params->having ) ? implode( ' AND ', $params->having ) : $params->having ) : '' ) . "
1344
+ ";
1345
+ }
1346
+ }
1347
+ // Rewrite
1348
+ else {
1349
+ $sql = ' ' . trim( str_replace( array( "\n", "\r" ), ' ', $params->sql ) );
1350
+ $sql = preg_replace( array(
1351
+ '/\sSELECT\sSQL_CALC_FOUND_ROWS\s/i',
1352
+ '/\sSELECT\s/i'
1353
+ ),
1354
+ array(
1355
+ ' SELECT ',
1356
+ ' SELECT SQL_CALC_FOUND_ROWS '
1357
+ ),
1358
+ $sql );
1359
+
1360
+ // Insert variables based on existing statements
1361
+ if ( false === stripos( $sql, '%%SELECT%%' ) )
1362
+ $sql = preg_replace( '/\sSELECT\sSQL_CALC_FOUND_ROWS\s/i', ' SELECT SQL_CALC_FOUND_ROWS %%SELECT%% ', $sql );
1363
+ if ( false === stripos( $sql, '%%WHERE%%' ) )
1364
+ $sql = preg_replace( '/\sWHERE\s(?!.*\sWHERE\s)/i', ' WHERE %%WHERE%% ', $sql );
1365
+ if ( false === stripos( $sql, '%%GROUPBY%%' ) )
1366
+ $sql = preg_replace( '/\sGROUP BY\s(?!.*\sGROUP BY\s)/i', ' GROUP BY %%GROUPBY%% ', $sql );
1367
+ if ( false === stripos( $sql, '%%HAVING%%' ) )
1368
+ $sql = preg_replace( '/\sHAVING\s(?!.*\sHAVING\s)/i', ' HAVING %%HAVING%% ', $sql );
1369
+ if ( false === stripos( $sql, '%%ORDERBY%%' ) )
1370
+ $sql = preg_replace( '/\sORDER BY\s(?!.*\sORDER BY\s)/i', ' ORDER BY %%ORDERBY%% ', $sql );
1371
+
1372
+ // Insert variables based on other existing statements
1373
+ if ( false === stripos( $sql, '%%JOIN%%' ) ) {
1374
+ if ( false !== stripos( $sql, ' WHERE ' ) )
1375
+ $sql = preg_replace( '/\sWHERE\s(?!.*\sWHERE\s)/i', ' %%JOIN%% WHERE ', $sql );
1376
+ elseif ( false !== stripos( $sql, ' GROUP BY ' ) )
1377
+ $sql = preg_replace( '/\sGROUP BY\s(?!.*\sGROUP BY\s)/i', ' %%WHERE%% GROUP BY ', $sql );
1378
+ elseif ( false !== stripos( $sql, ' ORDER BY ' ) )
1379
+ $sql = preg_replace( '/\ORDER BY\s(?!.*\ORDER BY\s)/i', ' %%WHERE%% ORDER BY ', $sql );
1380
+ else
1381
+ $sql .= ' %%JOIN%% ';
1382
+ }
1383
+ if ( false === stripos( $sql, '%%WHERE%%' ) ) {
1384
+ if ( false !== stripos( $sql, ' GROUP BY ' ) )
1385
+ $sql = preg_replace( '/\sGROUP BY\s(?!.*\sGROUP BY\s)/i', ' %%WHERE%% GROUP BY ', $sql );
1386
+ elseif ( false !== stripos( $sql, ' ORDER BY ' ) )
1387
+ $sql = preg_replace( '/\ORDER BY\s(?!.*\ORDER BY\s)/i', ' %%WHERE%% ORDER BY ', $sql );
1388
+ else
1389
+ $sql .= ' %%WHERE%% ';
1390
+ }
1391
+ if ( false === stripos( $sql, '%%GROUPBY%%' ) ) {
1392
+ if ( false !== stripos( $sql, ' HAVING ' ) )
1393
+ $sql = preg_replace( '/\sHAVING\s(?!.*\sHAVING\s)/i', ' %%GROUPBY%% HAVING ', $sql );
1394
+ elseif ( false !== stripos( $sql, ' ORDER BY ' ) )
1395
+ $sql = preg_replace( '/\ORDER BY\s(?!.*\ORDER BY\s)/i', ' %%GROUPBY%% ORDER BY ', $sql );
1396
+ else
1397
+ $sql .= ' %%GROUPBY%% ';
1398
+ }
1399
+ if ( false === stripos( $sql, '%%HAVING%%' ) ) {
1400
+ if ( false !== stripos( $sql, ' ORDER BY ' ) )
1401
+ $sql = preg_replace( '/\ORDER BY\s(?!.*\ORDER BY\s)/i', ' %%HAVING%% ORDER BY ', $sql );
1402
+ else
1403
+ $sql .= ' %%HAVING%% ';
1404
+ }
1405
+ if ( false === stripos( $sql, '%%ORDERBY%%' ) )
1406
+ $sql .= ' %%ORDERBY%% ';
1407
+ if ( false === stripos( $sql, '%%LIMIT%%' ) )
1408
+ $sql .= ' %%LIMIT%% ';
1409
+
1410
+ // Replace variables
1411
+ if ( 0 < strlen( $params->select ) ) {
1412
+ if ( false === stripos( $sql, '%%SELECT%% FROM ' ) )
1413
+ $sql = str_ireplace( '%%SELECT%%', $params->select . ', ', $sql );
1414
+ else
1415
+ $sql = str_ireplace( '%%SELECT%%', $params->select, $sql );
1416
+ }
1417
+ if ( 0 < strlen( $params->join ) )
1418
+ $sql = str_ireplace( '%%JOIN%%', $params->join, $sql );
1419
+ if ( 0 < strlen( $params->where ) ) {
1420
+ if ( false !== stripos( $sql, ' WHERE ' ) ) {
1421
+ if ( false !== stripos( $sql, ' WHERE %%WHERE%% ' ) )
1422
+ $sql = str_ireplace( '%%WHERE%%', $params->where . ' AND ', $sql );
1423
+ else
1424
+ $sql = str_ireplace( '%%WHERE%%', ' AND ' . $params->where, $sql );
1425
+ }
1426
+ else
1427
+ $sql = str_ireplace( '%%WHERE%%', ' WHERE ' . $params->where, $sql );
1428
+ }
1429
+ if ( 0 < strlen( $params->groupby ) ) {
1430
+ if ( false !== stripos( $sql, ' GROUP BY ' ) ) {
1431
+ if ( false !== stripos( $sql, ' GROUP BY %%GROUPBY%% ' ) )
1432
+ $sql = str_ireplace( '%%GROUPBY%%', $params->groupby . ', ', $sql );
1433
+ else
1434
+ $sql = str_ireplace( '%%GROUPBY%%', ', ' . $params->groupby, $sql );
1435
+ }
1436
+ else
1437
+ $sql = str_ireplace( '%%GROUPBY%%', ' GROUP BY ' . $params->groupby, $sql );
1438
+ }
1439
+ if ( 0 < strlen( $params->having ) && false !== stripos( $sql, ' GROUP BY ' ) ) {
1440
+ if ( false !== stripos( $sql, ' HAVING ' ) ) {
1441
+ if ( false !== stripos( $sql, ' HAVING %%HAVING%% ' ) )
1442
+ $sql = str_ireplace( '%%HAVING%%', $params->having . ' AND ', $sql );
1443
+ else
1444
+ $sql = str_ireplace( '%%HAVING%%', ' AND ' . $params->having, $sql );
1445
+ }
1446
+ else
1447
+ $sql = str_ireplace( '%%HAVING%%', ' HAVING ' . $params->having, $sql );
1448
+ }
1449
+ if ( 0 < strlen( $params->orderby ) ) {
1450
+ if ( false !== stripos( $sql, ' ORDER BY ' ) ) {
1451
+ if ( false !== stripos( $sql, ' ORDER BY %%ORDERBY%% ' ) )
1452
+ $sql = str_ireplace( '%%ORDERBY%%', $params->groupby . ', ', $sql );
1453
+ else
1454
+ $sql = str_ireplace( '%%ORDERBY%%', ', ' . $params->groupby, $sql );
1455
+ }
1456
+ else
1457
+ $sql = str_ireplace( '%%ORDERBY%%', ' ORDER BY ' . $params->groupby, $sql );
1458
+ }
1459
+ if ( 0 < $params->page && 0 < $params->limit ) {
1460
+ $start = ( $params->page - 1 ) * $params->limit;
1461
+ $end = $start + $params->limit;
1462
+ $sql .= 'LIMIT ' . (int) $start . ', ' . (int) $end;
1463
+ }
1464
+
1465
+ // Clear any unused variables
1466
+ $sql = str_ireplace( array(
1467
+ '%%SELECT%%',
1468
+ '%%JOIN%%',
1469
+ '%%WHERE%%',
1470
+ '%%GROUPBY%%',
1471
+ '%%HAVING%%',
1472
+ '%%ORDERBY%%',
1473
+ '%%LIMIT%%'
1474
+ ), '', $sql );
1475
+ $sql = str_replace( array( '``', '`' ), array( ' ', ' ' ), $sql );
1476
+ }
1477
+
1478
+ return $sql;
1479
+ }
1480
+
1481
+ /**
1482
+ * Fetch the total row count returned
1483
+ *
1484
+ * @return int Number of rows returned by select()
1485
+ * @since 2.0
1486
+ */
1487
+ public function total () {
1488
+ return (int) $this->total;
1489
+ }
1490
+
1491
+ /**
1492
+ * Fetch the total row count total
1493
+ *
1494
+ * @return int Number of rows found by select()
1495
+ * @since 2.0
1496
+ */
1497
+ public function total_found () {
1498
+ if(false === $this->total_found_calculated)
1499
+ $this->calculate_totals();
1500
+
1501
+ return (int) $this->total_found;
1502
+ }
1503
+
1504
+ /**
1505
+ * Fetch the zebra state
1506
+ *
1507
+ * @return bool Zebra state
1508
+ * @since 1.12
1509
+ * @see PodsData::nth
1510
+ */
1511
+ public function zebra () {
1512
+ return $this->nth( 'odd' ); // Odd numbers
1513
+ }
1514
+
1515
+ /**
1516
+ * Fetch the nth state
1517
+ *
1518
+ * @param int|string $nth The $nth to match on the PodsData::row_number
1519
+ *
1520
+ * @return bool Whether $nth matches
1521
+ * @since 2.3
1522
+ */
1523
+ public function nth ( $nth ) {
1524
+ if ( empty( $nth ) )
1525
+ $nth = 2;
1526
+
1527
+ $offset = 0;
1528
+ $negative = false;
1529
+
1530
+ if ( 'even' == $nth )
1531
+ $nth = 2;
1532
+ elseif ( 'odd' == $nth ) {
1533
+ $negative = true;
1534
+ $nth = 2;
1535
+ }
1536
+ elseif ( false !== strpos( $nth, '+' ) ) {
1537
+ $nth = explode( '+', $nth );
1538
+
1539
+ if ( isset( $nth[ 1 ] ) )
1540
+ $offset += (int) trim( $nth[ 1 ] );
1541
+
1542
+ $nth = (int) trim( $nth[ 0 ], ' n' );
1543
+ }
1544
+ elseif ( false !== strpos( $nth, '-' ) ) {
1545
+ $nth = explode( '-', $nth );
1546
+
1547
+ if ( isset( $nth[ 1 ] ) )
1548
+ $offset -= (int) trim( $nth[ 1 ] );
1549
+
1550
+ $nth = (int) trim( $nth[ 0 ], ' n' );
1551
+ }
1552
+
1553
+ $nth = (int) $nth;
1554
+ $offset = (int) $offset;
1555
+
1556
+ if ( 0 == ( ( $this->row_number % $nth ) + $offset ) )
1557
+ return ( $negative ? false: true );
1558
+
1559
+ return ( $negative ? true : false );
1560
+ }
1561
+
1562
+ /**
1563
+ * Fetch the current position in the loop (starting at 1)
1564
+ *
1565
+ * @return int Current row number (+1)
1566
+ * @since 2.3
1567
+ */
1568
+ public function position () {
1569
+ return $this->row_number + 1;
1570
+ }
1571
+
1572
+ /**
1573
+ * Create a Table
1574
+ *
1575
+ * @param string $table Table name
1576
+ * @param string $fields
1577
+ * @param boolean $if_not_exists Check if the table exists.
1578
+ *
1579
+ * @return array|bool|mixed|null|void
1580
+ *
1581
+ * @uses PodsData::query
1582
+ *
1583
+ * @since 2.0
1584
+ */
1585
+ public static function table_create ( $table, $fields, $if_not_exists = false ) {
1586
+ /**
1587
+ * @var $wpdb wpdb
1588
+ */
1589
+ global $wpdb;
1590
+
1591
+ $sql = "CREATE TABLE";
1592
+
1593
+ if ( true === $if_not_exists )
1594
+ $sql .= " IF NOT EXISTS";
1595
+
1596
+ $sql .= " `{$wpdb->prefix}" . self::$prefix . "{$table}` ({$fields})";
1597
+
1598
+ if ( !empty( $wpdb->charset ) )
1599
+ $sql .= " DEFAULT CHARACTER SET {$wpdb->charset}";
1600
+
1601
+ if ( !empty( $wpdb->collate ) )
1602
+ $sql .= " COLLATE {$wpdb->collate}";
1603
+
1604
+ return self::query( $sql );
1605
+ }
1606
+
1607
+ /**
1608
+ * Alter a Table
1609
+ *
1610
+ * @param string $table Table name
1611
+ * @param string $changes
1612
+ *
1613
+ * @return array|bool|mixed|null|void
1614
+ *
1615
+ * @uses PodsData::query
1616
+ *
1617
+ * @since 2.0
1618
+ */
1619
+ public static function table_alter ( $table, $changes ) {
1620
+ /**
1621
+ * @var $wpdb wpdb
1622
+ */
1623
+ global $wpdb;
1624
+
1625
+ $sql = "ALTER TABLE `{$wpdb->prefix}" . self::$prefix . "{$table}` {$changes}";
1626
+
1627
+ return self::query( $sql );
1628
+ }
1629
+
1630
+ /**
1631
+ * Truncate a Table
1632
+ *
1633
+ * @param string $table Table name
1634
+ *
1635
+ * @return array|bool|mixed|null|void
1636
+ *
1637
+ * @uses PodsData::query
1638
+ *
1639
+ * @since 2.0
1640
+ */
1641
+ public static function table_truncate ( $table ) {
1642
+ /**
1643
+ * @var $wpdb wpdb
1644
+ */
1645
+ global $wpdb;
1646
+
1647
+ $sql = "TRUNCATE TABLE `{$wpdb->prefix}" . self::$prefix . "{$table}`";
1648
+
1649
+ return self::query( $sql );
1650
+ }
1651
+
1652
+ /**
1653
+ * Drop a Table
1654
+ *
1655
+ * @param string $table Table name
1656
+ *
1657
+ * @uses PodsData::query
1658
+ *
1659
+ * @return array|bool|mixed|null|void
1660
+ *
1661
+ * @uses PodsData::query
1662
+ *
1663
+ * @since 2.0
1664
+ */
1665
+ public static function table_drop ( $table ) {
1666
+ /**
1667
+ * @var $wpdb wpdb
1668
+ */
1669
+ global $wpdb;
1670
+
1671
+ $sql = "DROP TABLE `{$wpdb->prefix}" . self::$prefix . "{$table}`";
1672
+
1673
+ return self::query( $sql );
1674
+ }
1675
+
1676
+ /**
1677
+ * Reorder Items
1678
+ *
1679
+ * @param string $table Table name
1680
+ * @param string $weight_field
1681
+ * @param string $id_field
1682
+ * @param array $ids
1683
+ *
1684
+ * @return bool
1685
+ *
1686
+ * @uses PodsData::update
1687
+ *
1688
+ * @since 2.0
1689
+ */
1690
+ public function reorder ( $table, $weight_field, $id_field, $ids ) {
1691
+ $success = false;
1692
+ $ids = (array) $ids;
1693
+
1694
+ list( $table, $weight_field, $id_field, $ids ) = $this->do_hook( 'reorder', array(
1695
+ $table,
1696
+ $weight_field,
1697
+ $id_field,
1698
+ $ids
1699
+ ) );
1700
+
1701
+ if ( !empty( $ids ) ) {
1702
+ $success = true;
1703
+
1704
+ foreach ( $ids as $weight => $id ) {
1705
+ $updated = $this->update( $table, array( $weight_field => $weight ), array( $id_field => $id ), array( '%d' ), array( '%d' ) );
1706
+
1707
+ if ( false === $updated )
1708
+ $success = false;
1709
+ }
1710
+ }
1711
+
1712
+ return $success;
1713
+ }
1714
+
1715
+ /**
1716
+ * Fetch a new row for the current pod_data
1717
+ *
1718
+ * @param int $row Row number to fetch
1719
+ * @param bool $explicit_set Whether to set explicitly (use false when in loop)
1720
+ *
1721
+ * @return mixed
1722
+ *
1723
+ * @since 2.0
1724
+ */
1725
+ public function fetch ( $row = null, $explicit_set = true ) {
1726
+ global $wpdb;
1727
+
1728
+ if ( null === $row )
1729
+ $explicit_set = false;
1730
+
1731
+ $already_cached = false;
1732
+ $id = $row;
1733
+
1734
+ $tableless_field_types = PodsForm::tableless_field_types();
1735
+
1736
+ if ( null === $row ) {
1737
+ $this->row_number++;
1738
+
1739
+ $this->row = false;
1740
+
1741
+ if ( isset( $this->data[ $this->row_number ] ) ) {
1742
+ $this->row = get_object_vars( $this->data[ $this->row_number ] );
1743
+
1744
+ $current_row_id = false;
1745
+
1746
+ if ( in_array( $this->pod_data[ 'type' ], array( 'post_type', 'media' ) ) )
1747
+ $current_row_id = pods_var_raw( 'ID', $this->row );
1748
+ elseif ( 'taxonomy' == $this->pod_data[ 'type' ] )
1749
+ $current_row_id = pods_var_raw( 'term_id', $this->row );
1750
+ elseif ( 'user' == $this->pod_data[ 'type' ] )
1751
+ $current_row_id = pods_var_raw( 'ID', $this->row );
1752
+ elseif ( 'comment' == $this->pod_data[ 'type' ] )
1753
+ $current_row_id = pods_var_raw( 'comment_ID', $this->row );
1754
+ elseif ( 'settings' == $this->pod_data[ 'type' ] )
1755
+ $current_row_id = $this->pod_data[ 'id' ];
1756
+
1757
+ if ( 0 < $current_row_id )
1758
+ $row = $current_row_id;
1759
+ }
1760
+ }
1761
+
1762
+ if ( null !== $row || 'settings' == $this->pod_data[ 'type' ] ) {
1763
+ if ( $explicit_set )
1764
+ $this->row_number = -1;
1765
+
1766
+ $mode = 'id';
1767
+ $id = pods_absint( $row );
1768
+
1769
+ if ( !is_numeric( $row ) || 0 === strpos( $row, '0' ) || $row != preg_replace( '/[^0-9]/', '', $row ) ) {
1770
+ $mode = 'slug';
1771
+ $id = $row;
1772
+ }
1773
+
1774
+ $row = false;
1775
+
1776
+ if ( !empty( $this->pod ) ) {
1777
+ $row = pods_cache_get( $id, 'pods_items_' . $this->pod );
1778
+ if ( false !== $row ) {
1779
+ $already_cached = true;
1780
+ }
1781
+ }
1782
+
1783
+ $current_row_id = false;
1784
+ $get_table_data = false;
1785
+
1786
+ $old_row = $this->row;
1787
+
1788
+ if ( false !== $row && is_array( $row ) )
1789
+ $this->row = $row;
1790
+ elseif ( in_array( $this->pod_data[ 'type' ], array( 'post_type', 'media' ) ) ) {
1791
+ if ( 'post_type' == $this->pod_data[ 'type' ] ) {
1792
+ if ( empty( $this->pod_data[ 'object' ] ) ) {
1793
+ $post_type = $this->pod_data[ 'name' ];
1794
+ }
1795
+ else {
1796
+ $post_type = $this->pod_data[ 'object' ];
1797
+ }
1798
+ }
1799
+ else
1800
+ $post_type = 'attachment';
1801
+
1802
+ if ( 'id' == $mode ) {
1803
+ $this->row = get_post( $id, ARRAY_A );
1804
+
1805
+ if ( is_array( $this->row ) && $this->row[ 'post_type' ] != $post_type )
1806
+ $this->row = false;
1807
+ }
1808
+ else {
1809
+ $args = array(
1810
+ 'post_type' => $post_type,
1811
+ 'name' => $id,
1812
+ 'numberposts' => 5
1813
+ );
1814
+
1815
+ $find = get_posts( $args );
1816
+
1817
+ if ( !empty( $find ) )
1818
+ $this->row = get_object_vars( $find[ 0 ] );
1819
+ }
1820
+
1821
+ if ( is_wp_error( $this->row ) || empty( $this->row ) )
1822
+ $this->row = false;
1823
+ else
1824
+ $current_row_id = $this->row[ 'ID' ];
1825
+
1826
+ $get_table_data = true;
1827
+ }
1828
+ elseif ( 'taxonomy' == $this->pod_data[ 'type' ] ) {
1829
+ $taxonomy = $this->pod_data[ 'object' ];
1830
+
1831
+ if ( empty( $taxonomy ) )
1832
+ $taxonomy = $this->pod_data[ 'name' ];
1833
+
1834
+ // Taxonomies are registered during init, so they aren't available before then
1835
+ if ( !did_action( 'init' ) ) {
1836
+ // hackaround :(
1837
+ if ( 'id' == $mode )
1838
+ $term_where = 't.term_id = %d';
1839
+ else
1840
+ $term_where = 't.slug = %s';
1841
+
1842
+ $filter = 'raw';
1843
+ $term = $id;
1844
+
1845
+ if ( 'id' != $mode || !$_term = wp_cache_get( $term, $taxonomy ) ) {
1846
+ $_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = %s AND {$term_where} LIMIT 1", $taxonomy, $term ) );
1847
+
1848
+ if ( $_term )
1849
+ wp_cache_add( $term, $_term, $taxonomy );
1850
+ }
1851
+
1852
+ $_term = apply_filters( 'get_term', $_term, $taxonomy );
1853
+ $_term = apply_filters( "get_$taxonomy", $_term, $taxonomy );
1854
+ $_term = sanitize_term( $_term, $taxonomy, $filter );
1855
+
1856
+ if ( is_object( $_term ) )
1857
+ $this->row = get_object_vars( $_term );
1858
+ }
1859
+ elseif ( 'id' == $mode )
1860
+ $this->row = get_term( $id, $taxonomy, ARRAY_A );
1861
+ else
1862
+ $this->row = get_term_by( 'slug', $id, $taxonomy, ARRAY_A );
1863
+
1864
+ if ( is_wp_error( $this->row ) || empty( $this->row ) )
1865
+ $this->row = false;
1866
+ else
1867
+ $current_row_id = $this->row[ 'term_id' ];
1868
+
1869
+ $get_table_data = true;
1870
+ }
1871
+ elseif ( 'user' == $this->pod_data[ 'type' ] ) {
1872
+ if ( 'id' == $mode )
1873
+ $this->row = get_userdata( $id );
1874
+ else
1875
+ $this->row = get_user_by( 'slug', $id );
1876
+
1877
+ if ( is_wp_error( $this->row ) || empty( $this->row ) )
1878
+ $this->row = false;
1879
+ else {
1880
+ // Get other vars
1881
+ $roles = $this->row->roles;
1882
+ $caps = $this->row->caps;
1883
+ $allcaps = $this->row->allcaps;
1884
+
1885
+ $this->row = get_object_vars( $this->row->data );
1886
+
1887
+ // Set other vars
1888
+ $this->row[ 'roles' ] = $roles;
1889
+ $this->row[ 'caps' ] = $caps;
1890
+ $this->row[ 'allcaps' ] = $allcaps;
1891
+
1892
+ unset( $this->row[ 'user_pass' ] );
1893
+
1894
+ $current_row_id = $this->row[ 'ID' ];
1895
+ }
1896
+
1897
+ $get_table_data = true;
1898
+ }
1899
+ elseif ( 'comment' == $this->pod_data[ 'type' ] ) {
1900
+ $this->row = get_comment( $id, ARRAY_A );
1901
+
1902
+ // No slug handling here
1903
+
1904
+ if ( is_wp_error( $this->row ) || empty( $this->row ) )
1905
+ $this->row = false;
1906
+ else
1907
+ $current_row_id = $this->row[ 'comment_ID' ];
1908
+
1909
+ $get_table_data = true;
1910
+ }
1911
+ elseif ( 'settings' == $this->pod_data[ 'type' ] ) {
1912
+ $this->row = array();
1913
+
1914
+ if ( empty( $this->fields ) )
1915
+ $this->row = false;
1916
+ else {
1917
+ foreach ( $this->fields as $field ) {
1918
+ if ( !in_array( $field[ 'type' ], $tableless_field_types ) )
1919
+ $this->row[ $field[ 'name' ] ] = get_option( $this->pod_data[ 'name' ] . '_' . $field[ 'name' ], null );
1920
+ }
1921
+
1922
+ // Force ID
1923
+ $this->id = $this->pod_data[ 'id' ];
1924
+ $this->row[ 'option_id' ] = $this->id;
1925
+ }
1926
+ }
1927
+ else {
1928
+ $params = array(
1929
+ 'table' => $this->table,
1930
+ 'where' => "`t`.`{$this->field_id}` = " . (int) $id,
1931
+ 'orderby' => "`t`.`{$this->field_id}` DESC",
1932
+ 'page' => 1,
1933
+ 'limit' => 1,
1934
+ 'search' => false
1935
+ );
1936
+
1937
+ if ( 'slug' == $mode && !empty( $this->field_slug ) ) {
1938
+ $id = pods_sanitize( $id );
1939
+ $params[ 'where' ] = "`t`.`{$this->field_slug}` = '{$id}'";
1940
+ }
1941
+
1942
+ $this->row = pods_data()->select( $params );
1943
+
1944
+ if ( empty( $this->row ) )
1945
+ $this->row = false;
1946
+ else {
1947
+ $current_row = (array) $this->row;
1948
+ $this->row = get_object_vars( (object) @current( $current_row ) );
1949
+ }
1950
+ }
1951
+
1952
+ if ( !$explicit_set && !empty( $this->row ) && is_array( $this->row ) && !empty( $old_row ) ) {
1953
+ $this->row = array_merge( $old_row, $this->row );
1954
+ }
1955
+
1956
+ if ( 'table' == $this->pod_data[ 'storage' ] && false !== $get_table_data && is_numeric( $current_row_id ) ) {
1957
+ $params = array(
1958
+ 'table' => $wpdb->prefix . "pods_",
1959
+ 'where' => "`t`.`id` = {$current_row_id}",
1960
+ 'orderby' => "`t`.`id` DESC",
1961
+ 'page' => 1,
1962
+ 'limit' => 1,
1963
+ 'search' => false,
1964
+ 'strict' => true
1965
+ );
1966
+
1967
+ if ( empty( $this->pod_data[ 'object' ] ) )
1968
+ $params[ 'table' ] .= $this->pod_data[ 'name' ];
1969
+ else
1970
+ $params[ 'table' ] .= $this->pod_data[ 'object' ];
1971
+
1972
+ $row = pods_data()->select( $params );
1973
+
1974
+ if ( !empty( $row ) ) {
1975
+ $current_row = (array) $row;
1976
+ $row = get_object_vars( (object) @current( $current_row ) );
1977
+
1978
+ if ( is_array( $this->row ) && !empty( $this->row ) )
1979
+ $this->row = array_merge( $this->row, $row );
1980
+ else
1981
+ $this->row = $row;
1982
+ }
1983
+ }
1984
+
1985
+ if ( !empty( $this->pod ) && ! $already_cached ) {
1986
+ pods_cache_set( $id, $this->row, 'pods_items_' . $this->pod, 0 );
1987
+ }
1988
+ }
1989
+
1990
+ $this->row = apply_filters( 'pods_data_fetch', $this->row, $id, $this->row_number, $this );
1991
+
1992
+ return $this->row;
1993
+ }
1994
+
1995
+ /**
1996
+ * Reset the current data
1997
+ *
1998
+ * @param int $row Row number to reset to
1999
+ *
2000
+ * @return mixed
2001
+ *
2002
+ * @since 2.0
2003
+ */
2004
+ public function reset ( $row = null ) {
2005
+ $row = pods_absint( $row );
2006
+
2007
+ $this->row = false;
2008
+
2009
+ if ( isset( $this->data[ $row ] ) )
2010
+ $this->row = get_object_vars( $this->data[ $row ] );
2011
+
2012
+ if ( empty( $row ) )
2013
+ $this->row_number = -1;
2014
+ else
2015
+ $this->row_number = $row - 1;
2016
+
2017
+ return $this->row;
2018
+ }
2019
+
2020
+ /**
2021
+ * @static
2022
+ *
2023
+ * Do a query on the database
2024
+ *
2025
+ * @param string|array $sql The SQL to execute
2026
+ * @param string $error Error to throw on problems
2027
+ * @param null $results_error (optional)
2028
+ * @param null $no_results_error (optional)
2029
+ *
2030
+ * @return array|bool|mixed|null|void Result of the query
2031
+ *
2032
+ * @since 2.0
2033
+ */
2034
+ public static function query ( $sql, $error = 'Database Error', $results_error = null, $no_results_error = null ) {
2035
+ /**
2036
+ * @var $wpdb wpdb
2037
+ */
2038
+ global $wpdb;
2039
+
2040
+ if ( $wpdb->show_errors )
2041
+ self::$display_errors = true;
2042
+
2043
+ $display_errors = self::$display_errors;
2044
+
2045
+ if ( is_object( $error ) ) {
2046
+ if ( isset( $error->display_errors ) && false === $error->display_errors )
2047
+ $display_errors = false;
2048
+
2049
+ $error = 'Database Error';
2050
+ }
2051
+ elseif ( is_bool( $error ) ) {
2052
+ $display_errors = $error;
2053
+
2054
+ if ( false !== $error )
2055
+ $error = 'Database Error';
2056
+ }
2057
+
2058
+ $params = (object) array(
2059
+ 'sql' => $sql,
2060
+ 'error' => $error,
2061
+ 'results_error' => $results_error,
2062
+ 'no_results_error' => $no_results_error,
2063
+ 'display_errors' => $display_errors
2064
+ );
2065
+
2066
+ // Handle Preparations of Values (sprintf format)
2067
+ if ( is_array( $sql ) ) {
2068
+ if ( isset( $sql[ 0 ] ) && 1 < count( $sql ) ) {
2069
+ if ( 2 == count( $sql ) ) {
2070
+ if ( !is_array( $sql[ 1 ] ) )
2071
+ $sql[ 1 ] = array( $sql[ 1 ] );
2072
+
2073
+ $params->sql = self::prepare( $sql[ 0 ], $sql[ 1 ] );
2074
+ }
2075
+ elseif ( 3 == count( $sql ) )
2076
+ $params->sql = self::prepare( $sql[ 0 ], array( $sql[ 1 ], $sql[ 2 ] ) );
2077
+ else
2078
+ $params->sql = self::prepare( $sql[ 0 ], array( $sql[ 1 ], $sql[ 2 ], $sql[ 3 ] ) );
2079
+ }
2080
+ else
2081
+ $params = array_merge( $params, $sql );
2082
+
2083
+ if ( 1 == pods_var( 'pods_debug_sql_all', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) )
2084
+ echo '<textarea cols="100" rows="24">' . esc_textarea( str_replace( array( '@wp_users', '@wp_' ), array( $wpdb->users, $wpdb->prefix ), $params->sql ) ) . '</textarea>';
2085
+ }
2086
+
2087
+ $params->sql = trim( $params->sql );
2088
+
2089
+ // Run Query
2090
+ $params->sql = apply_filters( 'pods_data_query', $params->sql, $params );
2091
+
2092
+ $result = $wpdb->query( $params->sql );
2093
+
2094
+ $result = apply_filters( 'pods_data_query_result', $result, $params );
2095
+
2096
+ if ( false === $result && !empty( $params->error ) && !empty( $wpdb->last_error ) )
2097
+ return pods_error( "{$params->error}; SQL: {$params->sql}; Response: {$wpdb->last_error}", $params->display_errors );
2098
+
2099
+ if ( 'INSERT' == strtoupper( substr( $params->sql, 0, 6 ) ) || 'REPLACE' == strtoupper( substr( $params->sql, 0, 7 ) ) )
2100
+ $result = $wpdb->insert_id;
2101
+ elseif ( preg_match( '/^[\s\r\n\(]*SELECT/', strtoupper( $params->sql ) ) ) {
2102
+ $result = (array) $wpdb->last_result;
2103
+
2104
+ if ( !empty( $result ) && !empty( $params->results_error ) )
2105
+ return pods_error( $params->results_error, $params->display_errors );
2106
+ elseif ( empty( $result ) && !empty( $params->no_results_error ) )
2107
+ return pods_error( $params->no_results_error, $params->display_errors );
2108
+ }
2109
+
2110
+ return $result;
2111
+ }
2112
+
2113
+ /**
2114
+ * Gets all tables in the WP database, optionally exclude WP core
2115
+ * tables, and/or Pods table by settings the parameters to false.
2116
+ *
2117
+ * @param boolean $wp_core
2118
+ * @param boolean $pods_tables restrict Pods 2.x tables
2119
+ *
2120
+ * @return array
2121
+ *
2122
+ * @since 2.0
2123
+ */
2124
+ public static function get_tables ( $wp_core = true, $pods_tables = true ) {
2125
+ global $wpdb;
2126
+
2127
+ $core_wp_tables = array(
2128
+ $wpdb->options,
2129
+ $wpdb->comments,
2130
+ $wpdb->commentmeta,
2131
+ $wpdb->posts,
2132
+ $wpdb->postmeta,
2133
+ $wpdb->users,
2134
+ $wpdb->usermeta,
2135
+ $wpdb->links,
2136
+ $wpdb->terms,
2137
+ $wpdb->term_taxonomy,
2138
+ $wpdb->term_relationships
2139
+ );
2140
+
2141
+ $showTables = $wpdb->get_results( 'SHOW TABLES in ' . DB_NAME, ARRAY_A );
2142
+
2143
+ $finalTables = array();
2144
+
2145
+ foreach ( $showTables as $table ) {
2146
+ if ( !$pods_tables && 0 === ( strpos( $table[ 0 ], $wpdb->prefix . rtrim( self::$prefix, '_' ) ) ) ) // don't include pods tables
2147
+ continue;
2148
+ elseif ( !$wp_core && in_array( $table[ 0 ], $core_wp_tables ) )
2149
+ continue;
2150
+ else
2151
+ $finalTables[] = $table[ 0 ];
2152
+ }
2153
+
2154
+ return $finalTables;
2155
+ }
2156
+
2157
+ /**
2158
+ * Gets column information from a table
2159
+ *
2160
+ * @param string $table Table Name
2161
+ *
2162
+ * @return array
2163
+ *
2164
+ * @since 2.0
2165
+ */
2166
+ public static function get_table_columns ( $table ) {
2167
+ global $wpdb;
2168
+
2169
+ self::query( "SHOW COLUMNS FROM `{$table}` " );
2170
+
2171
+ $table_columns = $wpdb->last_result;
2172
+
2173
+ $table_cols_and_types = array();
2174
+
2175
+ foreach ( $table_columns as $table_col ) {
2176
+ // Get only the type, not the attributes
2177
+ if ( false === strpos( $table_col->Type, '(' ) )
2178
+ $modified_type = $table_col->Type;
2179
+ else
2180
+ $modified_type = substr( $table_col->Type, 0, ( strpos( $table_col->Type, '(' ) ) );
2181
+
2182
+ $table_cols_and_types[ $table_col->Field ] = $modified_type;
2183
+ }
2184
+
2185
+ return $table_cols_and_types;
2186
+ }
2187
+
2188
+ /**
2189
+ * Gets column data information from a table
2190
+ *
2191
+ * @param string $column_name Column name
2192
+ * @param string $table Table name
2193
+ *
2194
+ * @return array
2195
+ *
2196
+ * @since 2.0
2197
+ */
2198
+ public static function get_column_data ( $column_name, $table ) {
2199
+ global $wpdb;
2200
+
2201
+ $column_data = $wpdb->get_results( 'DESCRIBE ' . $table, ARRAY_A );
2202
+
2203
+ foreach ( $column_data as $single_column ) {
2204
+ if ( $column_name == $single_column[ 'Field' ] )
2205
+ return $single_column;
2206
+ }
2207
+
2208
+ return $column_data;
2209
+ }
2210
+
2211
+ /**
2212
+ * Prepare values for the DB
2213
+ *
2214
+ * @param string $sql SQL to prepare
2215
+ * @param array $data Data to add to the sql prepare statement
2216
+ *
2217
+ * @return bool|null|string
2218
+ *
2219
+ * @since 2.0
2220
+ */
2221
+ public static function prepare ( $sql, $data ) {
2222
+ /**
2223
+ * @var $wpdb wpdb
2224
+ */
2225
+ global $wpdb;
2226
+ list( $sql, $data ) = apply_filters( 'pods_data_prepare', array( $sql, $data ) );
2227
+ return $wpdb->prepare( $sql, $data );
2228
+ }
2229
+
2230
+ /**
2231
+ * Get the string to use in a query for WHERE/HAVING, uses WP_Query meta_query arguments
2232
+ *
2233
+ * @param array $fields Array of field matches for querying
2234
+ * @param array $pod Related Pod
2235
+ * @param object $params Parameters passed from select()
2236
+ *
2237
+ * @return string|null Query string for WHERE/HAVING
2238
+ *
2239
+ * @static
2240
+ * @since 2.3
2241
+ */
2242
+ public static function query_fields ( $fields, $pod = null, &$params = null ) {
2243
+ $query_fields = array();
2244
+
2245
+ if ( !is_object( $params ) ) {
2246
+ $params = new stdClass();
2247
+ }
2248
+
2249
+ if ( !isset( $params->query_field_level ) || 0 == $params->query_field_level ) {
2250
+ $params->query_fields = array();
2251
+ $params->query_field_syntax = false;
2252
+ $params->query_field_level = 1;
2253
+
2254
+ if ( !isset( $params->where_default ) ) {
2255
+ $params->where_default = array();
2256
+ }
2257
+
2258
+ if ( !isset( $params->where_defaulted ) ) {
2259
+ $params->where_defaulted = false;
2260
+ }
2261
+ }
2262
+
2263
+ $current_level = $params->query_field_level;
2264
+
2265
+ $relation = 'AND';
2266
+
2267
+ if ( isset( $fields[ 'relation' ] ) ) {
2268
+ $relation = strtoupper( trim( pods_var( 'relation', $fields, 'AND', null, true ) ) );
2269
+
2270
+ if ( 'AND' != $relation )
2271
+ $relation = 'OR';
2272
+
2273
+ unset( $fields[ 'relation' ] );
2274
+ }
2275
+
2276
+ foreach ( $fields as $field => $match ) {
2277
+ if ( is_array( $match ) && isset( $match[ 'relation' ] ) ) {
2278
+ $params->query_field_level = $current_level + 1;
2279
+
2280
+ $query_field = self::query_fields( $match, $pod, $params );
2281
+
2282
+ $params->query_field_level = $current_level;
2283
+
2284
+ if ( !empty( $query_field ) ) {
2285
+ $query_fields[] = $query_field;
2286
+ }
2287
+ }
2288
+ else {
2289
+ $query_field = self::query_field( $field, $match, $pod, $params );
2290
+
2291
+ if ( !empty( $query_field ) ) {
2292
+ $query_fields[] = $query_field;
2293
+ }
2294
+ }
2295
+ }
2296
+
2297
+ if ( !empty( $query_fields ) ) {
2298
+ // If post_status not sent, detect it
2299
+ if ( !empty( $pod ) && 'post_type' == $pod[ 'type' ] && 1 == $current_level && !$params->where_defaulted && !empty( $params->where_default ) ) {
2300
+ $post_status_found = false;
2301
+
2302
+ if ( !$params->query_field_syntax ) {
2303
+ $haystack = implode( ' ', (array) $query_fields );
2304
+ $haystack = preg_replace( '/\s/', ' ', $haystack );
2305
+ $haystack = preg_replace( '/\w\(/', ' ', $haystack );
2306
+ $haystack = str_replace( array( '(', ')', ' ', '\\\'', "\\\"" ), ' ', $haystack );
2307
+
2308
+ preg_match_all( '/`?[\w\-]+`?(?:\\.`?[\w\-]+`?)+(?=[^"\']*(?:"[^"]*"[^"]*|\'[^\']*\'[^\']*)*$)/', $haystack, $found, PREG_PATTERN_ORDER );
2309
+
2310
+ $found = (array) @current( $found );
2311
+
2312
+ foreach ( $found as $value ) {
2313
+ $value = str_replace( '`', '', $value );
2314
+ $value = explode( '.', $value );
2315
+
2316
+ if ( ( 'post_status' == $value[ 0 ] && 1 == count( $value ) ) || ( 2 == count( $value ) && 't' == $value[ 0 ] && 'post_status' == $value[ 1 ] ) ) {
2317
+ $post_status_found = true;
2318
+
2319
+ break;
2320
+ }
2321
+ }
2322
+ }
2323
+ elseif ( !empty( $params->query_fields ) && in_array( 'post_status', $params->query_fields ) ) {
2324
+ $post_status_found = true;
2325
+ }
2326
+
2327
+ if ( !$post_status_found ) {
2328
+ $query_fields[] = $params->where_default;
2329
+ }
2330
+ }
2331
+
2332
+ if ( 1 < count( $query_fields ) )
2333
+ $query_fields = '( ( ' . implode( ' ) ' . $relation . ' ( ', $query_fields ) . ' ) )';
2334
+ else
2335
+ $query_fields = '( ' . implode( ' ' . $relation . ' ', $query_fields ) . ' )';
2336
+ }
2337
+ else
2338
+ $query_fields = null;
2339
+
2340
+ // query_fields level complete
2341
+ if ( 1 == $params->query_field_level ) {
2342
+ $params->query_field_level = 0;
2343
+ }
2344
+
2345
+ return $query_fields;
2346
+ }
2347
+
2348
+ /**
2349
+ * Get the string to use in a query for matching, uses WP_Query meta_query arguments
2350
+ *
2351
+ * @param string|int $field Field name or array index
2352
+ * @param array|string $q Query array (meta_query) or string for matching
2353
+ * @param array $pod Related Pod
2354
+ * @param object $params Parameters passed from select()
2355
+ *
2356
+ * @return string|null Query field string
2357
+ *
2358
+ * @see PodsData::query_fields
2359
+ * @static
2360
+ * @since 2.3
2361
+ */
2362
+ public static function query_field ( $field, $q, $pod = null, &$params = null ) {
2363
+ global $wpdb;
2364
+
2365
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
2366
+
2367
+ $field_query = null;
2368
+
2369
+ // Plain queries
2370
+ if ( is_numeric( $field ) && !is_array( $q ) ) {
2371
+ return $q;
2372
+ }
2373
+ // key => value queries (backwards compatibility)
2374
+ elseif ( !is_numeric( $field ) && ( !is_array( $q ) || ( !isset( $q[ 'key' ] ) && !isset( $q[ 'field' ] ) ) ) ) {
2375
+ $new_q = array(
2376
+ 'field' => $field,
2377
+ 'compare' => pods_var_raw( 'compare', $q, '=', null, true ),
2378
+ 'value' => pods_var_raw( 'value', $q, $q, null, true ),
2379
+ 'sanitize' => pods_var_raw( 'sanitize', $q, true ),
2380
+ 'sanitize_format' => pods_var_raw( 'sanitize_format', $q ),
2381
+ 'cast' => pods_var_raw( 'cast', $q )
2382
+ );
2383
+
2384
+ if ( is_array( $new_q[ 'value' ] ) ) {
2385
+ if ( '=' == $new_q[ 'compare' ] )
2386
+ $new_q[ 'compare' ] = 'IN';
2387
+
2388
+ if ( isset( $new_q[ 'value' ][ 'compare' ] ) )
2389
+ unset( $new_q[ 'value' ][ 'compare' ] );
2390
+ }
2391
+
2392
+ $q = $new_q;
2393
+ }
2394
+
2395
+ $field_name = trim( pods_var_raw( 'field', $q, pods_var_raw( 'key', $q, $field, null, true ), null, true ) );
2396
+ $field_type = strtoupper( trim( pods_var_raw( 'type', $q, 'CHAR', null, true ) ) );
2397
+ $field_value = pods_var_raw( 'value', $q );
2398
+ $field_compare = strtoupper( trim( pods_var_raw( 'compare', $q, ( is_array( $field_value ? 'IN' : '=' ) ), null, true ) ) );
2399
+ $field_sanitize = (boolean) pods_var( 'sanitize', $q, true );
2400
+ $field_sanitize_format = pods_var_raw( 'sanitize_format', $q, null, null, true );
2401
+ $field_cast = pods_var_raw( 'cast', $q, null, null, true );
2402
+
2403
+ if ( is_object( $params ) ) {
2404
+ $params->meta_query_syntax = true;
2405
+ $params->query_fields[] = $field_name;
2406
+ }
2407
+
2408
+ // Deprecated WP type
2409
+ if ( 'NUMERIC' == $field_type )
2410
+ $field_type = 'SIGNED';
2411
+ // Restrict to supported types
2412
+ elseif ( !in_array( $field_type, array( 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED' ) ) )
2413
+ $field_type = 'CHAR';
2414
+
2415
+ // Alias / Casting
2416
+ if ( empty( $field_cast ) ) {
2417
+ // Setup field casting from field name
2418
+ if ( false === strpos( $field_name, '`' ) && false === strpos( $field_name, '(' ) && false === strpos( $field_name, ' ' ) ) {
2419
+ // Handle field naming if Pod-based
2420
+ if ( !empty( $pod ) && false === strpos( $field_name, '.' ) ) {
2421
+ $field_cast = '';
2422
+
2423
+ $tableless_field_types = PodsForm::tableless_field_types();
2424
+
2425
+ if ( isset( $pod[ 'fields' ][ $field_name ] ) && in_array( $pod[ 'fields' ][ $field_name ][ 'type' ], $tableless_field_types ) ) {
2426
+ if ( in_array( $pod[ 'fields' ][ $field_name ][ 'pick_object' ], $simple_tableless_objects ) ) {
2427
+ if ( 'meta' == $pod[ 'storage' ] )
2428
+ $field_cast = "`{$field_name}`.`meta_value`";
2429
+ else
2430
+ $field_cast = "`t`.`{$field_name}`";
2431
+ }
2432
+ else {
2433
+ $table = pods_api()->get_table_info( $pod[ 'fields' ][ $field_name ][ 'pick_object' ], $pod[ 'fields' ][ $field_name ][ 'pick_val' ] );
2434
+
2435
+ if ( !empty( $table ) )
2436
+ $field_cast = "`{$field_name}`.`" . $table[ 'field_index' ] . '`';
2437
+ }
2438
+ }
2439
+
2440
+ if ( empty( $field_cast ) ) {
2441
+ if ( !in_array( $pod[ 'type' ], array( 'pod', 'table' ) ) ) {
2442
+ if ( isset( $pod[ 'object_fields' ][ $field_name ] ) )
2443
+ $field_cast = "`t`.`{$field_name}`";
2444
+ elseif ( isset( $pod[ 'fields' ][ $field_name ] ) ) {
2445
+ if ( 'meta' == $pod['storage'] )
2446
+ $field_cast = "`{$field_name}`.`meta_value`";
2447
+ else
2448
+ $field_cast = "`d`.`{$field_name}`";
2449
+ }
2450
+ else {
2451
+ foreach ( $pod[ 'object_fields' ] as $object_field => $object_field_opt ) {
2452
+ if ( $object_field == $field_name || in_array( $field_name, $object_field_opt[ 'alias' ] ) ) {
2453
+ $field_cast = "`t`.`{$object_field}`";
2454
+
2455
+ break;
2456
+ }
2457
+ }
2458
+ }
2459
+ }
2460
+ elseif ( isset( $pod[ 'fields' ][ $field_name ] ) ) {
2461
+ if ( 'meta' == $pod['storage'] )
2462
+ $field_cast = "`{$field_name}`.`meta_value`";
2463
+ else
2464
+ $field_cast = "`t`.`{$field_name}`";
2465
+ }
2466
+
2467
+ if ( empty( $field_cast ) ) {
2468
+ if ( 'meta' == $pod['storage'] ) {
2469
+ $field_cast = "`{$field_name}`.`meta_value`";
2470
+ }
2471
+ else
2472
+ $field_cast = "`t`.`{$field_name}`";
2473
+ }
2474
+ }
2475
+ }
2476
+ else {
2477
+ $field_cast = '`' . str_replace( '.', '`.`', $field_name ) . '`';
2478
+ }
2479
+ }
2480
+ else {
2481
+ $field_cast = $field_name;
2482
+ }
2483
+
2484
+ // Cast field if needed
2485
+ if ( 'CHAR' != $field_type ) {
2486
+ $field_cast = 'CAST( ' . $field_cast . ' AS ' . $field_type .' )';
2487
+ }
2488
+ }
2489
+
2490
+ // Setup string sanitizing for $wpdb->prepare()
2491
+ if ( empty( $field_sanitize_format ) ) {
2492
+ // Sanitize as string
2493
+ $field_sanitize_format = '%s';
2494
+
2495
+ // Sanitize as integer if needed
2496
+ if ( in_array( $field_type, array( 'UNSIGNED', 'SIGNED' ) ) )
2497
+ $field_sanitize_format = '%d';
2498
+ }
2499
+
2500
+ // Restrict to supported comparisons
2501
+ if ( !in_array( $field_compare, array( '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'ALL', 'BETWEEN', 'NOT BETWEEN', 'EXISTS', 'NOT EXISTS', 'REGEXP', 'NOT REGEXP', 'RLIKE' ) ) )
2502
+ $field_compare = '=';
2503
+
2504
+ // Restrict to supported array comparisons
2505
+ if ( is_array( $field_value ) && !in_array( $field_compare, array( 'IN', 'NOT IN', 'ALL', 'BETWEEN', 'NOT BETWEEN' ) ) ) {
2506
+ if ( in_array( $field_compare, array( '!=', 'NOT LIKE' ) ) )
2507
+ $field_compare = 'NOT IN';
2508
+ else
2509
+ $field_compare = 'IN';
2510
+ }
2511
+ // Restrict to supported string comparisons
2512
+ elseif ( !is_array( $field_value ) && in_array( $field_compare, array( 'IN', 'NOT IN', 'ALL', 'BETWEEN', 'NOT BETWEEN' ) ) ) {
2513
+ $check_value = preg_split( '/[,\s]+/', $field_value );
2514
+
2515
+ if ( 1 < count( $check_value ) )
2516
+ $field_value = $check_value;
2517
+ elseif ( in_array( $field_compare, array( 'NOT IN', 'NOT BETWEEN' ) ) )
2518
+ $field_compare = '!=';
2519
+ else
2520
+ $field_compare = '=';
2521
+ }
2522
+
2523
+ // Restrict to two values, force = and != if only one value provided
2524
+ if ( in_array( $field_compare, array( 'BETWEEN', 'NOT BETWEEN' ) ) ) {
2525
+ $field_value = array_values( array_slice( $field_value, 0, 2 ) );
2526
+
2527
+ if ( 1 == count( $field_value ) ) {
2528
+ if ( 'NOT IN' == $field_compare )
2529
+ $field_compare = '!=';
2530
+ else
2531
+ $field_compare = '=';
2532
+ }
2533
+ }
2534
+
2535
+ // Single array handling
2536
+ if ( 1 == count( $field_value ) && $field_compare == 'ALL' ) {
2537
+ $field_compare = '=';
2538
+ }
2539
+ // Empty array handling
2540
+ elseif ( empty( $field_value ) && in_array( $field_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) {
2541
+ $field_compare = 'EXISTS';
2542
+ }
2543
+
2544
+ // Rebuild $q
2545
+ $q = array(
2546
+ 'field' => $field_name,
2547
+ 'type' => $field_type,
2548
+ 'value' => $field_value,
2549
+ 'compare' => $field_compare,
2550
+ 'sanitize' => $field_sanitize,
2551
+ 'sanitize_format' => $field_sanitize_format,
2552
+ 'cast' => $field_cast
2553
+ );
2554
+
2555
+ // Make the query
2556
+ if ( in_array( $field_compare, array( '=', '!=', '>', '>=', '<', '<=', 'REGEXP', 'NOT REGEXP', 'RLIKE' ) ) ) {
2557
+ if ( $field_sanitize ) {
2558
+ $field_query = $wpdb->prepare( $field_cast . ' ' . $field_compare . ' ' . $field_sanitize_format, $field_value );
2559
+ }
2560
+ else {
2561
+ $field_query = $field_cast . ' ' . $field_compare . ' "' . $field_value . '"';
2562
+ }
2563
+ }
2564
+ elseif ( in_array( $field_compare, array( 'LIKE', 'NOT LIKE' ) ) ) {
2565
+ if ( $field_sanitize ) {
2566
+ $field_query = $field_cast . ' ' . $field_compare . ' "%' . pods_sanitize_like( $field_value ) . '%"';
2567
+ }
2568
+ else {
2569
+ $field_query = $field_cast . ' ' . $field_compare . ' "' . $field_value . '"';
2570
+ }
2571
+ }
2572
+ elseif ( in_array( $field_compare, array( 'IN', 'NOT IN', 'ALL' ) ) ) {
2573
+ if ( $field_compare == 'ALL' ) {
2574
+ $field_compare = 'IN';
2575
+
2576
+ if ( ! empty( $pod ) ) {
2577
+ $params->having[] = 'COUNT( DISTINCT ' . $field_cast . ' ) = ' . count( $field_value );
2578
+
2579
+ if ( empty( $params->groupby ) || ( ! in_array( '`t`.`' . $pod['field_id'] . '`', $params->groupby ) && ! in_array( 't.' . $pod['field_id'] . '', $params->groupby ) ) ) {
2580
+ $params->groupby[] = '`t`.`' . $pod['field_id'] . '`';
2581
+ }
2582
+ }
2583
+ }
2584
+
2585
+ if ( $field_sanitize ) {
2586
+ $field_query = $wpdb->prepare( $field_cast . ' ' . $field_compare . ' ( ' . substr( str_repeat( ', ' . $field_sanitize_format, count( $field_value ) ), 1 ) . ' )', $field_value );
2587
+ }
2588
+ else {
2589
+ $field_query = $field_cast . ' ' . $field_compare . ' ( "' . implode( '", "', $field_value ) . '" )';
2590
+ }
2591
+ }
2592
+ elseif ( in_array( $field_compare, array( 'BETWEEN', 'NOT BETWEEN' ) ) ) {
2593
+ if ( $field_sanitize ) {
2594
+ $field_query = $wpdb->prepare( $field_cast . ' ' . $field_compare . ' ' . $field_sanitize_format . ' AND ' . $field_sanitize_format, $field_value );
2595
+ }
2596
+ else {
2597
+ $field_query = $field_cast . ' ' . $field_compare . ' "' . $field_value[ 0 ] . '" AND "' . $field_value[ 1 ] . '"';
2598
+ }
2599
+ }
2600
+ elseif ( 'EXISTS' == $field_compare )
2601
+ $field_query = $field_cast . ' IS NOT NULL';
2602
+ elseif ( 'NOT EXISTS' == $field_compare )
2603
+ $field_query = $field_cast . ' IS NULL';
2604
+
2605
+ $field_query = apply_filters( 'pods_data_field_query', $field_query, $q );
2606
+
2607
+ return $field_query;
2608
+ }
2609
+
2610
+ /**
2611
+ * Setup fields for traversal
2612
+ *
2613
+ * @param array $fields Associative array of fields data
2614
+ *
2615
+ * @return array Traverse feed
2616
+ * @param object $params (optional) Parameters from build()
2617
+ *
2618
+ * @since 2.0
2619
+ */
2620
+ function traverse_build ( $fields = null, $params = null ) {
2621
+ if ( null === $fields )
2622
+ $fields = $this->fields;
2623
+
2624
+ $feed = array();
2625
+
2626
+ foreach ( $fields as $field => $data ) {
2627
+ if ( !is_array( $data ) )
2628
+ $field = $data;
2629
+
2630
+ if ( !isset( $_GET[ 'filter_' . $field ] ) )
2631
+ continue;
2632
+
2633
+ $field_value = pods_var( 'filter_' . $field, 'get', false, null, true );
2634
+
2635
+ if ( !empty( $field_value ) || 0 < strlen( $field_value ) )
2636
+ $feed[ 'traverse_' . $field ] = array( $field );
2637
+ }
2638
+
2639
+ return $feed;
2640
+ }
2641
+
2642
+ /**
2643
+ * Recursively join tables based on fields
2644
+ *
2645
+ * @param array $traverse_recurse Array of traversal options
2646
+ *
2647
+ * @return array Array of table joins
2648
+ *
2649
+ * @since 2.0
2650
+ */
2651
+ function traverse_recurse ( $traverse_recurse ) {
2652
+ global $wpdb;
2653
+
2654
+ $defaults = array(
2655
+ 'pod' => null,
2656
+ 'fields' => array(),
2657
+ 'joined' => 't',
2658
+ 'depth' => 0,
2659
+ 'joined_id' => 'id',
2660
+ 'joined_index' => 'id',
2661
+ 'params' => new stdClass(),
2662
+ 'last_table_info' => array()
2663
+ );
2664
+
2665
+ $traverse_recurse = array_merge( $defaults, $traverse_recurse );
2666
+
2667
+ $joins = array();
2668
+
2669
+ if ( 0 == $traverse_recurse[ 'depth' ] && !empty( $traverse_recurse[ 'pod' ] ) && !empty( $traverse_recurse [ 'last_table_info' ] ) && isset( $traverse_recurse [ 'last_table_info' ][ 'id' ] ) )
2670
+ $pod_data = $traverse_recurse [ 'last_table_info' ];
2671
+ elseif ( empty( $traverse_recurse[ 'pod' ] ) ) {
2672
+ if ( !empty( $traverse_recurse[ 'params' ] ) && !empty( $traverse_recurse[ 'params' ]->table ) && 0 === strpos( $traverse_recurse[ 'params' ]->table, $wpdb->prefix ) ) {
2673
+ if ( $wpdb->posts == $traverse_recurse[ 'params' ]->table )
2674
+ $traverse_recurse[ 'pod' ] = 'post_type';
2675
+ elseif ( $wpdb->terms == $traverse_recurse[ 'params' ]->table )
2676
+ $traverse_recurse[ 'pod' ] = 'taxonomy';
2677
+ elseif ( $wpdb->users == $traverse_recurse[ 'params' ]->table )
2678
+ $traverse_recurse[ 'pod' ] = 'user';
2679
+ elseif ( $wpdb->comments == $traverse_recurse[ 'params' ]->table )
2680
+ $traverse_recurse[ 'pod' ] = 'comment';
2681
+ else
2682
+ return $joins;
2683
+
2684
+ $pod_data = array();
2685
+
2686
+ if ( in_array( $traverse_recurse[ 'pod' ], array( 'user', 'comment' ) ) ) {
2687
+ $pod = $this->api->load_pod( array( 'name' => $traverse_recurse[ 'pod' ], 'table_info' => true ) );
2688
+
2689
+ if ( !empty( $pod ) && $pod[ 'type' ] == $pod )
2690
+ $pod_data = $pod;
2691
+ }
2692
+
2693
+ if ( empty( $pod_data ) ) {
2694
+ $default_storage = 'meta';
2695
+
2696
+ if ( 'taxonomy' == $traverse_recurse['pod'] && ! function_exists( 'get_term_meta' ) ) {
2697
+ $default_storage = 'none';
2698
+ }
2699
+
2700
+ $pod_data = array(
2701
+ 'id' => 0,
2702
+ 'name' => '_table_' . $traverse_recurse[ 'pod' ],
2703
+ 'type' => $traverse_recurse[ 'pod' ],
2704
+ 'storage' => $default_storage,
2705
+ 'fields' => array(),
2706
+ 'object_fields' => $this->api->get_wp_object_fields( $traverse_recurse[ 'pod' ] )
2707
+ );
2708
+
2709
+ $pod_data = array_merge( $this->api->get_table_info( $traverse_recurse[ 'pod' ], '' ), $pod_data );
2710
+ } elseif ( 'taxonomy' == $pod_data['type'] && 'none' == $pod_data['storage'] && function_exists( 'get_term_meta' ) ) {
2711
+ $pod_data['storage'] = 'meta';
2712
+ }
2713
+
2714
+ $traverse_recurse[ 'pod' ] = $pod_data[ 'name' ];
2715
+ }
2716
+ else
2717
+ return $joins;
2718
+ }
2719
+ else {
2720
+ $pod_data = $this->api->load_pod( array( 'name' => $traverse_recurse[ 'pod' ], 'table_info' => true ), false );
2721
+
2722
+ if ( empty( $pod_data ) )
2723
+ return $joins;
2724
+ }
2725
+
2726
+ if ( isset( $pod_data[ 'object_fields' ] ) ) {
2727
+ $pod_data[ 'fields' ] = array_merge( $pod_data[ 'fields' ], $pod_data[ 'object_fields' ] );
2728
+ }
2729
+
2730
+ $tableless_field_types = PodsForm::tableless_field_types();
2731
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
2732
+ $file_field_types = PodsForm::file_field_types();
2733
+
2734
+ if ( !isset( $this->traversal[ $traverse_recurse[ 'pod' ] ] ) )
2735
+ $this->traversal[ $traverse_recurse[ 'pod' ] ] = array();
2736
+
2737
+ if ( ( empty( $pod_data[ 'meta_table' ] ) || $pod_data[ 'meta_table' ] == $pod_data[ 'table' ] ) && ( empty( $traverse_recurse[ 'fields' ] ) || empty( $traverse_recurse[ 'fields' ][ $traverse_recurse[ 'depth' ] ] ) ) )
2738
+ return $joins;
2739
+
2740
+ $field = $traverse_recurse[ 'fields' ][ $traverse_recurse[ 'depth' ] ];
2741
+
2742
+ $ignore_aliases = array(
2743
+ 'wpml_languages',
2744
+ 'polylang_languages'
2745
+ );
2746
+
2747
+ $ignore_aliases = apply_filters( 'pods_data_traverse_recurse_ignore_aliases', $ignore_aliases, $field, $traverse_recurse, $this );
2748
+
2749
+ if ( in_array( $field, $ignore_aliases ) )
2750
+ return $joins;
2751
+
2752
+ $meta_data_table = false;
2753
+
2754
+ if ( !isset( $pod_data[ 'fields' ][ $field ] ) && 'd' == $field && isset( $traverse_recurse[ 'fields' ][ $traverse_recurse[ 'depth' ] - 1 ] ) ) {
2755
+ $field = $traverse_recurse[ 'fields' ][ $traverse_recurse[ 'depth' ] - 1 ];
2756
+
2757
+ $field_type = 'pick';
2758
+
2759
+ if ( isset( $traverse_recurse[ 'last_table_info' ][ 'pod' ][ 'fields' ][ $field ] ) ) {
2760
+ $field_type = $traverse_recurse[ 'last_table_info' ][ 'pod' ][ 'fields' ][ $field ][ 'type' ];
2761
+ }
2762
+ elseif ( isset( $traverse_recurse[ 'last_table_info' ][ 'pod' ][ 'object_fields' ][ $field ] ) ) {
2763
+ $field_type = $traverse_recurse[ 'last_table_info' ][ 'pod' ][ 'object_fields' ][ $field ][ 'type' ];
2764
+ }
2765
+
2766
+ $pod_data[ 'fields' ][ $field ] = array(
2767
+ 'id' => 0,
2768
+ 'name' => $field,
2769
+ 'type' => $field_type,
2770
+ 'pick_object' => $traverse_recurse[ 'last_table_info' ][ 'pod' ][ 'type' ],
2771
+ 'pick_val' => $traverse_recurse[ 'last_table_info' ][ 'pod' ][ 'name' ]
2772
+ );
2773
+
2774
+ $meta_data_table = true;
2775
+ }
2776
+
2777
+ // Fallback to meta table if the pod type supports it
2778
+ if ( !isset( $pod_data[ 'fields' ][ $field ] ) ) {
2779
+ $last = end( $traverse_recurse[ 'fields' ] );
2780
+
2781
+ if ( 'post_type' == $pod_data[ 'type' ] && !isset( $pod_data[ 'object_fields' ] ) )
2782
+ $pod_data[ 'object_fields' ] = $this->api->get_wp_object_fields( 'post_type', $pod_data );
2783
+
2784
+ if ( 'post_type' == $pod_data[ 'type' ] && isset( $pod_data[ 'object_fields'][ $field ] ) && in_array( $pod_data[ 'object_fields' ][ $field ][ 'type' ], $tableless_field_types ) )
2785
+ $pod_data[ 'fields' ][ $field ] = $pod_data[ 'object_fields' ][ $field ];
2786
+ elseif ( 'meta_value' === $last && in_array( $pod_data[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) )
2787
+ $pod_data[ 'fields' ][ $field ] = PodsForm::field_setup( array( 'name' => $field ) );
2788
+ else {
2789
+ if ( 'post_type' == $pod_data[ 'type' ] ) {
2790
+ $pod_data[ 'object_fields' ] = $this->api->get_wp_object_fields( 'post_type', $pod_data, true );
2791
+
2792
+ if ( 'post_type' == $pod_data[ 'type' ] && isset( $pod_data[ 'object_fields' ][ $field ] ) && in_array( $pod_data[ 'object_fields' ][ $field ][ 'type' ], $tableless_field_types ) )
2793
+ $pod_data[ 'fields' ][ $field ] = $pod_data[ 'object_fields' ][ $field ];
2794
+ else
2795
+ return $joins;
2796
+ }
2797
+ else
2798
+ return $joins;
2799
+ }
2800
+ } elseif ( isset( $pod_data[ 'object_fields' ] ) && isset( $pod_data[ 'object_fields' ][ $field ] ) && ! in_array( $pod_data[ 'object_fields' ][ $field ][ 'type' ], $tableless_field_types ) ) {
2801
+ return $joins;
2802
+ }
2803
+
2804
+ $traverse = $pod_data[ 'fields' ][ $field ];
2805
+
2806
+ if ( 'taxonomy' == $traverse[ 'type' ] )
2807
+ $traverse[ 'table_info' ] = $this->api->get_table_info( $traverse[ 'type' ], $traverse[ 'name' ] );
2808
+ elseif ( in_array( $traverse[ 'type' ], $file_field_types ) )
2809
+ $traverse[ 'table_info' ] = $this->api->get_table_info( 'post_type', 'attachment' );
2810
+ elseif ( !in_array( $traverse[ 'type' ], $tableless_field_types ) )
2811
+ $traverse[ 'table_info' ] = $this->api->get_table_info( $pod_data[ 'type' ], $pod_data[ 'name' ], $pod_data[ 'name' ], $pod_data );
2812
+ elseif ( empty( $traverse[ 'table_info' ] ) || ( in_array( $traverse[ 'pick_object' ], $simple_tableless_objects ) && !empty( $traverse_recurse[ 'last_table_info' ] ) ) ) {
2813
+ if ( in_array( $traverse[ 'pick_object' ], $simple_tableless_objects ) && !empty( $traverse_recurse[ 'last_table_info' ] ) ) {
2814
+ $traverse[ 'table_info' ] = $traverse_recurse[ 'last_table_info' ];
2815
+
2816
+ if ( !empty( $traverse[ 'table_info' ][ 'meta_table' ] ) )
2817
+ $meta_data_table = true;
2818
+ }
2819
+ elseif ( !in_array( $traverse[ 'type' ], $tableless_field_types ) && !empty( $traverse_recurse[ 'last_table_info' ] ) && 0 == $traverse_recurse[ 'depth' ] )
2820
+ $traverse[ 'table_info' ] = $traverse_recurse[ 'last_table_info' ];
2821
+ else {
2822
+ if ( ! isset( $traverse[ 'pod' ] ) ) {
2823
+ $traverse[ 'pod' ] = null;
2824
+ }
2825
+
2826
+ $traverse[ 'table_info' ] = $this->api->get_table_info( $traverse[ 'pick_object' ], $traverse[ 'pick_val' ], null, $traverse[ 'pod' ], $traverse );
2827
+ }
2828
+ }
2829
+
2830
+ if ( isset( $this->traversal[ $traverse_recurse[ 'pod' ] ][ $traverse[ 'name' ] ] ) )
2831
+ $traverse = array_merge( $traverse, (array) $this->traversal[ $traverse_recurse[ 'pod' ] ][ $traverse[ 'name' ] ] );
2832
+
2833
+ $traverse = apply_filters( 'pods_data_traverse', $traverse, compact( 'pod', 'fields', 'joined', 'depth', 'joined_id', 'params' ), $this );
2834
+
2835
+ if ( empty( $traverse ) )
2836
+ return $joins;
2837
+
2838
+ $traverse[ 'id' ] = (int) $traverse[ 'id' ];
2839
+
2840
+ if ( empty( $traverse[ 'id' ] ) )
2841
+ $traverse[ 'id' ] = $field;
2842
+
2843
+ $table_info = $traverse[ 'table_info' ];
2844
+
2845
+ $this->traversal[ $traverse_recurse[ 'pod' ] ][ $field ] = $traverse;
2846
+
2847
+ $field_joined = $field;
2848
+
2849
+ if ( 0 < $traverse_recurse[ 'depth' ] && 't' != $traverse_recurse[ 'joined' ] ) {
2850
+ if ( $meta_data_table && ( 'pick' != $traverse[ 'type' ] || !in_array( pods_var( 'pick_object', $traverse ), $simple_tableless_objects ) ) )
2851
+ $field_joined = $traverse_recurse[ 'joined' ] . '_d';
2852
+ else
2853
+ $field_joined = $traverse_recurse[ 'joined' ] . '_' . $field;
2854
+ }
2855
+
2856
+ $rel_alias = 'rel_' . $field_joined;
2857
+
2858
+ if ( pods_v( 'search', $traverse_recurse[ 'params' ], false ) && empty( $traverse_recurse[ 'params' ]->filters ) ) {
2859
+ if ( 0 < strlen( pods_var( 'filter_' . $field_joined, 'get' ) ) ) {
2860
+ $val = absint( pods_var( 'filter_' . $field_joined, 'get' ) );
2861
+
2862
+ $search = "`{$field_joined}`.`{$table_info[ 'field_id' ]}` = {$val}";
2863
+
2864
+ if ( 'text' == $this->search_mode ) {
2865
+ $val = pods_var( 'filter_' . $field_joined, 'get' );
2866
+
2867
+ $search = "`{$field_joined}`.`{$traverse[ 'name' ]}` = '{$val}'";
2868
+ }
2869
+ elseif ( 'text_like' == $this->search_mode ) {
2870
+ $val = pods_sanitize( pods_sanitize_like( pods_var_raw( 'filter_' . $field_joined ) ) );
2871
+
2872
+ $search = "`{$field_joined}`.`{$traverse[ 'name' ]}` LIKE '%{$val}%'";
2873
+ }
2874
+
2875
+ $this->search_where[] = " {$search} ";
2876
+ }
2877
+ }
2878
+
2879
+ $the_join = null;
2880
+
2881
+ $joined_id = $table_info[ 'field_id' ];
2882
+ $joined_index = $table_info[ 'field_index' ];
2883
+
2884
+ if ( 'taxonomy' == $traverse[ 'type' ] ) {
2885
+ $rel_tt_alias = 'rel_tt_' . $field_joined;
2886
+
2887
+ if ( pods_tableless() && function_exists( 'get_term_meta' ) ) {
2888
+ $the_join = "
2889
+ LEFT JOIN `{$table_info[ 'meta_table' ]}` AS `{$rel_alias}` ON
2890
+ `{$rel_alias}`.`{$table_info[ 'meta_field_index' ]}` = '{$traverse[ 'name' ]}'
2891
+ AND `{$rel_alias}`.`{$table_info[ 'meta_field_id' ]}` = `{$traverse_recurse[ 'joined' ]}`.`{$traverse_recurse[ 'joined_id' ]}`
2892
+
2893
+ LEFT JOIN `{$table_info[ 'meta_table' ]}` AS `{$field_joined}` ON
2894
+ `{$field_joined}`.`{$table_info[ 'meta_field_index' ]}` = '{$traverse[ 'name' ]}'
2895
+ AND `{$field_joined}`.`{$table_info[ 'meta_field_id' ]}` = CONVERT( `{$rel_alias}`.`{$table_info[ 'meta_field_value' ]}`, SIGNED )
2896
+ ";
2897
+
2898
+ $joined_id = $table_info[ 'meta_field_id' ];
2899
+ $joined_index = $table_info[ 'meta_field_index' ];
2900
+ } elseif ( $meta_data_table ) {
2901
+ $the_join = "
2902
+ LEFT JOIN `{$table_info[ 'pod_table' ]}` AS `{$field_joined}` ON
2903
+ `{$field_joined}`.`{$table_info[ 'pod_field_id' ]}` = `{$traverse_recurse[ 'rel_alias' ]}`.`{$traverse_recurse[ 'joined_id' ]}`
2904
+ ";
2905
+ }
2906
+ else {
2907
+ $the_join = "
2908
+ LEFT JOIN `{$wpdb->term_relationships}` AS `{$rel_alias}` ON
2909
+ `{$rel_alias}`.`object_id` = `{$traverse_recurse[ 'joined' ]}`.`ID`
2910
+
2911
+ LEFT JOIN `{$wpdb->term_taxonomy}` AS `{$rel_tt_alias}` ON
2912
+ `{$rel_tt_alias}`.`taxonomy` = '{$traverse[ 'name' ]}'
2913
+ AND `{$rel_tt_alias}`.`term_taxonomy_id` = `{$rel_alias}`.`term_taxonomy_id`
2914
+
2915
+ LEFT JOIN `{$table_info[ 'table' ]}` AS `{$field_joined}` ON
2916
+ `{$field_joined}`.`{$table_info[ 'field_id' ]}` = `{$rel_tt_alias}`.`{$table_info[ 'field_id' ]}`
2917
+ ";
2918
+
2919
+ // Override $rel_alias
2920
+ $rel_alias = $field_joined;
2921
+
2922
+ $joined_id = $table_info[ 'field_id' ];
2923
+ $joined_index = $table_info[ 'field_index' ];
2924
+ }
2925
+ }
2926
+ elseif ( in_array( $traverse[ 'type' ], $tableless_field_types ) && ( 'pick' != $traverse[ 'type' ] || !in_array( pods_v( 'pick_object', $traverse ), $simple_tableless_objects ) ) ) {
2927
+ if ( pods_tableless() ) {
2928
+ $the_join = "
2929
+ LEFT JOIN `{$table_info[ 'meta_table' ]}` AS `{$rel_alias}` ON
2930
+ `{$rel_alias}`.`{$table_info[ 'meta_field_index' ]}` = '{$traverse[ 'name' ]}'
2931
+ AND `{$rel_alias}`.`{$table_info[ 'meta_field_id' ]}` = `{$traverse_recurse[ 'joined' ]}`.`{$traverse_recurse[ 'joined_id' ]}`
2932
+
2933
+ LEFT JOIN `{$table_info[ 'meta_table' ]}` AS `{$field_joined}` ON
2934
+ `{$field_joined}`.`{$table_info[ 'meta_field_index' ]}` = '{$traverse[ 'name' ]}'
2935
+ AND `{$field_joined}`.`{$table_info[ 'meta_field_id' ]}` = CONVERT( `{$rel_alias}`.`{$table_info[ 'meta_field_value' ]}`, SIGNED )
2936
+ ";
2937
+
2938
+ $joined_id = $table_info[ 'meta_field_id' ];
2939
+ $joined_index = $table_info[ 'meta_field_index' ];
2940
+ }
2941
+ elseif ( $meta_data_table ) {
2942
+ if ( $traverse[ 'id' ] !== $traverse[ 'pick_val' ] ) {
2943
+ // This must be a relationship
2944
+ $joined_id = 'related_item_id';
2945
+ } else {
2946
+ $joined_id = $traverse_recurse[ 'joined_id' ];
2947
+ }
2948
+
2949
+ $the_join = "
2950
+ LEFT JOIN `{$table_info['pod_table']}` AS `{$field_joined}` ON
2951
+ `{$field_joined}`.`{$table_info['pod_field_id']}` = `{$traverse_recurse['rel_alias']}`.`{$joined_id}`
2952
+ ";
2953
+ }
2954
+ else {
2955
+ if (
2956
+ ( $traverse_recurse[ 'depth' ] + 2 ) == count( $traverse_recurse[ 'fields' ] )
2957
+ && ( 'pick' != $traverse[ 'type' ] || !in_array( pods_var( 'pick_object', $traverse ), $simple_tableless_objects ) )
2958
+ && 'post_author' == $traverse_recurse[ 'fields' ][ $traverse_recurse[ 'depth' ] + 1 ] ) {
2959
+ $table_info[ 'recurse' ] = false;
2960
+ }
2961
+
2962
+ $the_join = "
2963
+ LEFT JOIN `@wp_podsrel` AS `{$rel_alias}` ON
2964
+ `{$rel_alias}`.`field_id` = {$traverse[ 'id' ]}
2965
+ AND `{$rel_alias}`.`item_id` = `{$traverse_recurse[ 'joined' ]}`.`{$traverse_recurse[ 'joined_id' ]}`
2966
+
2967
+ LEFT JOIN `{$table_info[ 'table' ]}` AS `{$field_joined}` ON
2968
+ `{$field_joined}`.`{$table_info[ 'field_id' ]}` = `{$rel_alias}`.`related_item_id`
2969
+ ";
2970
+ }
2971
+ }
2972
+ elseif ( 'meta' == $pod_data[ 'storage' ] ) {
2973
+ if (
2974
+ ( $traverse_recurse[ 'depth' ] + 2 ) == count( $traverse_recurse[ 'fields' ] )
2975
+ && ( 'pick' != $traverse[ 'type' ] || !in_array( pods_var( 'pick_object', $traverse ), $simple_tableless_objects ) )
2976
+ && $table_info[ 'meta_field_value' ] == $traverse_recurse[ 'fields' ][ $traverse_recurse[ 'depth' ] + 1 ] ) {
2977
+ $the_join = "
2978
+ LEFT JOIN `{$table_info[ 'meta_table' ]}` AS `{$field_joined}` ON
2979
+ `{$field_joined}`.`{$table_info[ 'meta_field_index' ]}` = '{$traverse[ 'name' ]}'
2980
+ AND `{$field_joined}`.`{$table_info[ 'meta_field_id' ]}` = `{$traverse_recurse[ 'joined' ]}`.`{$traverse_recurse[ 'joined_id' ]}`
2981
+ ";
2982
+
2983
+ $table_info[ 'recurse' ] = false;
2984
+ }
2985
+ else {
2986
+ $the_join = "
2987
+ LEFT JOIN `{$table_info[ 'meta_table' ]}` AS `{$field_joined}` ON
2988
+ `{$field_joined}`.`{$table_info[ 'meta_field_index' ]}` = '{$traverse[ 'name' ]}'
2989
+ AND `{$field_joined}`.`{$table_info[ 'meta_field_id' ]}` = `{$traverse_recurse[ 'joined' ]}`.`{$traverse_recurse[ 'joined_id' ]}`
2990
+ ";
2991
+
2992
+ $joined_id = $table_info[ 'meta_field_id' ];
2993
+ $joined_index = $table_info[ 'meta_field_index' ];
2994
+ }
2995
+ }
2996
+
2997
+ $traverse_recursive = array(
2998
+ 'pod' => pods_var_raw( 'name', pods_var_raw( 'pod', $table_info ) ),
2999
+ 'fields' => $traverse_recurse[ 'fields' ],
3000
+ 'joined' => $field_joined,
3001
+ 'depth' => ( $traverse_recurse[ 'depth' ] + 1 ),
3002
+ 'joined_id' => $joined_id,
3003
+ 'joined_index' => $joined_index,
3004
+ 'params' => $traverse_recurse[ 'params' ],
3005
+ 'rel_alias' => $rel_alias,
3006
+ 'last_table_info' => $table_info
3007
+ );
3008
+
3009
+ $the_join = apply_filters( 'pods_data_traverse_the_join', $the_join, $traverse_recurse, $traverse_recursive, $this );
3010
+
3011
+ if ( empty( $the_join ) )
3012
+ return $joins;
3013
+
3014
+ $joins[ $traverse_recurse[ 'pod' ] . '_' . $traverse_recurse[ 'depth' ] . '_' . $traverse[ 'id' ] ] = $the_join;
3015
+
3016
+ if ( ( $traverse_recurse[ 'depth' ] + 1 ) < count( $traverse_recurse[ 'fields' ] ) && !empty( $traverse_recurse[ 'pod' ] ) && false !== $table_info[ 'recurse' ] )
3017
+ $joins = array_merge( $joins, $this->traverse_recurse( $traverse_recursive ) );
3018
+
3019
+ return $joins;
3020
+ }
3021
+
3022
+ /**
3023
+ * Recursively join tables based on fields
3024
+ *
3025
+ * @param array $fields Fields to recurse
3026
+ * @param null $all_fields (optional) If $fields is empty then traverse all fields, argument does not need to be passed
3027
+ * @param object $params (optional) Parameters from build()
3028
+ *
3029
+ * @return array Array of joins
3030
+ */
3031
+ function traverse ( $fields = null, $all_fields = null, $params = null ) {
3032
+ $joins = array();
3033
+
3034
+ if ( null === $fields )
3035
+ $fields = $this->traverse_build( $all_fields, $params );
3036
+
3037
+ foreach ( (array) $fields as $field_group ) {
3038
+ $traverse_recurse = array(
3039
+ 'pod' => $this->pod,
3040
+ 'fields' => $fields,
3041
+ 'params' => $params,
3042
+ 'last_table_info' => $this->pod_data,
3043
+ 'joined_id' => $this->pod_data[ 'field_id' ],
3044
+ 'joined_index' => $this->pod_data[ 'field_index' ]
3045
+ );
3046
+
3047
+ if ( is_array( $field_group ) ) {
3048
+ $traverse_recurse[ 'fields' ] = $field_group;
3049
+
3050
+ $joins = array_merge( $joins, $this->traverse_recurse( $traverse_recurse ) );
3051
+ }
3052
+ else {
3053
+ $joins = array_merge( $joins, $this->traverse_recurse( $traverse_recurse ) );
3054
+ $joins = array_filter( $joins );
3055
+
3056
+ return $joins;
3057
+ }
3058
+ }
3059
+
3060
+ $joins = array_filter( $joins );
3061
+
3062
+ return $joins;
3063
+ }
3064
+
3065
+ /**
3066
+ * Handle filters / actions for the class
3067
+ *
3068
+ * @since 2.0
3069
+ */
3070
+ private static function do_hook () {
3071
+ $args = func_get_args();
3072
+
3073
+ if ( empty( $args ) )
3074
+ return false;
3075
+
3076
+ $name = array_shift( $args );
3077
+
3078
+ return pods_do_hook( 'data', $name, $args );
3079
+ }
3080
+
3081
+ /**
3082
+ * Get the complete sql
3083
+ *
3084
+ * @since 2.0.5
3085
+ */
3086
+ public function get_sql ( $sql ) {
3087
+ global $wpdb;
3088
+
3089
+ if ( empty( $sql ) )
3090
+ $sql = $this->sql;
3091
+
3092
+ $sql = str_replace( array( '@wp_users', '@wp_' ), array( $wpdb->users, $wpdb->prefix ), $sql );
3093
+
3094
+ $sql = str_replace( '{prefix}', '@wp_', $sql );
3095
+ $sql = str_replace( '{/prefix/}', '{prefix}', $sql );
3096
+
3097
+ return $sql;
3098
+ }
3099
+ }
classes/PodsField.php ADDED
@@ -0,0 +1,384 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Pods
4
+ */
5
+ class PodsField {
6
+
7
+ /**
8
+ * Whether this field is running under 1.x deprecated forms
9
+ *
10
+ * @var bool
11
+ * @since 2.0
12
+ */
13
+ public static $deprecated = false;
14
+
15
+ /**
16
+ * Field Type Identifier
17
+ *
18
+ * @var string
19
+ * @since 2.0
20
+ */
21
+ public static $type = 'text';
22
+
23
+ /**
24
+ * Field Type Label
25
+ *
26
+ * @var string
27
+ * @since 2.0
28
+ */
29
+ public static $label = 'Unknown';
30
+
31
+ /**
32
+ * Field Type Preparation
33
+ *
34
+ * @var string
35
+ * @since 2.0
36
+ */
37
+ public static $prepare = '%s';
38
+
39
+ /**
40
+ * Pod Types supported on (true for all, false for none, or give array of specific types supported)
41
+ *
42
+ * @var array|bool
43
+ * @since 2.1
44
+ */
45
+ public static $pod_types = true;
46
+
47
+ /**
48
+ * API caching for fields that need it during validate/save
49
+ *
50
+ * @var \PodsAPI
51
+ * @since 2.3
52
+ */
53
+ private static $api = false;
54
+
55
+ /**
56
+ * Do things like register/enqueue scripts and stylesheets
57
+ *
58
+ * @return \PodsField
59
+ *
60
+ * @since 2.0
61
+ */
62
+ public function __construct () {
63
+
64
+ }
65
+
66
+ /**
67
+ * Add options and set defaults for field type, shows in admin area
68
+ *
69
+ * @return array $options
70
+ *
71
+ * @since 2.0
72
+ * @see PodsField::ui_options
73
+ */
74
+ public function options () {
75
+ $options = array( /*
76
+ 'option_name' => array(
77
+ 'label' => 'Option Label',
78
+ 'depends-on' => array( 'another_option' => 'specific-value' ),
79
+ 'default' => 'default-value',
80
+ 'type' => 'field_type',
81
+ 'data' => array(
82
+ 'value1' => 'Label 1',
83
+
84
+ // Group your options together
85
+ 'Option Group' => array(
86
+ 'gvalue1' => 'Option Label 1',
87
+ 'gvalue2' => 'Option Label 2'
88
+ ),
89
+
90
+ // below is only if the option_name above is the "{$fieldtype}_format_type"
91
+ 'value2' => array(
92
+ 'label' => 'Label 2',
93
+ 'regex' => '[a-zA-Z]' // Uses JS regex validation for the value saved if this option selected
94
+ )
95
+ ),
96
+
97
+ // below is only for a boolean group
98
+ 'group' => array(
99
+ 'option_boolean1' => array(
100
+ 'label' => 'Option boolean 1?',
101
+ 'default' => 1,
102
+ 'type' => 'boolean'
103
+ ),
104
+ 'option_boolean2' => array(
105
+ 'label' => 'Option boolean 2?',
106
+ 'default' => 0,
107
+ 'type' => 'boolean'
108
+ )
109
+ )
110
+ ) */
111
+ );
112
+
113
+ return $options;
114
+ }
115
+
116
+ /**
117
+ * Options for the Admin area, defaults to $this->options()
118
+ *
119
+ * @return array $options
120
+ *
121
+ * @since 2.0
122
+ * @see PodsField::options
123
+ */
124
+ public function ui_options () {
125
+ return $this->options();
126
+ }
127
+
128
+ /**
129
+ * Define the current field's schema for DB table storage
130
+ *
131
+ * @param array $options
132
+ *
133
+ * @return string
134
+ * @since 2.0
135
+ */
136
+ public function schema ( $options = null ) {
137
+ $schema = 'VARCHAR(255)';
138
+
139
+ return $schema;
140
+ }
141
+
142
+ /**
143
+ * Define the current field's preparation for sprintf
144
+ *
145
+ * @param array $options
146
+ *
147
+ * @return array
148
+ * @since 2.0
149
+ */
150
+ public function prepare ( $options = null ) {
151
+ $format = self::$prepare;
152
+
153
+ return $format;
154
+ }
155
+
156
+ /**
157
+ * Change the value of the field
158
+ *
159
+ * @param mixed $value
160
+ * @param string $name
161
+ * @param array $options
162
+ * @param array $pod
163
+ * @param int $id
164
+ *
165
+ * @return mixed|null|string
166
+ * @since 2.3
167
+ */
168
+ public function value ( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
169
+ return $value;
170
+ }
171
+
172
+ /**
173
+ * Change the way the value of the field is displayed with Pods::get
174
+ *
175
+ * @param mixed $value
176
+ * @param string $name
177
+ * @param array $options
178
+ * @param array $pod
179
+ * @param int $id
180
+ *
181
+ * @return mixed|null|string
182
+ * @since 2.0
183
+ */
184
+ public function display ( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
185
+ return $value;
186
+ }
187
+
188
+ /**
189
+ * Customize output of the form field
190
+ *
191
+ * @param string $name
192
+ * @param mixed $value
193
+ * @param array $options
194
+ * @param array $pod
195
+ * @param int $id
196
+ *
197
+ * @return void
198
+ *
199
+ * @since 2.0
200
+ */
201
+ public function input ( $name, $value = null, $options = null, $pod = null, $id = null ) {
202
+ $options = (array) $options;
203
+ $form_field_type = PodsForm::$field_type;
204
+
205
+ if ( is_array( $value ) )
206
+ $value = implode( ' ', $value );
207
+
208
+ pods_view( PODS_DIR . 'ui/fields/text.php', compact( array_keys( get_defined_vars() ) ) );
209
+ }
210
+
211
+ /**
212
+ * Get the data from the field
213
+ *
214
+ * @param string $name The name of the field
215
+ * @param string|array $value The value of the field
216
+ * @param array $options
217
+ * @param array $pod
218
+ * @param int $id
219
+ * @param boolean $in_form
220
+ *
221
+ * @return array Array of possible field data
222
+ *
223
+ * @since 2.0
224
+ */
225
+ public function data ( $name, $value = null, $options = null, $pod = null, $id = null, $in_form = true ) {
226
+ return (array) $value;
227
+ }
228
+
229
+ /**
230
+ * Build regex necessary for JS validation
231
+ *
232
+ * @param mixed $value
233
+ * @param string $name
234
+ * @param array $options
235
+ * @param string $pod
236
+ * @param int $id
237
+ *
238
+ * @return bool
239
+ * @since 2.0
240
+ */
241
+ public function regex ( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
242
+ return false;
243
+ }
244
+
245
+ /**
246
+ * Validate a value before it's saved
247
+ *
248
+ * @param mixed $value
249
+ * @param string $name
250
+ * @param array $options
251
+ * @param array $fields
252
+ * @param array $pod
253
+ * @param int $id
254
+ * @param array $params
255
+ *
256
+ * @return bool
257
+ * @since 2.0
258
+ */
259
+ public function validate ( $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
260
+ return true;
261
+ }
262
+
263
+ /**
264
+ * Change the value or perform actions after validation but before saving to the DB
265
+ *
266
+ * @param mixed $value
267
+ * @param int $id
268
+ * @param string $name
269
+ * @param array $options
270
+ * @param array $fields
271
+ * @param array $pod
272
+ * @param object $params
273
+ *
274
+ * @return mixed
275
+ * @since 2.0
276
+ */
277
+ public function pre_save ( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
278
+ return $value;
279
+ }
280
+
281
+ /**
282
+ * Save the value to the DB
283
+ *
284
+ * @param mixed $value
285
+ * @param int $id
286
+ * @param string $name
287
+ * @param array $options
288
+ * @param array $fields
289
+ * @param array $pod
290
+ * @param object $params
291
+ *
292
+ * @return bool|void Whether the value was saved
293
+ *
294
+ * @since 2.3
295
+ */
296
+ public function save ( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
297
+ return null;
298
+ }
299
+
300
+ /**
301
+ * Perform actions after saving to the DB
302
+ *
303
+ * @param mixed $value
304
+ * @param int $id
305
+ * @param string $name
306
+ * @param array $options
307
+ * @param array $fields
308
+ * @param array $pod
309
+ * @param object $params
310
+ *
311
+ * @since void
312
+ *
313
+ * @since 2.0
314
+ */
315
+ public function post_save ( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
316
+
317
+ }
318
+
319
+ /**
320
+ * Perform actions before deleting from the DB
321
+ *
322
+ * @param int $id
323
+ * @param string $name
324
+ * @param null $options
325
+ * @param string $pod
326
+ *
327
+ * @since void
328
+ *
329
+ * @since 2.0
330
+ */
331
+ public function pre_delete ( $id = null, $name = null, $options = null, $pod = null ) {
332
+
333
+ }
334
+
335
+ /**
336
+ * Delete the value from the DB
337
+ *
338
+ * @param int $id
339
+ * @param string $name
340
+ * @param array $options
341
+ * @param array $pod
342
+ *
343
+ * @since void
344
+ *
345
+ * @since 2.3
346
+ */
347
+ public function delete ( $id = null, $name = null, $options = null, $pod = null ) {
348
+
349
+ }
350
+
351
+ /**
352
+ * Perform actions after deleting from the DB
353
+ *
354
+ * @param int $id
355
+ * @param string $name
356
+ * @param array $options
357
+ * @param array $pod
358
+ *
359
+ * @since void
360
+ *
361
+ * @since 2.0
362
+ */
363
+ public function post_delete ( $id = null, $name = null, $options = null, $pod = null ) {
364
+
365
+ }
366
+
367
+ /**
368
+ * Customize the Pods UI manage table column output
369
+ *
370
+ * @param int $id
371
+ * @param mixed $value
372
+ * @param string $name
373
+ * @param array $options
374
+ * @param array $fields
375
+ * @param array $pod
376
+ *
377
+ * @since string Value to be shown in the UI
378
+ *
379
+ * @since 2.0
380
+ */
381
+ public function ui ( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) {
382
+ return $value;
383
+ }
384
+ }
classes/PodsForm.php ADDED
@@ -0,0 +1,1540 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Pods
4
+ */
5
+ class PodsForm {
6
+
7
+ /**
8
+ * @var PodsForm
9
+ */
10
+ protected static $instance = null;
11
+
12
+ /**
13
+ * @var string
14
+ */
15
+ static $field = null;
16
+
17
+ /**
18
+ * @var string
19
+ */
20
+ static $field_group = null;
21
+
22
+ /**
23
+ * @var string
24
+ */
25
+ static $field_type = null;
26
+
27
+ /**
28
+ * @var array
29
+ */
30
+ static $field_types = array();
31
+
32
+ /**
33
+ * @var array
34
+ */
35
+ static $loaded = array();
36
+
37
+ /**
38
+ * @var int
39
+ */
40
+ static $form_counter = 0;
41
+
42
+ /**
43
+ * Singleton handling for a basic pods_form() request
44
+ *
45
+ * @return \PodsForm
46
+ *
47
+ * @since 2.3.5
48
+ */
49
+ public static function init () {
50
+ if ( !is_object( self::$instance ) )
51
+ self::$instance = new PodsForm();
52
+
53
+ return self::$instance;
54
+ }
55
+
56
+ /**
57
+ * Master handler for all field / form methods
58
+ *
59
+ * @return \PodsForm
60
+ *
61
+ * @license http://www.gnu.org/licenses/gpl-2.0.html
62
+ * @since 2.0
63
+ */
64
+ private function __construct() {
65
+ add_action( 'admin_init', array( $this, 'admin_init' ), 14 );
66
+ }
67
+
68
+ /**
69
+ * Prevent clones
70
+ *
71
+ * @since 2.3
72
+ */
73
+ private function __clone() {
74
+ // Hulk smash
75
+ }
76
+
77
+ /**
78
+ * Output a field's label
79
+ *
80
+ * @since 2.0
81
+ */
82
+
83
+ /**
84
+ * Output a field's label
85
+ *
86
+ * @param string $name Field name
87
+ * @param string $label Label text
88
+ * @param string $help Help text
89
+ * @param array $options Field options
90
+ *
91
+ * @return string Label HTML
92
+ *
93
+ * @since 2.0
94
+ */
95
+ public static function label( $name, $label, $help = '', $options = null ) {
96
+ if ( is_array( $label ) || is_object( $label ) ) {
97
+ $options = $label;
98
+ $label = $options[ 'label' ];
99
+
100
+ if ( empty( $label ) )
101
+ $label = ucwords( str_replace( '_', ' ', $name ) );
102
+
103
+ $help = $options[ 'help' ];
104
+ }
105
+ else
106
+ $options = self::options( null, $options );
107
+
108
+ $label = apply_filters( 'pods_form_ui_label_text', $label, $name, $help, $options );
109
+ $help = apply_filters( 'pods_form_ui_label_help', $help, $name, $label, $options );
110
+
111
+ ob_start();
112
+
113
+ $name_clean = self::clean( $name );
114
+ $name_more_clean = self::clean( $name, true );
115
+
116
+ $type = 'label';
117
+ $attributes = array();
118
+ $attributes[ 'class' ] = 'pods-form-ui-' . $type . ' pods-form-ui-' . $type . '-' . $name_more_clean;
119
+ $attributes[ 'for' ] = ( false === strpos( $name_clean, 'pods-form-ui-' ) ? 'pods-form-ui-' : '' ) . $name_clean;
120
+ $attributes = self::merge_attributes( $attributes, $name, $type, $options, false );
121
+
122
+ pods_view( PODS_DIR . 'ui/fields/_label.php', compact( array_keys( get_defined_vars() ) ) );
123
+
124
+ $output = ob_get_clean();
125
+
126
+ return apply_filters( 'pods_form_ui_' . $type, $output, $name, $label, $help, $attributes, $options );
127
+ }
128
+
129
+ /**
130
+ * Output a Field Comment Paragraph
131
+ *
132
+ * @param string $name Field name
133
+ * @param string $message Field comments
134
+ * @param array $options Field options
135
+ *
136
+ * @return string Comment HTML
137
+ *
138
+ * @since 2.0
139
+ */
140
+ public static function comment( $name, $message = null, $options = null ) {
141
+ $options = self::options( null, $options );
142
+
143
+ $name_more_clean = self::clean( $name, true );
144
+
145
+ if ( isset( $options[ 'description' ] ) && !empty( $options[ 'description' ] ) )
146
+ $message = $options[ 'description' ];
147
+ elseif ( empty( $message ) )
148
+ return '';
149
+
150
+ $message = apply_filters( 'pods_form_ui_comment_text', $message, $name, $options );
151
+
152
+ ob_start();
153
+
154
+ $type = 'comment';
155
+ $attributes = array();
156
+ $attributes[ 'class' ] = 'pods-form-ui-' . $type . ' pods-form-ui-' . $type . '-' . $name_more_clean;
157
+ $attributes = self::merge_attributes( $attributes, $name, $type, $options, false );
158
+
159
+ pods_view( PODS_DIR . 'ui/fields/_comment.php', compact( array_keys( get_defined_vars() ) ) );
160
+
161
+ $output = ob_get_clean();
162
+
163
+ return apply_filters( 'pods_form_ui_' . $type, $output, $name, $message, $attributes, $options );
164
+ }
165
+
166
+ /**
167
+ * Output a field
168
+ *
169
+ * @param string $name Field name
170
+ * @param mixed $value Field value
171
+ * @param string $type Field type
172
+ * @param array $options Field options
173
+ * @param array $pod Pod data
174
+ * @param int $id Item ID
175
+ *
176
+ * @return string Field HTML
177
+ *
178
+ * @since 2.0
179
+ */
180
+ public static function field( $name, $value, $type = 'text', $options = null, $pod = null, $id = null ) {
181
+ // Take a field array
182
+ if ( is_array( $name ) || is_object( $name ) ) {
183
+ $options = $name;
184
+
185
+ if ( is_object( $type ) ) {
186
+ $pod = $type;
187
+ $id = $options;
188
+ }
189
+
190
+ $name = pods_v( 'name', $options );
191
+ $type = pods_v( 'type', $options );
192
+ }
193
+
194
+ $options = self::options( $type, $options );
195
+ $options = apply_filters( 'pods_form_ui_field_' . $type . '_options', $options, $value, $name, $pod, $id );
196
+
197
+ if ( null === $value || ( '' === $value && 'boolean' === $type ) || ( !empty( $pod ) && empty( $id ) ) )
198
+ $value = self::default_value( $value, $type, $name, $options, $pod, $id );
199
+
200
+ // Fix double help qtip when using single checkboxes (boolean type)
201
+ if ( 'boolean' === $type )
202
+ $options['help'] = '';
203
+
204
+ if ( false === self::permission( $type, $name, $options, null, $pod, $id ) )
205
+ return false;
206
+
207
+ $value = apply_filters( 'pods_form_ui_field_' . $type . '_value', $value, $name, $options, $pod, $id );
208
+ $form_field_type = self::$field_type;
209
+
210
+ ob_start();
211
+
212
+ $helper = false;
213
+
214
+ if ( 0 < strlen( pods_v( 'input_helper', $options ) ) )
215
+ $helper = pods_api()->load_helper( array( 'name' => $options[ 'input_helper' ] ) );
216
+
217
+ if ( ( !isset( $options[ 'data' ] ) || empty( $options[ 'data' ] ) ) && is_object( self::$loaded[ $type ] ) && method_exists( self::$loaded[ $type ], 'data' ) )
218
+ $data = $options[ 'data' ] = self::$loaded[ $type ]->data( $name, $value, $options, $pod, $id, true );
219
+
220
+ if ( true === apply_filters( 'pods_form_ui_field_' . $type . '_override', false, $name, $value, $options, $pod, $id ) )
221
+ do_action( 'pods_form_ui_field_' . $type, $name, $value, $options, $pod, $id );
222
+ elseif ( !empty( $helper ) && 0 < strlen( pods_v( 'code', $helper ) ) && false === strpos( $helper[ 'code' ], '$this->' ) && ( !defined( 'PODS_DISABLE_EVAL' ) || !PODS_DISABLE_EVAL ) )
223
+ eval( '?>' . $helper[ 'code' ] );
224
+ elseif ( method_exists( get_class(), 'field_' . $type ) )
225
+ echo call_user_func( array( get_class(), 'field_' . $type ), $name, $value, $options );
226
+ elseif ( is_object( self::$loaded[ $type ] ) && method_exists( self::$loaded[ $type ], 'input' ) )
227
+ self::$loaded[ $type ]->input( $name, $value, $options, $pod, $id );
228
+ else
229
+ do_action( 'pods_form_ui_field_' . $type, $name, $value, $options, $pod, $id );
230
+
231
+ $output = ob_get_clean();
232
+
233
+ return apply_filters( 'pods_form_ui_field_' . $type, $output, $name, $value, $options, $pod, $id );
234
+ }
235
+
236
+ /**
237
+ * Output field type 'db'
238
+ *
239
+ * Used for field names and other places where only [a-z0-9_] is accepted
240
+ *
241
+ * @since 2.0
242
+ */
243
+ protected static function field_db( $name, $value = null, $options = null ) {
244
+ $form_field_type = self::$field_type;
245
+
246
+ ob_start();
247
+
248
+ pods_view( PODS_DIR . 'ui/fields/_db.php', compact( array_keys( get_defined_vars() ) ) );
249
+
250
+ $output = ob_get_clean();
251
+
252
+ return apply_filters( 'pods_form_ui_field_db', $output, $name, $value, $options );
253
+ }
254
+
255
+ /**
256
+ * Output a hidden field
257
+ */
258
+ protected static function field_hidden( $name, $value = null, $options = null ) {
259
+ $form_field_type = self::$field_type;
260
+
261
+ ob_start();
262
+
263
+ pods_view( PODS_DIR . 'ui/fields/_hidden.php', compact( array_keys( get_defined_vars() ) ) );
264
+
265
+ $output = ob_get_clean();
266
+
267
+ return apply_filters( 'pods_form_ui_field_hidden', $output, $name, $value, $options );
268
+ }
269
+
270
+ /**
271
+ * Returns a submit button, with provided text and appropriate class, copied from WP Core for use on the frontend
272
+ *
273
+ * @see get_submit_button
274
+ *
275
+ * @param string $text The text of the button (defaults to 'Save Changes')
276
+ * @param string $type The type of button. One of: primary, secondary, delete
277
+ * @param string $name The HTML name of the submit button. Defaults to "submit". If no id attribute
278
+ * is given in $other_attributes below, $name will be used as the button's id.
279
+ * @param bool $wrap True if the output button should be wrapped in a paragraph tag,
280
+ * false otherwise. Defaults to true
281
+ * @param array|string $other_attributes Other attributes that should be output with the button,
282
+ * mapping attributes to their values, such as array( 'tabindex' => '1' ).
283
+ * These attributes will be output as attribute="value", such as tabindex="1".
284
+ * Defaults to no other attributes. Other attributes can also be provided as a
285
+ * string such as 'tabindex="1"', though the array format is typically cleaner.
286
+ *
287
+ * @since 3.0
288
+ */
289
+ public static function submit_button( $text = null, $type = 'primary large', $name = 'submit', $wrap = true, $other_attributes = null ) {
290
+
291
+ if ( function_exists( 'get_submit_button' ) ) {
292
+ return get_submit_button( $text, $type, $name, $wrap, $other_attributes );
293
+ }
294
+
295
+ if ( !is_array( $type ) ) {
296
+ $type = explode( ' ', $type );
297
+ }
298
+
299
+ $button_shorthand = array(
300
+ 'primary',
301
+ 'small',
302
+ 'large'
303
+ );
304
+
305
+ $classes = array(
306
+ 'button'
307
+ );
308
+
309
+ foreach ( $type as $t ) {
310
+ if ( 'secondary' === $t || 'button-secondary' === $t ) {
311
+ continue;
312
+ }
313
+
314
+ $classes[] = in_array( $t, $button_shorthand ) ? 'button-' . $t : $t;
315
+ }
316
+
317
+ $class = implode( ' ', array_unique( $classes ) );
318
+
319
+ if ( 'delete' === $type ) {
320
+ $class = 'button-secondary delete';
321
+ }
322
+
323
+ $text = $text ? $text : __( 'Save Changes' );
324
+
325
+ // Default the id attribute to $name unless an id was specifically provided in $other_attributes
326
+ $id = $name;
327
+
328
+ if ( is_array( $other_attributes ) && isset( $other_attributes[ 'id' ] ) ) {
329
+ $id = $other_attributes[ 'id' ];
330
+ unset( $other_attributes[ 'id' ] );
331
+ }
332
+
333
+ $attributes = '';
334
+
335
+ if ( is_array( $other_attributes ) ) {
336
+ foreach ( $other_attributes as $attribute => $value ) {
337
+ $attributes .= $attribute . '="' . esc_attr( $value ) . '" '; // Trailing space is important
338
+ }
339
+ }
340
+ elseif ( !empty( $other_attributes ) ) { // Attributes provided as a string
341
+ $attributes = $other_attributes;
342
+ }
343
+
344
+ $button = '<input type="submit" name="' . esc_attr( $name ) . '" id="' . esc_attr( $id ) . '" class="' . esc_attr( $class );
345
+ $button .= '" value="' . esc_attr( $text ) . '" ' . $attributes . ' />';
346
+
347
+ if ( $wrap ) {
348
+ $button = '<p class="submit">' . $button . '</p>';
349
+ }
350
+
351
+ return $button;
352
+
353
+ }
354
+
355
+ /**
356
+ * Output a row (label, field, and comment)
357
+ *
358
+ * @param string $name Field name
359
+ * @param mixed $value Field value
360
+ * @param string $type Field type
361
+ * @param array $options Field options
362
+ * @param array $pod Pod data
363
+ * @param int $id Item ID
364
+ *
365
+ * @return string Row HTML
366
+ *
367
+ * @since 2.0
368
+ */
369
+ public static function row( $name, $value, $type = 'text', $options = null, $pod = null, $id = null ) {
370
+ $options = self::options( null, $options );
371
+
372
+ ob_start();
373
+
374
+ pods_view( PODS_DIR . 'ui/fields/_row.php', compact( array_keys( get_defined_vars() ) ) );
375
+
376
+ $output = ob_get_clean();
377
+
378
+ return apply_filters( 'pods_form_ui_field_row', $output, $name, $value, $options, $pod, $id );
379
+ }
380
+
381
+ /**
382
+ * Output a field's attributes
383
+ *
384
+ * @since 2.0
385
+ */
386
+ public static function attributes( $attributes, $name = null, $type = null, $options = null ) {
387
+ $attributes = (array) apply_filters( 'pods_form_ui_field_' . $type . '_attributes', $attributes, $name, $options );
388
+
389
+ foreach ( $attributes as $attribute => $value ) {
390
+ if ( null === $value )
391
+ continue;
392
+
393
+ echo ' ' . esc_attr( (string) $attribute ) . '="' . esc_attr( (string) $value ) . '"';
394
+ }
395
+ }
396
+
397
+ /**
398
+ * Output a field's data (for use with jQuery)
399
+ *
400
+ * @since 2.0
401
+ */
402
+ public static function data( $data, $name = null, $type = null, $options = null ) {
403
+ $data = (array) apply_filters( 'pods_form_ui_field_' . $type . '_data', $data, $name, $options );
404
+
405
+ foreach ( $data as $key => $value ) {
406
+ if ( null === $value )
407
+ continue;
408
+
409
+ $key = sanitize_title( $key );
410
+
411
+ if ( is_array( $value ) )
412
+ $value = implode( ',', $value );
413
+
414
+ echo ' data-' . esc_attr( (string) $key ) . '="' . esc_attr( (string) $value ) . '"';
415
+ }
416
+ }
417
+
418
+ /**
419
+ * Merge attributes and handle classes
420
+ *
421
+ * @since 2.0
422
+ */
423
+ public static function merge_attributes( $attributes, $name = null, $type = null, $options = null, $classes = '' ) {
424
+ $options = (array) $options;
425
+
426
+ if ( !in_array( $type, array( 'label', 'comment' ) ) ) {
427
+ $name_clean = self::clean( $name );
428
+ $name_more_clean = self::clean( $name, true );
429
+ $_attributes = array();
430
+ $_attributes[ 'name' ] = $name;
431
+ $_attributes[ 'data-name-clean' ] = $name_more_clean;
432
+
433
+ if ( 0 < strlen( pods_v( 'label', $options, '' ) ) )
434
+ $_attributes[ 'data-label' ] = strip_tags( pods_v( 'label', $options ) );
435
+
436
+ $_attributes['id'] = 'pods-form-ui-' . $name_clean . ( self::$form_counter > 1 ? '-' . self::$form_counter : '' );
437
+ $_attributes[ 'class' ] = 'pods-form-ui-field-type-' . $type . ' pods-form-ui-field-name-' . $name_more_clean;
438
+
439
+ if ( isset( $options[ 'dependency' ] ) && false !== $options[ 'dependency' ] )
440
+ $_attributes[ 'class' ] .= ' pods-dependent-toggle';
441
+
442
+ $attributes = array_merge( $_attributes, (array) $attributes );
443
+
444
+ if ( isset( $options[ 'attributes' ] ) && is_array( $options[ 'attributes' ] ) && !empty( $options[ 'attributes' ] ) )
445
+ $attributes = array_merge( $attributes, $options[ 'attributes' ] );
446
+ }
447
+ elseif ( isset( $options[ $type . '_attributes' ] ) && is_array( $options[ $type . '_attributes' ] ) && !empty( $options[ $type . '_attributes' ] ) )
448
+ $attributes = array_merge( $attributes, $options[ $type . '_attributes' ] );
449
+
450
+ if ( isset( $options[ 'class' ] ) && !empty( $options[ 'class' ] ) ) {
451
+ if ( is_array( $options[ 'class' ] ) )
452
+ $options[ 'class' ] = implode( ' ', $options[ 'class' ] );
453
+
454
+ $options[ 'class' ] = (string) $options[ 'class' ];
455
+ if ( isset( $attributes[ 'class' ] ) )
456
+ $attributes[ 'class' ] = $attributes[ 'class' ] . ' ' . $options[ 'class' ];
457
+ else
458
+ $attributes[ 'class' ] = $options[ 'class' ];
459
+
460
+ $attributes[ 'class' ] = trim( $attributes[ 'class' ] );
461
+ }
462
+
463
+ if ( !empty( $classes ) ) {
464
+ if ( isset( $attributes[ 'class' ] ) )
465
+ $attributes[ 'class' ] = $attributes[ 'class' ] . ' ' . $classes;
466
+ else
467
+ $attributes[ 'class' ] = $classes;
468
+ }
469
+
470
+ if ( isset( $options[ 'placeholder' ] ) && !empty( $options[ 'placeholder' ] ) ) {
471
+ if ( is_array( $options[ 'placeholder' ] ) )
472
+ $options[ 'placeholder' ] = implode( ' ', $options[ 'placeholder' ] );
473
+
474
+ $options[ 'placeholder' ] = (string) $options[ 'placeholder' ];
475
+ $attributes[ 'placeholder' ] = trim( $options[ 'placeholder' ] );
476
+ }
477
+
478
+ if ( 1 == pods_v( 'required', $options, 0 ) )
479
+ $attributes[ 'class' ] .= ' pods-validate pods-validate-required';
480
+
481
+ $max_length = (int) pods_var( 'maxlength', $options, pods_v( $type . '_max_length', $options, 0 ), null, true );
482
+
483
+ if ( 0 < $max_length )
484
+ $attributes[ 'maxlength' ] = $max_length;
485
+
486
+ $attributes = (array) apply_filters( 'pods_form_ui_field_' . $type . '_merge_attributes', $attributes, $name, $options );
487
+ return $attributes;
488
+ }
489
+
490
+ /**
491
+ * Setup options for a field and store them for later use
492
+ *
493
+ * @param $type
494
+ * @param $options
495
+ *
496
+ * @return array
497
+ *
498
+ * @static
499
+ *
500
+ * @since 2.0
501
+ */
502
+ public static function options( $type, $options ) {
503
+ $options = (array) $options;
504
+
505
+ if ( !is_object( $options ) && isset( $options[ 'options' ] ) ) {
506
+ $options_temp = $options[ 'options' ];
507
+
508
+ unset( $options[ 'options' ] );
509
+
510
+ $options = array_merge( $options_temp, $options );
511
+
512
+ $override = array(
513
+ 'class'
514
+ );
515
+
516
+ foreach ( $override as $check ) {
517
+ if ( isset( $options_temp[ $check ] ) )
518
+ $options[ $check ] = $options_temp[ $check ];
519
+ }
520
+ }
521
+
522
+ $defaults = self::options_setup( $type, $options );
523
+
524
+ $core_defaults = array(
525
+ 'id' => 0,
526
+ 'label' => '',
527
+ 'description' => '',
528
+ 'help' => '',
529
+ 'default' => null,
530
+ 'attributes' => array(),
531
+ 'class' => '',
532
+ 'grouped' => 0,
533
+ );
534
+
535
+ $defaults = array_merge( $core_defaults, $defaults );
536
+
537
+ foreach ( $defaults as $option => $settings ) {
538
+ $default = $settings;
539
+
540
+ if ( is_array( $settings ) && isset( $settings[ 'default' ] ) )
541
+ $default = $settings[ 'default' ];
542
+
543
+ if ( !isset( $options[ $option ] ) )
544
+ $options[ $option ] = $default;
545
+ }
546
+
547
+ return $options;
548
+ }
549
+
550
+ /**
551
+ * Get options for a field type and setup defaults
552
+ *
553
+ * @static
554
+ *
555
+ * @param $type
556
+ *
557
+ * @return array|null
558
+ *
559
+ * @since 2.0
560
+ */
561
+ public static function options_setup( $type = null, $options = null ) {
562
+ $core_defaults = array(
563
+ 'id' => 0,
564
+ 'name' => '',
565
+ 'label' => '',
566
+ 'description' => '',
567
+ 'help' => '',
568
+ 'default' => null,
569
+ 'attributes' => array(),
570
+ 'class' => '',
571
+ 'type' => 'text',
572
+ 'group' => 0,
573
+ 'grouped' => 0,
574
+ 'developer_mode' => false,
575
+ 'dependency' => false,
576
+ 'depends-on' => array(),
577
+ 'excludes-on' => array(),
578
+ 'options' => array()
579
+ );
580
+
581
+ if ( !empty( $options ) && is_array( $options ) )
582
+ $core_defaults = array_merge( $core_defaults, $options );
583
+
584
+ if ( null === $type )
585
+ return $core_defaults;
586
+ else
587
+ self::field_loader( $type );
588
+
589
+ $options = apply_filters( 'pods_field_' . $type . '_options', (array) self::$loaded[ $type ]->options(), $type );
590
+
591
+ $first_field = current( $options );
592
+
593
+ if ( !empty( $options ) && !isset( $first_field[ 'name' ] ) && !isset( $first_field[ 'label' ] ) ) {
594
+ $all_options = array();
595
+
596
+ foreach ( $options as $group => $group_options ) {
597
+ $all_options = array_merge( $all_options, self::fields_setup( $group_options, $core_defaults ) );
598
+ }
599
+
600
+ $options = $all_options;
601
+ }
602
+ else
603
+ $options = self::fields_setup( $options, $core_defaults );
604
+
605
+ return $options;
606
+ }
607
+
608
+ /**
609
+ * Get Admin options for a field type and setup defaults
610
+ *
611
+ * @static
612
+ *
613
+ * @param $type
614
+ *
615
+ * @return array|null
616
+ *
617
+ * @since 2.0
618
+ */
619
+ public static function ui_options( $type ) {
620
+ $core_defaults = array(
621
+ 'id' => 0,
622
+ 'name' => '',
623
+ 'label' => '',
624
+ 'description' => '',
625
+ 'help' => '',
626
+ 'default' => null,
627
+ 'attributes' => array(),
628
+ 'class' => '',
629
+ 'type' => 'text',
630
+ 'group' => 0,
631
+ 'grouped' => 0,
632
+ 'developer_mode' => false,
633
+ 'dependency' => false,
634
+ 'depends-on' => array(),
635
+ 'excludes-on' => array(),
636
+ 'options' => array()
637
+ );
638
+
639
+ self::field_loader( $type );
640
+
641
+ $options = apply_filters( 'pods_field_' . $type . '_ui_options', (array) self::$loaded[ $type ]->ui_options(), $type );
642
+
643
+ $first_field = current( $options );
644
+
645
+ if ( !empty( $options ) && !isset( $first_field[ 'name' ] ) && !isset( $first_field[ 'label' ] ) ) {
646
+ foreach ( $options as $group => $group_options ) {
647
+ $options[ $group ] = self::fields_setup( $group_options, $core_defaults );
648
+ }
649
+ }
650
+ else
651
+ $options = self::fields_setup( $options, $core_defaults );
652
+
653
+ return $options;
654
+ }
655
+
656
+ /**
657
+ * Get options for a field and setup defaults
658
+ *
659
+ *
660
+ * @param null $fields
661
+ * @param null $core_defaults
662
+ * @param bool $single
663
+ *
664
+ * @return array|null
665
+ *
666
+ * @static
667
+ * @since 2.0
668
+ */
669
+ public static function fields_setup( $fields = null, $core_defaults = null, $single = false ) {
670
+ if ( empty( $core_defaults ) ) {
671
+ $core_defaults = array(
672
+ 'id' => 0,
673
+ 'name' => '',
674
+ 'label' => '',
675
+ 'description' => '',
676
+ 'help' => '',
677
+ 'default' => null,
678
+ 'attributes' => array(),
679
+ 'class' => '',
680
+ 'type' => 'text',
681
+ 'group' => 0,
682
+ 'grouped' => 0,
683
+ 'developer_mode' => false,
684
+ 'dependency' => false,
685
+ 'depends-on' => array(),
686
+ 'excludes-on' => array(),
687
+ 'options' => array()
688
+ );
689
+ }
690
+
691
+ if ( $single )
692
+ $fields = array( $fields );
693
+
694
+ foreach ( $fields as $f => $field ) {
695
+ $fields[ $f ] = self::field_setup( $field, $core_defaults, pods_v( 'type', $field, 'text' ) );
696
+
697
+ if ( !$single && strlen( $fields[ $f ][ 'name' ] ) < 1 )
698
+ $fields[ $f ][ 'name' ] = $f;
699
+ }
700
+
701
+ if ( $single )
702
+ $fields = $fields[ 0 ];
703
+
704
+ return $fields;
705
+ }
706
+
707
+ /**
708
+ * Get options for a field and setup defaults
709
+ *
710
+ * @static
711
+ *
712
+ * @param null $field
713
+ * @param null $core_defaults
714
+ * @param null $type
715
+ *
716
+ * @return array|null
717
+ *
718
+ * @since 2.0
719
+ */
720
+ public static function field_setup( $field = null, $core_defaults = null, $type = null ) {
721
+ $options = array();
722
+
723
+ if ( empty( $core_defaults ) ) {
724
+ $core_defaults = array(
725
+ 'id' => 0,
726
+ 'name' => '',
727
+ 'label' => '',
728
+ 'description' => '',
729
+ 'help' => '',
730
+ 'default' => null,
731
+ 'attributes' => array(),
732
+ 'class' => '',
733
+ 'type' => 'text',
734
+ 'group' => 0,
735
+ 'grouped' => 0,
736
+ 'developer_mode' => false,
737
+ 'dependency' => false,
738
+ 'depends-on' => array(),
739
+ 'excludes-on' => array(),
740
+ 'options' => array()
741
+ );
742
+
743
+ if ( null !== $type ) {
744
+ self::field_loader( $type );
745
+
746
+ if ( method_exists( self::$loaded[ $type ], 'options' ) )
747
+ $options = apply_filters( 'pods_field_' . $type . '_options', (array) self::$loaded[ $type ]->options(), $type );
748
+ }
749
+ }
750
+
751
+ if ( !is_array( $field ) )
752
+ $field = array( 'default' => $field );
753
+
754
+ if ( isset( $field[ 'group' ] ) && is_array( $field[ 'group' ] ) ) {
755
+ foreach ( $field[ 'group' ] as $g => $group_option ) {
756
+ $field[ 'group' ][ $g ] = array_merge( $core_defaults, $group_option );
757
+
758
+ if ( strlen( $field[ 'group' ][ $g ][ 'name' ] ) < 1 )
759
+ $field[ 'group' ][ $g ][ 'name' ] = $g;
760
+ }
761
+ }
762
+
763
+ $field = array_merge( $core_defaults, $field );
764
+
765
+ foreach ( $options as $option => $settings ) {
766
+ $v = null;
767
+
768
+ if ( isset( $settings[ 'default' ] ) )
769
+ $v = $settings[ 'default' ];
770
+
771
+ if ( !isset( $field[ 'options' ][ $option ] ) )
772
+ $field[ 'options' ][ $option ] = $v;
773
+ }
774
+
775
+ return $field;
776
+ }
777
+
778
+ /**
779
+ * Setup dependency / exclusion classes
780
+ *
781
+ * @param array $options array( 'depends-on' => ..., 'excludes-on' => ...)
782
+ * @param string $prefix
783
+ *
784
+ * @return string
785
+ * @static
786
+ * @since 2.0
787
+ */
788
+ public static function dependencies( $options, $prefix = '' ) {
789
+ $options = (array) $options;
790
+
791
+ $depends_on = $excludes_on = array();
792
+ if ( isset( $options[ 'depends-on' ] ) )
793
+ $depends_on = (array) $options[ 'depends-on' ];
794
+
795
+ if ( isset( $options[ 'excludes-on' ] ) )
796
+ $excludes_on = (array) $options[ 'excludes-on' ];
797
+
798
+ $classes = array();
799
+
800
+ if ( !empty( $depends_on ) ) {
801
+ $classes[] = 'pods-depends-on';
802
+
803
+ foreach ( $depends_on as $depends => $on ) {
804
+ $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true );
805
+
806
+ if ( !is_bool( $on ) ) {
807
+ $on = (array) $on;
808
+
809
+ foreach ( $on as $o ) {
810
+ $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true ) . '-' . self::clean( $o, true );
811
+ }
812
+ }
813
+ }
814
+ }
815
+
816
+ if ( !empty( $excludes_on ) ) {
817
+ $classes[] = 'pods-excludes-on';
818
+ foreach ( $excludes_on as $excludes => $on ) {
819
+ $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true );
820
+
821
+ $on = (array) $on;
822
+
823
+ foreach ( $on as $o ) {
824
+ $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true ) . '-' . self::clean( $o, true );
825
+ }
826
+ }
827
+ }
828
+
829
+ $classes = implode( ' ', $classes );
830
+
831
+ return $classes;
832
+ }
833
+
834
+ /**
835
+ * Change the value of the field
836
+ *
837
+ * @param mixed $value
838
+ * @param string $name
839
+ * @param array $options
840
+ * @param array $fields
841
+ * @param array $pod
842
+ * @param int $id
843
+ * @param array $traverse
844
+ *
845
+ * @since 2.3
846
+ */
847
+ public static function value( $type, $value = null, $name = null, $options = null, $pod = null, $id = null, $traverse = null ) {
848
+ self::field_loader( $type );
849
+
850
+ if ( in_array( $type, self::repeatable_field_types() ) && 1 == pods_v( $type . '_repeatable', $options, 0 ) && !is_array( $value ) ) {
851
+ if ( 0 < strlen( $value ) ) {
852
+ $simple = @json_decode( $value, true );
853
+
854
+ if ( is_array( $simple ) )
855
+ $value = $simple;
856
+ else
857
+ $value = (array) $value;
858
+ }
859
+ else
860
+ $value = array();
861
+ }
862
+
863
+ if ( method_exists( self::$loaded[ $type ], 'value' ) ) {
864
+ if ( is_array( $value ) && in_array( $type, self::tableless_field_types() ) ) {
865
+ foreach ( $value as &$display_value ) {
866
+ $display_value = call_user_func_array( array( self::$loaded[ $type ], 'value' ), array( $display_value, $name, $options, $pod, $id, $traverse ) );
867
+ }
868
+ }
869
+ else
870
+ $value = call_user_func_array( array( self::$loaded[ $type ], 'value' ), array( $value, $name, $options, $pod, $id, $traverse ) );
871
+ }
872
+
873
+ return $value;
874
+ }
875
+
876
+ /**
877
+ * Change the way the value of the field is displayed with Pods::get
878
+ *
879
+ * @param mixed $value
880
+ * @param string $name
881
+ * @param array $options
882
+ * @param array $fields
883
+ * @param array $pod
884
+ * @param int $id
885
+ * @param array $traverse
886
+ *
887
+ * @since 2.0
888
+ */
889
+ public static function display( $type, $value = null, $name = null, $options = null, $pod = null, $id = null, $traverse = null ) {
890
+ self::field_loader( $type );
891
+
892
+ $tableless_field_types = self::tableless_field_types();
893
+
894
+ if ( method_exists( self::$loaded[ $type ], 'display' ) ) {
895
+ if ( is_array( $value ) && !in_array( $type, $tableless_field_types ) ) {
896
+ foreach ( $value as $k => $display_value ) {
897
+ $value[ $k ] = call_user_func_array( array( self::$loaded[ $type ], 'display' ), array( $display_value, $name, $options, $pod, $id, $traverse ) );
898
+ }
899
+ }
900
+ else
901
+ $value = call_user_func_array( array( self::$loaded[ $type ], 'display' ), array( $value, $name, $options, $pod, $id, $traverse ) );
902
+ }
903
+
904
+ $value = apply_filters( 'pods_form_display_' . $type, $value, $name, $options, $pod, $id, $traverse );
905
+
906
+ return $value;
907
+ }
908
+
909
+ /**
910
+ * Setup regex for JS / PHP
911
+ *
912
+ * @static
913
+ *
914
+ * @param $type
915
+ * @param $options
916
+ *
917
+ * @return mixed|void
918
+ * @since 2.0
919
+ */
920
+ public static function regex( $type, $options ) {
921
+ self::field_loader( $type );
922
+
923
+ $regex = false;
924
+
925
+ if ( method_exists( self::$loaded[ $type ], 'regex' ) )
926
+ $regex = self::$loaded[ $type ]->regex( $options );
927
+
928
+ $regex = apply_filters( 'pods_field_' . $type . '_regex', $regex, $options, $type );
929
+
930
+ return $regex;
931
+ }
932
+
933
+ /**
934
+ * Setup value preparation for sprintf
935
+ *
936
+ * @static
937
+ *
938
+ * @param $type
939
+ * @param $options
940
+ *
941
+ * @return mixed|void
942
+ * @since 2.0
943
+ */
944
+ public static function prepare( $type, $options ) {
945
+ self::field_loader( $type );
946
+
947
+ $prepare = '%s';
948
+
949
+ if ( method_exists( self::$loaded[ $type ], 'prepare' ) )
950
+ $prepare = self::$loaded[ $type ]->prepare( $options );
951
+
952
+ $prepare = apply_filters( 'pods_field_' . $type . '_prepare', $prepare, $options, $type );
953
+
954
+ return $prepare;
955
+ }
956
+
957
+ /**
958
+ * Validate a value before it's saved
959
+ *
960
+ * @param string $type
961
+ * @param mixed $value
962
+ * @param string $name
963
+ * @param array $options
964
+ * @param array $fields
965
+ * @param array $pod
966
+ * @param int $id
967
+ * @param array|object $params
968
+ *
969
+ * @static
970
+ *
971
+ * @since 2.0
972
+ */
973
+ public static function validate( $type, $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
974
+ self::field_loader( $type );
975
+
976
+ $validate = true;
977
+
978
+ if ( 1 == pods_v( 'pre_save', $options, 1 ) && method_exists( self::$loaded[ $type ], 'validate' ) )
979
+ $validate = self::$loaded[ $type ]->validate( $value, $name, $options, $fields, $pod, $id, $params );
980
+
981
+ $validate = apply_filters( 'pods_field_' . $type . '_validate', $validate, $value, $name, $options, $fields, $pod, $id, $type, $params );
982
+
983
+ return $validate;
984
+ }
985
+
986
+ /**
987
+ * Change the value or perform actions after validation but before saving to the DB
988
+ *
989
+ * @param string $type
990
+ * @param mixed $value
991
+ * @param int $id
992
+ * @param string $name
993
+ * @param array $options
994
+ * @param array $fields
995
+ * @param array $pod
996
+ * @param object $params
997
+ *
998
+ * @static
999
+ *
1000
+ * @since 2.0
1001
+ */
1002
+ public static function pre_save( $type, $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
1003
+ self::field_loader( $type );
1004
+
1005
+ if ( 1 == pods_v( 'field_pre_save', $options, 1 ) && method_exists( self::$loaded[ $type ], 'pre_save' ) )
1006
+ $value = self::$loaded[ $type ]->pre_save( $value, $id, $name, $options, $fields, $pod, $params );
1007
+
1008
+ return $value;
1009
+ }
1010
+
1011
+ /**
1012
+ * Save the value to the DB
1013
+ *
1014
+ * @param string $type
1015
+ * @param mixed $value
1016
+ * @param int $id
1017
+ * @param string $name
1018
+ * @param array $options
1019
+ * @param array $fields
1020
+ * @param array $pod
1021
+ * @param object $params
1022
+ *
1023
+ * @static
1024
+ *
1025
+ * @since 2.3
1026
+ */
1027
+ public static function save( $type, $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
1028
+ self::field_loader( $type );
1029
+
1030
+ $saved = null;
1031
+
1032
+ if ( 1 == pods_v( 'field_save', $options, 1 ) && method_exists( self::$loaded[ $type ], 'save' ) )
1033
+ $saved = self::$loaded[ $type ]->save( $value, $id, $name, $options, $fields, $pod, $params );
1034
+
1035
+ return $saved;
1036
+ }
1037
+
1038
+ /**
1039
+ * Delete the value from the DB
1040
+ *
1041
+ * @param string $type
1042
+ * @param int $id
1043
+ * @param string $name
1044
+ * @param array $options
1045
+ * @param array $pod
1046
+ *
1047
+ * @static
1048
+ *
1049
+ * @since 2.3
1050
+ */
1051
+ public static function delete( $type, $id = null, $name = null, $options = null, $pod = null ) {
1052
+ self::field_loader( $type );
1053
+
1054
+ $deleted = null;
1055
+
1056
+ if ( 1 == pods_v( 'field_delete', $options, 1 ) && method_exists( self::$loaded[ $type ], 'delete' ) )
1057
+ $deleted = self::$loaded[ $type ]->delete( $id, $name, $options, $pod );
1058
+
1059
+ return $deleted;
1060
+ }
1061
+
1062
+ /**
1063
+ * Check if a user has permission to be editing a field
1064
+ *
1065
+ * @param $type
1066
+ * @param null $name
1067
+ * @param null $options
1068
+ * @param null $fields
1069
+ * @param null $pod
1070
+ * @param null $id
1071
+ * @param null $params
1072
+ *
1073
+ * @static
1074
+ *
1075
+ * @since 2.0
1076
+ */
1077
+ public static function permission( $type, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
1078
+ $permission = pods_permission( $options );
1079
+
1080
+ $permission = (boolean) apply_filters( 'pods_form_field_permission', $permission, $type, $name, $options, $fields, $pod, $id, $params );
1081
+
1082
+ return $permission;
1083
+ }
1084
+
1085
+ /**
1086
+ * Parse the default the value
1087
+ *
1088
+ * @since 2.0
1089
+ */
1090
+ public static function default_value( $value, $type = 'text', $name = null, $options = null, $pod = null, $id = null ) {
1091
+ $default_value = pods_v( 'default_value', $options );
1092
+
1093
+ if ( '' === $default_value || null === $default_value ) {
1094
+ $default_value = $value;
1095
+ }
1096
+
1097
+ $default = pods_v( 'default', $options, $default_value, true );
1098
+
1099
+ if ( is_string( $default ) ) {
1100
+ $default_value = str_replace( array( '{@', '}' ), '', trim( $default ) );
1101
+ }
1102
+
1103
+ if ( $default != $default_value && 1 == (int) pods_v( 'default_evaluate_tags', $options, 1 ) )
1104
+ $default = pods_evaluate_tags( $default );
1105
+
1106
+ $default = pods_var_raw( pods_v( 'default_value_parameter', $options ), 'request', $default, null, true );
1107
+
1108
+ if ( $default != $value )
1109
+ $value = $default;
1110
+
1111
+ if ( is_array( $value ) )
1112
+ $value = pods_serial_comma( $value );
1113
+
1114
+ return apply_filters( 'pods_form_field_default_value', $value, $default, $type, $options, $pod, $id );
1115
+ }
1116
+
1117
+ /**
1118
+ * Clean a value for use in class / id
1119
+ *
1120
+ * @since 2.0
1121
+ */
1122
+ public static function clean( $input, $noarray = false, $db_field = false ) {
1123
+
1124
+ $output = trim( (string) $input );
1125
+
1126
+ $output = str_replace( '--1', 'podsfixtemp1', $output );
1127
+ $output = str_replace( '__1', 'podsfixtemp2', $output );
1128
+
1129
+ if ( false !== $noarray ) {
1130
+ $output = preg_replace( '/\[podsfixtemp\d+\]/', '-', $output );
1131
+ $output = preg_replace( '/\[\d*\]/', '-', $output );
1132
+ }
1133
+
1134
+ $output = str_replace( array( '[', ']' ), '-', $output );
1135
+
1136
+ $output = pods_clean_name( $output );
1137
+
1138
+ $output = preg_replace( '/([^a-z0-9\-_])/', '', $output );
1139
+ $output = preg_replace( '/(_){2,}/', '_', $output );
1140
+ $output = preg_replace( '/(-){2,}/', '-', $output );
1141
+
1142
+ if ( true !== $db_field ) {
1143
+ $output = str_replace( '_', '-', $output );
1144
+ }
1145
+
1146
+ $output = rtrim( $output, '-' );
1147
+
1148
+ $output = str_replace( 'podsfixtemp1', '--1', $output );
1149
+ $output = str_replace( 'podsfixtemp2', '__1', $output );
1150
+
1151
+ return $output;
1152
+ }
1153
+
1154
+ /**
1155
+ * Run admin_init methods for each field type
1156
+ *
1157
+ * @since 2.3
1158
+ */
1159
+ public function admin_init() {
1160
+ $admin_field_types = pods_transient_get( 'pods_form_admin_init_field_types' );
1161
+
1162
+ if ( empty( $admin_field_types ) ) {
1163
+ $admin_field_types = array();
1164
+
1165
+ $field_types = self::field_types();
1166
+
1167
+ foreach ( $field_types as $field_type => $field_type_data ) {
1168
+ $has_ajax = self::field_method( $field_type_data[ 'type' ], 'admin_init' );
1169
+
1170
+ if ( false !== $has_ajax )
1171
+ $admin_field_types[] = $field_type;
1172
+ }
1173
+
1174
+ pods_transient_set( 'pods_form_admin_init_field_types', $admin_field_types );
1175
+ }
1176
+ else {
1177
+ foreach ( $admin_field_types as $field_type ) {
1178
+ self::field_method( $field_type, 'admin_init' );
1179
+ }
1180
+ }
1181
+ }
1182
+
1183
+ /**
1184
+ * Autoload a Field Type's class
1185
+ *
1186
+ * @param string $field_type Field Type indentifier
1187
+ * @param string $file The Field Type class file location
1188
+ *
1189
+ * @return string
1190
+ * @access public
1191
+ * @static
1192
+ * @since 2.0
1193
+ */
1194
+ public static function field_loader( $field_type, $file = '' ) {
1195
+ if ( isset( self::$loaded[ $field_type ] ) ) {
1196
+ $class_vars = get_class_vars( get_class( self::$loaded[ $field_type ] ) ); // PHP 5.2.x workaround
1197
+
1198
+ self::$field_group = ( isset( $class_vars[ 'group' ] ) ? $class_vars[ 'group' ] : '' );
1199
+ self::$field_type = $class_vars[ 'type' ];
1200
+
1201
+ if ( 'Unknown' != $class_vars[ 'label' ] )
1202
+ return self::$loaded[ $field_type ];
1203
+ }
1204
+
1205
+ include_once PODS_DIR . 'classes/PodsField.php';
1206
+
1207
+ $field_type = self::clean( $field_type, true, true );
1208
+
1209
+ $class_name = ucfirst( $field_type );
1210
+ $class_name = "PodsField_{$class_name}";
1211
+
1212
+ $content_dir = realpath( WP_CONTENT_DIR );
1213
+ $plugins_dir = realpath( WP_PLUGIN_DIR );
1214
+ $muplugins_dir = realpath( WPMU_PLUGIN_DIR );
1215
+ $abspath_dir = realpath( ABSPATH );
1216
+ $pods_dir = realpath( PODS_DIR );
1217
+
1218
+ if ( !class_exists( $class_name ) ) {
1219
+ if ( isset( self::$field_types[ $field_type ] ) && !empty( self::$field_types[ $field_type ][ 'file' ] ) )
1220
+ $file = realpath( self::$field_types[ $field_type ][ 'file' ] );
1221
+
1222
+ if ( !empty( $file ) && 0 === strpos( $file, $abspath_dir ) && file_exists( $file ) )
1223
+ include_once $file;
1224
+ else {
1225
+ $file = str_replace( '../', '', apply_filters( 'pods_form_field_include', PODS_DIR . 'classes/fields/' . basename( $field_type ) . '.php', $field_type ) );
1226
+ $file = realpath( $file );
1227
+
1228
+ if ( file_exists( $file ) && ( 0 === strpos( $file, $pods_dir ) || 0 === strpos( $file, $content_dir ) || 0 === strpos( $file, $plugins_dir ) || 0 === strpos( $file, $muplugins_dir ) || 0 === strpos( $file, $abspath_dir ) ) )
1229
+ include_once $file;
1230
+ }
1231
+ }
1232
+
1233
+ if ( class_exists( $class_name ) )
1234
+ $class = new $class_name();
1235
+ else {
1236
+ $class = new PodsField();
1237
+ $class_name = 'PodsField';
1238
+ }
1239
+
1240
+ $class_vars = get_class_vars( $class_name ); // PHP 5.2.x workaround
1241
+
1242
+ self::$field_group = ( isset( $class_vars[ 'group' ] ) ? $class_vars[ 'group' ] : '' );
1243
+ self::$field_type = $class_vars[ 'type' ];
1244
+
1245
+ self::$loaded[ $field_type ] =& $class;
1246
+
1247
+ return self::$loaded[ $field_type ];
1248
+ }
1249
+
1250
+ /**
1251
+ * Run a method from a Field Type's class
1252
+ *
1253
+ * @param string $field_type Field Type indentifier
1254
+ * @param string $method Method name
1255
+ * @param mixed $arg More arguments
1256
+ *
1257
+ * @return mixed
1258
+ * @access public
1259
+ * @static
1260
+ * @since 2.0
1261
+ */
1262
+ public static function field_method() {
1263
+ $args = func_get_args();
1264
+
1265
+ if ( empty( $args ) && count( $args ) < 2 )
1266
+ return false;
1267
+
1268
+ $field_type = array_shift( $args );
1269
+ $method = array_shift( $args );
1270
+
1271
+ $class = self::field_loader( $field_type );
1272
+
1273
+ if ( method_exists( $class, $method ) )
1274
+ return call_user_func_array( array( $class, $method ), $args );
1275
+
1276
+ return false;
1277
+ }
1278
+
1279
+ /**
1280
+ * Add a new Pod field type
1281
+ *
1282
+ * @param string $type The new field type identifier
1283
+ * @param string $file The new field type class file location
1284
+ *
1285
+ * @return array Field Type data
1286
+ *
1287
+ * @since 2.3
1288
+ */
1289
+ public static function register_field_type( $type, $file = null ) {
1290
+ $field_type = pods_transient_get( 'pods_field_type_' . $type );
1291
+
1292
+ if ( empty( $field_type ) || $field_type[ 'type' ] != $type || $field_type[ 'file' ] != $file ) {
1293
+ self::field_loader( $type, $file );
1294
+
1295
+ $class_vars = get_class_vars( get_class( self::$loaded[ $type ] ) ); // PHP 5.2.x workaround
1296
+
1297
+ self::$field_types[ $type ] = $class_vars;
1298
+ self::$field_types[ $type ][ 'file' ] = $file;
1299
+
1300
+ pods_transient_set( 'pods_field_type_' . $type, self::$field_types[ $type ] );
1301
+ }
1302
+ else
1303
+ self::$field_types[ $type ] = $field_type;
1304
+
1305
+ return self::$field_types[ $type ];
1306
+ }
1307
+
1308
+ /**
1309
+ * Get a list of all available field types and include
1310
+ *
1311
+ * @return array Registered Field Types data
1312
+ *
1313
+ * @since 2.3
1314
+ */
1315
+ public static function field_types() {
1316
+ $field_types = array(
1317
+ 'text',
1318
+ 'website',
1319
+ 'phone',
1320
+ 'email',
1321
+ 'password',
1322
+ 'paragraph',
1323
+ 'wysiwyg',
1324
+ 'code',
1325
+ 'datetime',
1326
+ 'date',
1327
+ 'time',
1328
+ 'number',
1329
+ 'currency',
1330
+ 'file',
1331
+ 'avatar',
1332
+ 'pick',
1333
+ 'boolean',
1334
+ 'color',
1335
+ 'slug'
1336
+ );
1337
+
1338
+ $field_types = array_merge( $field_types, array_keys( self::$field_types ) );
1339
+
1340
+ $field_types = array_filter( array_unique( $field_types ) );
1341
+
1342
+ $types = apply_filters( 'pods_api_field_types', $field_types );
1343
+
1344
+ $field_types = pods_transient_get( 'pods_field_types' );
1345
+
1346
+ if ( empty( $field_types ) || count( $types ) != count( $field_types ) ) {
1347
+ $field_types = array();
1348
+
1349
+ foreach ( $types as $field_type ) {
1350
+ $file = null;
1351
+
1352
+ if ( isset( self::$field_types[ $field_type ] ) )
1353
+ $file = self::$field_types[ $field_type ][ 'file' ];
1354
+
1355
+ self::field_loader( $field_type, $file );
1356
+
1357
+ if ( !isset( self::$loaded[ $field_type ] ) || !is_object( self::$loaded[ $field_type ] ) )
1358
+ continue;
1359
+
1360
+ $class_vars = get_class_vars( get_class( self::$loaded[ $field_type ] ) ); // PHP 5.2.x workaround
1361
+
1362
+ $field_types[ $field_type ] = $class_vars;
1363
+ $field_types[ $field_type ][ 'file' ] = $file;
1364
+ }
1365
+
1366
+ self::$field_types = $field_types;
1367
+
1368
+ pods_transient_set( 'pods_field_types', self::$field_types );
1369
+ }
1370
+ else
1371
+ self::$field_types = array_merge( $field_types, self::$field_types );
1372
+
1373
+ return self::$field_types;
1374
+ }
1375
+
1376
+ /**
1377
+ * Get list of available tableless field types
1378
+ *
1379
+ * @return array Tableless field types
1380
+ *
1381
+ * @since 2.3
1382
+ */
1383
+ public static function tableless_field_types() {
1384
+ static $field_types = null;
1385
+
1386
+ if ( null === $field_types ) {
1387
+ $field_types = array( 'pick', 'file', 'avatar', 'taxonomy' );
1388
+
1389
+ $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1390
+ }
1391
+ return $field_types;
1392
+ }
1393
+
1394
+ /**
1395
+ * Get list of available file field types
1396
+ *
1397
+ * @return array File field types
1398
+ *
1399
+ * @since 2.3
1400
+ */
1401
+ public static function file_field_types() {
1402
+ static $field_types = null;
1403
+
1404
+ if ( null === $field_types ) {
1405
+ $field_types = array( 'file', 'avatar' );
1406
+
1407
+ $field_types = apply_filters( 'pods_file_field_types', $field_types );
1408
+ }
1409
+ return $field_types;
1410
+ }
1411
+
1412
+ /**
1413
+ * Get list of available repeatable field types
1414
+ *
1415
+ * @return array Repeatable field types
1416
+ *
1417
+ * @since 2.3
1418
+ */
1419
+ public static function repeatable_field_types() {
1420
+ static $field_types = null;
1421
+
1422
+ if ( null === $field_types ) {
1423
+ $field_types = array(
1424
+ 'code',
1425
+ 'color',
1426
+ 'currency',
1427
+ 'date',
1428
+ 'datetime',
1429
+ 'email',
1430
+ 'number',
1431
+ 'paragraph',
1432
+ 'phone',
1433
+ 'text',
1434
+ 'time',
1435
+ 'website',
1436
+ 'wysiwyg'
1437
+ );
1438
+
1439
+ $field_types = apply_filters( 'pods_repeatable_field_types', $field_types );
1440
+ }
1441
+ return $field_types;
1442
+ }
1443
+
1444
+ /**
1445
+ * Get list of available number field types
1446
+ *
1447
+ * @return array Number field types
1448
+ *
1449
+ * @since 2.3
1450
+ */
1451
+ public static function number_field_types() {
1452
+ static $field_types = null;
1453
+
1454
+ if ( null === $field_types ) {
1455
+ $field_types = array( 'currency', 'number' );
1456
+
1457
+ $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1458
+ }
1459
+ return $field_types;
1460
+ }
1461
+
1462
+ /**
1463
+ * Get list of available date field types
1464
+ *
1465
+ * @return array Date field types
1466
+ *
1467
+ * @since 2.3
1468
+ */
1469
+ public static function date_field_types() {
1470
+ static $field_types = null;
1471
+
1472
+ if ( null === $field_types ) {
1473
+ $field_types = array( 'date', 'datetime', 'time' );
1474
+
1475
+ $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1476
+ }
1477
+ return $field_types;
1478
+ }
1479
+
1480
+ /**
1481
+ * Get list of available text field types
1482
+ *
1483
+ * @return array Text field types
1484
+ *
1485
+ * @since 2.3
1486
+ */
1487
+ public static function text_field_types() {
1488
+ static $field_types = null;
1489
+
1490
+ if ( null === $field_types ) {
1491
+ $field_types = array( 'code', 'paragraph', 'slug', 'password', 'text', 'wysiwyg' );
1492
+
1493
+ $field_types = apply_filters( 'pods_text_field_types', $field_types );
1494
+ }
1495
+ return $field_types;
1496
+ }
1497
+
1498
+ /**
1499
+ * Get list of available text field types
1500
+ *
1501
+ * @return array Text field types
1502
+ *
1503
+ * @since 2.3
1504
+ */
1505
+ public static function block_field_types() {
1506
+ static $field_types = null;
1507
+
1508
+ if ( null === $field_types ) {
1509
+ $field_types = array( 'heading', 'html' );
1510
+
1511
+ /**
1512
+ * Returns the available text field types
1513
+ *
1514
+ * @since unknown
1515
+ *
1516
+ * @param object $field_types Outputs the field types
1517
+ */
1518
+
1519
+ $field_types = apply_filters( 'pods_block_field_types', $field_types );
1520
+ }
1521
+ return $field_types;
1522
+ }
1523
+
1524
+ /**
1525
+ * Get list of available text field types
1526
+ *
1527
+ * @return array Text field types
1528
+ *
1529
+ * @since 2.3
1530
+ */
1531
+ public static function simple_tableless_objects() {
1532
+ static $object_types = null;
1533
+
1534
+ if ( null === $object_types ) {
1535
+ $object_types = PodsForm::field_method( 'pick', 'simple_objects' );
1536
+ }
1537
+ return $object_types;
1538
+ }
1539
+
1540
+ }
classes/PodsInit.php ADDED
@@ -0,0 +1,1585 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Pods
4
+ */
5
+ class PodsInit {
6
+
7
+ /**
8
+ * @var PodsInit
9
+ */
10
+ static $instance = null;
11
+
12
+ /**
13
+ * @var array
14
+ */
15
+ static $no_conflict = array();
16
+
17
+ /**
18
+ * @var array
19
+ */
20
+ static $content_types_registered = array();
21
+
22
+ /**
23
+ * @var PodsComponents
24
+ */
25
+ static $components;
26
+
27
+ /**
28
+ * @var PodsMeta
29
+ */
30
+ static $meta;
31
+
32
+ /**
33
+ * @var PodsAdmin
34
+ */
35
+ static $admin;
36
+
37
+ /**
38
+ * @var mixed|void
39
+ */
40
+ static $version;
41
+
42
+ /**
43
+ * @var mixed|void
44
+ */
45
+ static $version_last;
46
+
47
+ /**
48
+ * @var mixed|void
49
+ */
50
+ static $db_version;
51
+
52
+ /**
53
+ * Upgrades to trigger (last installed version => upgrade version)
54
+ *
55
+ * @var array
56
+ */
57
+ static $upgrades = array(
58
+ '1.0.0' => '2.0.0'
59
+ //'2.0.0' => '2.1.0'
60
+ );
61
+
62
+ /**
63
+ * Whether an Upgrade for 1.x has happened
64
+ *
65
+ * @var bool
66
+ */
67
+ static $upgraded;
68
+
69
+ /**
70
+ * Whether an Upgrade is needed
71
+ *
72
+ * @var bool
73
+ */
74
+ static $upgrade_needed = false;
75
+
76
+ /**
77
+ * Singleton handling for a basic pods_init() request
78
+ *
79
+ * @return \PodsInit
80
+ *
81
+ * @since 2.3.5
82
+ */
83
+ public static function init() {
84
+
85
+ if ( ! is_object( self::$instance ) ) {
86
+ self::$instance = new PodsInit();
87
+ }
88
+
89
+ return self::$instance;
90
+ }
91
+
92
+ /**
93
+ * Setup and Initiate Pods
94
+ *
95
+ * @return \PodsInit
96
+ *
97
+ * @license http://www.gnu.org/licenses/gpl-2.0.html
98
+ * @since 1.8.9
99
+ */
100
+ function __construct() {
101
+
102
+ self::$version = get_option( 'pods_framework_version' );
103
+ self::$version_last = get_option( 'pods_framework_version_last' );
104
+ self::$db_version = get_option( 'pods_framework_db_version' );
105
+ self::$upgraded = (int) get_option( 'pods_framework_upgraded_1_x' );
106
+
107
+ if ( empty( self::$version_last ) && 0 < strlen( get_option( 'pods_version' ) ) ) {
108
+ $old_version = get_option( 'pods_version' );
109
+
110
+ if ( ! empty( $old_version ) ) {
111
+ if ( false === strpos( $old_version, '.' ) ) {
112
+ $old_version = pods_version_to_point( $old_version );
113
+ }
114
+
115
+ update_option( 'pods_framework_version_last', $old_version );
116
+
117
+ self::$version_last = $old_version;
118
+ }
119
+ }
120
+
121
+ self::$upgrade_needed = $this->needs_upgrade();
122
+
123
+ add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
124
+ add_action( 'plugins_loaded', array( $this, 'activate_install' ), 9 );
125
+
126
+ add_action( 'wp_loaded', array( $this, 'flush_rewrite_rules' ) );
127
+
128
+ $this->run();
129
+
130
+ }
131
+
132
+ /**
133
+ * Load the plugin textdomain and set default constants
134
+ */
135
+ public function plugins_loaded() {
136
+
137
+ if ( ! defined( 'PODS_LIGHT' ) ) {
138
+ define( 'PODS_LIGHT', false );
139
+ }
140
+
141
+ if ( ! defined( 'PODS_TABLELESS' ) ) {
142
+ define( 'PODS_TABLELESS', false );
143
+ }
144
+
145
+ load_plugin_textdomain( 'pods' );
146
+
147
+ }
148
+
149
+ /**
150
+ * Load Pods Components
151
+ */
152
+ public function load_components() {
153
+
154
+ if ( empty( self::$version ) ) {
155
+ return;
156
+ }
157
+
158
+ if ( ! defined( 'PODS_LIGHT' ) || ! PODS_LIGHT ) {
159
+ self::$components = pods_components();
160
+ }
161
+
162
+ }
163
+
164
+ /**
165
+ * Load Pods Meta
166
+ */
167
+ public function load_meta() {
168
+
169
+ self::$meta = pods_meta()->core();
170
+ }
171
+
172
+ /**
173
+ * Set up the Pods core
174
+ */
175
+ public function core() {
176
+
177
+ if ( empty( self::$version ) ) {
178
+ return;
179
+ }
180
+
181
+ // Session start
182
+ pods_session_start();
183
+
184
+ add_shortcode( 'pods', 'pods_shortcode' );
185
+ add_shortcode( 'pods-form', 'pods_shortcode_form' );
186
+
187
+ $security_settings = array(
188
+ 'pods_disable_file_browser' => 0,
189
+ 'pods_files_require_login' => 1,
190
+ 'pods_files_require_login_cap' => '',
191
+ 'pods_disable_file_upload' => 0,
192
+ 'pods_upload_require_login' => 1,
193
+ 'pods_upload_require_login_cap' => ''
194
+ );
195
+
196
+ foreach ( $security_settings as $security_setting => $setting ) {
197
+ $setting = get_option( $security_setting );
198
+ if ( ! empty( $setting ) ) {
199
+ $security_settings[ $security_setting ] = $setting;
200
+ }
201
+ }
202
+
203
+ foreach ( $security_settings as $security_setting => $setting ) {
204
+ if ( 0 == $setting ) {
205
+ $setting = false;
206
+ } elseif ( 1 == $setting ) {
207
+ $setting = true;
208
+ }
209
+
210
+ if ( in_array( $security_setting, array( 'pods_files_require_login', 'pods_upload_require_login' ) ) ) {
211
+ if ( 0 < strlen( $security_settings[ $security_setting . '_cap' ] ) ) {
212
+ $setting = $security_settings[ $security_setting . '_cap' ];
213
+ }
214
+ } elseif ( in_array( $security_setting, array(
215
+ 'pods_files_require_login_cap',
216
+ 'pods_upload_require_login_cap'
217
+ ) ) ) {
218
+ continue;
219
+ }
220
+
221
+ if ( ! defined( strtoupper( $security_setting ) ) ) {
222
+ define( strtoupper( $security_setting ), $setting );
223
+ }
224
+ }
225
+
226
+ $this->register_pods();
227
+
228
+ $avatar = PodsForm::field_loader( 'avatar' );
229
+
230
+ if ( method_exists( $avatar, 'get_avatar' ) ) {
231
+ add_filter( 'get_avatar', array( $avatar, 'get_avatar' ), 10, 4 );
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Register Scripts and Styles
237
+ */
238
+ public function register_assets() {
239
+
240
+ if ( ! wp_style_is( 'jquery-ui', 'registered' ) ) {
241
+ wp_register_style( 'jquery-ui', PODS_URL . 'ui/css/smoothness/jquery-ui.custom.css', array(), '1.8.16' );
242
+ }
243
+
244
+ wp_register_script( 'pods-json', PODS_URL . 'ui/js/jquery.json.js', array( 'jquery' ), '2.3' );
245
+
246
+ if ( ! wp_style_is( 'jquery-qtip2', 'registered' ) ) {
247
+ wp_register_style( 'jquery-qtip2', PODS_URL . 'ui/css/jquery.qtip.min.css', array(), '2.2' );
248
+ }
249
+
250
+ if ( ! wp_script_is( 'jquery-qtip2', 'registered' ) ) {
251
+ wp_register_script( 'jquery-qtip2', PODS_URL . 'ui/js/jquery.qtip.min.js', array( 'jquery' ), '2.2' );
252
+ }
253
+
254
+ wp_register_script( 'pods', PODS_URL . 'ui/js/jquery.pods.js', array(
255
+ 'jquery',
256
+ 'pods-json',
257
+ 'jquery-qtip2'
258
+ ), PODS_VERSION );
259
+
260
+ wp_register_style( 'pods-form', PODS_URL . 'ui/css/pods-form.css', array(), PODS_VERSION );
261
+
262
+ wp_register_style( 'pods-cleditor', PODS_URL . 'ui/css/jquery.cleditor.css', array(), '1.3.0' );
263
+ wp_register_script( 'pods-cleditor', PODS_URL . 'ui/js/jquery.cleditor.min.js', array( 'jquery' ), '1.3.0' );
264
+
265
+ wp_register_style( 'pods-codemirror', PODS_URL . 'ui/css/codemirror.css', array(), '4.8' );
266
+ wp_register_script( 'pods-codemirror', PODS_URL . 'ui/js/codemirror.js', array(), '4.8', true );
267
+ wp_register_script( 'pods-codemirror-loadmode', PODS_URL . 'ui/js/codemirror/addon/mode/loadmode.js', array( 'pods-codemirror' ), '4.8', true );
268
+ wp_register_script( 'pods-codemirror-overlay', PODS_URL . 'ui/js/codemirror/addon/mode/overlay.js', array( 'pods-codemirror' ), '4.8', true );
269
+ wp_register_script( 'pods-codemirror-hints', PODS_URL . 'ui/js/codemirror/addon/mode/show-hint.js', array( 'pods-codemirror' ), '4.8', true );
270
+ wp_register_script( 'pods-codemirror-mode-xml', PODS_URL . 'ui/js/codemirror/mode/xml/xml.js', array( 'pods-codemirror' ), '4.8', true );
271
+ wp_register_script( 'pods-codemirror-mode-html', PODS_URL . 'ui/js/codemirror/mode/htmlmixed/htmlmixed.js', array( 'pods-codemirror' ), '4.8', true );
272
+ wp_register_script( 'pods-codemirror-mode-css', PODS_URL . 'ui/js/codemirror/mode/css/css.js', array( 'pods-codemirror' ), '4.8', true );
273
+
274
+ if ( ! wp_style_is( 'jquery-ui-timepicker', 'registered' ) ) {
275
+ wp_register_style( 'jquery-ui-timepicker', PODS_URL . 'ui/css/jquery.ui.timepicker.css', array(), '1.1.1' );
276
+ }
277
+
278
+ if ( ! wp_script_is( 'jquery-ui-timepicker', 'registered' ) ) {
279
+ wp_register_script( 'jquery-ui-timepicker', PODS_URL . 'ui/js/jquery.ui.timepicker.min.js', array(
280
+ 'jquery',
281
+ 'jquery-ui-core',
282
+ 'jquery-ui-datepicker',
283
+ 'jquery-ui-slider'
284
+ ), '1.1.1' );
285
+ }
286
+
287
+ wp_register_style( 'pods-attach', PODS_URL . 'ui/css/jquery.pods.attach.css', array(), PODS_VERSION );
288
+ wp_register_script( 'pods-attach', PODS_URL . 'ui/js/jquery.pods.attach.js', array(), PODS_VERSION );
289
+
290
+ wp_register_style( 'pods-select2', PODS_URL . 'ui/js/select2/select2.css', array(), '3.3.1' );
291
+ wp_register_script( 'pods-select2', PODS_URL . 'ui/js/select2/select2.min.js', array( 'jquery' ), '3.3.1' );
292
+
293
+ $register_handlebars = apply_filters( 'pods_script_register_handlebars', true );
294
+
295
+ if ( is_admin() ) {
296
+ $screen = get_current_screen();
297
+
298
+ // Deregister the outdated Pods handlebars script on TEC event screen
299
+ if ( $screen && 'tribe_events' === $screen->post_type ) {
300
+ $register_handlebars = false;
301
+ }
302
+ }
303
+
304
+ if ( $register_handlebars ) {
305
+ wp_register_script( 'pods-handlebars', PODS_URL . 'ui/js/handlebars.js', array(), '1.0.0.beta.6' );
306
+ }
307
+
308
+ }
309
+
310
+ /**
311
+ * Register internal Post Types
312
+ */
313
+ public function register_pods() {
314
+
315
+ $args = array(
316
+ 'label' => 'Pods',
317
+ 'labels' => array( 'singular_name' => 'Pod' ),
318
+ 'public' => false,
319
+ 'can_export' => false,
320
+ 'query_var' => false,
321
+ 'rewrite' => false,
322
+ 'capability_type' => 'pods_pod',
323
+ 'has_archive' => false,
324
+ 'hierarchical' => false,
325
+ 'supports' => array( 'title', 'author' ),
326
+ 'menu_icon' => 'dashicons-pods'
327
+ );
328
+
329
+ $args = self::object_label_fix( $args, 'post_type' );
330
+
331
+ register_post_type( '_pods_pod', apply_filters( 'pods_internal_register_post_type_pod', $args ) );
332
+
333
+ $args = array(
334
+ 'label' => 'Pod Fields',
335
+ 'labels' => array( 'singular_name' => 'Pod Field' ),
336
+ 'public' => false,
337
+ 'can_export' => false,
338
+ 'query_var' => false,
339
+ 'rewrite' => false,
340
+ 'capability_type' => 'pods_pod',
341
+ 'has_archive' => false,
342
+ 'hierarchical' => true,
343
+ 'supports' => array( 'title', 'editor', 'author' ),
344
+ 'menu_icon' => 'dashicons-pods'
345
+ );
346
+
347
+ $args = self::object_label_fix( $args, 'post_type' );
348
+
349
+ register_post_type( '_pods_field', apply_filters( 'pods_internal_register_post_type_field', $args ) );
350
+ }
351
+
352
+ /**
353
+ * Include Admin
354
+ */
355
+ public function admin_init() {
356
+
357
+ self::$admin = pods_admin();
358
+ }
359
+
360
+ /**
361
+ * Register Post Types and Taxonomies
362
+ */
363
+ public function setup_content_types( $force = false ) {
364
+
365
+ if ( empty( self::$version ) ) {
366
+ return;
367
+ }
368
+
369
+ $post_types = PodsMeta::$post_types;
370
+ $taxonomies = PodsMeta::$taxonomies;
371
+
372
+ $existing_post_types = get_post_types();
373
+ $existing_taxonomies = get_taxonomies();
374
+
375
+ $pods_cpt_ct = pods_transient_get( 'pods_wp_cpt_ct' );
376
+
377
+ $cpt_positions = array();
378
+
379
+ if ( empty( $pods_cpt_ct ) && ( ! empty( $post_types ) || ! empty( $taxonomies ) ) ) {
380
+ $force = true;
381
+ } elseif ( ! empty( $pods_cpt_ct ) && empty( $pods_cpt_ct['post_types'] ) && ! empty( $post_types ) ) {
382
+ $force = true;
383
+ } elseif ( ! empty( $pods_cpt_ct ) && empty( $pods_cpt_ct['taxonomies'] ) && ! empty( $taxonomies ) ) {
384
+ $force = true;
385
+ }
386
+
387
+ if ( false === $pods_cpt_ct || $force ) {
388
+ /**
389
+ * @var WP_Query
390
+ */
391
+ global $wp_query;
392
+
393
+ $reserved_query_vars = array(
394
+ 'post_type',
395
+ 'taxonomy',
396
+ 'output'
397
+ );
398
+
399
+ if ( is_object( $wp_query ) ) {
400
+ $reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) );
401
+ }
402
+
403
+ $pods_cpt_ct = array(
404
+ 'post_types' => array(),
405
+ 'taxonomies' => array()
406
+ );
407
+
408
+ $pods_post_types = $pods_taxonomies = array();
409
+ $supported_post_types = $supported_taxonomies = array();
410
+
411
+ $post_format_post_types = array();
412
+
413
+ foreach ( $post_types as $post_type ) {
414
+ // Post Type exists already
415
+ if ( isset( $pods_cpt_ct['post_types'][ $post_type['name'] ] ) ) {
416
+ continue;
417
+ } elseif ( ! empty( $post_type['object'] ) && isset( $existing_post_types[ $post_type['object'] ] ) ) {
418
+ continue;
419
+ } elseif ( ! $force && isset( $existing_post_types[ $post_type['name'] ] ) ) {
420
+ continue;
421
+ }
422
+
423
+ $post_type['options']['name'] = $post_type['name'];
424
+ $post_type = array_merge( $post_type, (array) $post_type['options'] );
425
+
426
+ $post_type_name = pods_var( 'name', $post_type );
427
+
428
+ // Labels
429
+ $cpt_label = esc_html( pods_var_raw( 'label', $post_type, ucwords( str_replace( '_', ' ', pods_var_raw( 'name', $post_type ) ) ), null, true ) );
430
+ $cpt_singular = esc_html( pods_var_raw( 'label_singular', $post_type, ucwords( str_replace( '_', ' ', pods_var_raw( 'label', $post_type, $post_type_name, null, true ) ) ), null, true ) );
431
+
432
+ $cpt_labels = array();
433
+ $cpt_labels['name'] = $cpt_label;
434
+ $cpt_labels['singular_name'] = $cpt_singular;
435
+ $cpt_labels['menu_name'] = pods_var_raw( 'menu_name', $post_type, '', null, true );
436
+ $cpt_labels['add_new'] = pods_var_raw( 'label_add_new', $post_type, '', null, true );
437
+ $cpt_labels['add_new_item'] = pods_var_raw( 'label_add_new_item', $post_type, '', null, true );
438
+ $cpt_labels['new_item'] = pods_var_raw( 'label_new_item', $post_type, '', null, true );
439
+ $cpt_labels['edit'] = pods_var_raw( 'label_edit', $post_type, '', null, true );
440
+ $cpt_labels['edit_item'] = pods_var_raw( 'label_edit_item', $post_type, '', null, true );
441
+ $cpt_labels['view'] = pods_var_raw( 'label_view', $post_type, '', null, true );
442
+ $cpt_labels['view_item'] = pods_var_raw( 'label_view_item', $post_type, '', null, true );
443
+ $cpt_labels['all_items'] = pods_var_raw( 'label_all_items', $post_type, '', null, true );
444
+ $cpt_labels['search_items'] = pods_var_raw( 'label_search_items', $post_type, '', null, true );
445
+ $cpt_labels['not_found'] = pods_var_raw( 'label_not_found', $post_type, '', null, true );
446
+ $cpt_labels['not_found_in_trash'] = pods_var_raw( 'label_not_found_in_trash', $post_type, '', null, true );
447
+ $cpt_labels['parent'] = pods_var_raw( 'label_parent', $post_type, '', null, true );
448
+ $cpt_labels['parent_item_colon'] = pods_var_raw( 'label_parent_item_colon', $post_type, '', null, true );
449
+
450
+ // Supported
451
+ $cpt_supported = array(
452
+ 'title' => (boolean) pods_var( 'supports_title', $post_type, false ),
453
+ 'editor' => (boolean) pods_var( 'supports_editor', $post_type, false ),
454
+ 'author' => (boolean) pods_var( 'supports_author', $post_type, false ),
455
+ 'thumbnail' => (boolean) pods_var( 'supports_thumbnail', $post_type, false ),
456
+ 'excerpt' => (boolean) pods_var( 'supports_excerpt', $post_type, false ),
457
+ 'trackbacks' => (boolean) pods_var( 'supports_trackbacks', $post_type, false ),
458
+ 'custom-fields' => (boolean) pods_var( 'supports_custom_fields', $post_type, false ),
459
+ 'comments' => (boolean) pods_var( 'supports_comments', $post_type, false ),
460
+ 'revisions' => (boolean) pods_var( 'supports_revisions', $post_type, false ),
461
+ 'page-attributes' => (boolean) pods_var( 'supports_page_attributes', $post_type, false ),
462
+ 'post-formats' => (boolean) pods_var( 'supports_post_formats', $post_type, false )
463
+ );
464
+
465
+ // Custom Supported
466
+ $cpt_supported_custom = pods_var( 'supports_custom', $post_type, '' );
467
+
468
+ if ( ! empty( $cpt_supported_custom ) ) {
469
+ $cpt_supported_custom = explode( ',', $cpt_supported_custom );
470
+ $cpt_supported_custom = array_filter( array_unique( $cpt_supported_custom ) );
471
+
472
+ foreach ( $cpt_supported_custom as $cpt_support ) {
473
+ $cpt_supported[ $cpt_support ] = true;
474
+ }
475
+ }
476
+
477
+ // Genesis Support
478
+ if ( function_exists( 'genesis' ) ) {
479
+ $cpt_supported['genesis-seo'] = (boolean) pods_var( 'supports_genesis_seo', $post_type, false );
480
+ $cpt_supported['genesis-layouts'] = (boolean) pods_var( 'supports_genesis_layouts', $post_type, false );
481
+ $cpt_supported['genesis-simple-sidebars'] = (boolean) pods_var( 'supports_genesis_simple_sidebars', $post_type, false );
482
+ }
483
+
484
+ // YARPP Support
485
+ if ( defined( 'YARPP_VERSION' ) ) {
486
+ $cpt_supported['yarpp_support'] = (boolean) pods_var( 'supports_yarpp_support', $post_type, false );
487
+ }
488
+
489
+ // Jetpack Support
490
+ if ( class_exists( 'Jetpack' ) ) {
491
+ $cpt_supported['supports_jetpack_publicize'] = (boolean) pods_var( 'supports_jetpack_publicize', $post_type, false );
492
+ $cpt_supported['supports_jetpack_markdown'] = (boolean) pods_var( 'supports_jetpack_markdown', $post_type, false );
493
+ }
494
+
495
+ // WP needs something, if this was empty and none were enabled, it would show title+editor pre 3.5 :(
496
+ $cpt_supports = array();
497
+
498
+ if ( ! pods_version_check( 'wp', '3.5' ) ) {
499
+ $cpt_supports = array( '_bug_fix_pre_35' );
500
+ }
501
+
502
+ foreach ( $cpt_supported as $cpt_support => $supported ) {
503
+ if ( true === $supported ) {
504
+ $cpt_supports[] = $cpt_support;
505
+
506
+ if ( 'post-formats' === $cpt_support ) {
507
+ $post_format_post_types[] = $post_type_name;
508
+ }
509
+ }
510
+ }
511
+
512
+ if ( empty( $cpt_supports ) && pods_version_check( 'wp', '3.5' ) ) {
513
+ $cpt_supports = false;
514
+ }
515
+
516
+ // Rewrite
517
+ $cpt_rewrite = (boolean) pods_var( 'rewrite', $post_type, true );
518
+ $cpt_rewrite_array = array(
519
+ 'slug' => pods_var( 'rewrite_custom_slug', $post_type, str_replace( '_', '-', $post_type_name ), null, true ),
520
+ 'with_front' => (boolean) pods_var( 'rewrite_with_front', $post_type, true ),
521
+ 'feeds' => (boolean) pods_var( 'rewrite_feeds', $post_type, (boolean) pods_var( 'has_archive', $post_type, false ) ),
522
+ 'pages' => (boolean) pods_var( 'rewrite_pages', $post_type, true )
523
+ );
524
+
525
+ if ( false !== $cpt_rewrite ) {
526
+ $cpt_rewrite = $cpt_rewrite_array;
527
+ }
528
+
529
+ $capability_type = pods_var( 'capability_type', $post_type, 'post' );
530
+
531
+ if ( 'custom' == $capability_type ) {
532
+ $capability_type = pods_var( 'capability_type_custom', $post_type, 'post' );
533
+ }
534
+
535
+ $show_in_menu = (boolean) pods_var( 'show_in_menu', $post_type, true );
536
+
537
+ if ( $show_in_menu && 0 < strlen( pods_var_raw( 'menu_location_custom', $post_type ) ) ) {
538
+ $show_in_menu = pods_var_raw( 'menu_location_custom', $post_type );
539
+ }
540
+
541
+ $menu_icon = pods_var( 'menu_icon', $post_type, null, null, true );
542
+
543
+ if ( ! empty( $menu_icon ) ) {
544
+ $menu_icon = pods_evaluate_tags( $menu_icon );
545
+ }
546
+
547
+ // Register Post Type
548
+ $pods_post_types[ $post_type_name ] = array(
549
+ 'label' => $cpt_label,
550
+ 'labels' => $cpt_labels,
551
+ 'description' => esc_html( pods_var_raw( 'description', $post_type ) ),
552
+ 'public' => (boolean) pods_var( 'public', $post_type, true ),
553
+ 'publicly_queryable' => (boolean) pods_var( 'publicly_queryable', $post_type, (boolean) pods_var( 'public', $post_type, true ) ),
554
+ 'exclude_from_search' => (boolean) pods_var( 'exclude_from_search', $post_type, ( (boolean) pods_var( 'public', $post_type, true ) ? false : true ) ),
555
+ 'show_ui' => (boolean) pods_var( 'show_ui', $post_type, (boolean) pods_var( 'public', $post_type, true ) ),
556
+ 'show_in_menu' => $show_in_menu,
557
+ 'show_in_nav_menus' => (boolean) pods_var( 'show_in_nav_menus', $post_type, (boolean) pods_var( 'public', $post_type, true ) ),
558
+ 'show_in_admin_bar' => (boolean) pods_var( 'show_in_admin_bar', $post_type, (boolean) pods_var( 'show_in_menu', $post_type, true ) ),
559
+ 'menu_position' => (int) pods_var( 'menu_position', $post_type, 0, null, true ),
560
+ 'menu_icon' => $menu_icon,
561
+ 'capability_type' => $capability_type,
562
+ //'capabilities' => $cpt_capabilities,
563
+ 'map_meta_cap' => (boolean) pods_var( 'capability_type_extra', $post_type, true ),
564
+ 'hierarchical' => (boolean) pods_var( 'hierarchical', $post_type, false ),
565
+ 'supports' => $cpt_supports,
566
+ //'register_meta_box_cb' => array($this, 'manage_meta_box'),
567
+ //'permalink_epmask' => EP_PERMALINK,
568
+ 'has_archive' => pods_v( 'has_archive_slug', $post_type, (boolean) pods_v( 'has_archive', $post_type, false ), true ),
569
+ 'rewrite' => $cpt_rewrite,
570
+ 'query_var' => ( false !== (boolean) pods_var( 'query_var', $post_type, true ) ? pods_var( 'query_var_string', $post_type, $post_type_name, null, true ) : false ),
571
+ 'can_export' => (boolean) pods_var( 'can_export', $post_type, true )
572
+ );
573
+
574
+ // YARPP doesn't use 'supports' array option (yet)
575
+ if ( ! empty( $cpt_supports['yarpp_support'] ) ) {
576
+ $pods_post_types[ $post_type_name ]['yarpp_support'] = true;
577
+ }
578
+
579
+ // Prevent reserved query_var issues
580
+ if ( in_array( $pods_post_types[ $post_type_name ]['query_var'], $reserved_query_vars ) ) {
581
+ $pods_post_types[ $post_type_name ]['query_var'] = 'post_type_' . $pods_post_types[ $post_type_name ]['query_var'];
582
+ }
583
+
584
+ if ( 25 == $pods_post_types[ $post_type_name ]['menu_position'] ) {
585
+ $pods_post_types[ $post_type_name ]['menu_position'] ++;
586
+ }
587
+
588
+ if ( $pods_post_types[ $post_type_name ]['menu_position'] < 1 || in_array( $pods_post_types[ $post_type_name ]['menu_position'], $cpt_positions ) ) {
589
+ unset( $pods_post_types[ $post_type_name ]['menu_position'] );
590
+ } else {
591
+ $cpt_positions[] = $pods_post_types[ $post_type_name ]['menu_position'];
592
+
593
+ // This would be nice if WP supported floats in menu_position
594
+ // $pods_post_types[ $post_type_name ][ 'menu_position' ] = $pods_post_types[ $post_type_name ][ 'menu_position' ] . '.1';
595
+ }
596
+
597
+ // Taxonomies
598
+ $cpt_taxonomies = array();
599
+ $_taxonomies = get_taxonomies();
600
+ $_taxonomies = array_merge_recursive( $_taxonomies, $pods_taxonomies );
601
+ $ignore = array( 'nav_menu', 'link_category', 'post_format' );
602
+
603
+ foreach ( $_taxonomies as $taxonomy => $label ) {
604
+ if ( in_array( $taxonomy, $ignore ) ) {
605
+ continue;
606
+ }
607
+
608
+ if ( false !== (boolean) pods_var( 'built_in_taxonomies_' . $taxonomy, $post_type, false ) ) {
609
+ $cpt_taxonomies[] = $taxonomy;
610
+
611
+ if ( isset( $supported_post_types[ $taxonomy ] ) && ! in_array( $post_type_name, $supported_post_types[ $taxonomy ] ) ) {
612
+ $supported_post_types[ $taxonomy ][] = $post_type_name;
613
+ }
614
+ }
615
+ }
616
+
617
+ if ( isset( $supported_taxonomies[ $post_type_name ] ) ) {
618
+ $supported_taxonomies[ $post_type_name ] = array_merge( (array) $supported_taxonomies[ $post_type_name ], $cpt_taxonomies );
619
+ } else {
620
+ $supported_taxonomies[ $post_type_name ] = $cpt_taxonomies;
621
+ }
622
+ }
623
+
624
+ foreach ( $taxonomies as $taxonomy ) {
625
+ // Taxonomy Type exists already
626
+ if ( isset( $pods_cpt_ct['taxonomies'][ $taxonomy['name'] ] ) ) {
627
+ continue;
628
+ } elseif ( ! empty( $taxonomy['object'] ) && isset( $existing_taxonomies[ $taxonomy['object'] ] ) ) {
629
+ continue;
630
+ } elseif ( ! $force && isset( $existing_taxonomies[ $taxonomy['name'] ] ) ) {
631
+ continue;
632
+ }
633
+
634
+ $taxonomy['options']['name'] = $taxonomy['name'];
635
+ $taxonomy = array_merge( $taxonomy, (array) $taxonomy['options'] );
636
+
637
+ $taxonomy_name = pods_var( 'name', $taxonomy );
638
+
639
+ // Labels
640
+ $ct_label = esc_html( pods_var_raw( 'label', $taxonomy, ucwords( str_replace( '_', ' ', pods_var_raw( 'name', $taxonomy ) ) ), null, true ) );
641
+ $ct_singular = esc_html( pods_var_raw( 'label_singular', $taxonomy, ucwords( str_replace( '_', ' ', pods_var_raw( 'label', $taxonomy, pods_var_raw( 'name', $taxonomy ), null, true ) ) ), null, true ) );
642
+
643
+ $ct_labels = array();
644
+ $ct_labels['name'] = $ct_label;
645
+ $ct_labels['singular_name'] = $ct_singular;
646
+ $ct_labels['menu_name'] = pods_var_raw( 'menu_name', $taxonomy, '', null, true );
647
+ $ct_labels['search_items'] = pods_var_raw( 'label_search_items', $taxonomy, '', null, true );
648
+ $ct_labels['popular_items'] = pods_var_raw( 'label_popular_items', $taxonomy, '', null, true );
649
+ $ct_labels['all_items'] = pods_var_raw( 'label_all_items', $taxonomy, '', null, true );
650
+ $ct_labels['parent_item'] = pods_var_raw( 'label_parent_item', $taxonomy, '', null, true );
651
+ $ct_labels['parent_item_colon'] = pods_var_raw( 'label_parent_item_colon', $taxonomy, '', null, true );
652
+ $ct_labels['edit_item'] = pods_var_raw( 'label_edit_item', $taxonomy, '', null, true );
653
+ $ct_labels['update_item'] = pods_var_raw( 'label_update_item', $taxonomy, '', null, true );
654
+ $ct_labels['add_new_item'] = pods_var_raw( 'label_add_new_item', $taxonomy, '', null, true );
655
+ $ct_labels['new_item_name'] = pods_var_raw( 'label_new_item_name', $taxonomy, '', null, true );
656
+ $ct_labels['separate_items_with_commas'] = pods_var_raw( 'label_separate_items_with_commas', $taxonomy, '', null, true );
657
+ $ct_labels['add_or_remove_items'] = pods_var_raw( 'label_add_or_remove_items', $taxonomy, '', null, true );
658
+ $ct_labels['choose_from_most_used'] = pods_var_raw( 'label_choose_from_the_most_used', $taxonomy, '', null, true );
659
+
660
+ // Rewrite
661
+ $ct_rewrite = (boolean) pods_var( 'rewrite', $taxonomy, true );
662
+ $ct_rewrite_array = array(
663
+ 'slug' => pods_var( 'rewrite_custom_slug', $taxonomy, str_replace( '_', '-', $taxonomy_name ), null, true ),
664
+ 'with_front' => (boolean) pods_var( 'rewrite_with_front', $taxonomy, true ),
665
+ 'hierarchical' => (boolean) pods_var( 'rewrite_hierarchical', $taxonomy, (boolean) pods_var( 'hierarchical', $taxonomy, false ) )
666
+ );
667
+
668
+ if ( false !== $ct_rewrite ) {
669
+ $ct_rewrite = $ct_rewrite_array;
670
+ }
671
+
672
+ /**
673
+ * Default tax capabilities
674
+ * @see https://codex.wordpress.org/Function_Reference/register_taxonomy
675
+ */
676
+ $capability_type = pods_var( 'capability_type', $taxonomy, 'default' );
677
+ $tax_capabilities = array();
678
+
679
+ if ( 'custom' == $capability_type ) {
680
+ $capability_type = pods_var( 'capability_type_custom', $taxonomy, 'default' );
681
+ if ( ! empty( $capability_type ) && 'default' != $capability_type ) {
682
+ $capability_type .= '_term';
683
+ $capability_type_plural = $capability_type . 's';
684
+ $tax_capabilities = array(
685
+ // Singular
686
+ 'edit_term' => 'edit_' . $capability_type,
687
+ 'delete_term' => 'delete_' . $capability_type,
688
+ 'assign_term' => 'assign_' . $capability_type,
689
+ // Plural
690
+ 'manage_terms' => 'manage_' . $capability_type_plural,
691
+ 'edit_terms' => 'edit_' . $capability_type_plural,
692
+ 'delete_terms' => 'delete_' . $capability_type_plural,
693
+ 'assign_terms' => 'assign_' . $capability_type_plural,
694
+ );
695
+ }
696
+ }
697
+
698
+ // Register Taxonomy
699
+ $pods_taxonomies[ $taxonomy_name ] = array(
700
+ 'label' => $ct_label,
701
+ 'labels' => $ct_labels,
702
+ 'public' => (boolean) pods_var( 'public', $taxonomy, true ),
703
+ 'show_in_nav_menus' => (boolean) pods_var( 'show_in_nav_menus', $taxonomy, (boolean) pods_var( 'public', $taxonomy, true ) ),
704
+ 'show_ui' => (boolean) pods_var( 'show_ui', $taxonomy, (boolean) pods_var( 'public', $taxonomy, true ) ),
705
+ 'show_in_menu' => (boolean) pods_var( 'show_in_menu', $taxonomy, (boolean) pods_var( 'public', $taxonomy, true ) ),
706
+ 'show_tagcloud' => (boolean) pods_var( 'show_tagcloud', $taxonomy, (boolean) pods_var( 'show_ui', $taxonomy, (boolean) pods_var( 'public', $taxonomy, true ) ) ),
707
+ 'hierarchical' => (boolean) pods_var( 'hierarchical', $taxonomy, false ),
708
+ //'capability_type' => $capability_type,
709
+ 'capabilities' => $tax_capabilities,
710
+ //'map_meta_cap' => (boolean) pods_var( 'capability_type_extra', $taxonomy, true ),
711
+ 'update_count_callback' => pods_var( 'update_count_callback', $taxonomy, null, null, true ),
712
+ 'query_var' => ( false !== (boolean) pods_var( 'query_var', $taxonomy, true ) ? pods_var( 'query_var_string', $taxonomy, $taxonomy_name, null, true ) : false ),
713
+ 'rewrite' => $ct_rewrite,
714
+ 'show_admin_column' => (boolean) pods_var( 'show_admin_column', $taxonomy, false ),
715
+ 'sort' => (boolean) pods_var( 'sort', $taxonomy, false )
716
+ );
717
+
718
+ if ( is_array( $ct_rewrite ) && ! $pods_taxonomies[ $taxonomy_name ]['query_var'] ) {
719
+ $pods_taxonomies[ $taxonomy_name ]['query_var'] = pods_var( 'query_var_string', $taxonomy, $taxonomy_name, null, true );
720
+ };
721
+
722
+ // Prevent reserved query_var issues
723
+ if ( in_array( $pods_taxonomies[ $taxonomy_name ]['query_var'], $reserved_query_vars ) ) {
724
+ $pods_taxonomies[ $taxonomy_name ]['query_var'] = 'taxonomy_' . $pods_taxonomies[ $taxonomy_name ]['query_var'];
725
+ }
726
+
727
+ // Integration for Single Value Taxonomy UI
728
+ if ( function_exists( 'tax_single_value_meta_box' ) ) {
729
+ $pods_taxonomies[ $taxonomy_name ]['single_value'] = (boolean) pods_var( 'single_value', $taxonomy, false );
730
+ $pods_taxonomies[ $taxonomy_name ]['required'] = (boolean) pods_var( 'single_value_required', $taxonomy, false );
731
+ }
732
+
733
+ // Post Types
734
+ $ct_post_types = array();
735
+ $_post_types = get_post_types();
736
+ $_post_types = array_merge_recursive( $_post_types, $pods_post_types );
737
+ $ignore = array( 'revision' );
738
+
739
+ foreach ( $_post_types as $post_type => $options ) {
740
+ if ( in_array( $post_type, $ignore ) ) {
741
+ continue;
742
+ }
743
+
744
+ if ( false !== (boolean) pods_var( 'built_in_post_types_' . $post_type, $taxonomy, false ) ) {
745
+ $ct_post_types[] = $post_type;
746
+
747
+ if ( isset( $supported_taxonomies[ $post_type ] ) && ! in_array( $taxonomy_name, $supported_taxonomies[ $post_type ] ) ) {
748
+ $supported_taxonomies[ $post_type ][] = $taxonomy_name;
749
+ }
750
+ }
751
+ }
752
+
753
+ if ( isset( $supported_post_types[ $taxonomy_name ] ) ) {
754
+ $supported_post_types[ $taxonomy_name ] = array_merge( $supported_post_types[ $taxonomy_name ], $ct_post_types );
755
+ } else {
756
+ $supported_post_types[ $taxonomy_name ] = $ct_post_types;
757
+ }
758
+ }
759
+
760
+ $pods_post_types = apply_filters( 'pods_wp_post_types', $pods_post_types );
761
+ $pods_taxonomies = apply_filters( 'pods_wp_taxonomies', $pods_taxonomies );
762
+
763
+ $supported_post_types = apply_filters( 'pods_wp_supported_post_types', $supported_post_types );
764
+ $supported_taxonomies = apply_filters( 'pods_wp_supported_taxonomies', $supported_taxonomies );
765
+
766
+ foreach ( $pods_taxonomies as $taxonomy => $options ) {
767
+ $ct_post_types = null;
768
+
769
+ if ( isset( $supported_post_types[ $taxonomy ] ) && ! empty( $supported_post_types[ $taxonomy ] ) ) {
770
+ $ct_post_types = $supported_post_types[ $taxonomy ];
771
+ }
772
+
773
+ $pods_cpt_ct['taxonomies'][ $taxonomy ] = array(
774
+ 'post_types' => $ct_post_types,
775
+ 'options' => $options
776
+ );
777
+ }
778
+
779
+ foreach ( $pods_post_types as $post_type => $options ) {
780
+ if ( isset( $supported_taxonomies[ $post_type ] ) && ! empty( $supported_taxonomies[ $post_type ] ) ) {
781
+ $options['taxonomies'] = $supported_taxonomies[ $post_type ];
782
+ }
783
+
784
+ $pods_cpt_ct['post_types'][ $post_type ] = $options;
785
+ }
786
+
787
+ $pods_cpt_ct['post_format_post_types'] = $post_format_post_types;
788
+
789
+ pods_transient_set( 'pods_wp_cpt_ct', $pods_cpt_ct );
790
+ }
791
+
792
+ foreach ( $pods_cpt_ct['taxonomies'] as $taxonomy => $options ) {
793
+ if ( isset( self::$content_types_registered['taxonomies'] ) && in_array( $taxonomy, self::$content_types_registered['taxonomies'] ) ) {
794
+ continue;
795
+ }
796
+
797
+ $ct_post_types = $options['post_types'];
798
+ $options = $options['options'];
799
+
800
+ $options = apply_filters( 'pods_register_taxonomy_' . $taxonomy, $options, $taxonomy );
801
+ $options = apply_filters( 'pods_register_taxonomy', $options, $taxonomy );
802
+
803
+ $options = self::object_label_fix( $options, 'taxonomy' );
804
+
805
+ // Max length for taxonomies are 32 characters
806
+ $taxonomy = substr( $taxonomy, 0, 32 );
807
+
808
+ // i18n compatibility for plugins that override it
809
+ if ( is_array( $options['rewrite'] ) && isset( $options['rewrite']['slug'] ) && ! empty( $options['rewrite']['slug'] ) ) {
810
+ $options['rewrite']['slug'] = _x( $options['rewrite']['slug'], 'URL taxonomy slug', 'pods' );
811
+ }
812
+
813
+ if ( 1 == pods_var( 'pods_debug_register', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) {
814
+ pods_debug( array( $taxonomy, $ct_post_types, $options ) );
815
+ }
816
+
817
+ register_taxonomy( $taxonomy, $ct_post_types, $options );
818
+
819
+ if ( ! isset( self::$content_types_registered['taxonomies'] ) ) {
820
+ self::$content_types_registered['taxonomies'] = array();
821
+ }
822
+
823
+ self::$content_types_registered['taxonomies'][] = $taxonomy;
824
+ }
825
+
826
+ foreach ( $pods_cpt_ct['post_types'] as $post_type => $options ) {
827
+ if ( isset( self::$content_types_registered['post_types'] ) && in_array( $post_type, self::$content_types_registered['post_types'] ) ) {
828
+ continue;
829
+ }
830
+
831
+ $options = apply_filters( 'pods_register_post_type_' . $post_type, $options, $post_type );
832
+ $options = apply_filters( 'pods_register_post_type', $options, $post_type );
833
+
834
+ $options = self::object_label_fix( $options, 'post_type' );
835
+
836
+ // Max length for post types are 20 characters
837
+ $post_type = substr( $post_type, 0, 20 );
838
+
839
+ // i18n compatibility for plugins that override it
840
+ if ( is_array( $options['rewrite'] ) && isset( $options['rewrite']['slug'] ) && ! empty( $options['rewrite']['slug'] ) ) {
841
+ $options['rewrite']['slug'] = _x( $options['rewrite']['slug'], 'URL slug', 'pods' );
842
+ }
843
+
844
+ if ( 1 == pods_var( 'pods_debug_register', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) {
845
+ pods_debug( array( $post_type, $options ) );
846
+ }
847
+
848
+ register_post_type( $post_type, $options );
849
+
850
+ // Register post format taxonomy for this post type
851
+ if ( isset( $pods_cpt_ct['post_format_post_types'] ) && in_array( $post_type, $pods_cpt_ct['post_format_post_types'], true ) ) {
852
+ register_taxonomy_for_object_type( 'post_format', $post_type );
853
+ }
854
+
855
+ if ( ! isset( self::$content_types_registered['post_types'] ) ) {
856
+ self::$content_types_registered['post_types'] = array();
857
+ }
858
+
859
+ self::$content_types_registered['post_types'][] = $post_type;
860
+ }
861
+
862
+ }
863
+
864
+ /**
865
+ * Check if we need to flush WordPress rewrite rules
866
+ * This gets run during 'init' action late in the game to give other plugins time to register their rewrite rules
867
+ */
868
+ public function flush_rewrite_rules() {
869
+
870
+ $flush = (int) pods_transient_get( 'pods_flush_rewrites' );
871
+
872
+ if ( 1 === $flush ) {
873
+ /**
874
+ * @var $wp_rewrite WP_Rewrite
875
+ */
876
+ global $wp_rewrite;
877
+ $wp_rewrite->flush_rules();
878
+ $wp_rewrite->init();
879
+
880
+ pods_transient_set( 'pods_flush_rewrites', 0 );
881
+ }
882
+ }
883
+
884
+ /**
885
+ * Update Post Type messages
886
+ *
887
+ * @param array $messages
888
+ *
889
+ * @return array
890
+ * @since 2.0.2
891
+ */
892
+ public function setup_updated_messages( $messages ) {
893
+
894
+ global $post, $post_ID;
895
+
896
+ $post_types = PodsMeta::$post_types;
897
+ $existing_post_types = get_post_types();
898
+
899
+ $pods_cpt_ct = pods_transient_get( 'pods_wp_cpt_ct' );
900
+
901
+ if ( empty( $pods_cpt_ct ) || empty( $post_types ) ) {
902
+ return $messages;
903
+ }
904
+
905
+ /**
906
+ * Use get_preview_post_link function added in 4.4, which eventually applies preview_post_link filter
907
+ * Before 4.4, this filter is defined in wp-admin/includes/meta-boxes.php, $post parameter added in 4.0
908
+ * there wasn't post parameter back in 3.8
909
+ * Let's add $post in the filter as it won't hurt anyway.
910
+ * @since 2.6.8.1
911
+ */
912
+ $preview_post_link = function_exists( 'get_preview_post_link' )
913
+ ? get_preview_post_link( $post )
914
+ : apply_filters( 'preview_post_link', add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ), $post );
915
+
916
+ foreach ( $post_types as $post_type ) {
917
+ if ( ! isset( $pods_cpt_ct['post_types'][ $post_type['name'] ] ) ) {
918
+ continue;
919
+ }
920
+
921
+ $labels = self::object_label_fix( $pods_cpt_ct['post_types'][ $post_type['name'] ], 'post_type' );
922
+ $labels = $labels['labels'];
923
+
924
+ $messages[ $post_type['name'] ] = array(
925
+ 1 => sprintf( __( '%s updated. <a href="%s">%s</a>', 'pods' ), $labels['singular_name'], esc_url( get_permalink( $post_ID ) ), $labels['view_item'] ),
926
+ 2 => __( 'Custom field updated.', 'pods' ),
927
+ 3 => __( 'Custom field deleted.', 'pods' ),
928
+ 4 => sprintf( __( '%s updated.', 'pods' ), $labels['singular_name'] ),
929
+ /* translators: %s: date and time of the revision */
930
+ 5 => isset( $_GET['revision'] ) ? sprintf( __( '%s restored to revision from %s', 'pods' ), $labels['singular_name'], wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
931
+ 6 => sprintf( __( '%s published. <a href="%s">%s</a>', 'pods' ), $labels['singular_name'], esc_url( get_permalink( $post_ID ) ), $labels['view_item'] ),
932
+ 7 => sprintf( __( '%s saved.', 'pods' ), $labels['singular_name'] ),
933
+ 8 => sprintf( __( '%s submitted. <a target="_blank" href="%s">Preview %s</a>', 'pods' ), $labels['singular_name'], esc_url( $preview_post_link ), $labels['singular_name'] ),
934
+ 9 => sprintf( __( '%s scheduled for: <strong>%s</strong>. <a target="_blank" href="%s">Preview %s</a>', 'pods' ), $labels['singular_name'], // translators: Publish box date format, see http://php.net/date
935
+ date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ), $labels['singular_name'] ),
936
+ 10 => sprintf( __( '%s draft updated. <a target="_blank" href="%s">Preview %s</a>', 'pods' ), $labels['singular_name'], esc_url( $preview_post_link ), $labels['singular_name'] )
937
+ );
938
+
939
+ if ( false === (boolean) $pods_cpt_ct['post_types'][ $post_type['name'] ]['public'] ) {
940
+ $messages[ $post_type['name'] ][1] = sprintf( __( '%s updated.', 'pods' ), $labels['singular_name'] );
941
+ $messages[ $post_type['name'] ][6] = sprintf( __( '%s published.', 'pods' ), $labels['singular_name'] );
942
+ $messages[ $post_type['name'] ][8] = sprintf( __( '%s submitted.', 'pods' ), $labels['singular_name'] );
943
+ $messages[ $post_type['name'] ][9] = sprintf( __( '%s scheduled for: <strong>%1$s</strong>.', 'pods' ), $labels['singular_name'], // translators: Publish box date format, see http://php.net/date
944
+ date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ) );
945
+ $messages[ $post_type['name'] ][10] = sprintf( __( '%s draft updated.', 'pods' ), $labels['singular_name'] );
946
+ }
947
+ }
948
+
949
+ return $messages;
950
+ }
951
+
952
+ /**
953
+ * @param $args
954
+ * @param string $type
955
+ *
956
+ * @return array
957
+ */
958
+ public static function object_label_fix( $args, $type = 'post_type' ) {
959
+
960
+ if ( empty( $args ) || ! is_array( $args ) ) {
961
+ $args = array();
962
+ }
963
+
964
+ if ( ! isset( $args['labels'] ) || ! is_array( $args['labels'] ) ) {
965
+ $args['labels'] = array();
966
+ }
967
+
968
+ $label = pods_var_raw( 'name', $args['labels'], pods_var_raw( 'label', $args, __( 'Items', 'pods' ), null, true ), null, true );
969
+ $singular_label = pods_var_raw( 'singular_name', $args['labels'], pods_var_raw( 'label_singular', $args, __( 'Item', 'pods' ), null, true ), null, true );
970
+
971
+ $labels = $args['labels'];
972
+
973
+ $labels['name'] = $label;
974
+ $labels['singular_name'] = $singular_label;
975
+
976
+ if ( 'post_type' == $type ) {
977
+ $labels['menu_name'] = pods_var_raw( 'menu_name', $labels, $label, null, true );
978
+ $labels['add_new'] = pods_var_raw( 'add_new', $labels, __( 'Add New', 'pods' ), null, true );
979
+ $labels['add_new_item'] = pods_var_raw( 'add_new_item', $labels, sprintf( __( 'Add New %s', 'pods' ), $singular_label ), null, true );
980
+ $labels['new_item'] = pods_var_raw( 'new_item', $labels, sprintf( __( 'New %s', 'pods' ), $singular_label ), null, true );
981
+ $labels['edit'] = pods_var_raw( 'edit', $labels, __( 'Edit', 'pods' ), null, true );
982
+ $labels['edit_item'] = pods_var_raw( 'edit_item', $labels, sprintf( __( 'Edit %s', 'pods' ), $singular_label ), null, true );
983
+ $labels['view'] = pods_var_raw( 'view', $labels, sprintf( __( 'View %s', 'pods' ), $singular_label ), null, true );
984
+ $labels['view_item'] = pods_var_raw( 'view_item', $labels, sprintf( __( 'View %s', 'pods' ), $singular_label ), null, true );
985
+ $labels['all_items'] = pods_var_raw( 'all_items', $labels, sprintf( __( 'All %s', 'pods' ), $label ), null, true );
986
+ $labels['search_items'] = pods_var_raw( 'search_items', $labels, sprintf( __( 'Search %s', 'pods' ), $label ), null, true );
987
+ $labels['not_found'] = pods_var_raw( 'not_found', $labels, sprintf( __( 'No %s Found', 'pods' ), $label ), null, true );
988
+ $labels['not_found_in_trash'] = pods_var_raw( 'not_found_in_trash', $labels, sprintf( __( 'No %s Found in Trash', 'pods' ), $label ), null, true );
989
+ $labels['parent'] = pods_var_raw( 'parent', $labels, sprintf( __( 'Parent %s', 'pods' ), $singular_label ), null, true );
990
+ $labels['parent_item_colon'] = pods_var_raw( 'parent_item_colon', $labels, sprintf( __( 'Parent %s:', 'pods' ), $singular_label ), null, true );
991
+ $labels['feature_image'] = pods_var_raw( 'feature_image', $labels, __( 'Featured Image', 'pods' ), null, true );
992
+ $labels['set_featured_image'] = pods_var_raw( 'set_featured_image', $labels, __( 'Set featured image', 'pods' ), null, true );
993
+ $labels['remove_featured_image'] = pods_var_raw( 'remove_featured_image', $labels, __( 'Remove featured image', 'pods' ), null, true );
994
+ $labels['use_featured_image'] = pods_var_raw( 'use_featured_image', $labels, __( 'Use as featured image', 'pods' ), null, true );
995
+ $labels['archives'] = pods_var_raw( 'archives', $labels, sprintf( __( '%s Archives', 'pods' ), $singular_label ), null, true );
996
+ $labels['insert_into_item'] = pods_var_raw( 'insert_into_item', $labels, sprintf( __( 'Insert into %s', 'pods' ), $singular_label ), null, true );
997
+ $labels['uploaded_to_this_item'] = pods_var_raw( 'uploaded_to_this_item', $labels, sprintf( __( 'Uploaded to this %s', 'pods' ), $singular_label ), null, true );
998
+ $labels['filter_items_list'] = pods_var_raw( 'filter_items_list', $labels, sprintf( __( 'Filter %s lists', 'pods' ), $label ), null, true );
999
+ $labels['items_list_navigation'] = pods_var_raw( 'items_list_navigation', $labels, sprintf( __( '%s navigation', 'pods' ), $label ), null, true );
1000
+ $labels['items_list'] = pods_var_raw( 'items_list', $labels, sprintf( __( '%s list', 'pods' ), $label ), null, true );
1001
+ } elseif ( 'taxonomy' == $type ) {
1002
+ $labels['menu_name'] = pods_var_raw( 'menu_name', $labels, $label, null, true );
1003
+ $labels['search_items'] = pods_var_raw( 'search_items', $labels, sprintf( __( 'Search %s', 'pods' ), $label ), null, true );
1004
+ $labels['popular_items'] = pods_var_raw( 'popular_items', $labels, sprintf( __( 'Popular %s', 'pods' ), $label ), null, true );
1005
+ $labels['all_items'] = pods_var_raw( 'all_items', $labels, sprintf( __( 'All %s', 'pods' ), $label ), null, true );
1006
+ $labels['parent_item'] = pods_var_raw( 'parent_item', $labels, sprintf( __( 'Parent %s', 'pods' ), $singular_label ), null, true );
1007
+ $labels['parent_item_colon'] = pods_var_raw( 'parent_item_colon', $labels, sprintf( __( 'Parent %s :', 'pods' ), $singular_label ), null, true );
1008
+ $labels['edit_item'] = pods_var_raw( 'edit_item', $labels, sprintf( __( 'Edit %s', 'pods' ), $singular_label ), null, true );
1009
+ $labels['update_item'] = pods_var_raw( 'update_item', $labels, sprintf( __( 'Update %s', 'pods' ), $singular_label ), null, true );
1010
+ $labels['add_new_item'] = pods_var_raw( 'add_new_item', $labels, sprintf( __( 'Add New %s', 'pods' ), $singular_label ), null, true );
1011
+ $labels['new_item_name'] = pods_var_raw( 'new_item_name', $labels, sprintf( __( 'New %s Name', 'pods' ), $singular_label ), null, true );
1012
+ $labels['separate_items_with_commas'] = pods_var_raw( 'separate_items_with_commas', $labels, sprintf( __( 'Separate %s with commas', 'pods' ), $label ), null, true );
1013
+ $labels['add_or_remove_items'] = pods_var_raw( 'add_or_remove_items', $labels, sprintf( __( 'Add or remove %s', 'pods' ), $label ), null, true );
1014
+ $labels['choose_from_most_used'] = pods_var_raw( 'choose_from_most_used', $labels, sprintf( __( 'Choose from the most used %s', 'pods' ), $label ), null, true );
1015
+ $labels['no_terms'] = pods_var_raw( 'no_terms', $labels, sprintf( __( 'No %s', 'pods' ), $label ), null, true );
1016
+ $labels['items_list_navigation'] = pods_var_raw( 'items_list_navigation', $labels, sprintf( __( '%s navigation', 'pods' ), $label ), null, true );
1017
+ $labels['items_list'] = pods_var_raw( 'items_list', $labels, sprintf( __( '%s list', 'pods' ), $label ), null, true );
1018
+ }
1019
+
1020
+ $args['labels'] = $labels;
1021
+
1022
+ return $args;
1023
+ }
1024
+
1025
+ /**
1026
+ * Activate and Install
1027
+ */
1028
+ public function activate_install() {
1029
+
1030
+ register_activation_hook( PODS_DIR . 'init.php', array( $this, 'activate' ) );
1031
+ register_deactivation_hook( PODS_DIR . 'init.php', array( $this, 'deactivate' ) );
1032
+
1033
+ add_action( 'wpmu_new_blog', array( $this, 'new_blog' ), 10, 6 );
1034
+
1035
+ if ( empty( self::$version ) || version_compare( self::$version, PODS_VERSION, '<' ) || version_compare( self::$version, PODS_DB_VERSION, '<=' ) || self::$upgrade_needed ) {
1036
+ $this->setup();
1037
+ } elseif ( self::$version !== PODS_VERSION ) {
1038
+ delete_option( 'pods_framework_version' );
1039
+ add_option( 'pods_framework_version', PODS_VERSION, '', 'yes' );
1040
+
1041
+ self::$version = PODS_VERSION;
1042
+
1043
+ pods_api()->cache_flush_pods();
1044
+ }
1045
+
1046
+ }
1047
+
1048
+ /**
1049
+ *
1050
+ */
1051
+ public function activate() {
1052
+
1053
+ global $wpdb;
1054
+
1055
+ if ( function_exists( 'is_multisite' ) && is_multisite() && isset( $_GET['networkwide'] ) && 1 == $_GET['networkwide'] ) {
1056
+ $_blog_ids = $wpdb->get_col( "SELECT `blog_id` FROM `{$wpdb->blogs}`" );
1057
+
1058
+ foreach ( $_blog_ids as $_blog_id ) {
1059
+ $this->setup( $_blog_id );
1060
+ }
1061
+ } else {
1062
+ $this->setup();
1063
+ }
1064
+ }
1065
+
1066
+ /**
1067
+ *
1068
+ */
1069
+ public function deactivate() {
1070
+
1071
+ pods_api()->cache_flush_pods();
1072
+
1073
+ }
1074
+
1075
+ /**
1076
+ *
1077
+ */
1078
+ public function needs_upgrade( $current = null, $last = null ) {
1079
+
1080
+ if ( null === $current ) {
1081
+ $current = self::$version;
1082
+ }
1083
+
1084
+ if ( null === $last ) {
1085
+ $last = self::$version_last;
1086
+ }
1087
+
1088
+ $upgrade_needed = false;
1089
+
1090
+ if ( ! empty( $current ) ) {
1091
+ foreach ( self::$upgrades as $old_version => $new_version ) {
1092
+ /*if ( '2.1.0' == $new_version && ( is_developer() ) )
1093
+ continue;*/
1094
+
1095
+ if ( version_compare( $last, $old_version, '>=' ) && version_compare( $last, $new_version, '<' ) && version_compare( $current, $new_version, '>=' ) && 1 != self::$upgraded ) {
1096
+ $upgrade_needed = true;
1097
+
1098
+ break;
1099
+ }
1100
+ }
1101
+ }
1102
+
1103
+ return $upgrade_needed;
1104
+ }
1105
+
1106
+ /**
1107
+ * @param $_blog_id
1108
+ * @param $user_id
1109
+ * @param $domain
1110
+ * @param $path
1111
+ * @param $site_id
1112
+ * @param $meta
1113
+ */
1114
+ public function new_blog( $_blog_id, $user_id, $domain, $path, $site_id, $meta ) {
1115
+
1116
+ if ( function_exists( 'is_multisite' ) && is_multisite() && is_plugin_active_for_network( basename( PODS_DIR ) . '/init.php' ) ) {
1117
+ $this->setup( $_blog_id );
1118
+ }
1119
+ }
1120
+
1121
+ /**
1122
+ * @param null $_blog_id
1123
+ */
1124
+ public function setup( $_blog_id = null ) {
1125
+
1126
+ global $wpdb;
1127
+
1128
+ // Switch DB table prefixes
1129
+ if ( null !== $_blog_id && $_blog_id != $wpdb->blogid ) {
1130
+ switch_to_blog( pods_absint( $_blog_id ) );
1131
+ } else {
1132
+ $_blog_id = null;
1133
+ }
1134
+
1135
+ // Setup DB tables
1136
+ $pods_version = get_option( 'pods_framework_version' );
1137
+ $pods_version_last = get_option( 'pods_framework_version_last' );
1138
+
1139
+ // Install Pods
1140
+ if ( empty( $pods_version ) ) {
1141
+ pods_upgrade()->install( $_blog_id );
1142
+
1143
+ $old_version = get_option( 'pods_version' );
1144
+
1145
+ if ( ! empty( $old_version ) ) {
1146
+ if ( false === strpos( $old_version, '.' ) ) {
1147
+ $old_version = pods_version_to_point( $old_version );
1148
+ }
1149
+
1150
+ delete_option( 'pods_framework_version_last' );
1151
+ add_option( 'pods_framework_version_last', $pods_version, '', 'yes' );
1152
+
1153
+ self::$version_last = $old_version;
1154
+ }
1155
+ } // Upgrade Wizard needed
1156
+ elseif ( $this->needs_upgrade( $pods_version, $pods_version_last ) ) {
1157
+ // Do not do anything
1158
+ return;
1159
+ } // Update Pods and run any required DB updates
1160
+ elseif ( version_compare( $pods_version, PODS_VERSION, '<=' ) ) {
1161
+ if ( false !== apply_filters( 'pods_update_run', null, PODS_VERSION, $pods_version, $_blog_id ) && ! isset( $_GET['pods_bypass_update'] ) ) {
1162
+ do_action( 'pods_update', PODS_VERSION, $pods_version, $_blog_id );
1163
+
1164
+ // Update 2.0 alpha / beta sites
1165
+ if ( version_compare( '2.0.0-a-1', $pods_version, '<=' ) && version_compare( $pods_version, '2.0.0-b-15', '<=' ) ) {
1166
+ include( PODS_DIR . 'sql/update-2.0-beta.php' );
1167
+ }
1168
+
1169
+ if ( version_compare( $pods_version, PODS_DB_VERSION, '<=' ) ) {
1170
+ include( PODS_DIR . 'sql/update.php' );
1171
+ }
1172
+
1173
+ do_action( 'pods_update_post', PODS_VERSION, $pods_version, $_blog_id );
1174
+ }
1175
+
1176
+ delete_option( 'pods_framework_version_last' );
1177
+ add_option( 'pods_framework_version_last', $pods_version, '', 'yes' );
1178
+
1179
+ self::$version_last = $pods_version;
1180
+ }
1181
+
1182
+ delete_option( 'pods_framework_version' );
1183
+ add_option( 'pods_framework_version', PODS_VERSION, '', 'yes' );
1184
+
1185
+ delete_option( 'pods_framework_db_version' );
1186
+ add_option( 'pods_framework_db_version', PODS_DB_VERSION, '', 'yes' );
1187
+
1188
+ self::$version = PODS_VERSION;
1189
+ self::$db_version = PODS_DB_VERSION;
1190
+
1191
+ pods_api()->cache_flush_pods();
1192
+
1193
+ // Restore DB table prefix (if switched)
1194
+ if ( null !== $_blog_id ) {
1195
+ restore_current_blog();
1196
+ }
1197
+
1198
+ }
1199
+
1200
+ /**
1201
+ * @param null $_blog_id
1202
+ */
1203
+ public function reset( $_blog_id = null ) {
1204
+
1205
+ global $wpdb;
1206
+
1207
+ // Switch DB table prefixes
1208
+ if ( null !== $_blog_id && $_blog_id != $wpdb->blogid ) {
1209
+ switch_to_blog( pods_absint( $_blog_id ) );
1210
+ } else {
1211
+ $_blog_id = null;
1212
+ }
1213
+
1214
+ $api = pods_api();
1215
+
1216
+ $pods = $api->load_pods( array( 'names_ids' => true, 'table_info' => false ) );
1217
+
1218
+ foreach ( $pods as $pod_id => $pod_label ) {
1219
+ $api->delete_pod( array( 'id' => $pod_id ) );
1220
+ }
1221
+
1222
+ $templates = $api->load_templates();
1223
+
1224
+ foreach ( $templates as $template ) {
1225
+ $api->delete_template( array( 'id' => $template['id'] ) );
1226
+ }
1227
+
1228
+ $pages = $api->load_pages();
1229
+
1230
+ foreach ( $pages as $page ) {
1231
+ $api->delete_page( array( 'id' => $page['id'] ) );
1232
+ }
1233
+
1234
+ $helpers = $api->load_helpers();
1235
+
1236
+ foreach ( $helpers as $helper ) {
1237
+ $api->delete_helper( array( 'id' => $helper['id'] ) );
1238
+ }
1239
+
1240
+ $tables = $wpdb->get_results( "SHOW TABLES LIKE '{$wpdb->prefix}pods%'", ARRAY_N );
1241
+
1242
+ if ( ! empty( $tables ) ) {
1243
+ foreach ( $tables as $table ) {
1244
+ $table = $table[0];
1245
+
1246
+ pods_query( "DROP TABLE `{$table}`", false );
1247
+ }
1248
+ }
1249
+
1250
+ // Remove any orphans
1251
+ $wpdb->query( "
1252
+ DELETE `p`, `pm`
1253
+ FROM `{$wpdb->posts}` AS `p`
1254
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1255
+ ON `pm`.`post_id` = `p`.`ID`
1256
+ WHERE
1257
+ `p`.`post_type` LIKE '_pods_%'
1258
+ " );
1259
+
1260
+ delete_option( 'pods_framework_version' );
1261
+ delete_option( 'pods_framework_db_version' );
1262
+ delete_option( 'pods_framework_upgrade_2_0' );
1263
+ delete_option( 'pods_framework_upgraded_1_x' );
1264
+
1265
+ // @todo Make sure all entries are being cleaned and do something about the pods_framework_upgrade_{version} dynamic entries created by PodsUpgrade
1266
+ delete_option( 'pods_framework_upgrade_2_0_0' );
1267
+ delete_option( 'pods_framework_upgrade_2_0_sister_ids' );
1268
+ delete_option( 'pods_framework_version_last' );
1269
+
1270
+ delete_option( 'pods_component_settings' );
1271
+
1272
+ $api->cache_flush_pods();
1273
+
1274
+ pods_transient_clear( 'pods_flush_rewrites' );
1275
+
1276
+ self::$version = '';
1277
+
1278
+ // Restore DB table prefix (if switched)
1279
+ if ( null !== $_blog_id ) {
1280
+ restore_current_blog();
1281
+ }
1282
+ }
1283
+
1284
+ public function run() {
1285
+
1286
+ static $ran;
1287
+
1288
+ if ( ! empty( $ran ) ) {
1289
+ return;
1290
+ }
1291
+
1292
+ $ran = true;
1293
+
1294
+ if ( ! did_action( 'plugins_loaded' ) ) {
1295
+ add_action( 'plugins_loaded', array( $this, 'load_components' ), 11 );
1296
+ } else {
1297
+ $this->load_components();
1298
+ }
1299
+
1300
+ if ( ! did_action( 'setup_theme' ) ) {
1301
+ add_action( 'setup_theme', array( $this, 'load_meta' ), 14 );
1302
+ } else {
1303
+ $this->load_meta();
1304
+ }
1305
+
1306
+ if ( ! did_action( 'init' ) ) {
1307
+ add_action( 'init', array( $this, 'core' ), 11 );
1308
+ add_action( 'init', array( $this, 'add_rest_support' ), 12 );
1309
+ add_action( 'init', array( $this, 'setup_content_types' ), 11 );
1310
+
1311
+ if ( is_admin() ) {
1312
+ add_action( 'init', array( $this, 'admin_init' ), 12 );
1313
+ }
1314
+ } else {
1315
+ $this->core();
1316
+ $this->add_rest_support();
1317
+ $this->setup_content_types();
1318
+
1319
+ if ( is_admin() ) {
1320
+ $this->admin_init();
1321
+ }
1322
+ }
1323
+
1324
+ add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ), 15 );
1325
+ add_action( 'admin_enqueue_scripts', array( $this, 'register_assets' ), 15 );
1326
+ add_action( 'login_enqueue_scripts', array( $this, 'register_assets' ), 15 );
1327
+
1328
+ add_filter( 'post_updated_messages', array( $this, 'setup_updated_messages' ), 10, 1 );
1329
+ add_action( 'delete_attachment', array( $this, 'delete_attachment' ) );
1330
+
1331
+ // Register widgets
1332
+ add_action( 'widgets_init', array( $this, 'register_widgets' ) );
1333
+
1334
+ // Show admin bar links
1335
+ add_action( 'admin_bar_menu', array( $this, 'admin_bar_links' ), 81 );
1336
+
1337
+ }
1338
+
1339
+ /**
1340
+ * Delete Attachments from relationships
1341
+ *
1342
+ * @param int $_ID
1343
+ */
1344
+ public function delete_attachment( $_ID ) {
1345
+
1346
+ global $wpdb;
1347
+
1348
+ $_ID = (int) $_ID;
1349
+
1350
+ do_action( 'pods_delete_attachment', $_ID );
1351
+
1352
+ $file_types = "'" . implode( "', '", PodsForm::file_field_types() ) . "'";
1353
+
1354
+ if ( ! pods_tableless() ) {
1355
+ $sql = "
1356
+ DELETE `rel`
1357
+ FROM `@wp_podsrel` AS `rel`
1358
+ LEFT JOIN `{$wpdb->posts}` AS `p`
1359
+ ON
1360
+ `p`.`post_type` = '_pods_field'
1361
+ AND ( `p`.`ID` = `rel`.`field_id` OR `p`.`ID` = `rel`.`related_field_id` )
1362
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1363
+ ON
1364
+ `pm`.`post_id` = `p`.`ID`
1365
+ AND `pm`.`meta_key` = 'type'
1366
+ AND `pm`.`meta_value` IN ( {$file_types} )
1367
+ WHERE
1368
+ `p`.`ID` IS NOT NULL
1369
+ AND `pm`.`meta_id` IS NOT NULL
1370
+ AND `rel`.`item_id` = {$_ID}";
1371
+
1372
+ pods_query( $sql, false );
1373
+ }
1374
+
1375
+ // Post Meta
1376
+ if ( ! empty( PodsMeta::$post_types ) ) {
1377
+ $sql = "
1378
+ DELETE `rel`
1379
+ FROM `@wp_postmeta` AS `rel`
1380
+ LEFT JOIN `{$wpdb->posts}` AS `p`
1381
+ ON
1382
+ `p`.`post_type` = '_pods_field'
1383
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1384
+ ON
1385
+ `pm`.`post_id` = `p`.`ID`
1386
+ AND `pm`.`meta_key` = 'type'
1387
+ AND `pm`.`meta_value` IN ( {$file_types} )
1388
+ WHERE
1389
+ `p`.`ID` IS NOT NULL
1390
+ AND `pm`.`meta_id` IS NOT NULL
1391
+ AND `rel`.`meta_key` = `p`.`post_name`
1392
+ AND `rel`.`meta_value` = '{$_ID}'";
1393
+
1394
+ pods_query( $sql, false );
1395
+ }
1396
+
1397
+ // User Meta
1398
+ if ( ! empty( PodsMeta::$user ) ) {
1399
+ $sql = "
1400
+ DELETE `rel`
1401
+ FROM `@wp_usermeta` AS `rel`
1402
+ LEFT JOIN `{$wpdb->posts}` AS `p`
1403
+ ON
1404
+ `p`.`post_type` = '_pods_field'
1405
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1406
+ ON
1407
+ `pm`.`post_id` = `p`.`ID`
1408
+ AND `pm`.`meta_key` = 'type'
1409
+ AND `pm`.`meta_value` IN ( {$file_types} )
1410
+ WHERE
1411
+ `p`.`ID` IS NOT NULL
1412
+ AND `pm`.`meta_id` IS NOT NULL
1413
+ AND `rel`.`meta_key` = `p`.`post_name`
1414
+ AND `rel`.`meta_value` = '{$_ID}'";
1415
+
1416
+ pods_query( $sql, false );
1417
+ }
1418
+
1419
+ // Comment Meta
1420
+ if ( ! empty( PodsMeta::$comment ) ) {
1421
+ $sql = "
1422
+ DELETE `rel`
1423
+ FROM `@wp_commentmeta` AS `rel`
1424
+ LEFT JOIN `{$wpdb->posts}` AS `p`
1425
+ ON
1426
+ `p`.`post_type` = '_pods_field'
1427
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm`
1428
+ ON
1429
+ `pm`.`post_id` = `p`.`ID`
1430
+ AND `pm`.`meta_key` = 'type'
1431
+ AND `pm`.`meta_value` IN ( {$file_types} )
1432
+ WHERE
1433
+ `p`.`ID` IS NOT NULL
1434
+ AND `pm`.`meta_id` IS NOT NULL
1435
+ AND `rel`.`meta_key` = `p`.`post_name`
1436
+ AND `rel`.`meta_value` = '{$_ID}'";
1437
+
1438
+ pods_query( $sql, false );
1439
+ }
1440
+ }
1441
+
1442
+ /**
1443
+ * Register widgets for Pods
1444
+ */
1445
+ public function register_widgets() {
1446
+
1447
+ $widgets = array(
1448
+ 'PodsWidgetSingle',
1449
+ 'PodsWidgetList',
1450
+ 'PodsWidgetField',
1451
+ 'PodsWidgetForm',
1452
+ 'PodsWidgetView'
1453
+ );
1454
+
1455
+ foreach ( $widgets as $widget ) {
1456
+ if ( ! file_exists( PODS_DIR . 'classes/widgets/' . $widget . '.php' ) ) {
1457
+ continue;
1458
+ }
1459
+
1460
+ require_once PODS_DIR . 'classes/widgets/' . $widget . '.php';
1461
+
1462
+ register_widget( $widget );
1463
+ }
1464
+ }
1465
+
1466
+ /**
1467
+ * Add Admin Bar links
1468
+ */
1469
+ public function admin_bar_links() {
1470
+
1471
+ global $wp_admin_bar, $pods;
1472
+
1473
+ if ( ! is_user_logged_in() || ! is_admin_bar_showing() ) {
1474
+ return;
1475
+ }
1476
+
1477
+ $all_pods = pods_api()->load_pods( array( 'type' => 'pod', 'fields' => false, 'table_info' => false ) );
1478
+
1479
+ // Add New item links for all pods
1480
+ foreach ( $all_pods as $pod ) {
1481
+ if ( 0 == $pod['options']['show_in_menu'] ) {
1482
+ continue;
1483
+ }
1484
+
1485
+ if ( ! pods_is_admin( array( 'pods', 'pods_content', 'pods_add_' . $pod['name'] ) ) ) {
1486
+ continue;
1487
+ }
1488
+
1489
+ $singular_label = pods_var_raw( 'label_singular', $pod['options'], pods_var_raw( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), null, true ), null, true );
1490
+
1491
+ $wp_admin_bar->add_node( array(
1492
+ 'id' => 'new-pod-' . $pod['name'],
1493
+ 'title' => $singular_label,
1494
+ 'parent' => 'new-content',
1495
+ 'href' => admin_url( 'admin.php?page=pods-manage-' . $pod['name'] . '&action=add' )
1496
+ ) );
1497
+ }
1498
+
1499
+ // Add edit link if we're on a pods page
1500
+ if ( is_object( $pods ) && ! is_wp_error( $pods ) && ! empty( $pods->id ) && isset( $pods->pod_data ) && ! empty( $pods->pod_data ) && 'pod' == $pods->pod_data['type'] ) {
1501
+ $pod = $pods->pod_data;
1502
+
1503
+ if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $pod['name'] ) ) ) {
1504
+ $singular_label = pods_var_raw( 'label_singular', $pod['options'], pods_var_raw( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), null, true ), null, true );
1505
+
1506
+ $wp_admin_bar->add_node( array(
1507
+ 'title' => sprintf( __( 'Edit %s', 'pods' ), $singular_label ),
1508
+ 'id' => 'edit-pod',
1509
+ 'href' => admin_url( 'admin.php?page=pods-manage-' . $pod['name'] . '&action=edit&id=' . $pods->id() )
1510
+ ) );
1511
+ }
1512
+ }
1513
+
1514
+ }
1515
+
1516
+ /**
1517
+ * Add REST API support to post type and taxonomy objects.
1518
+ *
1519
+ * @uses "init"
1520
+ *
1521
+ * @since 2.5.6
1522
+ */
1523
+ public function add_rest_support() {
1524
+
1525
+ if ( empty( self::$version ) ) {
1526
+ return;
1527
+ }
1528
+
1529
+ static $rest_support_added;
1530
+
1531
+ if ( ! function_exists( 'register_rest_field' ) ) {
1532
+ return;
1533
+ }
1534
+
1535
+ include_once( PODS_DIR . 'classes/PodsRESTFields.php' );
1536
+ include_once( PODS_DIR . 'classes/PodsRESTHandlers.php' );
1537
+
1538
+ $rest_bases = pods_transient_get( 'pods_rest_bases' );
1539
+
1540
+ if ( empty( $rest_bases ) ) {
1541
+ $pods = pods_api()->load_pods( array( 'type' => array( 'post_type', 'taxonomy', 'user', 'media', 'comment' ), 'fields' => false, 'table_info' => false ) );
1542
+
1543
+ $rest_bases = array();
1544
+
1545
+ if ( ! empty( $pods ) && is_array( $pods ) ) {
1546
+ foreach ( $pods as $pod ) {
1547
+ $type = $pod['type'];
1548
+
1549
+ if ( in_array( $type, array( 'post_type', 'taxonomy', 'user', 'media', 'comment' ) ) ) {
1550
+ if ( $pod && PodsRESTHandlers::pod_extends_core_route( $pod ) ) {
1551
+ $rest_bases[ $pod['name'] ] = array(
1552
+ 'type' => $type,
1553
+ 'base' => sanitize_title( pods_v( 'rest_base', $pod['options'], $pod['name'] ) ),
1554
+ );
1555
+ }
1556
+ }
1557
+ }
1558
+ }
1559
+
1560
+ if ( empty( $rest_bases ) ) {
1561
+ $rest_bases = 'none';
1562
+ }
1563
+
1564
+ pods_transient_set( 'pods_rest_bases', $rest_bases );
1565
+ }
1566
+
1567
+ if ( empty( $rest_support_added ) && ! empty( $rest_bases ) && 'none' !== $rest_bases ) {
1568
+ foreach ( $rest_bases as $pod_name => $pod_info ) {
1569
+ $pod_type = $pod_info['type'];
1570
+ $rest_base = $pod_info['base'];
1571
+
1572
+ if ( 'post_type' == $pod_type ) {
1573
+ PodsRESTHandlers::post_type_rest_support( $pod_name, $rest_base );
1574
+ } elseif ( 'taxonomy' == $pod_type ) {
1575
+ PodsRESTHandlers::taxonomy_rest_support( $pod_name, $rest_base );
1576
+ }
1577
+
1578
+ new PodsRESTFields( $pod_name );
1579
+ }
1580
+
1581
+ $rest_support_added = true;
1582
+ }
1583
+
1584
+ }
1585
+ }
classes/PodsMeta.php ADDED
@@ -0,0 +1,2973 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Pods
4
+ */
5
+ class PodsMeta {
6
+
7
+ /**
8
+ * @var PodsMeta
9
+ */
10
+ static $instance = null;
11
+
12
+ /**
13
+ * @var PodsAPI
14
+ */
15
+ private $api;
16
+
17
+ /**
18
+ * @var Pods
19
+ */
20
+ private static $current_pod;
21
+
22
+ /**
23
+ * @var array
24
+ */
25
+ private static $current_pod_data;
26
+
27
+ /**
28
+ * @var Pods
29
+ */
30
+ private static $current_field_pod;
31
+
32
+ /**
33
+ * @var int
34
+ */
35
+ public static $object_identifier = -1;
36
+
37
+ /**
38
+ * @var array
39
+ */
40
+ public static $advanced_content_types = array();
41
+
42
+ /**
43
+ * @var array
44
+ */
45
+ public static $post_types = array();
46
+
47
+ /**
48
+ * @var array
49
+ */
50
+ public static $taxonomies = array();
51
+
52
+ /**
53
+ * @var array
54
+ */
55
+ public static $media = array();
56
+
57
+ /**
58
+ * @var array
59
+ */
60
+ public static $user = array();
61
+
62
+ /**
63
+ * @var array
64
+ */
65
+ public static $comment = array();
66
+
67
+ /**
68
+ * @var array
69
+ */
70
+ public static $settings = array();
71
+
72
+ /**
73
+ * @var array
74
+ */
75
+ public static $queue = array();
76
+
77
+ /**
78
+ * @var array
79
+ */
80
+ public static $groups = array();
81
+
82
+ /**
83
+ * @var array
84
+ */
85
+ public static $old_post_status = array();
86
+
87
+ /**
88
+ * Singleton handling for a basic pods_meta() request
89
+ *
90
+ * @return \PodsMeta
91
+ *
92
+ * @since 2.3.5
93
+ */
94
+ public static function init () {
95
+ if ( !is_object( self::$instance ) )
96
+ self::$instance = new PodsMeta();
97
+
98
+ return self::$instance;
99
+ }
100
+
101
+ /**
102
+ * @return \PodsMeta
103
+ *
104
+ * @since 2.0
105
+ */
106
+ function __construct () {
107
+
108
+ }
109
+
110
+ /**
111
+ * @return \PodsMeta
112
+ */
113
+ public function core () {
114
+ self::$advanced_content_types = pods_api()->load_pods( array( 'type' => 'pod' ) );
115
+ self::$post_types = pods_api()->load_pods( array( 'type' => 'post_type' ) );
116
+ self::$taxonomies = pods_api()->load_pods( array( 'type' => 'taxonomy' ) );
117
+ self::$media = pods_api()->load_pods( array( 'type' => 'media' ) );
118
+ self::$user = pods_api()->load_pods( array( 'type' => 'user' ) );
119
+ self::$comment = pods_api()->load_pods( array( 'type' => 'comment' ) );
120
+ self::$settings = pods_api()->load_pods( array( 'type' => 'settings' ) );
121
+
122
+ // Handle Post Type Editor (needed for Pods core)
123
+
124
+ // Loop through and add meta boxes for individual types (can't use this, Tabify doesn't pick it up)
125
+ /*
126
+ foreach ( self::$post_types as $post_type ) {
127
+ $post_type_name = $post_type[ 'name' ];
128
+
129
+ if ( !empty( $post_type[ 'object' ] ) )
130
+ $post_type_name = $post_type[ 'object' ];
131
+
132
+ add_action( 'add_meta_boxes_' . $post_type_name, array( $this, 'meta_post_add' ) );
133
+ }
134
+ */
135
+
136
+ add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
137
+ add_action( 'transition_post_status', array( $this, 'save_post_detect_new' ), 10, 3 );
138
+ add_action( 'save_post', array( $this, 'save_post' ), 10, 3 );
139
+
140
+ if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) {
141
+ // Handle *_post_meta
142
+ if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) {
143
+ add_filter( 'get_post_metadata', array( $this, 'get_post_meta' ), 10, 4 );
144
+ }
145
+
146
+ if ( !pods_tableless() ) {
147
+ add_filter( 'add_post_metadata', array( $this, 'add_post_meta' ), 10, 5 );
148
+ add_filter( 'update_post_metadata', array( $this, 'update_post_meta' ), 10, 5 );
149
+ add_filter( 'delete_post_metadata', array( $this, 'delete_post_meta' ), 10, 5 );
150
+ }
151
+ }
152
+
153
+ add_action( 'delete_post', array( $this, 'delete_post' ), 10, 1 );
154
+
155
+ if ( !empty( self::$taxonomies ) ) {
156
+ $has_fields = false;
157
+
158
+ // Handle Taxonomy Editor
159
+ foreach ( self::$taxonomies as $taxonomy ) {
160
+ if ( empty( $taxonomy[ 'fields' ] ) ) {
161
+ continue;
162
+ }
163
+
164
+ $has_fields = true;
165
+
166
+ $taxonomy_name = $taxonomy[ 'name' ];
167
+
168
+ if ( !empty( $taxonomy[ 'object' ] ) )
169
+ $taxonomy_name = $taxonomy[ 'object' ];
170
+
171
+ add_action( $taxonomy_name . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 );
172
+ add_action( $taxonomy_name . '_add_form_fields', array( $this, 'meta_taxonomy' ), 10, 1 );
173
+ }
174
+
175
+ if ( $has_fields ) {
176
+ // Handle Term Editor
177
+ add_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 );
178
+ add_action( 'create_term', array( $this, 'save_taxonomy' ), 10, 3 );
179
+
180
+ if ( apply_filters( 'pods_meta_handler', true, 'term' ) ) {
181
+ // Handle *_term_meta
182
+ if ( apply_filters( 'pods_meta_handler_get', true, 'term' ) ) {
183
+ add_filter( 'get_term_metadata', array( $this, 'get_term_meta' ), 10, 4 );
184
+ }
185
+
186
+ if ( !pods_tableless() ) {
187
+ add_filter( 'add_term_metadata', array( $this, 'add_term_meta' ), 10, 5 );
188
+ add_filter( 'update_term_metadata', array( $this, 'update_term_meta' ), 10, 5 );
189
+ add_filter( 'delete_term_metadata', array( $this, 'delete_term_meta' ), 10, 5 );
190
+ }
191
+ }
192
+ }
193
+ }
194
+
195
+ /**
196
+ * Fires after a previously shared taxonomy term is split into two separate terms.
197
+ *
198
+ * @since 4.2.0
199
+ *
200
+ * @param int $term_id ID of the formerly shared term.
201
+ * @param int $new_term_id ID of the new term created for the $term_taxonomy_id.
202
+ * @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split.
203
+ * @param string $taxonomy Taxonomy for the split term.
204
+ */
205
+ add_action( 'split_shared_term', array( $this, 'split_shared_term' ), 10, 4 );
206
+
207
+ // Handle Delete
208
+ add_action( 'delete_term_taxonomy', array( $this, 'delete_taxonomy' ), 10, 1 );
209
+
210
+ if ( !empty( self::$media ) ) {
211
+ if ( pods_version_check( 'wp', '3.5' ) ) {
212
+ add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
213
+ add_action( 'wp_ajax_save-attachment-compat', array( $this, 'save_media_ajax' ), 0 );
214
+ }
215
+
216
+ add_filter( 'attachment_fields_to_edit', array( $this, 'meta_media' ), 10, 2 );
217
+
218
+ add_filter( 'attachment_fields_to_save', array( $this, 'save_media' ), 10, 2 );
219
+ add_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 );
220
+
221
+ if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) {
222
+ // Handle *_post_meta
223
+ if ( !has_filter( 'get_post_metadata', array( $this, 'get_post_meta' ) ) ) {
224
+ if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) {
225
+ add_filter( 'get_post_metadata', array( $this, 'get_post_meta' ), 10, 4 );
226
+ }
227
+
228
+ if ( !pods_tableless() ) {
229
+ add_filter( 'add_post_metadata', array( $this, 'add_post_meta' ), 10, 5 );
230
+ add_filter( 'update_post_metadata', array( $this, 'update_post_meta' ), 10, 5 );
231
+ add_filter( 'delete_post_metadata', array( $this, 'delete_post_meta' ), 10, 5 );
232
+ }
233
+ }
234
+ }
235
+ }
236
+
237
+ // Handle Delete
238
+ add_action( 'delete_attachment', array( $this, 'delete_media' ), 10, 1 );
239
+
240
+ if ( !empty( self::$user ) ) {
241
+ // Handle User Editor
242
+ add_action( 'show_user_profile', array( $this, 'meta_user' ) );
243
+ add_action( 'edit_user_profile', array( $this, 'meta_user' ) );
244
+ add_action( 'user_register', array( $this, 'save_user' ) );
245
+ add_action( 'profile_update', array( $this, 'save_user' ), 10, 2 );
246
+
247
+ if ( apply_filters( 'pods_meta_handler', true, 'user' ) ) {
248
+ // Handle *_user_meta
249
+ if ( apply_filters( 'pods_meta_handler_get', true, 'user' ) ) {
250
+ add_filter( 'get_user_metadata', array( $this, 'get_user_meta' ), 10, 4 );
251
+ }
252
+
253
+ if ( !pods_tableless() ) {
254
+ add_filter( 'add_user_metadata', array( $this, 'add_user_meta' ), 10, 5 );
255
+ add_filter( 'update_user_metadata', array( $this, 'update_user_meta' ), 10, 5 );
256
+ add_filter( 'delete_user_metadata', array( $this, 'delete_user_meta' ), 10, 5 );
257
+ }
258
+ }
259
+ }
260
+
261
+ // Handle Delete
262
+ add_action( 'delete_user', array( $this, 'delete_user' ), 10, 1 );
263
+
264
+ if ( !empty( self::$comment ) ) {
265
+ // Handle Comment Form / Editor
266
+ add_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 );
267
+ add_filter( 'comment_form_default_fields', array( $this, 'meta_comment_new' ) );
268
+ add_action( 'add_meta_boxes_comment', array( $this, 'meta_comment_add' ) );
269
+ add_filter( 'pre_comment_approved', array( $this, 'validate_comment' ), 10, 2 );
270
+ add_action( 'comment_post', array( $this, 'save_comment' ) );
271
+ add_action( 'edit_comment', array( $this, 'save_comment' ) );
272
+
273
+ if ( apply_filters( 'pods_meta_handler', true, 'comment' ) ) {
274
+ // Handle *_comment_meta
275
+ add_filter( 'get_comment_metadata', array( $this, 'get_comment_meta' ), 10, 4 );
276
+
277
+ if ( !pods_tableless() ) {
278
+ add_filter( 'add_comment_metadata', array( $this, 'add_comment_meta' ), 10, 5 );
279
+ add_filter( 'update_comment_metadata', array( $this, 'update_comment_meta' ), 10, 5 );
280
+ add_filter( 'delete_comment_metadata', array( $this, 'delete_comment_meta' ), 10, 5 );
281
+ }
282
+ }
283
+ }
284
+
285
+ // Handle Delete
286
+ add_action( 'delete_comment', array( $this, 'delete_comment' ), 10, 1 );
287
+
288
+ // @todo Patch core to provide $option back in filters, patch core to add filter pre_add_option to add_option
289
+ /*if ( !empty( self::$settings ) ) {
290
+ foreach ( self::$settings as $setting_pod ) {
291
+ foreach ( $setting_pod[ 'fields' ] as $option ) {
292
+ add_filter( 'pre_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'get_option' ), 10, 1 );
293
+ add_action( 'add_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'add_option' ), 10, 2 );
294
+ add_filter( 'pre_update_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'update_option' ), 10, 2 );
295
+ }
296
+ }
297
+ }*/
298
+
299
+ if ( is_admin() )
300
+ $this->integrations();
301
+
302
+ add_action( 'init', array( $this, 'enqueue' ), 9 );
303
+
304
+ if ( function_exists( 'pll_current_language' ) )
305
+ add_action( 'init', array( $this, 'cache_pods' ), 101 );
306
+
307
+ do_action( 'pods_meta_init' );
308
+
309
+ return $this;
310
+ }
311
+
312
+ public static function enqueue () {
313
+ foreach ( self::$queue as $type => $objects ) {
314
+ foreach ( $objects as $pod_name => $pod ) {
315
+ pods_transient_set( 'pods_pod_' . $pod_name, $pod );
316
+ }
317
+
318
+ self::$$type = array_merge( self::$$type, $objects );
319
+ }
320
+ }
321
+
322
+ /**
323
+ * Go back through and cache the Pods now that Polylang has loaded
324
+ */
325
+ public function cache_pods () {
326
+ self::$advanced_content_types = pods_api()->load_pods( array( 'type' => 'pod', 'refresh' => true ) );
327
+ self::$post_types = pods_api()->load_pods( array( 'type' => 'post_type', 'refresh' => true ) );
328
+ self::$taxonomies = pods_api()->load_pods( array( 'type' => 'taxonomy', 'refresh' => true ) );
329
+ self::$media = pods_api()->load_pods( array( 'type' => 'media', 'refresh' => true ) );
330
+ self::$user = pods_api()->load_pods( array( 'type' => 'user', 'refresh' => true ) );
331
+ self::$comment = pods_api()->load_pods( array( 'type' => 'comment', 'refresh' => true ) );
332
+ self::$settings = pods_api()->load_pods( array( 'type' => 'settings', 'refresh' => true ) );
333
+ }
334
+
335
+ public function register ( $type, $pod ) {
336
+ $pod_type = $type;
337
+
338
+ if ( 'post_type' == $type )
339
+ $type = 'post_types';
340
+ elseif ( 'taxonomy' == $type )
341
+ $type = 'taxonomies';
342
+ elseif ( 'pod' == $type )
343
+ $type = 'advanced_content_types';
344
+
345
+ if ( !isset( self::$queue[ $type ] ) )
346
+ self::$queue[ $type ] = array();
347
+
348
+ if ( is_array( $pod ) && !empty( $pod ) && !isset( $pod[ 'name' ] ) ) {
349
+ $data = array();
350
+
351
+ foreach ( $pod as $p ) {
352
+ $data[] = $this->register( $type, $p );
353
+ }
354
+
355
+ return $data;
356
+ }
357
+
358
+ $pod[ 'type' ] = $pod_type;
359
+ $pod = pods_api()->save_pod( $pod, false, false );
360
+
361
+ if ( !empty( $pod ) ) {
362
+ self::$object_identifier--;
363
+
364
+ self::$queue[ $type ][ $pod[ 'name' ] ] = $pod;
365
+
366
+ return $pod;
367
+ }
368
+
369
+ return false;
370
+ }
371
+
372
+ public function register_field ( $pod, $field ) {
373
+ if ( is_array( $pod ) && !empty( $pod ) && !isset( $pod[ 'name' ] ) ) {
374
+ $data = array();
375
+
376
+ foreach ( $pod as $p ) {
377
+ $data[] = $this->register_field( $p, $field );
378
+ }
379
+
380
+ return $data;
381
+ }
382
+
383
+ if ( empty( self::$current_pod_data ) || !is_object( self::$current_pod_data ) || self::$current_pod_data[ 'name' ] != $pod )
384
+ self::$current_pod_data = pods_api()->load_pod( array( 'name' => $pod ), false );
385
+
386
+ $pod = self::$current_pod_data;
387
+
388
+ if ( !empty( $pod ) ) {
389
+ $type = $pod[ 'type' ];
390
+
391
+ if ( 'post_type' == $pod[ 'type' ] )
392
+ $type = 'post_types';
393
+ elseif ( 'taxonomy' == $pod[ 'type' ] )
394
+ $type = 'taxonomies';
395
+ elseif ( 'pod' == $pod[ 'type' ] )
396
+ $type = 'advanced_content_types';
397
+
398
+ if ( !isset( self::$queue[ $pod[ 'type' ] ] ) )
399
+ self::$queue[ $type ] = array();
400
+
401
+ $field = pods_api()->save_field( $field, false, false, $pod[ 'id' ] );
402
+
403
+ if ( !empty( $field ) ) {
404
+ $pod[ 'fields' ][ $field[ 'name' ] ] = $field;
405
+
406
+ self::$queue[ $type ][ $pod[ 'name' ] ] = $pod;
407
+
408
+ return $field;
409
+ }
410
+ }
411
+
412
+ return false;
413
+ }
414
+
415
+ public function integrations () {
416
+ // Codepress Admin Columns 2.x
417
+ add_filter( 'cac/storage_model/meta_keys', array( $this, 'cpac_meta_keys' ), 10, 2 );
418
+ add_filter( 'cac/post_types', array( $this, 'cpac_post_types' ), 10, 1 );
419
+ add_filter( 'cac/column/meta/value', array( $this, 'cpac_meta_value' ), 10, 3 );
420
+ }
421
+
422
+
423
+ public function cpac_meta_keys ( $meta_fields, $storage_model ) {
424
+ $object_type = 'post_type';
425
+ $object = $storage_model->key;
426
+
427
+ if ( in_array( $storage_model->key, array( 'wp-links', 'link' ) ) ) {
428
+ $object_type = $object = 'link';
429
+ }
430
+ elseif ( in_array( $storage_model->key, array( 'wp-media', 'media' ) ) ) {
431
+ $object_type = $object = 'media';
432
+ }
433
+ elseif ( in_array( $storage_model->key, array( 'wp-users', 'user' ) ) ) {
434
+ $object_type = $object = 'user';
435
+ }
436
+ elseif ( in_array( $storage_model->key, array( 'wp-comments', 'comment' ) ) ) {
437
+ $object_type = $object = 'comment';
438
+ }
439
+ elseif ( 'taxonomy' === $storage_model->type ) {
440
+ $object_type = 'taxonomy';
441
+ $object = $storage_model->taxonomy;
442
+ }
443
+
444
+ if ( empty( self::$current_pod_data ) || !is_object( self::$current_pod_data ) || self::$current_pod_data[ 'name' ] != $object )
445
+ self::$current_pod_data = pods_api()->load_pod( array( 'name' => $object ), false );
446
+
447
+ $pod = self::$current_pod_data;
448
+
449
+ // Add Pods fields
450
+ if ( !empty( $pod ) && $object_type == $pod[ 'type' ] ) {
451
+ foreach ( $pod[ 'fields' ] as $field => $field_data ) {
452
+ if ( !is_array( $meta_fields ) )
453
+ $meta_fields = array();
454
+
455
+ if ( !in_array( $field, $meta_fields ) )
456
+ $meta_fields[] = $field;
457
+ }
458
+ }
459
+
460
+ // Remove internal Pods fields
461
+ if ( is_array( $meta_fields ) ) {
462
+ foreach ( $meta_fields as $k => $meta_field ) {
463
+ if ( 0 === strpos( $meta_field, '_pods_' ) )
464
+ unset( $meta_fields[ $k ] );
465
+ }
466
+ }
467
+
468
+ return $meta_fields;
469
+ }
470
+
471
+ public function cpac_post_types ( $post_types ) {
472
+ // Remove internal Pods post types
473
+ foreach ( $post_types as $post_type => $post_type_name ) {
474
+ if ( 0 === strpos( $post_type, '_pods_' ) || 0 === strpos( $post_type_name, '_pods_' ) )
475
+ unset( $post_types[ $post_type ] );
476
+ }
477
+
478
+ return $post_types;
479
+ }
480
+
481
+ public function cpac_meta_value ( $meta, $id, $obj ) {
482
+ $tableless_field_types = PodsForm::tableless_field_types();
483
+
484
+ $object_type = 'post_type';
485
+ $object = $obj->storage_model->key;
486
+
487
+ if ( in_array( $obj->storage_model->type, array( 'wp-links', 'link' ) ) ) {
488
+ $object_type = $object = 'link';
489
+ }
490
+ elseif ( in_array( $obj->storage_model->type, array( 'wp-media', 'media' ) ) ) {
491
+ $object_type = $object = 'media';
492
+ }
493
+ elseif ( in_array( $obj->storage_model->type, array( 'wp-users', 'user' ) ) ) {
494
+ $object_type = $object = 'user';
495
+ }
496
+ elseif ( in_array( $obj->storage_model->type, array( 'wp-comments', 'comment' ) ) ) {
497
+ $object_type = $object = 'comment';
498
+ }
499
+ elseif ( 'taxonomy' === $obj->storage_model->type ) {
500
+ $object_type = 'taxonomy';
501
+ $object = $obj->storage_model->taxonomy;
502
+ }
503
+
504
+ $field = substr( $obj->get_option( 'field' ), 0, 10 ) == "cpachidden" ? str_replace( 'cpachidden', '', $obj->get_option( 'field' ) ) : $obj->get_option( 'field' );
505
+ $field_type = $obj->get_option( 'field_type' );
506
+
507
+ if ( empty( self::$current_pod_data ) || !is_object( self::$current_pod_data ) || self::$current_pod_data[ 'name' ] != $object )
508
+ self::$current_pod_data = pods_api()->load_pod( array( 'name' => $object ), false );
509
+
510
+ $pod = self::$current_pod_data;
511
+
512
+ // Add Pods fields
513
+ if ( !empty( $pod ) && isset( $pod[ 'fields' ][ $field ] ) ) {
514
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'media', 'taxonomy', 'user', 'comment', 'media' ) ) && ( !empty( $field_type ) || in_array( $pod[ 'fields' ][ $field ][ 'type' ], $tableless_field_types ) ) ) {
515
+ $metadata_type = $pod['type'];
516
+
517
+ if ( in_array( $metadata_type, array( 'post_type', 'media' ) ) ) {
518
+ $metadata_type = 'post';
519
+ } elseif ( 'taxonomy' == $metadata_type ) {
520
+ $metadata_type = 'term';
521
+ }
522
+
523
+ if ( 'term' == $metadata_type && ! function_exists( 'get_term_meta' ) ) {
524
+ $podterms = pods( $pod['name'], $id );
525
+
526
+ $meta = $podterms->field( $field );
527
+ } else {
528
+ $meta = get_metadata( $metadata_type, $id, $field, true );
529
+ }
530
+ }
531
+ elseif ( 'taxonomy' == $pod['type'] ) {
532
+ $podterms = pods( $pod['name'], $id );
533
+
534
+ $meta = $podterms->field( $field );
535
+ }
536
+
537
+ $meta = PodsForm::field_method( $pod[ 'fields' ][ $field ][ 'type' ], 'ui', $id, $meta, $field, array_merge( $pod[ 'fields' ][ $field ], $pod[ 'fields' ][ $field ][ 'options' ] ), $pod[ 'fields' ], $pod );
538
+ }
539
+
540
+ return $meta;
541
+ }
542
+
543
+ public function cpac_meta_values ( $meta, $field_type, $field, $type, $id ) {
544
+ $tableless_field_types = PodsForm::tableless_field_types();
545
+
546
+ $object = $type;
547
+
548
+ if ( 'wp-media' == $type )
549
+ $object = 'media';
550
+ elseif ( 'wp-users' == $type )
551
+ $object = 'user';
552
+ elseif ( 'wp-comments' == $type )
553
+ $object = 'comment';
554
+
555
+ if ( empty( self::$current_pod_data ) || !is_object( self::$current_pod_data ) || self::$current_pod_data[ 'name' ] != $object )
556
+ self::$current_pod_data = pods_api()->load_pod( array( 'name' => $object ), false );
557
+
558
+ $pod = self::$current_pod_data;
559
+
560
+ // Add Pods fields
561
+ if ( !empty( $pod ) && isset( $pod[ 'fields' ][ $field ] ) ) {
562
+ if ( in_array( $pod[ 'type' ], array( 'post_type', 'user', 'taxonomy', 'comment', 'media' ) ) && ( !empty( $field_type ) || in_array( $pod[ 'fields' ][ $field ][ 'type' ], $tableless_field_types ) ) ) {
563
+ $metadata_type = $pod['type'];
564
+
565
+ if ( in_array( $metadata_type, array( 'post_type', 'media' ) ) ) {
566
+ $metadata_type = 'post';
567
+ } elseif ( 'taxonomy' == $metadata_type ) {
568
+ $metadata_type = 'term';
569
+ }
570
+
571
+ $meta = get_metadata( $metadata_type, $id, $field, true );
572
+ }
573
+
574
+ $meta = PodsForm::field_method( $pod[ 'fields' ][ $field ][ 'type' ], 'ui', $id, $meta, $field, array_merge( $pod[ 'fields' ][ $field ], $pod[ 'fields' ][ $field ][ 'options' ] ), $pod[ 'fields' ], $pod );
575
+ }
576
+
577
+ return $meta;
578
+ }
579
+
580
+ /**
581
+ * Add a meta group of fields to add/edit forms
582
+ *
583
+ * @param string|array $pod The pod or type of element to attach the group to.
584
+ * @param string $label Title of the edit screen section, visible to user.
585
+ * @param string|array $fields Either a comma separated list of text fields or an associative array containing field infomration.
586
+ * @param string $context (optional) The part of the page where the edit screen section should be shown ('normal', 'advanced', or 'side').
587
+ * @param string $priority (optional) The priority within the context where the boxes should show ('high', 'core', 'default' or 'low').
588
+ *
589
+ * @since 2.0
590
+ *
591
+ * @return mixed|void
592
+ */
593
+ public function group_add ( $pod, $label, $fields, $context = 'normal', $priority = 'default' ) {
594
+ if ( is_array( $pod ) && !empty( $pod ) && !isset( $pod[ 'name' ] ) ) {
595
+ foreach ( $pod as $p ) {
596
+ $this->group_add( $pod, $label, $fields, $context, $priority );
597
+ }
598
+
599
+ return true;
600
+ }
601
+
602
+ if ( !is_array( $pod ) ) {
603
+ if ( empty( self::$current_pod_data ) || !is_object( self::$current_pod_data ) || self::$current_pod_data[ 'name' ] != $pod )
604
+ self::$current_pod_data = pods_api()->load_pod( array( 'name' => $pod ), false );
605
+
606
+ if ( !empty( self::$current_pod_data ) )
607
+ $pod = self::$current_pod_data;
608
+ else {
609
+ $type = 'post_type';
610
+
611
+ if ( in_array( $pod, array( 'media', 'user', 'comment' ) ) )
612
+ $type = $pod;
613
+
614
+ $pod = array(
615
+ 'name' => $pod,
616
+ 'type' => $type
617
+ );
618
+ }
619
+ }
620
+
621
+ if ( is_array( $pod ) && !isset( $pod[ 'id' ] ) ) {
622
+ $defaults = array(
623
+ 'name' => '',
624
+ 'type' => 'post_type'
625
+ );
626
+
627
+ $pod = array_merge( $defaults, $pod );
628
+ }
629
+
630
+ if ( 'post' == $pod[ 'type' ] )
631
+ $pod[ 'type' ] = 'post_type';
632
+
633
+ if ( empty( $pod[ 'name' ] ) && isset( $pod[ 'object' ] ) && !empty( $pod[ 'object' ] ) )
634
+ $pod[ 'name' ] = $pod[ 'object' ];
635
+ elseif ( !isset( $pod[ 'object' ] ) || empty( $pod[ 'object' ] ) )
636
+ $pod[ 'object' ] = $pod[ 'name' ];
637
+
638
+ if ( empty( $pod[ 'object' ] ) )
639
+ return pods_error( __( 'Object required to add a Pods meta group', 'pods' ) );
640
+
641
+ $object_name = $pod[ 'object' ];
642
+
643
+ if ( 'pod' == $pod[ 'type' ] )
644
+ $object_name = $pod[ 'name' ];
645
+
646
+ if ( !isset( self::$groups[ $pod[ 'type' ] ] ) )
647
+ self::$groups[ $pod[ 'type' ] ] = array();
648
+
649
+ if ( !isset( self::$groups[ $pod[ 'type' ] ][ $object_name ] ) )
650
+ self::$groups[ $pod[ 'type' ] ][ $object_name ] = array();
651
+
652
+ $_fields = array();
653
+
654
+ if ( !is_array( $fields ) )
655
+ $fields = explode( ',', $fields );
656
+
657
+ foreach ( $fields as $k => $field ) {
658
+ $name = $k;
659
+
660
+ $defaults = array(
661
+ 'name' => $name,
662
+ 'label' => $name,
663
+ 'type' => 'text'
664
+ );
665
+
666
+ if ( !is_array( $field ) ) {
667
+ $name = trim( $field );
668
+
669
+ $field = array(
670
+ 'name' => $name,
671
+ 'label' => $name
672
+ );
673
+ }
674
+
675
+ $field = array_merge( $defaults, $field );
676
+
677
+ $field[ 'name' ] = trim( $field[ 'name' ] );
678
+
679
+ if ( isset( $pod[ 'fields' ] ) && isset( $pod[ 'fields' ][ $field[ 'name' ] ] ) )
680
+ $field = array_merge( $field, $pod[ 'fields' ][ $field[ 'name' ] ] );
681
+
682
+ $_fields[ $k ] = $field;
683
+ }
684
+
685
+ // Setup field options
686
+ $fields = PodsForm::fields_setup( $_fields );
687
+
688
+ $group = array(
689
+ 'pod' => $pod,
690
+ 'label' => $label,
691
+ 'fields' => $fields,
692
+ 'context' => $context,
693
+ 'priority' => $priority
694
+ );
695
+
696
+ // Filter group data, pass vars separately for reference down the line (in case array changed by other filter)
697
+ $group = apply_filters( 'pods_meta_group_add_' . $pod[ 'type' ] . '_' . $object_name, $group, $pod, $label, $fields );
698
+ $group = apply_filters( 'pods_meta_group_add_' . $pod[ 'type' ], $group, $pod, $label, $fields );
699
+ $group = apply_filters( 'pods_meta_group_add', $group, $pod, $label, $fields );
700
+
701
+ self::$groups[ $pod[ 'type' ] ][ $object_name ][] = $group;
702
+
703
+ // Hook it up!
704
+ if ( 'post_type' == $pod[ 'type' ] ) {
705
+ if ( !has_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) ) )
706
+ add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
707
+
708
+ /*if ( !has_action( 'save_post', array( $this, 'save_post' ), 10, 3 ) )
709
+ add_action( 'save_post', array( $this, 'save_post' ), 10, 3 );*/
710
+ }
711
+ elseif ( 'taxonomy' == $pod[ 'type' ] ) {
712
+ if ( !has_action( $pod[ 'object' ] . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 ) ) {
713
+ add_action( $pod[ 'object' ] . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 );
714
+ add_action( $pod[ 'object' ] . '_add_form_fields', array( $this, 'meta_taxonomy' ), 10, 1 );
715
+ }
716
+
717
+ if ( !has_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 ) ) {
718
+ add_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 );
719
+ add_action( 'create_term', array( $this, 'save_taxonomy' ), 10, 3 );
720
+ }
721
+ }
722
+ elseif ( 'media' == $pod[ 'type' ] ) {
723
+ if ( !has_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 ) ) {
724
+ if ( pods_version_check( 'wp', '3.5' ) ) {
725
+ add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
726
+ add_action( 'wp_ajax_save-attachment-compat', array( $this, 'save_media_ajax' ), 0 );
727
+ }
728
+
729
+ add_filter( 'attachment_fields_to_edit', array( $this, 'meta_media' ), 10, 2 );
730
+
731
+ add_filter( 'attachment_fields_to_save', array( $this, 'save_media' ), 10, 2 );
732
+ add_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 );
733
+ }
734
+ }
735
+ elseif ( 'user' == $pod[ 'type' ] ) {
736
+ if ( !has_action( 'show_user_profile', array( $this, 'meta_user' ) ) ) {
737
+ add_action( 'show_user_profile', array( $this, 'meta_user' ) );
738
+ add_action( 'edit_user_profile', array( $this, 'meta_user' ) );
739
+ add_action( 'user_register', array( $this, 'save_user' ) );
740
+ add_action( 'profile_update', array( $this, 'save_user' ), 10, 2 );
741
+ }
742
+ }
743
+ elseif ( 'comment' == $pod[ 'type' ] ) {
744
+ if ( !has_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 ) ) {
745
+ add_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 );
746
+ add_filter( 'comment_form_default_fields', array( $this, 'meta_comment_new' ) );
747
+ add_action( 'add_meta_boxes_comment', array( $this, 'meta_comment_add' ) );
748
+ add_action( 'wp_insert_comment', array( $this, 'save_comment' ) );
749
+ add_action( 'edit_comment', array( $this, 'save_comment' ) );
750
+ }
751
+ }
752
+ }
753
+
754
+ public function object_get ( $type, $name ) {
755
+ $object = self::$post_types;
756
+
757
+ if ( 'term' == $type ) {
758
+ $type = 'taxonomy';
759
+ }
760
+
761
+ if ( 'taxonomy' == $type )
762
+ $object = self::$taxonomies;
763
+ elseif ( 'media' == $type )
764
+ $object = self::$media;
765
+ elseif ( 'user' == $type )
766
+ $object = self::$user;
767
+ elseif ( 'comment' == $type )
768
+ $object = self::$comment;
769
+
770
+ if ( 'pod' != $type && !empty( $object ) && is_array( $object ) && isset( $object[ $name ] ) )
771
+ $pod = $object[ $name ];
772
+ else {
773
+ if ( empty( self::$current_pod_data ) || !is_object( self::$current_pod_data ) || self::$current_pod_data[ 'name' ] != $name )
774
+ self::$current_pod_data = pods_api()->load_pod( array( 'name' => $name ), false );
775
+
776
+ $pod = self::$current_pod_data;
777
+ }
778
+
779
+ if ( empty( $pod ) )
780
+ return array();
781
+
782
+ $defaults = array(
783
+ 'name' => 'post',
784
+ 'object' =>