Pods – Custom Content Types and Fields - Version 2.8.0

Version Description

Download this release

Release Info

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

Code changes from version 2.7.31 to 2.8.0

changelog.txt ADDED
@@ -0,0 +1,1006 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Found a bug? Have a great feature idea? Get on GitHub and tell us about it and we'll get right on it: https://pods.io/submit/
2
+
3
+ Our GitHub has the full list of all prior releases of Pods: https://github.com/pods-framework/pods/releases
4
+
5
+ = 2.8 - October 12th, 2021 =
6
+
7
+ Read the full [Pods 2.8 Field Guide](https://pods.io/2021/02/11/pods-2-8-beta-1-released-and-the-field-guide-to-pods-2-8/) which includes information about all of the features, enhancements, and changes in this major Pods release.
8
+
9
+ **Breaking compatability warning:**
10
+ * New minimum required versions have been updated as follows which includes notices to let you know if you need to update something.
11
+ * New minimum WP version required: WordPress 5.5+ (previously: WP 4.5+) — Going forward we will support the last two major WP releases on each major feature release of Pods.
12
+ * New minimum PHP version required: PHP 5.6+ (previously: PHP 5.3+) — Hey! You should take the time to update to PHP 7.4+ because there’s major speed improvements to be had 🙂
13
+ * New minimum MySQL version required: MySQL 5.5+ (previously: MySQL 5.1+)
14
+ * Refactored object handling for Pod and Field configurations — instead of passing around arrays we now are using a fully scoped object for these configs. This gives us flexibility to lazy load and pull things as-needed from the database instead of always pulling entire Pods and Fields configurations all at once on any page it may not be needed. This also reduces how much we have to use/cache on each page further reducing overall memory usage on every page. It remains backward compatible in most array usage cases like `$pod['name']` but be aware that PHP ArrayAccess overloading errors may occur when manipulating Pod configs like `$pod['fields']['your_field']['name'] = 'My new field name';` or `$pod['options']['some_option'] = 1;`
15
+
16
+ **Features and changes in this release**
17
+ * Feature: Now you can add multiple groups of fields. (@sc0ttkclark, @zrothauser)
18
+ * Feature: Our Edit Pod screen is powered by our all new React form interfaces, tooltips, and they use our new Pods Admin REST API endpoints. (@sc0ttkclark, @zrothauser)
19
+ * Feature: All of our form fields are powered by React now in preparation for Pods 2.9 repeatable fields that we're working on next. (@sc0ttkclark, @zrothauser)
20
+ * Feature: New field types for Heading and HTML. (@sc0ttkclark, @zrothauser)
21
+ * Feature: New Pods Blocks available and the underlying Pods Block PHP API is compatible with ACF Blocks if you've ever used those before. (@sc0ttkclark, @zrothauser)
22
+ * Feature: REST API endpoints are now available to create/edit various objects: Pods, Pod Groups, and Pod Fields. (@sc0ttkclark)
23
+ * Feature: WP-CLI commands that mirror the REST API endpoints we have. (@sc0ttkclark)
24
+ * Feature: The new WYSIWYG editor option to use [Quill Editor](https://github.com/zenoamaro/react-quill) is now available and the CLEditor has been removed. (@sc0ttkclark, @zrothauser)
25
+
26
+ = 2.7.31 - September 23rd, 2021 =
27
+
28
+ * Pods 2.8 is coming on October 12th! Check out the [Pods 2.8 Field Guide](https://pods.io/2021/02/11/pods-2-8-beta-1-released-and-the-field-guide-to-pods-2-8/) for more information.
29
+ * Fixed: Resolve issues where searching a Pod would cause queries like `post_title.t` or `display_name.t` unexpectedly. #6050 (@sc0ttkclark, @unknownnf)
30
+
31
+ = 2.7.30 - August 12th, 2021 =
32
+
33
+ * Fixed: Prevented a few PHP notices from showing on the new WordPress 5.8+ widgets screen.
34
+
35
+ = 2.7.29 - August 4th, 2021 =
36
+
37
+ * Security: Clean up post type and taxonomy labels so they avoid potential output escaping problems in WordPress core (@sc0ttkclark, reported by Muhammad Daffa via WPScan)
38
+ * Friends of Pods: Updated CTA text about our 2021 donor goals. (@sc0ttkclark)
39
+ * Added: Support for Timezones in datetime / time fields. #6042 (@JoryHogeveen)
40
+ * Added: Support for Pantheon WP Native Sessions plugin. (@sc0ttkclark)
41
+ * Enhancement: Optimized the PNG image assets using PNG8+Alpha with ImageAlpha and ImageOptim. #6028 (@lowwebtech)
42
+ * Fixed: Hidden fields now properly submit correctly. (@sc0ttkclark)
43
+ * Fixed: Post type `has_archive` no gets set to a false properly when disabled. #6069 (@JoryHogeveen)
44
+ * Fixed: Resolve PHP `strlen()`` warnings when validating text values being saved. #6062 (@pd-cm, @sc0ttkclark, @JoryHogeveen)
45
+ * Fixed: Sorting URLs in `PodsUI` include `post_type` and `taxonomy` when Advanced Content Types are set to be underneath a Post Type's top level menu. #6040 (@JoryHogeveen)
46
+ * Fixed: Fallback to the manage fields in `PodsUI` for reordering when reorder fields are not overridden. #6058 (@JoryHogeveen)
47
+ * Fixed: Depend on plupload when showing custom upload directory option for file fields. (@JoryHogeveen)
48
+
49
+ = 2.7.28 - May 20th, 2021 =
50
+
51
+ * Added: New upload directory option for File fields using Plupload that lets you choose to customize which directory the files end up in. #6021 (@JoryHogeveen)
52
+ * Added: Relationship fields now support custom selectors in the REST API. You can specify `my_field.some_field` to output a specific field in your REST API options for each relationship field. (@sc0ttkclark)
53
+ * Added: New `pods_image_for_post()` and `pods_image_url_for_post()` functions have been added for certain page builders like Oxygen. (@sc0ttkclark)
54
+ * Added: New query variable prefix option (`num_prefix`) for PodsUI instances. (@sc0ttkclark)
55
+ * Added: `pagination_type` and `pagination_location` options for PodsUI instances to support more flexible pagination options. (@sc0ttkclark)
56
+ * Enhancement: Implement `search` and `sort` field sets for PodsUI instances to more easily specify which fields are searchable or sortable. (@sc0ttkclark)
57
+ * Fixed: PHP fatal errors no longer occur for avatar fields in certain situations. #6007 (@JoryHogeveen)
58
+ * Fixed: PHP fatal errors no longer occur for PHP 8 in certain situations. #6012 (@JoryHogeveen)
59
+ * Fixed: Resolved an issue with relationship fields not outputting their full data to the REST API when the related object is not a valid pod. (@sc0ttkclark)
60
+ * Fixed: Resolved an issue with not saving the fields for the extended Media pod when making update requests through the REST API. (@sc0ttkclark)
61
+ * Fixed: Implemented a temporary PHP 7.4+ fix for Freemius. (@sc0ttkclark)
62
+ * Fixed: Searching WP-based objects in PodsUI interfaces now resolves to the proper fields. (@sc0ttkclark)
63
+
64
+ = 2.7.27 - March 4th, 2021 =
65
+
66
+ * Fixed: Resolved PHP notice in the PodsAPI. #5952 (@sc0ttkclark)
67
+ * Fixed: Resolved PHP notice when using `?pods_debug_sql=1` on Pods Admin UI screens. (@sc0ttkclark)
68
+
69
+ = 2.7.26 - January 8th, 2021 =
70
+
71
+ * Fixed: Prevent PHP warnings in the `components/Templates/includes/element-pod_reference.php` file. #5914 (@JoryHogeveen)
72
+ * Added: New filter `pods_shortcode_detect_from_current_post` allows you to override whether a shortcode should detect the post object outside of the loop (default is only when `in_the_loop()`). This helps to fix problems that are part of the integration which the free Pods Beaver Themer Add-On uses. (@sc0ttkclark)
73
+
74
+ = 2.7.25 - December 28th 2020 =
75
+
76
+ **New Features & Enhancements**
77
+
78
+ * Added: Custom no access message for templates. #5875 (@JoryHogeveen)
79
+ * Added: New filter `pods_field_validate_{$type}`. #1106 (@JoryHogeveen)
80
+
81
+ **Bug Fixes**
82
+
83
+ * Fixed: Ensure compatibility with the WordPress 5.6 jQuery update. #5892, #5896 & #5897 (@JoryHogeveen)
84
+ * Fixed: Prevent `wp_unslash()` from unnecessarily over sanitizing input. #5040 & #4424 (@JoryHogeveen)
85
+ * Fixed: Prevent issues with HTML entities in custom relationship values when it gets to JavaScript. #5894 (@JoryHogeveen)
86
+ * Fixed: Better support multiple languages in the Relationship AJAX search. #5888 (@JoryHogeveen)
87
+ * Fixed: Include the `post_type` value in attachment saves so that the more WordPress core actions trigger. #5748 (@JoryHogeveen)
88
+ * Fixed: Allow `the_excerpt` to be used as custom filter on singular pages. #5899 (@JoryHogeveen)
89
+ * Fixed: Better support caching of the avatar images/data and integrate with the `get_avatar_data` filter. #5771 (@JoryHogeveen)
90
+
91
+
92
+ = 2.7.24 - November 5th 2020 =
93
+
94
+ **Bug Fixes**
95
+
96
+ * Fixed: Fix media `[each]` loop if no `media` Pod exists. #5882 (@JoryHogeveen)
97
+ * Fixed: Fallback to default display field if custom option is invalid for relationship fields. #5839 & #5859 (@JoryHogeveen)
98
+ * Fixed: Use `pathinfo` to properly validate file extension. #5876 (@JoryHogeveen)
99
+
100
+ = 2.7.23 - October 30th 2020 =
101
+
102
+ **New Features & Enhancements**
103
+
104
+ * Added: Support auto-templates for taxonomies, users and comments. #3962 & #5832 (@JoryHogeveen, @sc0ttkclark, @gwhitney)
105
+ * Added: Support template parameter and nested shortcode content for field shortcodes. #5801 (@JoryHogeveen)
106
+ * Added: Allow function calls in all tags, not just template tags. #4887 (@JoryHogeveen)
107
+ * Added: Support custom image sizes for all image field types in magic tags. #5870 (@JoryHogeveen)
108
+ * Added/Fixed: Support special magic tags in Pods Templates. #5697 (@JoryHogeveen)
109
+ * Added/Fixed: Support Pod related magic tags in shortcode query parameters. #5734 (@JoryHogeveen)
110
+ * Enhancement: Allow traversing in avatar attachment. #5870 (@JoryHogeveen)
111
+ * Enhancement: If the media Pod exists, use it's context to run media loops to support other fields and traversal. #5855 (@JoryHogeveen)
112
+ * Enhancement: Implement PHP 5.4 `session_status()` function. #5840 (@JoryHogeveen)
113
+ * Enhancement: Allow WP objects to be passed in `pods()`. #5845 (@JoryHogeveen)
114
+ * Compatibility: Enqueue DFV scripts when editing the page with Beaver Builder to fully support the media window. #5799 (@JoryHogeveen)
115
+ * Updated: Primary Branch header for GitHub Updater. #5847 (@afragen)
116
+
117
+ **Bug Fixes**
118
+
119
+ * Fixed: `.src` tags for PDF's now render the PDF file link instead of the thumbnail in templates `[each]` loops. #4040 (@JoryHogeveen)
120
+ * Fixed. HTML entities for relationship fields UI. #5843, #5835 & #5796 (@JoryHogeveen, @sc0ttkclark)
121
+ * Fixed: Select2/SelectWoo now also enqueue the locale files when available. #5860 (@JoryHogeveen)
122
+ * Fixed: Support lowercase ID's for magic tags in media loops #5852 (@JoryHogeveen, @sc0ttkclark)
123
+ * Fixed: Avatar should always return a square image. #2738 (@JoryHogeveen)
124
+ * Fixed: Selected items query for autocomplete relationships. #5542 & #5831 (@JoryHogeveen)
125
+ * Fixed: Prevent SQL errors on magic tags in some cases. #5797 (@JoryHogeveen, @sc0ttkclark)
126
+ * Fixed: Error if there is no DB prefix available. #5803 (@JoryHogeveen, @sc0ttkclark)
127
+ * Fixed: Fix edge case "No Access" error when all Pods were deleted. Redirect to next Pod admin page if needed. #4842 (@JoryHogeveen)
128
+ * Fixed: Removed empty filter in `ui/admin/setup-edit-field.php`. #5686 (@sc0ttkclark, @JoryHogeveen)
129
+ * Fixed: Prevent possible notice if image doesn't exist. #5866 (@JoryHogeveen)
130
+ * Fixed: Remove source maps from production builds. #5822 (@sc0ttkclark)
131
+ * Fixed: PHP warning in file field gallery view. #5809 (@JoryHogeveen)
132
+
133
+ = 2.7.22 - August 13th 2020 =
134
+
135
+ **Bug Fixes**
136
+
137
+ * Fixed: WP 5.5+ compatibility layer for postbox headers so they appear and work correctly while still working for previous versions of WordPress. #5806 (@sc0ttkclark)
138
+ * Fixed: Patched a Freemius JS file that needed updating for WP 5.5+ compatibility. #5806 (@sc0ttkclark)
139
+ * Fixed: Prevent fatal errors about memory when using preview links for Advanced Content Types. #5783 (@JoryHogeveen)
140
+ * Fixed: Prevent fatal errors about memory when using certain magic tag / thumbnail combinations. #5805 (@JoryHogeveen)
141
+ * Fixed: Resolve our DFV JS `<div>` issues with `PodsUI` filters and add `.toggle-row` class handling for frontend. #5806 (@sc0ttkclark)
142
+ * Fixed: Ensure REST API responses for Media returns correct value when extended by Pods. #5763 (@JoryHogeveen)
143
+ * Fixed: Ensure pods_permission() unserializes when role/capability data is serialized. #5768 (@JoryHogeveen)
144
+
145
+ = 2.7.21 - June 30th 2020 =
146
+
147
+ **New Features & Enhancements**
148
+
149
+ * Added: New filter: `pods_field_pick_object_data_params`. #5756 (@JoryHogeveen)
150
+ * Added: Pods fields & magic tags: Traverse through serialized metadata. #5603 (@JoryHogeveen)
151
+ * Added: Support `get_query_var()` in pods_v (and thus special magic tags: `{@query.##}`). #5719 (@JoryHogeveen)
152
+ * Added: WYSIWYG field option for custom editor height. #5673 (@JoryHogeveen)
153
+ * Enhancement: REST field options: Only display depth for array response type. #5714 (@JoryHogeveen)
154
+ * Updated: Refactor Pods::field() method. #5682 (@JoryHogeveen)
155
+
156
+ **Bug Fixes**
157
+
158
+ * Fixed: Relationship dropdown error & encoding. #5740 (@JoryHogeveen)
159
+ * Fixed: Getting single vs multiple metadata values edge case errors. #5661 (@JoryHogeveen)
160
+ * Fixed: Nested relationship fields should render as array of objects in REST. #5745 (@lkraav)
161
+ * Fixed: Add `noopener` and `noreferrer` for all target `_blank` links. #5742 (@JoryHogeveen)
162
+ * Fixed: Only check `delete_users` for single installations in `pods_is_admin()`. #5712 (@JoryHogeveen)
163
+ * Fixed: Deprecated taxonomy form actions. #5700 (@JoryHogeveen)
164
+ * Fixed: DateTime field: Allow input values compatible with the display format. #5687 (@JoryHogeveen)
165
+ * Fixed: Whitespace trimming for templates. #5672 (@sc0ttkclark)
166
+ * Fixed: Taxonomy option rewrite with front label tooltip. #5681 (@JoryHogeveen)
167
+ * Fixed: Pods test factory compatibility with WP core text factory. #5716 (@JoryHogeveen)
168
+
169
+ = 2.7.20.1 - June 4th 2020 =
170
+
171
+ * Security: Remove deprecated usage of escapeMarkup in selectWoo and tighten JS rendering (@sc0ttkclark, @miha.jirov)
172
+
173
+ = 2.7.20 - April 5th 2020 =
174
+
175
+ **Bug Fixes**
176
+
177
+ * Fixed: Resolved issues with Freemius notices not being able to be properly dismissed. (@sc0ttkclark)
178
+
179
+ = 2.7.19 - April 5th 2020 =
180
+
181
+ This version was bugged due to a deployment that sent out a copy of 2.7.18 as 2.7.19.
182
+
183
+ = 2.7.18 - April 3rd 2020 =
184
+
185
+ **New Features & Enhancements**
186
+
187
+ * Added: Add is_required() helper method for fields objects to abstract some logic. #5657 (@JoryHogeveen)
188
+ * Updated: Removed duplicate code from pods_list_filter() that is now in wp_list_filter(). #5644 (@JoryHogeveen)
189
+ * Updated: Now prefixing the Templates and Pages component menu items with "Pod" so they aren't as easily confused with normal WordPress menu items. #5647 (@JoryHogeveen)
190
+
191
+ **Bug Fixes**
192
+
193
+ * Fixed: Compatibility layer for ACF so it won't conflict anymore. #5667 (@sc0ttkclark)
194
+ * Fixed: Remove PHP 5.6+ only code that was causing issues for those running older PHP versions. #5659 (@JoryHogeveen)
195
+ * Fixed: Prevent PHP errors when enforcing numeric values during validation of number fields. #5666 (@JoryHogeveen)
196
+ * Fixed: Prevent deprecated warnings with special magic tags usage like `{@user.id}` instead of `{@user.ID}`. #5642 (@JoryHogeveen)
197
+ * Fixed: Fix the decimal/thousands separator logic used for number and currency field validation and saving. #5653 (@JoryHogeveen)
198
+ * Fixed: Resolve issues with `[if]` and `[else]` logic for boolean fields that was causing it to always evaluate to true. #5656 (@JoryHogeveen)
199
+ * Fixed: Only load Freemius on Pods Admin, Plugins, or the Updates screens. (@sc0ttkclark)
200
+
201
+ = 2.7.17.1 - March 27th 2020 =
202
+
203
+ **Bug Fixes**
204
+
205
+ * Fixed: Double comma in custom pick display formats. #5637 (@JoryHogeveen)
206
+ * Fixed: Auto `use_current` not working correctly outside the loop. #5636 (@JoryHogeveen)
207
+ * Fixed: pods_trim() does not trim whitespaces by default. #5640 (@JoryHogeveen)
208
+
209
+ = 2.7.17 - March 26th 2020 =
210
+
211
+ **New Features & Enhancements**
212
+
213
+ * Added: New callout for our Friends of Pods program will show up on the Pods Admin > Pods list so we can let people know how to donate. #5571 (@nicdford, @sc0ttkclark, @JoryHogeveen)
214
+ * Added: Freemius integration to support our new Friends of Pods add-ons and enable us to let people opt-in to usage stats for planning future compatibility decisions. #5624 (@sc0ttkclark)
215
+ * Added: New `not_found` tag to the Pods shortcode to return default string if no output is empty. #5580 (@JoryHogeveen)
216
+ * Added: New hooks when saving field table definitions (table-based Pods). #5623 (@sc0ttkclark)
217
+ * Added: New custom multi-relationship display format. #5612 (@JoryHogeveen)
218
+ * Added: Support traversing into post thumbnails objects. #5610 (@JoryHogeveen)
219
+ * Compatibility: Add ACF backwards compatibility functions/shortcode. #4855 (@sc0ttkclark)
220
+ * Compatibility: WordPress 5.4 - Add user Pod fields to privacy export data. #5606 (@JoryHogeveen)
221
+ * Compatibility: Match WordPress 5.4 CSS changes. #5608 (@JoryHogeveen)
222
+ * Enhancement: Shortcodes now automatically revert to the current queried object. #5598 (@JoryHogeveen)
223
+ * Enhancement: Add "full" to available image sizes. #5185 (@JoryHogeveen)
224
+ * Enhancement: Set Pods current queried object detection based on class instances instead of class parameters. #5617 (@JoryHogeveen)
225
+ * Docs: Update inline docs for pick field selected logic. #5014 & #5017 (@sc0ttkclark)
226
+
227
+ **Bug Fixes**
228
+
229
+ * Fixed: Date/Time - Correct empty value validation. #5534 & #5544 (@JoryHogeveen)
230
+ * Fixed: Date/Time - Allow midnight (00:00:00) as time value. #5616 (@JoryHogeveen)
231
+ * Fixed: Number/Currency - Parsing error for number format 9'999.99. #5559 & #5597 (@JoryHogeveen)
232
+ * Fixed: Number/Currency - Do not set default value of `0` if field is empty. #5539 (@JoryHogeveen)
233
+ * Fixed: CLI export/export-item commands. #5041 (@0xLBF)
234
+ * Fixed: Allow No (0) as an answer for radio and select boolean fields. #5549 (@JoryHogeveen)
235
+ * Fixed: Prevent get_meta() cache loop. #5577 (@JoryHogeveen)
236
+ * Fixed: Pods component descriptions. #5543 (@JoryHogeveen)
237
+ * Fixed: PHP 7.4 - Array and string offset access syntax with curly braces is deprecated. #5582 (@JoryHogeveen)
238
+ * Fixed: PHP 7.4 - Trying to access array offset on value of type bool. #5556 & #5615 (@JoryHogeveen)
239
+ * Fixed: PHP 7.4 - Array access notices. #5631 (@JoryHogeveen)
240
+ * Fixed: Replaced hook used for meta boxes in admin for custom component integrations to avoid deprecated notices from WordPress. #5622 (@sc0ttkclark)
241
+ * Fixed: Prevented potential fatal errors on Pod Template editor screen when pod configuration is broken. #5622 (@sc0ttkclark)
242
+ * Docs: Link to Gallery Documentation in Image field inline help doc. #5541 (@wpacademy)
243
+
244
+ = 2.7.16.2 - November 14th 2019 =
245
+
246
+ * Fixed: The last SVN tag was temporarily missing files, this release just ensures people get the update that has all files.
247
+
248
+ = 2.7.16.1 - November 13th 2019 =
249
+
250
+ * Fixed: Reverted changes in #5289 to auto templates that introduced breaking changes. We will revisit this in a future maintenance release. #5531
251
+
252
+ = 2.7.16 - November 13th 2019 =
253
+
254
+ **Enhancements**
255
+
256
+ * Enhancement: CSS fixes for WP 5.3. #5501 (@JoryHogeveen)
257
+ * Enhancement: Format traversed fields properly. #4932 (@jamesgol)
258
+ * Enhancement: ACT list view pagination. #5510 (@JoryHogeveen)
259
+ * Enhancement: Add PODS_SHORTCODE_ALLOW_EVALUATE_TAGS to debug info. #5310 (@JoryHogeveen)
260
+
261
+ **Bug Fixes**
262
+
263
+ * Fixed: Avoid SQL errors when using special magic tags. #5310 (@sc0ttkclark)
264
+ * Fixed: Validate shortcode query tags before default to current object. #5520 (@JoryHogeveen)
265
+ * Fixed: Unslash simple relationship values to support saving quoted values. #5517 (@JoryHogeveen)
266
+ * Fixed: Add sanitize_title optional to sluggables instead of applying default. #5516 (@JoryHogeveen)
267
+ * Fixed: DateTime: Always parse any manual input data. Also fixes clearing values. #5488 (@JoryHogeveen)
268
+ * Fixed: DateTime: jQuery date & time picker overlapping formats. #5467 (@JoryHogeveen)
269
+ * Fixed: DateTime: Fix datetime-local HTML5 input format. #5460 (@JoryHogeveen)
270
+ * Fixed: Could not submit a form if required checkbox not ticked. #5481 (@Turkal)
271
+ * Fixed: Allow migrate packages to import pages. #5476 (@jamesgol)
272
+ * Fixed: Allow pods_str_replace() function to handle non-strings. #5254 (@jamesgol)
273
+ * Fixed: Refactor and fix issues with Advanced Content Types capabilities. #5504 (@JoryHogeveen)
274
+ * Fixed: Add `object` key to prevent undefined index notice. #5493 (@JoryHogeveen)
275
+ * Fixed: Make sure number of arguments passed to PodsMeta->save_post() is correct. #5512 (@jamesgol)
276
+ * Fixed: ACT pagination URL for child type. #5510 (@JoryHogeveen)
277
+ * Fixed: Custom table relationships SQL error. #5505 (@JoryHogeveen)
278
+ * Fixed: Allow Pods to ALTER table if the SQL field definition has changed. #5507 (@jamesgol)
279
+ * Fixed: Admin menu: set hook priority to 9 instead of 99 to fix CPT submenu placement. #5497 (@JoryHogeveen)
280
+ * Fixed: Make auto templates for a Taxonomy Pod behave sensibly. #5289 (@gwhitney, @sc0ttkclark, @JoryHogeveen)
281
+
282
+ = 2.7.15 - September 5th 2019 =
283
+
284
+ **Enhancements**
285
+
286
+ * Enhancement: Add year range option to date & datetime fields. #5442 (@JoryHogeveen)
287
+ * Enhancement: Support single select relationships in templates when using `[each]`. #4507 (@sc0ttkclark, @JoryHogeveen)
288
+ * Enhancement: Prevent creation of Pods using reserved keywords from WordPress Codex and Pods. #5428 (@JoryHogeveen)
289
+ * Enhancement: Allow all callables to be passed in magic tags. #5436 (@JoryHogeveen)
290
+
291
+ **Bug Fixes**
292
+
293
+ * Fixed: Always convert database value for date/time fields without timezone to maintain the actual value. #5423 & #5424 (@JoryHogeveen)
294
+ * Fixed: Solve issues with saving date/time fields in other locales. #5444, #5421, #5415 & #5451 (@JoryHogeveen)
295
+ * Fixed: Import from file with absolute path. #5430 (@mistraloz)
296
+ * Fixed: Fix numeric soft format issue removing decimals & numeric slider input formatting. #5281 & #5215 (@JoryHogeveen)
297
+ * Fixed: Fix & improve error handling & debug logs. #5452, #5450, #5440, #5419, #5435 & #5453 (@JoryHogeveen)
298
+ * Fixed: Corrected Malaysian Ringgit currency sign. #5446 (@JoryHogeveen)
299
+ * Fixed: Flush Pod cache before returning errors, #5420 (@JoryHogeveen)
300
+
301
+ = 2.7.14 - July 9th 2019 =
302
+
303
+ **Bug Fixes**
304
+
305
+ * Fixed: Always convert database value for date/time fields with UTC timezone to maintain the actual value, #5382, #5402, #5403 (@JoryHogeveen)
306
+ * Fixed: Stop add new button from being disabled when no selection has been made yet for single select, #5401 (@pglewis)
307
+ * Fixed: Resolved PHP notices in `PodsAPI::save_pod_item()`, #5411 (@pglewis)
308
+
309
+ = 2.7.13 - June 28th 2019 =
310
+
311
+ **Enhancements**
312
+
313
+ * Enhancement: Support meta fields as display field for relationships, #5299 (@sc0ttkclark)
314
+ * Enhancement: DateTime/Time field code and performance #5302 (@JoryHogeveen)
315
+ * Enhancement: Added Nigerian Naira currency, #5377 (@webcreativeng)
316
+ * Enhancement: Added filter `pods_enqueue_dfv_on_front` for enqueueing DFV scripts on frontend, #5313 & #5303 (@nicdford)
317
+ * Added: Add debug information for Pods to Site Health Info area, #5399 (@sc0ttclark, @JoryHogeveen)
318
+
319
+ **Bug Fixes**
320
+
321
+ * Fixed: Cursor is jumping to the start of the block when Gutenberg autosaves, #5274 (@pglewis)
322
+ * Fixed: Select drop-downs set to required, #5031 (@pglewis)
323
+ * Fixed: HTML escaping issue in the Manage Fields list, #5246 (@pglewis)
324
+ * Fixed: Translate Pods stuck with Portuguese translation in the Admin menus, #5259 (@JoryHogeveen)
325
+ * Fixed: option cache handling when using external object cache, #5294 (@sc0ttkclark)
326
+ * Fixed: Fix force WWW option on website/URL fields, #4881 (@pglewis)
327
+ * Fixed: Phone field should not put anything in the field input on 'blank' values, #4881 (@pglewis)
328
+ * Fixed: Versioned tag names are not compatible with Composer, #5278 (@pglewis)
329
+ * Fixed: `get_post_meta()` always retriggers `pods_transient_set()`, #4690 (@pglewis)
330
+ * Fixed: Date output in magic tags for date fields uses DateTime class by default instead of date_il8n, #5296 (@JoryHogeveen)
331
+ * Fixed: PHP 7.3 `compact()` notices due to undefined var names, #5266 (@sc0ttkclark)
332
+ * Fixed: Use `Marionette.noConflict()` to keep a private copy of Marionette, #5237 & #5354 (@pglewis)
333
+ * Fixed: Remove floats from fields within pods manage fields (UI), #5362 (@nicdford)
334
+ * Fixed: Set table charset for Pods Advanced Content Types to WP default charset, #5276 (@JoryHogeveen)
335
+ * Fixed: Avoid PHP warnings by removing unused $check_value logic in PodsField_Pick, #5205 (@ziqbal, @JoryHogeveen)
336
+ * Fixed: Fix PodsData fetch for when using object cache and settings pages, #4960 (@pcfreak30, @sc0ttclark, @JoryHogeveen)
337
+ * Fixed: Moved session_id() check outside the big conditional so it's always executed, #5182 (@mastef)
338
+ * Fixed: Change deprecated (since WP 5.1) hook `wpmu_new_blog` to `wp_insert_site` with backwards compatibility, #5369 (@JoryHogeveen)
339
+ * Fixed: Error when PodsInit isn't available on network pages, #3353 (@JoryHogeveen)
340
+ * Fixed: Shortcodes no longer stop the page from loading when they encounter SQL errors, #5279 (@sc0ttclark, @JoryHogeveen)
341
+
342
+ = 2.7.12 - December 20th 2018 =
343
+
344
+ **Enhancements**
345
+
346
+ * Enhancement: Sort currency list alphabetically by name, add Indonesian Rupiah (Rp) and US Cent currency support, #5247 (@sc0ttkclark)
347
+
348
+ **Bug Fixes**
349
+
350
+ Fixed: Serial comma display works again for Users, Comments, and Media relationships when used in Pods::display() and magic tag templating without specifying the object field you want to display, #5251 (@sc0ttkclark)
351
+
352
+ = 2.7.11 - December 7th 2018 =
353
+
354
+ **Enhancements**
355
+
356
+ * Enhancement: Added: New pods_data_auto_calculate_total_found filter can be set to true to auto-calculate total_found() number right away after a Pods::find() query runs, defaults to false, #5232, (@sc0ttkclark)
357
+
358
+ **Bug Fixes**
359
+
360
+ * Fixed: Javascript errors on pages without the Gutenberg editor active under certain circumstances, #5225 (@pglewis)
361
+ * Fixed: Avoid extra user queries when not necessary, #5230 (@sc0ttkclark)
362
+
363
+ = 2.7.10 - December 5th 2018 =
364
+
365
+ **Gutenberg / WordPress 5.0 Compatibility**
366
+
367
+ * Fixed: TinyMCE Compatibility Bug for Gutenberg, #5217 (@pglewis)
368
+ * Fixed: Read-only Checkboxes now properly save values as 0 or 1, #4961 (@atanas-angelov-dev)
369
+ * Fixed: Scrollbar Compatibility bug for List View in Gutenberg Editor, #5220 (@pglewis)
370
+ * Fixed: Modal Support for Gutenberg, Add/edit Modal now triggers save and close to the modal, #5191 (@pglewis)
371
+ * Fixed: Component header parsing for developer/tableless mode, #5222 (@sc0ttkclark)
372
+ * Fixed: Currency symbol no longer overlays input field in WP 5.0, #5219 (@pglewis, @sc0ttkclark)
373
+
374
+ **Enhancements**
375
+
376
+ * Enhancement: Added support for new WP 5.0 custom post type labels used by Gutenberg, #5223 (@wpstudio, @sc0ttkclark)
377
+ * Enhancement: Add pods conditional logic handling on frontend forms, #5136 (@JoryHogeveen)
378
+ * Enhancement: Add current memory usage to stats, #5178 (@sc0ttkclark)
379
+ * Enhancement: Add support for Taxonomy descriptions, #4766 (@sc0ttkclark)
380
+ * Enhancement: Component Pages does not allow adding page templates in plugins, #4734 (@creabrain)
381
+ * Enhancement: Add Pods functions to Query Monitor conditional, #5208 (@JoryHogeveen)
382
+ * Enhancement: Add bi-directional status label to relationship fields, #5200 (@JoryHogeveen)
383
+ * Enhancement: Removed old forum feed, inserted the wordpress.org feed, and squelched warnings from SimplePie/PHP 7+, #5172, #4363 (@pglewis)
384
+
385
+ **Bug Fixes**
386
+
387
+ * Fixed: pods->save() does not clear fields with shorthand syntax, #5166 (@mastef)
388
+ * Fixed: Comma character breaks custom post type dropdown, #2042 (@sc0ttkclark)
389
+ * Fixed: Compatibility with Admin Columns 3.2+, #5129 (@JoryHogeveen, @DGStefan)
390
+ * Fixed: Missing Styles of DFV form field using $pods->form, #5056 (@pglewis)
391
+ * Fixed: "Single Select" Relationship Return differently depending on Format, #5138 (@pglewis)
392
+ * Fixed: Media modal doesn't work on frontend using pods form, #4715 (@pglewis)
393
+ * Fixed: Use minified versions of Backbone.Marionette and Backbone.Radio, #5115
394
+ * Fixed: Always enqueue the DFV script by default if in the admin, #5111 (@pglewis, @sc0ttkclark)
395
+ * Fixed: Add static groups cache for PodsMeta::groups_get() to improve memory usage on bulk wp_insert_post and other similar calls, #5088 (@sc0ttkclark)
396
+ * Fixed: Only disable components when using PODS_TABLELESS if the component is relying on custom tables, #5206 (@JoryHogeveen)
397
+ * Fixed: PHP Warning for array key pods_rel not found, #5210 (@JoryHogeveen)
398
+
399
+ = 2.7.9 - August 9th 2018 =
400
+
401
+ **Features/Enhancements**
402
+
403
+ * Added: Support for Pods::fields() argument keyed which when set to true will return the array for relationship fields with the IDs used as keys, #5092 (@sc0ttkclark)
404
+ * Added: pods_shortcode_output filter to allow customization of shortcode output based on shortcode attributes, #5083 (@sc0ttkclark)
405
+
406
+ **Bug Fixes**
407
+
408
+ * Fixed: Fix compatibility issue with Polylang & WPML when getting the current language from the edit post and edit tax pages. #5060 (JoryHogeveen)
409
+
410
+ = 2.7.8 - July 26th 2018 =
411
+
412
+ * Hotfix: Time field generates a fatal error on PHP prior to 5.5, #5079 (@davegaeddert)
413
+
414
+ = 2.7.7 - July 26th 2018 =
415
+
416
+ **Features/Enhancements/Improvements**
417
+
418
+ * Code Quality: Disallow multiple assignments and assignment inside conditions, #5021 (@GaryJones)
419
+ * Code Quality: WordPress.WhiteSpace.PrecisionAlignment compliance, #5026 (@GaryJones)
420
+ * Code Quality: Use interpolation to construct all dynamic hook names, #4992 (@GaryJones)
421
+
422
+ **Bug Fixes**
423
+
424
+ * Fixed: 'others' capability checks for current_user_can pods_{$action}{$pod} vs pods{$action}others{$pod} capabilities, #5043 (@Ulminia, @sc0ttkclark)
425
+ * Fixed: "Export all" button for ACTs does not work, #5005 (@pglewis)
426
+ * Fixed: Pods Template Editor is adding two 'tabs' to the front of the template during Save. #5022 (@pglewis)
427
+ * Fixed: Midnight (00:00) results as 'empty' in an [if][/if] Template Tag. #4999 (@pglewis)
428
+ * Fixed: Non-internationalized string "Add Another Custom Capability". #5028 (@GaryJones, @pglewis)
429
+
430
+ = 2.7.6 - June 8th 2018 =
431
+
432
+ * Fixed: Records added modally via DFV's 'Add New' are not selected and don't refresh list view in 2.7.5, #5014 (@sc0ttkclark, @pglewis)
433
+
434
+ = 2.7.5 - June 7th 2018 =
435
+
436
+ **Bug Fixes**
437
+
438
+ * Fixed: Only flush rewrite rules in an admin context, #5006 (@sc0ttkclark)
439
+ * Fixed: SelectWoo fields would sometimes call `focus()` inappropriately #4725 (@GaryJones)
440
+
441
+ = 2.7.4 - June 6th 2018 =
442
+
443
+ **Features/Enhancements**
444
+
445
+ * Code Quality: Address some i18n code standard violations, #4982 (@GaryJones)
446
+ * Code Quality: All @since and @deprecated tags updated to use three digits everywhere, #4995 (@GaryJones)
447
+ * Added: Tooltip for the Hierarchical option for taxonomies, #4949 (@pglewis)
448
+
449
+ **Bug Fixes**
450
+
451
+ * Fixed: jQuery.fn.size() is deprecated #3898 (@GaryJones)
452
+ * Fixed: CLI: Fix missing negation on valid & exists checks #4989 (@GaryJones)
453
+ * Fixed: Check for localized 'help' before adding tooltip #4614 (@davidatwhieltrue, @GaryJones)
454
+ * Fixed: Autocomplete/List View broken with "Other WP Objects", #4504 (@pglewis, @sc0ttkclark)
455
+ * Fixed: HTML entities in a field's description are converted when the Pod is loaded again, #4495 (@pglewis)
456
+ * Fixed: Relationship fields related to the _pods_pod or _pods_field post type would not return the correct value, #4979 (@sc0ttkclark)
457
+ * Fixed: Code Editor for Pods Template double-escapes HTML when Visual Editor is OFF in WordPress, #3462 (@pglewis)
458
+ * Fixed: Pods breaks Theme Editor for PHP files, hangs loopback test #4595, #4931 (@jamesgol, @pglewis)
459
+ * Fixed: Time field cannot save midnight #3488, #4937 (@pglewis)
460
+ * Fixed: Resolve file uploads directory check logic for file exports #4970 (@elia-senatore-cippest, @sc0ttkclark)
461
+ * Fixed: Media modal issues in post edits, #4945, #4967 (@pglewis)
462
+ * Fixed: Fatal error if not logged in and accessing wp-admin, #4828 (@therealgilles)
463
+ * Fixed: Pick fields with predefined/custom lists using numeric keys not loading values #4892, #4753 (@pglewis)
464
+ * Fixed: Non-required color-picker field did not allow saving empty value #4919 (@JoryHogeveen)
465
+ * Fixed: CodeMirror fields in Taxonomy and User edit forms #4913 (@pglewis)
466
+
467
+ = 2.7.3 - May 6th 2018 =
468
+
469
+ **Bug Fixes**
470
+
471
+ * Fixed: 'search' param for Pods shortcodes #4909 (@pglewis)
472
+ * Fixed: 'before_content' and 'after_content' were ignored in widgets #4891 (@pglewis)
473
+
474
+ = 2.7.2.1 - May 5th 2018 =
475
+
476
+ **Developer and deployment enhancements**
477
+
478
+ * Added: .editorconfig file [http://editorconfig.org/](http://editorconfig.org/) #4571 (@JoryHogeveen)
479
+ * Updated: export-ignore list #4898 (@pglewis)
480
+
481
+ **Bug Fixes**
482
+
483
+ * Fixed: Pods Widget output #4891 (@pglewis)
484
+ * Fixed: Slider controls not showing #4895 (@pglewis)
485
+ * Fixed: Fatal exception attempting to parse Persian DateTime strings #4896 (@sc0ttkclark)
486
+ * Fixed: Array to string conversion notice in Pods form #4886 (@sc0ttkclark)
487
+
488
+ = 2.7.2 - May 3rd 2018 =
489
+
490
+ **New Features Added**
491
+
492
+ * Added WP-CLI commands for Pods, more details at [https://docs.pods.io/advanced-topics/pods-wp-cli/](https://docs.pods.io/advanced-topics/pods-wp-cli/) (@sc0ttkclark)
493
+ * Added: Filter HTML class for li.pods-field form element to allow for more styling options. #4813 (@paddelboot)
494
+ * Added: Currency field enhancement: Add a currency sign before the field input. #4714 (@JoryHogeveen)
495
+ * Added: Currency formats with spacing between currency sign and value #4838 (@JoryHogeveen)
496
+
497
+ **Bug Fixes & Corrections**
498
+
499
+ * Fixed: Missing thickbox styles for `PodsUI::filters()` #4797 Fixes #4693 which was preventing Advanced Content Type Filters Popup from Loading (@pglewis)
500
+ * Fixed: Text field readonly no longer defaults to `true` #4794 Fixes #4791 (@pglewis)
501
+ * Fixed: Simplify how we inject the PHP string into the JS #4787 Fixes #4786 which was creating syntax error in JS for number fields (@pglewis)
502
+ * Fixed: Tooltips were not working in the Pods Templates or Roles and Capabilities components #4851 (Fixes #4850) (@pglewis)
503
+ * Fixed: Isolates qtip styles and functionality to pods only which should hopefully resolve any issues with conflicting with other plugins/themes that may use the tooltip functionality [#4834] Fixes #4832 where tooltips were not displaying (@nicdford)
504
+ * Fixed: Tooltip corrections: Update Pods Add New screen for extended taxonomies as Table Storage is not required since Term Meta was added by WordPress. #4609 (@pglewis)
505
+ * Fixed: Issue where fields with particularly long post titles would extend past the width of the container #4831( Fixes #4700) (@nicdford)
506
+ * Added: appropriate CSS namespace prefixes to avoid style conflicts #4632 (#4612) (@nicdford)
507
+ * Fixed: Prefix all form styles with `form.pods-manage`. Namespace prefix all pods-manage styles to avoid CSS conflicts with Gravity forms (#4615,#4612) (@JoryHogeveen)
508
+ * Fixed: Pods DFV fields no longer depend upon the specific instance of jQuery shipped with WordPress (#4680). (@pglewis)
509
+ * Fixed: Update all storage type tooltips. Many were still referencing old Custom Taxonomy Table Storage requirements that were no longer required after Term Meta support. Fixes #4835 (@pglewis)
510
+ * Fixed: Bug with decimal handler when converting to dash (-) #4829 (@JoryHogeveen)
511
+ * Fixed: Checkbox misalignment on custom settings pages (#4711) (@JoryHogeveen)
512
+ * Fixed: Quality of life visual updates and optimizations for the CLEditor (#4633) (@nicdford)
513
+ * Fixed: `%F` with PHP's `sprintf` function defaults to a precision of 6 decimal places, we now include the precision specifier whenever more than 6 decimal places of precision is needed. (#4741) (@0xLBF)
514
+ * Fixed: Extend the condition for WPML validation exception to cover the Translation Editor so required fields don't break the Translation Editor in WPML. (#4802) (@dgwatkins)
515
+ * Fixed: Corrects most relationship fields on media items when editing in grid mode. Select2 based fields still need a workaround (Autocomplete, List View). (#4795) (@pglewis)
516
+ * Fixed: Avoid printing null message in PodsUI #4796 (@davidatwhiletrue)
517
+ * Fixed: Single-select Post Thumbnail does not display in Pods Template traversal. Allow traversing into post_thumbnail. (#4719) (@jamesgol)
518
+ * Fixed: Disable the "Add New" button for relationships when we're inside a media modal window (#4864). This is just a workaround until we can iron out the CSS and display for a modal from a modal. (@pglewis)
519
+ * Fixed: Autotemplate hook validation to verify filter before applying Auto Templates (#4695) (@JoryHogeveen)
520
+ * Fixed: Allow user-meta (and other extended Pods) to work in templates (#4847) (@jamesgol)
521
+ * Fixed: Corrected conflicts with container CSS/JS around Date/Time Fields (#4878) (@pglewis,@nicdford)
522
+
523
+ **Fixes for Unit Testing and Workflow**
524
+
525
+ * Fixed: Skip npm install and js tests on the PHP 5.3/Precise box to fix #4788 (#4789) (@pglewis)
526
+ * Fixed: mockery 1.0 requires php >=5.6.0; downgrade to 0.9 for now #4818 @pglewis
527
+ * Fixed: PHP Codesniffer Fixes #4569 (@sc0ttkclark)
528
+ * Fixed: eslint rules and formatting for Javascript (DFV only) #4590 (@sc0ttkclark)
529
+
530
+ = 2.7.1 - December 8th 2017 =
531
+
532
+ * Fix table join logic for taxonomies when renaming meta fields #4613 @sc0ttkclark
533
+ * Fix Pods Form submit errors and 404s #4618 @pglewis
534
+ * Fix dashicons style conflicts with Pods Form #4626 @nicdford
535
+ * Roll-back minimum version requirement for MySQL from 5.5 to 5.1 #4634 @sc0ttkclark
536
+
537
+ = 2.7 - December 4th 2017 =
538
+
539
+ **New PHP & WP Minimum Version Requirements:**
540
+
541
+ * PHP Version Change Requirement 5.3+
542
+ * WP Version Change Required 4.5+
543
+
544
+ **Major Changes in 2.7 Release: Flexible Relationships:**
545
+
546
+ * New Relationship Field Format "List View": The power of the new flexible relationships is our new modal window that opens within the existing record for relationship fields. This is modeled after the Media Modal from WordPress and provides full functionality to Add New related records or edit existing records all from within the parent record of the relationship. This is provided through our new List View field format for relationship fields. To see a demo of this field in action [head on over to our YouTube](https://youtu.be/V8c067GAEcA)
547
+ * Add New with Flexible Relationships: The new flexible relationships will automatically enable Add New on all your existing relationships, but you can disable this from the Additional Options tab for each relationship field. You can switch field formats to the new List View from additional options tab as well.
548
+ * Dynamic Field Views: The relationship fields and file upload fields have been rewritten to take advantage of "Dynamic Field Views", driven by JavaScript. More technical details about the directions we went towards these field changes can be read about in our ["Pods 2.7: What We Did and Why We Did It"](https://pods.io/2017/12/05/pods-2-7-developer-notes/)
549
+
550
+ **Significant Improvements and Fixes:**
551
+
552
+ * Enhancements for Date, Time & Date/Time Fields to improve class inheritance, use WP Defaults and allow for custom options for saving and display @JoryHOgeveen
553
+ * Gallery & Tile View for Upload/Media Fields #3589 @JoryHogeveen
554
+ * IsEmpty for all Date/Time Fields, Number, Currency, etc. improvements for `[if field][/if]` for Templates @JoryHogeveen
555
+ * Major fixes for Pods Templates: Proper handling of shortcodes within Pods Templates and in if/each blocks. Proper handling of all image tags and user traversal @jamesgol
556
+ * Comment Traversal #4118 @sc0ttkclark
557
+ * Update Compatibility with Admin Columns 3.0+ #4570 @JoryHogeveen
558
+ * Filter Added for Select2 Overrides #4571 @sc0ttkclark
559
+ * Fix for Advanced Content Types and Relationships in `[each][/each]` tags correcting for lowercase id. #4585 @0xLBF
560
+
561
+ **Behind the Scenes Fixes and Improvements:**
562
+
563
+ * js unit tests #3640, #4049 @pglewis
564
+ * pods_ui_get_params hook #3785 @telwing
565
+ * table storage list fields #4420 @jamesgol
566
+ * Refactor CSS @nicdford
567
+ * Built with Node @pglewis
568
+ * Pods Templates added for Polylang Translation Compatibility @JoryHogeveen
569
+ * SelectWoo migration from Select2 to address version incompatibilities #4546 @pglewis
570
+
571
+ **Known Issues with this Release:**
572
+
573
+ * Relationships to Taxonomy have Flexible Relationships disabled as the input screen for Taxonomy was not able to be accessed in an iFrame. We’re working on this for a future release.
574
+
575
+ = 2.6.11.2 - August 4th, 2021 =
576
+ * Security: Clean up post type and taxonomy labels so they avoid potential output escaping problems in WordPress core (@sc0ttkclark, reported by Muhammad Daffa via WPScan)
577
+
578
+ = 2.6.11.1 - June 4th, 2020 =
579
+ * Security: Remove deprecated usage of escapeMarkup in Select2 (@sc0ttkclark, @miha.jirov)
580
+
581
+ = 2.6.11 - September 20th 2017 =
582
+ * 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.
583
+ * Stay tuned for Pods 2.7 which will be out soon -- [Download Pods 2.7 RC1](https://github.com/pods-framework/pods/archive/release/2.7.zip) and join our [Pods Slack channel #pods-beta](https://pods.io/chat/) to help us finish the final testing
584
+
585
+ = 2.6.10 - July 14th 2017 =
586
+ * Fixed: Pods Templates were creating erroneous output with nested `[if _fieldname_][else][/if]` and `[each _fieldname_][/each]` template tags inside HTML entities after 2.6.9 upgrade. This fix bypasses `do_shortcode` and also bypasses `do_shortcodes_in_html_tags` which was the problem with this particular fix. Fixes (#4324,#4307,#4307). (#4335). [@pglewis]
587
+ * Fixed: Multi-file fields save was causing array to string conversion warning. New function & helper added called `array_filter_walker` for backwards compatibility. Also fixes the 'editable' titles in Multiple File Upload. Fixes (#4112,#4313). (#4314). [@mgratch,@JoryHogeveen,@sc0ttkclark]
588
+ * Added: Pods Templates & Page Capabilities have been added to the Members Cap Filter and Pods Role Manager from Components, Roles & Capabilities. This corrects an issue where Pods Templates and Pods Pages were not available to Admins, only Network Admins. Admins will still need to have the pods_templates_ and pods_pages_ capabilities added to their role, but now they'll be able to do this without additional code. Fixes (#4311). (#4342). [@JoryHogeveen]
589
+ * Fixed: Corrected 2.x branch for GitHub Feed. Fixes (#4305). (#4306). [@sc0ttkclark]
590
+ * Fixed: Minor Spelling fixes related to i18n. (#4276) [@garrett-eclipse]
591
+ * Updated: Removed CodeClimate Integration (#4275) and updated glob 7.1 (#4242). [@Ramoonus]
592
+
593
+ = 2.6.9 - May 30th 2017 =
594
+ * Added: Pods Template Component is now automatically active on initial installation or reinstallation of Pods. Fixes (#3446). (#4060,#4180). [@pglewis,@sc0ttkclark]
595
+ * Added: Auto Template Fix: Add configurations setting to override and allow Auto Templates to run against the_content outside of the WordPress_Loop. By default now, it will only run inside the WP Loop. (#4088). [@jamesgol]
596
+ * Added: Allow raw value in PodsUI rows. New type "raw" that can output HTML form elements; used in i18n component. Fixes (#3959). (#3960). [@JoryHogeveen]
597
+ * Fixed: Template Reference in Template Editor now properly displays without running out of memory. Fixes (#3370,#3992). (#4088,#4000). [@jamesgol]
598
+ * Fixed: post_author querying now works through traversal of related post type. Fixes (#3931). (#3953,#4065). [@sc0ttkclark,@pglewis]
599
+ * Fixed: Search the proper SQL column with "search" and meta based CPT. Fixes (#3858). (#4007). [@jamesgol]
600
+ * Fixed: Ensure call to pods_view returns shortcode generated content, instead of echo'ing. Fixes (#3433). (#4010) [@dom111]
601
+ * Fixed: Additional CSS Classes were not saved (#4003) so new Duplicating Pod now gives preference to existing field options values on duplication (#4028). [@pglewis]
602
+ * Fixed: duplicate_pod_item now works for WP objects. Fixes (#3238,#4025). (#4070). [@pglewis]
603
+ * Fixed: Hidden field did not save Default Values on fields with both Visibility hidden and a Default Value set. Fixes (#3996). (#4061). [@pglewis]
604
+ * Fixed: Use register_taxonomy_for_object_type for post types that support post formats. Was not originally being registered for Pods CPT. Fixes (#2165). (#4076,#4084). [@sc0ttkclark]
605
+ * Fixed: Help Text for HTML fields wpautop reference. Fixes (#4090,#4091). (#4089). [@JoryHogeveen]
606
+ * Fixed: Corrected Pods overriding preview link for post updated messages. Fixes (#4092). (#4093). [@tuanmh]
607
+ * Fixed: When using shortcodes/magic tags with PDF attachments, ._src returns an image since WP 4.7. This will now output the URL of the file. You can still get PDF generated images using ._src.image_size or ._img. Fixes (#4040). (#4111). [@JoryHogeveen]
608
+ * Fixed: Audio attachments will now work properly with pods_attachment_import. (#4155) [@sc0ttkclark]
609
+ * Fixed: Handling of Single & Double Quotes in post_thumbnail interpolation. Fixes (#4166). (#4167). [@quasel]
610
+ * Fixed: Adding back_link to wp_die() usage which allows Modal Add/Edit to give you a way to go back in the edit screen. Fixes (#4168). (#4169). [@sc0ttkclark]
611
+ * Fixed: Conflict with The Event Calendar issue with Handlebars (as we're using an older implementation). Temporary hack until 2.7 with the correct fix. (#4173). [@sc0ttkclark]
612
+ * Fixed: Missing images in unit test (#4177). [@sc0ttkclark]
613
+ * Fixed: Invalid AJAX error with frontend forms and Settings Pods; $id will always return for AJAX requests. Fixes (#4181). (#4184). [@JoryHogeveen]
614
+ * Fixed: Allow float values for menu positions and the option to remove trailing decimals from number field. Fixes issue where Pods Converted menu positions with decimals to INT on save. Fixes (#2839). (#4192). [@JoryHogeveen]
615
+ * Fixed: Composer: composer installers v1.2 to v1.3. (#4239) [@Ramoonus]
616
+ * Fixed: Editable Titles in Multiple File Upload fields are 'editable' again (broke in 2.6.8) without breaking bidirectional relationship saving. Fixes (#4112) and resolves (#3477,#3720). (#4264). [@sc0ttkclark]
617
+ * Fixed: Spelling error in UI. Fixes (#4266). (#4267). [@danmaby]
618
+ * Updated: Brand assets for Pods (icons and banners) for WordPress Plugin Directory. Fixes (#3948). (#4268) [@jimtrue]
619
+
620
+ = 2.6.8 - January 17th 2017 =
621
+ * Added: WP Gallery display options for image fields. Fixes (#3905). (#3910). [@JoryHogeveen]
622
+ * Added: Add action after successful AJAX in admin_ajax. This allows other scripts to hook in the ajax handlers from Pods. Fixes (#3839). (#3840). [@JoryHogeveen]
623
+ * Added: Keep Plupload instances in `windows.pods_uploader[id]`. This makes it possible to bind event listeners to the file uploader. Fixes (#3763). (#3768). [@thirdender]
624
+ * Added: New singular capabilities for Taxonomies for Compatibility with WP 4.7. Fixes (#3896). (#3946). [@JoryHogeveen]
625
+ * Added: Enhance Currency Field storage. Fixes Adds new format as arrays for multiple values (label, name, sign) and decimal handling options. Fixes(#1915,#3453). (#3949). [@JoryHogeveen]
626
+ * Fixed: Number/Currency format validation error with French formatting. Fixes (#3842). (#3950). [@JoryHogeveen]
627
+ * Fixed: Additional save_user/save_post handling problems corrected and addition of Unit Tests. Fixes (#3918,#3801). (#3945). [sc0ttkclark]
628
+ * Fixed: Double qtip/tooltip when using single checkboxes (boolean type). Fixes (#3940). (#3943) [@JoryHogeveen]
629
+ * Fixed: Undefined Index Notice in (#3936). (#3941). [@sc0ttkclark]
630
+ * Fixed: Properly clear cache before running post-save actions in PodsAPI::save_pod_item. Prevents double saves being necessary to use the `pods_api_post_save_pod_item` filters to update WordPress Object fields. Fixes (#3917). (#3938). [@sc0ttkclark]
631
+ * Fixed: Revamp pods_error to handle multiple modes, PodsMeta now returns false instead of die/exception. Fixes (#3930). (#3937). [@sc0ttkclark]
632
+ * Fixed: Update save_post / save_user handling with better fallbacks when nonce not active. Fixes an issue where the $is_new_item was not set as expected on post saves and user saves. Fixes (#3801,#3918). (#3936). [@sc0ttkclark]
633
+ * Fixed: Add `pods_ui_get_find_params` filter for PodsUI to extend default `find()`. Fixes (#3925). (#3926). [@sc0ttkclark]
634
+ * Fixed: Compatibility additions for WP 4.7, Taxonomy Class (#3895,#3894)
635
+ * Fixed: Proper reset of the local var cache in Pods::$row when using add_to/remove_from/save. Fixes (#3784). (#3923). [@sc0ttkclark]
636
+ * Fixed: get_meta() $single usage to ensure it's always a boolean. Fixes (#3742). (#3921). [@sc0ttkclark,@JoryHogeveen]
637
+ * Fixed: Multiple Travis and Unit Test fixes and build functions. (#3942,#3913,#3911,#3907,#3903,#3888,#3887,#3886,#3885,#3883,#3882,#3881,#3880,#3869,#3868,#3819,#3770,#3750,#3745,#3743) [@Ramoonus,@sc0ttkclark]
638
+ * Fixed: Removing a Bad Init Call generated by a fix to correct plupload file field listings. Fixes (#3900,#3731). (#3901). [@pcfreak30]
639
+ * Fixed: Pass audio_args to the Audio Shortcode, src wasn't being passed when multiple audio files were on the same page using the same shortcode. Fixes (#3891). [@jamesgol]
640
+ * Fixed: Corrected non-printable character added after $api->cache_flush_pods() to settings-tools.php. Fixes (#3876). [@szepeviktor]
641
+ * Fixed: opcache names and add OPcache. Fixes (#3864). (#3875). [@szepeviktor]
642
+ * Fixed: Make sure self::$field_data is set in all cases. Corrects issue where relationship to predefined list was not working in AutoComplete/Select2 fields. Fixes (#3862). (#3863). [@jamesgol]
643
+ * Fixed: Unchecking Show in Menu in the Admin UI selection for Custom Taxonomies will now properly not show the Taxonomy. `show_in_menu` option for for Taxonomies. Fixes (#3848). (#3852). [@JoryHogeveen]
644
+ * Fixed: Make field type labels translatable. Fixes (#3849). (#3850). [@JoryHogeveen]
645
+ * Fixed: Store the old field name in meta. Pods already stored the old 'pod' name, but didn't do the same for fields after updating. Added for (#3841). (#3842). [@JoryHogeveen]
646
+ * Fixed: Fix error with PODS_LIGHT and components. Fixes (#2301,#3811,#2293). (#3837). [@JoryHogeveen]
647
+ * Fixed: Update the attachment parent if updating a post type. Only updates if the parent isn't set but allows file fields/upload fields to now properly show parent post. Fixes (#3808). (#3834). [@JoryHogeveen]
648
+ * Fixed: CSS fixes (remove old images + linter), fixing issues with gradient button not in WP Core. Fixes (#3812). (#3833). [@JoryHogeveen]
649
+ * Fixed: Improve CSS for Code Field (CodeMirror). Fixes (#3818). (#3832). [@JoryHogeveen]
650
+ * Fixed: Set Start of Week Day from General Settings; fixes issue where Calendar of datetime field in admin UI didn't follow the first day of week settings from Setting, General. Fixes (#3826). (#3831). [@JoryHogeveen]
651
+ * Fixed: PHP7 Compatibility issues, a few deprecated constructors and deprecated mysql_ with the use of $wpdb. Fixes (#3828). (#3830). [@JoryHogeveen]
652
+ * Fixed: Update postmeta cache before get_post_meta calls when bypassing cache, ensuring the meta is "fresh". (#3807). [@sc0ttkclark]
653
+ * Fixed: When preloading config after flushing cache, bypass cache. solves the issue when running multisite and you’ve got an object cache drop-in that won’t flush cache for multisite when wp_cache_flush is called. (#3806). [@sc0ttkclark]
654
+ * Fixed: Fix error exporting taxonomy relationship over REST API. Fixes (#3606). (#3794). [@pcfreak30]
655
+ * Fixed: Use taxonomy capabilities in custom locations for taxonomy edit pages. Fixes an issue where Taxonomies assigned as Top Level Menu Items are not usable by Editors (only by Administrators). Fixes (#3569). (#3780). [@JoryHogeveen]
656
+ * Fixed: Correcting a bug in adding Taxonomy REST support. Fixes (#3777). (#3778). [@pcfreak30]
657
+ * Fixed: Clear `$related_item_cache` when saving a relationship. Fixes an issue where the $PodsAPI::save_relationships was not clearing the cache. Fixes (#3775). (#3776). [@pcfreak30]
658
+ * Fixed: jQuery fix to change from deprecated .live() to .on(). Fixes (#3771). (#3772). [@mikeschinkel]
659
+ * Fixed: Basic included post types from WP-API are no longer having their REST base overridden by Pods. Fixes (#3759). (#3760). [@sc0ttkclark]
660
+ * Fixed: Fix SQL for multilingual taxonomies for compatibility with PolyLang. Fixes (#3728). (#3754). [@JoryHogeveen]
661
+ * Fixed: Fix plupload file field listings, specifically fixing some issues in the CSS and jQuery. Fixes (#3731). (#3732). [@pcfreak30]
662
+ * Fixed: Removed max-length for default field value for Text & WYSIWYG fields. Fixes (#3729). (#3730). [@JoryHogeveen]
663
+ * Fixed: Updated URL for translation contributions. Fixes (#3725). (#3726). [@JoryHogeveen]
664
+ * Fixed: Validate field option dependencies based on location within tabs. Corrects and issue with compatibility between Pods SEO. Fixes (#3707). (#3723). [@JoryHogeveen]
665
+ * Fixed: Properly update bidirectional taggable relations. Corrects the issue where bidirectional relationships were creating new entries from the taggable choice in AutoComplete fields, but not saving the relationship. Fixes (#3477). (#3720). [@caleb]
666
+ * Fixed: Allow the entry of negative numbers in Currency fields. Fixes (#3708). (#3709). [@pcfreak30]
667
+
668
+ = 2.6.7 - August 15th 2016 =
669
+ * Fixed: Magic Tag {@permalink} fixes for taxonomy / user / comment detail URL Mapping. Fixes (#3339). [@sc0ttkclark]
670
+ * Fixed: Pods Wizard for Forms now properly uses the `[podsform]` shortcode. Fixes (#3251). [@sc0ttkclark]
671
+ * Fixed: Issue with pll_get_post returning false instead of null. Fixes (#3596). (#3599) [@JoryHogeveen]
672
+ * Fixed: WYSIWYG editor type option is used as dependency by the editor options. Fixes (#3549). (#3610) [@JoryHogeveen]
673
+ * Fixed: Do not display metagroup if all fields are set to hidden. Fixes (#1614). (#3615) [@JoryHogeveen]
674
+ * Fixed: Allow post_status filter to be set for related post_type objects in the edit field UI (#3626). Fixes (#3594). [@JoryHogeveen]
675
+ * Fixed: Refactor object type checking in PodsRESTHandlers::get_handler (#3630). Fixes (#3629). [@pcfreak30]
676
+ * Fixed: Added PODS_DIR to directories that are checked by field_loader() (#3644). Fixes (#3643). [@jamesgol]
677
+ * Fixed: Improved field alignment on setting pages (#3649). Fixes (#3648). [@JoryHogeveen]
678
+ * Fixed: Check for PodsInit in general.php (#3665). Fixes (#3473,#2803,#3353). [@JoryHogeveen]
679
+ * Fixed: Taxonomy capabilities + No more hardcoded tax settings (#3678). Fixes (#3676,#3677). [@JoryHogeveen]
680
+ * Fixed: Allow field options to be filtered (UI). Also allows for il8n module to improve translation handling. (#3683). Fixes (#3682). [@JoryHogeveen]
681
+ * Fixed: WPML Compatibility (#3691). Related to (#142). [@srdjan-jcc]
682
+ * Fixed: Pods field() now properly handles user and media when the output type is pod/pods. Original issue resulted in `$object` being empty as `user` and `media` do not have a `pick_val` (#3694). Fixes (#3693). [@pcfreak30]
683
+ * Fixed: travis-ci: test with PHP 7.1 (#3702). [@Ramoonus]
684
+
685
+ = 2.6.6 - June 23rd 2016 =
686
+ * Added: Polylang compatibility with latest versions along with fixes to longstanding issues with editing and displaying content, relationships, and taxonomy (#3574). Fixes (#3572, #3506) [@JoryHogeveen]
687
+ * Added: REST API v2 Compatibility (#3584). Switches `register_api_field` to `register_rest_field`. Fixes (#3581) [@sc0ttkclark]
688
+ * Added: Allow changing the Auto Templates Filter. This adds a new section in the Auto Templates tab that allows overriding the default `the_content` filter (#3542). Fixes (#3540) [@Shelob9]
689
+ * Added: Polylang support to pods_v post_id (#3562). Allows Pods templates that are translated to be properly selected. Fixes (#3561,#3537) [@jamesgol]
690
+ * Added: Create new 'post_id' method for pods_v (#3537). Provides a method to allow i18n plugins to return a different post id. Related to (#3542,#3526) [@jamesgol]
691
+ * Added: Add filter to PodsMeta->groups_get() allowing adjusting the groups via filter (#3548). Related to (#3547) [@jamesgol]
692
+ * Added: Use form_counter in field name to be unique and prevent conflicts. (#3535) Fixes (#3533) [@pcfreak30]
693
+ * Added: Add user, media and comment support to REST API (#3516). Related to (#3418,#3419) [@pcfreak30]
694
+ * Added: Filter the Pods Metas to Display (#3544). Fixes (#3520). [@coding-panda]
695
+ * Fixed: REST API cleanup for pick field handling. (#3560) Fixes (#3559) [@sc0ttkclark]
696
+ * Fixed: Exclude Unique Post fields from duplication during `$pods->save`. (#3564). Includes `ID`, `post_name`, `post_date`, `post_date_gmt`, `post_modified`, `post_modified_gmt` and `guid`. Fixes (#3563) [@pcfreak30]
697
+ * Fixed: Allow midnight (00:00) as valid time (#3555). If "Allow empty value" is unchecked and a value is not passed it will default to the current time, but it will still accept 00:00:00 as a valid value. Related to (#3488) [@jamesgol]
698
+ * Fixed: Pass $strict = false to load_pod (#3554). This will keep the "Pod not found" message from being displayed during register of other post types. Related to (#3416) [@jamesgol]
699
+ * Fixed: Don't add space to currency names that use HTML encoding (#3553). Fixes British pound currency symbols and others. Resolves (#3498) [@jamesgol]
700
+ * Fixed: Removed extra setting showing up in Auto Templates settings for Taxonomies (#3543). Fixes (#3541) [@Shelob9]
701
+ * Fixed: Use html_entity_decode to convert separator as it is an html entity. (#3536) Fixes (#3527) [@pcfreak30]
702
+ * Fixed: PodsRESTHandlers::write_handler needs to be static (#3511). Fixes (#3510) [@pcfreak30]
703
+
704
+ = 2.6.5.2 - May 4th 2016 =
705
+ * Fixed: Typo in PLL Compatibility check corrected. (#3504) Fixes (#3503). Thank you @JoryHogeveen and @fmommeja for tracking down, fixing and validating this fix. [@JoryHogeveen]
706
+
707
+ = 2.6.5.1 - May 4th, 2016 =
708
+ * Fixed: Additional Field Options tab disappears from field admin view. Fixes (#3501). [@sc0ttkclark]
709
+
710
+ = 2.6.5 - May 3rd, 2016 =
711
+ * Fixed: Renaming of Pods with underscores to hyphenated names that was introduced in 2.6.3. Hyphenated Pods names will remain hyphenated and Underscored Pods names will remain underscored. Fixes (#3499). [@sc0ttkclark]
712
+ * Fixed: Support for new Polylang Versions with much kudos to @JoryHogeveen for tackling this (#3491). Fixes (#3490,#3223) [@JoryHogeveen]
713
+
714
+ = 2.6.4 - April 25th, 2016 =
715
+ * Fixed: Modified Run activation/install priority to fire before plugins loaded. Fix for the Clearing Pods Cache automatically after Pods Upgrade (#3487). Fixes (#2558,#3348) [@sc0ttkclark]
716
+
717
+ = 2.6.3.1 - April 21st, 2016 =
718
+ * Fixed: An Git / SVN deploy bug caused some files to not be properly pushed to WordPress.org SVN, this release is just to ensure everyone who may have updated to 2.6.3 during the period which we were fixing it will be able to still get the proper file updates
719
+
720
+ = 2.6.3 - April 21st, 2016 =
721
+ * Fixed: Fix forcing underscores when loading Edit Pod Form (#3483). Fixes (#3095) [@sc0ttkclark] Kudos to @lkraav for helping us pin this particular issue down and bring it to resolution.
722
+ * Fixed: Clearing Pods Cache automatically after Pods Upgrade "Salt n'Pepa"'ing the cache keys (#3401). Fixes (#2558,#3348) [@sc0ttkclark]
723
+
724
+ = 2.6.2 - March 24th, 2016 =
725
+ * Added: Support for object fields when using Pods::field() with a specific $field and $option. This was also used to correct a problem with "fetching" Custom Taxonomy's Term List when using Pods Feeds in Pods Gravity Forms Plugin. (#3437) [@sc0ttkclark]
726
+ * Fixed: Correcting CSS used for Dashicon to remove conflict with icon usage in Divi. (#3404,#3406) [@jimtrue]
727
+ * Fixed: Currency/Number Validation used to correct issue with Currency Usage in the Pods Gravity Forms plugin (#3436) [@sc0ttkclark]
728
+
729
+ = 2.6.1 - February 15th, 2016 =
730
+ * Added: Additional Label support for Post Type / Taxonomy register functions (#3275) [@pcfreak30]
731
+ * Added: Add use_current option for Widget Single (#3393,#3394) [@sc0ttkclark]
732
+ * Added: Add option to website fields to open links in new window (#3388,#3387) [@sc0ttkclark]
733
+ * Fixed: 'type' not 'object_type' (#3378,#3351) [@pglewis]
734
+ * Fixed: Update Select2 to v3.2.0, should resolve #3344 (#3377,#344) [@pglewis]
735
+ * Fixed: Change Markup to Support CSS in WP 4.4 (Thanks to @nicdford we missed mentioning in 2.6 Change log) (#3277,#3270,#3279)
736
+ * Fixed: Non-Zero Array Keys here in PHP7 cause odd behaviour so just strip the keys (#3294,#3299) [@pglewis]
737
+ * Fixed: Corrected Dashicons Link in the Menu Options panel of Edit Pods (#3287,#3271) [@benbrandt]
738
+ * Fixed: Update Version number on 2.x (#3282,#3281) [@pglewis]
739
+ * Fixed: Typo's Rest into REST (#3303) [@Ramoonus]
740
+ * Fixed: Disable xdebug on Travis (#3284,#3283) [@pglewis]
741
+ * Fixed: Remove dockunit leftovers (#3307) [@Ramoonus]
742
+ * Fixed: Do not use Hashtag as name (#3316) [@Ramoonus]
743
+ * Fixed: Over-escaping strikes again (file upload, restrict file types with more than one mime type) (#3083,#3328) [@pglewis]
744
+ * Fixed: Refresh #3388 with 2.x (#3388,#3389) [@sc0ttkclark]
745
+ * Fixed: Replace usage of get_currentuserinfo with wp_get_current_user (preparation for WP 4.5) (#3399,#3398) [@sc0ttkclark]
746
+ * Fixed: Taxonomy custom meta fields returning false from REST API (#3365,#3369) [@anandamd]
747
+
748
+ = 2.6 - December 9th, 2015 =
749
+ * Added: Support for Term Meta in WP 4.4 - Now create meta-based taxonomies and Pods just magically works! (#3169,#3163) [@sc0ttkclark]
750
+ * Added: Add REST API Support to Post Types, Taxonomies, Users. Read the update in https://github.com/pods-framework/pods/pull/3184 for step by step details. (#3184,#3182) [@Shelob9]
751
+ * Added: Added compatibility with the latest Polylang version, using $polylang-model to get the current language and version. (#3223) [@JoryHogeveen]
752
+ * Added: Inline hook docs in PodsAdmin class (#3180,#3179) [@Shelob9]
753
+ * Added: Fixes to REST API Admin Tab (thanks @nicdford) to display always but also explain why it won't work if not able to work. (#3246,#3259) [@Shelob9,@nicdford]
754
+ * Added: PHPunit support for clover-coverage FN (#3176) [@Ramoonus]
755
+ * Added: Travis do not allow PHP7 to fail (#3235) [@Ramoonus]
756
+ * Added: Tests for Mariadb and mysql 5.6+7 with PHP 5.6 Travis (#3212,#3208) [@Ramoonus]
757
+ * Added: Nonce and text translation to delete link in pod edit sidebar. Fixes issue where attempted to delete pod from edit page results in fatal error. (#3203,#3194) [@cpruitt]
758
+ * Added: Use phpcs standard wordpress in scrutinizer (#3166) [@Ramoonus]
759
+ * Added: phpunit support for clover-coverage (#3161) [@Ramoonus]
760
+ * Added: Travis allow PHP7 to fail (#3153) [@Ramoonus]
761
+ * Added: Travis include WordPress 4.3 in test matrix (#3152) [@Ramoonus]
762
+ * Added: Travis cache composer (#3151) [@Ramoonus]
763
+ * Added: Grunt ignore dockunit.json (#3150) [@Ramoonus]
764
+ * Updated: Dockunit - replace PHP 7 rc1 with rc4 (#3201) [@Ramoonus]
765
+ * Updated: Improve Contributing guidelines correcting wrong pull location and fixing correct release branch. (#3149,#3147) [@quasel]
766
+ * Fixed: Scheduled post preview message/URL. When a post was scheduled, the status message displayed at the top of the edit post page was malformed where the string placeholders were numbered. (#3234) [@sparkdevelopment]
767
+ * Fixed: Merged #3205 to fix install-wp-tests.sh (#3211,#3205) [@Ramoonus]
768
+ * Fixed: Add pods_auto_template_name filter, by context to change auto template (#3199,#3200,#3198) [@Shelob9]
769
+ * Fixed: Revert scrutinizer less is more (#3172,#3170) [@sc0ttkclark,@Ramoonus]
770
+ * Fixed: Remove limit of 5 in get_template_titles Auto Template (#3157,#3160) [@jimtrue]
771
+ * Fixed: Related_act.permalink calls to fix permalink/slug traversal in ACTs and related taxonomies (#3156,#3155,#2779) [@sc0ttkclark]
772
+ * Fixed: Added option to deselect Auto Template for Archive views. There needed an 'empty' selection to correct issue where Template error wouldn't go away. (#3148,#3146,#3142,#3247) [@Sgillessen]
773
+ * Fixed: Added Dockunit Badge (#3145) [@tlovett1]
774
+ * Removed: Double exclude path in scrutinizer (#3228) [@Ramoonus]
775
+ * Removed: Readme removed code coverage badge (#3220) [@Ramoonus]
776
+ * Removed: Dump composer in Scrutinizer (#3204,#3167) [@Ramoonus]
777
+ * Removed: Composer remove coveralls. Was not being used and needs phpunit support. Could also be replaced by php codesniffer or scrutinizer. (#3174) [@Ramoonus]
778
+
779
+ = 2.5.5 - September 16th, 2015 =
780
+ * Added: Unit testing for PHPUnit 4.8 support. (#3090, #3069) Kudos to @Ramoonus
781
+ * Fixed: Drop External code coverage - timeout in Scrutinizer. (#3091) Kudos to @Ramoonus
782
+ * Fixed: Changed Content property to fix spacing issues with AutoComplete Field where the formatted selection fields have awkward spacing between the selection box and the selection list. (#3098, #3097, #3099) Kudos to @nicdford
783
+ * Fixed: Issue where [each] tag traversal did not work with Taxonomy in Pods Templates. Related notes regarding pod->object_fields for taxonomy added for 3.0 notes. (#3106, #3018, #3107, #3111) Major thanks to @pglewis
784
+ * Fixed: `permalink` field traversal has only been working for post types, not for related taxonomies. (#2779, #3114, #3115) Kudos to @pglewis
785
+ * Added: Support for CPT UI 1.0.x in CPT UI migration component by adding support for multiple possible option names for post types and taxonomies. (#3112, #3109, #3113, #3116, #3117) Kudos to @pglewis
786
+ * Added: Merged Auto Template into Pods Template Component. (#3125, #3105) Major thanks to @Shelob9 both for the original plugin and for incorporating this into Pods Templates.
787
+ * Added: License.txt changes to sync with GPL v2 (#3130, #3133) Kudos to @Ramoonus
788
+
789
+ = 2.5.4 - August 10th, 2015 =
790
+ * Added: Support for Compare ALL with meta_query syntax. Kudos to @pcfreak30. (#3037, #3038)
791
+ * Added: Query_field tests (meta_query syntax for where) (#3033, #3032, #1662, #2689)
792
+ * Added: Support for autoCAST()ing meta_value orderby for dates and numbers (#3043, #3041, #3058)
793
+ * Added: Feature/pods page export support. Added 'pods_page_exists' filter to allow Pods Page content to be supplied from another source (eg exported files) (#3049, #3054)
794
+ * Added: Copy of EDDs scrutinizer (#2917, #3072)
795
+ * Removed: PHP4-style constructor removed in Pods Widgets (#3055, #3056, #3057)
796
+ * Fixed: PHP Doc Improvement (#3039, #3040)
797
+ * Fixed: Style escaping which created a quote encoding bug in PodsMeta.php. (#3053, #3032)
798
+
799
+ = 2.5.3 - June 11th, 2015 =
800
+ * Added: Support for Term Splitting in WP 4.2 (#2856, #2660)
801
+ * Added: Support for Pod and Field names with dashes and prefixes with underscores (#3012, #3021, #3022)
802
+ * Added: Add git workflow and a link to it from contributing.md (#2490, #2496)
803
+ * Added: Unit tests for PodsField_Boolean (#2473, #2474)
804
+ * Added: Unit test to create pod factory object and moves fixture set up from traversal tests to test case. (#2445)
805
+ * Added: Additional Pods_Field_Text tests added to incorrect text dependencies. (#2388)
806
+ * Fixed: Fixes for Drag and Drop Reorder Action not working in ACT's (#3015, #3016)
807
+ * Fixed: Fix for pagination handling in shortcodes. Shortcodes currently use 'pagination' for two contexts (display and data) but if page or offset is supplied, it's only meant for one context (display). (#2807, #3004)
808
+ * Fixed: Update post field in pod instance before saving, related to MetaData (post field) not flushing after saving (#3000, #3002, #3003)
809
+ * Fixed: Corrects Delete not working for Edit Items (#2752, #2991)
810
+ * Fixed: Corrects ACT - Admin Order DESC not working && SQL error if order by an relationship field (#2843, #2989)
811
+ * Fixed: Composer: updated for phpunit 4.7 (#2987, #2988, #2783)
812
+ * Fixed: ui/js/jquery.pods.js fixes (#2971, #2972)
813
+ * Fixed: Remove `@internal` phpDoc for pods_query() (#2970, #2969, #2975)
814
+ * Fixed: Fix for ACT editor not staying on current item after saving (#2968, #2942, #2974)
815
+ * Fixed: Fix for over escaping icon URL in file fields previewer (#2957, #2956, #2955, #2978)
816
+ * Fixed: Fix for symlinked pods in local deve environment (#2946, #2945, #2949)
817
+ * Fixed: Removed Vestiges of Old Updater (#2940, #2983)
818
+ * Fixed: Clarify help text as to what does and doesn't get deleted on reset (#2792, #2778)
819
+ * Fixed: Missing $ in PodsInit line 494 (#2475, #2476)
820
+ * Fixed: Trim off whitespace when saving custom fields; code in classes/fields/pick.php already does this. (#2386, #2343)
821
+ * Fixed: Updated Taxonomy to get called after cache is flushed (#2264, #2375, #2382)
822
+ * Fixed: Cleared old unit tests from EDD (#2380)
823
+ * Fixed: Allow fields to be sorted by orderby; Two separate but connected issues. First if orderby is passed then the $data array is never populated. Then looping through $ids will always give it results sorted by priority in the relationships field (data returned by lookup_related_items) (#2350, #2277)
824
+
825
+ = 2.5.2 - May 14th, 2015 =
826
+ * Fixed: Issues with default values for number and other types of fields.
827
+ * Fixed: Issue where Pods update was causing WP-API endpoints to 404. Rewirte rules now flush on wp_loaded.
828
+ * Fixed: Issue preventing proper display of fields in a related CPT via Pods::field()
829
+ * Fixed: Issue preventing codemirror from being enqueued in Pods templates and therefore breaking Pods tempaltes editor in certain configurations.
830
+ * Added: Added caching info to debug info.
831
+ * Fixed: Bug that was causing Pods to overwrite admin menus.
832
+ * Fixed: Issue preventing ongoing compatibility with Admin Columns.
833
+ * Improved: Style of components filter bar.
834
+ * Improved: Proper sanitization/ escaping of URLs.
835
+ * Fixed: Shortcode button was outputted in post editor when shortcodes were disabled. This will no longer happen.
836
+ * Improved: Translation strings in ui/admin/help
837
+ * Improved: Gradients in Pods wizard.
838
+ * Fixed: Issue preventing associated taxonomies to be fetched via Pods::field() and therefore magic tags.
839
+ * Improved: Icon font used for Pods admin icon.
840
+ * Improved: Elaborated on what data is and isn't deleted when Pods data is reset.
841
+ * Added: Compatibility with Github updater plugin.
842
+ * Updated: New youtube video in readme.
843
+ * Added: Support for term splitting in WordPress 4.2.
844
+ * Removed: Extra meta data with _pods_ prefix
845
+ * Fixed: Issue where multiple post type Pods objects called in same session were treated as the same in cache.
846
+ * Fixed: Double slashing in PodsView class.
847
+ * Improved: URL escaping in PodsUI
848
+
849
+ = 2.5.1.2 - March 16th, 2015 =
850
+ * Security Update: We recommend all Pods 2.x installations be updated to the latest version of Pods
851
+ * or replace your plugin files with the download of your version from http://wordpress.org/plugins/pods/developers/
852
+ * Fixed: Pods UI orderby now strictly enforces Database column format
853
+
854
+ = 2.5.1.1 - January 22nd, 2015 =
855
+ * Fixed missing files for font icon.
856
+
857
+ = 2.5.1 - January 22nd, 2015 =
858
+ * Fixed: Issue preventing fields from being sorted by weight or by orderby, that was affecting image multi-select image field ordering.
859
+ * Fixed: Missing gradients in UI.
860
+ * Fixed: Use of anonymous function in PodsMeta.php causing issues with old versions of PHP.
861
+ * Fixed: Issue where hidden fields were being shown for admin users, when they should have been hidden.
862
+ * Fixed: Issue where PodsAPI::delete_field() was unable to delete fields in certain situations.
863
+ * Fixed: Issue with pods_version_check() usage that was causing a deprecated core function to run, when it was supposed to prevent it from running.
864
+ * Fixed: Issue with pods_error() that was causing it to display AJAX errors improperly.
865
+ * Fixed: Issue preventing public, publicly queryable & rewrite with front from saving choices in advanced options.
866
+ * Fixed: Magic tag for custom taxonomy, which was showing no content in Pods Templates in 2.5.
867
+ * Fixed: If block in Frontier.
868
+ * Fixed: Issue with custom taxonomy joins preventing "custom_tax.d.custom_field" type where clauses from working.
869
+
870
+ = 2.5 - December 30th, 2014 =
871
+ * Major performance enhancements can now make things run up to 400% faster (props to @jamesgol!)
872
+ * More unit tests -- now 1,858 tests with a total of 13,420 assertions covering all content type, storage type, and field variations (props to @sc0ttkclark, @clubduece, and @mordauk! it was a group effort)
873
+ * Added Travis-CI / Scrutinizer-CI for all pushes and pull requests to unit test and check for other issues
874
+ * Upgraded Code Mirror library
875
+ * Upgraded qTip library
876
+ * Updated translations -- Add your translations at http://wp-translate.org/projects/pods
877
+ * Fixed: Added nonces for multiple actions in the admin area to avoid accidental / unwanted results
878
+ * Fixed: Issue causing issues in admin with CodePress admin columns.
879
+ * Fixed: Issue preventing Pods Template editor from working with certain xcache configurations.
880
+ * Added: 'join' to the accepted tags for Pods Shortcode.
881
+ * Added: 'pods_data_pre_select_params' filter.
882
+ * Improve: PodsAPI::export_pod_item_lvl(), adding item ID to all steps.
883
+ * Simplify logic when creating new PodsAPI singleton internally.
884
+ * Switch from Pods::do_hook() to apply_filters() or do_action() for 'pods_pods_fields', 'pods_pods_field_related_output_type', 'pods_pods_field_', 'pods_pods_field', 'pods_pods_fetch', 'pods_pods_reset', 'pods_pods_total_found', 'pods_pods_filters'
885
+ * Fixed: YARRP support.
886
+ * Ensure that pods_v_sanitized() passes the $strict argument to pods_v().
887
+ * Prevent use of date_i18n() in PodsData when not needed.
888
+ * Fixed: Issue where updating relationship to users in pods editor threw an erroneous error.
889
+ * Fixed: Hiding of text in title-prompt-text
890
+ * Updated design of new Pod wizard to match MP6 (props to @nikv!)
891
+ * Fixed: Inline docs for pods_api_get_table_info_default_post_status filter
892
+ * Fixed: Issue where Pods::field() showed cached data after saving via Pods::save(), without re-building the Pods Object.
893
+ * Allowed PodsField_Pick to save names
894
+ * Switched pods_v() to use switch/case instead of if/else where possible.
895
+ * Prevented Pods::id() from calling the field method unless it has to.
896
+ * In PodsData::select(), allow proper use of cache expiration time.
897
+ * Fixed: Issue in currency fields to ensure proper handling of decimals.
898
+ * Added a "pre_select" hook in PodsData.
899
+ * Improved traversal regex in Pods::find() to have better handling for variation of backticks.
900
+ * Removed usages of the deprecated WordPress function like_escape().
901
+ * Remove redundant file/class checks for Pods Templates.
902
+ * Implement glotpress-grunt for manging translations.
903
+ * Fixed: Issue where get_current_screen(), in some contexts was used as an object, when it was null.
904
+ * Improved: Styling of shortcode insert button.
905
+ * Prevented string replace and trim from running on a form field default when default value is not a string
906
+ * Fixed: Issue preventing color pickers from working in front-end form.
907
+ * Switched from using $wpdb->prefix to $wpdb->base_prefix in pick field class.
908
+ * Fixed: Default avatars on the Discussion settings page replaced by user's custom avatar.
909
+ * When saving custom fields, whitespace is now trimmed.
910
+ * Better validation of custom fields when saving custom post types.
911
+ * Improved: Handling of required fields.
912
+ * Changed the default of $display_errors in Pods class to true.
913
+ * Allowed save_post_meta to delete single meta elements instead of update.
914
+ * Fixed: An issue preventing fields from being sorted by orderby.
915
+ * Fixed: Issue where fields, storing one value, returned arrays, instead of strings.
916
+ * Allowed extending the link category taxonomy, if in use.
917
+ * Added join as an acceptable tag for Pods shortcodes.
918
+ * Fixed pods_error(): reversed logic that was emitting an error instead of throwing an exception when $display_errors is false
919
+ * Fixed issue where user_url was created as a required field when extending users.
920
+ * Add ability to use pods_group_add() in the ACT editor.
921
+ * Security Update Reminder: As of Pods 2.4.2, we recommend all Pods 2.x installations be updated to the latest version, or replace your plugin files with the download of your version from http://wordpress.org/plugins/pods/developers/
922
+ * If you need assistance in upgrading your Pods 2.x site to the latest version of Pods, please don't hesitate to contact us at https://pods.io/help/
923
+
924
+ = 2.4.3 - June 23rd, 2014 =
925
+ * Fixed: Pods Templates component now has better handling of the new shortcodes
926
+ * Fixed: PodsUI data issue with Custom DB Table support
927
+ * Fixed: Readonly fields and noncing now works properly, Pods 2.4.2 caused all forms with readonly fields to fail submission
928
+ * Hardened: Further security hardening of the `[pods]` shortcode, added PODS_DISABLE_SHORTCODE constant to allow sites to disable the Pods shortcode altogether
929
+
930
+ = 2.4.2 - June 22nd, 2014 =
931
+ * Security Update: We recommend all Pods 2.x installations be updated to the latest version of Pods to fix a noncing issue with form saving, or replace your plugin files with the download of your version from http://wordpress.org/plugins/pods/developers/
932
+
933
+ = 2.4.1 - June 19th, 2014 =
934
+ * Fixed: Display of of hidden fields in Pods Forms
935
+ * Fixed: Reordering fields in PodsUI
936
+ * Fixed: PodsUI Admin Icon Display
937
+ * Add new filter: ‘pods_pod_form_success_message’ for changing the message when Pods Forms are successfully submitted.
938
+ * Fixed: Issues in Packages component when importing existing fields.
939
+ * Added new filter: ‘pods_view_alt_view’ for overriding normal Pods Views to be loaded in via AJAX inline from Pods AJAX Views plugin.
940
+ * Fixed: PHP error in Pods Template reference.
941
+ * New Constant: PODS_PRELOAD_CONFIG_AFTER_FLUSH check to allow for preloading $api->load_pods() after a Pods Cache flush.
942
+ * Fixed: Issue with tabled-based SQL delete actions.
943
+ * Fixed: PodsUI SQL table-based lookups
944
+ * Added: New Hooks In ui/admin/form, which generates ACT editor, for adding additional forms or other content to editor.
945
+ * Added: Inline docs for 'pods_meta_default_box_title' filter and normalized args across each usage.
946
+ * Added: Item ID to pods_api::export() item array.
947
+ * Fixed: Update from GitHub functionality.
948
+ * Fixed: Issue where extended custom post types had diffrent names then original post type due to use of dashes in names.
949
+ * Improved UX for select2 field adding new items.
950
+ * Fixed: $params with unslashed data in Pods_Admin::admin_ajax()
951
+ * Fixed: Unwarranted base_dir warnings.
952
+ * Fixed: Pagination/search boolean checks.
953
+ * Fixed: Issue when mbstring module is not active.
954
+ * Fixed: Issue with markdown module header causing activation errors.
955
+ * New Filter: 'pods_admin_components_menu' to add/edit components submenu items.
956
+ * Added: Ability to use pods() without any parameters. Will pull the pod object based off of the current WP_Query queried object / object id
957
+
958
+ = 2.4 - April 16th, 2014 =
959
+ * After a long road, we've got a new minor release out that fixes a large number of outstanding bugs and adds a few improvements that were within reach right away.
960
+ * In Pods 3.0 we're focusing on finishing some overarching performance improvements that are necessary to support large installs with the new Loop and Repeatable fields features.
961
+ * Added: Tagging feature for Relationship fields with Autocomplete (Select2) which lets you add new items on-demand when saving
962
+ * Added: PodsAPI::get_changed_fields() that can be used when in a pre-save hook to return array of changed values or used in PodsAPI::save_pods_item() to track changes to fields
963
+ * Added: _pods_location to $params for PodsAPI::save_pod_item which will contain the URL of the form it was submitted from
964
+ * Added: New Pods Template editor revamp to include auto-complete for magic tags and field reference, which can be further extended by installing Pods Frontier
965
+ * Added: An optional download link to File Upload field type
966
+ * Added: Additional Currency formats to Currency field type
967
+ * Added: created/modified functionality (see Advanced Content Types) to other Pod types, as long as they are date/datetime fields
968
+ * Added: Support for JetPack Publicize and Markdown modules
969
+ * Added: Max character length option for paragraph fields
970
+ * Added: Actions before and after Pods Form all and individual form fields are outputted
971
+ * Added: New constant PODS_ALLOW_FULL_META for for enabling/disabling get_post_meta( $id ) interaction with Pods (on by default)
972
+ * Added: New constant PODS_DISABLE_SHORTCODE_SQL to disable SQL-related parameters in shortcode
973
+ * Added: 'pods_admin_media_button' filter to disable the Pods shortcode button in post editor
974
+ * Added: 'pods_api_save_pod_item_track_changed_fields_{POD_NAME}' filter for tracking changes to fields
975
+ * Added: 'pods_pick_ignore_internal' filter to enable/disable Relationships with core Pods types (_pods_pod, etc)
976
+ * Added: 'pods_image_default' filter to allow for placekitten.com or other image placeholder scripts for testing
977
+ * Added: Improved Pods Template code sanitization
978
+ * Added: Better names for many fields in Pods Editor
979
+ * Added: New and improved help bubbles in Pods Editor
980
+ * Added: Instructions about using Pods Templates in Pods Widgets
981
+ * Added: New descriptions for Pods Pages and Pods Advanced Content Types component descriptions
982
+ * Added: Support links in Pods Admin -> Help
983
+ * Added: Currently active theme to Pods Debug info list
984
+ * Added: Inline docs for 'pods_api_get_table_info_default_post_status' filter
985
+ * Added: Inline docs for 'pods_admin_menu' filter
986
+ * Added: Inline docs for 'pods_admin_setup_edit_options' (and related) filters
987
+ * Added: Inline docs for 'pods_admin_setup_edit_tabs' (and related) filters
988
+ * Fixed: Issues with user tables in multisite
989
+ * Fixed: Issue with PodsForm::default_value
990
+ * Fixed: With Pods UI. Keep view when generating pagination links
991
+ * Fixed: Bug with custom extensions for allowed file types in upload fields
992
+ * Fixed: Compatibility problem with changes to plupload in WordPress 3.9 that prevented upload pop-up from loading
993
+ * Fixed: Array to string conversion error for CSS fields in Pods UI
994
+ * Fixed: Magic tags for taxonomies in Pods Templates
995
+ * Fixed: Fixed jQuery scope in Pods Form inline JavaScript
996
+ * Fixed: Added 'output' to reserved content types names and reserved query vars
997
+ * Fixed: Issue where required currency and number fields could be saved at default value
998
+ * Fixed: Undefined method error in WP 3.4 due to use of WP_User::to_array() which was added in WP 3.5
999
+ * Fixed: Issue with ability to use filters on reorder page with Pods UI
1000
+ * Fixed: Pre-save enforcing of max length for meta-based values
1001
+ * Fixed: Extra spaces in custom defined list labels
1002
+ * Fixed: Pagination default value for Pods shortcode
1003
+ * Fixed: PodsForm::submit_button() method that had been lost from previous versions
1004
+ * Fixed: Usage of pods_v in currency.php for optimzation purposes
1005
+ * Fixed: Correct parent_file to highlight the correct top level menu
1006
+ * Fixed: Improper wording for text at top of settings page field
classes/Pods.php CHANGED
@@ -1,9 +1,28 @@
1
  <?php
2
 
 
 
 
 
 
3
  /**
4
  * Pods class.
5
  *
6
  * @package Pods
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  */
8
  class Pods implements Iterator {
9
 
@@ -14,13 +33,6 @@ class Pods implements Iterator {
14
  */
15
  private $iterator = false;
16
 
17
- /**
18
- * PodsAPI object.
19
- *
20
- * @var PodsAPI
21
- */
22
- public $api;
23
-
24
  /**
25
  * PodsData object.
26
  *
@@ -35,27 +47,6 @@ class Pods implements Iterator {
35
  */
36
  public $alt_data;
37
 
38
- /**
39
- * Array of pod item arrays.
40
- *
41
- * @var array
42
- */
43
- public $rows;
44
-
45
- /**
46
- * Current pod item array.
47
- *
48
- * @var array
49
- */
50
- public $row;
51
-
52
- /**
53
- * Row number.
54
- *
55
- * @var int
56
- */
57
- private $row_number;
58
-
59
  /**
60
  * Override pod item array.
61
  *
@@ -73,129 +64,10 @@ class Pods implements Iterator {
73
  /**
74
  * Current pod information.
75
  *
76
- * @var array|bool|mixed|null|void
77
  */
78
  public $pod_data;
79
 
80
- /**
81
- * Last used Pods::find() parameters.
82
- *
83
- * @var array
84
- */
85
- public $params = array();
86
-
87
- /**
88
- * Current Pod name.
89
- *
90
- * @var string
91
- */
92
- public $pod;
93
-
94
- /**
95
- * Current Pod ID.
96
- *
97
- * @var int
98
- */
99
- public $pod_id;
100
-
101
- /**
102
- * Pod fields information.
103
- *
104
- * @var array
105
- */
106
- public $fields;
107
-
108
- /**
109
- * Last used filters() parameters.
110
- *
111
- * @var array
112
- */
113
- public $filters = array();
114
-
115
- /**
116
- * Detail page URL used for Advanced Content Types.
117
- *
118
- * @var string
119
- */
120
- public $detail_page;
121
-
122
- /**
123
- * Current Item ID.
124
- *
125
- * @var int
126
- */
127
- public $id;
128
-
129
- /**
130
- * Last used limit from find() lookup.
131
- *
132
- * @var int
133
- */
134
- public $limit = 15;
135
-
136
- /**
137
- * Last used offset from find() lookup.
138
- *
139
- * @var int
140
- */
141
- public $offset = 0;
142
-
143
- /**
144
- * Query variable used for pagination number.
145
- *
146
- * @var string
147
- */
148
- public $page_var = 'pg';
149
-
150
- /**
151
- * Last used page from find() lookup.
152
- *
153
- * @var int|mixed
154
- */
155
- public $page = 1;
156
-
157
- /**
158
- * Last used state of whether pagination was enabled from find() lookup.
159
- *
160
- * @var bool
161
- */
162
- public $pagination = true;
163
-
164
- /**
165
- * Last used state of whether search was enabled from find() lookup.
166
- *
167
- * @var bool
168
- */
169
- public $search = true;
170
-
171
- /**
172
- * Query variable used for search string.
173
- *
174
- * @var string
175
- */
176
- public $search_var = 'search';
177
-
178
- /**
179
- * Search mode (int | text | text_like).
180
- *
181
- * @var string
182
- */
183
- public $search_mode = 'int';
184
-
185
- /**
186
- * Total number of records returned from find() lookup.
187
- *
188
- * @var int
189
- */
190
- public $total = 0;
191
-
192
- /**
193
- * Total number of records found from find() lookup.
194
- *
195
- * @var int
196
- */
197
- public $total_found = 0;
198
-
199
  /**
200
  * Last used ui options for ui() call.
201
  *
@@ -238,13 +110,6 @@ class Pods implements Iterator {
238
  */
239
  public $meta_extra = '';
240
 
241
- /**
242
- * Last SQL query used by a find() lookup.
243
- *
244
- * @var string
245
- */
246
- public $sql;
247
-
248
  /**
249
  * Pods_Deprecated object.
250
  *
@@ -252,24 +117,6 @@ class Pods implements Iterator {
252
  */
253
  public $deprecated;
254
 
255
- /**
256
- * Old Pod name variable.
257
- *
258
- * @var string
259
- *
260
- * @deprecated 2.0.0
261
- */
262
- public $datatype;
263
-
264
- /**
265
- * Old Pod ID variable.
266
- *
267
- * @var int
268
- *
269
- * @deprecated 2.0.0
270
- */
271
- public $datatype_id;
272
-
273
  /**
274
  * Constructor - Pods Framework core.
275
  *
@@ -278,10 +125,9 @@ class Pods implements Iterator {
278
  *
279
  * @license http://www.gnu.org/licenses/gpl-2.0.html
280
  * @since 1.0.0
281
- * @link https://pods.io/docs/pods/
282
  */
283
  public function __construct( $pod = null, $id = null ) {
284
-
285
  if ( null === $pod ) {
286
  $pod = get_queried_object();
287
  }
@@ -314,76 +160,21 @@ class Pods implements Iterator {
314
  }
315
  }//end if
316
 
317
- $this->api = pods_api( $pod );
318
- $this->api->display_errors =& $this->display_errors;
319
-
320
- $this->data = pods_data( $this->api, $id, false );
321
- PodsData::$display_errors =& $this->display_errors;
322
-
323
- // Set up page variable.
324
- if ( pods_strict( false ) ) {
325
- $this->page = 1;
326
- $this->pagination = false;
327
- $this->search = false;
328
- } else {
329
- // Get the page variable.
330
- $this->page = pods_v( $this->page_var, 'get', 1, true );
331
 
332
- if ( ! empty( $this->page ) ) {
333
- $this->page = max( 1, pods_absint( $this->page ) );
334
- }
335
  }
336
 
337
- // Set default pagination handling to on/off.
338
- if ( defined( 'PODS_GLOBAL_POD_PAGINATION' ) ) {
339
- if ( ! PODS_GLOBAL_POD_PAGINATION ) {
340
- $this->page = 1;
341
- $this->pagination = false;
342
- } else {
343
- $this->pagination = true;
344
- }
345
- }
346
 
347
- // Set default search to on/off.
348
- if ( defined( 'PODS_GLOBAL_POD_SEARCH' ) ) {
349
- if ( PODS_GLOBAL_POD_SEARCH ) {
350
- $this->search = true;
351
- } else {
352
- $this->search = false;
353
- }
354
  }
355
 
356
- // Set default search mode.
357
- $allowed_search_modes = array( 'int', 'text', 'text_like' );
358
-
359
- if ( defined( 'PODS_GLOBAL_POD_SEARCH_MODE' ) && in_array( PODS_GLOBAL_POD_SEARCH_MODE, $allowed_search_modes, true ) ) {
360
- $this->search_mode = PODS_GLOBAL_POD_SEARCH_MODE;
361
- }
362
-
363
- // Sync Settings.
364
- $this->data->page =& $this->page;
365
- $this->data->limit =& $this->limit;
366
- $this->data->pagination =& $this->pagination;
367
- $this->data->search =& $this->search;
368
- $this->data->search_mode =& $this->search_mode;
369
-
370
- // Sync Pod Data.
371
- $this->api->pod_data =& $this->data->pod_data;
372
- $this->pod_data =& $this->api->pod_data;
373
- $this->api->pod_id =& $this->data->pod_id;
374
- $this->pod_id =& $this->api->pod_id;
375
- $this->datatype_id =& $this->pod_id;
376
- $this->api->pod =& $this->data->pod;
377
- $this->pod =& $this->api->pod;
378
- $this->datatype =& $this->pod;
379
- $this->api->fields =& $this->data->fields;
380
- $this->fields =& $this->api->fields;
381
- $this->detail_page =& $this->data->detail_page;
382
- $this->id =& $this->data->id;
383
- $this->row =& $this->data->row;
384
- $this->rows =& $this->data->data;
385
- $this->row_number =& $this->data->row_number;
386
- $this->sql =& $this->data->sql;
387
 
388
  if ( is_array( $id ) || is_object( $id ) ) {
389
  $this->find( $id );
@@ -398,13 +189,12 @@ class Pods implements Iterator {
398
  * @since 2.0.0
399
  */
400
  public function valid() {
401
-
402
- if ( empty( $this->pod_id ) ) {
403
  return false;
404
  }
405
 
406
  if ( $this->iterator ) {
407
- return isset( $this->rows[ $this->row_number ] );
408
  }
409
 
410
  return true;
@@ -420,7 +210,6 @@ class Pods implements Iterator {
420
  * @link http://www.php.net/manual/en/class.iterator.php
421
  */
422
  public function is_iterator() {
423
-
424
  return $this->iterator;
425
  }
426
 
@@ -451,7 +240,7 @@ class Pods implements Iterator {
451
  if ( ! $this->iterator ) {
452
  $this->iterator = true;
453
 
454
- $this->row_number = 0;
455
  }
456
  }
457
 
@@ -484,7 +273,7 @@ class Pods implements Iterator {
484
  */
485
  public function key() {
486
 
487
- return $this->row_number;
488
  }
489
 
490
  /**
@@ -498,7 +287,7 @@ class Pods implements Iterator {
498
  */
499
  public function next() {
500
 
501
- $this->row_number ++;
502
  }
503
 
504
  /**
@@ -510,7 +299,7 @@ class Pods implements Iterator {
510
  */
511
  public function exists() {
512
 
513
- if ( empty( $this->row ) ) {
514
  return false;
515
  }
516
 
@@ -526,17 +315,17 @@ class Pods implements Iterator {
526
  * @return array|bool An array of all rows returned from a find() call, or false if no items returned
527
  *
528
  * @since 2.0.0
529
- * @link https://pods.io/docs/data/
530
  */
531
  public function data() {
532
 
533
  do_action( 'pods_pods_data', $this );
534
 
535
- if ( empty( $this->rows ) ) {
536
  return false;
537
  }
538
 
539
- return (array) $this->rows;
540
  }
541
 
542
  /**
@@ -551,8 +340,9 @@ class Pods implements Iterator {
551
  * @since 2.3.10
552
  */
553
  public function input( $field, $input_name = null, $value = '__null' ) {
 
554
 
555
- if ( is_array( $field ) ) {
556
  // Field data override.
557
  $field_data = $field;
558
 
@@ -589,47 +379,35 @@ class Pods implements Iterator {
589
  * @param null $field Field name.
590
  * @param null $option Option name.
591
  *
592
- * @return bool|mixed
593
  *
594
  * @since 2.0.0
595
  */
596
- public function fields( $field = null, $option = null ) {
597
 
598
  $field_data = null;
599
 
600
- if ( empty( $this->fields ) ) {
601
- // No fields found.
602
- $field_data = array();
603
- } elseif ( empty( $field ) ) {
 
604
  // Return all fields.
605
- $field_data = (array) $this->fields;
606
- } elseif ( ! isset( $this->fields[ $field ] ) && ! isset( $this->pod_data['object_fields'][ $field ] ) ) {
607
- // Field not found.
608
- $field_data = array();
609
- } elseif ( empty( $option ) ) {
610
- // Return all field data.
611
- if ( isset( $this->fields[ $field ] ) ) {
612
- $field_data = $this->fields[ $field ];
613
- } elseif ( isset( $this->pod_data['object_fields'] ) ) {
614
- $field_data = $this->pod_data['object_fields'][ $field ];
615
- }
616
  } else {
617
- $options = array();
618
 
619
- // Merge options.
620
- if ( isset( $this->fields[ $field ] ) ) {
621
- $options = array_merge( $this->fields[ $field ], $this->fields[ $field ]['options'] );
622
- } elseif ( isset( $this->pod_data['object_fields'] ) ) {
623
- $options = array_merge( $this->pod_data['object_fields'][ $field ], $this->pod_data['object_fields'][ $field ]['options'] );
624
- }
625
 
626
- if ( 'data' === $option && in_array( pods_v( 'type', $options ), PodsForm::tableless_field_types(), true ) ) {
 
 
627
  // Get a list of available items from a relationship field.
628
- $field_data = PodsForm::field_method( 'pick', 'get_field_data', $options );
629
- } elseif ( isset( $options[ $option ] ) ) {
630
  // Return option.
631
- $field_data = $options[ $option ];
632
- }
633
  }//end if
634
 
635
  /**
@@ -637,12 +415,13 @@ class Pods implements Iterator {
637
  *
638
  * @since unknown
639
  *
640
- * @param array $field_data The data for the field.
641
- * @param string|null $field The specific field that data is being return for, if set when method is called or null.
642
- * @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.
643
- * @param Pods|object $this The current Pods class instance.
 
644
  */
645
- return apply_filters( 'pods_pods_fields', $field_data, $field, $option, $this );
646
 
647
  }
648
 
@@ -657,11 +436,11 @@ class Pods implements Iterator {
657
 
658
  do_action( 'pods_pods_row', $this );
659
 
660
- if ( ! is_array( $this->row ) ) {
661
  return false;
662
  }
663
 
664
- return (array) $this->row;
665
  }
666
 
667
  /**
@@ -675,7 +454,7 @@ class Pods implements Iterator {
675
  * @return string|null|false The output from the field, null if the field doesn't exist, false if no value returned
676
  * for tableless fields
677
  * @since 2.0.0
678
- * @link https://pods.io/docs/display/
679
  */
680
  public function display( $name, $single = null ) {
681
 
@@ -703,11 +482,7 @@ class Pods implements Iterator {
703
  $value = $this->field( $params );
704
 
705
  if ( is_array( $value ) ) {
706
- $fields = $this->fields;
707
-
708
- if ( isset( $this->pod_data['object_fields'] ) ) {
709
- $fields = array_merge( $fields, $this->pod_data['object_fields'] );
710
- }
711
 
712
  $serial_params = array(
713
  'field' => $params->name,
@@ -735,7 +510,7 @@ class Pods implements Iterator {
735
  * @return string|null|false The output from the field, null if the field doesn't exist, false if no value returned
736
  * for tableless fields
737
  * @since 2.0.0
738
- * @link https://pods.io/docs/display/
739
  */
740
  public function raw( $name, $single = null ) {
741
 
@@ -776,26 +551,26 @@ class Pods implements Iterator {
776
  * @return mixed|null Value returned depends on the field type, null if the field doesn't exist, false if no value
777
  * returned for tableless fields.
778
  * @since 2.0.0
779
- * @link https://pods.io/docs/field/
780
  */
781
  public function field( $name, $single = null, $raw = false ) {
782
-
783
- $defaults = array(
784
- 'name' => $name,
785
- 'orderby' => null,
786
- 'single' => $single,
787
- 'params' => null,
788
- 'in_form' => false,
789
- 'raw' => $raw,
790
- 'raw_display' => false,
791
- 'display' => false,
792
- 'get_meta' => false,
793
- 'output' => null,
794
- 'deprecated' => false,
795
- 'keyed' => false,
796
  // extra data to send to field handlers.
797
- 'args' => array(),
798
- );
799
 
800
  if ( is_object( $name ) ) {
801
  $name = get_object_vars( $name );
@@ -836,7 +611,7 @@ class Pods implements Iterator {
836
  * @param array $params Params array passed to field().
837
  * @param Pods $this Current Pods object.
838
  */
839
- $params->output = apply_filters( 'pods_pods_field_related_output_type', 'arrays', $this->row, $params, $this );
840
  }
841
 
842
  if ( in_array( $params->output, array( 'id', 'name', 'object', 'array', 'pod' ), true ) ) {
@@ -845,7 +620,7 @@ class Pods implements Iterator {
845
 
846
  // Support old $orderby variable.
847
  if ( null !== $params->single && is_string( $params->single ) && empty( $params->orderby ) ) {
848
- if ( ! class_exists( 'Pod' ) || Pod::$deprecated_notice ) {
849
  pods_deprecated( 'Pods::field', '2.0', 'Use $params[ \'orderby\' ] instead' );
850
  }
851
 
@@ -879,8 +654,8 @@ class Pods implements Iterator {
879
  }
880
 
881
  if ( $this->data->field_id === $params->name ) {
882
- if ( isset( $this->row[ $params->name ] ) ) {
883
- return $this->row[ $params->name ];
884
  // @codingStandardsIgnoreLine.
885
  } elseif ( null !== $value ) {
886
  return $value;
@@ -912,7 +687,17 @@ class Pods implements Iterator {
912
  /** @var string $pod_type The pod object type. */
913
  $pod_type = pods_v( 'type', $this->pod_data, '' );
914
 
915
- $is_wp_object = in_array( $pod_type, $wp_object_types, true );
 
 
 
 
 
 
 
 
 
 
916
 
917
  if ( in_array( $params->name, $permalink_fields, true ) ) {
918
  if ( 0 < strlen( $this->detail_page ) && false === strpos( $params->name, 'permalink' ) ) {
@@ -961,46 +746,34 @@ class Pods implements Iterator {
961
  $first_field = $traverse_fields[0];
962
  $last_field_data = null;
963
 
964
- if ( isset( $this->fields[ $params->name ] ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
965
  // Get the full field name data.
966
- $field_data = $this->fields[ $params->name ];
967
- $field_source = 'field';
 
 
 
968
  $is_field_set = true;
969
- } elseif ( isset( $this->fields[ $first_field ] ) ) {
970
- // Get the first field name data.
971
- $field_data = $this->fields[ $first_field ];
972
  $field_source = 'field';
973
  $is_field_set = true;
974
- } elseif ( ! empty( $this->pod_data['object_fields'] ) ) {
975
- // Get the object field data.
976
- if ( isset( $this->pod_data['object_fields'][ $first_field ] ) ) {
977
- $field_data = $this->pod_data['object_fields'][ $first_field ];
978
- $field_source = 'object_field';
979
- $is_field_set = true;
980
- } else {
981
- $object_fields = (array) $this->pod_data['object_fields'];
982
-
983
- // Search through field aliases.
984
- foreach ( $object_fields as $object_field => $object_field_opt ) {
985
- if ( in_array( $first_field, $object_field_opt['alias'], true ) ) {
986
- if ( $first_field === $params->name ) {
987
- $params->name = $object_field;
988
- }
989
-
990
- $first_field = $object_field;
991
- $field_data = $object_field_opt;
992
- $field_source = 'object_field';
993
- $is_field_set = true;
994
-
995
- break;
996
- }
997
- }
998
- }
999
- }//end if
1000
 
1001
  // Store field info.
1002
  $field_type = pods_v( 'type', $field_data, '' );
1003
- $field_options = pods_v( 'options', $field_data, array() );
1004
  $is_tableless_field = in_array( $field_type, $tableless_field_types, true );
1005
 
1006
  // Simple fields have no other output options.
@@ -1016,10 +789,10 @@ class Pods implements Iterator {
1016
 
1017
  $row_key = '_' . $params->output . '_' . $params->name;
1018
 
1019
- if ( 'arrays' !== $params->output && isset( $this->row[ $row_key ] ) ) {
1020
- $value = $this->row[ $row_key ];
1021
- } elseif ( 'arrays' === $params->output && isset( $this->row[ $params->name ] ) ) {
1022
- $value = $this->row[ $params->name ];
1023
  }
1024
 
1025
  if (
@@ -1034,10 +807,14 @@ class Pods implements Iterator {
1034
 
1035
  if (
1036
  empty( $value ) &&
1037
- isset( $this->row[ $params->name ] ) &&
1038
  ( ! $is_tableless_field || 'arrays' === $params->output )
1039
  ) {
1040
- if ( empty( $field_data ) || in_array( $field_type, array( 'boolean', 'number', 'currency' ), true ) ) {
 
 
 
 
1041
  $params->raw = true;
1042
  }
1043
 
@@ -1049,147 +826,27 @@ class Pods implements Iterator {
1049
  }
1050
  }
1051
 
1052
- $value = $this->row[ $params->name ];
1053
  } elseif ( empty( $value ) ) {
1054
  $object_field_found = false;
1055
 
1056
  if ( 'object_field' === $field_source ) {
1057
  $object_field_found = true;
1058
 
1059
- if ( isset( $this->row[ $first_field ] ) ) {
1060
- $value = $this->row[ $first_field ];
1061
  } elseif ( $is_tableless_field ) {
1062
- // Overwrite existing field data.
1063
- $this->fields[ $first_field ] = $field_data;
1064
-
1065
  $object_field_found = false;
1066
  } else {
1067
  return null;
1068
  }
 
 
 
1069
 
1070
- } elseif ( 'avatar' === $first_field && 'user' === $pod_type ) {
1071
- // User avatar.
1072
- $size = null;
1073
- $get_avatar = true;
1074
-
1075
- if ( $is_traversal ) {
1076
- if ( $is_field_set ) {
1077
- // This is a registered field.
1078
- if ( isset( $traverse_fields[1] ) && is_numeric( $traverse_fields[1] ) ) {
1079
- $size = (int) $traverse_fields[1];
1080
- } else {
1081
- // Traverse through attachment post.
1082
- $get_avatar = false;
1083
- }
1084
- } else {
1085
- if ( isset( $traverse_fields[1] ) ) {
1086
- $size = (int) $traverse_fields[1];
1087
- }
1088
- }
1089
- }
1090
-
1091
- if ( $get_avatar ) {
1092
- $object_field_found = true;
1093
- if ( 0 < $size ) {
1094
- $value = get_avatar( $this->id(), $size );
1095
- } else {
1096
- $value = get_avatar( $this->id() );
1097
- }
1098
- }
1099
-
1100
- } elseif ( ! $is_field_set ) {
1101
-
1102
- $image_fields = array(
1103
- 'image_attachment',
1104
- 'image_attachment_url',
1105
- );
1106
-
1107
- if ( 'post_type' === $pod_type ) {
1108
- $image_fields[] = 'post_thumbnail';
1109
- $image_fields[] = 'post_thumbnail_url';
1110
- }
1111
-
1112
- // Handle special field tags.
1113
- if ( in_array( $first_field, $image_fields, true ) ) {
1114
- // Default image field handlers.
1115
- $object_field_found = true;
1116
-
1117
- $image_field = $first_field;
1118
- // Is it a URL request?
1119
- $url = '_url' === substr( $image_field, - 4 );
1120
- if ( $url ) {
1121
- $image_field = substr( $image_field, 0, - 4 );
1122
- }
1123
-
1124
- // Copy traversal parameters.
1125
- $traverse_params = $traverse_fields;
1126
- // Results in an empty array if no traversal params are passed.
1127
- array_shift( $traverse_params );
1128
-
1129
- $attachment_id = 0;
1130
- switch ( $image_field ) {
1131
- case 'post_thumbnail':
1132
- $attachment_id = get_post_thumbnail_id( $this->id() );
1133
- break;
1134
- case 'image_attachment':
1135
- if ( isset( $traverse_params[0] ) ) {
1136
- $attachment_id = $traverse_params[0];
1137
- array_shift( $traverse_params );
1138
- }
1139
- break;
1140
- }
1141
-
1142
- if ( $attachment_id ) {
1143
- $is_image = wp_attachment_is_image( $attachment_id );
1144
-
1145
- $size = 'thumbnail';
1146
- if ( isset( $traverse_params[0] ) ) {
1147
- $size = $traverse_params[0];
1148
-
1149
- if ( pods_is_image_size( $size ) ) {
1150
- // Force image request since a valid size parameter is passed.
1151
- $is_image = true;
1152
- } else {
1153
- // No valid image size found.
1154
- $size = false;
1155
- }
1156
- }
1157
-
1158
- if ( $url ) {
1159
- if ( $is_image ) {
1160
- $value = pods_image_url( $attachment_id, $size, 0, true );
1161
- } else {
1162
- $value = wp_get_attachment_url( $attachment_id );
1163
- }
1164
- } elseif ( $size ) {
1165
- // Pods will auto-get the thumbnail ID if this isn't an attachment.
1166
- $value = pods_image( $attachment_id, $size, 0, null, true );
1167
- } else {
1168
- // Fallback to attachment Post object to look for other image properties.
1169
- $media = pods( 'media', $attachment_id );
1170
-
1171
- if ( $media && $media->valid() && $media->exists() ) {
1172
- $value = $media->field( implode( '.', $traverse_params ) );
1173
- } else {
1174
- // Fallback to default attachment object.
1175
- $attachment = get_post( $attachment_id );
1176
- $value = pods_v( implode( '.', $traverse_params ), $attachment, null );
1177
-
1178
- if ( null === $value ) {
1179
- // Start traversal though object property or metadata.
1180
- $name_key = array_shift( $traverse_params );
1181
- $value = pods_v( $name_key, $attachment, null );
1182
-
1183
- if ( null === $value ) {
1184
- $value = get_post_meta( $attachment_id, $name_key, true );
1185
- }
1186
 
1187
- $value = pods_traverse( $traverse_params, $value );
1188
- }
1189
- }
1190
- }
1191
- }
1192
- }
1193
  }
1194
 
1195
  // Continue regular field parsing.
@@ -1202,8 +859,9 @@ class Pods implements Iterator {
1202
  $params->name = $params->traverse[0];
1203
  }
1204
 
1205
- if ( $field_type ) {
1206
 
 
1207
  /**
1208
  * Modify value returned by field() after its retrieved, but before its validated or formatted
1209
  *
@@ -1211,21 +869,17 @@ class Pods implements Iterator {
1211
  *
1212
  * @since unknown
1213
  *
1214
- * @param array|string|null $value Value retrieved.
1215
- * @param array|object $row Current row being outputted.
1216
- * @param array $params Params array passed to field().
1217
- * @param object|Pods $this Current Pods object.
 
1218
  */
1219
- $v = apply_filters( "pods_pods_field_{$field_type}", null, $this->fields[ $params->name ], $this->row, $params, $this );
1220
 
1221
  if ( null !== $v ) {
1222
  return $v;
1223
  }
1224
- }
1225
-
1226
- $simple = false;
1227
-
1228
- if ( $is_field_set ) {
1229
 
1230
  if ( 'meta' === $this->pod_data['storage'] && ! $is_tableless_field ) {
1231
  $simple = true;
@@ -1238,7 +892,11 @@ class Pods implements Iterator {
1238
  $simple = true;
1239
  $params->single = true;
1240
  }
1241
- } elseif ( in_array( $field_type, array( 'boolean', 'number', 'currency' ), true ) ) {
 
 
 
 
1242
  $params->raw = true;
1243
  }
1244
  }
@@ -1259,32 +917,34 @@ class Pods implements Iterator {
1259
  pods_no_conflict_on( $pod_type );
1260
  }
1261
 
1262
- if ( $is_wp_object ) {
1263
- $id = $this->id();
1264
-
1265
  $metadata_type = $pod_type;
1266
 
1267
  if ( in_array( $metadata_type, array( 'post_type', 'media' ), true ) ) {
1268
  $metadata_type = 'post';
1269
-
1270
- // Support for WPML 'duplicated' translation handling.
1271
- if ( did_action( 'wpml_loaded' ) && apply_filters( 'wpml_is_translated_post_type', false, $this->pod_data['name'] ) ) {
1272
- $master_post_id = (int) apply_filters( 'wpml_master_post_from_duplicate', $id );
1273
-
1274
- if ( $master_post_id ) {
1275
- $id = $master_post_id;
1276
- }
1277
- }
1278
  } elseif ( 'taxonomy' === $metadata_type ) {
1279
  $metadata_type = 'term';
1280
  }
1281
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1282
  $value = get_metadata( $metadata_type, $id, $params->name, $params->single );
1283
 
1284
  $single_multi = 'single';
1285
 
1286
- if ( $is_field_set && $field_type ) {
1287
- $single_multi = pods_v( $field_type . '_format_type', $field_options, $single_multi );
1288
  }
1289
 
1290
  if ( $simple && ! is_array( $value ) && 'single' !== $single_multi ) {
@@ -1300,7 +960,7 @@ class Pods implements Iterator {
1300
  $params->single = false;
1301
  }
1302
 
1303
- $value = PodsForm::field_method( 'pick', 'simple_value', $params->name, $value, $this->fields[ $params->name ], $this->pod_data, $this->id(), true );
1304
  }
1305
 
1306
  if ( ! $no_conflict ) {
@@ -1309,7 +969,7 @@ class Pods implements Iterator {
1309
  }
1310
  } else {
1311
  // Dot-traversal.
1312
- $pod = $this->pod;
1313
  $ids = array( $this->id() );
1314
  $all_fields = array();
1315
 
@@ -1317,12 +977,17 @@ class Pods implements Iterator {
1317
 
1318
  // Get fields matching traversal names.
1319
  if ( ! empty( $lookup ) ) {
1320
- $fields = $this->api->load_fields( array(
1321
- 'name' => $lookup,
1322
- 'type' => $tableless_field_types,
1323
- 'object_fields' => true,
1324
- // @todo support object fields too.
1325
- ) );
 
 
 
 
 
1326
 
1327
  if ( ! empty( $fields ) ) {
1328
  foreach ( $fields as $field ) {
@@ -1335,26 +1000,17 @@ class Pods implements Iterator {
1335
  }
1336
  }
1337
  }
1338
-
1339
- if ( ! empty( $this->pod_data['object_fields'] ) ) {
1340
- $object_fields = (array) $this->pod_data['object_fields'];
1341
-
1342
- foreach ( $object_fields as $object_field => $object_field_opt ) {
1343
- if ( in_array( $object_field_opt['type'], $tableless_field_types, true ) ) {
1344
- $all_fields[ $this->pod ][ $object_field ] = $object_field_opt;
1345
- }
1346
- }
1347
- }
1348
  }//end if
1349
 
1350
  $last_type = '';
1351
  $last_object = '';
1352
  $last_pick_val = '';
 
1353
 
1354
- $single_multi = pods_v( $field_type . '_format_type', $field_options, 'single' );
1355
 
1356
  if ( 'multi' === $single_multi ) {
1357
- $limit = (int) pods_v( $field_type . '_limit', $field_options, 0 );
1358
  } else {
1359
  $limit = 1;
1360
  }
@@ -1369,41 +1025,39 @@ class Pods implements Iterator {
1369
 
1370
  $field_exists = isset( $all_fields[ $pod ][ $field ] );
1371
 
1372
- $simple = false;
1373
- $last_options = array();
 
 
 
 
1374
 
1375
- if (
1376
- $field_exists &&
1377
- 'pick' === $all_fields[ $pod ][ $field ]['type'] &&
1378
- in_array( $all_fields[ $pod ][ $field ]['pick_object'], $simple_tableless_objects, true )
1379
- ) {
1380
- $simple = true;
1381
- $last_options = $all_fields[ $pod ][ $field ];
1382
  }
1383
 
1384
  // Tableless handler.
1385
- if ( $field_exists && ( ! $simple || ! in_array( $all_fields[ $pod ][ $field ]['type'], array(
1386
  'pick',
1387
  'taxonomy',
1388
  'comment',
1389
  ), true ) ) ) {
1390
- $type = $all_fields[ $pod ][ $field ]['type'];
1391
- $pick_object = $all_fields[ $pod ][ $field ]['pick_object'];
1392
- $pick_val = $all_fields[ $pod ][ $field ]['pick_val'];
1393
-
1394
- if ( 'table' === $pick_object ) {
1395
- $pick_val = pods_v( 'pick_table', $all_fields[ $pod ][ $field ]['options'], $pick_val, true );
1396
- } elseif ( '__current__' === $pick_val ) {
1397
- $pick_val = $pod;
1398
- }
1399
 
1400
  $last_limit = 0;
1401
 
1402
  if ( in_array( $type, $tableless_field_types, true ) ) {
1403
- $single_multi = pods_v( "{$type}_format_type", $all_fields[ $pod ][ $field ]['options'], 'single' );
1404
 
1405
  if ( 'multi' === $single_multi ) {
1406
- $last_limit = (int) pods_v( "{$type}_limit", $all_fields[ $pod ][ $field ]['options'], 0 );
1407
  } else {
1408
  $last_limit = 1;
1409
  }
@@ -1412,24 +1066,26 @@ class Pods implements Iterator {
1412
  $last_type = $type;
1413
  $last_object = $pick_object;
1414
  $last_pick_val = $pick_val;
1415
- $last_options = $all_fields[ $pod ][ $field ];
1416
 
1417
  // Temporary hack until there's some better handling here.
1418
  $last_limit *= count( $ids );
1419
 
1420
  // Get related IDs.
1421
- if ( ! isset( $all_fields[ $pod ][ $field ]['pod_id'] ) ) {
1422
- $all_fields[ $pod ][ $field ]['pod_id'] = 0;
1423
- }
1424
-
1425
- if ( isset( $all_fields[ $pod ][ $field ]['id'] ) ) {
1426
- $ids = $this->api->lookup_related_items( $all_fields[ $pod ][ $field ]['id'], $all_fields[ $pod ][ $field ]['pod_id'], $ids, $all_fields[ $pod ][ $field ] );
1427
  }
1428
 
1429
  // No items found.
1430
  if ( empty( $ids ) ) {
 
 
1431
  return false;
1432
- } elseif ( 0 < $last_limit ) {
 
 
 
 
1433
  // @todo This should return array() if not $params->single.
1434
  $ids = array_slice( $ids, 0, $last_limit );
1435
  }
@@ -1443,9 +1099,9 @@ class Pods implements Iterator {
1443
  if ( 'pod' === $pick_object ) {
1444
  $pod = $pick_val;
1445
  } else {
1446
- $check = $this->api->get_table_info( $pick_object, $pick_val );
1447
 
1448
- if ( ! empty( $check ) && ! empty( $check['pod'] ) ) {
1449
  $pod = $check['pod']['name'];
1450
  }
1451
  }
@@ -1467,12 +1123,15 @@ class Pods implements Iterator {
1467
 
1468
  if ( in_array( $last_type, PodsForm::file_field_types(), true ) ) {
1469
  $object_type = 'media';
1470
- $object = 'attachment';
1471
  }
1472
 
1473
- $data = array();
 
1474
 
1475
- $table = $this->api->get_table_info( $object_type, $object, null, null, $last_options );
 
 
1476
 
1477
  $join = array();
1478
  $where = array();
@@ -1481,7 +1140,9 @@ class Pods implements Iterator {
1481
  $join = (array) $table['join'];
1482
  }
1483
 
1484
- if ( ! empty( $ids ) || ! empty( $table['where'] ) ) {
 
 
1485
  foreach ( $ids as $id ) {
1486
  $where[ $id ] = '`t`.`' . $table['field_id'] . '` = ' . (int) $id;
1487
  }
@@ -1516,7 +1177,7 @@ class Pods implements Iterator {
1516
  $related_obj = pods( $table['pod']['name'], null, false );
1517
  }
1518
 
1519
- if ( $related_obj || ! empty( $table['table'] ) ) {
1520
  $sql = array(
1521
  'select' => '*, `t`.`' . $table['field_id'] . '` AS `pod_item_id`',
1522
  'table' => $table['table'],
@@ -1557,7 +1218,7 @@ class Pods implements Iterator {
1557
 
1558
  if ( ! $related_obj || ! $related_obj->valid() ) {
1559
  if ( ! is_object( $this->alt_data ) ) {
1560
- $this->alt_data = pods_data( null, 0, true, true );
1561
  }
1562
 
1563
  $item_data = $this->alt_data->select( $sql );
@@ -1711,12 +1372,12 @@ class Pods implements Iterator {
1711
  // Return an array of single column values.
1712
  $value = array();
1713
 
1714
- foreach ( $data as $item_id => $item ) {
1715
- // $field is 123x123, needs to be _src.123x123
1716
- $traverse_fields = array_splice( $params->traverse, $key );
1717
- $full_field = implode( '.', $traverse_fields );
1718
- array_shift( $traverse_fields );
1719
 
 
1720
  if ( is_array( $item ) && isset( $item[ $field ] ) ) {
1721
  if ( $table['field_id'] === $field ) {
1722
  $value[] = (int) $item[ $field ];
@@ -1736,7 +1397,7 @@ class Pods implements Iterator {
1736
  (
1737
  ( false !== strpos( $full_field, '_src' ) || 'guid' === $field )
1738
  && (
1739
- in_array( $table['type'], array( 'attachment', 'media' ), true )
1740
  || in_array( $last_type, PodsForm::file_field_types(), true )
1741
  )
1742
  )
@@ -1830,24 +1491,20 @@ class Pods implements Iterator {
1830
 
1831
  $metadata_type = $object_type;
1832
 
1833
- if ( 'post' === $object_type ) {
1834
- // Support for WPML 'duplicated' translation handling.
1835
- if ( did_action( 'wpml_loaded' ) && apply_filters( 'wpml_is_translated_post_type', false, $object ) ) {
1836
- $master_post_id = (int) apply_filters( 'wpml_master_post_from_duplicate', $metadata_object_id );
1837
-
1838
- if ( 0 < $master_post_id ) {
1839
- $metadata_object_id = $master_post_id;
1840
- }
1841
- }
1842
- } elseif ( 'taxonomy' === $object_type ) {
1843
  $metadata_type = 'term';
1844
  }
1845
 
 
 
 
1846
  $meta_value = get_metadata( $metadata_type, $metadata_object_id, $field, true );
1847
- $value[] = pods_traverse( $traverse_fields, $meta_value );
 
1848
  } elseif ( 'settings' === $object_type ) {
1849
  $option_value = get_option( $object . '_' . $field );
1850
- $value[] = pods_traverse( $traverse_fields, $option_value );
 
1851
  }//end if
1852
  }//end foreach
1853
  }//end if
@@ -1874,6 +1531,9 @@ class Pods implements Iterator {
1874
  }
1875
  }//end if
1876
 
 
 
 
1877
  if ( $last_options ) {
1878
  $last_field_data = $last_options;
1879
  } elseif ( isset( $related_obj, $related_obj->fields, $related_obj->fields[ $field ] ) ) {
@@ -1891,11 +1551,11 @@ class Pods implements Iterator {
1891
  if ( ! empty( $params->traverse ) && 1 < count( $params->traverse ) ) {
1892
  $field_names = implode( '.', $params->traverse );
1893
 
1894
- $this->row[ $field_names ] = $value;
1895
- } elseif ( 'arrays' !== $params->output && in_array( $field_data['type'], $tableless_field_types, true ) ) {
1896
- $this->row[ '_' . $params->output . '_' . $params->full_name ] = $value;
1897
- } elseif ( 'arrays' === $params->output || ! in_array( $field_data['type'], $tableless_field_types, true ) ) {
1898
- $this->row[ $params->full_name ] = $value;
1899
  }
1900
 
1901
  if ( true === $params->single && is_array( $value ) && 1 === count( $value ) ) {
@@ -1908,8 +1568,6 @@ class Pods implements Iterator {
1908
 
1909
  if ( ! empty( $field_data ) && ( $params->display || ! $params->raw ) && ! $params->in_form && ! $params->raw_display ) {
1910
  if ( $params->display || ( ( $params->get_meta || $params->deprecated ) && ! in_array( $field_data['type'], $tableless_field_types, true ) ) ) {
1911
- $field_data['options'] = pods_v( 'options', $field_data, array(), true );
1912
-
1913
  $post_temp = false;
1914
  $old_post = null;
1915
  $old_post_id = null;
@@ -1929,22 +1587,20 @@ class Pods implements Iterator {
1929
  $post_ID = $this->id();
1930
  }
1931
 
1932
- $filter = pods_v( 'display_filter', $field_data['options'] );
1933
 
1934
  if ( 0 < strlen( $filter ) ) {
1935
-
1936
  if ( $params->single ) {
1937
  $value = array( $value );
1938
  }
1939
 
1940
  foreach ( $value as $key => $val ) {
1941
-
1942
  $args = array(
1943
  $filter,
1944
  $val,
1945
  );
1946
 
1947
- $filter_args = pods_v( 'display_filter_args', $field_data['options'] );
1948
 
1949
  if ( ! empty( $filter_args ) ) {
1950
  $args = array_merge( $args, compact( $filter_args ) );
@@ -1959,9 +1615,16 @@ class Pods implements Iterator {
1959
  if ( $params->single ) {
1960
  $value = reset( $value );
1961
  }
1962
-
1963
- } elseif ( 1 === (int) pods_v( 'display_process', $field_data['options'], 1 ) ) {
1964
- $value = PodsForm::display( $field_data['type'], $value, $params->name, array_merge( $field_data, $field_data['options'] ), $this->pod_data, $this->id() );
 
 
 
 
 
 
 
1965
  }
1966
 
1967
  if ( $post_temp ) {
@@ -1971,7 +1634,7 @@ class Pods implements Iterator {
1971
  $post_ID = $old_post_id;
1972
  }
1973
  } else {
1974
- $value = PodsForm::value( $field_data['type'], $value, $params->name, array_merge( $field_data, $field_data['options'] ), $this->pod_data, $this->id() );
1975
  }//end if
1976
  }//end if
1977
 
@@ -1987,7 +1650,7 @@ class Pods implements Iterator {
1987
  * @param array $params Params array passed to field().
1988
  * @param object|Pods $this Current Pods object.
1989
  */
1990
- $value = apply_filters( 'pods_pods_field', $value, $this->row, $params, $this );
1991
 
1992
  return $value;
1993
  }
@@ -2040,7 +1703,7 @@ class Pods implements Iterator {
2040
  }
2041
  }
2042
  } else {
2043
- $related_ids = $this->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data );
2044
 
2045
  foreach ( $value as $k => $v ) {
2046
  if ( ! preg_match( '/[^\D]/', $v ) ) {
@@ -2122,7 +1785,7 @@ class Pods implements Iterator {
2122
  }
2123
  }
2124
  } else {
2125
- $related_ids = $this->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data );
2126
 
2127
  foreach ( $value as $k => $v ) {
2128
  if ( ! preg_match( '/[^\D]/', $v ) ) {
@@ -2203,7 +1866,7 @@ class Pods implements Iterator {
2203
  */
2204
  public function id() {
2205
 
2206
- if ( isset( $this->data->row, $this->data->row['id'] ) ) {
2207
  // If we already have data loaded return that ID.
2208
  return $this->data->row['id'];
2209
  }
@@ -2255,8 +1918,8 @@ class Pods implements Iterator {
2255
  }
2256
  } elseif ( isset( $params['offset'] ) && 0 < $params['offset'] ) {
2257
  $params['offset'] --;
2258
- } elseif ( 0 < $this->row_number && ! isset( $params['offset'] ) && ! empty( $this->params ) ) {
2259
- $params['offset'] = $this->row_number - 1;
2260
  } else {
2261
  return 0;
2262
  }
@@ -2343,8 +2006,8 @@ class Pods implements Iterator {
2343
  $params['where'] = "{$id} < `t`.`{$this->data->field_id}`";
2344
  }
2345
  } elseif ( ! isset( $params['offset'] ) ) {
2346
- if ( ! empty( $this->params ) && - 1 < $this->row_number ) {
2347
- $params['offset'] = $this->row_number + 1;
2348
  } else {
2349
  $params['offset'] = 1;
2350
  }
@@ -2507,7 +2170,7 @@ class Pods implements Iterator {
2507
  *
2508
  * @return \Pods The pod object
2509
  * @since 2.0.0
2510
- * @link https://pods.io/docs/find/
2511
  */
2512
  public function find( $params = null, $limit = 15, $where = null, $sql = null ) {
2513
 
@@ -2518,6 +2181,10 @@ class Pods implements Iterator {
2518
 
2519
  $select = '`t`.*';
2520
 
 
 
 
 
2521
  if ( 'table' === $this->pod_data['storage'] && ! in_array( $this->pod_data['type'], array(
2522
  'pod',
2523
  'table',
@@ -2525,13 +2192,15 @@ class Pods implements Iterator {
2525
  $select .= ', `d`.*';
2526
  }
2527
 
2528
- if ( empty( $this->data->table ) ) {
 
 
2529
  return $this;
2530
  }
2531
 
2532
  $defaults = array(
2533
  // Optimization parameters.
2534
- 'table' => $this->data->table,
2535
  'select' => $select,
2536
  'join' => null,
2537
  // Main query parameters.
@@ -2609,8 +2278,13 @@ class Pods implements Iterator {
2609
  $order = 'DESC';
2610
  }
2611
 
2612
- if ( isset( $this->fields[ $k ] ) && in_array( $this->fields[ $k ]['type'], $tableless_field_types, true ) ) {
2613
- if ( in_array( $this->fields[ $k ]['pick_object'], $simple_tableless_objects, true ) ) {
 
 
 
 
 
2614
  if ( 'table' === $this->pod_data['storage'] ) {
2615
  if ( ! in_array( $this->pod_data['type'], array( 'pod', 'table' ), true ) ) {
2616
  $key = "`d`.`{$k}`";
@@ -2621,13 +2295,7 @@ class Pods implements Iterator {
2621
  $key = "`{$k}`.`meta_value`";
2622
  }
2623
  } else {
2624
- $pick_val = $this->fields[ $k ]['pick_val'];
2625
-
2626
- if ( '__current__' === $pick_val ) {
2627
- $pick_val = $this->pod;
2628
- }
2629
-
2630
- $table = $this->api->get_table_info( $this->fields[ $k ]['pick_object'], $pick_val );
2631
 
2632
  if ( ! empty( $table ) ) {
2633
  $key = "`{$k}`.`" . $table['field_index'] . '`';
@@ -2639,7 +2307,7 @@ class Pods implements Iterator {
2639
  if ( ! in_array( $this->pod_data['type'], array( 'pod', 'table' ), true ) ) {
2640
  if ( isset( $this->pod_data['object_fields'][ $k ] ) ) {
2641
  $key = "`t`.`{$k}`";
2642
- } elseif ( isset( $this->fields[ $k ] ) ) {
2643
  if ( 'table' === $this->pod_data['storage'] ) {
2644
  $key = "`d`.`{$k}`";
2645
  } else {
@@ -2654,7 +2322,7 @@ class Pods implements Iterator {
2654
  }
2655
  }
2656
  }
2657
- } elseif ( isset( $this->fields[ $k ] ) ) {
2658
  if ( 'table' === $this->pod_data['storage'] ) {
2659
  $key = "`t`.`{$k}`";
2660
  } else {
@@ -2700,10 +2368,12 @@ class Pods implements Iterator {
2700
 
2701
  $key = $k;
2702
 
 
 
2703
  if ( ! in_array( $this->pod_data['type'], array( 'pod', 'table' ), true ) ) {
2704
  if ( isset( $this->pod_data['object_fields'][ $k ] ) ) {
2705
  $key = "`t`.`{$k}`";
2706
- } elseif ( isset( $this->fields[ $k ] ) ) {
2707
  if ( 'table' === $this->pod_data['storage'] ) {
2708
  $key = "`d`.`{$k}`";
2709
  } else {
@@ -2718,7 +2388,7 @@ class Pods implements Iterator {
2718
  }
2719
  }
2720
  }
2721
- } elseif ( isset( $this->fields[ $k ] ) ) {
2722
  if ( 'table' === $this->pod_data['storage'] ) {
2723
  $key = "`t`.`{$k}`";
2724
  } else {
@@ -2753,7 +2423,7 @@ class Pods implements Iterator {
2753
  * @return array An array of fields from the row
2754
  *
2755
  * @since 2.0.0
2756
- * @link https://pods.io/docs/fetch/
2757
  */
2758
  public function fetch( $id = null, $explicit_set = true ) {
2759
 
@@ -2773,7 +2443,7 @@ class Pods implements Iterator {
2773
 
2774
  $this->data->fetch( $id, $explicit_set );
2775
 
2776
- return $this->row;
2777
  }
2778
 
2779
  /**
@@ -2786,7 +2456,7 @@ class Pods implements Iterator {
2786
  * @return \Pods The pod object
2787
  *
2788
  * @since 2.0.0
2789
- * @link https://pods.io/docs/reset/
2790
  */
2791
  public function reset( $row = null ) {
2792
 
@@ -2814,7 +2484,7 @@ class Pods implements Iterator {
2814
  *
2815
  * @return int Number of rows returned by find(), based on the 'limit' parameter set
2816
  * @since 2.0.0
2817
- * @link https://pods.io/docs/total/
2818
  */
2819
  public function total() {
2820
 
@@ -2822,9 +2492,7 @@ class Pods implements Iterator {
2822
 
2823
  $this->data->total();
2824
 
2825
- $this->total =& $this->data->total;
2826
-
2827
- return $this->total;
2828
  }
2829
 
2830
  /**
@@ -2836,7 +2504,7 @@ class Pods implements Iterator {
2836
  *
2837
  * @return int Number of rows returned by find(), regardless of the 'limit' parameter
2838
  * @since 2.0.0
2839
- * @link https://pods.io/docs/total-found/
2840
  */
2841
  public function total_found() {
2842
 
@@ -2851,9 +2519,7 @@ class Pods implements Iterator {
2851
 
2852
  $this->data->total_found();
2853
 
2854
- $this->total_found =& $this->data->total_found;
2855
-
2856
- return $this->total_found;
2857
  }
2858
 
2859
  /**
@@ -2947,7 +2613,7 @@ class Pods implements Iterator {
2947
  * @return int The item ID
2948
  *
2949
  * @since 2.0.0
2950
- * @link https://pods.io/docs/add/
2951
  */
2952
  public function add( $data = null, $value = null ) {
2953
 
@@ -2967,7 +2633,7 @@ class Pods implements Iterator {
2967
  'allow_custom_fields' => true,
2968
  );
2969
 
2970
- return $this->api->save_pod_item( $params );
2971
  }
2972
 
2973
  /**
@@ -3022,7 +2688,7 @@ class Pods implements Iterator {
3022
 
3023
  $value = array_merge( $current_value, $value );
3024
  } else {
3025
- $related_ids = $this->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data );
3026
 
3027
  foreach ( $value as $k => $v ) {
3028
  if ( ! preg_match( '/[^\D]/', $v ) ) {
@@ -3074,7 +2740,7 @@ class Pods implements Iterator {
3074
  ),
3075
  );
3076
 
3077
- $id = $this->api->save_pod_item( $params );
3078
 
3079
  if ( 0 < $id && $fetch ) {
3080
  // Clear local var cache of field values.
@@ -3148,7 +2814,7 @@ class Pods implements Iterator {
3148
 
3149
  $value = $current_value;
3150
  } else {
3151
- $related_ids = $this->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data );
3152
 
3153
  foreach ( $value as $k => $v ) {
3154
  if ( ! preg_match( '/[^\D]/', $v ) ) {
@@ -3211,7 +2877,7 @@ class Pods implements Iterator {
3211
  ),
3212
  );
3213
 
3214
- $id = $this->api->save_pod_item( $params );
3215
 
3216
  if ( 0 < $id && $fetch ) {
3217
  // Clear local var cache of field values.
@@ -3240,7 +2906,7 @@ class Pods implements Iterator {
3240
  * @return int The item ID
3241
  *
3242
  * @since 2.0.0
3243
- * @link https://pods.io/docs/save/
3244
  */
3245
  public function save( $data = null, $value = null, $id = null, $params = null ) {
3246
 
@@ -3251,7 +2917,7 @@ class Pods implements Iterator {
3251
  $fetch = false;
3252
 
3253
  // @codingStandardsIgnoreLine
3254
- if ( null === $id || ( $this->row && $id == $this->id() ) ) {
3255
  $fetch = true;
3256
 
3257
  if ( null === $id ) {
@@ -3261,7 +2927,7 @@ class Pods implements Iterator {
3261
 
3262
  $data = (array) $this->do_hook( 'save', $data, $id );
3263
 
3264
- if ( empty( $data ) && empty( $params['is_new_item'] ) ) {
3265
  return $id;
3266
  }
3267
 
@@ -3271,6 +2937,13 @@ class Pods implements Iterator {
3271
  $default = $params;
3272
  }
3273
 
 
 
 
 
 
 
 
3274
  $params = array(
3275
  'pod' => $this->pod,
3276
  'id' => $id,
@@ -3283,7 +2956,7 @@ class Pods implements Iterator {
3283
  $params = array_merge( $params, $default );
3284
  }
3285
 
3286
- $id = $this->api->save_pod_item( $params );
3287
 
3288
  if ( 0 < $id && $fetch ) {
3289
  // Clear local var cache of field values.
@@ -3317,7 +2990,7 @@ class Pods implements Iterator {
3317
  * @return bool Whether the item was successfully deleted
3318
  *
3319
  * @since 2.0.0
3320
- * @link https://pods.io/docs/delete/
3321
  */
3322
  public function delete( $id = null ) {
3323
 
@@ -3336,7 +3009,7 @@ class Pods implements Iterator {
3336
  'id' => $id,
3337
  );
3338
 
3339
- return $this->api->delete_pod_item( $params );
3340
  }
3341
 
3342
  /**
@@ -3349,17 +3022,19 @@ class Pods implements Iterator {
3349
  * @since 2.1.1
3350
  */
3351
  public function reset_pod() {
3352
-
3353
- $params = array( 'id' => $this->pod_id );
 
 
3354
 
3355
  $this->data->id = null;
3356
- $this->data->row = array();
3357
- $this->data->data = array();
3358
 
3359
  $this->data->total = 0;
3360
  $this->data->total_found = 0;
3361
 
3362
- return $this->api->reset_pod( $params );
3363
  }
3364
 
3365
  /**
@@ -3372,7 +3047,7 @@ class Pods implements Iterator {
3372
  * @return int|bool ID of the new pod item
3373
  *
3374
  * @since 2.0.0
3375
- * @link https://pods.io/docs/duplicate/
3376
  */
3377
  public function duplicate( $id = null ) {
3378
 
@@ -3391,7 +3066,7 @@ class Pods implements Iterator {
3391
  'id' => $id,
3392
  );
3393
 
3394
- return $this->api->duplicate_pod_item( $params );
3395
  }
3396
 
3397
  /**
@@ -3409,7 +3084,7 @@ class Pods implements Iterator {
3409
  */
3410
  public function import( $import_data, $numeric_mode = false, $format = null ) {
3411
 
3412
- return $this->api->import( $import_data, $numeric_mode, $format );
3413
  }
3414
 
3415
  /**
@@ -3424,7 +3099,7 @@ class Pods implements Iterator {
3424
  * @return array|bool Data array of the exported pod item
3425
  *
3426
  * @since 2.0.0
3427
- * @link https://pods.io/docs/export/
3428
  */
3429
  public function export( $fields = null, $id = null, $format = null ) {
3430
 
@@ -3458,7 +3133,7 @@ class Pods implements Iterator {
3458
  return false;
3459
  }
3460
 
3461
- $data = $this->api->export_pod_item( $params );
3462
 
3463
  if ( ! empty( $params['format'] ) && 'json' === $params['format'] ) {
3464
  $data = wp_json_encode( (array) $data );
@@ -3492,7 +3167,7 @@ class Pods implements Iterator {
3492
  $params = array_merge( $defaults, (array) $params );
3493
  }
3494
 
3495
- return $this->api->export( $this, $params );
3496
  }
3497
 
3498
  /**
@@ -3504,7 +3179,7 @@ class Pods implements Iterator {
3504
  *
3505
  * @return string Pagination HTML
3506
  * @since 2.0.0
3507
- * @link https://pods.io/docs/pagination/
3508
  */
3509
  public function pagination( $params = null ) {
3510
 
@@ -3583,7 +3258,7 @@ class Pods implements Iterator {
3583
  * @return string Filters HTML
3584
  *
3585
  * @since 2.0.0
3586
- * @link https://pods.io/docs/filters/
3587
  */
3588
  public function filters( $params = null ) {
3589
 
@@ -3634,7 +3309,9 @@ class Pods implements Iterator {
3634
  'name' => $name,
3635
  );
3636
 
3637
- if ( ! is_array( $field ) ) {
 
 
3638
  $name = $field;
3639
 
3640
  $field = array(
@@ -3643,7 +3320,7 @@ class Pods implements Iterator {
3643
  }
3644
 
3645
  // @codingStandardsIgnoreLine.
3646
- $field = array_merge( $defaults, $field );
3647
 
3648
  $field['name'] = trim( $field['name'] );
3649
 
@@ -3653,14 +3330,14 @@ class Pods implements Iterator {
3653
 
3654
  if ( isset( $object_fields[ $field['name'] ] ) ) {
3655
  // @codingStandardsIgnoreLine.
3656
- $fields[ $field['name'] ] = array_merge( $object_fields[ $field['name'] ], $field );
3657
  } elseif ( isset( $this->fields[ $field['name'] ] ) ) {
3658
  // @codingStandardsIgnoreLine.
3659
- $fields[ $field['name'] ] = array_merge( $this->fields[ $field['name'] ], $field );
3660
  }
3661
  }//end foreach
3662
 
3663
- // Cleanup.
3664
  unset( $filter_fields );
3665
  }//end if
3666
 
@@ -3699,9 +3376,7 @@ class Pods implements Iterator {
3699
  }
3700
 
3701
  /**
3702
- * Run a helper within a Pod Page or WP Template
3703
- *
3704
- * @see Pods_Helpers::helper
3705
  *
3706
  * @param string|array $helper Helper name.
3707
  * @param string $value Value to run the helper on.
@@ -3727,65 +3402,82 @@ class Pods implements Iterator {
3727
  $params = array_merge( $params, $helper );
3728
  }
3729
 
3730
- if ( class_exists( 'Pods_Helpers' ) ) {
3731
- $value = Pods_Helpers::helper( $params, $this );
3732
- } elseif ( is_callable( $params['helper'] ) ) {
3733
- $disallowed = array(
3734
- 'system',
3735
- 'exec',
3736
- 'popen',
3737
- 'eval',
3738
- 'preg_replace',
3739
- 'create_function',
3740
- 'include',
3741
- 'include_once',
3742
- 'require',
3743
- 'require_once',
3744
- );
3745
 
3746
- $allowed = array();
 
 
3747
 
3748
- /**
3749
- * Allows adjusting the disallowed callbacks as needed.
3750
- *
3751
- * @param array $disallowed List of callbacks not allowed.
3752
- * @param array $params Parameters used by Pods::helper() method.
3753
- *
3754
- * @since 2.7.0
3755
- */
3756
- $disallowed = apply_filters( 'pods_helper_disallowed_callbacks', $disallowed, $params );
3757
 
3758
- /**
3759
- * Allows adjusting the allowed allowed callbacks as needed.
3760
- *
3761
- * @param array $allowed List of callbacks explicitly allowed.
3762
- * @param array $params Parameters used by Pods::helper() method.
3763
- *
3764
- * @since 2.7.0
3765
- */
3766
- $allowed = apply_filters( 'pods_helper_allowed_callbacks', $allowed, $params );
 
 
 
 
 
 
 
 
3767
 
3768
- // Clean up helper callback (if string).
3769
- if ( is_string( $params['helper'] ) ) {
3770
- $params['helper'] = strip_tags( str_replace( array( '`', chr( 96 ) ), "'", $params['helper'] ) );
3771
- }
3772
 
3773
- $is_allowed = false;
 
 
 
 
 
 
 
 
3774
 
3775
- if ( ! empty( $allowed ) ) {
3776
- if ( in_array( $params['helper'], $allowed, true ) ) {
3777
- $is_allowed = true;
3778
- }
3779
- } elseif ( ! in_array( $params['helper'], $disallowed, true ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3780
  $is_allowed = true;
3781
  }
 
 
 
3782
 
3783
- if ( $is_allowed ) {
3784
- $value = call_user_func( $params['helper'], $value );
3785
- }
3786
- } else {
3787
- $value = apply_filters( $params['helper'], $value );
3788
- }//end if
3789
 
3790
  return $value;
3791
  }
@@ -3802,7 +3494,7 @@ class Pods implements Iterator {
3802
  * @return mixed Template output
3803
  *
3804
  * @since 2.0.0
3805
- * @link https://pods.io/docs/template/
3806
  */
3807
  public function template( $template_name, $code = null, $deprecated = false ) {
3808
 
@@ -3810,7 +3502,9 @@ class Pods implements Iterator {
3810
 
3811
  $obj =& $this;
3812
 
3813
- if ( ! empty( $code ) ) {
 
 
3814
  // backwards compatibility.
3815
  $code = str_replace( '$this->', '$obj->', $code );
3816
 
@@ -3868,8 +3562,15 @@ class Pods implements Iterator {
3868
  * @param Pods $pod Pods object.
3869
  */
3870
  $out = apply_filters( "pods_templates_post_template_{$template_name}", $out, $code, $template_name, $this );
3871
- } elseif ( class_exists( 'Pods_Templates' ) ) {
3872
- $out = Pods_Templates::template( $template_name, $code, $this, $deprecated );
 
 
 
 
 
 
 
3873
  } elseif ( trim( preg_replace( '/[^a-zA-Z0-9_\-\/]/', '', $template_name ), ' /-' ) === $template_name ) {
3874
  ob_start();
3875
 
@@ -3918,7 +3619,16 @@ class Pods implements Iterator {
3918
  $out = apply_filters( "pods_templates_post_template_{$template_name}", $out, $code, $template_name, $this );
3919
  }//end if
3920
 
3921
- return $out;
 
 
 
 
 
 
 
 
 
3922
  }
3923
 
3924
  /**
@@ -3932,15 +3642,52 @@ class Pods implements Iterator {
3932
  *
3933
  * @return bool|mixed
3934
  * @since 2.0.0
3935
- * @link https://pods.io/docs/form/
3936
  */
3937
  public function form( $params = null, $label = null, $thank_you = null ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3938
 
3939
  $defaults = array(
3940
  'fields' => $params,
3941
  'label' => $label,
3942
  'thank_you' => $thank_you,
3943
  'fields_only' => false,
 
3944
  );
3945
 
3946
  if ( is_array( $params ) ) {
@@ -3953,41 +3700,41 @@ class Pods implements Iterator {
3953
 
3954
  $params = $this->do_hook( 'form_params', $params );
3955
 
3956
- $fields = $params['fields'];
3957
 
3958
- if ( null !== $fields && ! is_array( $fields ) && 0 < strlen( $fields ) ) {
3959
- $fields = explode( ',', $fields );
3960
  }
3961
 
3962
- $object_fields = (array) pods_v( 'object_fields', $this->pod_data, array(), true );
3963
 
3964
- if ( empty( $fields ) ) {
3965
- // Add core object fields if $fields is empty.
3966
- $fields = array_merge( $object_fields, $this->fields );
3967
- }
3968
 
3969
- // Temporary.
3970
- $form_fields = $fields;
 
3971
 
3972
- $fields = array();
 
 
 
3973
 
3974
  foreach ( $form_fields as $k => $field ) {
3975
  $name = $k;
3976
 
3977
- $defaults = array(
3978
  'name' => $name,
3979
- );
3980
 
3981
- if ( ! is_array( $field ) ) {
3982
  $name = $field;
3983
 
3984
- $field = array(
3985
  'name' => $name,
3986
- );
3987
  }
3988
 
3989
- // @codingStandardsIgnoreLine.
3990
- $field = array_merge( $defaults, $field );
3991
 
3992
  $field['name'] = trim( $field['name'] );
3993
 
@@ -3998,12 +3745,20 @@ class Pods implements Iterator {
3998
  $field['name'] = trim( $name );
3999
  }
4000
 
4001
- if ( isset( $object_fields[ $field['name'] ] ) ) {
4002
- // @codingStandardsIgnoreLine.
4003
- $field = array_merge( $object_fields[ $field['name'] ], $field );
4004
- } elseif ( isset( $this->fields[ $field['name'] ] ) ) {
4005
- // @codingStandardsIgnoreLine.
4006
- $field = array_merge( $this->fields[ $field['name'] ], $field );
 
 
 
 
 
 
 
 
4007
  }
4008
 
4009
  if ( pods_v( 'hidden', $field, false, true ) ) {
@@ -4015,11 +3770,11 @@ class Pods implements Iterator {
4015
  if ( empty( $this->id ) && null !== $default_value ) {
4016
  $this->row_override[ $field['name'] ] = $default_value;
4017
  } elseif ( ! empty( $this->id ) && null !== $value ) {
4018
- $this->row[ $field['name'] ] = $value;
4019
  }
4020
  }//end foreach
4021
 
4022
- // Cleanup.
4023
  unset( $form_fields );
4024
 
4025
  $fields = $this->do_hook( 'form_fields', $fields, $params );
@@ -4032,6 +3787,7 @@ class Pods implements Iterator {
4032
 
4033
  $thank_you = $params['thank_you'];
4034
  $fields_only = $params['fields_only'];
 
4035
 
4036
  PodsForm::$form_counter ++;
4037
 
@@ -4079,47 +3835,45 @@ class Pods implements Iterator {
4079
  /**
4080
  * Render a singular view for the Pod item content.
4081
  *
4082
- * @param array|string|null $fields (optional) Fields to show in the view, defaults to all fields.
4083
  *
4084
  * @return mixed
4085
  * @since 2.3.10
4086
  */
4087
- public function view( $fields = null ) {
4088
 
4089
  $pod =& $this;
4090
 
4091
  // Convert comma separated list of fields to an array.
4092
- if ( null !== $fields && ! is_array( $fields ) && 0 < strlen( $fields ) ) {
4093
- $fields = explode( ',', $fields );
4094
  }
4095
 
4096
- $object_fields = (array) pods_v( 'object_fields', $this->pod_data, array(), true );
4097
 
4098
- if ( empty( $fields ) ) {
4099
- // Add core object fields if $fields is empty.
4100
- $fields = array_merge( $object_fields, $this->fields );
4101
  }
4102
 
4103
- // Temporary.
4104
- $view_fields = $fields;
4105
-
4106
- $fields = array();
4107
 
4108
  foreach ( $view_fields as $name => $field ) {
4109
- $defaults = array(
4110
  'name' => $name,
4111
- );
4112
 
4113
- if ( ! is_array( $field ) ) {
 
 
4114
  $name = $field;
4115
 
4116
- $field = array(
4117
  'name' => $name,
4118
- );
4119
  }
4120
 
4121
- // @codingStandardsIgnoreLine.
4122
- $field = array_merge( $defaults, $field );
4123
 
4124
  $field['name'] = trim( $field['name'] );
4125
 
@@ -4127,24 +3881,22 @@ class Pods implements Iterator {
4127
  $field['name'] = trim( $name );
4128
  }
4129
 
4130
- if ( isset( $object_fields[ $field['name'] ] ) ) {
4131
- // @codingStandardsIgnoreLine.
4132
- $field = array_merge( $field, $object_fields[ $field['name'] ] );
4133
- } elseif ( isset( $this->fields[ $field['name'] ] ) ) {
4134
- // @codingStandardsIgnoreLine.
4135
- $field = array_merge( $this->fields[ $field['name'] ], $field );
4136
  }
4137
 
4138
  if ( pods_v( 'hidden', $field, false, true ) || 'hidden' === $field['type'] ) {
4139
  continue;
4140
- } elseif ( ! PodsForm::permission( $field['type'], $field['name'], $field['options'], $fields, $pod, $pod->id() ) ) {
4141
  continue;
4142
  }
4143
 
4144
  $fields[ $field['name'] ] = $field;
4145
  }//end foreach
4146
 
4147
- // Cleanup.
4148
  unset( $view_fields );
4149
 
4150
  $output = pods_view( PODS_DIR . 'ui/front/view.php', compact( array_keys( get_defined_vars() ) ), false, 'cache', true );
@@ -4305,8 +4057,8 @@ class Pods implements Iterator {
4305
  $this->ui = $options;
4306
 
4307
  return pods_ui( $this );
4308
- } elseif ( ! empty( $options ) || 'custom' !== pods_v( 'ui_style', $this->pod_data['options'], 'post_type', true ) ) {
4309
- $actions_enabled = pods_v( 'ui_actions_enabled', $this->pod_data['options'] );
4310
 
4311
  if ( ! empty( $actions_enabled ) ) {
4312
  $actions_enabled = (array) $actions_enabled;
@@ -4340,7 +4092,7 @@ class Pods implements Iterator {
4340
  'export' => 'export',
4341
  );
4342
 
4343
- if ( 1 === pods_v( 'ui_export', $this->pod_data['options'], 0 ) ) {
4344
  unset( $actions_disabled['export'] );
4345
  }
4346
  }//end if
@@ -4397,7 +4149,7 @@ class Pods implements Iterator {
4397
  $manage['modified'] = $this->pod_data['fields']['modified']['label'];
4398
  }
4399
 
4400
- $manage_fields = (array) pods_v( 'ui_fields_manage', $this->pod_data['options'] );
4401
 
4402
  if ( ! empty( $manage_fields ) ) {
4403
  $manage_new = array();
@@ -4427,13 +4179,13 @@ class Pods implements Iterator {
4427
  $pod_name = $this->pod;
4428
  $manage = apply_filters( "pods_admin_ui_fields_{$pod_name}", apply_filters( 'pods_admin_ui_fields', $manage, $this->pod, $this ), $this->pod, $this );
4429
 
4430
- $icon = pods_v( 'ui_icon', $this->pod_data['options'] );
4431
 
4432
  if ( ! empty( $icon ) ) {
4433
  $icon = pods_image_url( $icon, '32x32' );
4434
  }
4435
 
4436
- $filters = pods_v( 'ui_filters', $this->pod_data['options'] );
4437
 
4438
  if ( ! empty( $filters ) ) {
4439
  $filters_new = array();
@@ -4469,7 +4221,7 @@ class Pods implements Iterator {
4469
  $ui['filters_enhanced'] = true;
4470
  }
4471
 
4472
- $reorder_field = pods_v( 'ui_reorder_field', $this->pod_data['options'] );
4473
 
4474
  if ( ! empty( $reorder_field ) && in_array( 'reorder', $actions_enabled, true ) && ! in_array( 'reorder', $actions_disabled, true ) && ( ( ! empty( $this->pod_data['object_fields'] ) && isset( $this->pod_data['object_fields'][ $reorder_field ] ) ) || isset( $this->pod_data['fields'][ $reorder_field ] ) ) ) {
4475
  $ui['reorder'] = array( 'on' => $reorder_field );
@@ -4495,7 +4247,7 @@ class Pods implements Iterator {
4495
  );
4496
  }
4497
 
4498
- $detail_url = pods_v( 'detail_url', $this->pod_data['options'] );
4499
 
4500
  if ( 0 < strlen( $detail_url ) ) {
4501
  $ui['actions_custom'] = array(
@@ -4562,35 +4314,117 @@ class Pods implements Iterator {
4562
  * @since 2.0.0
4563
  */
4564
  public function __get( $name ) {
4565
-
4566
  $name = (string) $name;
4567
 
4568
- // PodsData vars.
4569
- if ( isset( $this->data->{$name} ) && 0 === strpos( $name, 'field_' ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4570
  return $this->data->{$name};
4571
  }
4572
 
4573
- if ( ! $this->deprecated ) {
4574
- require_once PODS_DIR . 'deprecated/classes/Pods.php';
 
 
 
 
 
 
4575
 
4576
- $this->deprecated = new Pods_Deprecated( $this );
 
 
 
 
 
4577
  }
4578
 
4579
- $var = null;
 
 
 
 
4580
 
4581
- $pod_class_exists = class_exists( 'Pod' );
 
4582
 
4583
- if ( isset( $this->deprecated->{$name} ) ) {
4584
- if ( ! $pod_class_exists || Pod::$deprecated_notice ) {
4585
- pods_deprecated( "Pods->{$name}", '2.0' );
4586
- }
4587
 
4588
- $var = $this->deprecated->{$name};
4589
- } elseif ( ! $pod_class_exists || Pod::$deprecated_notice ) {
4590
- pods_deprecated( "Pods->{$name}", '2.0' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4591
  }
 
4592
 
4593
- return $var;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4594
  }
4595
 
4596
  /**
@@ -4618,12 +4452,12 @@ class Pods implements Iterator {
4618
  $this->deprecated = new Pods_Deprecated( $this );
4619
  }
4620
 
4621
- $pod_class_exists = class_exists( 'Pod' );
4622
 
4623
  if ( method_exists( $this->deprecated, $name ) ) {
4624
  return call_user_func_array( array( $this->deprecated, $name ), $args );
4625
  // @codingStandardsIgnoreLine
4626
- } elseif ( ! $pod_class_exists || Pod::$deprecated_notice ) {
4627
  pods_deprecated( "Pods::{$name}", '2.0' );
4628
  }
4629
 
1
  <?php
2
 
3
+ use Pods\Data\Map_Field_Values;
4
+ use Pods\Whatsit\Field;
5
+ use Pods\Whatsit\Pod;
6
+ use Pod as Deprecated_Pod;
7
+
8
  /**
9
  * Pods class.
10
  *
11
  * @package Pods
12
+ *
13
+ * @property null|string $pod The Pod name.
14
+ * @property null|string $pod_id The Pod ID.
15
+ * @property null|string $id The current item ID (singular mode).
16
+ * @property null|string $rows The list of rows.
17
+ * @property null|string $row The current row.
18
+ * @property null|string $pagination Whether pagination is enabled.
19
+ * @property null|string $page The current page number.
20
+ * @property null|string $page_var The query variable used for pagination.
21
+ * @property null|string $search Whether search is enabled.
22
+ * @property null|string $search_var The query variable used for search.
23
+ * @property null|string $search_mode The search mode to use.
24
+ * @property null|string $params The last find() params.
25
+ * @property null|string $sql The last find() SQL query.
26
  */
27
  class Pods implements Iterator {
28
 
33
  */
34
  private $iterator = false;
35
 
 
 
 
 
 
 
 
36
  /**
37
  * PodsData object.
38
  *
47
  */
48
  public $alt_data;
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  /**
51
  * Override pod item array.
52
  *
64
  /**
65
  * Current pod information.
66
  *
67
+ * @var \Pods\Whatsit\Pod|array|bool|mixed|null|void
68
  */
69
  public $pod_data;
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  /**
72
  * Last used ui options for ui() call.
73
  *
110
  */
111
  public $meta_extra = '';
112
 
 
 
 
 
 
 
 
113
  /**
114
  * Pods_Deprecated object.
115
  *
117
  */
118
  public $deprecated;
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  /**
121
  * Constructor - Pods Framework core.
122
  *
125
  *
126
  * @license http://www.gnu.org/licenses/gpl-2.0.html
127
  * @since 1.0.0
128
+ * @link https://docs.pods.io/code/pods/
129
  */
130
  public function __construct( $pod = null, $id = null ) {
 
131
  if ( null === $pod ) {
132
  $pod = get_queried_object();
133
  }
160
  }
161
  }//end if
162
 
163
+ $maybe_id = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
+ if ( ! is_array( $id ) && ! is_object( $id ) ) {
166
+ $maybe_id = $id;
 
167
  }
168
 
169
+ $this->data = pods_data( $pod, $maybe_id, false );
 
 
 
 
 
 
 
 
170
 
171
+ PodsData::$display_errors =& $this->display_errors;
172
+
173
+ if ( ! $pod ) {
174
+ return;
 
 
 
175
  }
176
 
177
+ $this->pod_data =& $this->data->pod_data;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
 
179
  if ( is_array( $id ) || is_object( $id ) ) {
180
  $this->find( $id );
189
  * @since 2.0.0
190
  */
191
  public function valid() {
192
+ if ( empty( $this->pod_data ) ) {
 
193
  return false;
194
  }
195
 
196
  if ( $this->iterator ) {
197
+ return isset( $this->data->rows[ $this->data->row_number ] );
198
  }
199
 
200
  return true;
210
  * @link http://www.php.net/manual/en/class.iterator.php
211
  */
212
  public function is_iterator() {
 
213
  return $this->iterator;
214
  }
215
 
240
  if ( ! $this->iterator ) {
241
  $this->iterator = true;
242
 
243
+ $this->data->row_number = 0;
244
  }
245
  }
246
 
273
  */
274
  public function key() {
275
 
276
+ return $this->data->row_number;
277
  }
278
 
279
  /**
287
  */
288
  public function next() {
289
 
290
+ $this->data->row_number ++;
291
  }
292
 
293
  /**
299
  */
300
  public function exists() {
301
 
302
+ if ( empty( $this->data->row ) ) {
303
  return false;
304
  }
305
 
315
  * @return array|bool An array of all rows returned from a find() call, or false if no items returned
316
  *
317
  * @since 2.0.0
318
+ * @link https://docs.pods.io/code/pods/data/
319
  */
320
  public function data() {
321
 
322
  do_action( 'pods_pods_data', $this );
323
 
324
+ if ( empty( $this->data->rows ) ) {
325
  return false;
326
  }
327
 
328
+ return (array) $this->data->rows;
329
  }
330
 
331
  /**
340
  * @since 2.3.10
341
  */
342
  public function input( $field, $input_name = null, $value = '__null' ) {
343
+ $is_field_object = $field instanceof Field;
344
 
345
+ if ( is_array( $field ) || $is_field_object ) {
346
  // Field data override.
347
  $field_data = $field;
348
 
379
  * @param null $field Field name.
380
  * @param null $option Option name.
381
  *
382
+ * @return array|\Pods\Whatsit\Field|mixed|null
383
  *
384
  * @since 2.0.0
385
  */
386
+ public function fields( $field_name = null, $option = null ) {
387
 
388
  $field_data = null;
389
 
390
+ if ( empty( $this->pod_data ) ) {
391
+ return null;
392
+ }
393
+
394
+ if ( empty( $field_name ) ) {
395
  // Return all fields.
396
+ $field_data = pods_config_get_all_fields( $this->pod_data );
 
 
 
 
 
 
 
 
 
 
397
  } else {
398
+ $tableless_field_types = PodsForm::tableless_field_types();
399
 
400
+ $field = pods_config_get_field_from_all_fields( $field_name, $this->pod_data );
 
 
 
 
 
401
 
402
+ if ( empty( $field ) || empty( $option ) ) {
403
+ $field_data = $field;
404
+ } elseif ( 'data' === $option && in_array( $field['type'], $tableless_field_types, true ) ) {
405
  // Get a list of available items from a relationship field.
406
+ $field_data = PodsForm::field_method( 'pick', 'get_field_data', $field );
407
+ } elseif ( isset( $field[ $option ] ) ) {
408
  // Return option.
409
+ $field_data = $field[ $option ];
410
+ }//end if
411
  }//end if
412
 
413
  /**
415
  *
416
  * @since unknown
417
  *
418
+ * @param array|\Pods\Whatsit\Field|mixed $field_data The data to be returned for the field / option.
419
+ * @param array|\Pods\Whatsit\Field $field The field information.
420
+ * @param string|null $field_name The specific field that data is being return for, if set when method is called or null.
421
+ * @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.
422
+ * @param Pods|object $this The current Pods class instance.
423
  */
424
+ return apply_filters( 'pods_pods_fields', $field_data, $field_name, $option, $this );
425
 
426
  }
427
 
436
 
437
  do_action( 'pods_pods_row', $this );
438
 
439
+ if ( ! is_array( $this->data->row ) ) {
440
  return false;
441
  }
442
 
443
+ return (array) $this->data->row;
444
  }
445
 
446
  /**
454
  * @return string|null|false The output from the field, null if the field doesn't exist, false if no value returned
455
  * for tableless fields
456
  * @since 2.0.0
457
+ * @link https://docs.pods.io/code/pods/display/
458
  */
459
  public function display( $name, $single = null ) {
460
 
482
  $value = $this->field( $params );
483
 
484
  if ( is_array( $value ) ) {
485
+ $fields = pods_config_get_all_fields( $this->pod_data );
 
 
 
 
486
 
487
  $serial_params = array(
488
  'field' => $params->name,
510
  * @return string|null|false The output from the field, null if the field doesn't exist, false if no value returned
511
  * for tableless fields
512
  * @since 2.0.0
513
+ * @link https://docs.pods.io/code/pods/display/
514
  */
515
  public function raw( $name, $single = null ) {
516
 
551
  * @return mixed|null Value returned depends on the field type, null if the field doesn't exist, false if no value
552
  * returned for tableless fields.
553
  * @since 2.0.0
554
+ * @link https://docs.pods.io/code/pods/field/
555
  */
556
  public function field( $name, $single = null, $raw = false ) {
557
+ $defaults = [
558
+ 'name' => $name,
559
+ 'orderby' => null,
560
+ 'single' => $single,
561
+ 'params' => null,
562
+ 'in_form' => false,
563
+ 'raw' => $raw,
564
+ 'raw_display' => false,
565
+ 'display' => false,
566
+ 'display_process_individually' => false,
567
+ 'get_meta' => false,
568
+ 'output' => null,
569
+ 'deprecated' => false,
570
+ 'keyed' => false,
571
  // extra data to send to field handlers.
572
+ 'args' => [],
573
+ ];
574
 
575
  if ( is_object( $name ) ) {
576
  $name = get_object_vars( $name );
611
  * @param array $params Params array passed to field().
612
  * @param Pods $this Current Pods object.
613
  */
614
+ $params->output = apply_filters( 'pods_pods_field_related_output_type', 'arrays', $this->data->row, $params, $this );
615
  }
616
 
617
  if ( in_array( $params->output, array( 'id', 'name', 'object', 'array', 'pod' ), true ) ) {
620
 
621
  // Support old $orderby variable.
622
  if ( null !== $params->single && is_string( $params->single ) && empty( $params->orderby ) ) {
623
+ if ( ! class_exists( 'Deprecated_Pod' ) || Deprecated_Pod::$deprecated_notice ) {
624
  pods_deprecated( 'Pods::field', '2.0', 'Use $params[ \'orderby\' ] instead' );
625
  }
626
 
654
  }
655
 
656
  if ( $this->data->field_id === $params->name ) {
657
+ if ( isset( $this->data->row[ $params->name ] ) ) {
658
+ return $this->data->row[ $params->name ];
659
  // @codingStandardsIgnoreLine.
660
  } elseif ( null !== $value ) {
661
  return $value;
687
  /** @var string $pod_type The pod object type. */
688
  $pod_type = pods_v( 'type', $this->pod_data, '' );
689
 
690
+ $use_meta_fallback = in_array( $pod_type, $wp_object_types, true );
691
+
692
+ /**
693
+ * Allow hooking in to support getting meta using the meta fallback.
694
+ *
695
+ * @since 2.8.0
696
+ *
697
+ * @param bool $use_meta_fallback Whether to support getting meta using the meta fallback.
698
+ * @param string $object_type The object type.
699
+ */
700
+ $use_meta_fallback = apply_filters( 'pods_field_wp_object_use_meta_fallback', $use_meta_fallback, $pod_type );
701
 
702
  if ( in_array( $params->name, $permalink_fields, true ) ) {
703
  if ( 0 < strlen( $this->detail_page ) && false === strpos( $params->name, 'permalink' ) ) {
746
  $first_field = $traverse_fields[0];
747
  $last_field_data = null;
748
 
749
+ // Get the first field name data.
750
+ $field_data = $this->fields( $first_field );
751
+
752
+ // Ensure the field name is using the correct name and not the alias.
753
+ if ( $field_data ) {
754
+ $first_field = $field_data['name'];
755
+
756
+ if ( ! $is_traversal ) {
757
+ $params->name = $first_field;
758
+ }
759
+ }
760
+
761
+ if ( ! $field_data && ! $is_traversal ) {
762
  // Get the full field name data.
763
+ $field_data = $this->fields( $params->name );
764
+ }
765
+
766
+ if ( $field_data instanceof \Pods\Whatsit\Object_Field ) {
767
+ $field_source = 'object_field';
768
  $is_field_set = true;
769
+ } elseif ( $field_data instanceof \Pods\Whatsit\Field ) {
 
 
770
  $field_source = 'field';
771
  $is_field_set = true;
772
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
773
 
774
  // Store field info.
775
  $field_type = pods_v( 'type', $field_data, '' );
776
+ $field_options = $field_data;
777
  $is_tableless_field = in_array( $field_type, $tableless_field_types, true );
778
 
779
  // Simple fields have no other output options.
789
 
790
  $row_key = '_' . $params->output . '_' . $params->name;
791
 
792
+ if ( 'arrays' !== $params->output && isset( $this->data->row[ $row_key ] ) ) {
793
+ $value = $this->data->row[ $row_key ];
794
+ } elseif ( 'arrays' === $params->output && isset( $this->data->row[ $params->name ] ) ) {
795
+ $value = $this->data->row[ $params->name ];
796
  }
797
 
798
  if (
807
 
808
  if (
809
  empty( $value ) &&
810
+ isset( $this->data->row[ $params->name ] ) &&
811
  ( ! $is_tableless_field || 'arrays' === $params->output )
812
  ) {
813
+ if ( empty( $field_data ) || in_array( $field_type, [
814
+ 'boolean',
815
+ 'number',
816
+ 'currency',
817
+ ], true ) ) {
818
  $params->raw = true;
819
  }
820
 
826
  }
827
  }
828
 
829
+ $value = $this->data->row[ $params->name ];
830
  } elseif ( empty( $value ) ) {
831
  $object_field_found = false;
832
 
833
  if ( 'object_field' === $field_source ) {
834
  $object_field_found = true;
835
 
836
+ if ( isset( $this->data->row[ $first_field ] ) ) {
837
+ $value = $this->data->row[ $first_field ];
838
  } elseif ( $is_tableless_field ) {
 
 
 
839
  $object_field_found = false;
840
  } else {
841
  return null;
842
  }
843
+ } else {
844
+ // Handle custom/supported value mappings.
845
+ $map_field_values = tribe( Map_Field_Values::class );
846
 
847
+ $value = $map_field_values->map_value( $first_field, $traverse_fields, $is_field_set ? $field_data : null, $this );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
848
 
849
+ $object_field_found = null !== $value;
 
 
 
 
 
850
  }
851
 
852
  // Continue regular field parsing.
859
  $params->name = $params->traverse[0];
860
  }
861
 
862
+ $simple = false;
863
 
864
+ if ( $field_data ) {
865
  /**
866
  * Modify value returned by field() after its retrieved, but before its validated or formatted
867
  *
869
  *
870
  * @since unknown
871
  *
872
+ * @param array|string|null $value Value retrieved.
873
+ * @param array $field_data Current field object.
874
+ * @param array|object $row Current row being outputted.
875
+ * @param array $params Params array passed to field().
876
+ * @param object|Pods $this Current Pods object.
877
  */
878
+ $v = apply_filters( "pods_pods_field_{$field_type}", null, $field_data, $this->row(), $params, $this );
879
 
880
  if ( null !== $v ) {
881
  return $v;
882
  }
 
 
 
 
 
883
 
884
  if ( 'meta' === $this->pod_data['storage'] && ! $is_tableless_field ) {
885
  $simple = true;
892
  $simple = true;
893
  $params->single = true;
894
  }
895
+ } elseif ( in_array( $field_type, [
896
+ 'boolean',
897
+ 'number',
898
+ 'currency',
899
+ ], true ) ) {
900
  $params->raw = true;
901
  }
902
  }
917
  pods_no_conflict_on( $pod_type );
918
  }
919
 
920
+ if ( $use_meta_fallback ) {
 
 
921
  $metadata_type = $pod_type;
922
 
923
  if ( in_array( $metadata_type, array( 'post_type', 'media' ), true ) ) {
924
  $metadata_type = 'post';
 
 
 
 
 
 
 
 
 
925
  } elseif ( 'taxonomy' === $metadata_type ) {
926
  $metadata_type = 'term';
927
  }
928
 
929
+ /**
930
+ * Modify the object ID for getting metadata.
931
+ * Added for i18n integration classes.
932
+ *
933
+ * @since 2.8.0
934
+ *
935
+ * @param int $id The object ID.
936
+ * @param string $metadata_type The object metadata type.
937
+ * @param array $params Field params
938
+ * @param \Pods $pod Pods object.
939
+ */
940
+ $id = apply_filters( 'pods_pods_field_get_metadata_object_id', $this->id(), $metadata_type, $params, $this );
941
+
942
  $value = get_metadata( $metadata_type, $id, $params->name, $params->single );
943
 
944
  $single_multi = 'single';
945
 
946
+ if ( $is_field_set ) {
947
+ $single_multi = pods_v( $field_type . '_format_type', $field_data, $single_multi );
948
  }
949
 
950
  if ( $simple && ! is_array( $value ) && 'single' !== $single_multi ) {
960
  $params->single = false;
961
  }
962
 
963
+ $value = PodsForm::field_method( 'pick', 'simple_value', $params->name, $value, $field_data, $this->pod_data, $this->id(), true );
964
  }
965
 
966
  if ( ! $no_conflict ) {
969
  }
970
  } else {
971
  // Dot-traversal.
972
+ $pod = $this->pod_data['name'];
973
  $ids = array( $this->id() );
974
  $all_fields = array();
975
 
977
 
978
  // Get fields matching traversal names.
979
  if ( ! empty( $lookup ) ) {
980
+ if ( 1 === count( $params->traverse ) && $params->name === $params->traverse[0] && $field_data && $field_data['name'] === $params->traverse[0] ) {
981
+ $fields = array(
982
+ $field_data,
983
+ );
984
+ } else {
985
+ $fields = $this->data->api->traverse_fields( array(
986
+ 'pod' => $pod,
987
+ 'expand' => $lookup,
988
+ 'type' => $tableless_field_types,
989
+ ) );
990
+ }
991
 
992
  if ( ! empty( $fields ) ) {
993
  foreach ( $fields as $field ) {
1000
  }
1001
  }
1002
  }
 
 
 
 
 
 
 
 
 
 
1003
  }//end if
1004
 
1005
  $last_type = '';
1006
  $last_object = '';
1007
  $last_pick_val = '';
1008
+ $last_options = array();
1009
 
1010
+ $single_multi = pods_v( $field_type . '_format_type', $field_data, 'single' );
1011
 
1012
  if ( 'multi' === $single_multi ) {
1013
+ $limit = (int) pods_v( $field_type . '_limit', $field_data, 0 );
1014
  } else {
1015
  $limit = 1;
1016
  }
1025
 
1026
  $field_exists = isset( $all_fields[ $pod ][ $field ] );
1027
 
1028
+ $current_field = null;
1029
+ $simple = false;
1030
+
1031
+ if ( $field_exists ) {
1032
+ /** @var \Pods\Whatsit\Field $current_field */
1033
+ $current_field = $all_fields[ $pod ][ $field ];
1034
 
1035
+ if ( in_array( $current_field['type'], $tableless_field_types, true ) ) {
1036
+ $last_options = $current_field;
1037
+
1038
+ if ( 'pick' === $current_field['type'] && in_array( $current_field->get_related_object_type(), $simple_tableless_objects, true ) ) {
1039
+ $simple = true;
1040
+ }
1041
+ }
1042
  }
1043
 
1044
  // Tableless handler.
1045
+ if ( $field_exists && ( ! $simple || ! in_array( $current_field['type'], array(
1046
  'pick',
1047
  'taxonomy',
1048
  'comment',
1049
  ), true ) ) ) {
1050
+ $type = $current_field['type'];
1051
+ $pick_object = $current_field->get_related_object_type();
1052
+ $pick_val = $current_field->get_related_object_name();
 
 
 
 
 
 
1053
 
1054
  $last_limit = 0;
1055
 
1056
  if ( in_array( $type, $tableless_field_types, true ) ) {
1057
+ $single_multi = $current_field->get_arg( "{$type}_format_type", 'single' );
1058
 
1059
  if ( 'multi' === $single_multi ) {
1060
+ $last_limit = (int) $current_field->get_arg( "{$type}_limit", 0 );
1061
  } else {
1062
  $last_limit = 1;
1063
  }
1066
  $last_type = $type;
1067
  $last_object = $pick_object;
1068
  $last_pick_val = $pick_val;
1069
+ $last_options = $current_field;
1070
 
1071
  // Temporary hack until there's some better handling here.
1072
  $last_limit *= count( $ids );
1073
 
1074
  // Get related IDs.
1075
+ if ( isset( $current_field['id'] ) ) {
1076
+ $ids = $this->data->api->lookup_related_items( $current_field['id'], $current_field->get_parent_id(), $ids, $current_field );
 
 
 
 
1077
  }
1078
 
1079
  // No items found.
1080
  if ( empty( $ids ) ) {
1081
+ // pods_debug( 'No related IDs found! ' . var_export( array( 'id' => $current_field['id'], 'pod_id' => $current_field->get_parent_id(), 'ids' => $ids, 'current_field' => empty( $current_field['id'] ) ? $current_field : 'has field id tho' ), true ) );
1082
+
1083
  return false;
1084
+ }
1085
+
1086
+ // pods_debug( 'Related IDs found! ' . var_export( array( 'id' => $current_field['id'], 'pod_id' => $current_field->get_parent_id(), 'ids' => $ids ), true ) );
1087
+
1088
+ if ( 0 < $last_limit ) {
1089
  // @todo This should return array() if not $params->single.
1090
  $ids = array_slice( $ids, 0, $last_limit );
1091
  }
1099
  if ( 'pod' === $pick_object ) {
1100
  $pod = $pick_val;
1101
  } else {
1102
+ $check = $current_field->get_table_info();
1103
 
1104
+ if ( $check && ! empty( $check['pod'] ) ) {
1105
  $pod = $check['pod']['name'];
1106
  }
1107
  }
1123
 
1124
  if ( in_array( $last_type, PodsForm::file_field_types(), true ) ) {
1125
  $object_type = 'media';
1126
+ $object = 'media';
1127
  }
1128
 
1129
+ $data = array();
1130
+ $table = array();
1131
 
1132
+ if ( $last_options ) {
1133
+ $table = $last_options->get_table_info();
1134
+ }
1135
 
1136
  $join = array();
1137
  $where = array();
1140
  $join = (array) $table['join'];
1141
  }
1142
 
1143
+ // pods_debug( 'IDs found: ' . var_export( $ids, true ) );
1144
+
1145
+ if ( $table && ( ! empty( $ids ) || ! empty( $table['where'] ) ) ) {
1146
  foreach ( $ids as $id ) {
1147
  $where[ $id ] = '`t`.`' . $table['field_id'] . '` = ' . (int) $id;
1148
  }
1177
  $related_obj = pods( $table['pod']['name'], null, false );
1178
  }
1179
 
1180
+ if ( $table && ( $related_obj || ! empty( $table['table'] ) ) ) {
1181
  $sql = array(
1182
  'select' => '*, `t`.`' . $table['field_id'] . '` AS `pod_item_id`',
1183
  'table' => $table['table'],
1218
 
1219
  if ( ! $related_obj || ! $related_obj->valid() ) {
1220
  if ( ! is_object( $this->alt_data ) ) {
1221
+ $this->alt_data = pods_data();
1222
  }
1223
 
1224
  $item_data = $this->alt_data->select( $sql );
1372
  // Return an array of single column values.
1373
  $value = array();
1374
 
1375
+ // $field is 123x123, needs to be _src.123x123
1376
+ $traverse_fields = array_splice( $params->traverse, $key );
1377
+ $full_field = implode( '.', $traverse_fields );
1378
+ array_shift( $traverse_fields );
 
1379
 
1380
+ foreach ( $data as $item_id => $item ) {
1381
  if ( is_array( $item ) && isset( $item[ $field ] ) ) {
1382
  if ( $table['field_id'] === $field ) {
1383
  $value[] = (int) $item[ $field ];
1397
  (
1398
  ( false !== strpos( $full_field, '_src' ) || 'guid' === $field )
1399
  && (
1400
+ in_array( $table['type'], [ 'attachment', 'media' ], true )
1401
  || in_array( $last_type, PodsForm::file_field_types(), true )
1402
  )
1403
  )
1491
 
1492
  $metadata_type = $object_type;
1493
 
1494
+ if ( 'taxonomy' === $object_type ) {
 
 
 
 
 
 
 
 
 
1495
  $metadata_type = 'term';
1496
  }
1497
 
1498
+ /** This filter is documented earlier in this method */
1499
+ $metadata_object_id = apply_filters( 'pods_pods_field_get_metadata_object_id', $metadata_object_id, $metadata_type, $params, $this );
1500
+
1501
  $meta_value = get_metadata( $metadata_type, $metadata_object_id, $field, true );
1502
+
1503
+ $value[] = pods_traverse( $traverse_fields, $meta_value );
1504
  } elseif ( 'settings' === $object_type ) {
1505
  $option_value = get_option( $object . '_' . $field );
1506
+
1507
+ $value[] = pods_traverse( $traverse_fields, $option_value );
1508
  }//end if
1509
  }//end foreach
1510
  }//end if
1531
  }
1532
  }//end if
1533
 
1534
+ // pods_debug( 'value' );
1535
+ // pods_debug( compact( 'value', 'data' ) );
1536
+
1537
  if ( $last_options ) {
1538
  $last_field_data = $last_options;
1539
  } elseif ( isset( $related_obj, $related_obj->fields, $related_obj->fields[ $field ] ) ) {
1551
  if ( ! empty( $params->traverse ) && 1 < count( $params->traverse ) ) {
1552
  $field_names = implode( '.', $params->traverse );
1553
 
1554
+ $this->data->row[ $field_names ] = $value;
1555
+ } elseif ( 'arrays' !== $params->output && $field_data && in_array( $field_data['type'], $tableless_field_types, true ) ) {
1556
+ $this->data->row[ '_' . $params->output . '_' . $params->full_name ] = $value;
1557
+ } elseif ( 'arrays' === $params->output || ! $field_data || ! in_array( $field_data['type'], $tableless_field_types, true ) ) {
1558
+ $this->data->row[ $params->full_name ] = $value;
1559
  }
1560
 
1561
  if ( true === $params->single && is_array( $value ) && 1 === count( $value ) ) {
1568
 
1569
  if ( ! empty( $field_data ) && ( $params->display || ! $params->raw ) && ! $params->in_form && ! $params->raw_display ) {
1570
  if ( $params->display || ( ( $params->get_meta || $params->deprecated ) && ! in_array( $field_data['type'], $tableless_field_types, true ) ) ) {
 
 
1571
  $post_temp = false;
1572
  $old_post = null;
1573
  $old_post_id = null;
1587
  $post_ID = $this->id();
1588
  }
1589
 
1590
+ $filter = pods_v( 'display_filter', $field_data );
1591
 
1592
  if ( 0 < strlen( $filter ) ) {
 
1593
  if ( $params->single ) {
1594
  $value = array( $value );
1595
  }
1596
 
1597
  foreach ( $value as $key => $val ) {
 
1598
  $args = array(
1599
  $filter,
1600
  $val,
1601
  );
1602
 
1603
+ $filter_args = pods_v( 'display_filter_args', $field_data );
1604
 
1605
  if ( ! empty( $filter_args ) ) {
1606
  $args = array_merge( $args, compact( $filter_args ) );
1615
  if ( $params->single ) {
1616
  $value = reset( $value );
1617
  }
1618
+ } elseif ( 1 === (int) pods_v( 'display_process', $field_data, 1 ) ) {
1619
+ if ( ! is_array( $value ) || ! $params->display_process_individually ) {
1620
+ // Do the normal display handling.
1621
+ $value = PodsForm::display( $field_data['type'], $value, $params->name, $field_data, $this->pod_data, $this->id() );
1622
+ } else {
1623
+ // Attempt to process each value independently.
1624
+ foreach ( $value as $k => $val ) {
1625
+ $value[ $k ] = PodsForm::display( $field_data['type'], $val, $params->name, $field_data, $this->pod_data, $this->id() );
1626
+ }
1627
+ }
1628
  }
1629
 
1630
  if ( $post_temp ) {
1634
  $post_ID = $old_post_id;
1635
  }
1636
  } else {
1637
+ $value = PodsForm::value( $field_data['type'], $value, $params->name, $field_data, $this->pod_data, $this->id() );
1638
  }//end if
1639
  }//end if
1640
 
1650
  * @param array $params Params array passed to field().
1651
  * @param object|Pods $this Current Pods object.
1652
  */
1653
+ $value = apply_filters( 'pods_pods_field', $value, $this->row(), $params, $this );
1654
 
1655
  return $value;
1656
  }
1703
  }
1704
  }
1705
  } else {
1706
+ $related_ids = $this->data->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data );
1707
 
1708
  foreach ( $value as $k => $v ) {
1709
  if ( ! preg_match( '/[^\D]/', $v ) ) {
1785
  }
1786
  }
1787
  } else {
1788
+ $related_ids = $this->data->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data );
1789
 
1790
  foreach ( $value as $k => $v ) {
1791
  if ( ! preg_match( '/[^\D]/', $v ) ) {
1866
  */
1867
  public function id() {
1868
 
1869
+ if ( isset( $this->data->row['id'] ) ) {
1870
  // If we already have data loaded return that ID.
1871
  return $this->data->row['id'];
1872
  }
1918
  }
1919
  } elseif ( isset( $params['offset'] ) && 0 < $params['offset'] ) {
1920
  $params['offset'] --;
1921
+ } elseif ( 0 < $this->data->row_number && ! isset( $params['offset'] ) && ! empty( $this->params ) ) {
1922
+ $params['offset'] = $this->data->row_number - 1;
1923
  } else {
1924
  return 0;
1925
  }
2006
  $params['where'] = "{$id} < `t`.`{$this->data->field_id}`";
2007
  }
2008
  } elseif ( ! isset( $params['offset'] ) ) {
2009
+ if ( ! empty( $this->params ) && - 1 < $this->data->row_number ) {
2010
+ $params['offset'] = $this->data->row_number + 1;
2011
  } else {
2012
  $params['offset'] = 1;
2013
  }
2170
  *
2171
  * @return \Pods The pod object
2172
  * @since 2.0.0
2173
+ * @link https://docs.pods.io/code/pods/find/
2174
  */
2175
  public function find( $params = null, $limit = 15, $where = null, $sql = null ) {
2176
 
2181
 
2182
  $select = '`t`.*';
2183
 
2184
+ if ( ! $this->pod_data instanceof Pods\Whatsit\Pod ) {
2185
+ return $this;
2186
+ }
2187
+
2188
  if ( 'table' === $this->pod_data['storage'] && ! in_array( $this->pod_data['type'], array(
2189
  'pod',
2190
  'table',
2192
  $select .= ', `d`.*';
2193
  }
2194
 
2195
+ $table = $this->pod_data['table'];
2196
+
2197
+ if ( empty( $table ) ) {
2198
  return $this;
2199
  }
2200
 
2201
  $defaults = array(
2202
  // Optimization parameters.
2203
+ 'table' => $table,
2204
  'select' => $select,
2205
  'join' => null,
2206
  // Main query parameters.
2278
  $order = 'DESC';
2279
  }
2280
 
2281
+ $order_field = $this->fields( $k );
2282
+
2283
+ if ( $order_field && in_array( $order_field['type'], $tableless_field_types, true ) ) {
2284
+ $order_object_type = $order_field->get_related_object_type();
2285
+ $order_object_name = $order_field->get_related_object_name();
2286
+
2287
+ if ( in_array( $order_object_type, $simple_tableless_objects, true ) ) {
2288
  if ( 'table' === $this->pod_data['storage'] ) {
2289
  if ( ! in_array( $this->pod_data['type'], array( 'pod', 'table' ), true ) ) {
2290
  $key = "`d`.`{$k}`";
2295
  $key = "`{$k}`.`meta_value`";
2296
  }
2297
  } else {
2298
+ $table = $order_field->get_table_info();
 
 
 
 
 
 
2299
 
2300
  if ( ! empty( $table ) ) {
2301
  $key = "`{$k}`.`" . $table['field_index'] . '`';
2307
  if ( ! in_array( $this->pod_data['type'], array( 'pod', 'table' ), true ) ) {
2308
  if ( isset( $this->pod_data['object_fields'][ $k ] ) ) {
2309
  $key = "`t`.`{$k}`";
2310
+ } elseif ( $order_field ) {
2311
  if ( 'table' === $this->pod_data['storage'] ) {
2312
  $key = "`d`.`{$k}`";
2313
  } else {
2322
  }
2323
  }
2324
  }
2325
+ } elseif ( $order_field ) {
2326
  if ( 'table' === $this->pod_data['storage'] ) {
2327
  $key = "`t`.`{$k}`";
2328
  } else {
2368
 
2369
  $key = $k;
2370
 
2371
+ $order_field = $this->fields( $k );
2372
+
2373
  if ( ! in_array( $this->pod_data['type'], array( 'pod', 'table' ), true ) ) {
2374
  if ( isset( $this->pod_data['object_fields'][ $k ] ) ) {
2375
  $key = "`t`.`{$k}`";
2376
+ } elseif ( $order_field ) {
2377
  if ( 'table' === $this->pod_data['storage'] ) {
2378
  $key = "`d`.`{$k}`";
2379
  } else {
2388
  }
2389
  }
2390
  }
2391
+ } elseif ( $order_field ) {
2392
  if ( 'table' === $this->pod_data['storage'] ) {
2393
  $key = "`t`.`{$k}`";
2394
  } else {
2423
  * @return array An array of fields from the row
2424
  *
2425
  * @since 2.0.0
2426
+ * @link https://docs.pods.io/code/pods/fetch/
2427
  */
2428
  public function fetch( $id = null, $explicit_set = true ) {
2429
 
2443
 
2444
  $this->data->fetch( $id, $explicit_set );
2445
 
2446
+ return $this->row();
2447
  }
2448
 
2449
  /**
2456
  * @return \Pods The pod object
2457
  *
2458
  * @since 2.0.0
2459
+ * @link https://docs.pods.io/code/pods/reset/
2460
  */
2461
  public function reset( $row = null ) {
2462
 
2484
  *
2485
  * @return int Number of rows returned by find(), based on the 'limit' parameter set
2486
  * @since 2.0.0
2487
+ * @link https://docs.pods.io/code/pods/total/
2488
  */
2489
  public function total() {
2490
 
2492
 
2493
  $this->data->total();
2494
 
2495
+ return $this->data->total;
 
 
2496
  }
2497
 
2498
  /**
2504
  *
2505
  * @return int Number of rows returned by find(), regardless of the 'limit' parameter
2506
  * @since 2.0.0
2507
+ * @link https://docs.pods.io/code/pods/total-found/
2508
  */
2509
  public function total_found() {
2510
 
2519
 
2520
  $this->data->total_found();
2521
 
2522
+ return $this->data->total_found;
 
 
2523
  }
2524
 
2525
  /**
2613
  * @return int The item ID
2614
  *
2615
  * @since 2.0.0
2616
+ * @link https://docs.pods.io/code/pods/add/
2617
  */
2618
  public function add( $data = null, $value = null ) {
2619
 
2633
  'allow_custom_fields' => true,
2634
  );
2635
 
2636
+ return $this->data->api->save_pod_item( $params );
2637
  }
2638
 
2639
  /**
2688
 
2689
  $value = array_merge( $current_value, $value );
2690
  } else {
2691
+ $related_ids = $this->data->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data );
2692
 
2693
  foreach ( $value as $k => $v ) {
2694
  if ( ! preg_match( '/[^\D]/', $v ) ) {
2740
  ),
2741
  );
2742
 
2743
+ $id = $this->data->api->save_pod_item( $params );
2744
 
2745
  if ( 0 < $id && $fetch ) {
2746
  // Clear local var cache of field values.
2814
 
2815
  $value = $current_value;
2816
  } else {
2817
+ $related_ids = $this->data->api->lookup_related_items( $this->fields[ $field ]['id'], $this->pod_data['id'], $id, $this->fields[ $field ], $this->pod_data );
2818
 
2819
  foreach ( $value as $k => $v ) {
2820
  if ( ! preg_match( '/[^\D]/', $v ) ) {
2877
  ),
2878
  );
2879
 
2880
+ $id = $this->data->api->save_pod_item( $params );
2881
 
2882
  if ( 0 < $id && $fetch ) {
2883
  // Clear local var cache of field values.
2906
  * @return int The item ID
2907
  *
2908
  * @since 2.0.0
2909
+ * @link https://docs.pods.io/code/pods/save/
2910
  */
2911
  public function save( $data = null, $value = null, $id = null, $params = null ) {
2912
 
2917
  $fetch = false;
2918
 
2919
  // @codingStandardsIgnoreLine
2920
+ if ( null === $id || ( $this->row() && $id == $this->id() ) ) {
2921
  $fetch = true;
2922
 
2923
  if ( null === $id ) {
2927
 
2928
  $data = (array) $this->do_hook( 'save', $data, $id );
2929
 
2930
+ if ( empty( $data ) && empty( $params['is_new_item'] ) && empty( $params['podsmeta'] ) ) {
2931
  return $id;
2932
  }
2933
 
2937
  $default = $params;
2938
  }
2939
 
2940
+ // If ID is sent as part of data, use it and then unset it from the data.
2941
+ if ( isset( $data[ $this->pod_data['field_id'] ] ) ) {
2942
+ $id = $data[ $this->pod_data['field_id'] ];
2943
+
2944
+ unset( $data[ $this->pod_data['field_id'] ] );
2945
+ }
2946
+
2947
  $params = array(
2948
  'pod' => $this->pod,
2949
  'id' => $id,
2956
  $params = array_merge( $params, $default );
2957
  }
2958
 
2959
+ $id = $this->data->api->save_pod_item( $params );
2960
 
2961
  if ( 0 < $id && $fetch ) {
2962
  // Clear local var cache of field values.
2990
  * @return bool Whether the item was successfully deleted
2991
  *
2992
  * @since 2.0.0
2993
+ * @link https://docs.pods.io/code/pods/delete/
2994
  */
2995
  public function delete( $id = null ) {
2996
 
3009
  'id' => $id,
3010
  );
3011
 
3012
+ return $this->data->api->delete_pod_item( $params );
3013
  }
3014
 
3015
  /**
3022
  * @since 2.1.1
3023
  */
3024
  public function reset_pod() {
3025
+ $params = [
3026
+ 'id' => $this->pod_id,
3027
+ 'name' => $this->pod,
3028
+ ];
3029
 
3030
  $this->data->id = null;
3031
+ $this->data->row = [];
3032
+ $this->data->data = [];
3033
 
3034
  $this->data->total = 0;
3035
  $this->data->total_found = 0;
3036
 
3037
+ return $this->data->api->reset_pod( $params );
3038
  }
3039
 
3040
  /**
3047
  * @return int|bool ID of the new pod item
3048
  *
3049
  * @since 2.0.0
3050
+ * @link https://docs.pods.io/code/pods/duplicate/
3051
  */
3052
  public function duplicate( $id = null ) {
3053
 
3066
  'id' => $id,
3067
  );
3068
 
3069
+ return $this->data->api->duplicate_pod_item( $params );
3070
  }
3071
 
3072
  /**
3084
  */
3085
  public function import( $import_data, $numeric_mode = false, $format = null ) {
3086
 
3087
+ return $this->data->api->import( $import_data, $numeric_mode, $format );
3088
  }
3089
 
3090
  /**
3099
  * @return array|bool Data array of the exported pod item
3100
  *
3101
  * @since 2.0.0
3102
+ * @link https://docs.pods.io/code/pods/export/
3103
  */
3104
  public function export( $fields = null, $id = null, $format = null ) {
3105
 
3133
  return false;
3134
  }
3135
 
3136
+ $data = $this->data->api->export_pod_item( $params );
3137
 
3138
  if ( ! empty( $params['format'] ) && 'json' === $params['format'] ) {
3139
  $data = wp_json_encode( (array) $data );
3167
  $params = array_merge( $defaults, (array) $params );
3168
  }
3169
 
3170
+ return $this->data->api->export( $this, $params );
3171
  }
3172
 
3173
  /**
3179
  *
3180
  * @return string Pagination HTML
3181
  * @since 2.0.0
3182
+ * @link https://docs.pods.io/code/pods/pagination/
3183
  */
3184
  public function pagination( $params = null ) {
3185
 
3258
  * @return string Filters HTML
3259
  *
3260
  * @since 2.0.0
3261
+ * @link https://docs.pods.io/code/pods/filters/
3262
  */
3263
  public function filters( $params = null ) {
3264
 
3309
  'name' => $name,
3310
  );
3311
 
3312
+ $is_field_object = $field instanceof Field;
3313
+
3314
+ if ( ! is_array( $field ) && ! $is_field_object ) {
3315
  $name = $field;
3316
 
3317
  $field = array(
3320
  }
3321
 
3322
  // @codingStandardsIgnoreLine.
3323
+ $field = pods_config_merge_data( $defaults, $field );
3324
 
3325
  $field['name'] = trim( $field['name'] );
3326
 
3330
 
3331
  if ( isset( $object_fields[ $field['name'] ] ) ) {
3332
  // @codingStandardsIgnoreLine.
3333
+ $fields[ $field['name'] ] = pods_config_merge_data( $object_fields[ $field['name'] ], $field );
3334
  } elseif ( isset( $this->fields[ $field['name'] ] ) ) {
3335
  // @codingStandardsIgnoreLine.
3336
+ $fields[ $field['name'] ] = pods_config_merge_data( $this->fields[ $field['name'] ], $field );
3337
  }
3338
  }//end foreach
3339
 
3340
+ // Cleanup before get_defined_vars().
3341
  unset( $filter_fields );
3342
  }//end if
3343
 
3376
  }
3377
 
3378
  /**
3379
+ * Run a helper within a Pod Page or WP Template.
 
 
3380
  *
3381
  * @param string|array $helper Helper name.
3382
  * @param string $value Value to run the helper on.
3402
  $params = array_merge( $params, $helper );
3403
  }
3404
 
3405
+ /**
3406
+ * Allows changing whether callbacks are allowed to run.
3407
+ *
3408
+ * @param bool $allowed Whether callbacks are allowed to run.
3409
+ * @param array $params Parameters used by Pods::helper() method.
3410
+ *
3411
+ * @since 2.8.0
3412
+ */
3413
+ $allow_callbacks = (boolean) apply_filters( 'pods_helper_allow_callbacks', true, $params );
 
 
 
 
 
 
3414
 
3415
+ if ( ! $allow_callbacks ) {
3416
+ return $value;
3417
+ }
3418
 
3419
+ if ( ! is_callable( $params['helper'] ) ) {
3420
+ return apply_filters( $params['helper'], $value );
3421
+ }
 
 
 
 
 
 
3422
 
3423
+ $disallowed = array(
3424
+ 'system',
3425
+ 'exec',
3426
+ 'popen',
3427
+ 'eval',
3428
+ 'preg_replace',
3429
+ 'preg_replace_array',
3430
+ 'preg_replace_callback',
3431
+ 'preg_replace_callback_array',
3432
+ 'preg_match',
3433
+ 'preg_match_all',
3434
+ 'create_function',
3435
+ 'include',
3436
+ 'include_once',
3437
+ 'require',
3438
+ 'require_once',
3439
+ );
3440
 
3441
+ $allowed = array();
 
 
 
3442
 
3443
+ /**
3444
+ * Allows adjusting the disallowed callbacks as needed.
3445
+ *
3446
+ * @param array $disallowed List of callbacks not allowed.
3447
+ * @param array $params Parameters used by Pods::helper() method.
3448
+ *
3449
+ * @since 2.7.0
3450
+ */
3451
+ $disallowed = apply_filters( 'pods_helper_disallowed_callbacks', $disallowed, $params );
3452
 
3453
+ /**
3454
+ * Allows adjusting the allowed callbacks as needed.
3455
+ *
3456
+ * @param array $allowed List of callbacks explicitly allowed.
3457
+ * @param array $params Parameters used by Pods::helper() method.
3458
+ *
3459
+ * @since 2.7.0
3460
+ */
3461
+ $allowed = apply_filters( 'pods_helper_allowed_callbacks', $allowed, $params );
3462
+
3463
+ // Clean up helper callback (if string).
3464
+ if ( is_string( $params['helper'] ) ) {
3465
+ $params['helper'] = strip_tags( str_replace( array( '`', chr( 96 ) ), "'", $params['helper'] ) );
3466
+ }
3467
+
3468
+ $is_allowed = false;
3469
+
3470
+ if ( ! empty( $allowed ) ) {
3471
+ if ( in_array( $params['helper'], $allowed, true ) ) {
3472
  $is_allowed = true;
3473
  }
3474
+ } elseif ( ! in_array( $params['helper'], $disallowed, true ) ) {
3475
+ $is_allowed = true;
3476
+ }
3477
 
3478
+ if ( $is_allowed ) {
3479
+ $value = call_user_func( $params['helper'], $value );
3480
+ }
 
 
 
3481
 
3482
  return $value;
3483
  }
3494
  * @return mixed Template output
3495
  *
3496
  * @since 2.0.0
3497
+ * @link https://docs.pods.io/code/pods/template/
3498
  */
3499
  public function template( $template_name, $code = null, $deprecated = false ) {
3500
 
3502
 
3503
  $obj =& $this;
3504
 
3505
+ if ( class_exists( 'Pods_Templates' ) ) {
3506
+ $out = Pods_Templates::template( $template_name, $code, $this, $deprecated );
3507
+ } elseif ( ! empty( $code ) ) {
3508
  // backwards compatibility.
3509
  $code = str_replace( '$this->', '$obj->', $code );
3510
 
3562
  * @param Pods $pod Pods object.
3563
  */
3564
  $out = apply_filters( "pods_templates_post_template_{$template_name}", $out, $code, $template_name, $this );
3565
+
3566
+ /**
3567
+ * Filter the final template output.
3568
+ *
3569
+ * @param string $out Template output.
3570
+ * @param string $code Template code.
3571
+ * @param Pods $pod Pods object.
3572
+ */
3573
+ $out = apply_filters( 'pods_templates_do_template', $out, $code, $this );
3574
  } elseif ( trim( preg_replace( '/[^a-zA-Z0-9_\-\/]/', '', $template_name ), ' /-' ) === $template_name ) {
3575
  ob_start();
3576
 
3619
  $out = apply_filters( "pods_templates_post_template_{$template_name}", $out, $code, $template_name, $this );
3620
  }//end if
3621
 
3622
+ /**
3623
+ * Filter the final content.
3624
+ *
3625
+ * @since 2.8.0
3626
+ *
3627
+ * @param string $out The template content.
3628
+ * @param string $code The original template code.
3629
+ * @param Pods $pod The current Pods object.
3630
+ */
3631
+ return apply_filters( 'pods_template_content', $out, $code, $this );
3632
  }
3633
 
3634
  /**
3642
  *
3643
  * @return bool|mixed
3644
  * @since 2.0.0
3645
+ * @link https://docs.pods.io/code/pods/form/
3646
  */
3647
  public function form( $params = null, $label = null, $thank_you = null ) {
3648
+ // Check for anonymous submissions.
3649
+ if ( ! is_user_logged_in() ) {
3650
+ $session_auto_start = pods_session_auto_start();
3651
+
3652
+ // Check if Pods sessions are disabled.
3653
+ if ( false === $session_auto_start ) {
3654
+ return sprintf(
3655
+ '<strong>%1$s</strong> %2$s, <a href="%3$s">%4$s</a> %5$s.',
3656
+ esc_html__( 'Error', 'pods' ),
3657
+ esc_html__( 'Anonymous form submissions are not enabled for this site', 'pods' ),
3658
+ esc_url( wp_login_url( pods_current_url() ) ),
3659
+ esc_html__( 'try logging in first', 'pods' ),
3660
+ esc_html__( 'contacting your site administrator', 'pods' )
3661
+ );
3662
+ }
3663
+
3664
+ // Check if we need to turn on sessions and have visitor refresh page.
3665
+ if ( 'auto' === $session_auto_start ) {
3666
+ pods_update_setting( 'pods_session_auto_start', '1' );
3667
+
3668
+ return sprintf(
3669
+ '<strong>%1$s</strong> %2$s',
3670
+ esc_html__( 'Error', 'pods' ),
3671
+ esc_html__( 'Please refresh the page to access this form.', 'pods' )
3672
+ );
3673
+ }
3674
+
3675
+ // Check if the session started properly.
3676
+ if ( '' === pods_session_id() ) {
3677
+ return sprintf(
3678
+ '<strong>%1$s</strong> %2$s',
3679
+ esc_html__( 'Error', 'pods' ),
3680
+ esc_html__( 'Anonymous form submissions are not compatible with sessions on this site.', 'pods' )
3681
+ );
3682
+ }
3683
+ }
3684
 
3685
  $defaults = array(
3686
  'fields' => $params,
3687
  'label' => $label,
3688
  'thank_you' => $thank_you,
3689
  'fields_only' => false,
3690
+ 'output_type' => 'div',
3691
  );
3692
 
3693
  if ( is_array( $params ) ) {
3700
 
3701
  $params = $this->do_hook( 'form_params', $params );
3702
 
3703
+ $form_fields = $params['fields'];
3704
 
3705
+ if ( null !== $form_fields && ! is_array( $form_fields ) && 0 < strlen( $form_fields ) ) {
3706
+ $form_fields = explode( ',', $form_fields );
3707
  }
3708
 
3709
+ $all_fields = pods_config_get_all_fields( $this->pod_data );
3710
 
3711
+ $default_form = false;
 
 
 
3712
 
3713
+ // Get all fields if form fields are empty.
3714
+ if ( empty( $form_fields ) ) {
3715
+ $form_fields = $all_fields;
3716
 
3717
+ $default_form = true;
3718
+ }
3719
+
3720
+ $fields = [];
3721
 
3722
  foreach ( $form_fields as $k => $field ) {
3723
  $name = $k;
3724
 
3725
+ $defaults = [
3726
  'name' => $name,
3727
+ ];
3728
 
3729
+ if ( is_string( $field ) ) {
3730
  $name = $field;
3731
 
3732
+ $field = [
3733
  'name' => $name,
3734
+ ];
3735
  }
3736
 
3737
+ $field = pods_config_merge_data( $defaults, $field );
 
3738
 
3739
  $field['name'] = trim( $field['name'] );
3740
 
3745
  $field['name'] = trim( $name );
3746
  }
3747
 
3748
+ $to_merge = pods_v( $field['name'], $all_fields );
3749
+
3750
+ if ( $to_merge ) {
3751
+ $field = pods_config_merge_data( $to_merge, $field );
3752
+ }
3753
+
3754
+ // Never show the ID field.
3755
+ if ( $this->pod_data['field_id'] === $field['name'] ) {
3756
+ continue;
3757
+ }
3758
+
3759
+ // Hide fields from default form.
3760
+ if ( 1 === (int) pods_v( 'hide_in_default_form', $field ) ) {
3761
+ continue;
3762
  }
3763
 
3764
  if ( pods_v( 'hidden', $field, false, true ) ) {
3770
  if ( empty( $this->id ) && null !== $default_value ) {
3771
  $this->row_override[ $field['name'] ] = $default_value;
3772
  } elseif ( ! empty( $this->id ) && null !== $value ) {
3773
+ $this->data->row[ $field['name'] ] = $value;
3774
  }
3775
  }//end foreach
3776
 
3777
+ // Cleanup before get_defined_vars().
3778
  unset( $form_fields );
3779
 
3780
  $fields = $this->do_hook( 'form_fields', $fields, $params );
3787
 
3788
  $thank_you = $params['thank_you'];
3789
  $fields_only = $params['fields_only'];
3790
+ $output_type = $params['output_type'];
3791
 
3792
  PodsForm::$form_counter ++;
3793
 
3835
  /**
3836
  * Render a singular view for the Pod item content.
3837
  *
3838
+ * @param array|string|null $view_fields (optional) Fields to show in the view, defaults to all fields.
3839
  *
3840
  * @return mixed
3841
  * @since 2.3.10
3842
  */
3843
+ public function view( $view_fields = null ) {
3844
 
3845
  $pod =& $this;
3846
 
3847
  // Convert comma separated list of fields to an array.
3848
+ if ( null !== $view_fields && ! is_array( $view_fields ) && 0 < strlen( $view_fields ) ) {
3849
+ $view_fields = explode( ',', $view_fields );
3850
  }
3851
 
3852
+ $all_fields = pods_config_get_all_fields( $this->pod_data );
3853
 
3854
+ // Get all fields if fields are empty.
3855
+ if ( empty( $view_fields ) ) {
3856
+ $view_fields = $all_fields;
3857
  }
3858
 
3859
+ $fields = [];
 
 
 
3860
 
3861
  foreach ( $view_fields as $name => $field ) {
3862
+ $defaults = [
3863
  'name' => $name,
3864
+ ];
3865
 
3866
+ $is_field_object = $field instanceof Field;
3867
+
3868
+ if ( ! is_array( $field ) && ! $is_field_object ) {
3869
  $name = $field;
3870
 
3871
+ $field = [
3872
  'name' => $name,
3873
+ ];
3874
  }
3875
 
3876
+ $field = pods_config_merge_data( $defaults, $fields );
 
3877
 
3878
  $field['name'] = trim( $field['name'] );
3879
 
3881
  $field['name'] = trim( $name );
3882
  }
3883
 
3884
+ $to_merge = pods_v( $field['name'], $all_fields );
3885
+
3886
+ if ( $to_merge ) {
3887
+ $field = pods_config_merge_data( $to_merge, $field );
 
 
3888
  }
3889
 
3890
  if ( pods_v( 'hidden', $field, false, true ) || 'hidden' === $field['type'] ) {
3891
  continue;
3892
+ } elseif ( ! pods_permission( $field ) ) {
3893
  continue;
3894
  }
3895
 
3896
  $fields[ $field['name'] ] = $field;
3897
  }//end foreach
3898
 
3899
+ // Cleanup before get_defined_vars().
3900
  unset( $view_fields );
3901
 
3902
  $output = pods_view( PODS_DIR . 'ui/front/view.php', compact( array_keys( get_defined_vars() ) ), false, 'cache', true );
4057
  $this->ui = $options;
4058
 
4059
  return pods_ui( $this );
4060
+ } elseif ( ! empty( $options ) || 'custom' !== pods_v( 'ui_style', $this->pod_data, 'post_type', true ) ) {
4061
+ $actions_enabled = pods_v( 'ui_actions_enabled', $this->pod_data );
4062
 
4063
  if ( ! empty( $actions_enabled ) ) {
4064
  $actions_enabled = (array) $actions_enabled;
4092
  'export' => 'export',
4093
  );
4094
 
4095
+ if ( 1 === pods_v( 'ui_export', $this->pod_data, 0 ) ) {
4096
  unset( $actions_disabled['export'] );
4097
  }
4098
  }//end if
4149
  $manage['modified'] = $this->pod_data['fields']['modified']['label'];
4150
  }
4151
 
4152
+ $manage_fields = (array) pods_v( 'ui_fields_manage', $this->pod_data );
4153
 
4154
  if ( ! empty( $manage_fields ) ) {
4155
  $manage_new = array();
4179
  $pod_name = $this->pod;
4180
  $manage = apply_filters( "pods_admin_ui_fields_{$pod_name}", apply_filters( 'pods_admin_ui_fields', $manage, $this->pod, $this ), $this->pod, $this );
4181
 
4182
+ $icon = pods_v( 'ui_icon', $this->pod_data );
4183
 
4184
  if ( ! empty( $icon ) ) {
4185
  $icon = pods_image_url( $icon, '32x32' );
4186
  }
4187
 
4188
+ $filters = pods_v( 'ui_filters', $this->pod_data );
4189
 
4190
  if ( ! empty( $filters ) ) {
4191
  $filters_new = array();
4221
  $ui['filters_enhanced'] = true;
4222
  }
4223
 
4224
+ $reorder_field = pods_v( 'ui_reorder_field', $this->pod_data );
4225
 
4226
  if ( ! empty( $reorder_field ) && in_array( 'reorder', $actions_enabled, true ) && ! in_array( 'reorder', $actions_disabled, true ) && ( ( ! empty( $this->pod_data['object_fields'] ) && isset( $this->pod_data['object_fields'][ $reorder_field ] ) ) || isset( $this->pod_data['fields'][ $reorder_field ] ) ) ) {
4227
  $ui['reorder'] = array( 'on' => $reorder_field );
4247
  );
4248
  }
4249
 
4250
+ $detail_url = pods_v( 'detail_url', $this->pod_data );
4251
 
4252
  if ( 0 < strlen( $detail_url ) ) {
4253
  $ui['actions_custom'] = array(
4314
  * @since 2.0.0
4315
  */
4316
  public function __get( $name ) {
 
4317
  $name = (string) $name;
4318
 
4319
+ // Handle PodsData properties.
4320
+ $supported_pods_data = array(
4321
+ 'rows',
4322
+ 'row',
4323
+ 'pagination',
4324
+ 'page',
4325
+ 'page_var',
4326
+ 'search',
4327
+ 'search_var',
4328
+ 'search_mode',
4329
+ 'api',
4330
+ 'row_number',
4331
+ 'params',
4332
+ 'filters',
4333
+ 'id',
4334
+ 'limit',
4335
+ 'offset',
4336
+ 'total',
4337
+ 'total_found',
4338
+ 'sql',
4339
+ );
4340
+
4341
+ if ( in_array( $name, $supported_pods_data, true ) ) {
4342
  return $this->data->{$name};
4343
  }
4344
 
4345
+ // Handle alias Pods\Whatsit\Pod properties.
4346
+ $supported_pods_object = array(
4347
+ 'pod' => 'name',
4348
+ 'pod_id' => 'id',
4349
+ 'fields' => 'fields',
4350
+ 'detail_page' => 'detail_url',
4351
+ 'detail_url' => 'detail_url',
4352
+ );
4353
 
4354
+ if ( isset( $supported_pods_object[ $name ] ) ) {
4355
+ if ( ! is_object( $this->pod_data ) ) {
4356
+ return null;
4357
+ }
4358
+
4359
+ return pods_v( $supported_pods_object[ $name ], $this->pod_data );
4360
  }
4361
 
4362
+ // Handle sending previously mapped PodsData properties directly to their correct place.
4363
+ if ( 0 === strpos( $name, 'field_' ) ) {
4364
+ if ( ! is_object( $this->pod_data ) ) {
4365
+ return null;
4366
+ }
4367
 
4368
+ return pods_v( $name, $this->pod_data );
4369
+ }
4370
 
4371
+ return null;
4372
+ }
 
 
4373
 
4374
+ /**
4375
+ * Handle variables that have been deprecated and PodsData vars
4376
+ *
4377
+ * @param string $name Property name.
4378
+ * @param mixed $value Property value.
4379
+ *
4380
+ * @since 2.8.0
4381
+ */
4382
+ public function __set( $name, $value ) {
4383
+ $name = (string) $name;
4384
+
4385
+ $supported_pods_data = array(
4386
+ 'rows' => 'array',
4387
+ 'row' => 'array',
4388
+ 'pagination' => 'boolean',
4389
+ 'page' => 'int',
4390
+ 'page_var' => 'string',
4391
+ 'search' => 'boolean',
4392
+ 'search_var' => 'string',
4393
+ 'search_mode' => 'string',
4394
+ );
4395
+
4396
+ if ( isset( $supported_pods_data[ $name ] ) ) {
4397
+ // Cast the value.
4398
+ settype( $value, $supported_pods_data[ $name ] );
4399
+
4400
+ $this->data->{$name} = $value;
4401
  }
4402
+ }
4403
 
4404
+ /**
4405
+ * Handle variables that have been deprecated and PodsData vars
4406
+ *
4407
+ * @param string $name Property name.
4408
+ *
4409
+ * @return bool Whether the variable is set or not.
4410
+ *
4411
+ * @since 2.8.0
4412
+ */
4413
+ public function __isset( $name ) {
4414
+ $value = $this->__get( $name );
4415
+
4416
+ return ( null !== $value );
4417
+ }
4418
+
4419
+ /**
4420
+ * Handle variables that have been deprecated and PodsData vars
4421
+ *
4422
+ * @param string $name Property name.
4423
+ *
4424
+ * @since 2.8.0
4425
+ */
4426
+ public function __unset( $name ) {
4427
+ $this->__set( $name, null );
4428
  }
4429
 
4430
  /**
4452
  $this->deprecated = new Pods_Deprecated( $this );
4453
  }
4454
 
4455
+ $pod_class_exists = class_exists( 'Deprecated_Pod' );
4456
 
4457
  if ( method_exists( $this->deprecated, $name ) ) {
4458
  return call_user_func_array( array( $this->deprecated, $name ), $args );
4459
  // @codingStandardsIgnoreLine
4460
+ } elseif ( ! $pod_class_exists || Deprecated_Pod::$deprecated_notice ) {
4461
  pods_deprecated( "Pods::{$name}", '2.0' );
4462
  }
4463
 
classes/PodsAPI.php CHANGED
@@ -1,5 +1,12 @@
1
  <?php
2
 
 
 
 
 
 
 
 
3
  /**
4
  * @package Pods
5
  */
@@ -8,12 +15,12 @@ class PodsAPI {
8
  /**
9
  * @var PodsAPI
10
  */
11
- static $instance = null;
12
 
13
  /**
14
  * @var array PodsAPI
15
  */
16
- static $instances = array();
17
 
18
  /**
19
  * @var bool
@@ -21,25 +28,10 @@ class PodsAPI {
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.0
@@ -51,26 +43,6 @@ class PodsAPI {
51
  */
52
  private $deprecated;
53
 
54
- /**
55
- * @var array
56
- * @since 2.5.0
57
- */
58
- private $fields_cache = array();
59
-
60
- /**
61
- * @var array
62
- * @since 2.5.0
63
- *
64
- */
65
- private static $table_info_cache = array();
66
-
67
- /**
68
- * @var array
69
- * @since 2.5.0
70
- *
71
- */
72
- private static $related_item_cache = array();
73
-
74
  /**
75
  * Singleton-ish handling for a basic pods_api() request
76
  *
@@ -82,7 +54,6 @@ class PodsAPI {
82
  * @since 2.3.5
83
  */
84
  public static function init( $pod = null, $format = null ) {
85
-
86
  if ( null !== $pod || null !== $format ) {
87
  if ( ! isset( self::$instances[ $pod ] ) ) {
88
  // Cache API singleton per Pod
@@ -90,7 +61,9 @@ class PodsAPI {
90
  }
91
 
92
  return self::$instances[ $pod ];
93
- } elseif ( ! is_object( self::$instance ) ) {
 
 
94
  self::$instance = new PodsAPI();
95
  }
96
 
@@ -109,24 +82,15 @@ class PodsAPI {
109
  * @since 1.7.1
110
  */
111
  public function __construct( $pod = null, $format = null ) {
 
 
 
112
 
113
- if ( null !== $pod && 0 < strlen( (string) $pod ) ) {
114
- if ( null !== $format ) {
115
- $this->format = $format;
116
-
117
- pods_deprecated( 'pods_api( $pod, $format )', '2.0', 'pods_api( $pod )' );
118
- }
119
-
120
- $pod = pods_clean_name( $pod );
121
-
122
- $pod = $this->load_pod( array( 'name' => $pod, 'table_info' => true ), false );
123
 
124
- if ( ! empty( $pod ) ) {
125
- $this->pod_data = $pod;
126
- $this->pod = $pod['name'];
127
- $this->pod_id = $pod['id'];
128
- $this->fields = $pod['fields'];
129
- }
130
  }
131
  }
132
 
@@ -139,41 +103,77 @@ class PodsAPI {
139
  * @param bool $strict (optional) Decides whether the previous saved meta should be deleted or not
140
  * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before
141
  * sending.
142
- * @param array $fields (optional) The array of fields and their options, for further processing with
143
  *
144
- * @return bool|mixed
145
  *
146
  * @since 2.0.0
147
  */
148
- public function save_wp_object( $object_type, $data, $meta = array(), $strict = false, $sanitized = false, $fields = array() ) {
149
-
150
- if ( in_array( $object_type, array( 'post_type', 'media' ) ) ) {
151
  $object_type = 'post';
152
- }
153
-
154
- if ( 'taxonomy' === $object_type ) {
155
  $object_type = 'term';
156
  }
157
 
158
- $is_meta_object = in_array( $object_type, array( 'post', 'term', 'user', 'comment' ), true );
159
-
160
  if ( $sanitized ) {
161
  $data = pods_unsanitize( $data );
162
  $meta = pods_unsanitize( $meta );
163
  }
164
 
165
- if ( $is_meta_object ) {
166
- return call_user_func( array( $this, 'save_' . $object_type ), $data, $meta, $strict, false, $fields );
167
  } elseif ( 'settings' === $object_type ) {
168
  // Nothing to save
169
  if ( empty( $meta ) ) {
170
  return true;
171
  }
172
 
173
- return $this->save_setting( pods_var( 'option_id', $data ), $meta, false );
174
  }
175
 
176
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  }
178
 
179
  /**
@@ -189,7 +189,7 @@ class PodsAPI {
189
  */
190
  public function delete_wp_object( $object_type, $id, $force_delete = true ) {
191
 
192
- if ( in_array( $object_type, array( 'post_type', 'media' ) ) ) {
193
  $object_type = 'post';
194
  }
195
 
@@ -201,7 +201,7 @@ class PodsAPI {
201
  return false;
202
  }
203
 
204
- if ( in_array( $object_type, array( 'post' ) ) ) {
205
  return wp_delete_post( $id, $force_delete );
206
  }
207
 
@@ -222,7 +222,7 @@ class PodsAPI {
222
  * sending.
223
  * @param array $fields (optional) The array of fields and their options, for further processing with
224
  *
225
- * @return mixed|void
226
  *
227
  * @since 2.0.0
228
  */
@@ -235,7 +235,9 @@ class PodsAPI {
235
  }
236
 
237
  if ( ! is_array( $post_data ) || empty( $post_data ) ) {
238
- $post_data = array( 'post_title' => '' );
 
 
239
  }
240
 
241
  if ( ! is_array( $post_meta ) ) {
@@ -306,7 +308,7 @@ class PodsAPI {
306
  $meta = get_post_meta( $id );
307
 
308
  foreach ( $meta as $k => $value ) {
309
- if ( is_array( $value ) && 1 == count( $value ) ) {
310
  $meta[ $k ] = current( $value );
311
  }
312
  }
@@ -330,7 +332,7 @@ class PodsAPI {
330
  if ( isset( $fields[ $meta_key ] ) ) {
331
  $field_data = $fields[ $meta_key ];
332
 
333
- $simple = ( 'pick' === pods_v( 'type', $field_data ) && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects ) );
334
  }
335
 
336
  if ( $simple ) {
@@ -486,7 +488,7 @@ class PodsAPI {
486
  if ( isset( $fields[ $meta_key ] ) ) {
487
  $field_data = $fields[ $meta_key ];
488
 
489
- $simple = ( 'pick' === $field_data['type'] && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
490
  }
491
 
492
  if ( $simple ) {
@@ -690,7 +692,9 @@ class PodsAPI {
690
  $conflicted = pods_no_conflict_check( 'taxonomy' );
691
 
692
  if ( ! is_array( $term_data ) || empty( $term_data ) ) {
693
- $term_data = array( 'name' => '' );
 
 
694
  }
695
 
696
  if ( ! $conflicted ) {
@@ -711,9 +715,13 @@ class PodsAPI {
711
  unset( $term_data['taxonomy'] );
712
 
713
  if ( empty( $term_data['term_id'] ) ) {
714
- $term_name = $term_data['name'];
715
 
716
- unset( $term_data['name'] );
 
 
 
 
717
 
718
  $term_data['term_id'] = wp_insert_term( $term_name, $taxonomy, $term_data );
719
  } elseif ( 1 < count( $term_data ) ) {
@@ -803,7 +811,7 @@ class PodsAPI {
803
  if ( isset( $fields[ $meta_key ] ) ) {
804
  $field_data = $fields[ $meta_key ];
805
 
806
- $simple = ( 'pick' === pods_v( 'type', $field_data ) && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects ) );
807
  }
808
 
809
  if ( $simple ) {
@@ -942,7 +950,7 @@ class PodsAPI {
942
  */
943
  public function get_wp_object_fields( $object = 'post_type', $pod = null, $refresh = false ) {
944
 
945
- $pod_name = pods_var_raw( 'name', $pod, $object, null, true );
946
 
947
  if ( 'media' === $pod_name ) {
948
  $object = 'post_type';
@@ -959,483 +967,520 @@ class PodsAPI {
959
  return $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
960
  }
961
 
962
- $fields = array();
963
 
964
  if ( 'post_type' === $object ) {
965
- $fields = array(
966
- 'ID' => array(
967
- 'name' => 'ID',
968
- 'label' => 'ID',
969
- 'type' => 'number',
970
- 'alias' => array( 'id' ),
971
- 'options' => array(
972
- 'number_format' => '9999.99'
973
- )
974
- ),
975
- 'post_title' => array(
 
976
  'name' => 'post_title',
977
  'label' => 'Title',
978
  'type' => 'text',
979
- 'alias' => array( 'title', 'name' ),
980
- 'options' => array(
981
  'display_filter' => 'the_title',
982
- 'display_filter_args' => array( 'post_ID' )
983
- )
984
- ),
985
- 'post_content' => array(
986
  'name' => 'post_content',
987
  'label' => 'Content',
988
  'type' => 'wysiwyg',
989
- 'alias' => array( 'content' ),
990
- 'options' => array(
991
  'wysiwyg_allowed_html_tags' => '',
992
  'display_filter' => 'the_content',
993
- 'pre_save' => 0
994
- )
995
- ),
996
- 'post_excerpt' => array(
997
  'name' => 'post_excerpt',
998
  'label' => 'Excerpt',
999
  'type' => 'paragraph',
1000
- 'alias' => array( 'excerpt' ),
1001
- 'options' => array(
1002
  'paragraph_allow_html' => 1,
1003
  'paragraph_allowed_html_tags' => '',
1004
  'display_filter' => 'the_excerpt',
1005
- 'pre_save' => 0
1006
- )
1007
- ),
1008
- 'post_author' => array(
1009
  'name' => 'post_author',
1010
  'label' => 'Author',
1011
  'type' => 'pick',
1012
- 'alias' => array( 'author' ),
1013
  'pick_object' => 'user',
1014
- 'options' => array(
1015
  'pick_format_type' => 'single',
1016
  'pick_format_single' => 'autocomplete',
1017
- 'default_value' => '{@user.ID}'
1018
- )
1019
- ),
1020
- 'post_date' => array(
1021
  'name' => 'post_date',
1022
  'label' => 'Publish Date',
1023
  'type' => 'datetime',
1024
- 'alias' => array( 'created', 'date' )
1025
- ),
1026
- 'post_date_gmt' => array(
1027
- 'name' => 'post_date_gmt',
1028
- 'label' => 'Publish Date (GMT)',
1029
- 'type' => 'datetime',
1030
- 'alias' => array(),
1031
- 'hidden' => true
1032
- ),
1033
- 'post_status' => array(
 
1034
  'name' => 'post_status',
1035
  'label' => 'Status',
1036
  'type' => 'pick',
1037
  'pick_object' => 'post-status',
1038
- 'default' => $this->do_hook( 'default_status_' . $pod_name, pods_var( 'default_status', pods_var_raw( 'options', $pod ), 'draft', null, true ), $pod ),
1039
- 'alias' => array( 'status' )
1040
- ),
1041
- 'comment_status' => array(
1042
  'name' => 'comment_status',
1043
  'label' => 'Comment Status',
1044
  'type' => 'text',
1045
  'default' => get_option( 'default_comment_status', 'open' ),
1046
- 'alias' => array(),
1047
- 'data' => array(
1048
  'open' => __( 'Open', 'pods' ),
1049
- 'closed' => __( 'Closed', 'pods' )
1050
- )
1051
- ),
1052
- 'ping_status' => array(
1053
- 'name' => 'ping_status',
1054
- 'label' => 'Ping Status',
1055
- 'default' => get_option( 'default_ping_status', 'open' ),
1056
- 'type' => 'text',
1057
- 'alias' => array(),
1058
- 'data' => array(
1059
  'open' => __( 'Open', 'pods' ),
1060
- 'closed' => __( 'Closed', 'pods' )
1061
- )
1062
- ),
1063
- 'post_password' => array(
 
1064
  'name' => 'post_password',
1065
  'label' => 'Password',
1066
  'type' => 'password',
1067
- 'alias' => array()
1068
- ),
1069
- 'post_name' => array(
1070
  'name' => 'post_name',
1071
  'label' => 'Permalink',
1072
  'type' => 'slug',
1073
- 'alias' => array( 'slug', 'permalink' )
1074
- ),
1075
- 'to_ping' => array(
1076
- 'name' => 'to_ping',
1077
- 'label' => 'To Ping',
1078
- 'type' => 'text',
1079
- 'alias' => array(),
1080
- 'hidden' => true
1081
- ),
1082
- 'pinged' => array(
1083
- 'name' => 'pinged',
1084
- 'label' => 'Pinged',
1085
- 'type' => 'text',
1086
- 'alias' => array(),
1087
- 'hidden' => true
1088
- ),
1089
- 'post_modified' => array(
1090
- 'name' => 'post_modified',
1091
- 'label' => 'Last Modified Date',
1092
- 'type' => 'datetime',
1093
- 'alias' => array( 'modified' ),
1094
- 'hidden' => true
1095
- ),
1096
- 'post_modified_gmt' => array(
1097
- 'name' => 'post_modified_gmt',
1098
- 'label' => 'Last Modified Date (GMT)',
1099
- 'type' => 'datetime',
1100
- 'alias' => array(),
1101
- 'hidden' => true
1102
- ),
1103
- 'post_content_filtered' => array(
1104
- 'name' => 'post_content_filtered',
1105
- 'label' => 'Content (filtered)',
1106
- 'type' => 'paragraph',
1107
- 'alias' => array(),
1108
- 'hidden' => true,
1109
- 'options' => array(
 
 
 
 
1110
  'paragraph_allow_html' => 1,
1111
  'paragraph_oembed' => 1,
1112
  'paragraph_wptexturize' => 1,
1113
  'paragraph_convert_chars' => 1,
1114
  'paragraph_wpautop' => 1,
1115
  'paragraph_allow_shortcode' => 1,
1116
- 'paragraph_allowed_html_tags' => ''
1117
- )
1118
- ),
1119
- 'post_parent' => array(
 
1120
  'name' => 'post_parent',
1121
  'label' => 'Parent',
1122
  'type' => 'pick',
1123
  'pick_object' => 'post_type',
1124
  'pick_val' => '__current__',
1125
- 'alias' => array( 'parent' ),
1126
- 'data' => array(),
1127
- 'hidden' => true
1128
- ),
1129
- 'guid' => array(
1130
- 'name' => 'guid',
1131
- 'label' => 'GUID',
1132
- 'type' => 'text',
1133
- 'alias' => array(),
1134
- 'hidden' => true
1135
- ),
1136
- 'menu_order' => array(
 
1137
  'name' => 'menu_order',
1138
  'label' => 'Menu Order',
1139
  'type' => 'number',
1140
- 'alias' => array(),
1141
- 'options' => array(
1142
- 'number_format' => '9999.99'
1143
- )
1144
- ),
1145
- 'post_type' => array(
1146
- 'name' => 'post_type',
1147
- 'label' => 'Type',
1148
- 'type' => 'text',
1149
- 'alias' => array( 'type' ),
1150
- 'hidden' => true
1151
- ),
1152
- 'post_mime_type' => array(
1153
- 'name' => 'post_mime_type',
1154
- 'label' => 'Mime Type',
1155
- 'type' => 'text',
1156
- 'alias' => array(),
1157
- 'hidden' => true
1158
- ),
1159
- 'comment_count' => array(
1160
- 'name' => 'comment_count',
1161
- 'label' => 'Comment Count',
1162
- 'type' => 'number',
1163
- 'alias' => array(),
1164
- 'hidden' => true
1165
- ),
1166
- 'comments' => array(
1167
- 'name' => 'comments',
1168
- 'label' => 'Comments',
1169
- 'type' => 'comment',
1170
- 'pick_object' => 'comment',
1171
- 'pick_val' => 'comment',
1172
- 'alias' => array(),
1173
- 'hidden' => true,
1174
- 'options' => array(
1175
- 'comment_format_type' => 'multi'
1176
- )
1177
- )
1178
- );
 
 
 
 
1179
 
1180
  if ( ! empty( $pod ) ) {
1181
  $taxonomies = get_object_taxonomies( $pod_name, 'objects' );
1182
 
1183
  foreach ( $taxonomies as $taxonomy ) {
1184
- $fields[ $taxonomy->name ] = array(
1185
  'name' => $taxonomy->name,
1186
  'label' => $taxonomy->labels->name,
1187
  'type' => 'taxonomy',
1188
  'pick_object' => 'taxonomy',
1189
  'pick_val' => $taxonomy->name,
1190
- 'alias' => array(),
1191
  'hidden' => true,
1192
- 'options' => array(
1193
- 'taxonomy_format_type' => 'multi'
1194
- )
1195
- );
1196
  }
1197
  }
1198
  } elseif ( 'user' === $object ) {
1199
- $fields = array(
1200
- 'ID' => array(
1201
- 'name' => 'ID',
1202
- 'label' => 'ID',
1203
- 'type' => 'number',
1204
- 'alias' => array( 'id' ),
1205
- 'options' => array(
1206
- 'number_format' => '9999.99'
1207
- )
1208
- ),
1209
- 'user_login' => array(
 
1210
  'name' => 'user_login',
1211
  'label' => 'Title',
1212
  'type' => 'text',
1213
- 'alias' => array( 'login' ),
1214
- 'options' => array(
1215
- 'required' => 1
1216
- )
1217
- ),
1218
- 'user_nicename' => array(
1219
  'name' => 'user_nicename',
1220
  'label' => 'Permalink',
1221
  'type' => 'slug',
1222
- 'alias' => array( 'nicename', 'slug', 'permalink' )
1223
- ),
1224
- 'display_name' => array(
1225
  'name' => 'display_name',
1226
  'label' => 'Display Name',
1227
  'type' => 'text',
1228
- 'alias' => array( 'title', 'name' )
1229
- ),
1230
- 'user_pass' => array(
1231
  'name' => 'user_pass',
1232
  'label' => 'Password',
1233
  'type' => 'text',
1234
- 'alias' => array( 'password', 'pass' ),
1235
- 'options' => array(
1236
  'required' => 1,
1237
- 'text_format_type' => 'password'
1238
- )
1239
- ),
1240
- 'user_email' => array(
1241
  'name' => 'user_email',
1242
  'label' => 'E-mail',
1243
  'type' => 'text',
1244
- 'alias' => array( 'email' ),
1245
- 'options' => array(
1246
  'required' => 1,
1247
- 'text_format_type' => 'email'
1248
- )
1249
- ),
1250
- 'user_url' => array(
1251
  'name' => 'user_url',
1252
  'label' => 'URL',
1253
  'type' => 'text',
1254
- 'alias' => array( 'url', 'website' ),
1255
- 'options' => array(
1256
  'required' => 0,
1257
  'text_format_type' => 'website',
1258
- 'text_format_website' => 'normal'
1259
- )
1260
- ),
1261
- 'user_registered' => array(
1262
- 'name' => 'user_registered',
1263
- 'label' => 'Registration Date',
1264
- 'type' => 'date',
1265
- 'alias' => array( 'created', 'date', 'registered' ),
1266
- 'options' => array(
1267
- 'date_format_type' => 'datetime'
1268
- )
1269
- )
1270
- );
 
 
1271
  } elseif ( 'comment' === $object ) {
1272
- $fields = array(
1273
- 'comment_ID' => array(
1274
- 'name' => 'comment_ID',
1275
- 'label' => 'ID',
1276
- 'type' => 'number',
1277
- 'alias' => array( 'id', 'ID', 'comment_id' ),
1278
- 'options' => array(
1279
- 'number_format' => '9999.99'
1280
- )
1281
- ),
1282
- 'comment_content' => array(
 
1283
  'name' => 'comment_content',
1284
  'label' => 'Content',
1285
  'type' => 'wysiwyg',
1286
- 'alias' => array( 'content' )
1287
- ),
1288
- 'comment_approved' => array(
1289
  'name' => 'comment_approved',
1290
  'label' => 'Approved',
1291
  'type' => 'number',
1292
- 'alias' => array( 'approved' ),
1293
- 'options' => array(
1294
- 'number_format' => '9999.99'
1295
- )
1296
- ),
1297
- 'comment_post_ID' => array(
1298
  'name' => 'comment_post_ID',
1299
  'label' => 'Post',
1300
  'type' => 'pick',
1301
- 'alias' => array( 'post', 'post_id' ),
1302
- 'data' => array()
1303
- ),
1304
- 'user_id' => array(
1305
  'name' => 'user_id',
1306
  'label' => 'Author',
1307
  'type' => 'pick',
1308
- 'alias' => array( 'author' ),
1309
  'pick_object' => 'user',
1310
- 'data' => array()
1311
- ),
1312
- 'comment_date' => array(
1313
  'name' => 'comment_date',
1314
  'label' => 'Date',
1315
  'type' => 'date',
1316
- 'alias' => array( 'created', 'date' ),
1317
- 'options' => array(
1318
- 'date_format_type' => 'datetime'
1319
- )
1320
- ),
1321
- 'comment_author' => array(
1322
  'name' => 'comment_author',
1323
  'label' => 'Author',
1324
  'type' => 'text',
1325
- 'alias' => array( 'author' )
1326
- ),
1327
- 'comment_author_email' => array(
1328
  'name' => 'comment_author_email',
1329
  'label' => 'Author E-mail',
1330
  'type' => 'email',
1331
- 'alias' => array( 'author_email' )
1332
- ),
1333
- 'comment_author_url' => array(
1334
  'name' => 'comment_author_url',
1335
  'label' => 'Author URL',
1336
  'type' => 'text',
1337
- 'alias' => array( 'author_url' )
1338
- ),
1339
- 'comment_author_IP' => array(
1340
- 'name' => 'comment_author_IP',
1341
- 'label' => 'Author IP',
1342
- 'type' => 'text',
1343
- 'alias' => array( 'author_IP' )
1344
- ),
1345
- 'comment_type' => array(
1346
- 'name' => 'comment_type',
1347
- 'label' => 'Type',
1348
- 'type' => 'text',
1349
- 'alias' => array( 'type' ),
1350
- 'hidden' => true
1351
- ),
1352
- 'comment_parent' => array(
1353
- 'name' => 'comment_parent',
1354
- 'label' => 'Parent',
1355
- 'type' => 'pick',
1356
- 'pick_object' => 'comment',
1357
- 'pick_val' => '__current__',
1358
- 'alias' => array( 'parent' ),
1359
- 'data' => array(),
1360
- 'hidden' => true
1361
- )
1362
- );
 
 
 
1363
  } elseif ( 'taxonomy' === $object ) {
1364
- $fields = array(
1365
- 'term_id' => array(
1366
- 'name' => 'term_id',
1367
- 'label' => 'ID',
1368
- 'type' => 'number',
1369
- 'alias' => array( 'id', 'ID' ),
1370
- 'options' => array(
1371
- 'number_format' => '9999.99'
1372
- )
1373
- ),
1374
- 'name' => array(
 
1375
  'name' => 'name',
1376
  'label' => 'Title',
1377
  'type' => 'text',
1378
- 'alias' => array( 'title' )
1379
- ),
1380
- 'slug' => array(
1381
  'name' => 'slug',
1382
  'label' => 'Permalink',
1383
  'type' => 'slug',
1384
- 'alias' => array( 'permalink' )
1385
- ),
1386
- 'description' => array(
1387
  'name' => 'description',
1388
  'label' => 'Description',
1389
  'type' => 'wysiwyg',
1390
- 'alias' => array( 'content' )
1391
- ),
1392
- 'taxonomy' => array(
1393
  'name' => 'taxonomy',
1394
  'label' => 'Taxonomy',
1395
  'type' => 'text',
1396
- 'alias' => array()
1397
- ),
1398
- 'parent' => array(
1399
  'name' => 'parent',
1400
  'label' => 'Parent',
1401
  'type' => 'pick',
1402
  'pick_object' => 'taxonomy',
1403
  'pick_val' => '__current__',
1404
- 'alias' => array( 'parent' ),
1405
- 'data' => array(),
1406
- 'hidden' => true
1407
- ),
1408
- 'term_taxonomy_id' => array(
1409
- 'name' => 'term_taxonomy_id',
1410
- 'label' => 'Term Taxonomy ID',
1411
- 'type' => 'number',
1412
- 'alias' => array(),
1413
- 'hidden' => true,
1414
- 'options' => array(
1415
- 'number_format' => '9999.99'
1416
- )
1417
- ),
1418
- 'term_group' => array(
1419
- 'name' => 'term_group',
1420
- 'label' => 'Term Group',
1421
- 'type' => 'number',
1422
- 'alias' => array( 'group' ),
1423
- 'hidden' => true,
1424
- 'options' => array(
1425
- 'number_format' => '9999.99'
1426
- )
1427
- ),
1428
- 'count' => array(
1429
- 'name' => 'count',
1430
- 'label' => 'Count',
1431
- 'type' => 'number',
1432
- 'alias' => array(),
1433
- 'hidden' => true,
1434
- 'options' => array(
1435
- 'number_format' => '9999.99'
1436
- )
1437
- )
1438
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1439
  }
1440
 
1441
  $fields = $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
@@ -1457,7 +1502,7 @@ class PodsAPI {
1457
  $fields = PodsForm::fields_setup( $fields );
1458
 
1459
  if ( did_action( 'init' ) && pods_api_cache() ) {
1460
- pods_transient_set( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ), $fields );
1461
  }
1462
 
1463
  return $fields;
@@ -1476,6 +1521,7 @@ class PodsAPI {
1476
  * $params['create_label_singular'] string Singular Label (for Creating)
1477
  * $params['create_storage'] string Storage Type (for Creating Post Types)
1478
  * $params['create_storage_taxonomy'] string Storage Type (for Creating Taxonomies)
 
1479
  * $params['extend_pod_type'] string Pod Type (for Extending)
1480
  * $params['extend_post_type'] string Post Type (for Extending Post Types)
1481
  * $params['extend_taxonomy'] string Taxonomy (for Extending Taxonomies)
@@ -1497,6 +1543,7 @@ class PodsAPI {
1497
  'create_label_plural' => '',
1498
  'create_storage' => 'meta',
1499
  'create_storage_taxonomy' => '',
 
1500
 
1501
  'create_setting_name' => '',
1502
  'create_label_title' => '',
@@ -1511,7 +1558,7 @@ class PodsAPI {
1511
  'extend_storage_taxonomy' => '',
1512
  );
1513
 
1514
- if( !function_exists( 'get_term_meta' ) ) {
1515
  $defaults['create_storage_taxonomy'] = 'none';
1516
  $defaults['extend_storage_taxonomy' ] = 'table' ;
1517
  }
@@ -1539,18 +1586,16 @@ class PodsAPI {
1539
  $label = $params->create_label_singular;
1540
  }
1541
 
1542
- $pod_params['name'] = $params->create_name;
1543
- $pod_params['label'] = ( ! empty( $params->create_label_plural ) ? $params->create_label_plural : $label );
1544
- $pod_params['type'] = $params->create_pod_type;
1545
- $pod_params['options'] = array(
1546
- 'label_singular' => ( ! empty( $params->create_label_singular ) ? $params->create_label_singular : $pod_params['label'] ),
1547
- 'public' => 1,
1548
- 'show_ui' => 1
1549
- );
1550
 
1551
  // Auto-generate name if not provided
1552
- if ( empty( $pod_params['name'] ) && ! empty( $pod_params['options']['label_singular'] ) ) {
1553
- $pod_params['name'] = pods_clean_name( $pod_params['options']['label_singular'] );
1554
  }
1555
 
1556
  if ( 'post_type' === $pod_params['type'] ) {
@@ -1563,6 +1608,8 @@ class PodsAPI {
1563
  if ( pods_tableless() ) {
1564
  $pod_params['storage'] = 'meta';
1565
  }
 
 
1566
  } elseif ( 'taxonomy' === $pod_params['type'] ) {
1567
  if ( empty( $pod_params['name'] ) ) {
1568
  return pods_error( __( 'Please enter a Name for this Pod', 'pods' ), $this );
@@ -1578,7 +1625,9 @@ class PodsAPI {
1578
  $pod_params['storage'] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1579
  }
1580
 
1581
- $pod_params['options']['hierarchical'] = 1;
 
 
1582
  } elseif ( 'pod' === $pod_params['type'] ) {
1583
  if ( empty( $pod_params['name'] ) ) {
1584
  return pods_error( __( 'Please enter a Name for this Pod', 'pod' ), $this );
@@ -1589,13 +1638,11 @@ class PodsAPI {
1589
  $pod_params['storage'] = 'meta';
1590
  }
1591
  } elseif ( 'settings' === $pod_params['type'] ) {
1592
- $pod_params['name'] = $params->create_setting_name;
1593
- $pod_params['label'] = ( ! empty( $params->create_label_title ) ? $params->create_label_title : ucwords( str_replace( '_', ' ', $params->create_setting_name ) ) );
1594
- $pod_params['options'] = array(
1595
- 'menu_name' => ( ! empty( $params->create_label_menu ) ? $params->create_label_menu : $pod_params['label'] ),
1596
- 'menu_location' => $params->create_menu_location
1597
- );
1598
- $pod_params['storage'] = 'none';
1599
 
1600
  // Auto-generate name if not provided
1601
  if ( empty( $pod_params['name'] ) && ! empty( $pod_params['label'] ) ) {
@@ -1654,8 +1701,8 @@ class PodsAPI {
1654
  return pods_error( sprintf( __( 'Post Type %s already exists, try extending it instead', 'pods' ), $pod_params['name'] ), $this );
1655
  }
1656
 
1657
- $pod_params['options']['supports_title'] = 1;
1658
- $pod_params['options']['supports_editor'] = 1;
1659
  } elseif ( 'taxonomy' === $pod_params['type'] ) {
1660
  $check = get_taxonomy( $pod_params['name'] );
1661
 
@@ -1681,56 +1728,101 @@ class PodsAPI {
1681
  * $params['type'] string The Pod type
1682
  * $params['object'] string The object being extended (if any)
1683
  * $params['storage'] string The Pod storage
1684
- * $params['options'] array Options
1685
  * $params['create_extend'] string Create or Extend a Content Type
 
1686
  *
1687
- * @param array $params An associative array of parameters
1688
- * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will
1689
- * sanitize them if false.
1690
- * @param bool|int $db (optional) Whether to save into the DB or just return Pod array.
 
 
1691
  *
1692
  * @return int Pod ID
1693
  * @since 1.7.9
1694
  */
1695
  public function save_pod( $params, $sanitized = false, $db = true ) {
 
 
 
 
 
 
1696
 
1697
- $tableless_field_types = PodsForm::tableless_field_types();
1698
- $simple_tableless_objects = PodsForm::simple_tableless_objects();
1699
 
1700
- $extend = ( is_array( $params ) && ! empty( $params['create_extend'] ) && 'extend' === $params['create_extend'] );
1701
- unset( $params['create_extend'] );
1702
 
1703
- $load_params = (object) $params;
 
1704
 
1705
- if ( isset( $load_params->id ) && isset( $load_params->name ) ) {
1706
- unset( $load_params->name );
1707
  }
1708
 
1709
- if ( isset( $load_params->old_name ) ) {
1710
- $load_params->name = $load_params->old_name;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1711
  }
1712
 
1713
- $load_params->table_info = true;
 
1714
 
1715
- $pod = $this->load_pod( $load_params, false );
1716
 
1717
- $params = (object) $params;
 
 
 
 
 
 
 
 
 
 
 
 
 
1718
 
1719
  if ( false === $sanitized ) {
1720
  $params = pods_sanitize( $params );
 
 
1721
  }
1722
 
1723
  $old_id = null;
1724
  $old_name = null;
1725
  $old_storage = null;
1726
-
1727
  $old_fields = array();
1728
- $old_options = array();
1729
 
1730
  if ( isset( $params->name ) && ! isset( $params->object ) ) {
1731
  $params->name = pods_clean_name( $params->name );
1732
  }
1733
 
 
 
 
 
 
 
 
 
 
 
1734
  if ( ! empty( $pod ) ) {
1735
  // Existing pod (update).
1736
 
@@ -1741,9 +1833,18 @@ class PodsAPI {
1741
  $params->id = $pod['id'];
1742
 
1743
  $old_name = $pod['name'];
1744
- $old_storage = $pod['storage'];
1745
- $old_fields = $pod['fields'];
1746
- $old_options = $pod['options'];
 
 
 
 
 
 
 
 
 
1747
 
1748
  // Check if name is intentionally not set, set it as current name.
1749
  if ( ! isset( $params->name ) ) {
@@ -1763,16 +1864,16 @@ class PodsAPI {
1763
  }
1764
 
1765
  if (
1766
- in_array( $pod['type'], array( 'post_type', 'taxonomy' ), true )
1767
- && ! empty( $pod['object'] )
1768
- && $pod['object'] == $old_name
1769
  ) {
1770
  return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1771
  }
1772
  }
1773
 
1774
- if ( $old_id != $params->id ) {
1775
- if ( $params->type == $pod['type'] && isset( $params->object ) && $params->object == $pod['object'] ) {
1776
  return pods_error( sprintf( __( 'Pod using %s already exists, you can not reuse an object across multiple pods', 'pods' ), $params->object ), $this );
1777
  } else {
1778
  return pods_error( sprintf( __( 'Pod %s already exists', 'pods' ), $params->name ), $this );
@@ -1781,6 +1882,10 @@ class PodsAPI {
1781
  } else {
1782
  // New pod (create).
1783
 
 
 
 
 
1784
  if (
1785
  in_array( $params->name, pods_reserved_keywords(), true )
1786
  && in_array( pods_v( 'type', $params ), array( 'post_type', 'taxonomy' ), true )
@@ -1811,15 +1916,13 @@ class PodsAPI {
1811
  'storage' => 'table',
1812
  'object' => '',
1813
  'alias' => '',
1814
- 'options' => array(),
1815
- 'fields' => array(),
1816
  );
1817
  }
1818
 
1819
  // Blank out fields and options for AJAX calls (everything should be sent to it for a full overwrite)
1820
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1821
- $pod['fields'] = array();
1822
- $pod['options'] = array();
1823
  }
1824
 
1825
  // Setup options
@@ -1829,6 +1932,18 @@ class PodsAPI {
1829
  unset( $options['method'] );
1830
  }
1831
 
 
 
 
 
 
 
 
 
 
 
 
 
1832
  $options_ignore = array(
1833
  'object_type',
1834
  'object_name',
@@ -1846,7 +1961,9 @@ class PodsAPI {
1846
  'meta_field_value',
1847
  'pod_field_id',
1848
  'pod_field_index',
 
1849
  'object_fields',
 
1850
  'join',
1851
  'where',
1852
  'where_default',
@@ -1860,7 +1977,12 @@ class PodsAPI {
1860
  'developer_mode',
1861
  'dependency',
1862
  'depends-on',
1863
- 'excludes-on'
 
 
 
 
 
1864
  );
1865
 
1866
  foreach ( $options_ignore as $ignore ) {
@@ -1878,8 +2000,17 @@ class PodsAPI {
1878
  'storage',
1879
  'object',
1880
  'alias',
1881
- 'options',
1882
- 'fields'
 
 
 
 
 
 
 
 
 
1883
  );
1884
 
1885
  foreach ( $exclude as $k => $exclude_field ) {
@@ -1899,7 +2030,8 @@ class PodsAPI {
1899
  }
1900
  }
1901
 
1902
- if ( pods_tableless() && ! in_array( $pod['type'], array( 'settings', 'table' ) ) ) {
 
1903
  if ( 'pod' === $pod['type'] ) {
1904
  $pod['type'] = 'post_type';
1905
  }
@@ -1913,13 +2045,6 @@ class PodsAPI {
1913
  }
1914
  }
1915
 
1916
- $pod['options']['type'] = $pod['type'];
1917
- $pod['options']['storage'] = $pod['storage'];
1918
- $pod['options']['object'] = $pod['object'];
1919
- $pod['options']['alias'] = $pod['alias'];
1920
-
1921
- $pod['options'] = array_merge( $pod['options'], $options );
1922
-
1923
  /**
1924
  * @var WP_Query
1925
  */
@@ -1935,19 +2060,15 @@ class PodsAPI {
1935
  $reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) );
1936
  }
1937
 
1938
- if ( isset( $pod['options']['query_var_string'] ) ) {
1939
- if ( in_array( $pod['options']['query_var_string'], $reserved_query_vars ) ) {
1940
- $pod['options']['query_var_string'] = $pod['options']['type'] . '_' . $pod['options']['query_var_string'];
1941
- }
1942
  }
1943
 
1944
- if ( isset( $pod['options']['query_var'] ) ) {
1945
- if ( in_array( $pod['options']['query_var'], $reserved_query_vars ) ) {
1946
- $pod['options']['query_var'] = $pod['options']['type'] . '_' . $pod['options']['query_var'];
1947
- }
1948
  }
1949
 
1950
- if ( strlen( $pod['label'] ) < 1 ) {
1951
  $pod['label'] = $pod['name'];
1952
  }
1953
 
@@ -1982,7 +2103,7 @@ class PodsAPI {
1982
 
1983
  // Add new pod
1984
  if ( empty( $params->id ) ) {
1985
- if ( strlen( $params->name ) < 1 ) {
1986
  return pods_error( __( 'Pod name cannot be empty', 'pods' ), $this );
1987
  }
1988
 
@@ -1991,65 +2112,82 @@ class PodsAPI {
1991
  'post_title' => $pod['label'],
1992
  'post_content' => $pod['description'],
1993
  'post_type' => '_pods_pod',
1994
- 'post_status' => 'publish'
1995
  );
1996
 
1997
- if ( 'pod' === $pod['type'] && ( ! is_array( $pod['fields'] ) || empty( $pod['fields'] ) ) ) {
1998
- $pod['fields'] = array();
1999
-
2000
- $pod['fields']['name'] = array(
2001
- 'name' => 'name',
2002
- 'label' => 'Name',
2003
- 'type' => 'text',
2004
- 'options' => array(
2005
- 'required' => '1'
2006
- )
2007
- );
2008
-
2009
- $pod['fields']['created'] = array(
2010
- 'name' => 'created',
2011
- 'label' => 'Date Created',
2012
- 'type' => 'datetime',
2013
- 'options' => array(
2014
- 'datetime_format' => 'ymd_slash',
2015
- 'datetime_time_type' => '12',
2016
- 'datetime_time_format' => 'h_mm_ss_A'
2017
- )
2018
- );
2019
-
2020
- $pod['fields']['modified'] = array(
2021
- 'name' => 'modified',
2022
- 'label' => 'Date Modified',
2023
- 'type' => 'datetime',
2024
- 'options' => array(
2025
- 'datetime_format' => 'ymd_slash',
2026
- 'datetime_time_type' => '12',
2027
- 'datetime_time_format' => 'h_mm_ss_A'
2028
- )
2029
- );
2030
-
2031
- $pod['fields']['author'] = array(
2032
- 'name' => 'author',
2033
- 'label' => 'Author',
2034
- 'type' => 'pick',
2035
- 'pick_object' => 'user',
2036
- 'options' => array(
2037
- 'pick_format_type' => 'single',
2038
- 'pick_format_single' => 'autocomplete',
2039
- 'default_value' => '{@user.ID}'
2040
- )
2041
- );
 
 
 
 
 
 
2042
 
2043
- $pod['fields']['permalink'] = array(
2044
- 'name' => 'permalink',
2045
- 'label' => 'Permalink',
2046
- 'type' => 'slug',
2047
- 'description' => 'Leave blank to auto-generate from Name'
2048
- );
 
 
 
 
 
 
 
2049
 
2050
- if ( ! isset( $pod['options']['pod_index'] ) ) {
2051
- $pod['options']['pod_index'] = 'name';
2052
- }
 
 
 
 
2053
  }
2054
 
2055
  $pod = $this->do_hook( 'save_pod_default_pod', $pod, $params, $sanitized, $db );
@@ -2065,11 +2203,73 @@ class PodsAPI {
2065
  );
2066
  }
2067
 
2068
- if ( true === $db ) {
2069
- if ( ! has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) ) {
2070
- add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
2071
- }
2072
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2073
  $conflicted = false;
2074
 
2075
  // Headway compatibility fix
@@ -2079,7 +2279,7 @@ class PodsAPI {
2079
  $conflicted = true;
2080
  }
2081
 
2082
- $params->id = $this->save_wp_object( 'post', $post_data, $pod['options'], true, true );
2083
 
2084
  if ( $conflicted ) {
2085
  add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
@@ -2094,237 +2294,189 @@ class PodsAPI {
2094
 
2095
  $pod['id'] = $params->id;
2096
 
2097
- // Setup / update tables
2098
- if ( 'table' !== $pod['type'] && 'table' === $pod['storage'] && $old_storage !== $pod['storage'] && $db ) {
2099
- $definitions = array( "`id` BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY" );
2100
 
2101
- $defined_fields = array();
 
 
 
2102
 
2103
- foreach ( $pod['fields'] as $field ) {
2104
- if ( ! is_array( $field ) || ! isset( $field['name'] ) || in_array( $field['name'], $defined_fields ) ) {
2105
- continue;
2106
- }
 
 
2107
 
2108
- $defined_fields[] = $field['name'];
 
 
 
 
 
2109
 
2110
- if ( ! in_array( $field['type'], $tableless_field_types ) || ( 'pick' === $field['type'] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) ) {
2111
- $definition = $this->get_field_definition( $field['type'], array_merge( $field, pods_var_raw( 'options', $field, array() ) ) );
2112
 
2113
- if ( 0 < strlen( $definition ) ) {
2114
- $definitions[] = "`{$field['name']}` " . $definition;
2115
- }
2116
- }
2117
- }
2118
 
2119
- pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`" );
 
 
 
2120
 
2121
- /**
2122
- * @todo Central function to fetch charset.
2123
- * @see PodsUpgrade::install() L64-L76
2124
- */
2125
- $charset_collate = 'DEFAULT CHARSET utf8';
2126
 
2127
- global $wpdb;
2128
- if ( ! empty( $wpdb->charset ) ) {
2129
- $charset_collate = "DEFAULT CHARSET {$wpdb->charset}";
2130
- }
2131
 
2132
- if ( ! empty( $wpdb->collate ) ) {
2133
- $charset_collate .= " COLLATE {$wpdb->collate}";
2134
- }
2135
 
2136
- $result = pods_query( "CREATE TABLE `@wp_pods_{$params->name}` (" . implode( ', ', $definitions ) . ") {$charset_collate}", $this );
 
2137
 
2138
- if ( empty( $result ) ) {
2139
- return pods_error( __( 'Cannot add Database Table for Pod', 'pods' ), $this );
2140
- }
2141
 
2142
- } elseif ( 'table' !== $pod['type'] && 'table' === $pod['storage'] && $pod['storage'] == $old_storage && null !== $old_name && $old_name !== $params->name && $db ) {
2143
- $result = pods_query( "ALTER TABLE `@wp_pods_{$old_name}` RENAME `@wp_pods_{$params->name}`", $this );
 
2144
 
2145
- if ( empty( $result ) ) {
2146
- return pods_error( __( 'Cannot update Database Table for Pod', 'pods' ), $this );
2147
- }
2148
  }
2149
 
2150
- /**
2151
- * @var $wpdb wpdb
2152
- */
2153
- global $wpdb;
2154
-
2155
- if ( null !== $old_name && $old_name !== $params->name && $db ) {
2156
- // Rename items in the DB pointed at the old WP Object names
2157
- if ( 'post_type' === $pod['type'] && empty( $pod['object'] ) ) {
2158
- $this->rename_wp_object_type( 'post', $old_name, $params->name );
2159
- } elseif ( 'taxonomy' === $pod['type'] && empty( $pod['object'] ) ) {
2160
- $this->rename_wp_object_type( 'taxonomy', $old_name, $params->name );
2161
- } elseif ( 'comment' === $pod['type'] && empty( $pod['object'] ) ) {
2162
- $this->rename_wp_object_type( 'comment', $old_name, $params->name );
2163
- } elseif ( 'settings' === $pod['type'] ) {
2164
- $this->rename_wp_object_type( 'settings', $old_name, $params->name );
2165
- }
2166
 
2167
- // Sync any related fields if the name has changed
2168
- $fields = pods_query( "
2169
- SELECT `p`.`ID`
2170
- FROM `{$wpdb->posts}` AS `p`
2171
- LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
2172
- LEFT JOIN `{$wpdb->postmeta}` AS `pm2` ON `pm2`.`post_id` = `p`.`ID`
2173
- WHERE
2174
- `p`.`post_type` = '_pods_field'
2175
- AND `pm`.`meta_key` = 'pick_object'
2176
- AND (
2177
- `pm`.`meta_value` = 'pod'
2178
- OR `pm`.`meta_value` = '" . $pod['type'] . "'
2179
- )
2180
- AND `pm2`.`meta_key` = 'pick_val'
2181
- AND `pm2`.`meta_value` = '{$old_name}'
2182
- " );
2183
 
2184
- if ( ! empty( $fields ) ) {
2185
- foreach ( $fields as $field ) {
2186
- update_post_meta( $field->ID, 'pick_object', $pod['type'] );
2187
- update_post_meta( $field->ID, 'pick_val', $params->name );
2188
- }
2189
  }
 
2190
 
2191
- $fields = pods_query( "
2192
- SELECT `p`.`ID`
2193
- FROM `{$wpdb->posts}` AS `p`
2194
- LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
2195
- WHERE
2196
- `p`.`post_type` = '_pods_field'
2197
- AND `pm`.`meta_key` = 'pick_object'
2198
- AND (
2199
- `pm`.`meta_value` = 'pod-{$old_name}'
2200
- OR `pm`.`meta_value` = '" . $pod['type'] . "-{$old_name}'
2201
- )
2202
- " );
2203
 
2204
- if ( ! empty( $fields ) ) {
2205
- foreach ( $fields as $field ) {
2206
- update_post_meta( $field->ID, 'pick_object', $pod['type'] );
2207
- update_post_meta( $field->ID, 'pick_val', $params->name );
2208
- }
2209
- }
2210
- }
2211
 
2212
- // Sync built-in options for post types and taxonomies
2213
- if ( in_array( $pod['type'], array( 'post_type', 'taxonomy' ) ) && empty( $pod['object'] ) && $db ) {
2214
- // Build list of 'built_in' for later
2215
- $built_in = array();
2216
 
2217
- foreach ( $pod['options'] as $key => $val ) {
2218
- if ( false === strpos( $key, 'built_in_' ) ) {
2219
- continue;
2220
- } elseif ( false !== strpos( $key, 'built_in_post_types_' ) ) {
2221
- $built_in_type = 'post_type';
2222
- } elseif ( false !== strpos( $key, 'built_in_taxonomies_' ) ) {
2223
- $built_in_type = 'taxonomy';
2224
- } else {
2225
- continue;
2226
- }
2227
 
2228
- if ( $built_in_type == $pod['type'] ) {
2229
  continue;
2230
  }
2231
 
2232
- if ( ! isset( $built_in[ $built_in_type ] ) ) {
2233
- $built_in[ $built_in_type ] = array();
2234
- }
2235
 
2236
- $built_in_object = str_replace( array( 'built_in_post_types_', 'built_in_taxonomies_' ), '', $key );
 
2237
 
2238
- $built_in[ $built_in_type ][ $built_in_object ] = (int) $val;
2239
  }
 
 
2240
 
2241
- $lookup_option = false;
2242
- $lookup_built_in = false;
2243
 
2244
- $lookup_name = $pod['name'];
2245
-
2246
- if ( 'post_type' === $pod['type'] ) {
2247
- $lookup_option = 'built_in_post_types_' . $lookup_name;
2248
- $lookup_built_in = 'taxonomy';
2249
- } elseif ( 'taxonomy' === $pod['type'] ) {
2250
- $lookup_option = 'built_in_taxonomies_' . $lookup_name;
2251
- $lookup_built_in = 'post_type';
2252
- }
2253
 
2254
- if ( ! empty( $lookup_option ) && ! empty( $lookup_built_in ) && isset( $built_in[ $lookup_built_in ] ) ) {
2255
- foreach ( $built_in[ $lookup_built_in ] as $built_in_object => $val ) {
2256
- $search_val = 1;
2257
 
2258
- if ( 1 == $val ) {
2259
- $search_val = 0;
2260
- }
 
2261
 
2262
- $query = "SELECT p.ID FROM {$wpdb->posts} AS p
2263
- LEFT JOIN {$wpdb->postmeta} AS pm ON pm.post_id = p.ID AND pm.meta_key = '{$lookup_option}'
2264
- LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm2.post_id = p.ID AND pm2.meta_key = 'type' AND pm2.meta_value = '{$lookup_built_in}'
2265
- LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm3.post_id = p.ID AND pm3.meta_key = 'object' AND pm3.meta_value = ''
2266
- WHERE p.post_type = '_pods_pod' AND p.post_name = '{$built_in_object}'
2267
- AND pm2.meta_id IS NOT NULL
2268
- AND ( pm.meta_id IS NULL OR pm.meta_value = {$search_val} )";
2269
 
2270
- $results = pods_query( $query );
 
2271
 
2272
- if ( ! empty( $results ) ) {
2273
- foreach ( $results as $the_pod ) {
2274
- delete_post_meta( $the_pod->ID, $lookup_option );
2275
 
2276
- add_post_meta( $the_pod->ID, $lookup_option, $val );
2277
- }
2278
- }
2279
- }
2280
- }
2281
- }
2282
 
2283
- $saved = array();
2284
- $errors = array();
2285
 
2286
- $field_index_change = false;
2287
- $field_index_id = 0;
2288
 
2289
- $id_required = false;
2290
 
2291
- $field_index = pods_var( 'pod_index', $pod['options'], 'id', null, true );
 
2292
 
2293
- if ( 'pod' === $pod['type'] && ! empty( $pod['fields'] ) && isset( $pod['fields'][ $field_index ] ) ) {
2294
- $field_index_id = $pod['fields'][ $field_index ];
2295
- }
2296
 
2297
- if ( isset( $params->fields ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
2298
- $fields = array();
 
2299
 
2300
- if ( isset( $params->fields ) ) {
2301
- $params->fields = (array) $params->fields;
2302
 
2303
- $weight = 0;
 
 
 
 
2304
 
2305
- foreach ( $params->fields as $field ) {
2306
- if ( ! is_array( $field ) || ! isset( $field['name'] ) ) {
2307
- continue;
2308
- }
2309
 
2310
- if ( ! isset( $field['weight'] ) ) {
2311
- $field['weight'] = $weight;
2312
 
2313
- $weight ++;
2314
  }
2315
-
2316
- $fields[ $field['name'] ] = $field;
2317
  }
2318
  }
 
 
 
 
 
 
2319
 
2320
  $weight = 0;
2321
 
2322
- $saved_field_ids = array();
 
 
 
 
 
 
2323
 
2324
- foreach ( $pod['fields'] as $k => $field ) {
2325
- if ( ! empty( $old_id ) && ( ! is_array( $field ) || ! isset( $field['name'] ) || ! isset( $fields[ $field['name'] ] ) ) ) {
 
 
 
 
 
2326
  // Iterative change handling for setup-edit.php
2327
- if ( ! is_array( $field ) && isset( $old_fields[ $k ] ) ) {
2328
  $saved[ $old_fields[ $k ]['name'] ] = true;
2329
  }
2330
 
@@ -2332,10 +2484,13 @@ class PodsAPI {
2332
  }
2333
 
2334
  if ( ! empty( $old_id ) ) {
2335
- $field = array_merge( $field, $fields[ $field['name'] ] );
 
 
 
2336
  }
2337
 
2338
- $field['pod'] = $pod;
2339
 
2340
  if ( ! isset( $field['weight'] ) ) {
2341
  $field['weight'] = $weight;
@@ -2343,11 +2498,11 @@ class PodsAPI {
2343
  $weight ++;
2344
  }
2345
 
2346
- if ( 0 < $field_index_id && pods_var( 'id', $field ) == $field_index_id ) {
2347
  $field_index_change = $field['name'];
2348
  }
2349
 
2350
- if ( 0 < pods_var( 'id', $field ) ) {
2351
  $id_required = true;
2352
  }
2353
 
@@ -2357,30 +2512,28 @@ class PodsAPI {
2357
 
2358
  $field_data = $field;
2359
 
2360
- $field = $this->save_field( $field_data, $field_table_operation, true, $db );
2361
 
2362
  if ( true !== $db ) {
2363
- $pod['fields'][ $k ] = $field;
2364
  $saved_field_ids[] = $field['id'];
 
 
 
2365
  } else {
2366
- if ( ! empty( $field ) && 0 < $field ) {
2367
- $saved[ $field_data['name'] ] = true;
2368
- $saved_field_ids[] = $field;
2369
- } else {
2370
- $errors[] = sprintf( __( 'Cannot save the %s field', 'pods' ), $field_data['name'] );
2371
- }
2372
  }
2373
  }
2374
 
2375
  if ( true === $db ) {
2376
  foreach ( $old_fields as $field ) {
2377
- if ( isset( $pod['fields'][ $field['name'] ] ) || isset( $saved[ $field['name'] ] ) || in_array( $field['id'], $saved_field_ids ) ) {
2378
  continue;
2379
  }
2380
 
2381
- if ( $field['id'] == $field_index_id ) {
2382
  $field_index_change = 'id';
2383
- } elseif ( $field['name'] == $field_index ) {
2384
  $field_index_change = 'id';
2385
  }
2386
 
@@ -2398,6 +2551,10 @@ class PodsAPI {
2398
  }
2399
  }
2400
 
 
 
 
 
2401
  $this->cache_flush_pods( $pod );
2402
 
2403
  if ( ! empty( $errors ) ) {
@@ -2432,7 +2589,7 @@ class PodsAPI {
2432
  && in_array( $pod['type'], array(
2433
  'post_type',
2434
  'taxonomy'
2435
- ) )
2436
  && empty( $pod['object'] )
2437
  ) {
2438
  pods_init()->setup_content_types( true );
@@ -2446,175 +2603,1622 @@ class PodsAPI {
2446
  }
2447
 
2448
  /**
2449
- * Add or edit a field within a Pod
2450
  *
2451
- * $params['id'] int Field ID (id OR pod_id+pod+name required)
2452
- * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required)
2453
- * $params['pod'] string Pod name (id OR pod_id+pod+name required)
2454
- * $params['name'] string Field name (id OR pod_id+pod+name required)
2455
- * $params['label'] string (optional) Field label
2456
- * $params['type'] string (optional) Field type (avatar, boolean, code, color, currency, date, datetime, email,
2457
- * file, number, paragraph, password, phone, pick, slug, text, time, website, wysiwyg)
2458
- * $params['pick_object'] string (optional) Related Object (for relationships)
2459
- * $params['pick_val'] string (optional) Related Object name (for relationships)
2460
- * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships)
2461
- * $params['weight'] int (optional) Order in which the field appears
2462
- * $params['options'] array (optional) Options
2463
  *
2464
- * @param array $params An associative array of parameters
2465
- * @param bool $table_operation (optional) Whether or not to handle table operations
2466
- * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed,
2467
- * will sanitize them if false.
2468
- * @param bool|int $db (optional) Whether to save into the DB or just return field array.
2469
  *
2470
- * @return int|array The field ID or field array (if !$db)
2471
- * @since 1.7.9
 
2472
  */
2473
- public function save_field( $params, $table_operation = true, $sanitized = false, $db = true ) {
2474
-
2475
- /**
2476
- * @var $wpdb wpdb
2477
- */
2478
  global $wpdb;
2479
 
2480
- if ( true !== $db ) {
2481
- $table_operation = false;
2482
- }
2483
-
2484
  $tableless_field_types = PodsForm::tableless_field_types();
2485
  $simple_tableless_objects = PodsForm::simple_tableless_objects();
2486
 
2487
- $params = (object) $params;
2488
-
2489
- if ( false === $sanitized ) {
2490
- $params = pods_sanitize( $params );
2491
- }
2492
 
2493
- if ( isset( $params->pod_id ) ) {
2494
- $params->pod_id = pods_absint( $params->pod_id );
 
2495
  }
2496
 
2497
- if ( true !== $db ) {
2498
- $params->pod_id = (int) $db;
 
2499
  }
2500
 
2501
- $pod = null;
2502
- $save_pod = false;
2503
- $id_required = false;
2504
 
2505
- if ( isset( $params->id_required ) ) {
2506
- unset( $params->id_required );
 
 
 
2507
 
2508
- $id_required = true;
2509
- }
2510
 
2511
- if ( ( ! isset( $params->pod ) || empty( $params->pod ) ) && ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) ) {
2512
- return pods_error( __( 'Pod ID or name is required', 'pods' ), $this );
2513
- }
2514
 
2515
- if ( isset( $params->pod ) && is_array( $params->pod ) ) {
2516
- $pod = $params->pod;
 
 
 
 
 
 
 
 
 
2517
 
2518
- $save_pod = true;
2519
- } elseif ( ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) && ( true === $db || 0 < $db ) ) {
2520
- $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
2521
- } elseif ( ! isset( $params->pod ) && ( true === $db || 0 < $db ) ) {
2522
- $pod = $this->load_pod( array( 'id' => $params->pod_id, 'table_info' => true ) );
2523
- } elseif ( true === $db || 0 < $db ) {
2524
- $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
2525
- }
2526
 
2527
- if ( empty( $pod ) && true === $db ) {
2528
- return pods_error( __( 'Pod not found', 'pods' ), $this );
2529
- }
2530
 
2531
- $params->pod_id = $pod['id'];
2532
- $params->pod = $pod['name'];
2533
- $params->pod_data = $pod;
 
 
 
 
 
 
 
 
2534
 
2535
- $params->name = pods_clean_name( $params->name, true, ( 'meta' === $pod['storage'] ? false : true ) );
2536
 
2537
- if ( ! isset( $params->id ) ) {
2538
- $params->id = 0;
2539
- }
 
2540
 
2541
- if ( empty( $params->name ) ) {
2542
- return pods_error( __( 'Pod field name is required', 'pods' ), $this );
2543
- }
2544
 
2545
- $field = $this->load_field( $params );
 
 
 
 
2546
 
2547
- unset( $params->pod_data );
 
 
2548
 
2549
- $old_id = null;
2550
- $old_name = null;
2551
- $old_type = null;
2552
- $old_definition = null;
2553
- $old_simple = null;
2554
- $old_options = null;
2555
- $old_sister_id = null;
2556
 
2557
- // @todo pods_reserved_keywords();
2558
- $reserved_keywords = array( 'id', 'ID' );
 
2559
 
2560
- if ( ! empty( $field ) ) {
2561
- $old_id = pods_var( 'id', $field );
2562
- $old_name = pods_clean_name( $field['name'], true, ( 'meta' === $pod['storage'] ? false : true ) );
2563
- $old_type = $field['type'];
2564
- $old_options = $field['options'];
2565
- $old_sister_id = (int) pods_var( 'sister_id', $old_options, 0 );
2566
 
2567
- $old_simple = ( 'pick' === $old_type && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
2568
 
2569
- if ( isset( $params->name ) && ! empty( $params->name ) ) {
2570
- $field['name'] = $params->name;
2571
  }
 
 
 
2572
 
2573
- if ( $old_name !== $field['name'] ) {
2574
- if ( in_array( $field['name'], $reserved_keywords, true ) ) {
2575
- return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
2576
- }
2577
-
2578
- if ( false !== $this->field_exists( $params ) ) {
2579
- return pods_error( sprintf( __( 'Field %1$s already exists, you cannot rename %2$s to that', 'pods' ), $field['name'], $old_name ), $this );
2580
- }
2581
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2582
 
2583
- if ( ( $id_required || ! empty( $params->id ) ) && ( empty( $old_id ) || $old_id != $params->id ) ) {
2584
- return pods_error( sprintf( __( 'Field %s already exists', 'pods' ), $field['name'] ), $this );
 
 
 
 
 
 
 
 
 
 
 
2585
  }
2586
 
2587
- if ( empty( $params->id ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2588
  $params->id = $old_id;
2589
  }
2590
 
2591
- if ( ! in_array( $old_type, $tableless_field_types ) || $old_simple ) {
2592
- $definition = $this->get_field_definition( $old_type, array_merge( $field, $old_options ) );
2593
 
2594
- if ( 0 < strlen( $definition ) ) {
2595
- $old_definition = "`{$old_name}` " . $definition;
 
 
 
 
 
 
2596
  }
 
 
 
 
 
 
 
 
 
 
 
 
2597
  }
2598
  } else {
2599
- $field = array(
2600
  'id' => 0,
2601
  'pod_id' => $params->pod_id,
2602
- 'name' => $params->name,
2603
- 'label' => $params->name,
2604
- 'description' => '',
2605
- 'type' => 'text',
2606
- 'pick_object' => '',
2607
- 'pick_val' => '',
2608
- 'sister_id' => '',
2609
  'weight' => null,
2610
- 'options' => array()
2611
- );
2612
  }
2613
 
2614
  // Setup options
2615
  $options = get_object_vars( $params );
2616
 
2617
- $options_ignore = array(
2618
  'method',
2619
  'table_info',
2620
  'attributes',
@@ -2623,8 +4227,14 @@ class PodsAPI {
2623
  'developer_mode',
2624
  'dependency',
2625
  'depends-on',
2626
- 'excludes-on'
2627
- );
 
 
 
 
 
 
2628
 
2629
  foreach ( $options_ignore as $ignore ) {
2630
  if ( isset( $options[ $ignore ] ) ) {
@@ -2632,13 +4242,7 @@ class PodsAPI {
2632
  }
2633
  }
2634
 
2635
- if ( isset( $options['method'] ) ) {
2636
- unset( $options['method'] );
2637
- } elseif ( isset( $options['table_info'] ) ) {
2638
- unset( $options['table_info'] );
2639
- }
2640
-
2641
- $exclude = array(
2642
  'id',
2643
  'pod_id',
2644
  'pod',
@@ -2646,212 +4250,106 @@ class PodsAPI {
2646
  'label',
2647
  'description',
2648
  'type',
2649
- 'pick_object',
2650
- 'pick_val',
2651
- 'sister_id',
2652
  'weight',
2653
- 'options'
2654
- );
 
 
 
 
2655
 
2656
- foreach ( $exclude as $k => $exclude_field ) {
2657
- $aliases = array( $exclude_field );
2658
 
2659
- if ( is_array( $exclude_field ) ) {
2660
- $aliases = array_merge( array( $k ), $exclude_field );
2661
- $exclude_field = $k;
2662
  }
2663
 
2664
  foreach ( $aliases as $alias ) {
2665
  if ( isset( $options[ $alias ] ) ) {
2666
- $field[ $exclude_field ] = pods_trim( $options[ $alias ] );
2667
 
2668
  unset( $options[ $alias ] );
2669
  }
2670
  }
2671
  }
2672
 
2673
- if ( strlen( $field['label'] ) < 1 ) {
2674
- $field['label'] = $field['name'];
2675
  }
2676
 
2677
- $field['options']['type'] = $field['type'];
2678
-
2679
- if ( in_array( $field['options']['type'], $tableless_field_types ) ) {
2680
- // Clean up special drop-down in field editor and save out pick_val
2681
- $field['pick_object'] = pods_var( 'pick_object', $field, '', null, true );
2682
-
2683
- if ( 0 === strpos( $field['pick_object'], 'pod-' ) ) {
2684
- $field['pick_val'] = pods_str_replace( 'pod-', '', $field['pick_object'], 1 );
2685
- $field['pick_object'] = 'pod';
2686
- } elseif ( 0 === strpos( $field['pick_object'], 'post_type-' ) ) {
2687
- $field['pick_val'] = pods_str_replace( 'post_type-', '', $field['pick_object'], 1 );
2688
- $field['pick_object'] = 'post_type';
2689
- } elseif ( 0 === strpos( $field['pick_object'], 'taxonomy-' ) ) {
2690
- $field['pick_val'] = pods_str_replace( 'taxonomy-', '', $field['pick_object'], 1 );
2691
- $field['pick_object'] = 'taxonomy';
2692
- } elseif ( 'table' === $field['pick_object'] && 0 < strlen( pods_var_raw( 'pick_table', $field['options'] ) ) ) {
2693
- $field['pick_val'] = $field['options']['pick_table'];
2694
- $field['pick_object'] = 'table';
2695
- } elseif ( false === strpos( $field['pick_object'], '-' ) && ! in_array( $field['pick_object'], array(
2696
- 'pod',
2697
- 'post_type',
2698
- 'taxonomy'
2699
- ) ) ) {
2700
- $field['pick_val'] = '';
2701
- } elseif ( 'custom-simple' === $field['pick_object'] ) {
2702
- $field['pick_val'] = '';
2703
- }
2704
-
2705
- $field['options']['pick_object'] = $field['pick_object'];
2706
- $field['options']['pick_val'] = $field['pick_val'];
2707
- $field['options']['sister_id'] = pods_var( 'sister_id', $field );
2708
-
2709
- unset( $field['pick_object'] );
2710
- unset( $field['pick_val'] );
2711
-
2712
- if ( isset( $field['sister_id'] ) ) {
2713
- unset( $field['sister_id'] );
2714
- }
2715
  }
2716
 
2717
- $field['options'] = array_merge( $field['options'], $options );
 
2718
 
2719
- $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
2720
-
2721
- if ( 0 < $old_id && defined( 'PODS_FIELD_STRICT' ) && ! PODS_FIELD_STRICT ) {
2722
  $params->id = $old_id;
2723
- $field['id'] = $old_id;
2724
  }
2725
 
2726
- // Add new field
2727
- if ( ! isset( $params->id ) || empty( $params->id ) || empty( $field ) ) {
2728
- if ( $table_operation && in_array( $field['name'], array(
2729
- 'created',
2730
- 'modified'
2731
- ) ) && ! in_array( $field['type'], array(
2732
- 'date',
2733
- 'datetime'
2734
- ) ) && ( ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) ) {
2735
- return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
2736
- }
2737
-
2738
- if ( $table_operation && 'author' === $field['name'] && 'pick' !== $field['type'] && ( ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) ) {
2739
- return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
2740
- }
2741
-
2742
- if ( in_array( $field['name'], $reserved_keywords, true ) ) {
2743
- return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
2744
- }
2745
-
2746
- foreach ( $object_fields as $object_field => $object_field_opt ) {
2747
- if ( $object_field == $field['name'] || in_array( $field['name'], $object_field_opt['alias'] ) ) {
2748
- 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 );
2749
- }
2750
- }
2751
-
2752
- if ( in_array( $field['name'], array( 'rss' ) ) ) // Reserved post_name values that can't be used as field names
2753
- {
2754
- $field['name'] .= '2';
2755
  }
2756
 
2757
- if ( 'slug' === $field['type'] && true === $db ) {
2758
- if ( in_array( $pod['type'], array( 'post_type', 'taxonomy', 'user' ) ) ) {
2759
- return pods_error( __( 'This pod already has an internal WordPress permalink field', 'pods' ), $this );
2760
- }
2761
-
2762
- $slug_field = get_posts( array(
2763
- 'post_type' => '_pods_field',
2764
- 'orderby' => 'menu_order',
2765
- 'order' => 'ASC',
2766
- 'posts_per_page' => 1,
2767
- 'post_parent' => $field['pod_id'],
2768
- 'meta_query' => array(
2769
- array(
2770
- 'key' => 'type',
2771
- 'value' => 'slug'
2772
- )
2773
- )
2774
- ) );
2775
-
2776
- if ( ! empty( $slug_field ) ) {
2777
- return pods_error( __( 'This pod already has a permalink field', 'pods' ), $this );
2778
- }
2779
  }
2780
 
2781
- // Sink the new field to the bottom of the list
2782
- if ( null === $field['weight'] ) {
2783
- $field['weight'] = 0;
2784
 
2785
- $bottom_most_field = get_posts( array(
2786
- 'post_type' => '_pods_field',
2787
  'orderby' => 'menu_order',
2788
  'order' => 'DESC',
2789
  'posts_per_page' => 1,
2790
- 'post_parent' => $field['pod_id']
2791
  ) );
2792
 
2793
- if ( ! empty( $bottom_most_field ) ) {
2794
- $field['weight'] = pods_absint( $bottom_most_field[0]->menu_order ) + 1;
2795
  }
2796
  }
2797
 
2798
- $field['weight'] = pods_absint( $field['weight'] );
2799
 
2800
  $post_data = array(
2801
- 'post_name' => $field['name'],
2802
- 'post_title' => $field['label'],
2803
- 'post_content' => $field['description'],
2804
- 'post_type' => '_pods_field',
2805
- 'post_parent' => $field['pod_id'],
2806
  'post_status' => 'publish',
2807
- 'menu_order' => $field['weight']
2808
  );
2809
  } else {
2810
- if ( in_array( $field['name'], array( 'id', 'ID' ) ) ) {
2811
- if ( null !== $old_name ) {
2812
- return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
2813
- } else {
2814
- return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field['name'] ), $this );
2815
- }
2816
- }
2817
-
2818
- if ( null !== $old_name && $field['name'] !== $old_name && in_array( $field['name'], array(
2819
- 'created',
2820
- 'modified'
2821
- ) ) && ! in_array( $field['type'], array(
2822
- 'date',
2823
- 'datetime'
2824
- ) ) && ( ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) ) {
2825
- return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
2826
- }
2827
-
2828
- if ( null !== $old_name && $field['name'] !== $old_name && 'author' === $field['name'] && 'pick' !== $field['type'] && ( ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT ) ) {
2829
- return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
2830
- }
2831
-
2832
- foreach ( $object_fields as $object_field => $object_field_opt ) {
2833
- if ( $object_field !== $field['name'] && ! in_array( $field['name'], $object_field_opt['alias'] ) ) {
2834
- continue;
2835
- }
2836
-
2837
  if ( null !== $old_name ) {
2838
- return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
2839
  } else {
2840
- return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field['name'] ), $this );
2841
  }
2842
  }
2843
 
2844
  $post_data = array(
2845
- 'ID' => $field['id'],
2846
- 'post_name' => $field['name'],
2847
- 'post_title' => $field['label'],
2848
- 'post_content' => $field['description']
2849
  );
2850
 
2851
- if ( null !== $field['weight'] ) {
2852
- $field['weight'] = pods_absint( $field['weight'] );
2853
 
2854
- $post_data['menu_order'] = $field['weight'];
2855
  }
2856
  }
2857
 
@@ -2862,271 +4360,81 @@ class PodsAPI {
2862
 
2863
  $conflicted = false;
2864
 
2865
- // Headway compatibility fix
2866
- if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
2867
- remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2868
-
2869
- $conflicted = true;
2870
- }
2871
-
2872
- // Store the old field name
2873
- if ( $old_name && $old_name !== $post_data['post_name'] ) {
2874
- $field['options']['old_name'] = $old_name;
2875
- }
2876
-
2877
- $params->id = $this->save_wp_object( 'post', $post_data, $field['options'], true, true );
2878
-
2879
- if ( $conflicted ) {
2880
- add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2881
- }
2882
-
2883
- if ( false === $params->id ) {
2884
- return pods_error( __( 'Cannot save Field', 'pods' ), $this );
2885
- }
2886
- } else {
2887
- $params->id = $field['name'];
2888
- }
2889
-
2890
- $field['id'] = $params->id;
2891
-
2892
- $simple = ( 'pick' === $field['type'] && in_array( pods_v( 'pick_object', $field['options'] ), $simple_tableless_objects, true ) );
2893
-
2894
- $definition = false;
2895
-
2896
- if ( ! in_array( $field['type'], $tableless_field_types ) || $simple ) {
2897
- $field_definition = $this->get_field_definition( $field['type'], array_merge( $field, $field['options'] ) );
2898
-
2899
- if ( 0 < strlen( $field_definition ) ) {
2900
- $definition = '`' . $field['name'] . '` ' . $field_definition;
2901
- }
2902
- }
2903
-
2904
- $sister_id = (int) pods_var( 'sister_id', $field['options'], 0 );
2905
-
2906
- $definition_mode = 'bypass';
2907
-
2908
- if ( $table_operation && 'table' === $pod['storage'] && ! pods_tableless() ) {
2909
- if ( ! empty( $old_id ) ) {
2910
- if ( ( $field['type'] !== $old_type || $old_simple !== $simple ) && empty( $definition ) ) {
2911
- $definition_mode = 'drop';
2912
- } elseif ( 0 < strlen( $definition ) ) {
2913
- if ( $old_name !== $field['name'] || $old_simple !== $simple || $old_definition !== $definition ) {
2914
- $definition_mode = 'add';
2915
-
2916
- if ( 0 < strlen( $old_definition ) ) {
2917
- $definition_mode = 'change';
2918
- }
2919
- } elseif ( null !== $old_definition && $definition !== $old_definition ) {
2920
- $definition_mode = 'change';
2921
- }
2922
- }
2923
- } elseif ( 0 < strlen( $definition ) ) {
2924
- $definition_mode = 'add';
2925
-
2926
- if ( 0 < strlen( $old_definition ) ) {
2927
- $definition_mode = 'change';
2928
- }
2929
- }
2930
-
2931
- if ( 'bypass' !== $definition_mode ) {
2932
- /**
2933
- * Allow hooking into before the table has been altered for any custom functionality needed.
2934
- *
2935
- * @since 2.7.17
2936
- *
2937
- * @param string $definition_mode The definition mode used for the table field.
2938
- * @param array $pod The pod object.
2939
- * @param string $type The field type.
2940
- * @param array $field The field object.
2941
- * @param array $extra_info {
2942
- * Extra information about the field.
2943
- *
2944
- * @type bool $simple Whether the field is a simple tableless field.
2945
- * @type string $definition The field definition.
2946
- * @type null|string $old_name The old field name (if preexisting).
2947
- * @type null|string $old_definition The old field definition (if preexisting).
2948
- * @type null|array $old_options The old field options (if preexisting).
2949
- * }
2950
- */
2951
- do_action( 'pods_api_save_field_table_pre_alter', $definition_mode, $pod, $field['type'], $field, array(
2952
- 'simple' => $simple,
2953
- 'definition' => $definition,
2954
- 'old_name' => $old_name,
2955
- 'old_definition' => $old_definition,
2956
- 'old_options' => $old_options,
2957
- ) );
2958
-
2959
- if ( 'drop' === $definition_mode ) {
2960
- // Drop field column.
2961
- pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$old_name}`", false );
2962
- } elseif ( 'change' === $definition_mode ) {
2963
- // Change field column definition.
2964
- if ( $old_name && $old_name !== $field['name'] ) {
2965
- $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
2966
- } else {
2967
- $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` MODIFY {$definition}", false );
2968
- }
2969
-
2970
- if ( false === $test ) {
2971
- $definition_mode = 'add';
2972
- }
2973
- }
2974
-
2975
- // If the old field doesn't exist, continue to add a new field
2976
- if ( 'add' === $definition_mode ) {
2977
- pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
2978
- }
2979
-
2980
- /**
2981
- * Allow hooking into after the table has been altered for any custom functionality needed.
2982
- *
2983
- * @since 2.7.17
2984
- *
2985
- * @param string $definition_mode The definition mode used for the table field.
2986
- * @param array $pod The pod object.
2987
- * @param string $type The field type.
2988
- * @param array $field The field object.
2989
- * @param array $extra_info {
2990
- * Extra information about the field.
2991
- *
2992
- * @type bool $simple Whether the field is a simple tableless field.
2993
- * @type string $definition The field definition.
2994
- * @type null|string $old_name The old field name (if preexisting).
2995
- * @type null|string $old_definition The old field definition (if preexisting).
2996
- * @type null|array $old_options The old field options (if preexisting).
2997
- * }
2998
- */
2999
- do_action( 'pods_api_save_field_table_altered', $definition_mode, $pod, $field['type'], $field, array(
3000
- 'simple' => $simple,
3001
- 'definition' => $definition,
3002
- 'old_name' => $old_name,
3003
- 'old_definition' => $old_definition,
3004
- 'old_options' => $old_options,
3005
- ) );
3006
- }
3007
- }
3008
-
3009
- if ( ! empty( $old_id ) && 'meta' === $pod['storage'] && $old_name !== $field['name'] && $pod['meta_table'] !== $pod['table'] ) {
3010
- $prepare = array(
3011
- $field['name'],
3012
- $old_name
3013
- );
3014
-
3015
- // Users don't have a type
3016
- if ( ! empty( $pod['field_type'] ) ) {
3017
- $prepare[] = $pod['name'];
3018
- }
3019
-
3020
- $join_table = $pod['table'];
3021
 
3022
- // Taxonomies are the odd type out, terrible I know
3023
- if ( 'taxonomy' === $pod['type'] ) {
3024
- // wp_term_taxonomy has the 'taxonomy' field we need to limit by
3025
- $join_table = $wpdb->term_taxonomy;
3026
  }
3027
 
3028
- pods_query( "
3029
- UPDATE `{$pod[ 'meta_table' ]}` AS `m`
3030
- LEFT JOIN `{$join_table}` AS `t`
3031
- ON `t`.`{$pod[ 'field_id' ]}` = `m`.`{$pod[ 'meta_field_id' ]}`
3032
- SET
3033
- `m`.`{$pod[ 'meta_field_index' ]}` = %s
3034
- WHERE
3035
- `m`.`{$pod[ 'meta_field_index' ]}` = %s
3036
- " . ( ! empty( $pod['field_type'] ) ? " AND `t`.`{$pod[ 'field_type' ]}` = %s" : "" ), $prepare );
3037
- }
3038
-
3039
- if ( $field['type'] !== $old_type && in_array( $old_type, $tableless_field_types ) ) {
3040
- delete_post_meta( $old_sister_id, 'sister_id' );
3041
 
3042
- if ( true === $db ) {
3043
- pods_query( "
3044
- DELETE pm
3045
- FROM {$wpdb->postmeta} AS pm
3046
- LEFT JOIN {$wpdb->posts} AS p
3047
- ON p.post_type = '_pods_field'
3048
- AND p.ID = pm.post_id
3049
- WHERE
3050
- p.ID IS NOT NULL
3051
- AND pm.meta_key = 'sister_id'
3052
- AND pm.meta_value = %d
3053
- ", array(
3054
- $params->id
3055
- ) );
3056
 
3057
- if ( ! pods_tableless() ) {
3058
- pods_query( "DELETE FROM @wp_podsrel WHERE `field_id` = {$params->id}", false );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3059
 
3060
- pods_query( "
3061
- UPDATE `@wp_podsrel`
3062
- SET `related_field_id` = 0
3063
- WHERE `field_id` = %d
3064
- ", array(
3065
- $old_sister_id
3066
- ) );
3067
  }
3068
  }
3069
- } elseif ( 0 < $sister_id ) {
3070
- update_post_meta( $sister_id, 'sister_id', $params->id );
3071
 
3072
- if ( true === $db && ( ! pods_tableless() ) ) {
3073
- pods_query( "
3074
- UPDATE `@wp_podsrel`
3075
- SET `related_field_id` = %d
3076
- WHERE `field_id` = %d
3077
- ", array(
3078
- $params->id,
3079
- $sister_id
3080
- ) );
3081
  }
3082
- } elseif ( 0 < $old_sister_id ) {
3083
- delete_post_meta( $old_sister_id, 'sister_id' );
3084
 
3085
- if ( true === $db && ( ! pods_tableless() ) ) {
3086
- pods_query( "
3087
- UPDATE `@wp_podsrel`
3088
- SET `related_field_id` = 0
3089
- WHERE `field_id` = %d
3090
- ", array(
3091
- $old_sister_id
3092
- ) );
3093
  }
 
 
3094
  }
3095
 
3096
- if ( ! empty( $old_id ) && $old_name !== $field['name'] && true === $db ) {
3097
- pods_query( "
3098
- UPDATE `@wp_postmeta`
3099
- SET `meta_value` = %s
3100
- WHERE
3101
- `post_id` = %d
3102
- AND `meta_key` = 'pod_index'
3103
- AND `meta_value` = %s
3104
- ", array(
3105
- $field['name'],
3106
- $pod['id'],
3107
- $old_name
3108
- ) );
3109
- }
3110
 
3111
- if ( ! $save_pod ) {
3112
- $this->cache_flush_pods( $pod );
3113
- } else {
3114
- pods_transient_clear( 'pods_field_' . $pod['name'] . '_' . $field['name'] );
3115
 
3116
- if ( ! empty( $old_id ) && $old_name !== $field['name'] ) {
3117
- pods_transient_clear( 'pods_field_' . $pod['name'] . '_' . $old_name );
3118
- }
3119
- }
 
 
 
 
 
 
3120
 
3121
  if ( true === $db ) {
3122
  return $params->id;
3123
  } else {
3124
- return $field;
3125
  }
3126
  }
3127
 
3128
  /**
3129
- * Fix Pod / Field post_name to ensure they are exactly as saved (allow multiple posts w/ same post_name)
3130
  *
3131
  * @param string $slug Unique slug value
3132
  * @param int $post_ID Post ID
@@ -3140,8 +4448,7 @@ class PodsAPI {
3140
  * @since 2.3.3
3141
  */
3142
  public function save_slug_fix( $slug, $post_ID, $post_status, $post_type, $post_parent = 0, $original_slug = null ) {
3143
-
3144
- if ( in_array( $post_type, array( '_pods_field', '_pods_pod' ) ) && false !== strpos( $slug, '-' ) ) {
3145
  $slug = $original_slug;
3146
  }
3147
 
@@ -3154,7 +4461,6 @@ class PodsAPI {
3154
  * $params['id'] int The Object ID
3155
  * $params['name'] string The Object name
3156
  * $params['type'] string The Object type
3157
- * $params['options'] Associative array of Object options
3158
  *
3159
  * @param array|object $params An associative array of parameters
3160
  * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed,
@@ -3169,6 +4475,8 @@ class PodsAPI {
3169
 
3170
  if ( false === $sanitized ) {
3171
  $params = pods_sanitize( $params );
 
 
3172
  }
3173
 
3174
  if ( ! isset( $params->name ) || empty( $params->name ) ) {
@@ -3179,56 +4487,37 @@ class PodsAPI {
3179
  return pods_error( __( 'Type must be given to save an Object', 'pods' ), $this );
3180
  }
3181
 
3182
- $object = array(
3183
- 'id' => 0,
3184
- 'name' => $params->name,
3185
- 'type' => $params->type,
3186
- 'code' => '',
3187
- 'options' => array()
3188
- );
3189
 
3190
  // Setup options
3191
  $options = get_object_vars( $params );
3192
 
 
 
 
 
 
 
3193
  if ( isset( $options['method'] ) ) {
3194
  unset( $options['method'] );
3195
  }
3196
 
3197
- $exclude = array(
3198
- 'id',
3199
- 'name',
3200
- 'helper_type',
3201
- 'code',
3202
- 'options',
3203
- 'status'
3204
- );
3205
-
3206
- foreach ( $exclude as $k => $exclude_field ) {
3207
- $aliases = array( $exclude_field );
3208
-
3209
- if ( is_array( $exclude_field ) ) {
3210
- $aliases = array_merge( array( $k ), $exclude_field );
3211
- $exclude_field = $k;
3212
- }
3213
 
3214
- foreach ( $aliases as $alias ) {
3215
- if ( isset( $options[ $alias ] ) ) {
3216
- $object[ $exclude_field ] = pods_trim( $options[ $alias ] );
3217
 
3218
- unset( $options[ $alias ] );
3219
- }
 
3220
  }
3221
  }
3222
 
3223
- if ( 'helper' === $object['type'] ) {
3224
- $object['options']['helper_type'] = $object['helper_type'];
3225
- }
3226
-
3227
- if ( isset( $object['options']['code'] ) ) {
3228
- unset( $object['options']['code'] );
3229
- }
3230
-
3231
- $object['options'] = array_merge( $object['options'], $options );
3232
 
3233
  $post_data = array(
3234
  'post_name' => pods_clean_name( $object['name'], true ),
@@ -3242,15 +4531,17 @@ class PodsAPI {
3242
  $post_data['ID'] = $object['id'];
3243
  }
3244
 
3245
- if ( null !== pods_var( 'status', $object, null, null, true ) ) {
3246
- $post_data['post_status'] = pods_var( 'status', $object, null, null, true );
 
 
3247
  }
3248
 
3249
  remove_filter( 'content_save_pre', 'balanceTags', 50 );
3250
 
3251
  $post_data = pods_sanitize( $post_data );
3252
 
3253
- $params->id = $this->save_post( $post_data, $object['options'], true, true );
3254
 
3255
  pods_transient_clear( 'pods_objects_' . $params->type );
3256
  pods_transient_clear( 'pods_objects_' . $params->type . '_get' );
@@ -3268,7 +4559,7 @@ class PodsAPI {
3268
  * $params['code'] string The template code
3269
  *
3270
  * @param array|object $params An associative array of parameters
3271
- * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed,
3272
  * will sanitize them if false.
3273
  *
3274
  * @return int The Template ID
@@ -3294,7 +4585,7 @@ class PodsAPI {
3294
  * $params['code'] string The page code
3295
  *
3296
  * @param array|object $params An associative array of parameters
3297
- * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed,
3298
  * will sanitize them if false.
3299
  *
3300
  * @return int The page ID
@@ -3331,29 +4622,16 @@ class PodsAPI {
3331
  * $params['code'] string The helper code
3332
  *
3333
  * @param array $params An associative array of parameters
3334
- * @param bool $sanitized (optional) Decides wether the params have been sanitized before being passed, will
3335
  * sanitize them if false.
3336
  *
3337
  * @return int The helper ID
3338
  * @since 1.7.9
 
 
3339
  */
3340
  public function save_helper( $params, $sanitized = false ) {
3341
-
3342
- $params = (object) $params;
3343
-
3344
- if ( isset( $params->phpcode ) ) {
3345
- $params->code = $params->phpcode;
3346
- unset( $params->phpcode );
3347
- }
3348
-
3349
- if ( isset( $params->type ) ) {
3350
- $params->helper_type = $params->type;
3351
- unset( $params->type );
3352
- }
3353
-
3354
- $params->type = 'helper';
3355
-
3356
- return $this->save_object( $params, $sanitized );
3357
  }
3358
 
3359
  /**
@@ -3382,6 +4660,7 @@ class PodsAPI {
3382
 
3383
  $tableless_field_types = PodsForm::tableless_field_types();
3384
  $repeatable_field_types = PodsForm::repeatable_field_types();
 
3385
  $simple_tableless_objects = PodsForm::simple_tableless_objects();
3386
 
3387
  $error_mode = $this->display_errors;
@@ -3390,51 +4669,6 @@ class PodsAPI {
3390
  $error_mode = $params->error_mode;
3391
  }
3392
 
3393
- // @deprecated 2.0.0
3394
- if ( isset( $params->datatype ) ) {
3395
- pods_deprecated( '$params->pod instead of $params->datatype', '2.0' );
3396
-
3397
- $params->pod = $params->datatype;
3398
-
3399
- unset( $params->datatype );
3400
-
3401
- if ( isset( $params->pod_id ) ) {
3402
- pods_deprecated( '$params->id instead of $params->pod_id', '2.0' );
3403
-
3404
- $params->id = $params->pod_id;
3405
-
3406
- unset( $params->pod_id );
3407
- }
3408
-
3409
- if ( isset( $params->data ) && ! empty( $params->data ) && is_array( $params->data ) ) {
3410
- $check = current( $params->data );
3411
-
3412
- if ( is_array( $check ) ) {
3413
- pods_deprecated( 'PodsAPI::save_pod_items', '2.0' );
3414
-
3415
- return $this->save_pod_items( $params, $params->data );
3416
- }
3417
- }
3418
- }
3419
-
3420
- // @deprecated 2.0.0
3421
- if ( isset( $params->tbl_row_id ) ) {
3422
- pods_deprecated( '$params->id instead of $params->tbl_row_id', '2.0' );
3423
-
3424
- $params->id = $params->tbl_row_id;
3425
-
3426
- unset( $params->tbl_row_id );
3427
- }
3428
-
3429
- // @deprecated 2.0.0
3430
- if ( isset( $params->columns ) ) {
3431
- pods_deprecated( '$params->data instead of $params->columns', '2.0' );
3432
-
3433
- $params->data = $params->columns;
3434
-
3435
- unset( $params->columns );
3436
- }
3437
-
3438
  if ( ! isset( $params->pod ) ) {
3439
  $params->pod = false;
3440
  }
@@ -3520,7 +4754,7 @@ class PodsAPI {
3520
  }
3521
 
3522
  // Get array of Pods
3523
- $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod, 'table_info' => true ) );
3524
 
3525
  if ( false === $pod ) {
3526
  return pods_error( __( 'Pod not found', 'pods' ), $error_mode );
@@ -3533,9 +4767,12 @@ class PodsAPI {
3533
  $params->id = $pod['id'];
3534
  }
3535
 
3536
- $fields = $pod['fields'];
 
3537
 
3538
- $object_fields = (array) pods_var_raw( 'object_fields', $pod, array(), null, true );
 
 
3539
 
3540
  $fields_active = array();
3541
  $custom_data = array();
@@ -3546,14 +4783,17 @@ class PodsAPI {
3546
  foreach ( $params->data as $field => $value ) {
3547
  if ( isset( $object_fields[ $field ] ) ) {
3548
  $object_fields[ $field ]['value'] = $value;
3549
- $fields_active[] = $field;
 
3550
  } elseif ( isset( $fields[ $field ] ) ) {
3551
- if ( 'save' === $params->from || true === PodsForm::permission( $fields[ $field ]['type'], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3552
  $fields[ $field ]['value'] = $value;
3553
- $fields_active[] = $field;
3554
- } elseif ( ! pods_has_permissions( $fields[ $field ]['options'] ) && pods_var( 'hidden', $fields[ $field ]['options'], false ) ) {
 
3555
  $fields[ $field ]['value'] = $value;
3556
- $fields_active[] = $field;
 
3557
  }
3558
  } else {
3559
  $found = false;
@@ -3561,7 +4801,8 @@ class PodsAPI {
3561
  foreach ( $object_fields as $object_field => $object_field_opt ) {
3562
  if ( in_array( $field, $object_field_opt['alias'] ) ) {
3563
  $object_fields[ $object_field ]['value'] = $value;
3564
- $fields_active[] = $object_field;
 
3565
 
3566
  $found = true;
3567
 
@@ -3584,46 +4825,50 @@ class PodsAPI {
3584
  unset( $params->data );
3585
  }
3586
 
3587
- if ( empty( $params->id ) && ! in_array( 'created', $fields_active ) && isset( $fields['created'] ) && in_array( $fields['created']['type'], array(
3588
  'date',
3589
  'datetime'
3590
- ) ) ) {
3591
  $fields['created']['value'] = current_time( 'mysql' );
3592
- $fields_active[] = 'created';
 
3593
  }
3594
 
3595
- if ( ! in_array( 'modified', $fields_active ) && isset( $fields['modified'] ) && in_array( $fields['modified']['type'], array(
3596
  'date',
3597
  'datetime'
3598
- ) ) ) {
3599
  $fields['modified']['value'] = current_time( 'mysql' );
3600
- $fields_active[] = 'modified';
 
3601
  }
3602
 
3603
- if ( in_array( $pod['type'], array(
3604
  'pod',
3605
  'table'
3606
- ) ) && 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'] ] ) ) {
3607
  $fields[ $pod['pod_field_slug'] ]['value'] = ''; // this will get picked up by slug pre_save method
3608
- $fields_active[] = $pod['pod_field_slug'];
 
3609
  }
3610
 
3611
  // Handle hidden fields
3612
  if ( empty( $params->id ) ) {
3613
  foreach ( $fields as $field => $field_data ) {
3614
- if ( in_array( $field, $fields_active ) ) {
3615
  continue;
3616
  }
3617
 
3618
  if ( in_array( $params->from, array(
3619
  'save',
3620
  'process_form'
3621
- ) ) || true === PodsForm::permission( $fields[ $field ]['type'], $field, $fields[ $field ], $fields, $pod, $params->id, $params ) ) {
3622
- $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 );
3623
 
3624
  if ( null !== $value && '' !== $value && false !== $value ) {
3625
  $fields[ $field ]['value'] = $value;
3626
- $fields_active[] = $field;
 
3627
  }
3628
  }
3629
  }
@@ -3631,34 +4876,40 @@ class PodsAPI {
3631
  // Set default field values for object fields
3632
  if ( ! empty( $object_fields ) ) {
3633
  foreach ( $object_fields as $field => $field_data ) {
3634
- if ( in_array( $field, $fields_active ) ) {
3635
  continue;
3636
- } elseif ( ! isset( $field_data['default'] ) || strlen( $field_data['default'] ) < 1 ) {
 
 
3637
  continue;
3638
  }
3639
 
3640
- $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 );
3641
 
3642
  if ( null !== $value && '' !== $value && false !== $value ) {
3643
  $object_fields[ $field ]['value'] = $value;
3644
- $fields_active[] = $field;
 
3645
  }
3646
  }
3647
  }
3648
 
3649
  // Set default field values for Pod fields
3650
  foreach ( $fields as $field => $field_data ) {
3651
- if ( in_array( $field, $fields_active ) ) {
3652
  continue;
3653
- } elseif ( ! isset( $field_data['default'] ) || strlen( $field_data['default'] ) < 1 ) {
 
 
3654
  continue;
3655
  }
3656
 
3657
- $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 );
3658
 
3659
  if ( null !== $value && '' !== $value && false !== $value ) {
3660
  $fields[ $field ]['value'] = $value;
3661
- $fields_active[] = $field;
 
3662
  }
3663
  }
3664
  }
@@ -3728,24 +4979,12 @@ class PodsAPI {
3728
 
3729
  // Call any pre-save helpers (if not bypassed)
3730
  if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) {
3731
- if ( ! empty( $pod['options'] ) && is_array( $pod['options'] ) ) {
3732
  $helpers = array( 'pre_save_helpers', 'post_save_helpers' );
3733
 
3734
  foreach ( $helpers as $helper ) {
3735
- if ( isset( $pod['options'][ $helper ] ) && ! empty( $pod['options'][ $helper ] ) ) {
3736
- ${$helper} = explode( ',', $pod['options'][ $helper ] );
3737
- }
3738
- }
3739
- }
3740
-
3741
- if ( ! empty( $pre_save_helpers ) ) {
3742
- pods_deprecated( sprintf( __( 'Pre-save helpers are deprecated, use the action pods_pre_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
3743
-
3744
- foreach ( $pre_save_helpers as $helper ) {
3745
- $helper = $this->load_helper( array( 'name' => $helper ) );
3746
-
3747
- if ( false !== $helper ) {
3748
- eval( '?>' . $helper['code'] );
3749
  }
3750
  }
3751
  }
@@ -3762,10 +5001,10 @@ class PodsAPI {
3762
 
3763
  $object_ID = 'ID';
3764
 
3765
- if ( 'comment' === $object_type ) {
3766
- $object_ID = 'comment_ID';
3767
- } elseif ( 'taxonomy' === $object_type ) {
3768
- $object_ID = 'term_id';
3769
  }
3770
 
3771
  $object_data = array();
@@ -3792,7 +5031,11 @@ class PodsAPI {
3792
 
3793
  $value = $field_data['value'];
3794
  $type = $field_data['type'];
3795
- $options = pods_var( 'options', $field_data, array() );
 
 
 
 
3796
 
3797
  // WPML AJAX compatibility
3798
  if ( is_admin()
@@ -3801,10 +5044,10 @@ class PodsAPI {
3801
  && isset( $_POST['icl_ajx_action'] ) && isset( $_POST['_icl_nonce'] )
3802
  && wp_verify_nonce( $_POST['_icl_nonce'], $_POST['icl_ajx_action'] . '_nonce' ) )
3803
  ) {
3804
- $options['unique'] = 0;
3805
- $fields[ $field ]['options']['unique'] = 0;
3806
- $options['required'] = 0;
3807
- $fields[ $field ]['options']['required'] = 0;
3808
  } else {
3809
  // Validate value
3810
  $validate = $this->handle_field_validation( $value, $field, $object_fields, $fields, $pod, $params );
@@ -3820,7 +5063,7 @@ class PodsAPI {
3820
  }
3821
  }
3822
 
3823
- $value = PodsForm::pre_save( $field_data['type'], $value, $params->id, $field, array_merge( $field_data, $options ), array_merge( $fields, $object_fields ), $pod, $params );
3824
 
3825
  $field_data['value'] = $value;
3826
 
@@ -3832,7 +5075,7 @@ class PodsAPI {
3832
  $object_data[ $field ] = $value;
3833
  }
3834
  } else {
3835
- $simple = ( 'pick' === $type && in_array( pods_var( 'pick_object', $field_data ), $simple_tableless_objects ) );
3836
  $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field_data, $field, $fields, $pod, $params );
3837
 
3838
  // Handle Simple Relationships
@@ -3845,16 +5088,16 @@ class PodsAPI {
3845
  }
3846
  }
3847
 
3848
- $pick_limit = (int) pods_var_raw( 'pick_limit', $options, 0 );
3849
 
3850
- if ( 'single' === pods_var_raw( 'pick_format_type', $options ) ) {
3851
  $pick_limit = 1;
3852
  }
3853
 
3854
- if ( 'custom-simple' === pods_var( 'pick_object', $field_data ) ) {
3855
- $custom = pods_var_raw( 'pick_custom', $options, '' );
3856
 
3857
- $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $field_data['name'], $value, array_merge( $field_data, $options ), $pod, $params->id );
3858
 
3859
  // Input values are unslashed. Unslash database values as well to ensure correct comparison.
3860
  $custom = pods_unslash( $custom );
@@ -3906,10 +5149,10 @@ class PodsAPI {
3906
  if ( empty( $value ) ) {
3907
  $value = '';
3908
  } elseif ( is_array( $value ) ) {
3909
- if ( 1 == $pick_limit || 1 == count( $value ) ) {
3910
  // If there's just one item, don't save as an array, save the string
3911
  $value = implode( '', $value );
3912
- } elseif ( 'table' === pods_var( 'storage', $pod ) ) {
3913
  // If storage is set to table, json encode, otherwise WP will serialize automatically
3914
  $value = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $value, JSON_UNESCAPED_UNICODE ) : json_encode( $value );
3915
  }
@@ -3917,16 +5160,16 @@ class PodsAPI {
3917
  }
3918
 
3919
  // Prepare all table / meta data
3920
- if ( ! in_array( $type, $tableless_field_types ) || $simple ) {
3921
- if ( in_array( $type, $repeatable_field_types ) && 1 == pods_var( $type . '_repeatable', $field_data, 0 ) ) {
3922
  // Don't save an empty array, just make it an empty string
3923
  if ( empty( $value ) ) {
3924
  $value = '';
3925
  } elseif ( is_array( $value ) ) {
3926
- if ( 1 == count( $value ) ) {
3927
  // If there's just one item, don't save as an array, save the string
3928
  $value = implode( '', $value );
3929
- } elseif ( 'table' === pods_var( 'storage', $pod ) ) {
3930
  // If storage is set to table, json encode, otherwise WP will serialize automatically
3931
  $value = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $value, JSON_UNESCAPED_UNICODE ) : json_encode( $value );
3932
  }
@@ -4049,40 +5292,42 @@ class PodsAPI {
4049
  pods_no_conflict_on( $pod['type'] );
4050
  }
4051
 
 
 
4052
  // Save relationship / file data
4053
  if ( ! empty( $rel_fields ) ) {
4054
  foreach ( $rel_fields as $type => $data ) {
4055
  // Only handle tableless fields
4056
- if ( ! in_array( $type, $tableless_field_types ) ) {
4057
  continue;
4058
  }
4059
 
4060
  foreach ( $data as $field => $values ) {
4061
- $pick_val = pods_var( 'pick_val', $fields[ $field ] );
4062
 
4063
- if ( 'table' === pods_var( 'pick_object', $fields[ $field ] ) ) {
4064
- $pick_val = pods_var( 'pick_table', $fields[ $field ]['options'], $pick_val, null, true );
4065
  }
4066
 
4067
  if ( '__current__' === $pick_val ) {
4068
- if ( is_object( $pod ) ) {
4069
- $pick_val = $pod->pod;
4070
- } elseif ( is_array( $pod ) ) {
4071
  $pick_val = $pod['name'];
4072
- } elseif ( 0 < strlen( $pod ) ) {
 
 
4073
  $pick_val = $pod;
4074
  }
4075
  }
4076
 
4077
- $fields[ $field ]['options']['table_info'] = pods_api()->get_table_info( pods_var( 'pick_object', $fields[ $field ] ), $pick_val, null, null, $fields[ $field ]['options'] );
4078
 
4079
- if ( isset( $fields[ $field ]['options']['table_info']['pod'] ) && ! empty( $fields[ $field ]['options']['table_info']['pod'] ) && isset( $fields[ $field ]['options']['table_info']['pod']['name'] ) ) {
4080
- $search_data = pods( $fields[ $field ]['options']['table_info']['pod']['name'] );
4081
 
4082
  $data_mode = 'pods';
4083
  } else {
4084
  $search_data = pods_data();
4085
- $search_data->table( $fields[ $field ]['options']['table_info'] );
4086
 
4087
  $data_mode = 'data';
4088
  }
@@ -4101,17 +5346,17 @@ class PodsAPI {
4101
  $find_rel_params = false;
4102
  }
4103
 
4104
- $related_limit = (int) pods_var_raw( $type . '_limit', $fields[ $field ]['options'], 0 );
4105
 
4106
- if ( 'single' === pods_var_raw( $type . '_format_type', $fields[ $field ]['options'] ) ) {
4107
  $related_limit = 1;
4108
  }
4109
 
4110
  // Enforce integers / unique values for IDs
4111
  $value_ids = array();
4112
 
4113
- $is_file_field = in_array( $type, PodsForm::file_field_types() );
4114
- $is_taggable = ( in_array( $type, PodsForm::tableless_field_types() ) && 1 == pods_v( $type . '_taggable', $fields[ $field ]['options'] ) );
4115
 
4116
  // @todo Handle simple relationships eventually
4117
  foreach ( $values as $v ) {
@@ -4199,9 +5444,11 @@ class PodsAPI {
4199
  $values = array_slice( $values, 0, $related_limit );
4200
  }
4201
 
 
 
4202
  // Get current values
4203
- if ( 'pick' === $type && isset( PodsField_Pick::$related_data[ $fields[ $field ]['id'] ] ) && isset( PodsField_Pick::$related_data[ $fields[ $field ]['id'] ]['current_ids'] ) ) {
4204
- $related_ids = PodsField_Pick::$related_data[ $fields[ $field ]['id'] ]['current_ids'];
4205
  } else {
4206
  $related_ids = $this->lookup_related_items( $fields[ $field ]['id'], $pod['id'], $params->id, $fields[ $field ], $pod );
4207
  }
@@ -4209,14 +5456,16 @@ class PodsAPI {
4209
  // Get ids to remove
4210
  $remove_ids = array_diff( $related_ids, $value_ids );
4211
 
4212
- // Delete relationships
4213
- if ( ! empty( $remove_ids ) ) {
4214
- $this->delete_relationships( $params->id, $remove_ids, $pod, $fields[ $field ] );
4215
- }
 
4216
 
4217
- // Save relationships
4218
- if ( ! empty( $value_ids ) ) {
4219
- $this->save_relationships( $params->id, $value_ids, $pod, $fields[ $field ] );
 
4220
  }
4221
 
4222
  $field_save_values = $value_ids;
@@ -4226,15 +5475,20 @@ class PodsAPI {
4226
  }
4227
 
4228
  // Run save function for field type (where needed)
4229
- PodsForm::save( $type, $field_save_values, $params->id, $field, array_merge( $fields[ $field ], $fields[ $field ]['options'] ), array_merge( $fields, $object_fields ), $pod, $params );
4230
  }
4231
 
4232
  // Unset data no longer needed
4233
  if ( 'pick' === $type ) {
4234
  foreach ( $data as $field => $values ) {
4235
- if ( isset( PodsField_Pick::$related_data[ $fields[ $field ]['id'] ] ) ) {
4236
- unset( PodsField_Pick::$related_data[ PodsField_Pick::$related_data[ $fields[ $field ]['id'] ]['related_field']['id'] ] );
4237
- unset( PodsField_Pick::$related_data[ $fields[ $field ]['id'] ] );
 
 
 
 
 
4238
  }
4239
  }
4240
  }
@@ -4286,21 +5540,6 @@ class PodsAPI {
4286
  $this->do_hook( 'post_edit_pod_item', $compact_pieces, $params->id );
4287
  $this->do_hook( "post_edit_pod_item_{$params->pod}", $compact_pieces, $params->id );
4288
  }
4289
-
4290
- // Call any post-save helpers (if not bypassed)
4291
- if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) {
4292
- if ( ! empty( $post_save_helpers ) ) {
4293
- pods_deprecated( sprintf( __( 'Post-save helpers are deprecated, use the action pods_post_save_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
4294
-
4295
- foreach ( $post_save_helpers as $helper ) {
4296
- $helper = $this->load_helper( array( 'name' => $helper ) );
4297
-
4298
- if ( false !== $helper && ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) ) {
4299
- eval( '?>' . $helper['code'] );
4300
- }
4301
- }
4302
- }
4303
- }
4304
  }
4305
 
4306
  // Success! Return the id
@@ -4357,10 +5596,11 @@ class PodsAPI {
4357
  * @return array List of changed fields (if $mode = 'get')
4358
  */
4359
  public static function handle_changed_fields( $pod, $id, $mode = 'set' ) {
 
4360
 
4361
- static $changed_pods_cache = array();
4362
- static $old_fields_cache = array();
4363
- static $changed_fields_cache = array();
4364
 
4365
  $cache_key = $pod . '|' . $id;
4366
 
@@ -4418,6 +5658,10 @@ class PodsAPI {
4418
  }
4419
  }
4420
 
 
 
 
 
4421
  return $changed_fields;
4422
 
4423
  }
@@ -4432,32 +5676,39 @@ class PodsAPI {
4432
  * @deprecated 2.7.0 Use PodsAPI::handle_changed_fields
4433
  */
4434
  public function get_changed_fields( $pieces ) {
 
4435
 
4436
  return self::handle_changed_fields( $pieces['params']->pod, $pieces['params']->id, 'get' );
4437
-
4438
  }
4439
 
4440
  /**
4441
  * Save relationships
4442
  *
4443
- * @param int $id ID of item
4444
- * @param int|array $related_id ID or IDs to save
4445
- * @param array $pod Pod data
4446
- * @param array $field Field data
 
 
4447
  */
4448
  public function save_relationships( $id, $related_ids, $pod, $field ) {
 
 
 
4449
 
4450
  // Get current values
4451
- if ( 'pick' === $field['type'] && isset( PodsField_Pick::$related_data[ $field['id'] ] ) && isset( PodsField_Pick::$related_data[ $field['id'] ]['current_ids'] ) ) {
4452
- $current_ids = PodsField_Pick::$related_data[ $field['id'] ]['current_ids'];
4453
  } else {
4454
  $current_ids = $this->lookup_related_items( $field['id'], $pod['id'], $id, $field, $pod );
4455
  }
4456
 
4457
- if ( isset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] ) ) {
4458
- // Delete relationship from cache
4459
- unset( self::$related_item_cache[ $pod['id'] ][ $field['id'] ] );
4460
- }
 
 
4461
 
4462
  if ( ! is_array( $related_ids ) ) {
4463
  $related_ids = implode( ',', $related_ids );
@@ -4469,9 +5720,9 @@ class PodsAPI {
4469
 
4470
  $related_ids = array_unique( array_filter( $related_ids ) );
4471
 
4472
- $related_limit = (int) pods_var_raw( $field['type'] . '_limit', $field['options'], 0 );
4473
 
4474
- if ( 'single' === pods_var_raw( $field['type'] . '_format_type', $field['options'] ) ) {
4475
  $related_limit = 1;
4476
  }
4477
 
@@ -4481,10 +5732,16 @@ class PodsAPI {
4481
  }
4482
 
4483
  // Post Types, Media, Users, and Comments (meta-based)
4484
- if ( in_array( $pod['type'], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
 
 
 
 
 
 
4485
  $object_type = $pod['type'];
4486
 
4487
- if ( in_array( $object_type, array( 'post_type', 'media' ) ) ) {
4488
  $object_type = 'post';
4489
  } elseif ( 'taxonomy' === $object_type ) {
4490
  $object_type = 'term';
@@ -4513,18 +5770,18 @@ class PodsAPI {
4513
  $related_pod_id = 0;
4514
  $related_field_id = 0;
4515
 
4516
- if ( 'pick' === $field['type'] && isset( PodsField_Pick::$related_data[ $field['id'] ] ) && ! empty( PodsField_Pick::$related_data[ $field['id'] ]['related_field'] ) ) {
4517
- $related_pod_id = PodsField_Pick::$related_data[ $field['id'] ]['related_pod']['id'];
4518
- $related_field_id = PodsField_Pick::$related_data[ $field['id'] ]['related_field']['id'];
4519
  }
4520
 
4521
  // Relationships table
4522
- if ( ! pods_tableless() ) {
4523
  $related_weight = 0;
4524
 
4525
  foreach ( $related_ids as $related_id ) {
4526
  if ( in_array( $related_id, $current_ids ) ) {
4527
- pods_query( "
4528
  UPDATE `@wp_podsrel`
4529
  SET
4530
  `pod_id` = %d,
@@ -4539,7 +5796,7 @@ class PodsAPI {
4539
  AND `field_id` = %d
4540
  AND `item_id` = %d
4541
  AND `related_item_id` = %d
4542
- ", array(
4543
  $pod['id'],
4544
  $field['id'],
4545
  $id,
@@ -4554,7 +5811,7 @@ class PodsAPI {
4554
  $related_id,
4555
  ) );
4556
  } else {
4557
- pods_query( "
4558
  INSERT INTO `@wp_podsrel`
4559
  (
4560
  `pod_id`,
@@ -4566,36 +5823,165 @@ class PodsAPI {
4566
  `weight`
4567
  )
4568
  VALUES ( %d, %d, %d, %d, %d, %d, %d )
4569
- ", array(
4570
  $pod['id'],
4571
  $field['id'],
4572
  $id,
4573
  $related_pod_id,
4574
  $related_field_id,
4575
  $related_id,
4576
- $related_weight
4577
  ) );
4578
  }
4579
 
4580
- $related_weight ++;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4581
  }
4582
  }
 
 
4583
  }
4584
 
4585
  /**
4586
- * Duplicate a Pod
4587
  *
4588
- * $params['id'] int The Pod ID
4589
- * $params['name'] string The Pod name
4590
- * $params['new_name'] string The new Pod name
4591
  *
4592
- * @param array $params An associative array of parameters
4593
- * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
4594
  *
4595
- * @return int New Pod ID
4596
- * @since 2.3.0
 
 
4597
  */
4598
- public function duplicate_pod( $params, $strict = false ) {
4599
 
4600
  if ( ! is_object( $params ) && ! is_array( $params ) ) {
4601
  if ( is_numeric( $params ) ) {
@@ -4609,68 +5995,95 @@ class PodsAPI {
4609
  $params = (object) pods_sanitize( $params );
4610
  }
4611
 
4612
- $params->table_info = false;
 
 
 
 
4613
 
4614
- $pod = $this->load_pod( $params, $strict );
4615
 
4616
- if ( empty( $pod ) ) {
4617
  if ( false !== $strict ) {
4618
- return pods_error( __( 'Pod not found', 'pods' ), $this );
4619
  }
4620
 
4621
  return false;
4622
- } elseif ( in_array( $pod['type'], array( 'media', 'user', 'comment' ) ) ) {
4623
- if ( false !== $strict ) {
4624
- return pods_error( __( 'Pod not allowed to be duplicated', 'pods' ), $this );
4625
- }
4626
 
4627
- return false;
4628
- } elseif ( in_array( $pod['type'], array( 'post_type', 'taxonomy' ) ) && 0 < strlen( $pod['object'] ) ) {
4629
- $pod['object'] = '';
 
 
 
4630
  }
4631
 
4632
- unset( $pod['id'] );
4633
 
4634
  if ( isset( $params->new_name ) ) {
4635
- $pod['name'] = $params->new_name;
4636
  }
4637
 
4638
  $try = 1;
4639
 
4640
- $check_name = $pod['name'];
4641
- $new_label = $pod['label'];
4642
 
4643
- while ( $this->load_pod( array( 'name' => $check_name, 'table_info' => false ), false ) ) {
4644
  $try ++;
4645
 
4646
- $check_name = $pod['name'] . $try;
4647
- $new_label = $pod['label'] . $try;
4648
  }
4649
 
4650
- $pod['name'] = $check_name;
4651
- $pod['label'] = $new_label;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4652
 
4653
- foreach ( $pod['fields'] as $field => $field_data ) {
4654
- unset( $pod['fields'][ $field ]['id'] );
 
 
 
 
 
4655
  }
4656
 
4657
- return $this->save_pod( $pod );
4658
  }
4659
 
4660
  /**
4661
- * Duplicate a Field
4662
  *
4663
- * $params['pod_id'] int The Pod ID
4664
- * $params['pod'] string The Pod name
4665
- * $params['id'] int The Field ID
4666
- * $params['name'] string The Field name
4667
- * $params['new_name'] string The new Field name
4668
- *
4669
- * @param array $params An associative array of parameters
4670
- * @param bool $strict (optional) Makes sure a field exists, if it doesn't throws an error
4671
  *
4672
- * @return int New Field ID
4673
  * @since 2.3.10
 
 
 
 
 
4674
  */
4675
  public function duplicate_field( $params, $strict = false ) {
4676
 
@@ -4684,9 +6097,21 @@ class PodsAPI {
4684
 
4685
  $params = (object) pods_sanitize( $params );
4686
 
4687
- $params->table_info = false;
 
 
 
 
 
 
 
 
 
 
 
 
4688
 
4689
- $field = $this->load_field( $params, $strict );
4690
 
4691
  if ( empty( $field ) ) {
4692
  if ( false !== $strict ) {
@@ -4696,7 +6121,9 @@ class PodsAPI {
4696
  return false;
4697
  }
4698
 
4699
- unset( $field['id'] );
 
 
4700
 
4701
  if ( isset( $params->new_name ) ) {
4702
  $field['name'] = $params->new_name;
@@ -4708,9 +6135,8 @@ class PodsAPI {
4708
  $new_label = $field['label'];
4709
 
4710
  while ( $this->load_field( array(
4711
- 'pod_id' => $field['pod_id'],
4712
- 'name' => $check_name,
4713
- 'table_info' => false
4714
  ), false ) ) {
4715
  $try ++;
4716
 
@@ -4721,6 +6147,8 @@ class PodsAPI {
4721
  $field['name'] = $check_name;
4722
  $field['label'] = $new_label;
4723
 
 
 
4724
  return $this->save_field( $field, true, true );
4725
 
4726
  }
@@ -4744,11 +6172,10 @@ class PodsAPI {
4744
  $params = (object) pods_sanitize( $params );
4745
 
4746
  $load_pod_params = array(
4747
- 'name' => $params->pod,
4748
- 'table_info' => false,
4749
  );
4750
 
4751
- $pod = $this->load_pod( $load_pod_params );
4752
 
4753
  if ( false === $pod ) {
4754
  return pods_error( __( 'Pod not found', 'pods' ), $this );
@@ -4759,8 +6186,8 @@ class PodsAPI {
4759
  $params->pod = $pod->pod;
4760
  $params->pod_id = $pod->pod_id;
4761
 
4762
- $fields = (array) pods_var_raw( 'fields', $pod->pod_data, array(), null, true );
4763
- $object_fields = (array) pods_var_raw( 'object_fields', $pod->pod_data, array(), null, true );
4764
 
4765
  if ( ! empty( $object_fields ) ) {
4766
  $fields = array_merge( $object_fields, $fields );
@@ -4777,7 +6204,7 @@ class PodsAPI {
4777
  $pod->pod_data['field_slug'],
4778
  );
4779
 
4780
- if ( in_array( $pod->pod_data['type'], array( 'post_type', 'media' ) ) ) {
4781
  $ignore_fields = array(
4782
  'ID',
4783
  'post_name',
@@ -4921,7 +6348,7 @@ class PodsAPI {
4921
  $tableless_field_types = PodsForm::tableless_field_types();
4922
  $simple_tableless_objects = PodsForm::simple_tableless_objects();
4923
 
4924
- $object_fields = (array) pods_v( 'object_fields', $pod->pod_data, array(), true );
4925
 
4926
  $export_fields = array();
4927
 
@@ -4943,7 +6370,7 @@ class PodsAPI {
4943
 
4944
  // If in rest, check if this pod can be exposed
4945
  if ( 'rest' === $context ) {
4946
- $read_all = (int) pods_v( 'read_all', $pod->pod_data['options'], 0 );
4947
 
4948
  if ( 1 === $read_all ) {
4949
  $show_in_rest = true;
@@ -4951,7 +6378,9 @@ class PodsAPI {
4951
  }
4952
 
4953
  foreach ( $fields as $k => $field ) {
4954
- if ( ! is_array( $field ) ) {
 
 
4955
  $field = array(
4956
  'id' => 0,
4957
  'name' => $field
@@ -4975,11 +6404,13 @@ class PodsAPI {
4975
  }
4976
  }
4977
 
4978
- $field = $pod->fields[ $field['name'] ];
4979
  $field['lookup_name'] = $field['name'];
4980
 
4981
- if ( in_array( $field['type'], $tableless_field_types, true ) && ! in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) ) {
4982
- if ( 'pick' === $field['type'] ) {
 
 
4983
  if ( empty( $field['table_info'] ) ) {
4984
  $field['table_info'] = $this->get_table_info( pods_v( 'pick_object', $field ), pods_v( 'pick_val', $field ), null, null, $field );
4985
  }
@@ -4987,7 +6418,7 @@ class PodsAPI {
4987
  if ( ! empty( $field['table_info'] ) && 'table' !== $field['table_info']['object_type'] ) {
4988
  $field['lookup_name'] .= '.' . $field['table_info']['field_id'];
4989
  }
4990
- } elseif ( in_array( $field['type'], PodsForm::file_field_types() ) ) {
4991
  $field['lookup_name'] .= '.guid';
4992
  }
4993
  }
@@ -4998,7 +6429,7 @@ class PodsAPI {
4998
  $field['lookup_name'] = $field['name'];
4999
 
5000
  $export_fields[ $field['name'] ] = $field;
5001
- } elseif ( $field['name'] == $pod->pod_data['field_id'] ) {
5002
  $field['type'] = 'number';
5003
  $field['lookup_name'] = $field['name'];
5004
 
@@ -5010,9 +6441,9 @@ class PodsAPI {
5010
 
5011
  foreach ( $export_fields as $field ) {
5012
  // Return IDs (or guid for files) if only one level deep
5013
- if ( 1 == $depth ) {
5014
  $data[ $field['name'] ] = $pod->field( array( 'name' => $field['lookup_name'], 'output' => 'arrays' ) );
5015
- } elseif ( ( - 1 == $depth || $current_depth < $depth ) && 'pick' === $field['type'] && ! in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) ) {
5016
  // Recurse depth levels for pick fields if $depth allows
5017
  $related_data = array();
5018
 
@@ -5021,15 +6452,15 @@ class PodsAPI {
5021
  if ( ! empty( $related_ids ) ) {
5022
  $related_ids = (array) $related_ids;
5023
 
5024
- $pick_object = pods_var_raw( 'pick_object', $field );
5025
 
5026
- $related_pod = pods( pods_var_raw( 'pick_val', $field ), null, false );
5027
 
5028
  // If this isn't a Pod, return data exactly as Pods does normally
5029
- if ( empty( $related_pod ) || empty( $related_pod->pod_data ) || ( 'pod' !== $pick_object && $pick_object !== pods_v( 'type', $related_pod->pod_data, null ) ) || $related_pod->pod == $pod->pod ) {
5030
  $related_data = $pod->field( array( 'name' => $field['name'], 'output' => 'arrays' ) );
5031
  } else {
5032
- $related_object_fields = (array) pods_var_raw( 'object_fields', $related_pod->pod_data, array(), null, true );
5033
 
5034
  $related_fields = array_merge( $related_pod->fields, $related_object_fields );
5035
 
@@ -5102,16 +6533,7 @@ class PodsAPI {
5102
 
5103
  $params = (object) pods_sanitize( $params );
5104
 
5105
- // @deprecated 2.0.0
5106
- if ( isset( $params->datatype ) ) {
5107
- pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
5108
-
5109
- $params->pod = $params->datatype;
5110
-
5111
- unset( $params->datatype );
5112
- }
5113
-
5114
- if ( null === pods_var_raw( 'pod', $params, null, null, true ) ) {
5115
  return pods_error( __( '$params->pod is required', 'pods' ), $this );
5116
  }
5117
 
@@ -5119,17 +6541,17 @@ class PodsAPI {
5119
  $params->order = explode( ',', $params->order );
5120
  }
5121
 
5122
- $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => true ) );
5123
-
5124
- $params->name = $pod['name'];
5125
 
5126
  if ( false === $pod ) {
5127
  return pods_error( __( 'Pod is required', 'pods' ), $this );
5128
  }
5129
 
 
 
5130
  foreach ( $params->order as $order => $id ) {
5131
  if ( isset( $pod['fields'][ $params->field ] ) || isset( $pod['object_fields'][ $params->field ] ) ) {
5132
- if ( 'table' === $pod['storage'] && ( ! pods_tableless() ) ) {
5133
  if ( isset( $pod['fields'][ $params->field ] ) ) {
5134
  pods_query( "UPDATE `@wp_pods_{$params->name}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `id` = " . pods_absint( $id ) . " LIMIT 1" );
5135
  } else {
@@ -5167,20 +6589,21 @@ class PodsAPI {
5167
  * @since 1.9.0
5168
  */
5169
  public function reset_pod( $params, $pod = false ) {
5170
-
5171
- $params = (object) pods_sanitize( $params );
5172
-
5173
- $params->table_info = true;
5174
-
5175
  if ( empty( $pod ) ) {
5176
- $pod = $this->load_pod( $params );
5177
  }
5178
 
5179
  if ( false === $pod ) {
5180
  return pods_error( __( 'Pod not found', 'pods' ), $this );
5181
  }
5182
 
5183
- $params->id = $pod['id'];
 
 
 
 
 
 
5184
  $params->name = $pod['name'];
5185
 
5186
  if ( ! pods_tableless() ) {
@@ -5195,14 +6618,23 @@ class PodsAPI {
5195
  }
5196
  }
5197
 
 
 
 
5198
  pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
5199
  }
5200
 
5201
  // @todo Delete relationships from tableless relationships
5202
 
5203
- // Delete all posts/revisions from this post type
5204
- if ( in_array( $pod['type'], array( 'post_type', 'media' ) ) ) {
5205
- $type = pods_var( 'object', $pod, $pod['name'], null, true );
 
 
 
 
 
 
5206
 
5207
  $sql = "
5208
  DELETE `t`, `r`, `m`
@@ -5216,7 +6648,7 @@ class PodsAPI {
5216
 
5217
  pods_query( $sql, false );
5218
  } elseif ( 'taxonomy' === $pod['type'] ) {
5219
- // Delete all terms from this taxonomy
5220
  if ( function_exists( 'get_term_meta' ) ) {
5221
  $sql = "
5222
  DELETE `t`, `m`, `tt`, `tr`
@@ -5251,7 +6683,13 @@ class PodsAPI {
5251
  pods_query( $sql, false );
5252
  } elseif ( 'comment' === $pod['type'] ) {
5253
  // Delete all comments
5254
- $type = pods_var( 'object', $pod, $pod['name'], null, true );
 
 
 
 
 
 
5255
 
5256
  $sql = "
5257
  DELETE `t`, `m`
@@ -5275,9 +6713,9 @@ class PodsAPI {
5275
  * $params['id'] int The Pod ID
5276
  * $params['name'] string The Pod name
5277
  *
5278
- * @param array $params An associative array of parameters
5279
- * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
5280
- * @param bool $delete_all (optional) Whether to delete all content from a WP object
5281
  *
5282
  * @uses PodsAPI::load_pod
5283
  * @uses wp_delete_post
@@ -5287,31 +6725,7 @@ class PodsAPI {
5287
  * @since 1.7.9
5288
  */
5289
  public function delete_pod( $params, $strict = false, $delete_all = false ) {
5290
-
5291
- /**
5292
- * @var $wpdb wpdb
5293
- */
5294
- global $wpdb;
5295
-
5296
- if ( ! is_object( $params ) && ! is_array( $params ) ) {
5297
- if ( is_numeric( $params ) ) {
5298
- $params = array( 'id' => $params );
5299
- } else {
5300
- $params = array( 'name' => $params );
5301
- }
5302
-
5303
- $params = (object) pods_sanitize( $params );
5304
- } else {
5305
- $params = (object) pods_sanitize( $params );
5306
- }
5307
-
5308
- if ( ! isset( $params->delete_all ) ) {
5309
- $params->delete_all = $delete_all;
5310
- }
5311
-
5312
- $params->table_info = false;
5313
-
5314
- $pod = $this->load_pod( $params, $strict );
5315
 
5316
  if ( empty( $pod ) ) {
5317
  if ( false !== $strict ) {
@@ -5321,331 +6735,153 @@ class PodsAPI {
5321
  return false;
5322
  }
5323
 
5324
- $params->id = (int) $pod['id'];
5325
- $params->name = $pod['name'];
5326
-
5327
- // Reset content
5328
- if ( true === $params->delete_all ) {
5329
- $this->reset_pod( $params, $pod );
5330
- }
5331
-
5332
- foreach ( $pod['fields'] as $field ) {
5333
- $field['pod'] = $pod;
5334
-
5335
- $this->delete_field( $field, false );
5336
- }
5337
-
5338
- // Only delete the post once the fields are taken care of, it's not required anymore
5339
- $success = wp_delete_post( $params->id );
5340
-
5341
- if ( ! $success ) {
5342
- return pods_error( __( 'Pod unable to be deleted', 'pods' ), $this );
5343
- }
5344
-
5345
- if ( ! pods_tableless() ) {
5346
- if ( 'table' === $pod['storage'] ) {
5347
- try {
5348
- pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`", false );
5349
- } catch ( Exception $e ) {
5350
- // Allow pod to be deleted if the table doesn't exist
5351
- if ( false === strpos( $e->getMessage(), 'Unknown table' ) ) {
5352
- return pods_error( $e->getMessage(), $this );
5353
- }
5354
- }
5355
- }
5356
-
5357
- pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
5358
- }
5359
-
5360
- // @todo Delete relationships from tableless relationships
5361
-
5362
- // Delete any relationship references
5363
- $sql = "
5364
- DELETE `pm`
5365
- FROM `{$wpdb->postmeta}` AS `pm`
5366
- LEFT JOIN `{$wpdb->posts}` AS `p`
5367
- ON `p`.`post_type` = '_pods_field'
5368
- AND `p`.`ID` = `pm`.`post_id`
5369
- LEFT JOIN `{$wpdb->postmeta}` AS `pm2`
5370
- ON `pm2`.`meta_key` = 'pick_object'
5371
- AND `pm2`.`meta_value` = 'pod'
5372
- AND `pm2`.`post_id` = `pm`.`post_id`
5373
- WHERE
5374
- `p`.`ID` IS NOT NULL
5375
- AND `pm2`.`meta_id` IS NOT NULL
5376
- AND `pm`.`meta_key` = 'pick_val'
5377
- AND `pm`.`meta_value` = '{$params->name}'
5378
- ";
5379
-
5380
- pods_query( $sql );
5381
-
5382
- $this->cache_flush_pods( $pod );
5383
-
5384
- return true;
5385
- }
5386
-
5387
- /**
5388
- * Drop a field within a Pod
5389
- *
5390
- * $params['id'] int The field ID
5391
- * $params['name'] int The field name
5392
- * $params['pod'] string The Pod name
5393
- * $params['pod_id'] string The Pod name
5394
- *
5395
- * @param array $params An associative array of parameters
5396
- * @param bool $table_operation Whether or not to handle table operations
5397
- *
5398
- * @uses PodsAPI::load_field
5399
- * @uses wp_delete_post
5400
- * @uses pods_query
5401
- *
5402
- * @return bool
5403
- * @since 1.7.9
5404
- */
5405
- public function delete_field( $params, $table_operation = true ) {
5406
-
5407
  /**
5408
  * @var $wpdb wpdb
5409
  */
5410
  global $wpdb;
5411
 
5412
- $tableless_field_types = PodsForm::tableless_field_types();
5413
- $simple_tableless_objects = PodsForm::simple_tableless_objects();
5414
-
5415
- $params = (object) pods_sanitize( $params );
5416
-
5417
- if ( ! isset( $params->pod ) ) {
5418
- $params->pod = '';
5419
- }
5420
-
5421
- if ( ! isset( $params->pod_id ) ) {
5422
- $params->pod_id = 0;
5423
- }
5424
-
5425
- $pod = $params->pod;
5426
-
5427
- $save_pod = false;
5428
-
5429
- if ( ! is_array( $pod ) ) {
5430
- $pod = $this->load_pod( array( 'name' => $pod, 'id' => $params->pod_id, 'table_info' => false ) );
5431
  } else {
5432
- $save_pod = true;
5433
- }
5434
-
5435
- if ( empty( $pod ) ) {
5436
- return pods_error( __( 'Pod not found', 'pods' ), $this );
5437
- }
5438
-
5439
- $params->pod_id = $pod['id'];
5440
- $params->pod = $pod['name'];
5441
-
5442
- if ( ! isset( $params->name ) ) {
5443
- $params->name = '';
5444
- }
5445
-
5446
- if ( ! isset( $params->id ) ) {
5447
- $params->id = 0;
5448
- }
5449
-
5450
- $field = $this->load_field( array(
5451
- 'name' => $params->name,
5452
- 'id' => $params->id,
5453
- 'pod' => $params->pod,
5454
- 'pod_id' => $params->pod_id
5455
- ) );
5456
-
5457
- if ( false === $field ) {
5458
- return pods_error( __( 'Field not found', 'pods' ), $this );
5459
  }
5460
 
5461
- $params->id = $field['id'];
5462
- $params->name = $field['name'];
5463
 
5464
- $simple = ( 'pick' === $field['type'] && in_array( pods_var( 'pick_object', $field ), $simple_tableless_objects ) );
5465
- $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field, $pod, $params );
5466
 
5467
- if ( $table_operation && 'table' === $pod['storage'] && ( ! in_array( $field['type'], $tableless_field_types ) || $simple ) ) {
5468
- pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$params->name}`", false );
5469
  }
5470
 
5471
- $success = wp_delete_post( $params->id );
5472
-
5473
- if ( ! $success ) {
5474
- return pods_error( __( 'Field unable to be deleted', 'pods' ), $this );
5475
  }
5476
 
5477
- $wpdb->query( $wpdb->prepare( "DELETE pm FROM {$wpdb->postmeta} AS pm
5478
- LEFT JOIN {$wpdb->posts} AS p
5479
- ON p.post_type = '_pods_field' AND p.ID = pm.post_id
5480
- WHERE p.ID IS NOT NULL AND pm.meta_key = 'sister_id' AND pm.meta_value = %d", $params->id ) );
5481
 
5482
- if ( ( ! pods_tableless() ) && $table_operation ) {
5483
- 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 );
 
5484
  }
5485
 
5486
- // @todo Delete tableless relationship meta
 
 
 
 
 
5487
 
5488
- if ( true === $save_pod ) {
5489
- $this->cache_flush_pods( $pod );
5490
  }
5491
 
5492
- return true;
5493
- }
5494
 
5495
- /**
5496
- * Drop a Pod Object
5497
- *
5498
- * $params['id'] int The object ID
5499
- * $params['name'] string The object name
5500
- * $params['type'] string The object type
5501
- *
5502
- * @param array|object $params An associative array of parameters
5503
- *
5504
- * @uses wp_delete_post
5505
- *
5506
- * @return bool
5507
- * @since 2.0.0
5508
- */
5509
- public function delete_object( $params ) {
5510
 
5511
- $params = (object) $params;
5512
- $object = $this->load_object( $params );
5513
 
5514
- if ( empty( $object ) ) {
5515
- return pods_error( sprintf( __( "%s Object not found", 'pods' ), ucwords( $params->type ) ), $this );
5516
- }
5517
 
5518
- $success = wp_delete_post( $params->id );
 
 
5519
 
5520
  if ( ! $success ) {
5521
- return pods_error( sprintf( __( "%s Object not deleted", 'pods' ), ucwords( $params->type ) ), $this );
5522
  }
5523
 
5524
- pods_transient_clear( 'pods_objects_' . $params->type );
5525
-
5526
- return true;
5527
- }
 
 
 
 
 
 
 
 
5528
 
5529
- /**
5530
- * @see PodsAPI::delete_object
5531
- *
5532
- * Drop a Pod Template
5533
- *
5534
- * $params['id'] int The template ID
5535
- * $params['name'] string The template name
5536
- *
5537
- * @param array $params An associative array of parameters
5538
- *
5539
- * @return bool
5540
- * @since 1.7.9
5541
- */
5542
- public function delete_template( $params ) {
5543
 
5544
- $params = (object) $params;
5545
- $params->type = 'template';
5546
 
5547
- return $this->delete_object( $params );
5548
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5549
 
5550
- /**
5551
- * @see PodsAPI::delete_object
5552
- *
5553
- * Drop a Pod Page
5554
- *
5555
- * $params['id'] int The page ID
5556
- * $params['uri'] string The page URI
5557
- *
5558
- * @param array $params An associative array of parameters
5559
- *
5560
- * @return bool
5561
- * @since 1.7.9
5562
- */
5563
- public function delete_page( $params ) {
5564
 
5565
- $params = (object) $params;
5566
- if ( isset( $params->uri ) ) {
5567
- $params->name = $params->uri;
5568
- unset( $params->uri );
5569
- }
5570
- if ( isset( $params->name ) ) {
5571
- $params->name = trim( $params->name, '/' );
5572
- }
5573
- $params->type = 'page';
5574
 
5575
- return $this->delete_object( $params );
5576
  }
5577
 
5578
  /**
5579
- * @see PodsAPI::delete_object
5580
- *
5581
- * Drop a Pod Helper
5582
- *
5583
- * $params['id'] int The helper ID
5584
- * $params['name'] string The helper name
5585
- *
5586
- * @param array $params An associative array of parameters
5587
  *
5588
- * @return bool
5589
- * @since 1.7.9
5590
- */
5591
- public function delete_helper( $params ) {
5592
-
5593
- $params = (object) $params;
5594
- $params->type = 'helper';
5595
-
5596
- return $this->delete_object( $params );
5597
- }
5598
-
5599
- /**
5600
- * Drop a single pod item
5601
  *
5602
- * $params['id'] int (optional) The item's ID from the wp_pod_* table (used with datatype parameter)
5603
- * $params['pod'] string (optional) The Pod name (used with id parameter)
5604
- * $params['pod_id'] int (optional) The Pod ID (used with id parameter)
5605
- * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
5606
  *
5607
- * @param array $params An associative array of parameters
5608
- * @param bool $wp Whether to run WP object delete action
 
5609
  *
5610
  * @return bool
5611
  * @since 1.7.9
5612
  */
5613
- public function delete_pod_item( $params, $wp = true ) {
5614
-
5615
- $params = (object) pods_sanitize( $params );
5616
-
5617
- // @deprecated 2.0.0
5618
- if ( isset( $params->datatype_id ) || isset( $params->datatype ) || isset( $params->tbl_row_id ) ) {
5619
- if ( isset( $params->tbl_row_id ) ) {
5620
- pods_deprecated( __( '$params->id instead of $params->tbl_row_id', 'pods' ), '2.0' );
5621
- $params->id = $params->tbl_row_id;
5622
- unset( $params->tbl_row_id );
5623
- }
5624
 
5625
- if ( isset( $params->pod_id ) ) {
5626
- pods_deprecated( __( '$params->id instead of $params->pod_id', 'pods' ), '2.0' );
5627
- $params->id = $params->pod_id;
5628
- unset( $params->pod_id );
5629
- }
5630
 
5631
- if ( isset( $params->dataype_id ) ) {
5632
- pods_deprecated( __( '$params->pod_id instead of $params->datatype_id', 'pods' ), '2.0' );
5633
- $params->pod_id = $params->dataype_id;
5634
- unset( $params->dataype_id );
5635
- }
5636
 
5637
- if ( isset( $params->datatype ) ) {
5638
- pods_deprecated( __( '$params->pod instead of $params->datatype', 'pods' ), '2.0' );
5639
- $params->pod = $params->datatype;
5640
- unset( $params->datatype );
5641
- }
5642
- }
5643
 
5644
- if ( ! isset( $params->id ) ) {
5645
- return pods_error( __( 'Pod Item not found', 'pods' ), $this );
 
 
 
 
5646
  }
5647
 
5648
- $params->id = pods_absint( $params->id );
5649
 
5650
  if ( ! isset( $params->pod ) ) {
5651
  $params->pod = '';
@@ -5655,1056 +6891,927 @@ class PodsAPI {
5655
  $params->pod_id = 0;
5656
  }
5657
 
5658
- $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id, 'table_info' => false ) );
5659
-
5660
- if ( false === $pod ) {
5661
- return pods_error( __( 'Pod not found', 'pods' ), $this );
5662
- }
5663
-
5664
- $params->pod_id = $pod['id'];
5665
- $params->pod = $pod['name'];
5666
-
5667
- // Allow Helpers to bypass subsequent helpers in recursive delete_pod_item calls
5668
- $bypass_helpers = false;
5669
-
5670
- if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers ) {
5671
- $bypass_helpers = true;
5672
  }
5673
 
5674
- $pre_delete_helpers = array();
5675
- $post_delete_helpers = array();
5676
-
5677
- if ( false === $bypass_helpers ) {
5678
- // Plugin hook
5679
- $this->do_hook( 'pre_delete_pod_item', $params, $pod );
5680
- $this->do_hook( "pre_delete_pod_item_{$params->pod}", $params, $pod );
5681
-
5682
- // Call any pre-save helpers (if not bypassed)
5683
- if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) {
5684
- if ( ! empty( $pod['options'] ) && is_array( $pod['options'] ) ) {
5685
- $helpers = array( 'pre_delete_helpers', 'post_delete_helpers' );
5686
 
5687
- foreach ( $helpers as $helper ) {
5688
- if ( isset( $pod['options'][ $helper ] ) && ! empty( $pod['options'][ $helper ] ) ) {
5689
- ${$helper} = explode( ',', $pod['options'][ $helper ] );
5690
- }
5691
- }
5692
- }
5693
 
5694
- if ( ! empty( $pre_delete_helpers ) ) {
5695
- pods_deprecated( sprintf( __( 'Pre-delete helpers are deprecated, use the action pods_pre_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
 
 
 
 
 
 
 
5696
 
5697
- foreach ( $pre_delete_helpers as $helper ) {
5698
- $helper = $this->load_helper( array( 'name' => $helper ) );
5699
 
5700
- if ( false !== $helper ) {
5701
- eval( '?>' . $helper['code'] );
5702
- }
5703
- }
5704
- }
5705
  }
 
 
5706
  }
5707
 
5708
- // Delete object from relationship fields
5709
- $this->delete_object_from_relationships( $params->id, $pod );
5710
-
5711
- if ( 'table' === $pod['storage'] ) {
5712
- pods_query( "DELETE FROM `@wp_pods_{$params->pod}` WHERE `id` = {$params->id} LIMIT 1" );
5713
  }
5714
 
5715
- if ( $wp ) {
5716
- if ( 'taxonomy' === $pod['type'] ) {
5717
- $taxonomy = $pod['name'];
5718
-
5719
- if ( ! empty( $pod['object'] ) ) {
5720
- $taxonomy = $pod['object'];
5721
- }
5722
-
5723
- wp_delete_term( $params->id, $taxonomy );
5724
- } elseif ( ! in_array( $pod['type'], array( 'pod', 'table', '', 'taxonomy' ) ) ) {
5725
- $this->delete_wp_object( $pod['type'], $params->id );
5726
- }
5727
  }
5728
 
5729
- if ( false === $bypass_helpers ) {
5730
- // Plugin hook
5731
- $this->do_hook( 'post_delete_pod_item', $params, $pod );
5732
- $this->do_hook( "post_delete_pod_item_{$params->pod}", $params, $pod );
5733
-
5734
- // Call any post-save helpers (if not bypassed)
5735
- if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) {
5736
- if ( ! empty( $post_delete_helpers ) ) {
5737
- pods_deprecated( sprintf( __( 'Post-delete helpers are deprecated, use the action pods_post_delete_pod_item_%s instead', 'pods' ), $params->pod ), '2.0' );
5738
-
5739
- foreach ( $post_delete_helpers as $helper ) {
5740
- $helper = $this->load_helper( array( 'name' => $helper ) );
5741
 
5742
- if ( false !== $helper ) {
5743
- eval( '?>' . $helper['code'] );
5744
- }
5745
- }
5746
- }
5747
- }
5748
  }
5749
 
5750
- pods_cache_clear( $params->id, 'pods_items_' . $params->pod );
 
 
5751
 
5752
- return true;
5753
- }
5754
 
5755
- /**
5756
- * Delete an object from tableless fields
5757
- *
5758
- * @param int $id
5759
- * @param string $type
5760
- * @param string $name
5761
- *
5762
- * @return bool
5763
- *
5764
- * @since 2.3.0
5765
- */
5766
- public function delete_object_from_relationships( $id, $object, $name = null ) {
5767
 
5768
- /**
5769
- * @var $pods_init \PodsInit
5770
- * @todo Use pods_init() function?
5771
- */
5772
- global $pods_init;
5773
 
5774
- $pod = false;
5775
 
5776
- // Run any bidirectional delete operations
5777
- if ( is_array( $object ) ) {
5778
- $pod = $object;
5779
- } elseif ( is_object( $pods_init ) ) {
5780
- $pod = PodsInit::$meta->get_object( $object, $name );
5781
  }
 
 
5782
 
5783
- if ( ! empty( $pod ) ) {
5784
- $object = $pod['type'];
5785
- $name = $pod['name'];
5786
 
5787
- foreach ( $pod['fields'] as $field ) {
5788
- PodsForm::delete( $field['type'], $id, $field['name'], array_merge( $field, $field['options'] ), $pod );
 
5789
  }
5790
  }
5791
 
5792
- // Lookup related fields (non-bidirectional)
5793
- $params = array(
5794
- 'where' => array(
5795
- array(
5796
- 'key' => 'type',
5797
- 'value' => 'pick'
5798
- ),
5799
- array(
5800
- 'key' => 'pick_object',
5801
- 'value' => $object
5802
- )
5803
- )
5804
- );
5805
 
5806
- if ( ! empty( $name ) && $name !== $object ) {
5807
- $params['where'][] = array(
5808
- 'key' => 'pick_val',
5809
- 'value' => $name
5810
- );
5811
  }
5812
 
5813
- $fields = $this->load_fields( $params, false );
5814
-
5815
- if ( ! empty( $pod ) && 'media' === $pod['type'] ) {
5816
- $params['where'] = array(
5817
- array(
5818
- 'key' => 'type',
5819
- 'value' => 'file'
5820
- )
5821
- );
5822
 
5823
- $fields = array_merge( $fields, $this->load_fields( $params, false ) );
5824
- }
5825
 
5826
- if ( is_array( $fields ) && ! empty( $fields ) ) {
5827
- foreach ( $fields as $related_field ) {
5828
- $related_pod = $this->load_pod( array( 'id' => $related_field['pod_id'], 'fields' => false ), false );
5829
 
5830
- if ( empty( $related_pod ) ) {
5831
- continue;
5832
- }
5833
 
5834
- $related_from = $this->lookup_related_items_from( $related_field['id'], $related_pod['id'], $id, $related_field, $related_pod );
 
 
 
5835
 
5836
- $this->delete_relationships( $related_from, $id, $related_pod, $related_field );
5837
- }
5838
  }
5839
 
5840
- if ( ! empty( $pod ) && ! pods_tableless() ) {
5841
- pods_query( "
5842
- DELETE FROM `@wp_podsrel`
5843
- WHERE
5844
- (
5845
- `pod_id` = %d
5846
- AND `item_id` = %d
5847
- )
5848
- OR (
5849
- `related_pod_id` = %d
5850
- AND `related_item_id` = %d
5851
- )
5852
- ", array(
5853
- $pod['id'],
5854
- $id,
5855
 
5856
- $pod['id'],
5857
- $id
5858
- ) );
5859
  }
5860
 
 
 
5861
  return true;
5862
  }
5863
 
5864
  /**
5865
- * Delete relationships
5866
  *
5867
- * @param int|array $related_id IDs for items to save
5868
- * @param int|array $id ID or IDs to remove
5869
- * @param array $related_pod Pod data
5870
- * @param array $related_field Field data
5871
  *
5872
- * @return void
5873
  *
5874
- * @since 2.3.0
 
 
 
 
5875
  */
5876
- public function delete_relationships( $related_id, $id, $related_pod, $related_field ) {
 
 
 
 
5877
 
5878
- if ( is_array( $related_id ) ) {
5879
- foreach ( $related_id as $rid ) {
5880
- $this->delete_relationships( $rid, $id, $related_pod, $related_field );
 
 
5881
  }
5882
 
5883
- return;
 
 
5884
  }
5885
 
5886
- if ( is_array( $id ) ) {
5887
- foreach ( $id as $rid ) {
5888
- $this->delete_relationships( $related_id, $rid, $related_pod, $related_field );
5889
- }
5890
-
5891
- return;
5892
  }
5893
 
5894
- $id = (int) $id;
5895
-
5896
- if ( empty( $id ) ) {
5897
- return;
5898
- }
5899
 
5900
- $related_ids = $this->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod );
 
 
 
5901
 
5902
- if ( empty( $related_ids ) ) {
5903
- return;
5904
- } elseif ( ! in_array( $id, $related_ids ) ) {
5905
- return;
5906
  }
5907
 
5908
- if ( isset( self::$related_item_cache[ $related_pod['id'] ][ $related_field['id'] ] ) ) {
5909
- // Delete relationship from cache
5910
- unset( self::$related_item_cache[ $related_pod['id'] ][ $related_field['id'] ] );
5911
- }
5912
 
5913
- // @codingStandardsIgnoreLine
5914
- unset( $related_ids[ array_search( $id, $related_ids ) ] );
5915
 
5916
- $no_conflict = pods_no_conflict_check( $related_pod['type'] );
 
 
 
 
 
 
 
5917
 
5918
- if ( ! $no_conflict ) {
5919
- pods_no_conflict_on( $related_pod['type'] );
5920
  }
5921
 
5922
- // Post Types, Media, Users, and Comments (meta-based)
5923
- if ( in_array( $related_pod['type'], array( 'post_type', 'media', 'taxonomy', 'user', 'comment' ) ) ) {
5924
- $object_type = $related_pod['type'];
5925
 
5926
- if ( in_array( $object_type, array( 'post_type', 'media' ) ) ) {
5927
- $object_type = 'post';
5928
- } elseif ( 'taxonomy' === $object_type ) {
5929
- $object_type = 'term';
5930
- }
5931
 
5932
- delete_metadata( $object_type, $related_id, $related_field['name'] );
5933
 
5934
- if ( ! empty( $related_ids ) ) {
5935
- update_metadata( $object_type, $related_id, '_pods_' . $related_field['name'], $related_ids );
5936
 
5937
- foreach ( $related_ids as $rel_id ) {
5938
- add_metadata( $object_type, $related_id, $related_field['name'], $rel_id );
5939
- }
5940
- } else {
5941
- delete_metadata( $object_type, $related_id, '_pods_' . $related_field['name'] );
5942
- }
5943
- } elseif ( 'settings' === $related_pod['type'] ) {
5944
- // Custom Settings Pages (options-based)
5945
- if ( ! empty( $related_ids ) ) {
5946
- update_option( $related_pod['name'] . '_' . $related_field['name'], $related_ids );
5947
- } else {
5948
- delete_option( $related_pod['name'] . '_' . $related_field['name'] );
5949
- }
5950
  }
5951
 
5952
- // Relationships table
5953
- if ( ! pods_tableless() ) {
5954
- pods_query( "
5955
- DELETE FROM `@wp_podsrel`
5956
- WHERE
5957
- (
5958
- `pod_id` = %d
5959
- AND `field_id` = %d
5960
- AND `item_id` = %d
5961
- AND `related_item_id` = %d
5962
- )
5963
- OR (
5964
- `related_pod_id` = %d
5965
- AND `related_field_id` = %d
5966
- AND `related_item_id` = %d
5967
- AND `item_id` = %d
5968
- )
5969
- ", array(
5970
- $related_pod['id'],
5971
- $related_field['id'],
5972
- $related_id,
5973
- $id,
5974
-
5975
- $related_pod['id'],
5976
- $related_field['id'],
5977
- $related_id,
5978
- $id
5979
- ) );
5980
  }
5981
 
5982
- if ( ! $no_conflict ) {
5983
- pods_no_conflict_off( $related_pod['type'] );
5984
- }
5985
  }
5986
 
5987
  /**
5988
- * Check if a Pod exists
5989
  *
5990
- * $params['id'] int Pod ID
5991
- * $params['name'] string Pod name
 
5992
  *
5993
- * @param array $params An associative array of parameters
5994
  *
5995
- * @return bool True if exists
5996
  *
5997
- * @since 1.12
 
5998
  */
5999
- public function pod_exists( $params, $type = null ) {
 
6000
 
6001
- if ( is_string( $params ) ) {
6002
- $params = array( 'name' => $params );
6003
  }
6004
 
6005
- $params = (object) pods_sanitize( $params );
6006
 
6007
- if ( ! empty( $params->id ) || ! empty( $params->name ) ) {
6008
- if ( ! isset( $params->name ) ) {
6009
- $dummy = (int) $params->id;
6010
- $pod = get_post( $dummy );
6011
- } else {
6012
- $pod = get_posts( array(
6013
- 'name' => $params->name,
6014
- 'post_type' => '_pods_pod',
6015
- 'posts_per_page' => 1
6016
- ) );
6017
 
6018
- if ( is_array( $pod ) && ! empty( $pod[0] ) ) {
6019
- $pod = $pod[0];
6020
- }
6021
- }
6022
 
6023
- if ( ! empty( $pod ) && ( empty( $type ) || $type == get_post_meta( $pod->ID, 'type', true ) ) ) {
6024
- return true;
6025
- }
 
 
 
 
 
6026
  }
6027
 
6028
- return false;
 
 
6029
  }
6030
 
6031
  /**
6032
- * Get number of pods for a specific pod type
6033
  *
6034
- * @param string $type Type to get count
6035
  *
6036
- * @return int Total number of pods for a type
 
6037
  *
6038
- * @since 2.6.6
 
 
 
6039
  */
6040
- public function get_pod_type_count( $type ) {
 
 
6041
 
6042
- $args = array(
6043
- 'post_type' => '_pods_pod',
6044
- 'posts_per_page' => - 1,
6045
- 'nopaging' => true,
6046
- 'fields' => 'ids',
6047
- 'meta_query' => array(
6048
- array(
6049
- 'key' => 'type',
6050
- 'value' => $type,
6051
- ),
6052
- ),
6053
- );
6054
 
6055
- $posts = get_posts( $args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6056
 
6057
- $total = count( $posts );
 
 
 
 
 
 
 
6058
 
6059
- return $total;
 
6060
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6061
  }
6062
 
6063
  /**
6064
- * Load a Pod and all of its fields
6065
  *
6066
- * $params['id'] int The Pod ID
6067
- * $params['name'] string The Pod name
6068
- * $params['fields'] bool Whether to load fields (default is true)
6069
- * $params['bypass_cache'] boolean Bypass the cache when getting data
6070
  *
6071
- * @param array|object $params An associative array of parameters or pod name as a string
6072
- * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work
6073
  *
6074
- * @return array|bool|mixed|void
6075
  * @since 1.7.9
6076
  */
6077
- public function load_pod( $params, $strict = true ) {
6078
 
6079
- /**
6080
- * @var $sitepress SitePress
6081
- * @var $wpdb wpdb
6082
- */
6083
- global $wpdb;
6084
 
6085
- $current_language = false;
6086
- $load_fields = true;
6087
- $bypass_cache = false;
6088
 
6089
- // Get current language data
6090
- $lang_data = pods_i18n()->get_current_language_data();
6091
 
6092
- if ( $lang_data ) {
6093
- if ( ! empty( $lang_data['language'] ) ) {
6094
- $current_language = $lang_data['language'];
6095
- }
6096
  }
6097
 
6098
- if ( ! is_array( $params ) && ! is_object( $params ) ) {
6099
- $params = array( 'name' => $params, 'table_info' => false, 'fields' => true );
6100
  }
6101
 
6102
- if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && isset( $params->fields ) && ! $params->fields ) {
6103
- $load_fields = false;
6104
- } elseif ( is_array( $params ) && isset( $params['fields'] ) && ! $params['fields'] ) {
6105
- $load_fields = false;
6106
  }
6107
 
6108
- $table_info = false;
 
 
 
 
 
6109
 
6110
- if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->table_info ) ) {
6111
- $table_info = true;
6112
- } elseif ( is_array( $params ) && ! empty( $params['table_info'] ) ) {
6113
- $table_info = true;
6114
  }
6115
 
6116
- $transient = 'pods_' . $wpdb->prefix . '_pod';
 
6117
 
6118
- if ( ! empty( $current_language ) ) {
6119
- $transient .= '_' . $current_language;
6120
- }
6121
 
6122
- if ( ! $load_fields ) {
6123
- $transient .= '_nofields';
6124
- }
6125
 
6126
- if ( $table_info ) {
6127
- $transient .= '_tableinfo';
6128
  }
6129
 
6130
- $check_pod = $params;
 
6131
 
6132
- if ( is_object( $params ) && ! is_a( $params, 'WP_Post' ) && ! empty( $params->pod ) ) {
6133
- $check_pod = $params->pod;
6134
- } elseif ( is_array( $params ) && ! empty( $params['pod'] ) ) {
6135
- $check_pod = $params['pod'];
6136
- }
6137
 
6138
- if ( is_object( $check_pod ) && ( is_a( $check_pod, 'WP_Post' ) || isset( $check_pod->post_name ) ) ) {
6139
- $pod = false;
 
 
6140
 
6141
- if ( pods_api_cache() ) {
6142
- $pod = pods_transient_get( $transient . '_' . $check_pod->post_name );
 
 
 
 
6143
  }
 
6144
 
6145
- if ( false !== $pod && ( ! $table_info || isset( $pod['table'] ) ) ) {
6146
- // @todo Is this needed anymore for WPML?
6147
- if ( in_array( $pod['type'], array(
6148
- 'post_type',
6149
- 'taxonomy'
6150
- ) ) && did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
6151
- $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) );
6152
- }
6153
 
6154
- return $pod;
6155
- }
 
6156
 
6157
- $_pod = get_object_vars( $check_pod );
6158
- } else {
6159
- $params = (object) pods_sanitize( $params );
6160
 
6161
- if ( ( ! isset( $params->id ) || empty( $params->id ) ) && ( ! isset( $params->name ) || empty( $params->name ) ) ) {
6162
- if ( $strict ) {
6163
- return pods_error( __( 'Either Pod ID or Name are required', 'pods' ), $this );
6164
  }
6165
 
6166
- return false;
 
 
6167
  }
 
6168
 
6169
- if ( ! empty( $params->bypass_cache ) ) {
6170
- $bypass_cache = true;
6171
- }
 
 
6172
 
6173
- if ( isset( $params->name ) ) {
6174
- $pod = false;
6175
 
6176
- if ( '_pods_pod' === $params->name ) {
6177
- $pod = array(
6178
- 'id' => 0,
6179
- 'name' => $params->name,
6180
- 'object' => $params->name,
6181
- 'label' => __( 'Pods', 'pods' ),
6182
- 'type' => 'post_type',
6183
- 'storage' => 'meta',
6184
- 'options' => array(
6185
- 'label_singular' => __( 'Pod', 'pods' )
6186
- ),
6187
- 'fields' => array()
6188
- );
6189
- } elseif ( '_pods_field' === $params->name ) {
6190
- $pod = array(
6191
- 'id' => 0,
6192
- 'name' => $params->name,
6193
- 'object' => $params->name,
6194
- 'label' => __( 'Pod Fields', 'pods' ),
6195
- 'type' => 'post_type',
6196
- 'storage' => 'meta',
6197
- 'options' => array(
6198
- 'label_singular' => __( 'Pod Field', 'pods' )
6199
- ),
6200
- 'fields' => array()
6201
- );
6202
- } elseif ( ! $bypass_cache & pods_api_cache() ) {
6203
- $pod = pods_transient_get( $transient . '_' . $params->name );
6204
- }
6205
 
6206
- if ( false !== $pod && ( ! $table_info || isset( $pod['table'] ) ) ) {
6207
- if ( in_array( $pod['type'], array(
6208
- 'post_type',
6209
- 'taxonomy'
6210
- ) ) && did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
6211
- $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) );
6212
- }
 
 
 
 
 
6213
 
6214
- return $pod;
6215
- }
6216
- }
 
 
6217
 
6218
- if ( ! isset( $params->name ) ) {
6219
- $dummy = (int) $params->id;
6220
- $pod = get_post( $dummy );
6221
- } else {
6222
- $pod = get_posts( array(
6223
- 'name' => $params->name,
6224
- 'post_type' => '_pods_pod',
6225
- 'posts_per_page' => 1
6226
- ) );
6227
- }
6228
 
6229
- if ( empty( $pod ) ) {
6230
- if ( $strict ) {
6231
- return pods_error( __( 'Pod not found', 'pods' ), $this );
6232
- }
 
 
6233
 
6234
- return false;
6235
- }
 
6236
 
6237
- if ( is_array( $pod ) && ! empty( $pod[0] ) ) {
6238
- $pod = $pod[0];
6239
  }
6240
-
6241
- $_pod = get_object_vars( $pod );
6242
  }
6243
 
6244
- $pod = false;
 
 
 
 
 
 
6245
 
6246
- if ( ! $bypass_cache || pods_api_cache() ) {
6247
- $pod = pods_transient_get( $transient . '_' . $_pod['post_name'] );
6248
  }
6249
 
6250
- if ( false !== $pod && ( ! $table_info || isset( $pod['table'] ) ) ) {
6251
- if ( in_array( $pod['type'], array(
6252
- 'post_type',
6253
- 'taxonomy'
6254
- ) ) && did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
6255
- $pod = array_merge( $pod, $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ) );
 
6256
  }
6257
 
6258
- return $pod;
6259
- }
 
6260
 
6261
- $pod = array(
6262
- 'id' => $_pod['ID'],
6263
- 'name' => $_pod['post_name'],
6264
- 'label' => $_pod['post_title'],
6265
- 'description' => $_pod['post_content']
6266
- );
6267
 
6268
- if ( strlen( $pod['label'] ) < 1 ) {
6269
- $pod['label'] = $pod['name'];
 
 
 
 
 
6270
  }
6271
 
6272
- // @todo update with a method to put all options in
6273
- $defaults = array(
6274
- 'show_in_menu' => 1,
6275
- 'type' => 'post_type',
6276
- 'storage' => 'meta',
6277
- 'object' => '',
6278
- 'alias' => ''
6279
- );
 
 
 
 
 
 
 
 
6280
 
6281
- if ( $bypass_cache ) {
6282
- wp_cache_delete( $pod['id'], 'post_meta' );
 
 
6283
 
6284
- update_postmeta_cache( array( $pod['id'] ) );
 
 
 
 
 
 
 
 
6285
  }
6286
 
6287
- $pod['options'] = get_post_meta( $pod['id'] );
 
6288
 
6289
- foreach ( $pod['options'] as $option => $value ) {
6290
- if ( is_array( $value ) ) {
6291
- foreach ( $value as $k => $v ) {
6292
- if ( ! is_array( $v ) ) {
6293
- $value[ $k ] = maybe_unserialize( $v );
6294
- }
6295
- }
 
 
 
 
 
6296
 
6297
- if ( 1 == count( $value ) ) {
6298
- $value = current( $value );
6299
- }
6300
- } else {
6301
- $value = maybe_unserialize( $value );
6302
  }
6303
 
6304
- $pod['options'][ $option ] = $value;
6305
  }
6306
 
6307
- $pod['options'] = array_merge( $defaults, $pod['options'] );
 
 
 
6308
 
6309
- $pod['type'] = $pod['options']['type'];
6310
- $pod['storage'] = $pod['options']['storage'];
6311
- $pod['object'] = $pod['options']['object'];
6312
- $pod['alias'] = $pod['options']['alias'];
6313
 
6314
- unset( $pod['options']['type'] );
6315
- unset( $pod['options']['storage'] );
6316
- unset( $pod['options']['object'] );
6317
- unset( $pod['options']['alias'] );
6318
 
6319
- if ( $table_info ) {
6320
- $pod = array_merge( $this->get_table_info( $pod['type'], $pod['object'], $pod['name'], $pod ), $pod );
6321
  }
6322
 
6323
- // Override old 'none' storage type
6324
- if ( 'taxonomy' === $pod['type'] && 'none' === $pod['storage'] && function_exists( 'get_term_meta' ) ) {
6325
- $pod['storage'] = 'meta';
6326
- }
6327
 
6328
- if ( isset( $pod['pod'] ) ) {
6329
- unset( $pod['pod'] );
 
 
 
 
6330
  }
6331
 
6332
- $pod['fields'] = array();
 
 
 
 
 
6333
 
6334
- $pod['object_fields'] = array();
 
6335
 
6336
- if ( 'pod' !== $pod['type'] ) {
6337
- $pod['object_fields'] = $this->get_wp_object_fields( $pod['type'], $pod );
6338
  }
6339
 
6340
- $fields = get_posts( array(
6341
- 'post_type' => '_pods_field',
6342
- 'posts_per_page' => - 1,
6343
- 'nopaging' => true,
6344
- 'post_parent' => $pod['id'],
6345
- 'orderby' => 'menu_order',
6346
- 'order' => 'ASC'
6347
- ) );
6348
 
6349
- if ( ! empty( $fields ) ) {
6350
- foreach ( $fields as $field ) {
6351
- $field->pod = $pod['name'];
6352
- $field->table_info = $table_info;
6353
- $field->bypass_cache = $bypass_cache;
6354
 
6355
- if ( $load_fields ) {
6356
- $field = $this->load_field( $field );
 
 
 
 
 
 
 
6357
 
6358
- $field = PodsForm::field_setup( $field, null, $field['type'] );
6359
- } else {
6360
- if ( $bypass_cache ) {
6361
- wp_cache_delete( $field->ID, 'post_meta' );
 
6362
 
6363
- update_postmeta_cache( array( $field->ID ) );
6364
- }
6365
 
6366
- $field = array(
6367
- 'id' => $field->ID,
6368
- 'name' => $field->post_name,
6369
- 'label' => $field->post_title,
6370
- 'type' => get_post_meta( $field->ID, 'type', true )
6371
- );
6372
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6373
 
6374
- $pod['fields'][ $field['name'] ] = $field;
6375
- }
 
 
 
6376
  }
6377
 
6378
- if ( did_action( 'init' ) && pods_api_cache() ) {
6379
- pods_transient_set( $transient . '_' . $pod['name'], $pod );
6380
- }
 
 
 
 
 
 
 
 
6381
 
6382
- return $pod;
 
 
6383
  }
6384
 
6385
  /**
6386
- * Load a list of Pods based on filters specified.
6387
  *
6388
- * $params['type'] string/array Pod Type(s) to filter by
6389
- * $params['object'] string/array Pod Object(s) to filter by
6390
- * $params['options'] array Pod Option(s) key=>value array to filter by
6391
- * $params['orderby'] string ORDER BY clause of query
6392
- * $params['limit'] string Number of Pods to return
6393
- * $params['where'] string WHERE clause of query
6394
- * $params['ids'] string|array IDs of Objects
6395
- * $params['count'] boolean Return only a count of Pods
6396
- * $params['names'] boolean Return only an array of name => label
6397
- * $params['ids'] boolean Return only an array of ID => label
6398
- * $params['fields'] boolean Return pod fields with Pods (default is true)
6399
- * $params['key_names'] boolean Return pods keyed by name
6400
- * $params['bypass_cache'] boolean Bypass the cache when getting data
6401
  *
6402
  * @param array $params An associative array of parameters
6403
  *
6404
- * @return array|mixed
6405
- *
6406
- * @uses PodsAPI::load_pod
6407
  *
6408
- * @since 2.0.0
6409
  */
6410
- public function load_pods( $params = null ) {
6411
-
6412
- $current_language = false;
6413
-
6414
- // Get current language data
6415
- $lang_data = pods_i18n()->get_current_language_data();
6416
 
6417
- if ( $lang_data ) {
6418
- if ( ! empty( $lang_data['language'] ) ) {
6419
- $current_language = $lang_data['language'];
6420
- }
6421
  }
6422
 
6423
  $params = (object) pods_sanitize( $params );
6424
 
6425
- $order = 'ASC';
6426
- $orderby = 'menu_order title';
6427
- $limit = - 1;
6428
- $ids = false;
6429
-
6430
- $meta_query = array();
6431
- $cache_key = '';
6432
-
6433
- $bypass_cache = false;
6434
-
6435
- if ( ! empty( $params->bypass_cache ) ) {
6436
- $bypass_cache = true;
6437
- }
6438
 
6439
- if ( isset( $params->type ) && ! empty( $params->type ) ) {
6440
- if ( ! is_array( $params->type ) ) {
6441
- $params->type = array( trim( $params->type ) );
6442
  }
6443
 
6444
- sort( $params->type );
6445
-
6446
- $meta_query[] = array(
6447
- 'key' => 'type',
6448
- 'value' => $params->type,
6449
- 'compare' => 'IN'
6450
- );
6451
-
6452
- if ( 0 < count( $params->type ) ) {
6453
- $cache_key .= '_type_' . trim( implode( '_', $params->type ) );
6454
  }
6455
  }
6456
 
6457
- if ( isset( $params->object ) && ! empty( $params->object ) ) {
6458
- if ( ! is_array( $params->object ) ) {
6459
- $params->object = array( $params->object );
6460
- }
6461
-
6462
- $params->object = pods_trim( $params->object );
6463
-
6464
- sort( $params->object );
6465
-
6466
- $meta_query[] = array(
6467
- 'key' => 'object',
6468
- 'value' => $params->object,
6469
- 'compare' => 'IN'
6470
- );
6471
 
6472
- if ( 1 == count( $params->object ) ) {
6473
- $cache_key .= '_object_' . trim( implode( '', $params->object ) );
6474
- }
6475
- }
 
 
 
 
 
 
6476
 
6477
- if ( isset( $params->options ) && ! empty( $params->options ) && is_array( $params->options ) ) {
6478
- foreach ( $params->options as $option => $value ) {
6479
- if ( ! is_array( $value ) ) {
6480
- $value = array( $value );
6481
- }
 
 
 
 
 
 
 
6482
 
6483
- $value = pods_trim( $value );
6484
 
6485
- sort( $value );
6486
 
6487
- $meta_query[] = array(
6488
- 'key' => $option,
6489
- 'value' => pods_sanitize( $value ),
6490
- 'compare' => 'IN'
6491
- );
6492
- }
6493
 
6494
- $cache_key = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6495
  }
6496
 
6497
- if ( isset( $params->where ) && is_array( $params->where ) ) {
6498
- $meta_query = array_merge( $meta_query, (array) $params->where );
6499
  }
6500
 
6501
- if ( isset( $params->order ) && ! empty( $params->order ) && in_array( strtoupper( $params->order ), array(
6502
- 'ASC',
6503
- 'DESC'
6504
- ) ) ) {
6505
- $order = strtoupper( $params->order );
 
 
 
6506
  }
6507
 
6508
- if ( isset( $params->orderby ) && ! empty( $params->orderby ) ) {
6509
- $orderby = strtoupper( $params->orderby );
 
6510
  }
6511
 
6512
- if ( isset( $params->limit ) && ! empty( $params->limit ) ) {
6513
- $limit = pods_absint( $params->limit );
6514
  }
6515
 
6516
- if ( isset( $params->ids ) && ! empty( $params->ids ) ) {
6517
- $ids = $params->ids;
 
6518
 
6519
- if ( ! is_array( $ids ) ) {
6520
- $ids = explode( ',', $ids );
6521
  }
6522
  }
6523
 
6524
- if ( empty( $ids ) ) {
6525
- $ids = false;
6526
  }
6527
 
6528
- $pre_key = '';
6529
-
6530
- if ( ! empty( $current_language ) ) {
6531
- $pre_key .= '_' . $current_language;
6532
  }
6533
 
6534
- if ( isset( $params->count ) && $params->count ) {
6535
- $pre_key .= '_count';
6536
- }
6537
 
6538
- if ( isset( $params->ids ) && $params->ids && ! empty( $ids ) ) {
6539
- $pre_key .= '_ids_' . implode( '_', $ids );
6540
  }
6541
 
6542
- if ( isset( $params->names ) && $params->names ) {
6543
- $pre_key .= '_names';
6544
- } elseif ( isset( $params->names_ids ) && $params->names_ids ) {
6545
- $pre_key .= '_names_ids';
6546
  }
6547
 
6548
- if ( isset( $params->key_names ) && $params->key_names ) {
6549
- $pre_key .= '_namekeys';
6550
- }
6551
 
6552
- if ( isset( $params->fields ) && ! $params->fields ) {
6553
- $pre_key .= '_nofields';
6554
- }
6555
 
6556
- if ( isset( $params->table_info ) && $params->table_info ) {
6557
- $pre_key .= '_tableinfo';
 
 
6558
  }
6559
 
6560
- $pre_key .= '_get';
6561
-
6562
- if ( empty( $cache_key ) ) {
6563
- $cache_key = 'pods' . $pre_key . '_all';
6564
- } else {
6565
- $cache_key = 'pods' . $pre_key . $cache_key;
6566
  }
6567
 
6568
- 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 ) ) {
6569
- $the_pods = pods_transient_get( $cache_key );
6570
-
6571
- if ( false === $the_pods ) {
6572
- $the_pods = pods_cache_get( $cache_key, 'pods' );
6573
- }
6574
-
6575
- if ( ! is_array( $the_pods ) && 'none' === $the_pods ) {
6576
- return array();
6577
- } elseif ( false !== $the_pods ) {
6578
- return $the_pods;
6579
- }
6580
  }
6581
 
6582
- $the_pods = array();
6583
-
6584
- $args = array(
6585
- 'post_type' => '_pods_pod',
6586
- 'nopaging' => true,
6587
- 'posts_per_page' => $limit,
6588
- 'order' => $order,
6589
- 'orderby' => $orderby,
6590
- 'meta_query' => $meta_query,
6591
- );
6592
 
6593
- // Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
6594
- if ( false !== $ids ) {
6595
- $args['post__in'] = $ids;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6596
  }
6597
 
6598
- $_pods = get_posts( $args );
6599
-
6600
- $export_ignore = array(
6601
- 'object_type',
6602
- 'object_name',
6603
- 'table',
6604
- 'meta_table',
6605
- 'pod_table',
6606
- 'field_id',
6607
- 'field_index',
6608
- 'field_slug',
6609
- 'field_type',
6610
- 'field_parent',
6611
- 'field_parent_select',
6612
- 'meta_field_id',
6613
- 'meta_field_index',
6614
- 'meta_field_value',
6615
- 'pod_field_id',
6616
- 'pod_field_index',
6617
- 'object_fields',
6618
- 'join',
6619
- 'where',
6620
- 'where_default',
6621
- 'orderby',
6622
- 'pod',
6623
- 'recurse',
6624
- 'table_info',
6625
- 'attributes',
6626
- 'group',
6627
- 'grouped',
6628
- 'developer_mode',
6629
- 'dependency',
6630
- 'depends-on',
6631
- 'excludes-on'
6632
- );
6633
-
6634
- $total_fields = 0;
6635
-
6636
- if ( isset( $params->count ) && $params->count ) {
6637
- $the_pods = count( $_pods );
6638
- } else {
6639
- foreach ( $_pods as $pod ) {
6640
- if ( isset( $params->names ) && $params->names ) {
6641
- $the_pods[ $pod->post_name ] = $pod->post_title;
6642
- } elseif ( isset( $params->names_ids ) && $params->names_ids ) {
6643
- $the_pods[ $pod->ID ] = $pod->post_name;
6644
- } else {
6645
- if ( isset( $params->fields ) && ! $params->fields ) {
6646
- $pod->fields = false;
6647
- }
6648
 
6649
- $pod = $this->load_pod( array(
6650
- 'pod' => $pod,
6651
- 'table_info' => ! empty( $params->table_info ),
6652
- 'bypass_cache' => $bypass_cache
6653
- ) );
6654
 
6655
- // Remove extra data not needed
6656
- if ( pods_var( 'export', $params, false ) && ( ! isset( $params->fields ) || $params->fields ) ) {
6657
- foreach ( $export_ignore as $ignore ) {
6658
- if ( isset( $pod[ $ignore ] ) ) {
6659
- unset( $pod[ $ignore ] );
6660
- }
6661
- }
6662
 
6663
- foreach ( $pod['fields'] as $field => $field_data ) {
6664
- if ( isset( $pod['fields'][ $field ]['table_info'] ) ) {
6665
- unset( $pod['fields'][ $field ]['table_info'] );
6666
- }
6667
- }
6668
- }
6669
 
6670
- $total_fields += count( $pod['fields'] );
 
 
6671
 
6672
- if ( isset( $params->key_names ) && $params->key_names ) {
6673
- $the_pods[ $pod['name'] ] = $pod;
6674
- } else {
6675
- $the_pods[ $pod['id'] ] = $pod;
6676
- }
6677
- }
6678
- }
6679
  }
6680
 
6681
- if ( ( ! function_exists( 'pll_current_language' ) || ! empty( $params->refresh ) ) && ! empty( $cache_key ) && ( 'pods' !== $cache_key || empty( $meta_query ) ) && $limit < 1 && ( empty( $orderby ) || 'menu_order title' === $orderby ) && empty( $ids ) ) {
6682
- $total_pods = (int) ( is_array( $the_pods ) ) ? count( $the_pods ) : $the_pods;
6683
- // Too many Pods can cause issues with the DB when caching is not enabled
6684
- if ( 15 < $total_pods || 75 < (int) $total_fields ) {
6685
- pods_transient_clear( $cache_key );
6686
 
6687
- if ( pods_api_cache() ) {
6688
- if ( empty( $the_pods ) && ( ! isset( $params->count ) || ! $params->count ) ) {
6689
- pods_cache_set( $cache_key, 'none', 'pods' );
6690
- } else {
6691
- pods_cache_set( $cache_key, $the_pods, 'pods' );
6692
- }
6693
- }
6694
- } else {
6695
- pods_cache_clear( $cache_key, 'pods' );
6696
 
6697
- if ( pods_api_cache() ) {
6698
- if ( empty( $the_pods ) && ( ! isset( $params->count ) || ! $params->count ) ) {
6699
- pods_transient_set( $cache_key, 'none' );
6700
- } else {
6701
- pods_transient_set( $cache_key, $the_pods );
6702
- }
6703
- }
6704
- }
6705
  }
6706
 
6707
- return $the_pods;
 
 
6708
  }
6709
 
6710
  /**
@@ -6714,476 +7821,521 @@ class PodsAPI {
6714
  * $params['id'] int The field ID
6715
  * $params['name'] string The field name
6716
  *
6717
- * @param array $params An associative array of parameters
 
6718
  *
6719
  * @return bool
6720
  *
6721
  * @since 1.12
6722
  */
6723
- public function field_exists( $params ) {
 
6724
 
6725
- $params = (object) pods_sanitize( $params );
 
 
 
 
6726
 
6727
- if ( ( ! empty( $params->id ) || ! empty( $params->name ) ) && isset( $params->pod_id ) && ! empty( $params->pod_id ) ) {
6728
- if ( ! isset( $params->name ) ) {
6729
- $dummy = (int) $params->id;
6730
- $field = get_post( $dummy );
6731
- } else {
6732
- $field = get_posts( array(
6733
- 'name' => $params->name,
6734
- 'post_type' => '_pods_field',
6735
- 'posts_per_page' => 1,
6736
- 'post_parent' => $params->pod_id
6737
- ) );
6738
- }
6739
 
6740
- if ( ! empty( $field ) ) {
6741
- return true;
 
 
 
6742
  }
 
 
6743
  }
6744
 
6745
- return false;
 
 
 
 
6746
  }
6747
 
6748
  /**
6749
- * Load a field
6750
  *
6751
- * $params['pod_id'] int The Pod ID
6752
- * $params['pod'] string The Pod name
6753
- * $params['id'] int The field ID
6754
- * $params['name'] string The field name
6755
- * $params['table_info'] boolean Whether to lookup a pick field's table info
6756
- * $params['bypass_cache'] boolean Bypass the cache when getting data
 
 
 
6757
  *
6758
- * @param array $params An associative array of parameters
6759
- * @param boolean $strict Whether to require a field exist or not when loading the info
6760
  *
6761
- * @return array|bool Array with field data, false if field not found
 
 
 
6762
  * @since 1.7.9
6763
  */
6764
  public function load_field( $params, $strict = false ) {
6765
-
6766
- $params = (object) $params;
6767
-
6768
- if ( ! isset( $params->table_info ) ) {
6769
- $params->table_info = false;
6770
  }
6771
 
6772
- $bypass_cache = false;
6773
-
6774
- if ( ! empty( $params->bypass_cache ) ) {
6775
- $bypass_cache = true;
6776
  }
6777
 
6778
- $pod = array();
6779
- $field = array();
6780
-
6781
- if ( isset( $params->post_title ) ) {
6782
- $_field = $params;
6783
- } elseif ( isset( $params->id ) && ! empty( $params->id ) ) {
6784
- $dummy = (int) $params->id;
6785
- $_field = get_post( $dummy );
6786
- } else {
6787
- if ( ! isset( $params->pod ) ) {
6788
- $params->pod = '';
6789
- }
6790
 
6791
- if ( ! isset( $params->pod_id ) ) {
6792
- $params->pod_id = 0;
6793
- }
 
6794
 
6795
- if ( isset( $params->pod_data ) ) {
6796
- $pod = $params->pod_data;
6797
- } else {
6798
- $pod = $this->load_pod( array(
6799
- 'name' => $params->pod,
6800
- 'id' => $params->pod_id,
6801
- 'table_info' => false,
6802
- 'bypass_cache' => $bypass_cache
6803
- ), false );
6804
-
6805
- if ( false === $pod ) {
6806
- if ( $strict ) {
6807
- return pods_error( __( 'Pod not found', 'pods' ), $this );
6808
- }
6809
 
6810
- return false;
6811
- }
6812
  }
 
6813
 
6814
- $params->pod_id = $pod['id'];
6815
- $params->pod = $pod['name'];
 
6816
 
6817
- if ( empty( $params->name ) && empty( $params->pod ) && empty( $params->pod_id ) ) {
6818
- return pods_error( __( 'Either Field Name or Field ID / Pod ID are required', 'pods' ), $this );
6819
- }
6820
 
6821
- $params->name = pods_clean_name( $params->name, true, ( 'meta' === $pod['storage'] ? false : true ) );
 
6822
 
6823
- if ( isset( $pod['fields'][ $params->name ] ) && isset( $pod['fields'][ $params->name ]['id'] ) ) {
6824
- return $pod['fields'][ $params->name ];
6825
- }
6826
 
6827
- $field = false;
6828
 
6829
- if ( ! $bypass_cache && pods_api_cache() ) {
6830
- $field = pods_transient_get( 'pods_field_' . $params->pod . '_' . $params->name );
 
6831
  }
6832
 
6833
- if ( empty( $field ) ) {
6834
- $field = get_posts( array(
6835
- 'name' => $params->name,
6836
- 'post_type' => '_pods_field',
6837
- 'posts_per_page' => 1,
6838
- 'post_parent' => $params->pod_id
6839
- ) );
6840
 
6841
- if ( empty( $field ) || empty( $field[0] ) ) {
6842
- if ( $strict ) {
6843
- return pods_error( __( 'Field not found', 'pods' ), $this );
6844
- }
6845
 
6846
- return false;
6847
- }
6848
 
6849
- $_field = $field[0];
 
6850
 
6851
- $field = array();
 
6852
  }
6853
  }
6854
 
6855
- if ( empty( $_field ) ) {
6856
- if ( $strict ) {
6857
- return pods_error( __( 'Field not found', 'pods' ), $this );
6858
- }
6859
 
6860
- return false;
 
 
 
6861
  }
6862
 
6863
- $_field = get_object_vars( $_field );
 
 
6864
 
6865
- if ( ! isset( $pod['name'] ) && ! isset( $_field['pod'] ) ) {
6866
- if ( 0 < $_field['post_parent'] ) {
6867
- $pod = $this->load_pod( array( 'id' => $_field['post_parent'], 'table_info' => false ), false );
6868
- }
6869
 
6870
- if ( empty( $pod ) ) {
6871
- if ( $strict ) {
6872
- return pods_error( __( 'Pod for field not found', 'pods' ), $this );
6873
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6874
 
6875
- return false;
 
 
 
6876
  }
6877
- }
6878
 
6879
- if ( empty( $field ) ) {
6880
- if ( ! $bypass_cache && pods_api_cache() && ( isset( $pod['name'] ) || isset( $_field['pod'] ) ) ) {
6881
- $field = pods_transient_get( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $_field['post_name'] );
 
 
 
 
6882
  }
6883
 
6884
- if ( empty( $field ) ) {
6885
- $defaults = array(
6886
- 'type' => 'text'
6887
- );
6888
 
6889
- $field = array(
6890
- 'id' => $_field['ID'],
6891
- 'name' => $_field['post_name'],
6892
- 'label' => $_field['post_title'],
6893
- 'description' => $_field['post_content'],
6894
- 'weight' => $_field['menu_order'],
6895
- 'pod_id' => $_field['post_parent'],
6896
- 'pick_object' => '',
6897
- 'pick_val' => '',
6898
- 'sister_id' => '',
6899
- 'table_info' => array()
6900
  );
6901
 
6902
- if ( isset( $pod['name'] ) ) {
6903
- $field['pod'] = $pod['name'];
6904
- } elseif ( isset( $_field['pod'] ) ) {
6905
- $field['pod'] = $_field['pod'];
6906
- }
6907
-
6908
- if ( $bypass_cache ) {
6909
- wp_cache_delete( $field['id'], 'post_meta' );
6910
 
6911
- update_postmeta_cache( array( $field['id'] ) );
6912
- }
 
6913
 
6914
- $field['options'] = get_post_meta( $field['id'] );
 
 
6915
 
6916
- $options_ignore = array(
6917
- 'method',
6918
- 'table_info',
6919
- 'attributes',
6920
- 'group',
6921
- 'grouped',
6922
- 'developer_mode',
6923
- 'dependency',
6924
- 'depends-on',
6925
- 'excludes-on'
6926
- );
6927
 
6928
- foreach ( $options_ignore as $ignore ) {
6929
- if ( isset( $field['options'][ $ignore ] ) ) {
6930
- unset( $field['options'][ $ignore ] );
6931
  }
6932
  }
6933
 
6934
- foreach ( $field['options'] as $option => $value ) {
6935
- if ( is_array( $value ) ) {
6936
- foreach ( $value as $k => $v ) {
6937
- if ( ! is_array( $v ) ) {
6938
- $value[ $k ] = maybe_unserialize( $v );
6939
- }
6940
- }
6941
 
6942
- if ( 1 == count( $value ) ) {
6943
- $value = current( $value );
6944
- }
6945
- } else {
6946
- $value = maybe_unserialize( $value );
6947
- }
6948
 
6949
- $field['options'][ $option ] = $value;
 
6950
  }
 
 
 
 
6951
 
6952
- $field['options'] = array_merge( $defaults, $field['options'] );
 
6953
 
6954
- $field['type'] = $field['options']['type'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6955
 
6956
- unset( $field['options']['type'] );
6957
 
6958
- if ( isset( $field['options']['pick_object'] ) ) {
6959
- $field['pick_object'] = $field['options']['pick_object'];
6960
 
6961
- unset( $field['options']['pick_object'] );
6962
- }
6963
 
6964
- if ( isset( $field['options']['pick_val'] ) ) {
6965
- $field['pick_val'] = $field['options']['pick_val'];
 
6966
 
6967
- unset( $field['options']['pick_val'] );
6968
- }
 
6969
 
6970
- if ( isset( $field['options']['sister_id'] ) ) {
6971
- $field['sister_id'] = $field['options']['sister_id'];
 
6972
 
6973
- unset( $field['options']['sister_id'] );
6974
- }
6975
 
6976
- if ( isset( $field['options']['sister_field_id'] ) ) {
6977
- unset( $field['options']['sister_field_id'] );
6978
- }
6979
 
6980
- if ( pods_api_cache() && ( isset( $pod['name'] ) || isset( $_field['pod'] ) ) ) {
6981
- pods_transient_set( 'pods_field_' . pods_var( 'name', $pod, pods_var( 'pod', $_field ), null, true ) . '_' . $field['name'], $field );
6982
- }
6983
- }
6984
  }
6985
 
6986
- $field['table_info'] = array();
 
 
 
 
 
 
 
 
 
6987
 
6988
- if ( 'pick' === $field['type'] && $params->table_info ) {
6989
- $field['table_info'] = $this->get_table_info( $field['pick_object'], $field['pick_val'], null, null, $field );
6990
  }
6991
 
6992
- return $field;
 
 
6993
  }
6994
 
6995
  /**
6996
- * Load fields by Pod, ID, Name, and/or Type
6997
  *
6998
- * $params['pod_id'] int The Pod ID
6999
- * $params['pod'] string The Pod name
7000
- * $params['id'] array The field IDs
7001
- * $params['name'] array The field names
7002
- * $params['type'] array The field types
7003
- * $params['options'] array Field Option(s) key=>value array to filter by
7004
- * $params['where'] string WHERE clause of query
7005
- * $params['object_fields'] bool Whether to include the object fields for WP objects, default true
7006
  *
7007
- * @param array $params An associative array of parameters
7008
- * @param bool $strict Whether to require a field exist or not when loading the info
 
 
 
 
 
7009
  *
7010
- * @return array Array of field data.
7011
  *
7012
- * @since 1.7.9
7013
  */
7014
- public function load_fields( $params, $strict = false ) {
 
 
 
 
 
 
 
7015
 
7016
- // @todo Get away from using md5/serialize, I'm sure we can cache specific parts
7017
- $cache_key = md5( serialize( $params ) );
7018
- if ( isset( $this->fields_cache[ $cache_key ] ) ) {
7019
- return $this->fields_cache[ $cache_key ];
7020
  }
7021
 
7022
- $params = (object) pods_sanitize( $params );
7023
 
7024
- if ( ! isset( $params->pod ) || empty( $params->pod ) ) {
7025
- $params->pod = '';
7026
- }
 
7027
 
7028
- if ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) {
7029
- $params->pod_id = 0;
7030
  }
7031
 
7032
- if ( ! isset( $params->name ) || empty( $params->name ) ) {
7033
- $params->name = array();
7034
- } else {
7035
- $params->name = (array) $params->name;
7036
  }
 
7037
 
7038
- if ( ! isset( $params->id ) || empty( $params->id ) ) {
7039
- $params->id = array();
7040
- } else {
7041
- $params->id = (array) $params->id;
7042
-
7043
- foreach ( $params->id as &$id ) {
7044
- $id = pods_absint( $id );
7045
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7046
  }
7047
 
7048
- if ( ! isset( $params->type ) || empty( $params->type ) ) {
7049
- $params->type = array();
7050
- } else {
7051
- $params->type = (array) $params->type;
7052
  }
7053
 
7054
- if ( ! isset( $params->object_fields ) ) {
7055
- $params->object_fields = true;
7056
- } else {
7057
- $params->object_fields = (boolean) $params->object_fields;
 
 
 
 
7058
  }
7059
 
7060
- $fields = array();
7061
-
7062
- if ( ! empty( $params->pod ) || ! empty( $params->pod_id ) ) {
7063
- $pod = $this->load_pod( array(
7064
- 'name' => $params->pod,
7065
- 'id' => $params->pod_id,
7066
- 'table_info' => true
7067
- ), false );
7068
-
7069
- if ( false === $pod ) {
7070
- if ( $strict ) {
7071
- return pods_error( __( 'Pod not found', 'pods' ), $this );
7072
- }
7073
 
7074
- return $fields;
7075
- }
 
7076
 
7077
- if ( $params->object_fields && ! empty( $pod['object_fields'] ) ) {
7078
- $pod['fields'] = array_merge( $pod['object_fields'], $pod['fields'] );
7079
  }
 
7080
 
7081
- foreach ( $pod['fields'] as $field ) {
7082
- if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) ) {
7083
- $fields[ $field['name'] ] = $field;
7084
- } elseif ( in_array( $fields['name'], $params->name ) || in_array( $fields['id'], $params->id ) || in_array( $fields['type'], $params->type ) ) {
7085
- $fields[ $field['name'] ] = $field;
7086
- }
7087
- }
7088
- } elseif ( ( isset( $params->options ) && ! empty( $params->options ) && is_array( $params->options ) ) || ( isset( $params->where ) && ! empty( $params->where ) && is_array( $params->where ) ) ) {
7089
- $order = 'ASC';
7090
- $orderby = 'menu_order title';
7091
- $limit = - 1;
7092
- $ids = false;
7093
 
7094
- $meta_query = array();
 
7095
 
7096
- if ( isset( $params->options ) && ! empty( $params->options ) && is_array( $params->options ) ) {
7097
- foreach ( $params->options as $option => $value ) {
7098
- if ( ! is_array( $value ) ) {
7099
- $value = array( $value );
7100
- }
7101
 
7102
- $value = pods_trim( $value );
 
 
7103
 
7104
- sort( $value );
7105
 
7106
- $meta_query[] = array(
7107
- 'key' => $option,
7108
- 'value' => pods_sanitize( $value ),
7109
- 'compare' => 'IN'
7110
- );
7111
  }
7112
  }
7113
 
7114
- if ( isset( $params->where ) && ! empty( $params->where ) && is_array( $params->where ) ) {
7115
- $meta_query = array_merge( $meta_query, (array) $params->where );
7116
- }
7117
 
7118
- $args = array(
7119
- 'post_type' => '_pods_field',
7120
- 'nopaging' => true,
7121
- 'posts_per_page' => $limit,
7122
- 'order' => $order,
7123
- 'orderby' => $orderby,
7124
- 'meta_query' => $meta_query,
7125
- );
7126
 
7127
- // Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
7128
- if ( false !== $ids ) {
7129
- $args['post__in'] = $ids;
7130
- }
 
7131
 
7132
- $fields = array();
 
 
7133
 
7134
- $_fields = get_posts( $args );
 
7135
 
7136
- foreach ( $_fields as $field ) {
7137
- $field = $this->load_field( $field, false );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7138
 
7139
- if ( ! empty( $field ) ) {
7140
- $fields[ $field['id'] ] = $field;
7141
- }
7142
- }
7143
- } else {
7144
- if ( empty( $params->name ) && empty( $params->id ) && empty( $params->type ) ) {
7145
- return pods_error( __( 'Either Field Name / Field ID / Field Type, or Pod Name / Pod ID are required', 'pods' ), $this );
7146
- }
7147
 
7148
- $lookup = array();
 
7149
 
7150
- if ( ! empty( $params->name ) ) {
7151
- $fields = implode( "', '", $params->name );
7152
 
7153
- $lookup[] = "`post_name` IN ( '{$fields}' )";
7154
- }
 
7155
 
7156
- if ( ! empty( $params->id ) ) {
7157
- $fields = implode( ", ", $params->id );
 
7158
 
7159
- $lookup[] = "`ID` IN ( {$fields} )";
7160
- }
 
7161
 
7162
- $lookup = implode( ' AND ', $lookup );
 
7163
 
7164
- $result = pods_query( "SELECT `ID`, `post_name`, `post_parent` FROM `@wp_posts` WHERE `post_type` = '_pods_field' AND ( {$lookup} )" );
 
7165
 
7166
- $fields = array();
 
 
7167
 
7168
- if ( ! empty( $result ) ) {
7169
- foreach ( $result as $field ) {
7170
- $field = $this->load_field( array(
7171
- 'id' => $field->ID,
7172
- 'name' => $field->post_name,
7173
- 'pod_id' => $field->post_parent
7174
- ), false );
7175
 
7176
- if ( ! empty( $field ) && ( empty( $params->type ) || in_array( $field['type'], $params->type ) ) ) {
7177
- $fields[ $field['id'] ] = $field;
7178
- }
7179
  }
7180
  }
7181
- }
7182
- if ( isset( $cache_key ) ) {
7183
- $this->fields_cache[ $cache_key ] = $fields;
7184
  }
7185
 
7186
- return $fields;
 
 
7187
  }
7188
 
7189
  /**
@@ -7200,59 +8352,29 @@ class PodsAPI {
7200
  * @since 2.0.0
7201
  */
7202
  public function load_object( $params, $strict = false ) {
 
 
 
 
7203
 
7204
- if ( is_object( $params ) && isset( $params->post_title ) ) {
7205
- $_object = get_object_vars( $params );
7206
- } else {
7207
- $params = (object) pods_sanitize( $params );
7208
-
7209
- if ( ! isset( $params->type ) || empty( $params->type ) ) {
7210
- return pods_error( __( 'Object type is required', 'pods' ), $this );
7211
- }
7212
-
7213
- if ( ( ! isset( $params->id ) || empty( $params->id ) ) && ( ! isset( $params->name ) || empty( $params->name ) ) ) {
7214
- return pods_error( __( 'Either Object ID or Name are required', 'pods' ), $this );
7215
- }
7216
-
7217
- /**
7218
- * @var $wpdb wpdb
7219
- */
7220
- global $wpdb;
7221
-
7222
- if ( isset( $params->name ) ) {
7223
- $_object = pods_by_title( $params->name, ARRAY_A, '_pods_' . $params->type, 'publish' );
7224
- } else {
7225
- $object = $params->id;
7226
-
7227
- $_object = get_post( $object, ARRAY_A );
7228
- }
7229
-
7230
- if ( empty( $_object ) ) {
7231
- if ( $strict ) {
7232
- return pods_error( __( 'Object not found', 'pods' ), $this );
7233
- }
7234
-
7235
- return false;
7236
- }
7237
  }
7238
 
7239
- $object = array(
7240
- 'id' => $_object['ID'],
7241
- 'name' => $_object['post_title'],
7242
- 'code' => $_object['post_content'],
7243
- 'type' => str_replace( '_pods_', '', $_object['post_type'] ),
7244
- 'slug' => $_object['post_name']
7245
- );
7246
 
7247
- $object['options'] = get_post_meta( $object['id'] );
7248
 
7249
- foreach ( $object['options'] as $option => &$value ) {
7250
- if ( is_array( $value ) && 1 == count( $value ) ) {
7251
- $value = current( $value );
 
 
 
7252
  }
7253
  }
7254
 
7255
- return $object;
7256
  }
7257
 
7258
  /**
@@ -7271,109 +8393,35 @@ class PodsAPI {
7271
  * @since 2.0.0
7272
  */
7273
  public function load_objects( $params ) {
7274
-
7275
- $params = (object) pods_sanitize( $params );
7276
-
7277
- if ( ! isset( $params->type ) || empty( $params->type ) ) {
7278
- return pods_error( __( 'Pods Object type is required', 'pods' ), $this );
7279
- }
7280
-
7281
- $order = 'ASC';
7282
- $orderby = 'menu_order';
7283
- $limit = - 1;
7284
- $ids = false;
7285
-
7286
- $meta_query = array();
7287
- $cache_key = '';
7288
-
7289
- if ( isset( $params->options ) && ! empty( $params->options ) && is_array( $params->options ) ) {
7290
- foreach ( $params->options as $option => $value ) {
7291
- if ( ! is_array( $value ) ) {
7292
- $value = array( $value );
7293
- }
7294
-
7295
- $value = pods_trim( $value );
7296
-
7297
- sort( $value );
7298
-
7299
- $meta_query[] = array(
7300
- 'key' => $option,
7301
- 'value' => pods_sanitize( $value ),
7302
- 'compare' => 'IN'
7303
- );
7304
- }
7305
  }
7306
 
7307
- if ( isset( $params->where ) && is_array( $params->where ) ) {
7308
- $meta_query = array_merge( $meta_query, (array) $params->where );
7309
- }
7310
-
7311
- if ( isset( $params->order ) && ! empty( $params->order ) && in_array( strtoupper( $params->order ), array(
7312
- 'ASC',
7313
- 'DESC'
7314
- ) ) ) {
7315
- $order = strtoupper( $params->order );
7316
- }
7317
-
7318
- if ( isset( $params->orderby ) && ! empty( $params->orderby ) ) {
7319
- $orderby = strtoupper( $params->orderby );
7320
  }
7321
 
7322
- if ( isset( $params->limit ) && ! empty( $params->limit ) ) {
7323
- $limit = pods_absint( $params->limit );
7324
- }
7325
 
7326
- if ( isset( $params->ids ) && ! empty( $params->ids ) ) {
7327
- $ids = $params->ids;
7328
 
7329
- if ( ! is_array( $ids ) ) {
7330
- $ids = explode( ',', $ids );
7331
- }
7332
- }
7333
 
7334
- if ( empty( $ids ) ) {
7335
- $ids = false;
7336
  }
7337
 
7338
- if ( pods_api_cache() && empty( $meta_query ) && empty( $limit ) && ( empty( $orderby ) || 'menu_order' === $orderby ) && empty( $ids ) ) {
7339
- $cache_key = 'pods_objects_' . $params->type;
 
7340
 
7341
- $the_objects = pods_transient_get( $cache_key );
7342
-
7343
- if ( false !== $the_objects ) {
7344
- return $the_objects;
7345
  }
7346
  }
7347
 
7348
- $the_objects = array();
7349
-
7350
- $args = array(
7351
- 'post_type' => '_pods_' . $params->type,
7352
- 'nopaging' => true,
7353
- 'posts_per_page' => $limit,
7354
- 'order' => $order,
7355
- 'orderby' => $orderby,
7356
- 'meta_query' => $meta_query,
7357
- );
7358
-
7359
- // Only set post__in if there are ids to filter (see https://core.trac.wordpress.org/ticket/28099)
7360
- if ( false !== $ids ) {
7361
- $args['post__in'] = $ids;
7362
- }
7363
-
7364
- $objects = get_posts( $args );
7365
-
7366
- foreach ( $objects as $object ) {
7367
- $object = $this->load_object( $object );
7368
-
7369
- $the_objects[ $object['name'] ] = $object;
7370
- }
7371
-
7372
- if ( pods_api_cache() && ! empty( $cache_key ) ) {
7373
- pods_transient_set( $cache_key, $the_objects );
7374
- }
7375
-
7376
- return $the_objects;
7377
  }
7378
 
7379
  /**
@@ -7390,7 +8438,6 @@ class PodsAPI {
7390
  * @since 1.7.9
7391
  */
7392
  public function load_template( $params ) {
7393
-
7394
  if ( ! class_exists( 'Pods_Templates' ) ) {
7395
  return false;
7396
  }
@@ -7398,6 +8445,12 @@ class PodsAPI {
7398
  $params = (object) $params;
7399
  $params->type = 'template';
7400
 
 
 
 
 
 
 
7401
  return $this->load_object( $params );
7402
  }
7403
 
@@ -7418,7 +8471,6 @@ class PodsAPI {
7418
  * @since 2.0.0
7419
  */
7420
  public function load_templates( $params = null ) {
7421
-
7422
  if ( ! class_exists( 'Pods_Templates' ) ) {
7423
  return array();
7424
  }
@@ -7444,16 +8496,24 @@ class PodsAPI {
7444
  * @since 1.7.9
7445
  */
7446
  public function load_page( $params ) {
7447
-
7448
  if ( ! class_exists( 'Pods_Pages' ) ) {
7449
  return false;
7450
  }
7451
 
7452
  $params = (object) $params;
7453
- if ( ! isset( $params->name ) && isset( $params->uri ) ) {
7454
- $params->name = $params->uri;
 
 
 
 
 
 
 
 
7455
  unset( $params->uri );
7456
  }
 
7457
  $params->type = 'page';
7458
 
7459
  return $this->load_object( $params );
@@ -7476,7 +8536,6 @@ class PodsAPI {
7476
  * @since 2.0.0
7477
  */
7478
  public function load_pages( $params = null ) {
7479
-
7480
  if ( ! class_exists( 'Pods_Pages' ) ) {
7481
  return array();
7482
  }
@@ -7500,17 +8559,11 @@ class PodsAPI {
7500
  * @return array|bool
7501
  *
7502
  * @since 1.7.9
 
 
7503
  */
7504
  public function load_helper( $params ) {
7505
-
7506
- if ( ! class_exists( 'Pods_Helpers' ) ) {
7507
- return false;
7508
- }
7509
-
7510
- $params = (object) $params;
7511
- $params->type = 'helper';
7512
-
7513
- return $this->load_object( $params );
7514
  }
7515
 
7516
  /**
@@ -7528,17 +8581,11 @@ class PodsAPI {
7528
  * @return array
7529
  *
7530
  * @since 2.0.0
 
 
7531
  */
7532
  public function load_helpers( $params = null ) {
7533
-
7534
- if ( ! class_exists( 'Pods_Helpers' ) ) {
7535
- return array();
7536
- }
7537
-
7538
- $params = (object) $params;
7539
- $params->type = 'helper';
7540
-
7541
- return $this->load_objects( $params );
7542
  }
7543
 
7544
  /**
@@ -7605,7 +8652,7 @@ class PodsAPI {
7605
  $params = (object) pods_sanitize( $params );
7606
 
7607
  if ( empty( $pod ) ) {
7608
- $pod = $this->load_pod( array( 'name' => $params->pod, 'table_info' => false ), false );
7609
 
7610
  if ( false === $pod ) {
7611
  return pods_error( __( 'Pod not found', 'pods' ), $this );
@@ -7630,7 +8677,7 @@ class PodsAPI {
7630
  $type = $params->related_pod;
7631
  }
7632
 
7633
- $related_pod = $this->load_pod( array( 'name' => $params->related_pod, 'table_info' => false ), false );
7634
 
7635
  if ( false === $related_pod || ( false !== $type && 'pod' !== $type && $type !== $related_pod['type'] ) ) {
7636
  return pods_error( __( 'Related Pod not found', 'pods' ), $this );
@@ -7644,8 +8691,8 @@ class PodsAPI {
7644
  foreach ( $related_pod['fields'] as $field ) {
7645
  if ( 'pick' === $field['type'] && in_array( $field['pick_object'], array(
7646
  $pod['type'],
7647
- 'pod'
7648
- ) ) && ( $params->pod == $field['pick_object'] || $params->pod == $field['pick_val'] ) ) {
7649
  $sister_fields[ $field['id'] ] = esc_html( $field['label'] . ' (' . $field['name'] . ')' );
7650
  }
7651
  }
@@ -7739,18 +8786,31 @@ class PodsAPI {
7739
  *
7740
  * @since 2.0.0
7741
  */
7742
- public function handle_field_validation( &$value, $field, $object_fields, $fields, $pod, $params ) {
7743
 
7744
  $tableless_field_types = PodsForm::tableless_field_types();
7745
 
7746
- $fields = array_merge( $fields, $object_fields );
7747
 
7748
  $options = $fields[ $field ];
7749
 
7750
- $id = ( is_object( $params ) ? $params->id : ( is_object( $pod ) ? $pod->id() : 0 ) );
 
 
 
 
 
 
 
 
 
 
7751
 
7752
- if ( is_object( $pod ) ) {
 
7753
  $pod = $pod->pod_data;
 
 
7754
  }
7755
 
7756
  $type = $options['type'];
@@ -7758,12 +8818,12 @@ class PodsAPI {
7758
  $label = empty( $label ) ? $field : $label;
7759
 
7760
  // Verify required fields
7761
- if ( 1 == pods_var( 'required', $options['options'], 0 ) && 'slug' !== $type ) {
7762
  if ( '' === $value || null === $value || array() === $value ) {
7763
  return pods_error( sprintf( __( '%s is empty', 'pods' ), $label ), $this );
7764
  }
7765
 
7766
- if ( 'multi' === pods_var( 'pick_format_type', $options['options'] ) && 'autocomplete' !== pods_var( 'pick_format_multi', $options['options'] ) ) {
7767
  $has_value = false;
7768
 
7769
  $check_value = (array) $value;
@@ -7785,12 +8845,12 @@ class PodsAPI {
7785
 
7786
  // @todo move this to after pre-save preparations
7787
  // Verify unique fields
7788
- if ( 1 == pods_var( 'unique', $options['options'], 0 ) && '' !== $value && null !== $value && array() !== $value ) {
7789
  if ( empty( $pod ) ) {
7790
  return false;
7791
  }
7792
 
7793
- if ( ! in_array( $type, $tableless_field_types ) ) {
7794
  $exclude = '';
7795
 
7796
  if ( ! empty( $id ) ) {
@@ -7815,7 +8875,7 @@ class PodsAPI {
7815
  }
7816
  }
7817
 
7818
- $validate = PodsForm::validate( $options['type'], $value, $field, array_merge( $options, pods_var( 'options', $options, array() ) ), $fields, $pod, $id, $params );
7819
 
7820
  $validate = $this->do_hook( 'field_validation', $validate, $value, $field, $object_fields, $fields, $pod, $params );
7821
 
@@ -7837,7 +8897,7 @@ class PodsAPI {
7837
  *
7838
  * @uses pods_query()
7839
  */
7840
- public function lookup_related_items( $field_id, $pod_id, $ids, $field = null, $pod = null ) {
7841
 
7842
  $related_ids = array();
7843
 
@@ -7851,31 +8911,45 @@ class PodsAPI {
7851
 
7852
  $idstring = implode( ',', $ids );
7853
 
7854
- if ( 0 != $pod_id && 0 != $field_id && isset( self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] ) ) {
7855
- // Check cache first, no point in running the same query multiple times
7856
- return self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ];
 
 
 
 
 
 
 
 
7857
  }
7858
 
7859
  $tableless_field_types = PodsForm::tableless_field_types();
7860
 
7861
  $field_type = pods_v( 'type', $field );
7862
 
7863
- if ( empty( $ids ) || ! in_array( $field_type, $tableless_field_types ) ) {
7864
  return array();
7865
  }
7866
 
7867
  $related_pick_limit = 0;
7868
 
7869
  if ( empty( $field ) ) {
7870
- $field = $this->load_field( array( 'id' => $field_id ) );
 
 
 
 
 
 
 
 
7871
  }
7872
 
7873
  if ( ! empty( $field ) ) {
7874
- $options = (array) pods_var_raw( 'options', $field, $field, null, true );
7875
 
7876
- $related_pick_limit = (int) pods_v( $field_type . '_limit', $options, 0 );
7877
-
7878
- if ( 'single' === pods_var_raw( $field_type . '_format_type', $options ) ) {
7879
  $related_pick_limit = 1;
7880
  }
7881
 
@@ -7900,22 +8974,18 @@ class PodsAPI {
7900
  if ( ! is_wp_error( $related ) ) {
7901
  $related_ids = $related;
7902
  }
7903
- } elseif ( ! pods_tableless() ) {
7904
  $ids = implode( ', ', $ids );
7905
 
7906
  $field_id = (int) $field_id;
7907
- $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
7908
-
7909
- $related_where = "
7910
- `field_id` = {$field_id}
7911
- AND `item_id` IN ( {$ids} )
7912
- ";
7913
 
7914
  $sql = "
7915
  SELECT item_id, related_item_id, related_field_id
7916
  FROM `@wp_podsrel`
7917
  WHERE
7918
- {$related_where}
 
7919
  ORDER BY `weight`
7920
  ";
7921
 
@@ -7931,8 +9001,8 @@ class PodsAPI {
7931
  }
7932
  }
7933
  } else {
7934
- if ( ! is_array( $pod ) ) {
7935
- $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
7936
  }
7937
 
7938
  if ( ! empty( $pod ) && in_array( $pod['type'], array(
@@ -7945,7 +9015,7 @@ class PodsAPI {
7945
  ) ) ) {
7946
  $meta_type = $pod['type'];
7947
 
7948
- if ( in_array( $meta_type, array( 'post_type', 'media' ) ) ) {
7949
  $meta_type = 'post';
7950
  } elseif ( 'taxonomy' === $meta_type ) {
7951
  $meta_type = 'term';
@@ -7980,7 +9050,7 @@ class PodsAPI {
7980
  }
7981
  }
7982
  }
7983
- } else {
7984
  $related_id = get_metadata( $meta_type, $id, '_pods_' . $field['name'], true );
7985
 
7986
  if ( empty( $related_id ) ) {
@@ -8022,9 +9092,14 @@ class PodsAPI {
8022
  $related_ids = array_slice( $related_ids, 0, $related_pick_limit );
8023
  }
8024
  }
 
8025
  if ( 0 != $pod_id && 0 != $field_id && ! empty( $related_ids ) ) {
8026
  // Only cache if $pod_id and $field_id were passed
8027
- self::$related_item_cache[ $pod_id ][ $field_id ][ $idstring ] = $related_ids;
 
 
 
 
8028
  }
8029
 
8030
  return $related_ids;
@@ -8060,33 +9135,31 @@ class PodsAPI {
8060
  $related_pick_limit = 0;
8061
 
8062
  if ( ! empty( $field ) ) {
8063
- $options = (array) pods_var_raw( 'options', $field, $field, null, true );
8064
-
8065
- $related_pick_limit = (int) pods_v( 'pick_limit', $options, 0 );
8066
 
8067
- if ( 'single' === pods_var_raw( 'pick_format_type', $options ) ) {
8068
  $related_pick_limit = 1;
8069
  }
8070
  }
8071
 
8072
  if ( ! pods_tableless() ) {
8073
  $field_id = (int) $field_id;
8074
- $sister_id = (int) pods_var_raw( 'sister_id', $field, 0 );
8075
 
8076
- $related_where = "
8077
- `field_id` = {$field_id}
8078
- AND `related_item_id` = {$id}
8079
- ";
8080
 
8081
- $sql = "
8082
- SELECT *
8083
- FROM `@wp_podsrel`
8084
- WHERE
8085
- {$related_where}
8086
- ORDER BY `weight`
8087
- ";
 
 
8088
 
8089
- $relationships = pods_query( $sql );
 
8090
 
8091
  if ( ! empty( $relationships ) ) {
8092
  $related_ids = array();
@@ -8103,8 +9176,8 @@ class PodsAPI {
8103
  // @todo handle meta-based lookups
8104
  return false;
8105
 
8106
- if ( ! is_array( $pod ) ) {
8107
- $pod = $this->load_pod( array( 'id' => $pod_id, 'table_info' => false ), false );
8108
  }
8109
 
8110
  if ( ! empty( $pod ) && in_array( $pod['type'], array(
@@ -8119,7 +9192,7 @@ class PodsAPI {
8119
 
8120
  $meta_type = $pod['type'];
8121
 
8122
- if ( in_array( $meta_type, array( 'post_type', 'media' ) ) ) {
8123
  $meta_type = 'post';
8124
  } elseif ( 'taxonomy' === $meta_type ) {
8125
  $meta_type = 'term';
@@ -8225,7 +9298,10 @@ class PodsAPI {
8225
  $name = $object;
8226
  }
8227
 
8228
- $pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
 
 
 
8229
 
8230
  if ( ! empty( $pod ) ) {
8231
  $object_type = $pod['type'];
@@ -8249,7 +9325,10 @@ class PodsAPI {
8249
  }
8250
 
8251
  if ( ! empty( $name ) ) {
8252
- $pod = $this->load_pod( array( 'name' => $name, 'table_info' => false ), false );
 
 
 
8253
 
8254
  if ( ! empty( $pod ) && ( null === $object_type || $object_type == $pod['type'] ) ) {
8255
  $object_type = $pod['type'];
@@ -8279,8 +9358,8 @@ class PodsAPI {
8279
  $info['meta_table'] = $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object );
8280
  $info['table'] = $info['meta_table'];
8281
 
8282
- if ( is_array( $info['pod'] ) && 'pod' === pods_v( 'type', $info['pod'] ) ) {
8283
- $info['meta_field_value'] = pods_v( 'pod_index', $info['pod']['options'], 'id', true );
8284
  $info['pod_field_index'] = $info['meta_field_value'];
8285
  $info['field_index'] = $info['meta_field_value'];
8286
  $info['meta_field_index'] = $info['meta_field_value'];
@@ -8307,8 +9386,8 @@ class PodsAPI {
8307
  $info['field_slug'] = $slug_field->post_name;
8308
  }
8309
 
8310
- if ( 1 == pods_v( 'hierarchical', $info['pod']['options'], 0 ) ) {
8311
- $parent_field = pods_v( 'pod_parent', $info['pod']['options'], 'id', true );
8312
 
8313
  if ( ! empty( $parent_field ) && isset( $info['pod']['fields'][ $parent_field ] ) ) {
8314
  $info['object_hierarchical'] = true;
@@ -8357,6 +9436,7 @@ class PodsAPI {
8357
  'type' => null,
8358
  'object_name' => $object,
8359
  'object_hierarchical' => false,
 
8360
 
8361
  'table' => $object,
8362
  'meta_table' => $object,
@@ -8394,74 +9474,65 @@ class PodsAPI {
8394
  $object = 'post';
8395
  } elseif ( empty( $object ) && in_array( $object_type, array( 'user', 'media', 'comment' ), true ) ) {
8396
  $object = $object_type;
 
 
 
8397
  }
8398
 
8399
  $pod_name = $pod;
8400
 
8401
- if ( is_array( $pod_name ) ) {
8402
- $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 );
8403
  } else {
8404
  $pod_name = $object;
8405
  }
8406
 
8407
  $field_name = $field;
8408
 
8409
- if ( is_array( $field_name ) ) {
8410
- $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 );
8411
  }
8412
 
8413
- $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
8414
-
8415
- $current_language = false;
8416
- $current_language_t_id = 0;
8417
- $current_language_tt_id = 0;
8418
-
8419
- // Get current language data
8420
- $lang_data = pods_i18n()->get_current_language_data();
8421
-
8422
- if ( $lang_data ) {
8423
- if ( ! empty( $lang_data['language'] ) ) {
8424
- $current_language = $lang_data['language'];
8425
- }
8426
-
8427
- if ( ! empty( $lang_data['t_id'] ) ) {
8428
- $current_language_t_id = $lang_data['t_id'];
8429
- }
8430
-
8431
- if ( ! empty( $lang_data['tt_id'] ) ) {
8432
- $current_language_tt_id = $lang_data['tt_id'];
8433
- }
8434
-
8435
- if ( ! empty( $lang_data['tl_t_id'] ) ) {
8436
- $current_language_tl_t_id = $lang_data['tl_t_id'];
8437
- }
8438
-
8439
- if ( ! empty( $lang_data['tl_tt_id'] ) ) {
8440
- $current_language_tl_tt_id = $lang_data['tl_tt_id'];
8441
- }
8442
- }
8443
 
 
8444
  if ( ! empty( $current_language ) ) {
8445
- $transient = 'pods_' . $wpdb->prefix . '_get_table_info_' . $current_language . '_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
8446
  }
8447
 
8448
  $_info = false;
8449
- $transient_cached = false;
8450
 
8451
- if ( isset( self::$table_info_cache[ $transient ] ) ) {
 
 
 
 
8452
  // Prefer info from the object internal cache
8453
- $_info = self::$table_info_cache[ $transient ];
8454
  } elseif ( pods_api_cache() ) {
8455
- $_info = pods_transient_get( $transient );
8456
- if ( false === $_info && ! did_action( 'init' ) ) {
8457
- $_info = pods_transient_get( $transient . '_pre_init' );
 
8458
  }
8459
- $transient_cached = true;
8460
  }
8461
 
8462
  if ( false !== $_info && is_array( $_info ) ) {
8463
  // Data was cached, use that
8464
  $info = $_info;
 
 
 
 
 
 
 
 
 
 
 
 
 
8465
  } else {
8466
  // Data not cached, load it up
8467
  $_info = $this->get_table_info_load( $object_type, $object, $name, $pod );
@@ -8472,19 +9543,25 @@ class PodsAPI {
8472
  $info = array_merge( $info, $_info );
8473
  }
8474
 
8475
- if ( 0 === strpos( $object_type, 'post_type' ) || 'media' === $object_type || in_array( pods_var_raw( 'type', $info['pod'] ), array(
 
 
 
8476
  'post_type',
8477
- 'media'
8478
- ) ) ) {
 
 
8479
  $info['table'] = $wpdb->posts;
8480
  $info['meta_table'] = $wpdb->postmeta;
 
8481
 
8482
  $info['field_id'] = 'ID';
8483
  $info['field_index'] = 'post_title';
8484
  $info['field_slug'] = 'post_name';
8485
  $info['field_type'] = 'post_type';
8486
  $info['field_parent'] = 'post_parent';
8487
- $info['field_parent_select'] = '`t`.`' . $info['field_parent'] . '`';
8488
 
8489
  $info['meta_field_id'] = 'post_id';
8490
  $info['meta_field_index'] = 'meta_key';
@@ -8510,9 +9587,9 @@ class PodsAPI {
8510
  $post_type = pods_sanitize( ( empty( $object ) ? $name : $object ) );
8511
 
8512
  if ( 'attachment' === $post_type || 'media' === $object_type ) {
8513
- $info['pod_table'] = $wpdb->prefix . 'pods_media';
8514
  } else {
8515
- $info['pod_table'] = $wpdb->prefix . 'pods_' . pods_clean_name( $post_type, true, false );
8516
  }
8517
 
8518
  $post_type_object = get_post_type_object( $post_type );
@@ -8525,9 +9602,7 @@ class PodsAPI {
8525
  $post_status = array( 'publish' );
8526
 
8527
  // Pick field post_status option
8528
- if ( ! empty( $field['options']['pick_post_status'] ) ) {
8529
- $post_status = (array) $field['options']['pick_post_status'];
8530
- } elseif ( ! empty( $field['pick_post_status'] ) ) {
8531
  $post_status = (array) $field['pick_post_status'];
8532
  }
8533
 
@@ -8548,53 +9623,29 @@ class PodsAPI {
8548
  */
8549
  $post_status = apply_filters( 'pods_api_get_table_info_default_post_status', $post_status, $post_type, $info, $object_type, $object, $name, $pod, $field );
8550
 
8551
- $info['where'] = array(
8552
- //'post_status' => '`t`.`post_status` IN ( "inherit", "publish" )', // @todo Figure out what statuses Attachments can be
8553
- 'post_type' => '`t`.`' . $info['field_type'] . '` = "' . $post_type . '"'
8554
- );
8555
 
8556
  if ( 'post_type' === $object_type ) {
8557
- $info['where_default'] = '`t`.`post_status` IN ( "' . implode( '", "', $post_status ) . '" )';
8558
  }
8559
 
8560
- $info['orderby'] = '`t`.`menu_order`, `t`.`' . $info['field_index'] . '`, `t`.`post_date`';
8561
-
8562
- /*
8563
- * @todo wpml-comp Check if WPML filters can be applied afterwards
8564
- */
8565
- // WPML support
8566
- 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' ) ) {
8567
- $info['join']['wpml_translations'] = "
8568
- LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
8569
- ON `wpml_translations`.`element_id` = `t`.`ID`
8570
- AND `wpml_translations`.`element_type` = 'post_{$post_type}'
8571
- AND `wpml_translations`.`language_code` = '{$current_language}'
8572
- ";
8573
-
8574
- $info['join']['wpml_languages'] = "
8575
- LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
8576
- ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
8577
- ";
8578
-
8579
- $info['where']['wpml_languages'] = "`wpml_languages`.`code` IS NOT NULL";
8580
- } elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && ! empty( $current_language ) && function_exists( 'pll_is_translated_post_type' ) && pll_is_translated_post_type( $post_type ) ) {
8581
- // Polylang support
8582
- $info['join']['polylang_languages'] = "
8583
- LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
8584
- ON `polylang_languages`.`object_id` = `t`.`ID`
8585
- AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tt_id}
8586
- ";
8587
-
8588
- $info['where']['polylang_languages'] = "`polylang_languages`.`object_id` IS NOT NULL";
8589
- }
8590
 
8591
  $info['object_fields'] = $this->get_wp_object_fields( $object_type, $info['pod'] );
8592
- } elseif ( 0 === strpos( $object_type, 'taxonomy' ) || in_array( $object_type, array(
 
8593
  'nav_menu',
8594
- 'post_format'
8595
- ) ) || 'taxonomy' === pods_var_raw( 'type', $info['pod'] ) ) {
 
 
 
8596
  $info['table'] = $wpdb->terms;
8597
  $info['meta_table'] = $wpdb->terms;
 
8598
 
8599
  $info['join']['tt'] = "LEFT JOIN `{$wpdb->term_taxonomy}` AS `tt` ON `tt`.`term_id` = `t`.`term_id`";
8600
  $info['join']['tr'] = "LEFT JOIN `{$wpdb->term_relationships}` AS `tr` ON `tr`.`term_taxonomy_id` = `tt`.`term_taxonomy_id`";
@@ -8606,7 +9657,7 @@ class PodsAPI {
8606
  $info['field_slug'] = 'slug';
8607
  $info['field_type'] = 'taxonomy';
8608
  $info['field_parent'] = 'parent';
8609
- $info['field_parent_select'] = '`tt`.`' . $info['field_parent'] . '`';
8610
 
8611
  if ( ! empty( $wpdb->termmeta ) ) {
8612
  $info['meta_table'] = $wpdb->termmeta;
@@ -8631,13 +9682,13 @@ class PodsAPI {
8631
  }
8632
  }
8633
 
8634
- if ( ! in_array( $object_type, array( 'nav_menu', 'post_format' ) ) ) {
8635
  $object_type = 'taxonomy';
8636
  }
8637
 
8638
  $taxonomy = pods_sanitize( ( empty( $object ) ? $name : $object ) );
8639
 
8640
- $info['pod_table'] = $wpdb->prefix . 'pods_' . pods_clean_name( $taxonomy, true, false );
8641
 
8642
  $taxonomy_object = get_taxonomy( $taxonomy );
8643
 
@@ -8645,45 +9696,17 @@ class PodsAPI {
8645
  $info['object_hierarchical'] = true;
8646
  }
8647
 
8648
- $info['where'] = array(
8649
- 'tt.taxonomy' => '`tt`.`' . $info['field_type'] . '` = "' . $taxonomy . '"'
8650
- );
8651
-
8652
- /*
8653
- * @todo wpml-comp WPML API call for is_translated_taxononomy
8654
- * @todo wpml-comp Check if WPML filters can be applied afterwards
8655
- */
8656
- // WPML Support
8657
- if ( is_object( $sitepress ) && ! empty( $current_language ) && $sitepress->is_translated_taxonomy( $taxonomy ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
8658
- $info['join']['wpml_translations'] = "
8659
- LEFT JOIN `{$wpdb->prefix}icl_translations` AS `wpml_translations`
8660
- ON `wpml_translations`.`element_id` = `tt`.`term_taxonomy_id`
8661
- AND `wpml_translations`.`element_type` = 'tax_{$taxonomy}'
8662
- AND `wpml_translations`.`language_code` = '{$current_language}'
8663
- ";
8664
-
8665
- $info['join']['wpml_languages'] = "
8666
- LEFT JOIN `{$wpdb->prefix}icl_languages` AS `wpml_languages`
8667
- ON `wpml_languages`.`code` = `wpml_translations`.`language_code` AND `wpml_languages`.`active` = 1
8668
- ";
8669
-
8670
- $info['where']['wpml_languages'] = "`wpml_languages`.`code` IS NOT NULL";
8671
- } 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 ) ) {
8672
- // Polylang support
8673
- $info['join']['polylang_languages'] = "
8674
- LEFT JOIN `{$wpdb->term_relationships}` AS `polylang_languages`
8675
- ON `polylang_languages`.`object_id` = `t`.`term_id`
8676
- AND `polylang_languages`.`term_taxonomy_id` = {$current_language_tl_tt_id}
8677
- ";
8678
-
8679
- $info['where']['polylang_languages'] = "`polylang_languages`.`object_id` IS NOT NULL";
8680
- }
8681
 
8682
  $info['object_fields'] = $this->get_wp_object_fields( $object_type, $info['pod'] );
8683
- } elseif ( 'user' === $object_type || 'user' === pods_var_raw( 'type', $info['pod'] ) ) {
 
8684
  $info['table'] = $wpdb->users;
8685
  $info['meta_table'] = $wpdb->usermeta;
8686
  $info['pod_table'] = $wpdb->prefix . 'pods_user';
 
8687
 
8688
  $info['field_id'] = 'ID';
8689
  $info['field_index'] = 'display_name';
@@ -8693,17 +9716,15 @@ class PodsAPI {
8693
  $info['meta_field_index'] = 'meta_key';
8694
  $info['meta_field_value'] = 'meta_value';
8695
 
8696
- $info['where'] = array(
8697
- 'user_status' => '`t`.`user_status` = 0'
8698
- );
8699
 
8700
  $info['object_fields'] = $this->get_wp_object_fields( $object_type, $info['pod'] );
8701
- } elseif ( 'comment' === $object_type || 'comment' === pods_var_raw( 'type', $info['pod'] ) ) {
8702
- //$info[ 'object_hierarchical' ] = true;
8703
-
8704
  $info['table'] = $wpdb->comments;
8705
  $info['meta_table'] = $wpdb->commentmeta;
8706
  $info['pod_table'] = $wpdb->prefix . 'pods_comment';
 
8707
 
8708
  $info['field_id'] = 'comment_ID';
8709
  $info['field_index'] = 'comment_date';
@@ -8717,26 +9738,33 @@ class PodsAPI {
8717
 
8718
  $object = 'comment';
8719
 
8720
- $comment_type = ( empty( $object ) ? $name : $object );
8721
 
8722
- $comment_type_clause = '`t`.`' . $info['field_type'] . '` = "' . $comment_type . '"';
8723
 
8724
  if ( 'comment' === $comment_type ) {
8725
- $comment_type_clause = '( ' . $comment_type_clause . ' OR `t`.`' . $info['field_type'] . '` = "" )';
8726
  }
8727
 
8728
- $info['where'] = array(
8729
  'comment_approved' => '`t`.`comment_approved` = 1',
8730
- 'comment_type' => $comment_type_clause
8731
- );
8732
 
8733
- $info['orderby'] = '`t`.`' . $info['field_index'] . '` DESC, `t`.`' . $info['field_id'] . '`';
8734
- } elseif ( in_array( $object_type, array(
 
 
 
8735
  'option',
8736
- 'settings'
8737
- ) ) || 'settings' === pods_var_raw( 'type', $info['pod'] ) ) {
 
 
 
8738
  $info['table'] = $wpdb->options;
8739
  $info['meta_table'] = $wpdb->options;
 
8740
 
8741
  $info['field_id'] = 'option_id';
8742
  $info['field_index'] = 'option_name';
@@ -8745,13 +9773,21 @@ class PodsAPI {
8745
  $info['meta_field_index'] = 'option_name';
8746
  $info['meta_field_value'] = 'option_value';
8747
 
8748
- $info['orderby'] = '`t`.`' . $info['field_index'] . '` ASC';
8749
- } elseif ( is_multisite() && ( in_array( $object_type, array(
 
 
 
8750
  'site_option',
8751
- 'site_settings'
8752
- ) ) || 'site_settings' === pods_var_raw( 'type', $info['pod'] ) ) ) {
 
 
 
 
8753
  $info['table'] = $wpdb->sitemeta;
8754
  $info['meta_table'] = $wpdb->sitemeta;
 
8755
 
8756
  $info['field_id'] = 'site_id';
8757
  $info['field_index'] = 'meta_key';
@@ -8760,10 +9796,12 @@ class PodsAPI {
8760
  $info['meta_field_index'] = 'meta_key';
8761
  $info['meta_field_value'] = 'meta_value';
8762
 
8763
- $info['orderby'] = '`t`.`' . $info['field_index'] . '` ASC';
8764
- } elseif ( is_multisite() && 'network' === $object_type ) { // Network = Site
 
8765
  $info['table'] = $wpdb->site;
8766
  $info['meta_table'] = $wpdb->sitemeta;
 
8767
 
8768
  $info['field_id'] = 'id';
8769
  $info['field_index'] = 'domain';
@@ -8772,40 +9810,68 @@ class PodsAPI {
8772
  $info['meta_field_index'] = 'meta_key';
8773
  $info['meta_field_value'] = 'meta_value';
8774
 
8775
- $info['orderby'] = '`t`.`' . $info['field_index'] . '` ASC, `t`.`path` ASC, `t`.`' . $info['field_id'] . '`';
8776
- } elseif ( is_multisite() && 'site' === $object_type ) { // Site = Blog
8777
- $info['table'] = $wpdb->blogs;
 
 
8778
 
8779
  $info['field_id'] = 'blog_id';
8780
  $info['field_index'] = 'domain';
8781
  $info['field_type'] = 'site_id';
8782
 
8783
- $info['where'] = array(
8784
  'archived' => '`t`.`archived` = 0',
8785
  'spam' => '`t`.`spam` = 0',
8786
  'deleted' => '`t`.`deleted` = 0',
8787
- 'site_id' => '`t`.`' . $info['field_type'] . '` = ' . (int) get_current_site()->id
8788
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8789
 
8790
- $info['orderby'] = '`t`.`' . $info['field_index'] . '` ASC, `t`.`path` ASC, `t`.`' . $info['field_id'] . '`';
8791
- } elseif ( 'table' === $object_type || 'table' === pods_var_raw( 'type', $info['pod'] ) ) {
8792
- $info['table'] = ( empty( $object ) ? $name : $object );
8793
- $info['pod_table'] = $wpdb->prefix . 'pods_' . $info['table'];
8794
 
 
 
 
 
 
 
8795
 
8796
  if ( ! empty( $field ) ) {
8797
- if ( ! is_array( $field ) ) {
 
 
8798
  if ( is_string( $pod ) ) {
8799
  $pod = pods( $pod );
8800
  }
8801
- if ( $pod && ! empty( $pod->fields[ $field ] ) ) {
 
8802
  $field = $pod->fields[ $field ];
8803
  }
8804
  }
8805
- if ( is_array( $field ) ) {
8806
- $info['table'] = pods_var_raw( 'pick_table', pods_var_raw( 'options', $field, $field ) );
8807
- $info['field_id'] = pods_var_raw( 'pick_table_id', pods_var_raw( 'options', $field, $field ) );
8808
- $info['meta_field_value'] = pods_var_raw( 'pick_table_index', pods_var_raw( 'options', $field, $field ) );
 
 
 
8809
  $info['field_index'] = $info['meta_field_value'];
8810
  $info['meta_field_index'] = $info['meta_field_value'];
8811
  }
@@ -8825,37 +9891,49 @@ class PodsAPI {
8825
  $info['meta_field_value'] = pods_clean_name( $info['meta_field_value'], false, false );
8826
 
8827
  if ( empty( $info['orderby'] ) ) {
8828
- $info['orderby'] = '`t`.`' . $info['field_index'] . '`, `t`.`' . $info['field_id'] . '`';
8829
  }
8830
 
8831
- if ( 'table' === pods_var_raw( 'storage', $info['pod'] ) && ! in_array( $object_type, array(
 
 
8832
  'pod',
8833
- 'table'
8834
- ) ) ) {
8835
- $info['join']['d'] = 'LEFT JOIN `' . $info['pod_table'] . '` AS `d` ON `d`.`id` = `t`.`' . $info['field_id'] . '`';
8836
- //$info[ 'select' ] .= ', `d`.*';
8837
  }
8838
 
8839
- if ( ! empty( $info['pod'] ) && is_array( $info['pod'] ) ) {
8840
  $info['recurse'] = true;
 
8841
  }
8842
 
8843
  $info['type'] = $object_type;
8844
  $info['object_name'] = $object;
8845
 
8846
- if ( pods_api_cache() ) {
8847
- if ( ! did_action( 'init' ) ) {
8848
- $transient .= '_pre_init';
8849
- }
8850
 
8851
- if ( !$transient_cached ) {
8852
- pods_transient_set( $transient, $info );
 
 
 
8853
  }
8854
  }
8855
 
8856
- self::$table_info_cache[ $transient ] = apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this );
8857
-
8858
- return self::$table_info_cache[ $transient ];
 
 
 
 
 
 
 
 
 
8859
  }
8860
 
8861
  /**
@@ -8973,7 +10051,7 @@ class PodsAPI {
8973
  $import_data = array( $import_data );
8974
  }
8975
 
8976
- $pod = $this->load_pod( array( 'name' => $this->pod ) );
8977
 
8978
  if ( false === $pod ) {
8979
  return pods_error( __( 'Pod not found', 'pods' ), $this );
@@ -9009,7 +10087,7 @@ class PodsAPI {
9009
  $pick_values = array();
9010
 
9011
  foreach ( $field_values as $pick_value ) {
9012
- if ( in_array( $type, PodsForm::file_field_types() ) || 'media' === $pick_object ) {
9013
  $where = "`guid` = '" . pods_sanitize( $pick_value ) . "'";
9014
 
9015
  if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode ) {
@@ -9027,15 +10105,14 @@ class PodsAPI {
9027
 
9028
  if ( 'pod' === $pick_object ) {
9029
  $related_pod = $this->load_pod( array(
9030
- 'name' => $pick_val,
9031
- 'table_info' => true
9032
  ), false );
9033
  }
9034
 
9035
  if ( empty( $related_pod ) ) {
9036
  $related_pod = array(
9037
  'id' => 0,
9038
- 'type' => $pick_object
9039
  );
9040
  }
9041
 
@@ -9053,7 +10130,7 @@ class PodsAPI {
9053
  }
9054
  } elseif ( in_array( 'post_type', array(
9055
  $pick_object,
9056
- $related_pod['type']
9057
  ) ) || in_array( 'media', array( $pick_object, $related_pod['type'] ) ) ) {
9058
  $where = "`post_title` = '" . pods_sanitize( $pick_value ) . "'";
9059
 
@@ -9086,7 +10163,7 @@ class PodsAPI {
9086
  if ( ! empty( $result ) ) {
9087
  $pick_values[] = $result[0]->id;
9088
  }
9089
- } elseif ( in_array( $pick_object, $simple_tableless_objects ) ) {
9090
  $pick_values[] = $pick_value;
9091
  } elseif ( ! empty( $related_pod['id'] ) ) {
9092
  $where = "`" . $related_pod['field_index'] . "` = '" . pods_sanitize( $pick_value ) . "'";
@@ -9203,15 +10280,12 @@ class PodsAPI {
9203
 
9204
  pods_transient_clear( 'pods' );
9205
  pods_transient_clear( 'pods_components' );
 
9206
 
9207
- if ( null !== $pod && is_array( $pod ) ) {
9208
  pods_transient_clear( 'pods_pod_' . $pod['name'] );
9209
  pods_cache_clear( $pod['name'], 'pods-class' );
9210
 
9211
- foreach ( $pod['fields'] as $field ) {
9212
- pods_transient_clear( 'pods_field_' . $pod['name'] . '_' . $field['name'] );
9213
- }
9214
-
9215
  if ( in_array( $pod['type'], array( 'post_type', 'taxonomy' ) ) ) {
9216
  pods_transient_clear( 'pods_wp_cpt_ct' );
9217
  }
@@ -9219,6 +10293,11 @@ class PodsAPI {
9219
  pods_transient_clear( 'pods_wp_cpt_ct' );
9220
  }
9221
 
 
 
 
 
 
9222
  // Delete transients in the database
9223
  $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_pods%'" );
9224
  $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_timeout_pods%'" );
@@ -9228,7 +10307,7 @@ class PodsAPI {
9228
 
9229
  pods_cache_clear( true );
9230
 
9231
- pods_transient_set( 'pods_flush_rewrites', 1 );
9232
 
9233
  do_action( 'pods_cache_flushed' );
9234
  }
@@ -9251,12 +10330,12 @@ class PodsAPI {
9251
 
9252
  $form = null;
9253
 
9254
- $nonce = pods_var( '_pods_nonce', $params );
9255
- $pod = pods_var( '_pods_pod', $params );
9256
- $id = pods_var( '_pods_id', $params );
9257
- $uri = pods_var( '_pods_uri', $params );
9258
- $form = pods_var( '_pods_form', $params );
9259
- $location = pods_var( '_pods_location', $params );
9260
 
9261
  if ( is_object( $obj ) ) {
9262
  $pod = $obj->pod;
@@ -9295,7 +10374,7 @@ class PodsAPI {
9295
  $data = array();
9296
 
9297
  foreach ( $fields as $field ) {
9298
- $data[ $field ] = pods_var_raw( 'pods_field_' . $field, $params, '' );
9299
  }
9300
 
9301
  $params = array(
@@ -9346,7 +10425,11 @@ class PodsAPI {
9346
  }
9347
 
9348
  /**
9349
- * Handle variables that have been deprecated
 
 
 
 
9350
  *
9351
  * @since 2.0.0
9352
  */
@@ -9354,43 +10437,22 @@ class PodsAPI {
9354
 
9355
  $name = (string) $name;
9356
 
9357
- if ( ! isset( $this->deprecated ) ) {
9358
- require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
9359
- $this->deprecated = new PodsAPI_Deprecated( $this );
9360
- }
9361
-
9362
- $var = null;
9363
-
9364
- if ( isset( $this->deprecated->{$name} ) ) {
9365
- pods_deprecated( "PodsAPI->{$name}", '2.0' );
9366
-
9367
- $var = $this->deprecated->{$name};
9368
- } else {
9369
- pods_deprecated( "PodsAPI->{$name}", '2.0' );
9370
- }
9371
-
9372
- return $var;
9373
- }
9374
-
9375
- /**
9376
- * Handle methods that have been deprecated
9377
- *
9378
- * @since 2.0.0
9379
- */
9380
- public function __call( $name, $args ) {
9381
 
9382
- $name = (string) $name;
 
 
 
9383
 
9384
- if ( ! isset( $this->deprecated ) ) {
9385
- require_once( PODS_DIR . 'deprecated/classes/PodsAPI.php' );
9386
- $this->deprecated = new PodsAPI_Deprecated( $this );
9387
  }
9388
 
9389
- if ( method_exists( $this->deprecated, $name ) ) {
9390
- return call_user_func_array( array( $this->deprecated, $name ), $args );
9391
- } else {
9392
- pods_deprecated( "PodsAPI::{$name}", '2.0' );
9393
- }
9394
  }
9395
 
9396
  /**
@@ -9427,4 +10489,357 @@ class PodsAPI {
9427
 
9428
  }
9429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9430
  }
1
  <?php
2
 
3
+ use Pods\API\Whatsit\Value_Field;
4
+ use Pods\Static_Cache;
5
+ use Pods\Whatsit\Field;
6
+ use Pods\Whatsit\Group;
7
+ use Pods\Whatsit\Object_Field;
8
+ use Pods\Whatsit\Pod;
9
+
10
  /**
11
  * @package Pods
12
  */
15
  /**
16
  * @var PodsAPI
17
  */
18
+ public static $instance = null;
19
 
20
  /**
21
  * @var array PodsAPI
22
  */
23
+ public static $instances = array();
24
 
25
  /**
26
  * @var bool
28
  public $display_errors = false;
29
 
30
  /**
31
+ * @var array|bool|mixed|null
32
  */
33
  public $pod_data;
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  /**
36
  * @var
37
  * @deprecated 2.0.0
43
  */
44
  private $deprecated;
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  /**
47
  * Singleton-ish handling for a basic pods_api() request
48
  *
54
  * @since 2.3.5
55
  */
56
  public static function init( $pod = null, $format = null ) {
 
57
  if ( null !== $pod || null !== $format ) {
58
  if ( ! isset( self::$instances[ $pod ] ) ) {
59
  // Cache API singleton per Pod
61
  }
62
 
63
  return self::$instances[ $pod ];
64
+ }
65
+
66
+ if ( ! is_object( self::$instance ) ) {
67
  self::$instance = new PodsAPI();
68
  }
69
 
82
  * @since 1.7.1
83
  */
84
  public function __construct( $pod = null, $format = null ) {
85
+ if ( null === $pod || '' === (string) $pod ) {
86
+ return;
87
+ }
88
 
89
+ $pod = pods_clean_name( $pod );
90
+ $pod = $this->load_pod( [ 'name' => $pod ] );
 
 
 
 
 
 
 
 
91
 
92
+ if ( ! empty( $pod ) ) {
93
+ $this->pod_data = $pod;
 
 
 
 
94
  }
95
  }
96
 
103
  * @param bool $strict (optional) Decides whether the previous saved meta should be deleted or not
104
  * @param bool $sanitized (optional) Will unsanitize the data, should be passed if the data is sanitized before
105
  * sending.
106
+ * @param array $fields (optional) The array of fields and their options, for further processing with.
107
  *
108
+ * @return int|string|false The object ID after saving, false if not saved.
109
  *
110
  * @since 2.0.0
111
  */
112
+ public function save_wp_object( $object_type, $data, $meta = [], $strict = false, $sanitized = false, $fields = [] ) {
113
+ if ( in_array( $object_type, [ 'post_type', 'media' ], true ) ) {
 
114
  $object_type = 'post';
115
+ } elseif ( 'taxonomy' === $object_type ) {
 
 
116
  $object_type = 'term';
117
  }
118
 
 
 
119
  if ( $sanitized ) {
120
  $data = pods_unsanitize( $data );
121
  $meta = pods_unsanitize( $meta );
122
  }
123
 
124
+ if ( in_array( $object_type, [ 'post', 'term', 'user', 'comment' ], true ) ) {
125
+ return call_user_func( [ $this, 'save_' . $object_type ], $data, $meta, $strict, false, $fields );
126
  } elseif ( 'settings' === $object_type ) {
127
  // Nothing to save
128
  if ( empty( $meta ) ) {
129
  return true;
130
  }
131
 
132
+ return $this->save_setting( pods_v( 'option_id', $data ), $meta, false );
133
  }
134
 
135
+ /**
136
+ * Allow hooking in to support saving for custom object types.
137
+ *
138
+ * @since 2.8.0
139
+ *
140
+ * @param int|string|false $object_id The object ID after saving, false if not saved.
141
+ * @param string $object_type The custom object type.
142
+ * @param array $data All object data to be saved
143
+ * @param array $meta Associative array of meta keys and values.
144
+ * @param bool $strict Decides whether the previous saved meta should be deleted or not.
145
+ * @param bool $sanitized Will unsanitize the data, should be passed if the data is sanitized before sending.
146
+ * @param array $fields The array of fields and their options, for further processing with.
147
+ */
148
+ $object_id = apply_filters( 'pods_api_save_wp_object_for_custom_object_type', false, $object_type, $data, $meta, $strict, $sanitized, $fields );
149
+
150
+ if ( false === $object_id ) {
151
+ return $object_id;
152
+ }
153
+
154
+ /**
155
+ * Allow hooking in to support saving meta using the meta fallback.
156
+ *
157
+ * @since 2.8.0
158
+ *
159
+ * @param bool $use_meta_fallback Whether to support saving meta using the meta fallback.
160
+ * @param string $object_type The custom object type.
161
+ * @param array $data All object data to be saved
162
+ * @param array $meta Associative array of meta keys and values.
163
+ * @param bool $strict Decides whether the previous saved meta should be deleted or not.
164
+ * @param bool $sanitized Will unsanitize the data, should be passed if the data is sanitized before sending.
165
+ * @param array $fields The array of fields and their options, for further processing with.
166
+ */
167
+ $use_meta_fallback = apply_filters( 'pods_api_save_wp_object_use_meta_fallback', false, $object_type, $data, $meta, $strict, $sanitized, $fields );
168
+
169
+ // Maybe use meta fallback for saving.
170
+ if ( $use_meta_fallback ) {
171
+ foreach ( $meta as $meta_key => $meta_value ) {
172
+ update_metadata( $object_type, $object_id, $meta_key, $meta_value );
173
+ }
174
+ }
175
+
176
+ return $object_id;
177
  }
178
 
179
  /**
189
  */
190
  public function delete_wp_object( $object_type, $id, $force_delete = true ) {
191
 
192
+ if ( in_array( $object_type, array( 'post_type', 'media' ), true ) ) {
193
  $object_type = 'post';
194
  }
195
 
201
  return false;
202
  }
203
 
204
+ if ( in_array( $object_type, array( 'post' ), true ) ) {
205
  return wp_delete_post( $id, $force_delete );
206
  }
207
 
222
  * sending.
223
  * @param array $fields (optional) The array of fields and their options, for further processing with
224
  *
225
+ * @return mixed
226
  *
227
  * @since 2.0.0
228
  */
235
  }
236
 
237
  if ( ! is_array( $post_data ) || empty( $post_data ) ) {
238
+ $post_data = [
239
+ 'post_title' => '',
240
+ ];
241
  }
242
 
243
  if ( ! is_array( $post_meta ) ) {
308
  $meta = get_post_meta( $id );
309
 
310
  foreach ( $meta as $k => $value ) {
311
+ if ( is_array( $value ) && 1 === count( $value ) ) {
312
  $meta[ $k ] = current( $value );
313
  }
314
  }
332
  if ( isset( $fields[ $meta_key ] ) ) {
333
  $field_data = $fields[ $meta_key ];
334
 
335
+ $simple = ( 'pick' === pods_v( 'type', $field_data ) && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects, true ) );
336
  }
337
 
338
  if ( $simple ) {
488
  if ( isset( $fields[ $meta_key ] ) ) {
489
  $field_data = $fields[ $meta_key ];
490
 
491
+ $simple = ( 'pick' === $field_data['type'] && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects ) );
492
  }
493
 
494
  if ( $simple ) {
692
  $conflicted = pods_no_conflict_check( 'taxonomy' );
693
 
694
  if ( ! is_array( $term_data ) || empty( $term_data ) ) {
695
+ $term_data = [
696
+ 'name' => '',
697
+ ];
698
  }
699
 
700
  if ( ! $conflicted ) {
715
  unset( $term_data['taxonomy'] );
716
 
717
  if ( empty( $term_data['term_id'] ) ) {
718
+ $term_name = '';
719
 
720
+ if ( ! empty( $term_data['name'] ) ) {
721
+ $term_name = $term_data['name'];
722
+
723
+ unset( $term_data['name'] );
724
+ }
725
 
726
  $term_data['term_id'] = wp_insert_term( $term_name, $taxonomy, $term_data );
727
  } elseif ( 1 < count( $term_data ) ) {
811
  if ( isset( $fields[ $meta_key ] ) ) {
812
  $field_data = $fields[ $meta_key ];
813
 
814
+ $simple = ( 'pick' === pods_v( 'type', $field_data ) && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects, true ) );
815
  }
816
 
817
  if ( $simple ) {
950
  */
951
  public function get_wp_object_fields( $object = 'post_type', $pod = null, $refresh = false ) {
952
 
953
+ $pod_name = pods_v( 'name', $pod, $object, true );
954
 
955
  if ( 'media' === $pod_name ) {
956
  $object = 'post_type';
967
  return $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
968
  }
969
 
970
+ $fields = [];
971
 
972
  if ( 'post_type' === $object ) {
973
+ $fields = [
974
+ 'ID' => [
975
+ 'name' => 'ID',
976
+ 'label' => 'ID',
977
+ 'type' => 'number',
978
+ 'alias' => [ 'id' ],
979
+ 'options' => [
980
+ 'number_format' => '9999.99',
981
+ ],
982
+ 'hide_in_default_form' => true,
983
+ ],
984
+ 'post_title' => [
985
  'name' => 'post_title',
986
  'label' => 'Title',
987
  'type' => 'text',
988
+ 'alias' => [ 'title', 'name' ],
989
+ 'options' => [
990
  'display_filter' => 'the_title',
991
+ 'display_filter_args' => [ 'post_ID' ],
992
+ ],
993
+ ],
994
+ 'post_content' => [
995
  'name' => 'post_content',
996
  'label' => 'Content',
997
  'type' => 'wysiwyg',
998
+ 'alias' => [ 'content' ],
999
+ 'options' => [
1000
  'wysiwyg_allowed_html_tags' => '',
1001
  'display_filter' => 'the_content',
1002
+ 'pre_save' => 0,
1003
+ ],
1004
+ ],
1005
+ 'post_excerpt' => [
1006
  'name' => 'post_excerpt',
1007
  'label' => 'Excerpt',
1008
  'type' => 'paragraph',
1009
+ 'alias' => [ 'excerpt' ],
1010
+ 'options' => [
1011
  'paragraph_allow_html' => 1,
1012
  'paragraph_allowed_html_tags' => '',
1013
  'display_filter' => 'the_excerpt',
1014
+ 'pre_save' => 0,
1015
+ ],
1016
+ ],
1017
+ 'post_author' => [
1018
  'name' => 'post_author',
1019
  'label' => 'Author',
1020
  'type' => 'pick',
1021
+ 'alias' => [ 'author' ],
1022
  'pick_object' => 'user',
1023
+ 'options' => [
1024
  'pick_format_type' => 'single',
1025
  'pick_format_single' => 'autocomplete',
1026
+ 'default_value' => '{@user.ID}',
1027
+ ],
1028
+ ],
1029
+ 'post_date' => [
1030
  'name' => 'post_date',
1031
  'label' => 'Publish Date',
1032
  'type' => 'datetime',
1033
+ 'alias' => [ 'created', 'date' ],
1034
+ ],
1035
+ 'post_date_gmt' => [
1036
+ 'name' => 'post_date_gmt',
1037
+ 'label' => 'Publish Date (GMT)',
1038
+ 'type' => 'datetime',
1039
+ 'alias' => [],
1040
+ 'hidden' => true,
1041
+ 'hide_in_default_form' => true,
1042
+ ],
1043
+ 'post_status' => [
1044
  'name' => 'post_status',
1045
  'label' => 'Status',
1046
  'type' => 'pick',
1047
  'pick_object' => 'post-status',
1048
+ 'default' => $this->do_hook( 'default_status_' . $pod_name, pods_v( 'default_status', pods_v( 'options', $pod ), 'draft', true ), $pod ),
1049
+ 'alias' => [ 'status' ],
1050
+ ],
1051
+ 'comment_status' => [
1052
  'name' => 'comment_status',
1053
  'label' => 'Comment Status',
1054
  'type' => 'text',
1055
  'default' => get_option( 'default_comment_status', 'open' ),
1056
+ 'alias' => [],
1057
+ 'data' => [
1058
  'open' => __( 'Open', 'pods' ),
1059
+ 'closed' => __( 'Closed', 'pods' ),
1060
+ ],
1061
+ ],
1062
+ 'ping_status' => [
1063
+ 'name' => 'ping_status',
1064
+ 'label' => 'Ping Status',
1065
+ 'default' => get_option( 'default_ping_status', 'open' ),
1066
+ 'type' => 'text',
1067
+ 'alias' => [],
1068
+ 'data' => [
1069
  'open' => __( 'Open', 'pods' ),
1070
+ 'closed' => __( 'Closed', 'pods' ),
1071
+ ],
1072
+ 'hide_in_default_form' => true,
1073
+ ],
1074
+ 'post_password' => [
1075
  'name' => 'post_password',
1076
  'label' => 'Password',
1077
  'type' => 'password',
1078
+ 'alias' => [],
1079
+ ],
1080
+ 'post_name' => [
1081
  'name' => 'post_name',
1082
  'label' => 'Permalink',
1083
  'type' => 'slug',
1084
+ 'alias' => [ 'slug', 'permalink' ],
1085
+ ],
1086
+ 'to_ping' => [
1087
+ 'name' => 'to_ping',
1088
+ 'label' => 'To Ping',
1089
+ 'type' => 'text',
1090
+ 'alias' => [],
1091
+ 'hidden' => true,
1092
+ 'hide_in_default_form' => true,
1093
+ ],
1094
+ 'pinged' => [
1095
+ 'name' => 'pinged',
1096
+ 'label' => 'Pinged',
1097
+ 'type' => 'text',
1098
+ 'alias' => [],
1099
+ 'hidden' => true,
1100
+ 'hide_in_default_form' => true,
1101
+ ],
1102
+ 'post_modified' => [
1103
+ 'name' => 'post_modified',
1104
+ 'label' => 'Last Modified Date',
1105
+ 'type' => 'datetime',
1106
+ 'alias' => [ 'modified' ],
1107
+ 'hidden' => true,
1108
+ 'hide_in_default_form' => true,
1109
+ ],
1110
+ 'post_modified_gmt' => [
1111
+ 'name' => 'post_modified_gmt',
1112
+ 'label' => 'Last Modified Date (GMT)',
1113
+ 'type' => 'datetime',
1114
+ 'alias' => [],
1115
+ 'hidden' => true,
1116
+ 'hide_in_default_form' => true,
1117
+ ],
1118
+ 'post_content_filtered' => [
1119
+ 'name' => 'post_content_filtered',
1120
+ 'label' => 'Content (filtered)',
1121
+ 'type' => 'paragraph',
1122
+ 'alias' => [],
1123
+ 'hidden' => true,
1124
+ 'options' => [
1125
  'paragraph_allow_html' => 1,
1126
  'paragraph_oembed' => 1,
1127
  'paragraph_wptexturize' => 1,
1128
  'paragraph_convert_chars' => 1,
1129
  'paragraph_wpautop' => 1,
1130
  'paragraph_allow_shortcode' => 1,
1131
+ 'paragraph_allowed_html_tags' => '',
1132
+ ],
1133
+ 'hide_in_default_form' => true,
1134
+ ],
1135
+ 'post_parent' => [
1136
  'name' => 'post_parent',
1137
  'label' => 'Parent',
1138
  'type' => 'pick',
1139
  'pick_object' => 'post_type',
1140
  'pick_val' => '__current__',
1141
+ 'alias' => [ 'parent' ],
1142
+ 'data' => [],
1143
+ 'hidden' => true,
1144
+ ],
1145
+ 'guid' => [
1146
+ 'name' => 'guid',
1147
+ 'label' => 'GUID',
1148
+ 'type' => 'text',
1149
+ 'alias' => [],
1150
+ 'hidden' => true,
1151
+ 'hide_in_default_form' => true,
1152
+ ],
1153
+ 'menu_order' => [
1154
  'name' => 'menu_order',
1155
  'label' => 'Menu Order',
1156
  'type' => 'number',
1157
+ 'alias' => [],
1158
+ 'options' => [
1159
+ 'number_format' => '9999.99',
1160
+ ],
1161
+ ],
1162
+ 'post_type' => [
1163
+ 'name' => 'post_type',
1164
+ 'label' => 'Type',
1165
+ 'type' => 'text',
1166
+ 'alias' => [ 'type' ],
1167
+ 'hidden' => true,
1168
+ 'hide_in_default_form' => true,
1169
+ ],
1170
+ 'post_mime_type' => [
1171
+ 'name' => 'post_mime_type',
1172
+ 'label' => 'Mime Type',
1173
+ 'type' => 'text',
1174
+ 'alias' => [],
1175
+ 'hidden' => true,
1176
+ 'hide_in_default_form' => true,
1177
+ ],
1178
+ 'comment_count' => [
1179
+ 'name' => 'comment_count',
1180
+ 'label' => 'Comment Count',
1181
+ 'type' => 'number',
1182
+ 'alias' => [],
1183
+ 'hidden' => true,
1184
+ 'hide_in_default_form' => true,
1185
+ ],
1186
+ 'comments' => [
1187
+ 'name' => 'comments',
1188
+ 'label' => 'Comments',
1189
+ 'type' => 'comment',
1190
+ 'pick_object' => 'comment',
1191
+ 'pick_val' => 'comment',
1192
+ 'alias' => [],
1193
+ 'hidden' => true,
1194
+ 'options' => [
1195
+ 'comment_format_type' => 'multi',
1196
+ ],
1197
+ 'hide_in_default_form' => true,
1198
+ ],
1199
+ ];
1200
 
1201
  if ( ! empty( $pod ) ) {
1202
  $taxonomies = get_object_taxonomies( $pod_name, 'objects' );
1203
 
1204
  foreach ( $taxonomies as $taxonomy ) {
1205
+ $fields[ $taxonomy->name ] = [
1206
  'name' => $taxonomy->name,
1207
  'label' => $taxonomy->labels->name,
1208
  'type' => 'taxonomy',
1209
  'pick_object' => 'taxonomy',
1210
  'pick_val' => $taxonomy->name,
1211
+ 'alias' => [],
1212
  'hidden' => true,
1213
+ 'options' => [
1214
+ 'taxonomy_format_type' => 'multi',
1215
+ ],
1216
+ ];
1217
  }
1218
  }
1219
  } elseif ( 'user' === $object ) {
1220
+ $fields = [
1221
+ 'ID' => [
1222
+ 'name' => 'ID',
1223
+ 'label' => 'ID',
1224
+ 'type' => 'number',
1225
+ 'alias' => [ 'id' ],
1226
+ 'options' => [
1227
+ 'number_format' => '9999.99',
1228
+ ],
1229
+ 'hide_in_default_form' => true,
1230
+ ],
1231
+ 'user_login' => [
1232
  'name' => 'user_login',
1233
  'label' => 'Title',
1234
  'type' => 'text',
1235
+ 'alias' => [ 'login' ],
1236
+ 'options' => [
1237
+ 'required' => 1,
1238
+ ],
1239
+ ],
1240
+ 'user_nicename' => [
1241
  'name' => 'user_nicename',
1242
  'label' => 'Permalink',
1243
  'type' => 'slug',
1244
+ 'alias' => [ 'nicename', 'slug', 'permalink' ],
1245
+ ],
1246
+ 'display_name' => [
1247
  'name' => 'display_name',
1248
  'label' => 'Display Name',
1249
  'type' => 'text',
1250
+ 'alias' => [ 'title', 'name' ],
1251
+ ],
1252
+ 'user_pass' => [
1253
  'name' => 'user_pass',
1254
  'label' => 'Password',
1255
  'type' => 'text',
1256
+ 'alias' => [ 'password', 'pass' ],
1257
+ 'options' => [
1258
  'required' => 1,
1259
+ 'text_format_type' => 'password',
1260
+ ],
1261
+ ],
1262
+ 'user_email' => [
1263
  'name' => 'user_email',
1264
  'label' => 'E-mail',
1265
  'type' => 'text',
1266
+ 'alias' => [ 'email' ],
1267
+ 'options' => [
1268
  'required' => 1,
1269
+ 'text_format_type' => 'email',
1270
+ ],
1271
+ ],
1272
+ 'user_url' => [
1273
  'name' => 'user_url',
1274
  'label' => 'URL',
1275
  'type' => 'text',
1276
+ 'alias' => [ 'url', 'website' ],
1277
+ 'options' => [
1278
  'required' => 0,
1279
  'text_format_type' => 'website',
1280
+ 'text_format_website' => 'normal',
1281
+ ],
1282
+ ],
1283
+ 'user_registered' => [
1284
+ 'name' => 'user_registered',
1285
+ 'label' => 'Registration Date',
1286
+ 'type' => 'date',
1287
+ 'alias' => [ 'created', 'date', 'registered' ],
1288
+ 'options' => [
1289
+ 'date_format_type' => 'datetime',
1290
+ ],
1291
+ 'hidden' => true,
1292
+ 'hide_in_default_form' => true,
1293
+ ],
1294
+ ];
1295
  } elseif ( 'comment' === $object ) {
1296
+ $fields = [
1297
+ 'comment_ID' => [
1298
+ 'name' => 'comment_ID',
1299
+ 'label' => 'ID',
1300
+ 'type' => 'number',
1301
+ 'alias' => [ 'id', 'ID', 'comment_id' ],
1302
+ 'options' => [
1303
+ 'number_format' => '9999.99',
1304
+ ],
1305
+ 'hide_in_default_form' => true,
1306
+ ],
1307
+ 'comment_content' => [
1308
  'name' => 'comment_content',
1309
  'label' => 'Content',
1310
  'type' => 'wysiwyg',
1311
+ 'alias' => [ 'content' ],
1312
+ ],
1313
+ 'comment_approved' => [
1314
  'name' => 'comment_approved',
1315
  'label' => 'Approved',
1316
  'type' => 'number',
1317
+ 'alias' => [ 'approved' ],
1318
+ 'options' => [
1319
+ 'number_format' => '9999.99',
1320
+ ],
1321
+ ],
1322
+ 'comment_post_ID' => [
1323
  'name' => 'comment_post_ID',
1324
  'label' => 'Post',
1325
  'type' => 'pick',
1326
+ 'alias' => [ 'post', 'post_id' ],
1327
+ 'data' => [],
1328
+ ],
1329
+ 'user_id' => [
1330
  'name' => 'user_id',
1331
  'label' => 'Author',
1332
  'type' => 'pick',
1333
+ 'alias' => [ 'author' ],
1334
  'pick_object' => 'user',
1335
+ 'data' => [],
1336
+ ],
1337
+ 'comment_date' => [
1338
  'name' => 'comment_date',
1339
  'label' => 'Date',
1340
  'type' => 'date',
1341
+ 'alias' => [ 'created', 'date' ],
1342
+ 'options' => [
1343
+ 'date_format_type' => 'datetime',
1344
+ ],
1345
+ ],
1346
+ 'comment_author' => [
1347
  'name' => 'comment_author',
1348
  'label' => 'Author',
1349
  'type' => 'text',
1350
+ 'alias' => [ 'author' ],
1351
+ ],
1352
+ 'comment_author_email' => [
1353
  'name' => 'comment_author_email',
1354
  'label' => 'Author E-mail',
1355
  'type' => 'email',
1356
+ 'alias' => [ 'author_email' ],
1357
+ ],
1358
+ 'comment_author_url' => [
1359
  'name' => 'comment_author_url',
1360
  'label' => 'Author URL',
1361
  'type' => 'text',
1362
+ 'alias' => [ 'author_url' ],
1363
+ ],
1364
+ 'comment_author_IP' => [
1365
+ 'name' => 'comment_author_IP',
1366
+ 'label' => 'Author IP',
1367
+ 'type' => 'text',
1368
+ 'alias' => [ 'author_IP' ],
1369
+ 'hide_in_default_form' => true,
1370
+ ],
1371
+ 'comment_type' => [
1372
+ 'name' => 'comment_type',
1373
+ 'label' => 'Type',
1374
+ 'type' => 'text',
1375
+ 'alias' => [ 'type' ],
1376
+ 'hidden' => true,
1377
+ 'hide_in_default_form' => true,
1378
+ ],
1379
+ 'comment_parent' => [
1380
+ 'name' => 'comment_parent',
1381
+ 'label' => 'Parent',
1382
+ 'type' => 'pick',
1383
+ 'pick_object' => 'comment',
1384
+ 'pick_val' => '__current__',
1385
+ 'alias' => [ 'parent' ],
1386
+ 'data' => [],
1387
+ 'hidden' => true,
1388
+ 'hide_in_default_form' => true,
1389
+ ],
1390
+ ];
1391
  } elseif ( 'taxonomy' === $object ) {
1392
+ $fields = [
1393
+ 'term_id' => [
1394
+ 'name' => 'term_id',
1395
+ 'label' => 'ID',
1396
+ 'type' => 'number',
1397
+ 'alias' => [ 'id', 'ID' ],
1398
+ 'options' => [
1399
+ 'number_format' => '9999.99',
1400
+ ],
1401
+ 'hide_in_default_form' => true,
1402
+ ],
1403
+ 'name' => [
1404
  'name' => 'name',
1405
  'label' => 'Title',
1406
  'type' => 'text',
1407
+ 'alias' => [ 'title' ],
1408
+ ],
1409
+ 'slug' => [
1410
  'name' => 'slug',
1411
  'label' => 'Permalink',
1412
  'type' => 'slug',
1413
+ 'alias' => [ 'permalink' ],
1414
+ ],
1415
+ 'description' => [
1416
  'name' => 'description',
1417
  'label' => 'Description',
1418
  'type' => 'wysiwyg',
1419
+ 'alias' => [ 'content' ],
1420
+ ],
1421
+ 'taxonomy' => [
1422
  'name' => 'taxonomy',
1423
  'label' => 'Taxonomy',
1424
  'type' => 'text',
1425
+ 'alias' => [],
1426
+ ],
1427
+ 'parent' => [
1428
  'name' => 'parent',
1429
  'label' => 'Parent',
1430
  'type' => 'pick',
1431
  'pick_object' => 'taxonomy',
1432
  'pick_val' => '__current__',
1433
+ 'alias' => [ 'parent' ],
1434
+ 'data' => [],
1435
+ 'hidden' => true,
1436
+ ],
1437
+ 'term_taxonomy_id' => [
1438
+ 'name' => 'term_taxonomy_id',
1439
+ 'label' => 'Term Taxonomy ID',
1440
+ 'type' => 'number',
1441
+ 'alias' => [],
1442
+ 'hidden' => true,
1443
+ 'options' => [
1444
+ 'number_format' => '9999.99',
1445
+ ],
1446
+ 'hide_in_default_form' => true,
1447
+ ],
1448
+ 'term_group' => [
1449
+ 'name' => 'term_group',
1450
+ 'label' => 'Term Group',
1451
+ 'type' => 'number',
1452
+ 'alias' => [ 'group' ],
1453
+ 'hidden' => true,
1454
+ 'options' => [
1455
+ 'number_format' => '9999.99',
1456
+ ],
1457
+ 'hide_in_default_form' => true,
1458
+ ],
1459
+ 'count' => [
1460
+ 'name' => 'count',
1461
+ 'label' => 'Count',
1462
+ 'type' => 'number',
1463
+ 'alias' => [],
1464
+ 'hidden' => true,
1465
+ 'options' => [
1466
+ 'number_format' => '9999.99',
1467
+ ],
1468
+ 'hide_in_default_form' => true,
1469
+ ],
1470
+ ];
1471
+ } elseif ( 'pod' === $object ) {
1472
+ $fields = [
1473
+ 'id' => [
1474
+ 'name' => 'id',
1475
+ 'label' => 'ID',
1476
+ 'type' => 'number',
1477
+ 'alias' => [ 'ID' ],
1478
+ 'options' => [
1479
+ 'number_format' => '9999.99',
1480
+ ],
1481
+ 'hide_in_default_form' => true,
1482
+ ],
1483
+ ];
1484
  }
1485
 
1486
  $fields = $this->do_hook( 'get_wp_object_fields', $fields, $object, $pod );
1502
  $fields = PodsForm::fields_setup( $fields );
1503
 
1504
  if ( did_action( 'init' ) && pods_api_cache() ) {
1505
+ pods_transient_set( trim( 'pods_api_object_fields_' . $object . $pod_name . '_', '_' ), $fields, WEEK_IN_SECONDS );
1506
  }
1507
 
1508
  return $fields;
1521
  * $params['create_label_singular'] string Singular Label (for Creating)
1522
  * $params['create_storage'] string Storage Type (for Creating Post Types)
1523
  * $params['create_storage_taxonomy'] string Storage Type (for Creating Taxonomies)
1524
+ * $params['create_rest_api'] int Whether REST API will be enabled (for Creating Post Types and Taxonomies)
1525
  * $params['extend_pod_type'] string Pod Type (for Extending)
1526
  * $params['extend_post_type'] string Post Type (for Extending Post Types)
1527
  * $params['extend_taxonomy'] string Taxonomy (for Extending Taxonomies)
1543
  'create_label_plural' => '',
1544
  'create_storage' => 'meta',
1545
  'create_storage_taxonomy' => '',
1546
+ 'create_rest_api' => 1,
1547
 
1548
  'create_setting_name' => '',
1549
  'create_label_title' => '',
1558
  'extend_storage_taxonomy' => '',
1559
  );
1560
 
1561
+ if( ! function_exists( 'get_term_meta' ) ) {
1562
  $defaults['create_storage_taxonomy'] = 'none';
1563
  $defaults['extend_storage_taxonomy' ] = 'table' ;
1564
  }
1586
  $label = $params->create_label_singular;
1587
  }
1588
 
1589
+ $pod_params['name'] = $params->create_name;
1590
+ $pod_params['label'] = ( ! empty( $params->create_label_plural ) ? $params->create_label_plural : $label );
1591
+ $pod_params['type'] = $params->create_pod_type;
1592
+ $pod_params['label_singular'] = ( ! empty( $params->create_label_singular ) ? $params->create_label_singular : $pod_params['label'] );
1593
+ $pod_params['public'] = 1;
1594
+ $pod_params['show_ui'] = 1;
 
 
1595
 
1596
  // Auto-generate name if not provided
1597
+ if ( empty( $pod_params['name'] ) && ! empty( $pod_params['label_singular'] ) ) {
1598
+ $pod_params['name'] = pods_clean_name( $pod_params['label_singular'] );
1599
  }
1600
 
1601
  if ( 'post_type' === $pod_params['type'] ) {
1608
  if ( pods_tableless() ) {
1609
  $pod_params['storage'] = 'meta';
1610
  }
1611
+
1612
+ $pod_params['rest_enable'] = 1 === (int) $params->create_rest_api ? 1 : 0;
1613
  } elseif ( 'taxonomy' === $pod_params['type'] ) {
1614
  if ( empty( $pod_params['name'] ) ) {
1615
  return pods_error( __( 'Please enter a Name for this Pod', 'pods' ), $this );
1625
  $pod_params['storage'] = ( function_exists( 'get_term_meta' ) ? 'meta' : 'none' );
1626
  }
1627
 
1628
+ $pod_params['hierarchical'] = 1;
1629
+
1630
+ $pod_params['rest_enable'] = 1 === (int) $params->create_rest_api ? 1 : 0;
1631
  } elseif ( 'pod' === $pod_params['type'] ) {
1632
  if ( empty( $pod_params['name'] ) ) {
1633
  return pods_error( __( 'Please enter a Name for this Pod', 'pod' ), $this );
1638
  $pod_params['storage'] = 'meta';
1639
  }
1640
  } elseif ( 'settings' === $pod_params['type'] ) {
1641
+ $pod_params['name'] = $params->create_setting_name;
1642
+ $pod_params['label'] = ( ! empty( $params->create_label_title ) ? $params->create_label_title : ucwords( str_replace( '_', ' ', $params->create_setting_name ) ) );
1643
+ $pod_params['menu_name'] = ( ! empty( $params->create_label_menu ) ? $params->create_label_menu : $pod_params['label'] );
1644
+ $pod_params['menu_location'] = $params->create_menu_location;
1645
+ $pod_params['storage'] = 'none';
 
 
1646
 
1647
  // Auto-generate name if not provided
1648
  if ( empty( $pod_params['name'] ) && ! empty( $pod_params['label'] ) ) {
1701
  return pods_error( sprintf( __( 'Post Type %s already exists, try extending it instead', 'pods' ), $pod_params['name'] ), $this );
1702
  }
1703
 
1704
+ $pod_params['supports_title'] = 1;
1705
+ $pod_params['supports_editor'] = 1;
1706
  } elseif ( 'taxonomy' === $pod_params['type'] ) {
1707
  $check = get_taxonomy( $pod_params['name'] );
1708
 
1728
  * $params['type'] string The Pod type
1729
  * $params['object'] string The object being extended (if any)
1730
  * $params['storage'] string The Pod storage
 
1731
  * $params['create_extend'] string Create or Extend a Content Type
1732
+ * $params['order'] array List of group and field IDs to reorder
1733
  *
1734
+ * @param array|Pod $params An associative array of parameters
1735
+ * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will
1736
+ * sanitize them if false.
1737
+ * @param bool|int $db (optional) Whether to save into the DB or just return Pod array.
1738
+ *
1739
+ * @throws Exception
1740
  *
1741
  * @return int Pod ID
1742
  * @since 1.7.9
1743
  */
1744
  public function save_pod( $params, $sanitized = false, $db = true ) {
1745
+ if ( $params instanceof Pod ) {
1746
+ $params = [
1747
+ 'id' => $params->get_id(),
1748
+ 'pod' => $params,
1749
+ ];
1750
+ }
1751
 
1752
+ $params = (object) $params;
 
1753
 
1754
+ $extend = false;
 
1755
 
1756
+ if ( isset( $params->create_extend ) ) {
1757
+ $extend = 'extend' === $params->create_extend;
1758
 
1759
+ unset( $params->create_extend );
 
1760
  }
1761
 
1762
+ if ( isset( $params->pod ) && $params->pod instanceof Pod ) {
1763
+ $pod = $params->pod;
1764
+
1765
+ unset( $params->pod );
1766
+ } else {
1767
+ $load_params = [];
1768
+
1769
+ if ( ! empty( $params->id ) ) {
1770
+ $load_params['id'] = $params->id;
1771
+ } elseif ( ! empty( $params->old_name ) ) {
1772
+ $load_params['name'] = $params->old_name;
1773
+ } elseif ( ! empty( $params->name ) ) {
1774
+ $load_params['name'] = $params->name;
1775
+ }
1776
+
1777
+ $pod = $this->load_pod( $load_params, false );
1778
  }
1779
 
1780
+ if ( $pod instanceof Pod ) {
1781
+ $groups = $pod->get_groups();
1782
 
1783
+ $pod = $pod->get_args();
1784
 
1785
+ $pod['groups'] = [];
1786
+
1787
+ foreach ( $groups as $group ) {
1788
+ $fields = $group->get_fields();
1789
+
1790
+ $pod['groups'][ $group->name ] = $group->get_args();
1791
+
1792
+ $pod['groups'][ $group->name ]['fields'] = [];
1793
+
1794
+ foreach ( $fields as $field ) {
1795
+ $pod['groups'][ $group->name ]['fields'][ $field->name ] = $field->get_args();
1796
+ }
1797
+ }
1798
+ }
1799
 
1800
  if ( false === $sanitized ) {
1801
  $params = pods_sanitize( $params );
1802
+
1803
+ $sanitized = true;
1804
  }
1805
 
1806
  $old_id = null;
1807
  $old_name = null;
1808
  $old_storage = null;
1809
+ $old_groups = array();
1810
  $old_fields = array();
 
1811
 
1812
  if ( isset( $params->name ) && ! isset( $params->object ) ) {
1813
  $params->name = pods_clean_name( $params->name );
1814
  }
1815
 
1816
+ $params->overwrite = ! empty( $params->overwrite ) ? (boolean) $params->overwrite : false;
1817
+
1818
+ $order_group_fields = null;
1819
+
1820
+ if ( isset( $params->order ) ) {
1821
+ $order_group_fields = $params->order;
1822
+
1823
+ unset( $params->order );
1824
+ }
1825
+
1826
  if ( ! empty( $pod ) ) {
1827
  // Existing pod (update).
1828
 
1833
  $params->id = $pod['id'];
1834
 
1835
  $old_name = $pod['name'];
1836
+ $old_storage = isset( $pod['storage'] ) ? $pod['storage'] : 'meta';
1837
+ $old_groups = isset( $pod['groups'] ) ? $pod['groups'] : [];
1838
+ $old_fields = isset( $pod['fields'] ) ? $pod['fields'] : [];
1839
+
1840
+ // Get group fields if we have groups.
1841
+ if ( ! empty( $old_groups ) ) {
1842
+ $old_fields = wp_list_pluck( array_values( $old_groups ), 'fields' );
1843
+
1844
+ if ( ! empty( $old_fields ) ) {
1845
+ $old_fields = array_merge( ...$old_fields );
1846
+ }
1847
+ }
1848
 
1849
  // Check if name is intentionally not set, set it as current name.
1850
  if ( ! isset( $params->name ) ) {
1864
  }
1865
 
1866
  if (
1867
+ ! empty( $pod['object'] )
1868
+ && $pod['object'] === $old_name
1869
+ && in_array( $pod['type'], array( 'post_type', 'taxonomy' ), true )
1870
  ) {
1871
  return pods_error( sprintf( __( 'Pod %s cannot be renamed, it extends an existing WP Object', 'pods' ), $old_name ), $this );
1872
  }
1873
  }
1874
 
1875
+ if ( (int) $old_id !== (int) $params->id ) {
1876
+ if ( $params->type === $pod['type'] && isset( $params->object ) && $params->object === $pod['object'] ) {
1877
  return pods_error( sprintf( __( 'Pod using %s already exists, you can not reuse an object across multiple pods', 'pods' ), $params->object ), $this );
1878
  } else {
1879
  return pods_error( sprintf( __( 'Pod %s already exists', 'pods' ), $params->name ), $this );
1882
  } else {
1883
  // New pod (create).
1884
 
1885
+ if ( empty( $params->name ) ) {
1886
+ return pods_error( __( 'Pod name is required', 'pods' ), $this );
1887
+ }
1888
+
1889
  if (
1890
  in_array( $params->name, pods_reserved_keywords(), true )
1891
  && in_array( pods_v( 'type', $params ), array( 'post_type', 'taxonomy' ), true )
1916
  'storage' => 'table',
1917
  'object' => '',
1918
  'alias' => '',
1919
+ 'groups' => array(),
 
1920
  );
1921
  }
1922
 
1923
  // Blank out fields and options for AJAX calls (everything should be sent to it for a full overwrite)
1924
+ if ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || $params->overwrite ) {
1925
+ $pod['groups'] = array();
 
1926
  }
1927
 
1928
  // Setup options
1932
  unset( $options['method'] );
1933
  }
1934
 
1935
+ if ( isset( $options['overwrite'] ) ) {
1936
+ unset( $options['overwrite'] );
1937
+ }
1938
+
1939
+ $pod = pods_config_merge_data( $pod, $options );
1940
+
1941
+ if ( is_array( $pod ) && isset( $pod['options'] ) ) {
1942
+ $pod = array_merge( $pod, $pod['options'] );
1943
+
1944
+ unset( $pod['options'] );
1945
+ }
1946
+
1947
  $options_ignore = array(
1948
  'object_type',
1949
  'object_name',
1961
  'meta_field_value',
1962
  'pod_field_id',
1963
  'pod_field_index',
1964
+ 'fields',
1965
  'object_fields',
1966
+ 'groups',
1967
  'join',
1968
  'where',
1969
  'where_default',
1977
  'developer_mode',
1978
  'dependency',
1979
  'depends-on',
1980
+ 'excludes-on',
1981
+ 'is_new',
1982
+ '_locale',
1983
+ 'old_name',
1984
+ 'parent',
1985
+ 'group_id',
1986
  );
1987
 
1988
  foreach ( $options_ignore as $ignore ) {
2000
  'storage',
2001
  'object',
2002
  'alias',
2003
+ 'fields',
2004
+ 'weight',
2005
+ 'parent',
2006
+ 'group',
2007
+ 'groups',
2008
+ 'is_new',
2009
+ '_locale',
2010
+ 'old_name',
2011
+ 'parent',
2012
+ 'group_id',
2013
+ 'post_status',
2014
  );
2015
 
2016
  foreach ( $exclude as $k => $exclude_field ) {
2030
  }
2031
  }
2032
 
2033
+ // Enforce pod types and storage types.
2034
+ if ( pods_tableless() && ! in_array( $pod['type'], array( 'settings', 'table' ), true ) ) {
2035
  if ( 'pod' === $pod['type'] ) {
2036
  $pod['type'] = 'post_type';
2037
  }
2045
  }
2046
  }
2047
 
 
 
 
 
 
 
 
2048
  /**
2049
  * @var WP_Query
2050
  */
2060
  $reserved_query_vars = array_merge( $reserved_query_vars, array_keys( $wp_query->fill_query_vars( array() ) ) );
2061
  }
2062
 
2063
+ if ( isset( $pod['query_var_string'] ) && in_array( $pod['query_var_string'], $reserved_query_vars, true ) ) {
2064
+ $pod['query_var_string'] = $pod['type'] . '_' . $pod['query_var_string'];
 
 
2065
  }
2066
 
2067
+ if ( isset( $pod['query_var'] ) && in_array( $pod['query_var'], $reserved_query_vars, true ) ) {
2068
+ $pod['query_var'] = $pod['type'] . '_' . $pod['query_var'];
 
 
2069
  }
2070
 
2071
+ if ( '' === $pod['label'] ) {
2072
  $pod['label'] = $pod['name'];
2073
  }
2074
 
2103
 
2104
  // Add new pod
2105
  if ( empty( $params->id ) ) {
2106
+ if ( '' === $params->name ) {
2107
  return pods_error( __( 'Pod name cannot be empty', 'pods' ), $this );
2108
  }
2109
 
2112
  'post_title' => $pod['label'],
2113
  'post_content' => $pod['description'],
2114
  'post_type' => '_pods_pod',
2115
+ 'post_status' => 'publish',
2116
  );
2117
 
2118
+ if ( ! is_array( $pod['groups'] ) || empty( $pod['groups'] ) ) {
2119
+ $default_group_label = __( 'More Fields', 'pods' );
2120
+ $default_group_fields = [];
2121
+
2122
+ // Advanced Content Types have default fields.
2123
+ if ( 'pod' === $pod['type'] ) {
2124
+ $default_group_label = __( 'Details', 'pods' );
2125
+ $default_group_fields = [
2126
+ 'name' => [
2127
+ 'name' => 'name',
2128
+ 'label' => 'Name',
2129
+ 'type' => 'text',
2130
+ 'required' => '1',
2131
+ ],
2132
+ 'created' => [
2133
+ 'name' => 'created',
2134
+ 'label' => 'Date Created',
2135
+ 'type' => 'datetime',
2136
+ 'datetime_format' => 'ymd_slash',
2137
+ 'datetime_time_type' => '12',
2138
+ 'datetime_time_format' => 'h_mm_ss_A',
2139
+ ],
2140
+ 'modified' => [
2141
+ 'name' => 'modified',
2142
+ 'label' => 'Date Modified',
2143
+ 'type' => 'datetime',
2144
+ 'datetime_format' => 'ymd_slash',
2145
+ 'datetime_time_type' => '12',
2146
+ 'datetime_time_format' => 'h_mm_ss_A',
2147
+ ],
2148
+ 'author' => [
2149
+ 'name' => 'author',
2150
+ 'label' => 'Author',
2151
+ 'type' => 'pick',
2152
+ 'pick_object' => 'user',
2153
+ 'pick_format_type' => 'single',
2154
+ 'pick_format_single' => 'autocomplete',
2155
+ 'default_value' => '{@user.ID}',
2156
+ ],
2157
+ 'permalink' => [
2158
+ 'name' => 'permalink',
2159
+ 'label' => 'Permalink',
2160
+ 'type' => 'slug',
2161
+ 'description' => 'Leave blank to auto-generate from Name',
2162
+ ],
2163
+ ];
2164
+
2165
+ if ( ! isset( $pod['pod_index'] ) ) {
2166
+ $pod['pod_index'] = 'name';
2167
+ }
2168
+ }
2169
 
2170
+ /**
2171
+ * Filter the title of the Pods Metabox used in the post editor.
2172
+ *
2173
+ * @since unknown
2174
+ *
2175
+ * @param string $title The title to use, default is 'More Fields'.
2176
+ * @param array $pod The Pods config data.
2177
+ * @param array $fields Array of fields that will go in the metabox.
2178
+ * @param string $type The type of Pod.
2179
+ * @param string $name Name of the Pod.
2180
+ */
2181
+ $default_group_label = apply_filters( 'pods_meta_default_box_title', $default_group_label, $pod, $default_group_fields, $pod['type'], $pod['name'] );
2182
+ $default_group_name = sanitize_key( pods_js_name( sanitize_title( $default_group_label ) ) );
2183
 
2184
+ $pod['groups'] = [
2185
+ $default_group_name => [
2186
+ 'name' => $default_group_name,
2187
+ 'label' => $default_group_label,
2188
+ 'fields' => $default_group_fields,
2189
+ ],
2190
+ ];
2191
  }
2192
 
2193
  $pod = $this->do_hook( 'save_pod_default_pod', $pod, $params, $sanitized, $db );
2203
  );
2204
  }
2205
 
2206
+ /**
2207
+ * Allow filtering the Pod config data before saving the options.
2208
+ *
2209
+ * @since 2.8.0
2210
+ *
2211
+ * @param array $pod The Pod config data to be used for saving groups/fields.
2212
+ * @param object $params The list of parameters used to save this pod.
2213
+ * @param bool $sanitized Whether the data was sanitized already.
2214
+ * @param bool $db Whether to save the data to the database.
2215
+ */
2216
+ $pod = apply_filters( 'pods_api_save_pod_config_data', $pod, $params, $sanitized, $db );
2217
+
2218
+ $meta = $pod;
2219
+
2220
+ $excluded_meta = array(
2221
+ 'id',
2222
+ 'name',
2223
+ 'label',
2224
+ 'description',
2225
+ 'weight',
2226
+ 'options',
2227
+ 'fields',
2228
+ 'group',
2229
+ 'groups',
2230
+ 'object_fields',
2231
+ 'object_type',
2232
+ 'storage_type',
2233
+ 'old_name',
2234
+ );
2235
+
2236
+ foreach ( $excluded_meta as $meta_key ) {
2237
+ if ( isset( $meta[ $meta_key ] ) ) {
2238
+ unset( $meta[ $meta_key ] );
2239
+ }
2240
+ }
2241
+
2242
+ /**
2243
+ * Allow filtering the Pod object data before saving.
2244
+ *
2245
+ * @since 2.8.0
2246
+ *
2247
+ * @param array $post_data The Pod object data to be saved.
2248
+ * @param array $pod The Pod config data.
2249
+ * @param object $params The list of parameters used to save this pod.
2250
+ * @param bool $sanitized Whether the data was sanitized already.
2251
+ * @param bool $db Whether to save the data to the database.
2252
+ */
2253
+ $post_data = apply_filters( 'pods_api_save_pod_post_data', $post_data, $pod, $params, $sanitized, $db );
2254
+
2255
+ /**
2256
+ * Allow filtering the Pod config data before saving the options.
2257
+ *
2258
+ * @since 2.8.0
2259
+ *
2260
+ * @param array $meta The Pod meta data to be saved.
2261
+ * @param array $pod The Pod config data.
2262
+ * @param object $params The list of parameters used to save this pod.
2263
+ * @param bool $sanitized Whether the data was sanitized already.
2264
+ * @param bool $db Whether to save the data to the database.
2265
+ */
2266
+ $meta = apply_filters( 'pods_api_save_pod_meta_data', $meta, $pod, $params, $sanitized, $db );
2267
+
2268
+ if ( true === $db ) {
2269
+ if ( ! has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) ) {
2270
+ add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
2271
+ }
2272
+
2273
  $conflicted = false;
2274
 
2275
  // Headway compatibility fix
2279
  $conflicted = true;
2280
  }
2281
 
2282
+ $params->id = $this->save_wp_object( 'post', $post_data, $meta, true, true );
2283
 
2284
  if ( $conflicted ) {
2285
  add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
2294
 
2295
  $pod['id'] = $params->id;
2296
 
2297
+ $all_fields = [];
 
 
2298
 
2299
+ if ( ! empty( $pod['fields'] ) ) {
2300
+ $all_fields = (array) $pod['fields'];
2301
+ } elseif ( ! empty( $pod['groups'] ) ) {
2302
+ $all_fields = wp_list_pluck( array_values( $pod['groups'] ), 'fields' );
2303
 
2304
+ if ( ! empty( $all_fields ) ) {
2305
+ $all_fields = array_merge( ...$all_fields );
2306
+ } else {
2307
+ $all_fields = [];
2308
+ }
2309
+ }
2310
 
2311
+ // Maybe save the pod table schema.
2312
+ if ( $db ) {
2313
+ $old_info = compact(
2314
+ 'old_storage',
2315
+ 'old_name'
2316
+ );
2317
 
2318
+ $this->save_pod_table_schema( $pod, $all_fields, $old_info );
2319
+ }
2320
 
2321
+ // Maybe handle renaming.
2322
+ if ( $db && $pod['name'] !== $old_name ) {
2323
+ $this->save_pod_handle_rename( $pod, $old_name );
2324
+ }
 
2325
 
2326
+ // Maybe sync built-in options for post type and taxonomies.
2327
+ if ( $db && empty( $pod['object'] ) ) {
2328
+ $this->save_pod_handle_sync_built_in( $pod );
2329
+ }
2330
 
2331
+ $saved = array();
2332
+ $errors = array();
 
 
 
2333
 
2334
+ $id_required = false;
 
 
 
2335
 
2336
+ // Save the object to the collection.
2337
+ $object_collection = Pods\Whatsit\Store::get_instance();
 
2338
 
2339
+ /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */
2340
+ $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() );
2341
 
2342
+ $object = $post_type_storage->to_object( $pod['id'], true );
 
 
2343
 
2344
+ if ( ! $object ) {
2345
+ $errors[] = __( 'Cannot save pod to collection', 'pods' );
2346
+ }
2347
 
2348
+ if ( ! empty( $errors ) ) {
2349
+ return pods_error( $errors, $this );
 
2350
  }
2351
 
2352
+ $field_index = pods_v( 'pod_index', $pod, 'id', true );
2353
+ $field_index_id = 0;
2354
+ $field_index_change = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
2355
 
2356
+ if ( 'pod' === $pod['type'] && isset( $all_fields[ $field_index ] ) ) {
2357
+ $field_index_id = $all_fields[ $field_index ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2358
 
2359
+ if ( is_array( $field_index_id ) && ! empty( $field_index_id['id'] ) ) {
2360
+ $field_index_id = $field_index_id['id'];
 
 
 
2361
  }
2362
+ }
2363
 
2364
+ $fields_to_save = [];
 
 
 
 
 
 
 
 
 
 
 
2365
 
2366
+ if ( ! empty( $params->fields ) ) {
2367
+ $params->fields = (array) $params->fields;
 
 
 
 
 
2368
 
2369
+ $weight = 0;
 
 
 
2370
 
2371
+ // Handle weight of fields.
2372
+ foreach ( $params->fields as $field ) {
2373
+ $is_field_object = $field instanceof Field;
 
 
 
 
 
 
 
2374
 
2375
+ if ( ! $is_field_object && ! is_array( $field ) && empty( $field['name'] ) ) {
2376
  continue;
2377
  }
2378
 
2379
+ if ( ! isset( $field['weight'] ) ) {
2380
+ $field['weight'] = $weight;
 
2381
 
2382
+ $weight ++;
2383
+ }
2384
 
2385
+ $fields_to_save[ $field['name'] ] = $field;
2386
  }
2387
+ } elseif ( ! empty( $params->groups ) ) {
2388
+ $params->groups = (array) $params->groups;
2389
 
2390
+ $group_weight = 0;
 
2391
 
2392
+ // Handle saving of groups.
2393
+ foreach ( $params->groups as $group ) {
2394
+ if ( ! ( is_array( $group ) || $group instanceof Pods\Whatsit ) || ! isset( $group['name'] ) ) {
2395
+ continue;
2396
+ }
 
 
 
 
2397
 
2398
+ $group_to_save = $group;
 
 
2399
 
2400
+ // Normalize as an array if an object.
2401
+ if ( $group instanceof Pods\Whatsit ) {
2402
+ $group_to_save = $group->get_args();
2403
+ }
2404
 
2405
+ if ( ! isset( $group_to_save['weight'] ) ) {
2406
+ $group_to_save['weight'] = $group_weight;
 
 
 
 
 
2407
 
2408
+ $group_weight ++;
2409
+ }
2410
 
2411
+ $group_to_save['pod'] = $object;
2412
+ $group_to_save['overwrite'] = $params->overwrite;
 
2413
 
2414
+ $group_fields = [];
 
 
 
 
 
2415
 
2416
+ if ( isset( $group_to_save['fields'] ) ) {
2417
+ $group_fields = $group_to_save['fields'];
2418
 
2419
+ unset( $group_to_save['fields'] );
2420
+ }
2421
 
2422
+ $group['id'] = $this->save_group( $group_to_save, $sanitized, $db );
2423
 
2424
+ if ( ! empty( $group_fields ) ) {
2425
+ $weight = 0;
2426
 
2427
+ // Handle weight of fields.
2428
+ foreach ( $group_fields as $field ) {
2429
+ $is_field_object = $field instanceof Field;
2430
 
2431
+ if ( ! $is_field_object && ! is_array( $field ) && empty( $field['name'] ) ) {
2432
+ continue;
2433
+ }
2434
 
2435
+ // Set the parent.
2436
+ $field['pod'] = $object;
2437
 
2438
+ if ( $group instanceof Pods\Whatsit ) {
2439
+ $field['group'] = $group;
2440
+ } else {
2441
+ $field['group_id'] = $group['id'];
2442
+ }
2443
 
2444
+ if ( ! isset( $field['weight'] ) ) {
2445
+ $field['weight'] = $weight;
 
 
2446
 
2447
+ $weight ++;
2448
+ }
2449
 
2450
+ $fields_to_save[ $field['name'] ] = $field;
2451
  }
 
 
2452
  }
2453
  }
2454
+ }
2455
+
2456
+ if ( $fields_to_save || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ! empty( $params->overwrite ) ) {
2457
+ $saved_field_ids = array();
2458
+
2459
+ $fields_to_save = $fields_to_save;
2460
 
2461
  $weight = 0;
2462
 
2463
+ foreach ( $fields_to_save as $k => $field ) {
2464
+ $is_field_object = $field instanceof Field;
2465
+
2466
+ $is_field_ok = (
2467
+ is_array( $field )
2468
+ || $is_field_object
2469
+ );
2470
 
2471
+ if (
2472
+ ! empty( $old_id )
2473
+ && (
2474
+ ! $is_field_ok
2475
+ || ! isset( $field['name'], $fields_to_save[ $field['name'] ] )
2476
+ )
2477
+ ) {
2478
  // Iterative change handling for setup-edit.php
2479
+ if ( ! $is_field_ok && isset( $old_fields[ $k ] ) ) {
2480
  $saved[ $old_fields[ $k ]['name'] ] = true;
2481
  }
2482
 
2484
  }
2485
 
2486
  if ( ! empty( $old_id ) ) {
2487
+ $field_data = $fields_to_save[ $field['name'] ];
2488
+
2489
+ /** @noinspection SlowArrayOperationsInLoopInspection */
2490
+ $field = pods_config_merge_data( $field, $field_data );
2491
  }
2492
 
2493
+ $field['pod_data'] = $object;
2494
 
2495
  if ( ! isset( $field['weight'] ) ) {
2496
  $field['weight'] = $weight;
2498
  $weight ++;
2499
  }
2500
 
2501
+ if ( 0 < $field_index_id && (int) pods_v( 'id', $field ) === $field_index_id ) {
2502
  $field_index_change = $field['name'];
2503
  }
2504
 
2505
+ if ( 0 < pods_v( 'id', $field ) ) {
2506
  $id_required = true;
2507
  }
2508
 
2512
 
2513
  $field_data = $field;
2514
 
2515
+ $field = $this->save_field( $field_data, $field_table_operation, $sanitized, $db );
2516
 
2517
  if ( true !== $db ) {
2518
+ $fields_to_save[ $k ] = $field;
2519
  $saved_field_ids[] = $field['id'];
2520
+ } elseif ( ! empty( $field ) && 0 < $field ) {
2521
+ $saved[ $field_data['name'] ] = true;
2522
+ $saved_field_ids[] = $field;
2523
  } else {
2524
+ $errors[] = sprintf( __( 'Cannot save the %s field', 'pods' ), $field_data['name'] );
 
 
 
 
 
2525
  }
2526
  }
2527
 
2528
  if ( true === $db ) {
2529
  foreach ( $old_fields as $field ) {
2530
+ if ( isset( $fields_to_save[ $field['name'] ] ) || isset( $saved[ $field['name'] ] ) || in_array( $field['id'], $saved_field_ids ) ) {
2531
  continue;
2532
  }
2533
 
2534
+ if ( $field['id'] === (int) $field_index_id ) {
2535
  $field_index_change = 'id';
2536
+ } elseif ( $field['name'] === $field_index ) {
2537
  $field_index_change = 'id';
2538
  }
2539
 
2551
  }
2552
  }
2553
 
2554
+ if ( is_array( $order_group_fields ) && ! empty( $order_group_fields['groups'] ) ) {
2555
+ $this->save_pod_group_field_order( $order_group_fields['groups'], $object, $db );
2556
+ }
2557
+
2558
  $this->cache_flush_pods( $pod );
2559
 
2560
  if ( ! empty( $errors ) ) {
2589
  && in_array( $pod['type'], array(
2590
  'post_type',
2591
  'taxonomy'
2592
+ ), true )
2593
  && empty( $pod['object'] )
2594
  ) {
2595
  pods_init()->setup_content_types( true );
2603
  }
2604
 
2605
  /**
2606
+ * Handle saving the pod table schema.
2607
  *
2608
+ * @since 2.8.0
 
 
 
 
 
 
 
 
 
 
 
2609
  *
2610
+ * @param array $pod The pod configuration.
2611
+ * @param array $fields The list of fields on the pod.
2612
+ * @param array $old_info The old information to reference.
 
 
2613
  *
2614
+ * @return bool|WP_Error True if the schema changes were handled, false or an error if it failed to create/update.
2615
+ *
2616
+ * @throws Exception
2617
  */
2618
+ public function save_pod_table_schema( $pod, array $fields, array $old_info ) {
 
 
 
 
2619
  global $wpdb;
2620
 
 
 
 
 
2621
  $tableless_field_types = PodsForm::tableless_field_types();
2622
  $simple_tableless_objects = PodsForm::simple_tableless_objects();
2623
 
2624
+ $old_storage = $old_info['old_storage'];
2625
+ $old_name = $old_info['old_name'];
 
 
 
2626
 
2627
+ // Skip custom mapped table pods.
2628
+ if ( 'table' === $pod['type'] || ! empty( $pod['table'] ) ) {
2629
+ return;
2630
  }
2631
 
2632
+ // Skip if not using table storage.
2633
+ if ( isset( $pod['storage'] ) && 'table' !== $pod['storage'] ) {
2634
+ return;
2635
  }
2636
 
2637
+ $table_name = "@wp_pods_{$pod['name']}";
2638
+ $old_table_name = "@wp_pods_{$old_name}";
 
2639
 
2640
+ if ( $old_storage !== $pod['storage'] ) {
2641
+ // Create the table if it wasn't there before.
2642
+ $definitions = [
2643
+ '`id` BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY',
2644
+ ];
2645
 
2646
+ $defined_fields = [];
 
2647
 
2648
+ foreach ( $fields as $field ) {
2649
+ $is_field_object = $field instanceof Field;
 
2650
 
2651
+ // Skip if not a field, if an invalid field, or if already defined.
2652
+ if (
2653
+ ! (
2654
+ is_array( $field )
2655
+ || $is_field_object
2656
+ )
2657
+ || ! isset( $field['name'] )
2658
+ || in_array( $field['name'], $defined_fields, true )
2659
+ ) {
2660
+ continue;
2661
+ }
2662
 
2663
+ $defined_fields[] = $field['name'];
 
 
 
 
 
 
 
2664
 
2665
+ $define_tableless_fields = false;
 
 
2666
 
2667
+ // Skip if we are not defining tableless fields and it is a tableless field or not a simple tableless object.
2668
+ if (
2669
+ ! $define_tableless_fields
2670
+ && in_array( $field['type'], $tableless_field_types, true )
2671
+ && (
2672
+ 'pick' !== $field['type']
2673
+ || in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true )
2674
+ )
2675
+ ) {
2676
+ continue;
2677
+ }
2678
 
2679
+ $definition = $this->get_field_definition( $field['type'], $field );
2680
 
2681
+ if ( 0 < strlen( $definition ) ) {
2682
+ $definitions[] = "`{$field['name']}` " . $definition;
2683
+ }
2684
+ }
2685
 
2686
+ // Drop the table if it already exists.
2687
+ pods_query( "DROP TABLE IF EXISTS `{$table_name}`" );
 
2688
 
2689
+ /**
2690
+ * @see PodsUpgrade::install() L64-L76
2691
+ * @todo Central function to fetch charset.
2692
+ */
2693
+ $charset_collate = 'DEFAULT CHARSET utf8';
2694
 
2695
+ if ( ! empty( $wpdb->charset ) ) {
2696
+ $charset_collate = "DEFAULT CHARSET {$wpdb->charset}";
2697
+ }
2698
 
2699
+ if ( ! empty( $wpdb->collate ) ) {
2700
+ $charset_collate .= " COLLATE {$wpdb->collate}";
2701
+ }
 
 
 
 
2702
 
2703
+ if ( empty( $definitions ) ) {
2704
+ return pods_error( __( 'Cannot add Database Table for Pod, no table column definitions provided', 'pods' ), $this );
2705
+ }
2706
 
2707
+ $all_definitions = implode( ', ', $definitions );
 
 
 
 
 
2708
 
2709
+ $result = pods_query( "CREATE TABLE `{$table_name}` ({$all_definitions}) {$charset_collate}", $this );
2710
 
2711
+ if ( empty( $result ) ) {
2712
+ return pods_error( __( 'Cannot add Database Table for Pod', 'pods' ), $this );
2713
  }
2714
+ } elseif ( null !== $old_name && $old_name !== $pod['name'] ) {
2715
+ // Rename the table.
2716
+ $result = pods_query( "ALTER TABLE `{$old_table_name}` RENAME `{$table_name}`", $this );
2717
 
2718
+ if ( empty( $result ) ) {
2719
+ return pods_error( __( 'Cannot update Database Table for Pod', 'pods' ), $this );
 
 
 
 
 
 
2720
  }
2721
+ }
2722
+
2723
+ /**
2724
+ * Allow hooking after the table schema has been created or the table has been renamed.
2725
+ *
2726
+ * @since 2.8.0
2727
+ *
2728
+ * @param array $pod The pod configuration.
2729
+ * @param array $fields The list of fields on the pod.
2730
+ * @param array $old_info The old information to reference.
2731
+ */
2732
+ do_action( 'pods_api_save_pod_table_schema_after', $pod, $fields, $old_info );
2733
+
2734
+ return true;
2735
+ }
2736
+
2737
+ /**
2738
+ * Handle saving the pod table schema.
2739
+ *
2740
+ * @since 2.8.0
2741
+ *
2742
+ * @param array $pod The pod configuration.
2743
+ * @param string $old_name The old pod name.
2744
+ *
2745
+ * @return bool Whether the pod was successfully renamed.
2746
+ *
2747
+ * @throws Exception
2748
+ */
2749
+ public function save_pod_handle_rename( $pod, $old_name ) {
2750
+ global $wpdb;
2751
+
2752
+ $pod_name = sanitize_key( $pod['name'] );
2753
+ $pod_id = (int) $pod['id'];
2754
+ $pod_type = pods_sanitize( $pod['type'] );
2755
+ $has_object = ! empty( $pod['object'] );
2756
+ $old_name = sanitize_key( $old_name );
2757
+
2758
+ // Skip if the name did not change.
2759
+ if ( $pod_name === $old_name ) {
2760
+ return false;
2761
+ }
2762
+
2763
+ // Skip if either name is empty.
2764
+ if ( empty( $pod_name ) || empty( $old_name ) ) {
2765
+ return false;
2766
+ }
2767
+
2768
+ // Rename items in the DB pointed at the old WP Object names.
2769
+ if ( 'post_type' === $pod_type && ! $has_object ) {
2770
+ $this->rename_wp_object_type( 'post', $old_name, $pod_name );
2771
+ } elseif ( 'taxonomy' === $pod_type && ! $has_object ) {
2772
+ $this->rename_wp_object_type( 'taxonomy', $old_name, $pod_name );
2773
+ } elseif ( 'comment' === $pod_type && ! $has_object ) {
2774
+ $this->rename_wp_object_type( 'comment', $old_name, $pod_name );
2775
+ } elseif ( 'settings' === $pod_type ) {
2776
+ $this->rename_wp_object_type( 'settings', $old_name, $pod_name );
2777
+ }
2778
+
2779
+ $fields_to_sync = [];
2780
+
2781
+ // Sync any related fields if the name has changed
2782
+ $fields_to_sync[] = pods_query(
2783
+ "
2784
+ SELECT `p`.`ID`
2785
+ FROM `{$wpdb->posts}` AS `p`
2786
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
2787
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm2` ON `pm2`.`post_id` = `p`.`ID`
2788
+ WHERE
2789
+ `p`.`post_type` = '_pods_field'
2790
+ AND `p`.`post_parent` != {$pod_id}
2791
+ AND `pm`.`meta_key` = 'pick_object'
2792
+ AND (
2793
+ `pm`.`meta_value` = 'pod'
2794
+ OR `pm`.`meta_value` = '{$pod_type}'
2795
+ )
2796
+ AND `pm2`.`meta_key` = 'pick_val'
2797
+ AND `pm2`.`meta_value` = '{$old_name}'
2798
+ "
2799
+ );
2800
+
2801
+ $fields_to_sync[] = pods_query(
2802
+ "
2803
+ SELECT `p`.`ID`
2804
+ FROM `{$wpdb->posts}` AS `p`
2805
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm` ON `pm`.`post_id` = `p`.`ID`
2806
+ WHERE
2807
+ `p`.`post_type` = '_pods_field'
2808
+ AND `p`.`post_parent` != {$pod_id}
2809
+ AND `pm`.`meta_key` = 'pick_object'
2810
+ AND (
2811
+ `pm`.`meta_value` = 'pod-{$old_name}'
2812
+ OR `pm`.`meta_value` = '{$pod_type}-{$old_name}'
2813
+ )
2814
+ "
2815
+ );
2816
+
2817
+ $fields_to_sync = array_merge( ...$fields_to_sync );
2818
+ $fields_to_sync = array_map( 'absint', $fields_to_sync );
2819
+ $fields_to_sync = array_unique( array_filter( $fields_to_sync ) );
2820
+
2821
+ // Update the field configurations for any related fields that changed.
2822
+ if ( ! empty( $fields_to_sync ) ) {
2823
+ foreach ( $fields_to_sync as $field_to_sync ) {
2824
+ $found_field = $this->load_field( [
2825
+ 'id' => $field_to_sync->ID,
2826
+ ] );
2827
+
2828
+ // Field not found.
2829
+ if ( ! $found_field ) {
2830
+ continue;
2831
+ }
2832
+
2833
+ // Save new location.
2834
+ $found_field['pick_object'] = $pod_type;
2835
+ $found_field['pick_val'] = $pod_name;
2836
+
2837
+ $this->save_field( $found_field );
2838
+ }
2839
+ }
2840
+
2841
+ /**
2842
+ * Allow hooking after the pod has been renamed.
2843
+ *
2844
+ * @since 2.8.0
2845
+ *
2846
+ * @param array $pod The pod configuration.
2847
+ * @param string $old_name The old pod name.
2848
+ */
2849
+ do_action( 'pods_api_save_pod_handle_rename_after', $pod, $old_name );
2850
+
2851
+ return true;
2852
+ }
2853
+
2854
+ /**
2855
+ * Handle syncing the built-in post type / taxonomy options.
2856
+ *
2857
+ * @since 2.8.0
2858
+ *
2859
+ * @param array $pod The pod configuration.
2860
+ *
2861
+ * @return bool Whether the sync was successful.
2862
+ */
2863
+ public function save_pod_handle_sync_built_in( $pod ) {
2864
+ global $wpdb;
2865
+
2866
+ if ( ! empty( $pod['object'] ) || ! in_array( $pod['type'], array( 'post_type', 'taxonomy' ), true ) ) {
2867
+ return false;
2868
+ }
2869
+
2870
+ // Build list of 'built_in' for later.
2871
+ $built_in = array();
2872
+
2873
+ $options = $pod;
2874
+
2875
+ if ( is_object( $options ) ) {
2876
+ $options = $pod->get_args();
2877
+ }
2878
+
2879
+ foreach ( $options as $key => $val ) {
2880
+ if ( false === strpos( $key, 'built_in_' ) ) {
2881
+ continue;
2882
+ }
2883
+
2884
+ if ( false !== strpos( $key, 'built_in_post_types_' ) ) {
2885
+ $built_in_type = 'post_type';
2886
+ } elseif ( false !== strpos( $key, 'built_in_taxonomies_' ) ) {
2887
+ $built_in_type = 'taxonomy';
2888
+ } else {
2889
+ continue;
2890
+ }
2891
+
2892
+ // The built in type is the same as this pod type.
2893
+ if ( $pod['type'] === $built_in_type ) {
2894
+ continue;
2895
+ }
2896
+
2897
+ if ( ! isset( $built_in[ $built_in_type ] ) ) {
2898
+ $built_in[ $built_in_type ] = array();
2899
+ }
2900
+
2901
+ $built_in_object = str_replace( array( 'built_in_post_types_', 'built_in_taxonomies_' ), '', $key );
2902
+
2903
+ $built_in[ $built_in_type ][ $built_in_object ] = (int) $val;
2904
+ }
2905
+
2906
+ $lookup_option = false;
2907
+ $lookup_built_in = false;
2908
+
2909
+ $lookup_name = $pod['name'];
2910
+
2911
+ if ( 'post_type' === $pod['type'] ) {
2912
+ $lookup_option = 'built_in_post_types_' . $lookup_name;
2913
+ $lookup_built_in = 'taxonomy';
2914
+ } elseif ( 'taxonomy' === $pod['type'] ) {
2915
+ $lookup_option = 'built_in_taxonomies_' . $lookup_name;
2916
+ $lookup_built_in = 'post_type';
2917
+ }
2918
+
2919
+ // The built in options were not found.
2920
+ if ( empty( $lookup_option ) || empty( $lookup_built_in ) || ! isset( $built_in[ $lookup_built_in ] ) ) {
2921
+ return false;
2922
+ }
2923
+
2924
+ foreach ( $built_in[ $lookup_built_in ] as $built_in_object => $val ) {
2925
+ $search_val = 1;
2926
+
2927
+ if ( 1 === (int) $val ) {
2928
+ $search_val = 0;
2929
+ }
2930
+
2931
+ $built_in_object = pods_sanitize( $built_in_object );
2932
+ $lookup_option = pods_sanitize( $lookup_option );
2933
+ $lookup_built_in = pods_sanitize( $lookup_built_in );
2934
+
2935
+ $query = "SELECT p.ID FROM {$wpdb->posts} AS p
2936
+ LEFT JOIN {$wpdb->postmeta} AS pm ON pm.post_id = p.ID AND pm.meta_key = '{$lookup_option}'
2937
+ LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm2.post_id = p.ID AND pm2.meta_key = 'type' AND pm2.meta_value = '{$lookup_built_in}'
2938
+ LEFT JOIN {$wpdb->postmeta} AS pm3 ON pm3.post_id = p.ID AND pm3.meta_key = 'object' AND pm3.meta_value = ''
2939
+ WHERE p.post_type = '_pods_pod' AND p.post_name = '{$built_in_object}'
2940
+ AND pm2.meta_id IS NOT NULL
2941
+ AND ( pm.meta_id IS NULL OR pm.meta_value = {$search_val} )";
2942
+
2943
+ $results = pods_query( $query );
2944
+
2945
+ if ( ! empty( $results ) ) {
2946
+ foreach ( $results as $the_pod ) {
2947
+ delete_post_meta( $the_pod->ID, $lookup_option );
2948
+
2949
+ add_post_meta( $the_pod->ID, $lookup_option, $val );
2950
+ }
2951
+ }
2952
+ }
2953
+
2954
+ return true;
2955
+ }
2956
+
2957
+ /**
2958
+ * Handle saving the groups/fields order for a pod.
2959
+ *
2960
+ * @since 2.8.0
2961
+ *
2962
+ * @param array $groups List of group IDs and their fields to reorder.
2963
+ * @param Pod $object The pod object.
2964
+ * @param bool|int $db (optional) Whether to save into the DB or just return group array.
2965
+ *
2966
+ * @throws Exception
2967
+ */
2968
+ public function save_pod_group_field_order( $groups, $object, $db = true ) {
2969
+ $group_order = 0;
2970
+
2971
+ foreach ( $groups as $group ) {
2972
+ if ( ! is_array( $group ) || empty( $group['group_id'] ) ) {
2973
+ continue;
2974
+ }
2975
+
2976
+ $group_id = (int) $group['group_id'];
2977
+
2978
+ $this->save_group( [
2979
+ 'pod_data' => $object,
2980
+ 'id' => $group_id,
2981
+ 'weight' => $group_order,
2982
+ ], false, $db );
2983
+
2984
+ $group_order ++;
2985
+
2986
+ if ( empty( $group['fields'] ) ) {
2987
+ continue;
2988
+ }
2989
+
2990
+ $group_field_order = 0;
2991
+
2992
+ foreach ( $group['fields'] as $field_id ) {
2993
+ $this->save_field( [
2994
+ 'pod_data' => $object,
2995
+ 'id' => (int) $field_id,
2996
+ 'new_group_id' => $group_id,
2997
+ 'weight' => $group_field_order,
2998
+ ], false, false, $db );
2999
+
3000
+ $group_field_order ++;
3001
+ }
3002
+ }
3003
+ }
3004
+
3005
+ /**
3006
+ * Add field within a Pod
3007
+ *
3008
+ * $params['id'] int Field ID (id OR pod_id+pod+name required)
3009
+ * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required)
3010
+ * $params['pod'] string Pod name (id OR pod_id+pod+name required)
3011
+ * $params['name'] string Field name (id OR pod_id+pod+name required)
3012
+ * $params['label'] string (optional) Field label
3013
+ * $params['type'] string (optional) Field type (avatar, boolean, code, color, currency, date, datetime, email,
3014
+ * file, number, paragraph, password, phone, pick, slug, text, time, website, wysiwyg)
3015
+ * $params['pick_object'] string (optional) Related Object (for relationships)
3016
+ * $params['pick_val'] string (optional) Related Object name (for relationships)
3017
+ * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships)
3018
+ * $params['weight'] int (optional) Order in which the field appears
3019
+ *
3020
+ * @param array $params An associative array of parameters
3021
+ * @param bool $table_operation (optional) Whether or not to handle table operations
3022
+ * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed,
3023
+ * will sanitize them if false.
3024
+ * @param bool|int $db (optional) Whether to save into the DB or just return field array.
3025
+ *
3026
+ * @return int|array The field ID or field array (if !$db)
3027
+ *
3028
+ * @since 2.8.0
3029
+ */
3030
+ public function add_field( $params, $table_operation = true, $sanitized = false, $db = true ) {
3031
+ $params = (object) $params;
3032
+
3033
+ $params->is_new = true;
3034
+
3035
+ return $this->save_field( $params, $table_operation, $sanitized, $db );
3036
+ }
3037
+
3038
+ /**
3039
+ * Add or edit a field within a Pod
3040
+ *
3041
+ * $params['id'] int Field ID (id OR pod_id+pod+name required)
3042
+ * $params['pod_id'] int Pod ID (id OR pod_id+pod+name required)
3043
+ * $params['pod'] string Pod name (id OR pod_id+pod+name required)
3044
+ * $params['name'] string Field name (id OR pod_id+pod+name required)
3045
+ * $params['label'] string (optional) Field label
3046
+ * $params['type'] string (optional) Field type (avatar, boolean, code, color, currency, date, datetime, email,
3047
+ * file, number, paragraph, password, phone, pick, slug, text, time, website, wysiwyg)
3048
+ * $params['pick_object'] string (optional) Related Object (for relationships)
3049
+ * $params['pick_val'] string (optional) Related Object name (for relationships)
3050
+ * $params['sister_id'] int (optional) Related Field ID (for bidirectional relationships)
3051
+ * $params['weight'] int (optional) Order in which the field appears
3052
+ *
3053
+ * @param array|Field $params An associative array of parameters
3054
+ * @param bool $table_operation (optional) Whether or not to handle table operations
3055
+ * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed,
3056
+ * will sanitize them if false.
3057
+ * @param bool|int $db (optional) Whether to save into the DB or just return field array.
3058
+ *
3059
+ * @return int|array The field ID or field array (if !$db)
3060
+ * @since 1.7.9
3061
+ */
3062
+ public function save_field( $params, $table_operation = true, $sanitized = false, $db = true ) {
3063
+ if ( $params instanceof Field ) {
3064
+ $params = [
3065
+ 'id' => $params->get_id(),
3066
+ 'field' => $params,
3067
+ ];
3068
+ }
3069
+
3070
+ $params = (object) $params;
3071
+
3072
+ $field = false;
3073
+
3074
+ if ( isset( $params->field ) && $params->field instanceof Field ) {
3075
+ $field = $params->field;
3076
+
3077
+ $params->id = $field->get_id();
3078
+
3079
+ unset( $params->field );
3080
+ }
3081
+
3082
+ /**
3083
+ * @var $wpdb wpdb
3084
+ */
3085
+ global $wpdb;
3086
+
3087
+ if ( true !== $db ) {
3088
+ $table_operation = false;
3089
+ }
3090
+
3091
+ $tableless_field_types = PodsForm::tableless_field_types();
3092
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
3093
+
3094
+ $pod = null;
3095
+ $save_pod = false;
3096
+
3097
+ if ( isset( $params->pod ) && $params->pod instanceof Pod ) {
3098
+ $pod = $params->pod;
3099
+
3100
+ $params->pod_id = $pod['id'];
3101
+ $params->pod = $pod['name'];
3102
+ } elseif ( isset( $params->pod_data ) ) {
3103
+ $pod = $params->pod_data;
3104
+
3105
+ unset( $params->pod_data );
3106
+
3107
+ $params->pod_id = $pod['id'];
3108
+ $params->pod = $pod['name'];
3109
+
3110
+ $save_pod = true;
3111
+ } elseif ( isset( $params->pod_id ) ) {
3112
+ $params->pod_id = pods_absint( $params->pod_id );
3113
+ } elseif ( true !== $db ) {
3114
+ $params->pod_id = (int) $db;
3115
+ }
3116
+
3117
+ $group = null;
3118
+ $new_group = null;
3119
+ $group_identifier = null;
3120
+ $new_group_identifier = null;
3121
+
3122
+ if ( ! empty( $params->group_id ) ) {
3123
+ $group_identifier = 'ID: ' . $params->group_id;
3124
+
3125
+ $group = $this->load_group( [
3126
+ 'id' => $params->group_id,
3127
+ 'pod' => $pod,
3128
+ ] );
3129
+ } elseif ( ! empty( $params->group ) ) {
3130
+ if ( $params->group instanceof Group ) {
3131
+ $group = $params->group;
3132
+ } else {
3133
+ $group_identifier = 'Slug: ' . $params->group;
3134
+
3135
+ $group = $this->load_group( [
3136
+ 'name' => $params->group,
3137
+ 'pod' => $pod,
3138
+ ] );
3139
+ }
3140
+ }
3141
+
3142
+ // Handle assigning to new groups.
3143
+ if ( ! empty( $params->new_group_id ) ) {
3144
+ $new_group_identifier = 'ID: ' . $params->new_group_id;
3145
+
3146
+ $new_group = $this->load_group( [
3147
+ 'id' => $params->new_group_id,
3148
+ 'pod' => $pod,
3149
+ ] );
3150
+
3151
+ unset( $params->new_group_id );
3152
+ } elseif ( ! empty( $params->new_group ) ) {
3153
+ if ( $params->new_group instanceof Group ) {
3154
+ $new_group = $params->new_group;
3155
+ } else {
3156
+ $new_group_identifier = 'Slug: ' . $params->new_group;
3157
+
3158
+ $new_group = $this->load_group( [
3159
+ 'name' => $params->new_group,
3160
+ 'pod' => $pod,
3161
+ ] );
3162
+ }
3163
+
3164
+ unset( $params->new_group );
3165
+ }
3166
+
3167
+ if ( $group instanceof Group ) {
3168
+ $params->group_id = $group['id'];
3169
+ $params->group = $group['name'];
3170
+ } elseif ( false === $group ) {
3171
+ return pods_error( sprintf( __( 'Group (%s) not found.', 'pods' ), $group_identifier ), $this );
3172
+ }
3173
+
3174
+ if ( false === $new_group ) {
3175
+ return pods_error( sprintf( __( 'New group (%s) not found.', 'pods' ), $new_group_identifier ), $this );
3176
+ }
3177
+
3178
+ if ( false === $sanitized ) {
3179
+ $params = pods_sanitize( $params );
3180
+
3181
+ $sanitized = true;
3182
+ }
3183
+
3184
+ $id_required = false;
3185
+
3186
+ if ( isset( $params->id_required ) ) {
3187
+ unset( $params->id_required );
3188
+
3189
+ $id_required = true;
3190
+ }
3191
+
3192
+ if ( ! $pod && ( ! isset( $params->pod ) || empty( $params->pod ) ) && ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) ) {
3193
+ return pods_error( __( 'Pod ID or name is required', 'pods' ), $this );
3194
+ }
3195
+
3196
+ if ( ! $pod ) {
3197
+ if ( isset( $params->pod ) && ( is_array( $params->pod ) || $params->pod instanceof Pods\Whatsit ) ) {
3198
+ $pod = $params->pod;
3199
+
3200
+ $save_pod = true;
3201
+ } elseif ( ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) && ( true === $db || 0 < $db ) ) {
3202
+ $pod = $this->load_pod( array( 'name' => $params->pod ), false );
3203
+ } elseif ( ! isset( $params->pod ) && ( true === $db || 0 < $db ) ) {
3204
+ $pod = $this->load_pod( array( 'id' => $params->pod_id ), false );
3205
+ } elseif ( true === $db || 0 < $db ) {
3206
+ $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod ), false );
3207
+ }
3208
+ }
3209
+
3210
+ if ( empty( $pod ) && true === $db ) {
3211
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
3212
+ }
3213
+
3214
+ $params->pod_id = $pod['id'];
3215
+ $params->pod = $pod['name'];
3216
+
3217
+ $params->is_new = isset( $params->is_new ) ? (boolean) $params->is_new : false;
3218
+
3219
+ $reserved_keywords = pods_reserved_keywords();
3220
+
3221
+ if ( isset( $params->name ) ) {
3222
+ $params->name = pods_clean_name( $params->name, true, 'meta' !== $pod['storage'] );
3223
+
3224
+ if ( $params->is_new && isset( $params->id ) ) {
3225
+ $params->id = null;
3226
+ }
3227
+ }
3228
+
3229
+ $field_obj = $field;
3230
+
3231
+ if ( ! $field ) {
3232
+ $load_params = [
3233
+ 'pod_id' => $params->pod_id,
3234
+ ];
3235
+
3236
+ $fail_on_load = false;
3237
+
3238
+ if ( ! empty( $params->id ) ) {
3239
+ $load_params['id'] = $params->id;
3240
+
3241
+ $fail_on_load = true;
3242
+ } elseif ( ! empty( $params->old_name ) ) {
3243
+ $load_params['name'] = $params->old_name;
3244
+
3245
+ $fail_on_load = true;
3246
+ } elseif ( ! empty( $params->name ) ) {
3247
+ $load_params['name'] = $params->name;
3248
+ } elseif ( ! empty( $params->label ) ) {
3249
+ $load_params = false;
3250
+ } else{
3251
+ return pods_error( __( 'Pod field name or label is required', 'pods' ), $this );
3252
+ }
3253
+
3254
+ if ( $load_params ) {
3255
+ $field_obj = $this->load_field( $load_params );
3256
+
3257
+ if ( $fail_on_load && ( empty( $field_obj ) || is_wp_error( $field_obj ) ) ) {
3258
+ return $field_obj;
3259
+ }
3260
+ }
3261
+ }
3262
+
3263
+ if ( $field_obj ) {
3264
+ $field = $field_obj->get_args();
3265
+ }
3266
+
3267
+ if ( empty( $params->name ) ) {
3268
+ if ( $field ) {
3269
+ $params->name = $field['name'];
3270
+ } elseif ( ! empty( $params->label ) ) {
3271
+ $params->name = pods_clean_name( $params->label, true, 'meta' !== $pod['storage'] );
3272
+ } else {
3273
+ return pods_error( __( 'Pod field name or label is required', 'pods' ), $this );
3274
+ }
3275
+ }
3276
+
3277
+ $old_id = null;
3278
+ $old_name = null;
3279
+ $old_type = null;
3280
+ $old_definition = null;
3281
+ $old_simple = null;
3282
+ $old_options = null;
3283
+ $old_sister_id = null;
3284
+ $old_type_is_tableless = false;
3285
+
3286
+ $act_safe_keywords = [
3287
+ 'name',
3288
+ 'author',
3289
+ 'permalink',
3290
+ 'slug',
3291
+ ];
3292
+
3293
+ $is_act = 'pod' === $pod->get_type();
3294
+
3295
+ if ( ! empty( $field ) ) {
3296
+ $old_id = pods_v( 'id', $field );
3297
+ $old_name = pods_clean_name( $field['name'], true, 'meta' !== $pod['storage'] );
3298
+ $old_type = $field['type'];
3299
+ $old_options = $field;
3300
+ $old_sister_id = (int) pods_v( 'sister_id', $old_options, 0 );
3301
+
3302
+ $old_simple = ( 'pick' === $old_type && in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) );
3303
+
3304
+ if ( isset( $params->new_name ) && ! empty( $params->new_name ) ) {
3305
+ $field['name'] = $params->new_name;
3306
+
3307
+ unset( $params->new_name );
3308
+ } elseif ( isset( $params->name ) && ! empty( $params->name ) ) {
3309
+ $field['name'] = $params->name;
3310
+ }
3311
+
3312
+ if ( $new_group && ( ! $group || $group->get_id() !== $new_group->get_id() ) ) {
3313
+ $field['group'] = $new_group->get_id();
3314
+ }
3315
+
3316
+ if ( $old_name !== $field['name'] || empty( $params->id ) || $old_id !== $params->id ) {
3317
+ if (
3318
+ in_array( $field['name'], $reserved_keywords, true )
3319
+ && (
3320
+ ! $is_act
3321
+ || ! in_array( $field['name'], $act_safe_keywords, true )
3322
+ )
3323
+ ) {
3324
+ return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
3325
+ }
3326
+
3327
+ if ( false !== $this->field_exists( $params, false ) ) {
3328
+ return pods_error( sprintf( __( 'Field %1$s already exists, you cannot rename %2$s to that', 'pods' ), $field['name'], $old_name ), $this );
3329
+ }
3330
+ }
3331
+
3332
+ if ( ( $id_required || ! empty( $params->id ) ) && ( empty( $old_id ) || $old_id !== $params->id ) ) {
3333
+ return pods_error( sprintf( __( 'Field %s already exists', 'pods' ), $field['name'] ), $this );
3334
+ }
3335
+
3336
+ if ( empty( $params->id ) ) {
3337
+ $params->id = $old_id;
3338
+ }
3339
+
3340
+ $field_definition = false;
3341
+ $old_type_is_tableless = in_array( $old_type, $tableless_field_types, true );
3342
+
3343
+ if ( $old_simple || ! $old_type_is_tableless ) {
3344
+ $field_definition = $this->get_field_definition( $old_type, $old_options );
3345
+ }
3346
+
3347
+ /**
3348
+ * Allow filtering of the old field definition when saving updated field.
3349
+ *
3350
+ * @since 2.8.0
3351
+ *
3352
+ * @param string|false $field_definition The SQL definition to use for the field's table column.
3353
+ * @param string $type The field type.
3354
+ * @param array $field The field data.
3355
+ * @param bool $simple Whether the field is a simple tableless field.
3356
+ * @param Pods\Whatsit\Field $field_obj The field object.
3357
+ */
3358
+ $field_definition = apply_filters( 'pods_api_save_field_old_definition', $field_definition, $old_type, $field, $old_simple, $field_obj );
3359
+
3360
+ if ( ! empty( $field_definition ) ) {
3361
+ $old_definition = "`{$old_name}` " . $field_definition;
3362
+ }
3363
+ } else {
3364
+ $field = [
3365
+ 'id' => 0,
3366
+ 'pod_id' => $params->pod_id,
3367
+ 'name' => $params->name,
3368
+ 'label' => $params->name,
3369
+ 'description' => '',
3370
+ 'type' => 'text',
3371
+ 'pick_object' => '',
3372
+ 'pick_val' => '',
3373
+ 'sister_id' => '',
3374
+ 'weight' => null,
3375
+ 'options' => [],
3376
+ ];
3377
+
3378
+ if ( $group ) {
3379
+ $field['group'] = $group->get_id();
3380
+ } elseif ( $new_group ) {
3381
+ $field['group'] = $new_group->get_id();
3382
+ }
3383
+ }
3384
+
3385
+ // Setup options
3386
+ $options = get_object_vars( $params );
3387
+
3388
+ $options_ignore = [
3389
+ '_locale',
3390
+ 'attributes',
3391
+ 'dependency',
3392
+ 'depends-on',
3393
+ 'developer_mode',
3394
+ 'excludes-on',
3395
+ 'group',
3396
+ 'group_id',
3397
+ 'grouped',
3398
+ 'is_new',
3399
+ 'method',
3400
+ 'object_type',
3401
+ 'old_name',
3402
+ 'parent',
3403
+ 'pod_data',
3404
+ 'sanitized',
3405
+ 'storage_type',
3406
+ 'table_info',
3407
+ ];
3408
+
3409
+ foreach ( $options_ignore as $ignore ) {
3410
+ if ( isset( $options[ $ignore ] ) ) {
3411
+ unset( $options[ $ignore ] );
3412
+ }
3413
+ }
3414
+
3415
+ if ( isset( $options['method'] ) ) {
3416
+ unset( $options['method'] );
3417
+ } elseif ( isset( $options['table_info'] ) ) {
3418
+ unset( $options['table_info'] );
3419
+ }
3420
+
3421
+ $exclude = [
3422
+ '_locale',
3423
+ 'description',
3424
+ 'group_id',
3425
+ 'id',
3426
+ 'is_new',
3427
+ 'label',
3428
+ 'name',
3429
+ 'old_name',
3430
+ 'options',
3431
+ 'parent',
3432
+ 'pick_object',
3433
+ 'pick_val',
3434
+ 'pod',
3435
+ 'pod_id',
3436
+ 'post_status',
3437
+ 'sister_id',
3438
+ 'type',
3439
+ 'weight',
3440
+ ];
3441
+
3442
+ foreach ( $exclude as $k => $exclude_field ) {
3443
+ $aliases = array( $exclude_field );
3444
+
3445
+ if ( is_array( $exclude_field ) ) {
3446
+ $aliases = array_merge( array( $k ), $exclude_field );
3447
+ $exclude_field = $k;
3448
+ }
3449
+
3450
+ foreach ( $aliases as $alias ) {
3451
+ if ( isset( $options[ $alias ] ) ) {
3452
+ $field[ $exclude_field ] = pods_trim( $options[ $alias ] );
3453
+
3454
+ unset( $options[ $alias ] );
3455
+ }
3456
+ }
3457
+ }
3458
+
3459
+ if ( '' === $field['label'] ) {
3460
+ $field['label'] = $field['name'];
3461
+ }
3462
+
3463
+ $type_is_tableless = in_array( $field['type'], $tableless_field_types, true );
3464
+
3465
+ if ( $type_is_tableless && 'pick' === $field['type'] ) {
3466
+ // Clean up special drop-down in field editor and save out pick_val
3467
+ $field['pick_object'] = pods_v( 'pick_object', $field, '', true );
3468
+
3469
+ if ( 0 === strpos( $field['pick_object'], 'pod-' ) ) {
3470
+ $field['pick_val'] = pods_str_replace( 'pod-', '', $field['pick_object'], 1 );
3471
+ $field['pick_object'] = 'pod';
3472
+ } elseif ( 0 === strpos( $field['pick_object'], 'post_type-' ) ) {
3473
+ $field['pick_val'] = pods_str_replace( 'post_type-', '', $field['pick_object'], 1 );
3474
+ $field['pick_object'] = 'post_type';
3475
+ } elseif ( 0 === strpos( $field['pick_object'], 'taxonomy-' ) ) {
3476
+ $field['pick_val'] = pods_str_replace( 'taxonomy-', '', $field['pick_object'], 1 );
3477
+ $field['pick_object'] = 'taxonomy';
3478
+ } elseif ( 'table' === $field['pick_object'] && 0 < strlen( pods_v( 'pick_table', $field ) ) ) {
3479
+ $field['pick_val'] = $field['pick_table'];
3480
+ $field['pick_object'] = 'table';
3481
+ } elseif ( false === strpos( $field['pick_object'], '-' ) && ! in_array( $field['pick_object'], array(
3482
+ 'pod',
3483
+ 'post_type',
3484
+ 'taxonomy'
3485
+ ) ) ) {
3486
+ $field['pick_val'] = '';
3487
+ } elseif ( 'custom-simple' === $field['pick_object'] ) {
3488
+ $field['pick_val'] = '';
3489
+ }
3490
+ }
3491
+
3492
+ foreach ( $options as $o => $v ) {
3493
+ $field[ $o ] = $v;
3494
+ }
3495
+
3496
+ // Check for strict mode (default: strict).
3497
+ $strict_mode = ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT;
3498
+
3499
+ $object_fields = (array) pods_v( 'object_fields', $pod, [], true );
3500
+
3501
+ if ( 0 < $old_id && ! $strict_mode ) {
3502
+ $params->id = $old_id;
3503
+ $field['id'] = $old_id;
3504
+ }
3505
+
3506
+ // Add new field
3507
+ if ( ! isset( $params->id ) || empty( $params->id ) || empty( $field ) ) {
3508
+ if ( $table_operation && $strict_mode && in_array( $field['name'], [
3509
+ 'created',
3510
+ 'modified',
3511
+ ], true ) && ! in_array( $field['type'], [
3512
+ 'date',
3513
+ 'datetime',
3514
+ ], true ) ) {
3515
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
3516
+ }
3517
+
3518
+ if ( $table_operation && $strict_mode && 'author' === $field['name'] && 'pick' !== $field['type'] ) {
3519
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
3520
+ }
3521
+
3522
+ if (
3523
+ in_array( $field['name'], $reserved_keywords, true )
3524
+ && (
3525
+ ! $is_act
3526
+ || ! in_array( $field['name'], $act_safe_keywords, true )
3527
+ )
3528
+ ) {
3529
+ return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
3530
+ }
3531
+
3532
+ foreach ( $object_fields as $object_field => $object_field_opt ) {
3533
+ if ( $object_field === $field['name'] || in_array( $field['name'], $object_field_opt['alias'], true ) ) {
3534
+ 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 );
3535
+ }
3536
+ }
3537
+
3538
+ // Reserved post_name values that can't be used as field names
3539
+ if ( 'rss' === $field['name'] ) {
3540
+ $field['name'] .= '2';
3541
+ }
3542
+
3543
+ if ( 'slug' === $field['type'] && true === $db ) {
3544
+ if ( in_array( $pod['type'], array( 'post_type', 'taxonomy', 'user' ) ) ) {
3545
+ return pods_error( __( 'This pod already has an internal WordPress permalink field', 'pods' ), $this );
3546
+ }
3547
+
3548
+ $slug_field = get_posts( array(
3549
+ 'post_type' => '_pods_field',
3550
+ 'orderby' => 'menu_order',
3551
+ 'order' => 'ASC',
3552
+ 'posts_per_page' => 1,
3553
+ 'post_parent' => $field['pod_id'],
3554
+ 'meta_query' => array(
3555
+ array(
3556
+ 'key' => 'type',
3557
+ 'value' => 'slug'
3558
+ )
3559
+ )
3560
+ ) );
3561
+
3562
+ if ( ! empty( $slug_field ) ) {
3563
+ return pods_error( __( 'This pod already has a permalink field', 'pods' ), $this );
3564
+ }
3565
+ }
3566
+
3567
+ // Sink the new field to the bottom of the list
3568
+ if ( null === $field['weight'] ) {
3569
+ $field['weight'] = 0;
3570
+
3571
+ $bottom_most_field = get_posts( array(
3572
+ 'post_type' => '_pods_field',
3573
+ 'orderby' => 'menu_order',
3574
+ 'order' => 'DESC',
3575
+ 'posts_per_page' => 1,
3576
+ 'post_parent' => $field['pod_id']
3577
+ ) );
3578
+
3579
+ if ( ! empty( $bottom_most_field ) ) {
3580
+ $field['weight'] = pods_absint( $bottom_most_field[0]->menu_order ) + 1;
3581
+ }
3582
+ }
3583
+
3584
+ $field['weight'] = pods_absint( $field['weight'] );
3585
+
3586
+ $post_data = array(
3587
+ 'post_name' => $field['name'],
3588
+ 'post_title' => $field['label'],
3589
+ 'post_content' => $field['description'],
3590
+ 'post_type' => '_pods_field',
3591
+ 'post_parent' => $field['pod_id'],
3592
+ 'post_status' => 'publish',
3593
+ 'menu_order' => $field['weight']
3594
+ );
3595
+ } else {
3596
+ if ( in_array( $field['name'], array( 'id', 'ID' ) ) ) {
3597
+ if ( null !== $old_name ) {
3598
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
3599
+ } else {
3600
+ return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field['name'] ), $this );
3601
+ }
3602
+ }
3603
+
3604
+ if ( $strict_mode && null !== $old_name && $field['name'] !== $old_name ) {
3605
+ if ( in_array( $field['name'], [
3606
+ 'created',
3607
+ 'modified',
3608
+ ] ) && ! in_array( $field['type'], [
3609
+ 'date',
3610
+ 'datetime',
3611
+ ] ) ) {
3612
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
3613
+ }
3614
+
3615
+ if ( 'author' === $field['name'] && 'pick' !== $field['type'] ) {
3616
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
3617
+ }
3618
+ }
3619
+
3620
+ foreach ( $object_fields as $object_field => $object_field_opt ) {
3621
+ if ( $object_field !== $field['name'] && ! in_array( $field['name'], $object_field_opt['alias'], true ) ) {
3622
+ continue;
3623
+ }
3624
+
3625
+ if ( null !== $old_name ) {
3626
+ return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $field['name'] ), $this );
3627
+ } else {
3628
+ return pods_error( sprintf( __( '%s is not editable', 'pods' ), $field['name'] ), $this );
3629
+ }
3630
+ }
3631
+
3632
+ $post_data = array(
3633
+ 'ID' => $field['id'],
3634
+ 'post_name' => $field['name'],
3635
+ 'post_title' => $field['label'],
3636
+ 'post_content' => $field['description']
3637
+ );
3638
+
3639
+ if ( null !== $field['weight'] ) {
3640
+ $field['weight'] = pods_absint( $field['weight'] );
3641
+
3642
+ $post_data['menu_order'] = $field['weight'];
3643
+ }
3644
+ }
3645
+
3646
+ $field_types = PodsForm::field_types_list();
3647
+
3648
+ if ( true === $db ) {
3649
+ if ( ! has_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ) ) ) {
3650
+ add_filter( 'wp_unique_post_slug', array( $this, 'save_slug_fix' ), 100, 6 );
3651
+ }
3652
+
3653
+ $conflicted = false;
3654
+
3655
+ // Headway compatibility fix
3656
+ if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
3657
+ remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
3658
+
3659
+ $conflicted = true;
3660
+ }
3661
+
3662
+ // Store the old field name
3663
+ if ( $old_name && $old_name !== $post_data['post_name'] ) {
3664
+ $field['old_name'] = $old_name;
3665
+ }
3666
+
3667
+ $meta = $field;
3668
+
3669
+ $excluded_meta = array(
3670
+ 'id',
3671
+ 'name',
3672
+ 'label',
3673
+ 'description',
3674
+ 'pod_id',
3675
+ 'pod',
3676
+ 'weight',
3677
+ 'options',
3678
+ 'fields',
3679
+ 'groups',
3680
+ 'object_fields',
3681
+ 'object_type',
3682
+ 'storage_type',
3683
+ 'parent',
3684
+ );
3685
+
3686
+ foreach ( $excluded_meta as $meta_key ) {
3687
+ if ( isset( $meta[ $meta_key ] ) ) {
3688
+ unset( $meta[ $meta_key ] );
3689
+ }
3690
+ }
3691
+
3692
+ // Get all field types except the current.
3693
+ $field_types = array_diff( $field_types, [ $field['type'] ] );
3694
+
3695
+ $pattern = '/^(' . implode( '|', $field_types ) . ')_/';
3696
+
3697
+ // Filter meta that is not for the current field type.
3698
+ $meta = array_filter( $meta, static function ( $value, $key ) use ( $pattern ) {
3699
+ return 1 !== preg_match( $pattern, $key );
3700
+ }, ARRAY_FILTER_USE_BOTH );
3701
+
3702
+ $params->id = $this->save_wp_object( 'post', $post_data, $meta, true, true );
3703
+
3704
+ if ( $conflicted ) {
3705
+ add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
3706
+ }
3707
+
3708
+ if ( false === $params->id ) {
3709
+ return pods_error( __( 'Cannot save Field', 'pods' ), $this );
3710
+ }
3711
+ } else {
3712
+ $params->id = $field['name'];
3713
+ }
3714
+
3715
+ $field['id'] = $params->id;
3716
+
3717
+ $simple = ( 'pick' === $field['type'] && in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) );
3718
+
3719
+ $definition = false;
3720
+ $field_definition = false;
3721
+
3722
+ if ( $simple || ! $type_is_tableless ) {
3723
+ $field_definition = $this->get_field_definition( $field['type'], $field );
3724
+ }
3725
+
3726
+ /**
3727
+ * Allow filtering of the field definition when saving field.
3728
+ *
3729
+ * @since 2.8.0
3730
+ *
3731
+ * @param string|false $field_definition The SQL definition to use for the field's table column.
3732
+ * @param string $type The field type.
3733
+ * @param array $field The field data.
3734
+ * @param bool $simple Whether the field is a simple tableless field.
3735
+ * @param Pods\Whatsit\Field $field_obj The field object.
3736
+ */
3737
+ $field_definition = apply_filters( 'pods_api_save_field_definition', $field_definition, $field['type'], $field, $simple, $field_obj );
3738
+
3739
+ if ( ! empty( $field_definition ) ) {
3740
+ $definition = '`' . $field['name'] . '` ' . $field_definition;
3741
+ }
3742
+
3743
+ $has_definition = ! empty( $definition );
3744
+ $has_old_definition = ! empty( $old_definition );
3745
+ $simple_diff = $old_simple !== $simple;
3746
+ $definition_diff = $old_definition !== $definition;
3747
+
3748
+ $sister_id = (int) pods_v( 'sister_id', $field, 0 );
3749
+
3750
+ $definition_mode = 'bypass';
3751
+
3752
+ if ( $table_operation && 'table' === $pod['storage'] && ! pods_tableless() ) {
3753
+ if ( ! empty( $old_id ) ) {
3754
+ if ( ( ( $field['type'] !== $old_type ) || $simple_diff ) && ! $has_definition ) {
3755
+ $definition_mode = 'drop';
3756
+ } elseif ( $has_definition ) {
3757
+ if ( $simple_diff || $old_name !== $field['name'] || $definition_diff ) {
3758
+ $definition_mode = 'add';
3759
 
3760
+ if ( $has_old_definition ) {
3761
+ $definition_mode = 'change';
3762
+ }
3763
+ } elseif ( $has_old_definition && $definition_diff ) {
3764
+ $definition_mode = 'change';
3765
+ }
3766
+ }
3767
+ } elseif ( $has_definition ) {
3768
+ $definition_mode = 'add';
3769
+
3770
+ if ( $has_old_definition ) {
3771
+ $definition_mode = 'change';
3772
+ }
3773
  }
3774
 
3775
+ if ( 'bypass' !== $definition_mode ) {
3776
+ /**
3777
+ * Allow hooking into before the table has been altered for any custom functionality needed.
3778
+ *
3779
+ * @since 2.7.17
3780
+ *
3781
+ * @param string $definition_mode The definition mode used for the table field.
3782
+ * @param Pods\Whatsit\Pod $pod The pod object.
3783
+ * @param string $type The field type.
3784
+ * @param array $field The field data.
3785
+ * @param array $extra_info {
3786
+ * Extra information about the field.
3787
+ *
3788
+ * @type bool $simple Whether the field is a simple tableless field.
3789
+ * @type string $definition The field definition.
3790
+ * @type null|string $old_name The old field name (if preexisting).
3791
+ * @type null|string $old_definition The old field definition (if preexisting).
3792
+ * @type null|array $old_options The old field options (if preexisting).
3793
+ * @type Pods\Whatsit\Field $field_obj The field object.
3794
+ * }
3795
+ */
3796
+ do_action( 'pods_api_save_field_table_pre_alter', $definition_mode, $pod, $field['type'], $field, [
3797
+ 'simple' => $simple,
3798
+ 'definition' => $definition,
3799
+ 'old_name' => $old_name,
3800
+ 'old_definition' => $old_definition,
3801
+ 'old_options' => $old_options,
3802
+ 'field_obj' => $field_obj,
3803
+ ] );
3804
+
3805
+ if ( 'drop' === $definition_mode ) {
3806
+ // Drop field column.
3807
+ pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$old_name}`", false );
3808
+ } elseif ( 'change' === $definition_mode ) {
3809
+ // Change field column definition.
3810
+ if ( $old_name && $old_name !== $field['name'] ) {
3811
+ $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` CHANGE `{$old_name}` {$definition}", false );
3812
+ } else {
3813
+ $test = pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` MODIFY {$definition}", false );
3814
+ }
3815
+
3816
+ if ( false === $test ) {
3817
+ $definition_mode = 'add';
3818
+ }
3819
+ }
3820
+
3821
+ // If the old field doesn't exist, continue to add a new field
3822
+ if ( 'add' === $definition_mode ) {
3823
+ pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` ADD COLUMN {$definition}", __( 'Cannot create new field', 'pods' ) );
3824
+ }
3825
+
3826
+ /**
3827
+ * Allow hooking into after the table has been altered for any custom functionality needed.
3828
+ *
3829
+ * @since 2.7.17
3830
+ *
3831
+ * @param string $definition_mode The definition mode used for the table field.
3832
+ * @param Pods\Whatsit\Pod $pod The pod object.
3833
+ * @param string $type The field type.
3834
+ * @param array $field The field object.
3835
+ * @param array $extra_info {
3836
+ * Extra information about the field.
3837
+ *
3838
+ * @type bool $simple Whether the field is a simple tableless field.
3839
+ * @type string $definition The field definition.
3840
+ * @type null|string $old_name The old field name (if preexisting).
3841
+ * @type null|string $old_definition The old field definition (if preexisting).
3842
+ * @type null|array $old_options The old field options (if preexisting).
3843
+ * @type Pods\Whatsit\Field $field_obj The field object.
3844
+ * }
3845
+ */
3846
+ do_action( 'pods_api_save_field_table_altered', $definition_mode, $pod, $field['type'], $field, [
3847
+ 'simple' => $simple,
3848
+ 'definition' => $definition,
3849
+ 'old_name' => $old_name,
3850
+ 'old_definition' => $old_definition,
3851
+ 'old_options' => $old_options,
3852
+ 'field_obj' => $field_obj,
3853
+ ] );
3854
+ }
3855
+ }
3856
+
3857
+ if ( ! empty( $old_id ) && 'meta' === $pod['storage'] && $old_name !== $field['name'] && $pod['meta_table'] !== $pod['table'] ) {
3858
+ $prepare = array(
3859
+ $field['name'],
3860
+ $old_name
3861
+ );
3862
+
3863
+ // Users don't have a type
3864
+ if ( ! empty( $pod['field_type'] ) ) {
3865
+ $prepare[] = $pod['name'];
3866
+ }
3867
+
3868
+ $join_table = $pod['table'];
3869
+
3870
+ // Taxonomies are the odd type out, terrible I know
3871
+ if ( 'taxonomy' === $pod['type'] ) {
3872
+ // wp_term_taxonomy has the 'taxonomy' field we need to limit by
3873
+ $join_table = $wpdb->term_taxonomy;
3874
+ }
3875
+
3876
+ pods_query( "
3877
+ UPDATE `{$pod[ 'meta_table' ]}` AS `m`
3878
+ LEFT JOIN `{$join_table}` AS `t`
3879
+ ON `t`.`{$pod[ 'field_id' ]}` = `m`.`{$pod[ 'meta_field_id' ]}`
3880
+ SET
3881
+ `m`.`{$pod[ 'meta_field_index' ]}` = %s
3882
+ WHERE
3883
+ `m`.`{$pod[ 'meta_field_index' ]}` = %s
3884
+ " . ( ! empty( $pod['field_type'] ) ? " AND `t`.`{$pod[ 'field_type' ]}` = %s" : "" ), $prepare );
3885
+ }
3886
+
3887
+ if ( $old_type_is_tableless && $field['type'] !== $old_type ) {
3888
+ delete_post_meta( $old_sister_id, 'sister_id' );
3889
+
3890
+ if ( true === $db ) {
3891
+ pods_query( "
3892
+ DELETE pm
3893
+ FROM {$wpdb->postmeta} AS pm
3894
+ LEFT JOIN {$wpdb->posts} AS p
3895
+ ON p.post_type = '_pods_field'
3896
+ AND p.ID = pm.post_id
3897
+ WHERE
3898
+ p.ID IS NOT NULL
3899
+ AND pm.meta_key = 'sister_id'
3900
+ AND pm.meta_value = %d
3901
+ ", array(
3902
+ $params->id,
3903
+ ) );
3904
+
3905
+ if ( pods_podsrel_enabled() ) {
3906
+ pods_query( "DELETE FROM @wp_podsrel WHERE `field_id` = {$params->id}", false );
3907
+
3908
+ pods_query( '
3909
+ UPDATE `@wp_podsrel`
3910
+ SET `related_field_id` = 0
3911
+ WHERE `field_id` = %d
3912
+ ', array(
3913
+ $old_sister_id,
3914
+ ) );
3915
+ }
3916
+ }
3917
+ } elseif ( 0 < $sister_id ) {
3918
+ update_post_meta( $sister_id, 'sister_id', $params->id );
3919
+
3920
+ if ( true === $db && pods_podsrel_enabled() ) {
3921
+ pods_query( '
3922
+ UPDATE `@wp_podsrel`
3923
+ SET `related_field_id` = %d
3924
+ WHERE `field_id` = %d
3925
+ ', array(
3926
+ $params->id,
3927
+ $sister_id,
3928
+ ) );
3929
+ }
3930
+ } elseif ( 0 < $old_sister_id ) {
3931
+ delete_post_meta( $old_sister_id, 'sister_id' );
3932
+
3933
+ if ( true === $db && pods_podsrel_enabled() ) {
3934
+ pods_query( '
3935
+ UPDATE `@wp_podsrel`
3936
+ SET `related_field_id` = 0
3937
+ WHERE `field_id` = %d
3938
+ ', array(
3939
+ $old_sister_id,
3940
+ ) );
3941
+ }
3942
+ }
3943
+
3944
+ if ( ! empty( $old_id ) && $old_name !== $field['name'] && true === $db ) {
3945
+ pods_query( '
3946
+ UPDATE `@wp_postmeta`
3947
+ SET `meta_value` = %s
3948
+ WHERE
3949
+ `post_id` = %d
3950
+ AND `meta_key` = "pod_index"
3951
+ AND `meta_value` = %s
3952
+ ', array(
3953
+ $field['name'],
3954
+ $pod['id'],
3955
+ $old_name,
3956
+ ) );
3957
+ }
3958
+
3959
+ $object_collection = Pods\Whatsit\Store::get_instance();
3960
+
3961
+ $storage_type = 'collection';
3962
+
3963
+ if ( true === $db ) {
3964
+ $storage_type = $this->get_default_object_storage_type();
3965
+ }
3966
+
3967
+ /** @var Pods\Whatsit\Storage $storage */
3968
+ $storage = $object_collection->get_storage_object( $storage_type );
3969
+
3970
+ $object = $storage->to_object( $field['id'], true );
3971
+
3972
+ if ( ! $object ) {
3973
+ return pods_error( __( 'Cannot save field to collection', 'pods' ), $this );
3974
+ }
3975
+
3976
+ if ( ! $save_pod ) {
3977
+ $this->cache_flush_pods( $pod );
3978
+ }
3979
+
3980
+ if ( true === $db ) {
3981
+ return $params->id;
3982
+ } else {
3983
+ return $object;
3984
+ }
3985
+ }
3986
+
3987
+ /**
3988
+ * Add a Group within a Pod.
3989
+ *
3990
+ * @since 2.8.0
3991
+ *
3992
+ * @param array $params {
3993
+ * An associative array of parameters
3994
+ *
3995
+ * @type int|null $id The Group ID (id OR pod_id+name OR pod+name required).
3996
+ * @type string|null $name The Group name (id OR pod_id+name OR pod+name required).
3997
+ * @type int|null $pod_id The Pod ID (id OR pod_id+name OR pod+name required).
3998
+ * @type string|null $pod The Pod name (id OR pod_id+name OR pod+name required).
3999
+ * @type string|null $label The Group label.
4000
+ * @type string|null $type The Group type.
4001
+ * @type int|null $weight The order in which the Group appears.
4002
+ * }
4003
+ * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed,
4004
+ * will sanitize them if false.
4005
+ * @param bool|int $db (optional) Whether to save into the DB or just return group array.
4006
+ *
4007
+ * @return int|array The group ID or group array (if !$db)
4008
+ *
4009
+ * @throws \Exception
4010
+ */
4011
+ public function add_group( $params, $sanitized = false, $db = true ) {
4012
+ $params = (object) $params;
4013
+
4014
+ $params->is_new = true;
4015
+
4016
+ return $this->save_group( $params, $sanitized, $db );
4017
+ }
4018
+
4019
+ /**
4020
+ * Add or edit a Group within a Pod.
4021
+ *
4022
+ * @since 2.8.0
4023
+ *
4024
+ * @param array|Group $params {
4025
+ * An associative array of parameters
4026
+ *
4027
+ * @type int|null $id The Group ID (id OR pod_id+name OR pod+name required).
4028
+ * @type string|null $name The Group name (id OR pod_id+name OR pod+name required).
4029
+ * @type int|null $pod_id The Pod ID (id OR pod_id+name OR pod+name required).
4030
+ * @type string|null $pod The Pod name (id OR pod_id+name OR pod+name required).
4031
+ * @type string|null $label The Group label.
4032
+ * @type string|null $type The Group type.
4033
+ * @type int|null $weight The order in which the Group appears.
4034
+ * @type bool $is_new Whether to try to add the group as a new group when passing name.
4035
+ * @type bool $overwrite Whether to try to replace the existing group if name and no ID is passed.
4036
+ * }
4037
+ * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed,
4038
+ * will sanitize them if false.
4039
+ * @param bool|int $db (optional) Whether to save into the DB or just return group array.
4040
+ *
4041
+ * @return int|array The group ID or group array (if !$db)
4042
+ *
4043
+ * @throws \Exception
4044
+ */
4045
+ public function save_group( $params, $sanitized = false, $db = true ) {
4046
+ if ( $params instanceof Group ) {
4047
+ $params = [
4048
+ 'id' => $params->get_id(),
4049
+ 'group' => $params,
4050
+ ];
4051
+ }
4052
+
4053
+ $params = (object) $params;
4054
+
4055
+ $pod = null;
4056
+ $group = null;
4057
+
4058
+ // Setup Pod if passed.
4059
+ if ( isset( $params->pod_data ) && $params->pod_data instanceof Pod ) {
4060
+ $pod = $params->pod_data;
4061
+
4062
+ unset( $params->pod_data );
4063
+
4064
+ $params->pod = $pod->get_name();
4065
+ $params->pod_id = $pod->get_id();
4066
+ } elseif ( isset( $params->pod ) && $params->pod instanceof Pod ) {
4067
+ $pod = $params->pod;
4068
+
4069
+ $params->pod = $pod->get_name();
4070
+ $params->pod_id = $pod->get_id();
4071
+ } elseif ( isset( $params->pod ) && is_array( $params->pod ) ) {
4072
+ $pod = $params->pod;
4073
+
4074
+ $params->pod = $pod['name'];
4075
+ $params->pod_id = $pod['id'];
4076
+ } elseif ( isset( $params->pod_id ) ) {
4077
+ $params->pod_id = pods_absint( $params->pod_id );
4078
+ }
4079
+
4080
+ // Setup Group if passed.
4081
+ if ( isset( $params->group ) && $params->group instanceof Group ) {
4082
+ $group = $params->group;
4083
+
4084
+ unset( $params->group );
4085
+
4086
+ $params->id = $group->get_id();
4087
+ } elseif ( isset( $params->group ) && is_array( $params->group ) ) {
4088
+ $group = $params->group;
4089
+
4090
+ unset( $params->group );
4091
+
4092
+ $params->id = $group['id'];
4093
+ } elseif ( isset( $params->id ) ) {
4094
+ $params->id = pods_absint( $params->id );
4095
+ }
4096
+
4097
+ if ( false === $sanitized ) {
4098
+ $params = pods_sanitize( $params );
4099
+
4100
+ $sanitized = true;
4101
+ }
4102
+
4103
+ $id_required = false;
4104
+
4105
+ if ( isset( $params->id_required ) ) {
4106
+ $id_required = (boolean) $params->id_required;
4107
+
4108
+ unset( $params->id_required );
4109
+ }
4110
+
4111
+ $params->is_new = isset( $params->is_new ) ? (boolean) $params->is_new : false;
4112
+ $params->overwrite = isset( $params->overwrite ) ? (boolean) $params->overwrite : false;
4113
+
4114
+ if ( ! $pod && ( ! isset( $params->pod ) || empty( $params->pod ) ) && ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) ) {
4115
+ return pods_error( __( 'Pod ID or name is required', 'pods' ), $this );
4116
+ }
4117
+
4118
+ if ( ! $pod ) {
4119
+ if ( ( ! isset( $params->pod_id ) || empty( $params->pod_id ) ) && ( true === $db || 0 < $db ) ) {
4120
+ $pod = $this->load_pod( array( 'name' => $params->pod ), false );
4121
+ } elseif ( ! isset( $params->pod ) && ( true === $db || 0 < $db ) ) {
4122
+ $pod = $this->load_pod( array( 'id' => $params->pod_id ), false );
4123
+ } elseif ( true === $db || 0 < $db ) {
4124
+ $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod ), false );
4125
+ }
4126
+ }
4127
+
4128
+ if ( empty( $pod ) && true === $db ) {
4129
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
4130
+ }
4131
+
4132
+ $reserved_keywords = pods_reserved_keywords();
4133
+
4134
+ /** @var Pod $pod */
4135
+ $params->pod_id = $pod->get_id();
4136
+ $params->pod = $pod->get_name();
4137
+
4138
+ if ( isset( $params->name ) ) {
4139
+ $params->name = pods_clean_name( $params->name, true, 'meta' !== $pod['storage'] );
4140
+
4141
+ if ( $params->is_new && isset( $params->id ) ) {
4142
+ $params->id = null;
4143
+ }
4144
+ }
4145
+
4146
+ if ( empty( $params->name ) && empty( $params->id ) ) {
4147
+ return pods_error( __( 'Pod group name is required', 'pods' ), $this );
4148
+ }
4149
+
4150
+ $load_params = array(
4151
+ 'parent' => $params->pod_id,
4152
+ );
4153
+
4154
+ if ( ! empty( $params->id ) ) {
4155
+ $load_params['id'] = $params->id;
4156
+ } elseif ( ! empty( $params->old_name ) ) {
4157
+ $load_params['name'] = $params->old_name;
4158
+ } elseif ( ! empty( $params->name ) ) {
4159
+ $load_params['name'] = $params->name;
4160
+ }
4161
+
4162
+ $group = $this->load_group( $load_params );
4163
+
4164
+ if ( $group instanceof Group ) {
4165
+ $group = $group->get_args();
4166
+ }
4167
+
4168
+ $old_id = null;
4169
+ $old_name = null;
4170
+
4171
+ if ( ! empty( $group ) ) {
4172
+ $old_id = $group['id'];
4173
+ $old_name = $group['name'];
4174
+
4175
+ // Maybe set up the group to save over the existing group.
4176
+ if ( $params->overwrite && empty( $params->id ) ) {
4177
  $params->id = $old_id;
4178
  }
4179
 
4180
+ if ( isset( $params->new_name ) && ! empty( $params->new_name ) ) {
4181
+ $group['name'] = $params->new_name;
4182
 
4183
+ unset( $params->new_name );
4184
+ } elseif ( isset( $params->name ) ) {
4185
+ $group['name'] = $params->name;
4186
+ }
4187
+
4188
+ if ( $old_name !== $group['name'] || empty( $params->id ) || $old_id !== $params->id ) {
4189
+ if ( in_array( $params->name, $reserved_keywords, true ) ) {
4190
+ return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $params->name ), $this );
4191
  }
4192
+
4193
+ if ( false !== $this->group_exists( $params, false ) ) {
4194
+ return pods_error( sprintf( __( 'Group %1$s already exists, you cannot rename %2$s to that', 'pods' ), $params->name, $old_name ), $this );
4195
+ }
4196
+ }
4197
+
4198
+ if ( ( $id_required || ! empty( $params->id ) ) && ( empty( $old_id ) || $old_id !== $params->id ) ) {
4199
+ return pods_error( sprintf( __( 'Group %s already exists', 'pods' ), $params->name ), $this );
4200
+ }
4201
+
4202
+ if ( empty( $params->id ) ) {
4203
+ $params->id = $old_id;
4204
  }
4205
  } else {
4206
+ $group = [
4207
  'id' => 0,
4208
  'pod_id' => $params->pod_id,
4209
+ 'name' => $params->name,
4210
+ 'label' => $params->name,
4211
+ 'description' => '',
4212
+ 'type' => '',
 
 
 
4213
  'weight' => null,
4214
+ 'options' => [],
4215
+ ];
4216
  }
4217
 
4218
  // Setup options
4219
  $options = get_object_vars( $params );
4220
 
4221
+ $options_ignore = [
4222
  'method',
4223
  'table_info',
4224
  'attributes',
4227
  'developer_mode',
4228
  'dependency',
4229
  'depends-on',
4230
+ 'excludes-on',
4231
+ 'object_type',
4232
+ 'storage_type',
4233
+ 'is_new',
4234
+ 'overwrite',
4235
+ '_locale',
4236
+ 'old_name',
4237
+ ];
4238
 
4239
  foreach ( $options_ignore as $ignore ) {
4240
  if ( isset( $options[ $ignore ] ) ) {
4242
  }
4243
  }
4244
 
4245
+ $exclude = [
 
 
 
 
 
 
4246
  'id',
4247
  'pod_id',
4248
  'pod',
4250
  'label',
4251
  'description',
4252
  'type',
 
 
 
4253
  'weight',
4254
+ 'options',
4255
+ 'is_new',
4256
+ 'overwrite',
4257
+ '_locale',
4258
+ 'post_status',
4259
+ ];
4260
 
4261
+ foreach ( $exclude as $k => $exclude_group ) {
4262
+ $aliases = array( $exclude_group );
4263
 
4264
+ if ( is_array( $exclude_group ) ) {
4265
+ $aliases = array_merge( array( $k ), $exclude_group );
4266
+ $exclude_group = $k;
4267
  }
4268
 
4269
  foreach ( $aliases as $alias ) {
4270
  if ( isset( $options[ $alias ] ) ) {
4271
+ $group[ $exclude_group ] = pods_trim( $options[ $alias ] );
4272
 
4273
  unset( $options[ $alias ] );
4274
  }
4275
  }
4276
  }
4277
 
4278
+ if ( '' === $group['label'] ) {
4279
+ $group['label'] = $group['name'];
4280
  }
4281
 
4282
+ foreach ( $options as $o => $v ) {
4283
+ $group[ $o ] = $v;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4284
  }
4285
 
4286
+ // Check for strict mode (default: strict).
4287
+ $strict_mode = ! defined( 'PODS_FIELD_STRICT' ) || PODS_FIELD_STRICT;
4288
 
4289
+ if ( 0 < $old_id && ! $strict_mode ) {
 
 
4290
  $params->id = $old_id;
4291
+ $group['id'] = $old_id;
4292
  }
4293
 
4294
+ // Add new group.
4295
+ if ( ! isset( $params->id ) || empty( $params->id ) || empty( $group ) ) {
4296
+ if ( in_array( $group['name'], $reserved_keywords, true ) ) {
4297
+ return pods_error( sprintf( __( '%s is reserved for internal WordPress or Pods usage, please try a different name', 'pods' ), $group['name'] ), $this );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4298
  }
4299
 
4300
+ // Reserved post_name values that can't be used as group names
4301
+ if ( 'rss' === $group['name'] ) {
4302
+ $group['name'] .= '2';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4303
  }
4304
 
4305
+ // Sink the new group to the bottom of the list
4306
+ if ( null === $group['weight'] ) {
4307
+ $group['weight'] = 0;
4308
 
4309
+ $bottom_most_group = get_posts( array(
4310
+ 'post_type' => '_pods_group',
4311
  'orderby' => 'menu_order',
4312
  'order' => 'DESC',
4313
  'posts_per_page' => 1,
4314
+ 'post_parent' => $group['pod_id']
4315
  ) );
4316
 
4317
+ if ( ! empty( $bottom_most_group ) ) {
4318
+ $group['weight'] = pods_absint( $bottom_most_group[0]->menu_order ) + 1;
4319
  }
4320
  }
4321
 
4322
+ $group['weight'] = pods_absint( $group['weight'] );
4323
 
4324
  $post_data = array(
4325
+ 'post_name' => $group['name'],
4326
+ 'post_title' => $group['label'],
4327
+ 'post_content' => $group['description'],
4328
+ 'post_type' => '_pods_group',
4329
+ 'post_parent' => $group['pod_id'],
4330
  'post_status' => 'publish',
4331
+ 'menu_order' => $group['weight']
4332
  );
4333
  } else {
4334
+ if ( in_array( $group['name'], array( 'id', 'ID' ) ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4335
  if ( null !== $old_name ) {
4336
+ return pods_error( sprintf( __( '%s is reserved for internal Pods usage, please try a different name', 'pods' ), $group['name'] ), $this );
4337
  } else {
4338
+ return pods_error( sprintf( __( '%s is not editable', 'pods' ), $group['name'] ), $this );
4339
  }
4340
  }
4341
 
4342
  $post_data = array(
4343
+ 'ID' => $group['id'],
4344
+ 'post_name' => $group['name'],
4345
+ 'post_title' => $group['label'],
4346
+ 'post_content' => $group['description']
4347
  );
4348
 
4349
+ if ( null !== $group['weight'] ) {
4350
+ $group['weight'] = pods_absint( $group['weight'] );
4351
 
4352
+ $post_data['menu_order'] = $group['weight'];
4353
  }
4354
  }
4355
 
4360
 
4361
  $conflicted = false;
4362
 
4363
+ // Headway compatibility fix
4364
+ if ( has_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 ) ) {
4365
+ remove_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4366
 
4367
+ $conflicted = true;
 
 
 
4368
  }
4369
 
4370
+ // Store the old group name
4371
+ if ( $old_name && $old_name !== $post_data['post_name'] ) {
4372
+ $group['old_name'] = $old_name;
4373
+ }
 
 
 
 
 
 
 
 
 
4374
 
4375
+ $meta = $group;
 
 
 
 
 
 
 
 
 
 
 
 
 
4376
 
4377
+ $excluded_meta = array(
4378
+ 'id',
4379
+ 'name',
4380
+ 'label',
4381
+ 'description',
4382
+ 'pod_id',
4383
+ 'pod',
4384
+ 'weight',
4385
+ 'options',
4386
+ 'groups',
4387
+ 'group',
4388
+ 'fields',
4389
+ 'object_fields',
4390
+ 'is_new',
4391
+ 'overwrite',
4392
+ '_locale',
4393
+ );
4394
 
4395
+ foreach ( $excluded_meta as $meta_key ) {
4396
+ if ( isset( $meta[ $meta_key ] ) ) {
4397
+ unset( $meta[ $meta_key ] );
 
 
 
 
4398
  }
4399
  }
 
 
4400
 
4401
+ $params->id = $this->save_wp_object( 'post', $post_data, $meta, true, true );
4402
+
4403
+ if ( $conflicted ) {
4404
+ add_filter( 'wp_insert_post_data', 'headway_clean_slug', 0 );
 
 
 
 
 
4405
  }
 
 
4406
 
4407
+ if ( false === $params->id ) {
4408
+ return pods_error( __( 'Cannot save Group', 'pods' ), $this );
 
 
 
 
 
 
4409
  }
4410
+ } else {
4411
+ $params->id = $group['name'];
4412
  }
4413
 
4414
+ $group['id'] = $params->id;
 
 
 
 
 
 
 
 
 
 
 
 
 
4415
 
4416
+ $object_collection = Pods\Whatsit\Store::get_instance();
 
 
 
4417
 
4418
+ /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */
4419
+ $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() );
4420
+
4421
+ $object = $post_type_storage->to_object( $group['id'], true );
4422
+
4423
+ if ( ! $object ) {
4424
+ return pods_error( __( 'Cannot save group to collection', 'pods' ), $this );
4425
+ }
4426
+
4427
+ $this->cache_flush_pods( $object );
4428
 
4429
  if ( true === $db ) {
4430
  return $params->id;
4431
  } else {
4432
+ return $object;
4433
  }
4434
  }
4435
 
4436
  /**
4437
+ * Fix Pod / Group / Field post_name to ensure they are exactly as saved (allow multiple posts w/ same post_name)
4438
  *
4439
  * @param string $slug Unique slug value
4440
  * @param int $post_ID Post ID
4448
  * @since 2.3.3
4449
  */
4450
  public function save_slug_fix( $slug, $post_ID, $post_status, $post_type, $post_parent = 0, $original_slug = null ) {
4451
+ if ( in_array( $post_type, array( '_pods_pod', '_pods_group', '_pods_field' ), true ) && false !== strpos( $slug, '-' ) ) {
 
4452
  $slug = $original_slug;
4453
  }
4454
 
4461
  * $params['id'] int The Object ID
4462
  * $params['name'] string The Object name
4463
  * $params['type'] string The Object type
 
4464
  *
4465
  * @param array|object $params An associative array of parameters
4466
  * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed,
4475
 
4476
  if ( false === $sanitized ) {
4477
  $params = pods_sanitize( $params );
4478
+
4479
+ $sanitized = true;
4480
  }
4481
 
4482
  if ( ! isset( $params->name ) || empty( $params->name ) ) {
4487
  return pods_error( __( 'Type must be given to save an Object', 'pods' ), $this );
4488
  }
4489
 
4490
+ $object = [
4491
+ 'id' => isset( $params->id ) ? $params->id : 0,
4492
+ 'name' => $params->name,
4493
+ 'type' => $params->type,
4494
+ 'code' => isset( $params->code ) ? $params->code : '',
4495
+ ];
 
4496
 
4497
  // Setup options
4498
  $options = get_object_vars( $params );
4499
 
4500
+ if ( isset( $options['options'] ) ) {
4501
+ $options = array_merge( $options, $options['options'] );
4502
+
4503
+ unset( $options['options'] );
4504
+ }
4505
+
4506
  if ( isset( $options['method'] ) ) {
4507
  unset( $options['method'] );
4508
  }
4509
 
4510
+ $post_meta = $options;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4511
 
4512
+ $exclude = array_keys( $object );
 
 
4513
 
4514
+ foreach ( $exclude as $excluded_key ) {
4515
+ if ( isset( $post_meta[ $excluded_key ] ) ) {
4516
+ unset( $post_meta[ $excluded_key ] );
4517
  }
4518
  }
4519
 
4520
+ $object = array_merge( $options, $object );
 
 
 
 
 
 
 
 
4521
 
4522
  $post_data = array(
4523
  'post_name' => pods_clean_name( $object['name'], true ),
4531
  $post_data['ID'] = $object['id'];
4532
  }
4533
 
4534
+ $post_status = pods_v( 'status', $object, null, true );
4535
+
4536
+ if ( null !== $post_status ) {
4537
+ $post_data['post_status'] = $post_status;
4538
  }
4539
 
4540
  remove_filter( 'content_save_pre', 'balanceTags', 50 );
4541
 
4542
  $post_data = pods_sanitize( $post_data );
4543
 
4544
+ $params->id = $this->save_post( $post_data, $post_meta, true, true );
4545
 
4546
  pods_transient_clear( 'pods_objects_' . $params->type );
4547
  pods_transient_clear( 'pods_objects_' . $params->type . '_get' );
4559
  * $params['code'] string The template code
4560
  *
4561
  * @param array|object $params An associative array of parameters
4562
+ * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed,
4563
  * will sanitize them if false.
4564
  *
4565
  * @return int The Template ID
4585
  * $params['code'] string The page code
4586
  *
4587
  * @param array|object $params An associative array of parameters
4588
+ * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed,
4589
  * will sanitize them if false.
4590
  *
4591
  * @return int The page ID
4622
  * $params['code'] string The helper code
4623
  *
4624
  * @param array $params An associative array of parameters
4625
+ * @param bool $sanitized (optional) Decides whether the params have been sanitized before being passed, will
4626
  * sanitize them if false.
4627
  *
4628
  * @return int The helper ID
4629
  * @since 1.7.9
4630
+ *
4631
+ * @deprecated since 2.8.0
4632
  */
4633
  public function save_helper( $params, $sanitized = false ) {
4634
+ return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4635
  }
4636
 
4637
  /**
4660
 
4661
  $tableless_field_types = PodsForm::tableless_field_types();
4662
  $repeatable_field_types = PodsForm::repeatable_field_types();
4663
+ $layout_field_types = PodsForm::layout_field_types();
4664
  $simple_tableless_objects = PodsForm::simple_tableless_objects();
4665
 
4666
  $error_mode = $this->display_errors;
4669
  $error_mode = $params->error_mode;
4670
  }
4671
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4672
  if ( ! isset( $params->pod ) ) {
4673
  $params->pod = false;
4674
  }
4754
  }
4755
 
4756
  // Get array of Pods
4757
+ $pod = $this->load_pod( array( 'id' => $params->pod_id, 'name' => $params->pod ), false );
4758
 
4759
  if ( false === $pod ) {
4760
  return pods_error( __( 'Pod not found', 'pods' ), $error_mode );
4767
  $params->id = $pod['id'];
4768
  }
4769
 
4770
+ $fields = $pod->get_fields();
4771
+ $object_fields = $pod->get_object_fields();
4772
 
4773
+ // Map the fields to Value_Field to store values.
4774
+ $fields = array_map( [ Value_Field::class, 'init' ], $fields );
4775
+ $object_fields = array_map( [ Value_Field::class, 'init' ], $object_fields );
4776
 
4777
  $fields_active = array();
4778
  $custom_data = array();
4783
  foreach ( $params->data as $field => $value ) {
4784
  if ( isset( $object_fields[ $field ] ) ) {
4785
  $object_fields[ $field ]['value'] = $value;
4786
+
4787
+ $fields_active[] = $field;
4788
  } elseif ( isset( $fields[ $field ] ) ) {
4789
+ if ( 'save' === $params->from || true === pods_permission( $fields[ $field ] ) ) {
4790
  $fields[ $field ]['value'] = $value;
4791
+
4792
+ $fields_active[] = $field;
4793
+ } elseif ( ! pods_has_permissions( $fields[ $field ] ) && pods_v( 'hidden', $fields[ $field ], false ) ) {
4794
  $fields[ $field ]['value'] = $value;
4795
+
4796
+ $fields_active[] = $field;
4797
  }
4798
  } else {
4799
  $found = false;
4801
  foreach ( $object_fields as $object_field => $object_field_opt ) {
4802
  if ( in_array( $field, $object_field_opt['alias'] ) ) {
4803
  $object_fields[ $object_field ]['value'] = $value;
4804
+
4805
+ $fields_active[] = $object_field;
4806
 
4807
  $found = true;
4808
 
4825
  unset( $params->data );
4826
  }
4827
 
4828
+ if ( empty( $params->id ) && isset( $fields['created'] ) && ! in_array( 'created', $fields_active, true ) && in_array( $fields['created']['type'], array(
4829
  'date',
4830
  'datetime'
4831
+ ), true ) ) {
4832
  $fields['created']['value'] = current_time( 'mysql' );
4833
+
4834
+ $fields_active[] = 'created';
4835
  }
4836
 
4837
+ if ( isset( $fields['modified'] ) && ! in_array( 'modified', $fields_active, true ) && in_array( $fields['modified']['type'], array(
4838
  'date',
4839
  'datetime'
4840
+ ), true ) ) {
4841
  $fields['modified']['value'] = current_time( 'mysql' );
4842
+
4843
+ $fields_active[] = 'modified';
4844
  }
4845
 
4846
+ if ( empty( $params->id ) && ! empty( $pod['pod_field_index'] ) && isset( $fields[ $pod['pod_field_slug'] ] ) && in_array( $pod['type'], array(
4847
  'pod',
4848
  'table'
4849
+ ), true ) && in_array( $pod['pod_field_index'], $fields_active, true ) && ! in_array( $pod['pod_field_slug'], $fields_active, true ) ) {
4850
  $fields[ $pod['pod_field_slug'] ]['value'] = ''; // this will get picked up by slug pre_save method
4851
+
4852
+ $fields_active[] = $pod['pod_field_slug'];
4853
  }
4854
 
4855
  // Handle hidden fields
4856
  if ( empty( $params->id ) ) {
4857
  foreach ( $fields as $field => $field_data ) {
4858
+ if ( in_array( $field, $fields_active, true ) ) {
4859
  continue;
4860
  }
4861
 
4862
  if ( in_array( $params->from, array(
4863
  'save',
4864
  'process_form'
4865
+ ), true ) || true === pods_permission( $fields[ $field ] ) ) {
4866
+ $value = PodsForm::default_value( pods_v( $field, 'post' ), $field_data['type'], $field, pods_v( 'options', $field_data, $field_data, true ), $pod, $params->id );
4867
 
4868
  if ( null !== $value && '' !== $value && false !== $value ) {
4869
  $fields[ $field ]['value'] = $value;
4870
+
4871
+ $fields_active[] = $field;
4872
  }
4873
  }
4874
  }
4876
  // Set default field values for object fields
4877
  if ( ! empty( $object_fields ) ) {
4878
  foreach ( $object_fields as $field => $field_data ) {
4879
+ if ( in_array( $field, $fields_active, true ) ) {
4880
  continue;
4881
+ }
4882
+
4883
+ if ( ! isset( $field_data['default'] ) || '' === $field_data['default'] ) {
4884
  continue;
4885
  }
4886
 
4887
+ $value = PodsForm::default_value( pods_v( $field, 'post' ), $field_data['type'], $field, pods_v( 'options', $field_data, $field_data, true ), $pod, $params->id );
4888
 
4889
  if ( null !== $value && '' !== $value && false !== $value ) {
4890
  $object_fields[ $field ]['value'] = $value;
4891
+
4892
+ $fields_active[] = $field;
4893
  }
4894
  }
4895
  }
4896
 
4897
  // Set default field values for Pod fields
4898
  foreach ( $fields as $field => $field_data ) {
4899
+ if ( in_array( $field, $fields_active, true ) ) {
4900
  continue;
4901
+ }
4902
+
4903
+ if ( ! isset( $field_data['default'] ) || '' === $field_data['default'] ) {
4904
  continue;
4905
  }
4906
 
4907
+ $value = PodsForm::default_value( pods_v( $field, 'post' ), $field_data['type'], $field, pods_v( 'options', $field_data, $field_data, true ), $pod, $params->id );
4908
 
4909
  if ( null !== $value && '' !== $value && false !== $value ) {
4910
  $fields[ $field ]['value'] = $value;
4911
+
4912
+ $fields_active[] = $field;
4913
  }
4914
  }
4915
  }
4979
 
4980
  // Call any pre-save helpers (if not bypassed)
4981
  if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) {
4982
+ if ( ! empty( $pod ) ) {
4983
  $helpers = array( 'pre_save_helpers', 'post_save_helpers' );
4984
 
4985
  foreach ( $helpers as $helper ) {
4986
+ if ( isset( $pod[ $helper ] ) && ! empty( $pod[ $helper ] ) ) {
4987
+ ${$helper} = explode( ',', $pod[ $helper ] );
 
 
 
 
 
 
 
 
 
 
 
 
4988
  }
4989
  }
4990
  }
5001
 
5002
  $object_ID = 'ID';
5003
 
5004
+ if ( ! empty( $pod['field_id'] ) ) {
5005
+ $object_ID = $pod['field_id'];
5006
+ } elseif ( ! empty( $pod['pod_field_id'] ) ) {
5007
+ $object_ID = $pod['pod_field_id'];
5008
  }
5009
 
5010
  $object_data = array();
5031
 
5032
  $value = $field_data['value'];
5033
  $type = $field_data['type'];
5034
+ $options = pods_v( 'options', $field_data, [] );
5035
+
5036
+ if ( in_array( $type, $layout_field_types, true ) ) {
5037
+ continue;
5038
+ }
5039
 
5040
  // WPML AJAX compatibility
5041
  if ( is_admin()
5044
  && isset( $_POST['icl_ajx_action'] ) && isset( $_POST['_icl_nonce'] )
5045
  && wp_verify_nonce( $_POST['_icl_nonce'], $_POST['icl_ajx_action'] . '_nonce' ) )
5046
  ) {
5047
+ $options['unique'] = 0;
5048
+ $fields[ $field ]['unique'] = 0;
5049
+ $options['required'] = 0;
5050
+ $fields[ $field ]['required'] = 0;
5051
  } else {
5052
  // Validate value
5053
  $validate = $this->handle_field_validation( $value, $field, $object_fields, $fields, $pod, $params );
5063
  }
5064
  }
5065
 
5066
+ $value = PodsForm::pre_save( $field_data['type'], $value, $params->id, $field, $field_data, pods_config_merge_fields( $fields, $object_fields ), $pod, $params );
5067
 
5068
  $field_data['value'] = $value;
5069
 
5075
  $object_data[ $field ] = $value;
5076
  }
5077
  } else {
5078
+ $simple = ( 'pick' === $type && in_array( pods_v( 'pick_object', $field_data ), $simple_tableless_objects ) );
5079
  $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field_data, $field, $fields, $pod, $params );
5080
 
5081
  // Handle Simple Relationships
5088
  }
5089
  }
5090
 
5091
+ $pick_limit = (int) pods_v( 'pick_limit', $options, 0 );
5092
 
5093
+ if ( 'single' === pods_v( 'pick_format_type', $options ) ) {
5094
  $pick_limit = 1;
5095
  }
5096
 
5097
+ if ( 'custom-simple' === pods_v( 'pick_object', $field_data ) ) {
5098
+ $custom = pods_v( 'pick_custom', $options, '' );
5099
 
5100
+ $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $field_data['name'], $value, $field_data, $pod, $params->id );
5101
 
5102
  // Input values are unslashed. Unslash database values as well to ensure correct comparison.
5103
  $custom = pods_unslash( $custom );
5149
  if ( empty( $value ) ) {
5150
  $value = '';
5151
  } elseif ( is_array( $value ) ) {
5152
+ if ( 1 === $pick_limit || 1 === count( $value ) ) {
5153
  // If there's just one item, don't save as an array, save the string
5154
  $value = implode( '', $value );
5155
+ } elseif ( 'table' === pods_v( 'storage', $pod ) ) {
5156
  // If storage is set to table, json encode, otherwise WP will serialize automatically
5157
  $value = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $value, JSON_UNESCAPED_UNICODE ) : json_encode( $value );
5158
  }
5160
  }
5161
 
5162
  // Prepare all table / meta data
5163
+ if ( $simple || ! in_array( $type, $tableless_field_types, true ) ) {
5164
+ if ( in_array( $type, $repeatable_field_types, true ) && 1 === (int) pods_v( $type . '_repeatable', $field_data, 0 ) ) {
5165
  // Don't save an empty array, just make it an empty string
5166
  if ( empty( $value ) ) {
5167
  $value = '';
5168
  } elseif ( is_array( $value ) ) {
5169
+ if ( 1 === count( $value ) ) {
5170
  // If there's just one item, don't save as an array, save the string
5171
  $value = implode( '', $value );
5172
+ } elseif ( 'table' === pods_v( 'storage', $pod ) ) {
5173
  // If storage is set to table, json encode, otherwise WP will serialize automatically
5174
  $value = version_compare( PHP_VERSION, '5.4.0', '>=' ) ? json_encode( $value, JSON_UNESCAPED_UNICODE ) : json_encode( $value );
5175
  }
5292
  pods_no_conflict_on( $pod['type'] );
5293
  }
5294
 
5295
+ $static_cache = tribe( Static_Cache::class );
5296
+
5297
  // Save relationship / file data
5298
  if ( ! empty( $rel_fields ) ) {
5299
  foreach ( $rel_fields as $type => $data ) {
5300
  // Only handle tableless fields
5301
+ if ( ! in_array( $type, $tableless_field_types, true ) ) {
5302
  continue;
5303
  }
5304
 
5305
  foreach ( $data as $field => $values ) {
5306
+ $pick_val = pods_v( 'pick_val', $fields[ $field ] );
5307
 
5308
+ if ( 'table' === pods_v( 'pick_object', $fields[ $field ] ) ) {
5309
+ $pick_val = pods_v( 'pick_table', $fields[ $field ], $pick_val, true );
5310
  }
5311
 
5312
  if ( '__current__' === $pick_val ) {
5313
+ if ( is_array( $pod ) || $pod instanceof Pods\Whatsit ) {
 
 
5314
  $pick_val = $pod['name'];
5315
+ } elseif ( is_object( $pod ) && isset( $pod->pod ) ) {
5316
+ $pick_val = $pod->pod;
5317
+ } elseif ( is_string( $pod ) && 0 < strlen( $pod ) ) {
5318
  $pick_val = $pod;
5319
  }
5320
  }
5321
 
5322
+ $fields[ $field ]['table_info'] = pods_api()->get_table_info( pods_v( 'pick_object', $fields[ $field ] ), $pick_val, null, null, $fields[ $field ] );
5323
 
5324
+ if ( isset( $fields[ $field ]['table_info']['pod'] ) && ! empty( $fields[ $field ]['table_info']['pod'] ) && isset( $fields[ $field ]['table_info']['pod']['name'] ) ) {
5325
+ $search_data = pods( $fields[ $field ]['table_info']['pod']['name'] );
5326
 
5327
  $data_mode = 'pods';
5328
  } else {
5329
  $search_data = pods_data();
5330
+ $search_data->table( $fields[ $field ]['table_info'] );
5331
 
5332
  $data_mode = 'data';
5333
  }
5346
  $find_rel_params = false;
5347
  }
5348
 
5349
+ $related_limit = (int) pods_v( $type . '_limit', $fields[ $field ], 0 );
5350
 
5351
+ if ( 'single' === pods_v( $type . '_format_type', $fields[ $field ] ) ) {
5352
  $related_limit = 1;
5353
  }
5354
 
5355
  // Enforce integers / unique values for IDs
5356
  $value_ids = array();
5357
 
5358
+ $is_file_field = in_array( $type, PodsForm::file_field_types(), true );
5359
+ $is_taggable = ( in_array( $type, PodsForm::tableless_field_types(), true ) && 1 === (int) pods_v( $type . '_taggable', $fields[ $field ] ) );
5360
 
5361
  // @todo Handle simple relationships eventually
5362
  foreach ( $values as $v ) {
5444
  $values = array_slice( $values, 0, $related_limit );
5445
  }
5446
 
5447
+ $related_data = $static_cache->get( $fields[ $field ]['name'] . '/' . $fields[ $field ]['id'], 'PodsField_Pick/related_data' ) ?: [];
5448
+
5449
  // Get current values
5450
+ if ( 'pick' === $type && isset( $related_data[ 'current_ids_' . $params->id ] ) ) {
5451
+ $related_ids = $related_data[ 'current_ids_' . $params->id ];
5452
  } else {
5453
  $related_ids = $this->lookup_related_items( $fields[ $field ]['id'], $pod['id'], $params->id, $fields[ $field ], $pod );
5454
  }
5456
  // Get ids to remove
5457
  $remove_ids = array_diff( $related_ids, $value_ids );
5458
 
5459
+ if ( ! empty( $fields[ $field ] ) ) {
5460
+ // Delete relationships
5461
+ if ( ! empty( $remove_ids ) ) {
5462
+ $this->delete_relationships( $params->id, $remove_ids, $pod, $fields[ $field ] );
5463
+ }
5464
 
5465
+ // Save relationships
5466
+ if ( ! empty( $value_ids ) ) {
5467
+ $this->save_relationships( $params->id, $value_ids, $pod, $fields[ $field ] );
5468
+ }
5469
  }
5470
 
5471
  $field_save_values = $value_ids;
5475
  }
5476
 
5477
  // Run save function for field type (where needed)
5478
+ PodsForm::save( $type, $field_save_values, $params->id, $field, $fields[ $field ], pods_config_merge_fields( $fields, $object_fields ), $pod, $params );
5479
  }
5480
 
5481
  // Unset data no longer needed
5482
  if ( 'pick' === $type ) {
5483
  foreach ( $data as $field => $values ) {
5484
+ $related_data = $static_cache->get( $fields[ $field ]['name'] . '/' . $fields[ $field ]['id'], 'PodsField_Pick/related_data' ) ?: [];
5485
+
5486
+ if ( ! empty( $related_data ) ) {
5487
+ if ( ! empty( $related_data['related_field'] ) ) {
5488
+ $static_cache->delete( $related_data['related_field']['name'] . '/' . $related_data['related_field']['id'], 'PodsField_Pick/related_data' );
5489
+ }
5490
+
5491
+ $static_cache->delete( $fields[ $field ]['name'] . '/' . $fields[ $field ]['id'], 'PodsField_Pick/related_data' );
5492
  }
5493
  }
5494
  }
5540
  $this->do_hook( 'post_edit_pod_item', $compact_pieces, $params->id );
5541
  $this->do_hook( "post_edit_pod_item_{$params->pod}", $compact_pieces, $params->id );
5542
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5543
  }
5544
 
5545
  // Success! Return the id
5596
  * @return array List of changed fields (if $mode = 'get')
5597
  */
5598
  public static function handle_changed_fields( $pod, $id, $mode = 'set' ) {
5599
+ $static_cache = tribe( Static_Cache::class );
5600
 
5601
+ $changed_pods_cache = $static_cache->get( 'changed_pods_cache', __CLASS__ ) ?: [];
5602
+ $old_fields_cache = $static_cache->get( 'old_fields_cache', __CLASS__ ) ?: [];
5603
+ $changed_fields_cache = $static_cache->get( 'changed_fields_cache', __CLASS__ ) ?: [];
5604
 
5605
  $cache_key = $pod . '|' . $id;
5606
 
5658
  }
5659
  }
5660
 
5661
+ $static_cache->set( 'changed_pods_cache', $changed_pods_cache, __CLASS__ );
5662
+ $static_cache->set( 'old_fields_cache', $old_fields_cache, __CLASS__ );
5663
+ $static_cache->set( 'changed_fields_cache', $changed_fields_cache, __CLASS__ );
5664
+
5665
  return $changed_fields;
5666
 
5667
  }
5676
  * @deprecated 2.7.0 Use PodsAPI::handle_changed_fields
5677
  */
5678
  public function get_changed_fields( $pieces ) {
5679
+ _deprecated_function( __METHOD__, '2.7.0', 'PodsAPI::handle_changed_fields' );
5680
 
5681
  return self::handle_changed_fields( $pieces['params']->pod, $pieces['params']->id, 'get' );
 
5682
  }
5683
 
5684
  /**
5685
  * Save relationships
5686
  *
5687
+ * @param int $id ID of item.
5688
+ * @param int|array $related_ids ID(s) for items to save.
5689
+ * @param array|Pod $pod The Pod object.
5690
+ * @param array|Field $field The Field object.
5691
+ *
5692
+ * @return array List of ID(s) that were setup for saving.
5693
  */
5694
  public function save_relationships( $id, $related_ids, $pod, $field ) {
5695
+ $static_cache = tribe( Static_Cache::class );
5696
+
5697
+ $related_data = $static_cache->get( $field['name'] . '/' . $field['id'], 'PodsField_Pick/related_data' ) ?: [];
5698
 
5699
  // Get current values
5700
+ if ( 'pick' === $field['type'] && isset( $related_data[ 'current_ids_' . $id ] ) ) {
5701
+ $current_ids = $related_data[ 'current_ids_' . $id ];
5702
  } else {
5703
  $current_ids = $this->lookup_related_items( $field['id'], $pod['id'], $id, $field, $pod );
5704
  }
5705
 
5706
+ $static_cache = tribe( Static_Cache::class );
5707
+
5708
+ $cache_key = $pod['id'] . '|' . $field['id'];
5709
+
5710
+ // Delete relationship from cache.
5711
+ $static_cache->delete( $cache_key, __CLASS__ . '/related_item_cache' );
5712
 
5713
  if ( ! is_array( $related_ids ) ) {
5714
  $related_ids = implode( ',', $related_ids );
5720
 
5721
  $related_ids = array_unique( array_filter( $related_ids ) );
5722
 
5723
+ $related_limit = (int) pods_v( $field['type'] . '_limit', $field, 0 );
5724
 
5725
+ if ( 'single' === pods_v( $field['type'] . '_format_type', $field ) ) {
5726
  $related_limit = 1;
5727
  }
5728
 
5732
  }
5733
 
5734
  // Post Types, Media, Users, and Comments (meta-based)
5735
+ if ( pods_relationship_meta_storage_enabled( $field, $pod ) && in_array( $pod['type'], [
5736
+ 'post_type',
5737
+ 'media',
5738
+ 'taxonomy',
5739
+ 'user',
5740
+ 'comment',
5741
+ ], true ) ) {
5742
  $object_type = $pod['type'];
5743
 
5744
+ if ( in_array( $object_type, [ 'post_type', 'media' ], true ) ) {
5745
  $object_type = 'post';
5746
  } elseif ( 'taxonomy' === $object_type ) {
5747
  $object_type = 'term';
5770
  $related_pod_id = 0;
5771
  $related_field_id = 0;
5772
 
5773
+ if ( 'pick' === $field['type'] && ! empty( $related_data['related_field'] ) ) {
5774
+ $related_pod_id = $related_data['related_pod']['id'];
5775
+ $related_field_id = $related_data['related_field']['id'];
5776
  }
5777
 
5778
  // Relationships table
5779
+ if ( pods_podsrel_enabled() ) {
5780
  $related_weight = 0;
5781
 
5782
  foreach ( $related_ids as $related_id ) {
5783
  if ( in_array( $related_id, $current_ids ) ) {
5784
+ pods_query( '
5785
  UPDATE `@wp_podsrel`
5786
  SET
5787
  `pod_id` = %d,
5796
  AND `field_id` = %d
5797
  AND `item_id` = %d
5798
  AND `related_item_id` = %d
5799
+ ', array(
5800
  $pod['id'],
5801
  $field['id'],
5802
  $id,
5811
  $related_id,
5812
  ) );
5813
  } else {
5814
+ pods_query( '
5815
  INSERT INTO `@wp_podsrel`
5816
  (
5817
  `pod_id`,
5823
  `weight`
5824
  )
5825
  VALUES ( %d, %d, %d, %d, %d, %d, %d )
5826
+ ', array(
5827
  $pod['id'],
5828
  $field['id'],
5829
  $id,
5830
  $related_pod_id,
5831
  $related_field_id,
5832
  $related_id,
5833
+ $related_weight,
5834
  ) );
5835
  }
5836
 
5837
+ $related_weight ++;
5838
+ }
5839
+ }
5840
+
5841
+ /**
5842
+ * Allow custom saving actions for relationships.
5843
+ *
5844
+ * @since 2.8.0
5845
+ *
5846
+ * @param int $id ID of item.
5847
+ * @param array $related_ids ID(s) for items to save.
5848
+ * @param array|Pod $pod The Pod object.
5849
+ * @param array|Field $field The Field object.
5850
+ */
5851
+ do_action( 'pods_api_save_relationships', $id, $related_ids, $field, $pod );
5852
+
5853
+ return $related_ids;
5854
+ }
5855
+
5856
+ /**
5857
+ * Duplicate a Pod.
5858
+ *
5859
+ * $params['id'] int The Pod ID.
5860
+ * $params['name'] string The Pod name.
5861
+ * $params['new_name'] string The new Pod name.
5862
+ *
5863
+ * @since 2.3.0
5864
+ *
5865
+ * @param array $params An associative array of parameters.
5866
+ * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error.
5867
+ *
5868
+ * @return int|false New Group ID or false if not successful.
5869
+ */
5870
+ public function duplicate_pod( $params, $strict = false ) {
5871
+
5872
+ if ( ! is_object( $params ) && ! is_array( $params ) ) {
5873
+ if ( is_numeric( $params ) ) {
5874
+ $params = array( 'id' => $params );
5875
+ } else {
5876
+ $params = array( 'name' => $params );
5877
+ }
5878
+
5879
+ $params = (object) pods_sanitize( $params );
5880
+ } else {
5881
+ $params = (object) pods_sanitize( $params );
5882
+ }
5883
+
5884
+ $pod = $this->load_pod( $params, false );
5885
+
5886
+ if ( empty( $pod ) ) {
5887
+ if ( false !== $strict ) {
5888
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
5889
+ }
5890
+
5891
+ return false;
5892
+ } elseif ( in_array( $pod['type'], array( 'media', 'user', 'comment' ) ) ) {
5893
+ if ( false !== $strict ) {
5894
+ return pods_error( __( 'Pod not allowed to be duplicated', 'pods' ), $this );
5895
+ }
5896
+
5897
+ return false;
5898
+ } elseif ( in_array( $pod['type'], array( 'post_type', 'taxonomy' ) ) && 0 < strlen( $pod['object'] ) ) {
5899
+ $pod['object'] = '';
5900
+ }
5901
+
5902
+ if ( $pod instanceof Pod ) {
5903
+ $pod = $pod->export(
5904
+ [
5905
+ 'include_groups' => true,
5906
+ 'include_fields' => false,
5907
+ ]
5908
+ );
5909
+ }
5910
+
5911
+ if ( isset( $params->new_name ) ) {
5912
+ $pod['name'] = $params->new_name;
5913
+ }
5914
+
5915
+ $try = 1;
5916
+
5917
+ $check_name = $pod['name'];
5918
+ $new_label = $pod['label'];
5919
+
5920
+ while ( $this->load_pod( array( 'name' => $check_name ), false ) ) {
5921
+ $try ++;
5922
+
5923
+ $check_name = $pod['name'] . $try;
5924
+ $new_label = $pod['label'] . $try;
5925
+ }
5926
+
5927
+ $pod['name'] = $check_name;
5928
+ $pod['label'] = $new_label;
5929
+
5930
+ $groups = $pod['groups'];
5931
+
5932
+ unset( $pod['id'], $pod['parent'], $pod['object_type'], $pod['storage_type'], $pod['groups'] );
5933
+
5934
+ try {
5935
+ $pod_id = $this->save_pod( $pod );
5936
+ } catch ( Exception $exception ) {
5937
+ return false;
5938
+ }
5939
+
5940
+ if ( ! is_int( $pod_id ) ) {
5941
+ return false;
5942
+ }
5943
+
5944
+ foreach ( $groups as $group => $group_data ) {
5945
+ $fields = $group_data['fields'];
5946
+
5947
+ unset( $group_data['id'], $group_data['parent'], $group_data['object_type'], $group_data['storage_type'], $group_data['fields'] );
5948
+
5949
+ $group_data['pod_id'] = $pod_id;
5950
+
5951
+ $group_id = $this->save_group( $group_data );
5952
+
5953
+ foreach ( $fields as $field => $field_data ) {
5954
+ unset( $field_data['id'], $field_data['parent'], $field_data['object_type'], $field_data['storage_type'], $field_data['group'] );
5955
+
5956
+ $field_data['pod_id'] = $pod_id;
5957
+ $field_data['group_id'] = $group_id;
5958
+
5959
+ try {
5960
+ $this->save_field( $field_data );
5961
+ } catch ( Exception $exception ) {
5962
+ // Field not saved.
5963
+ }
5964
  }
5965
  }
5966
+
5967
+ return $pod_id;
5968
  }
5969
 
5970
  /**
5971
+ * Duplicate a Group.
5972
  *
5973
+ * $params['id'] int The Group ID.
5974
+ * $params['name'] string The Group name.
5975
+ * $params['new_name'] string The new Group name.
5976
  *
5977
+ * @since 2.8.0
 
5978
  *
5979
+ * @param array $params An associative array of parameters.
5980
+ * @param bool $strict (optional) Makes sure a group exists, if it doesn't throws an error.
5981
+ *
5982
+ * @return int|false New Group ID or false if not successful.
5983
  */
5984
+ public function duplicate_group( $params, $strict = false ) {
5985
 
5986
  if ( ! is_object( $params ) && ! is_array( $params ) ) {
5987
  if ( is_numeric( $params ) ) {
5995
  $params = (object) pods_sanitize( $params );
5996
  }
5997
 
5998
+ if ( ! empty( $params->pod_id ) ) {
5999
+ $load_params['parent'] = $params->pod_id;
6000
+ } elseif ( ! empty( $params->pod ) ) {
6001
+ $load_params['pod'] = $params->pod;
6002
+ }
6003
 
6004
+ $group = $this->load_group( $params, false );
6005
 
6006
+ if ( empty( $group ) ) {
6007
  if ( false !== $strict ) {
6008
+ return pods_error( __( 'Group not found', 'pods' ), $this );
6009
  }
6010
 
6011
  return false;
6012
+ }
 
 
 
6013
 
6014
+ if ( $group instanceof Group ) {
6015
+ $group = $group->export(
6016
+ [
6017
+ 'include_fields' => true,
6018
+ ]
6019
+ );
6020
  }
6021
 
6022
+ unset( $group['id'] );
6023
 
6024
  if ( isset( $params->new_name ) ) {
6025
+ $group['name'] = $params->new_name;
6026
  }
6027
 
6028
  $try = 1;
6029
 
6030
+ $check_name = $group['name'];
6031
+ $new_label = $group['label'];
6032
 
6033
+ while ( $this->load_group( array( 'name' => $check_name ), false ) ) {
6034
  $try ++;
6035
 
6036
+ $check_name = $group['name'] . $try;
6037
+ $new_label = $group['label'] . $try;
6038
  }
6039
 
6040
+ $group['name'] = $check_name;
6041
+ $group['label'] = $new_label;
6042
+
6043
+ $fields = $group['fields'];
6044
+
6045
+ unset( $group['id'], $group['parent'], $group['object_type'], $group['storage_type'], $group['fields'] );
6046
+
6047
+ try {
6048
+ $group_id = $this->save_group( $group );
6049
+ } catch ( Exception $exception ) {
6050
+ return false;
6051
+ }
6052
+
6053
+ if ( ! is_int( $group_id ) ) {
6054
+ return false;
6055
+ }
6056
+
6057
+ foreach ( $fields as $field => $field_data ) {
6058
+ unset( $field_data['id'], $field_data['parent'], $field_data['object_type'], $field_data['storage_type'], $field_data['group'] );
6059
 
6060
+ $field_data['group_id'] = $group_id;
6061
+
6062
+ try {
6063
+ $this->save_field( $field_data );
6064
+ } catch ( Exception $exception ) {
6065
+ // Field not saved.
6066
+ }
6067
  }
6068
 
6069
+ return $group_id;
6070
  }
6071
 
6072
  /**
6073
+ * Duplicate a Field.
6074
  *
6075
+ * $params['pod_id'] int The Pod ID.
6076
+ * $params['pod'] string The Pod name.
6077
+ * $params['id'] int The Field ID.
6078
+ * $params['name'] string The Field name.
6079
+ * $params['new_name'] string The new Field name.
 
 
 
6080
  *
 
6081
  * @since 2.3.10
6082
+ *
6083
+ * @param array $params An associative array of parameters.
6084
+ * @param bool $strict (optional) Makes sure a field exists, if it doesn't throws an error.
6085
+ *
6086
+ * @return int|false New Field ID or false if not successful.
6087
  */
6088
  public function duplicate_field( $params, $strict = false ) {
6089
 
6097
 
6098
  $params = (object) pods_sanitize( $params );
6099
 
6100
+ $load_params = array();
6101
+
6102
+ if ( ! empty( $params->pod_id ) ) {
6103
+ $load_params['parent'] = $params->pod_id;
6104
+ } elseif ( ! empty( $params->pod ) ) {
6105
+ $load_params['pod'] = $params->pod;
6106
+ }
6107
+
6108
+ if ( ! empty( $params->id ) ) {
6109
+ $load_params['id'] = $params->id;
6110
+ } elseif ( ! empty( $params->name ) ) {
6111
+ $load_params['name'] = $params->name;
6112
+ }
6113
 
6114
+ $field = $this->load_field( $load_params, $strict );
6115
 
6116
  if ( empty( $field ) ) {
6117
  if ( false !== $strict ) {
6121
  return false;
6122
  }
6123
 
6124
+ if ( $field instanceof Field ) {
6125
+ $field = $field->export();
6126
+ }
6127
 
6128
  if ( isset( $params->new_name ) ) {
6129
  $field['name'] = $params->new_name;
6135
  $new_label = $field['label'];
6136
 
6137
  while ( $this->load_field( array(
6138
+ 'parent' => $field['pod_id'],
6139
+ 'name' => $check_name,
 
6140
  ), false ) ) {
6141
  $try ++;
6142
 
6147
  $field['name'] = $check_name;
6148
  $field['label'] = $new_label;
6149
 
6150
+ unset( $field['id'], $field['object_type'], $field['storage_type'] );
6151
+
6152
  return $this->save_field( $field, true, true );
6153
 
6154
  }
6172
  $params = (object) pods_sanitize( $params );
6173
 
6174
  $load_pod_params = array(
6175
+ 'name' => $params->pod,
 
6176
  );
6177
 
6178
+ $pod = $this->load_pod( $load_pod_params, false );
6179
 
6180
  if ( false === $pod ) {
6181
  return pods_error( __( 'Pod not found', 'pods' ), $this );
6186
  $params->pod = $pod->pod;
6187
  $params->pod_id = $pod->pod_id;
6188
 
6189
+ $fields = (array) pods_v( 'fields', $pod->pod_data, [], true );
6190
+ $object_fields = (array) pods_v( 'object_fields', $pod->pod_data, [], true );
6191
 
6192
  if ( ! empty( $object_fields ) ) {
6193
  $fields = array_merge( $object_fields, $fields );
6204
  $pod->pod_data['field_slug'],
6205
  );
6206
 
6207
+ if ( in_array( $pod->pod_data['type'], array( 'post_type', 'media' ), true ) ) {
6208
  $ignore_fields = array(
6209
  'ID',
6210
  'post_name',
6348
  $tableless_field_types = PodsForm::tableless_field_types();
6349
  $simple_tableless_objects = PodsForm::simple_tableless_objects();
6350
 
6351
+ $object_fields = (array) is_object( $pod->pod_data ) ? $pod->pod_data->get_object_fields() : pods_v( 'object_fields', $pod->pod_data, [], true );
6352
 
6353
  $export_fields = array();
6354
 
6370
 
6371
  // If in rest, check if this pod can be exposed
6372
  if ( 'rest' === $context ) {
6373
+ $read_all = (int) pods_v( 'read_all', $pod->pod_data, 0 );
6374
 
6375
  if ( 1 === $read_all ) {
6376
  $show_in_rest = true;
6378
  }
6379
 
6380
  foreach ( $fields as $k => $field ) {
6381
+ $is_field_object = $field instanceof Field;
6382
+
6383
+ if ( ! is_array( $field ) && ! $is_field_object ) {
6384
  $field = array(
6385
  'id' => 0,
6386
  'name' => $field
6404
  }
6405
  }
6406
 
6407
+ $field = $pod->fields( $field['name'] );
6408
  $field['lookup_name'] = $field['name'];
6409
 
6410
+ $field_type = pods_v( 'type', $field, 'text' );
6411
+
6412
+ if ( in_array( $field_type, $tableless_field_types, true ) && ! in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) ) {
6413
+ if ( 'pick' === $field_type ) {
6414
  if ( empty( $field['table_info'] ) ) {
6415
  $field['table_info'] = $this->get_table_info( pods_v( 'pick_object', $field ), pods_v( 'pick_val', $field ), null, null, $field );
6416
  }
6418
  if ( ! empty( $field['table_info'] ) && 'table' !== $field['table_info']['object_type'] ) {
6419
  $field['lookup_name'] .= '.' . $field['table_info']['field_id'];
6420
  }
6421
+ } elseif ( in_array( $field_type, PodsForm::file_field_types(), true ) ) {
6422
  $field['lookup_name'] .= '.guid';
6423
  }
6424
  }
6429
  $field['lookup_name'] = $field['name'];
6430
 
6431
  $export_fields[ $field['name'] ] = $field;
6432
+ } elseif ( $field['name'] === $pod->pod_data['field_id'] ) {
6433
  $field['type'] = 'number';
6434
  $field['lookup_name'] = $field['name'];
6435
 
6441
 
6442
  foreach ( $export_fields as $field ) {
6443
  // Return IDs (or guid for files) if only one level deep
6444
+ if ( 1 === $depth ) {
6445
  $data[ $field['name'] ] = $pod->field( array( 'name' => $field['lookup_name'], 'output' => 'arrays' ) );
6446
+ } elseif ( ( - 1 === $depth || $current_depth < $depth ) && 'pick' === $field['type'] && ! in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) ) {
6447
  // Recurse depth levels for pick fields if $depth allows
6448
  $related_data = array();
6449
 
6452
  if ( ! empty( $related_ids ) ) {
6453
  $related_ids = (array) $related_ids;
6454
 
6455
+ $pick_object = pods_v( 'pick_object', $field );
6456
 
6457
+ $related_pod = pods( pods_v( 'pick_val', $field ), null, false );
6458
 
6459
  // If this isn't a Pod, return data exactly as Pods does normally
6460
+ if ( empty( $related_pod ) || empty( $related_pod->pod_data ) || ( 'pod' !== $pick_object && $pick_object !== $related_pod->pod_data['type'] ) || $related_pod->pod === $pod->pod ) {
6461
  $related_data = $pod->field( array( 'name' => $field['name'], 'output' => 'arrays' ) );
6462
  } else {
6463
+ $related_object_fields = (array) pods_v( 'object_fields', $related_pod->pod_data, [], true );
6464
 
6465
  $related_fields = array_merge( $related_pod->fields, $related_object_fields );
6466
 
6533
 
6534
  $params = (object) pods_sanitize( $params );
6535
 
6536
+ if ( null === pods_v( 'pod', $params, null, true ) ) {
 
 
 
 
 
 
 
 
 
6537
  return pods_error( __( '$params->pod is required', 'pods' ), $this );
6538
  }
6539
 
6541
  $params->order = explode( ',', $params->order );
6542
  }
6543
 
6544
+ $pod = $this->load_pod( array( 'name' => $params->pod ), false );
 
 
6545
 
6546
  if ( false === $pod ) {
6547
  return pods_error( __( 'Pod is required', 'pods' ), $this );
6548
  }
6549
 
6550
+ $params->name = $pod['name'];
6551
+
6552
  foreach ( $params->order as $order => $id ) {
6553
  if ( isset( $pod['fields'][ $params->field ] ) || isset( $pod['object_fields'][ $params->field ] ) ) {
6554
+ if ( 'table' === $pod['storage'] && ! pods_tableless() ) {
6555
  if ( isset( $pod['fields'][ $params->field ] ) ) {
6556
  pods_query( "UPDATE `@wp_pods_{$params->name}` SET `{$params->field}` = " . pods_absint( $order ) . " WHERE `id` = " . pods_absint( $id ) . " LIMIT 1" );
6557
  } else {
6589
  * @since 1.9.0
6590
  */
6591
  public function reset_pod( $params, $pod = false ) {
 
 
 
 
 
6592
  if ( empty( $pod ) ) {
6593
+ $pod = $this->load_pod( $params, false );
6594
  }
6595
 
6596
  if ( false === $pod ) {
6597
  return pods_error( __( 'Pod not found', 'pods' ), $this );
6598
  }
6599
 
6600
+ if ( is_array( $params ) || is_object( $params ) ) {
6601
+ $params = (object) pods_sanitize( $params );
6602
+ } else {
6603
+ $params = new stdClass();
6604
+ }
6605
+
6606
+ $params->id = (int) $pod['id'];
6607
  $params->name = $pod['name'];
6608
 
6609
  if ( ! pods_tableless() ) {
6618
  }
6619
  }
6620
 
6621
+ }
6622
+
6623
+ if ( pods_podsrel_enabled() ) {
6624
  pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
6625
  }
6626
 
6627
  // @todo Delete relationships from tableless relationships
6628
 
6629
+ if ( in_array( $pod['type'], [ 'post_type', 'media' ], true ) ) {
6630
+ // Delete all posts/revisions from this post type.
6631
+ $type = $pod['name'];
6632
+
6633
+ if ( ! empty( $pod['object'] ) ) {
6634
+ $type = $pod['object'];
6635
+ }
6636
+
6637
+ $type = pods_sanitize( $type );
6638
 
6639
  $sql = "
6640
  DELETE `t`, `r`, `m`
6648
 
6649
  pods_query( $sql, false );
6650
  } elseif ( 'taxonomy' === $pod['type'] ) {
6651
+ // Delete all terms from this taxonomy.
6652
  if ( function_exists( 'get_term_meta' ) ) {
6653
  $sql = "
6654
  DELETE `t`, `m`, `tt`, `tr`
6683
  pods_query( $sql, false );
6684
  } elseif ( 'comment' === $pod['type'] ) {
6685
  // Delete all comments
6686
+ $type = $pod['name'];
6687
+
6688
+ if ( ! empty( $pod['object'] ) ) {
6689
+ $type = $pod['object'];
6690
+ }
6691
+
6692
+ $type = pods_sanitize( $type );
6693
 
6694
  $sql = "
6695
  DELETE `t`, `m`
6713
  * $params['id'] int The Pod ID
6714
  * $params['name'] string The Pod name
6715
  *
6716
+ * @param array|string|int $params An associative array of parameters, the pod name, or pod ID.
6717
+ * @param bool $strict (optional) Makes sure a pod exists, if it doesn't throws an error
6718
+ * @param bool $delete_all (optional) Whether to delete all content from a WP object
6719
  *
6720
  * @uses PodsAPI::load_pod
6721
  * @uses wp_delete_post
6725
  * @since 1.7.9
6726
  */
6727
  public function delete_pod( $params, $strict = false, $delete_all = false ) {
6728
+ $pod = $this->load_pod( $params, false );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6729
 
6730
  if ( empty( $pod ) ) {
6731
  if ( false !== $strict ) {
6735
  return false;
6736
  }
6737
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6738
  /**
6739
  * @var $wpdb wpdb
6740
  */
6741
  global $wpdb;
6742
 
6743
+ if ( is_array( $params ) || is_object( $params ) ) {
6744
+ $params = (object) pods_sanitize( $params );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6745
  } else {
6746
+ $params = new stdClass();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6747
  }
6748
 
6749
+ $params->id = (int) $pod['id'];
6750
+ $params->name = $pod['name'];
6751
 
6752
+ $type = $pod['name'];
 
6753
 
6754
+ if ( ! empty( $pod['object'] ) ) {
6755
+ $type = $pod['object'];
6756
  }
6757
 
6758
+ if ( ! isset( $params->delete_all ) ) {
6759
+ $params->delete_all = $delete_all;
 
 
6760
  }
6761
 
6762
+ $params->delete_all = (boolean) $params->delete_all;
 
 
 
6763
 
6764
+ // Reset content
6765
+ if ( true === $params->delete_all ) {
6766
+ $this->reset_pod( $params, $pod );
6767
  }
6768
 
6769
+ foreach ( $pod['fields'] as $field ) {
6770
+ $delete_field = array(
6771
+ 'id' => $field->get_id(),
6772
+ 'name' => $field->get_name(),
6773
+ 'pod' => $pod,
6774
+ );
6775
 
6776
+ $this->delete_field( $delete_field, false );
 
6777
  }
6778
 
6779
+ $object_collection = Pods\Whatsit\Store::get_instance();
 
6780
 
6781
+ /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */
6782
+ $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() );
 
 
 
 
 
 
 
 
 
 
 
 
 
6783
 
6784
+ $object = $post_type_storage->to_object( $params->id );
 
6785
 
6786
+ $success = false;
 
 
6787
 
6788
+ if ( $object ) {
6789
+ $success = $post_type_storage->delete( $object );
6790
+ }
6791
 
6792
  if ( ! $success ) {
6793
+ return pods_error( __( 'Pod unable to be deleted', 'pods' ), $this );
6794
  }
6795
 
6796
+ // @todo Push this logic into pods_object_storage_delete_pod action.
6797
+ if ( ! pods_tableless() ) {
6798
+ if ( 'table' === $pod['storage'] ) {
6799
+ try {
6800
+ pods_query( "DROP TABLE IF EXISTS `@wp_pods_{$params->name}`", false );
6801
+ } catch ( Exception $e ) {
6802
+ // Allow pod to be deleted if the table doesn't exist
6803
+ if ( false === strpos( $e->getMessage(), 'Unknown table' ) ) {
6804
+ return pods_error( $e->getMessage(), $this );
6805
+ }
6806
+ }
6807
+ }
6808
 
6809
+ if ( pods_podsrel_enabled() ) {
6810
+ pods_query( "DELETE FROM `@wp_podsrel` WHERE `pod_id` = {$params->id} OR `related_pod_id` = {$params->id}", false );
6811
+ }
6812
+ }
 
 
 
 
 
 
 
 
 
 
6813
 
6814
+ // @todo Delete relationships from tableless relationships
 
6815
 
6816
+ // Delete any relationship references
6817
+ $sql = "
6818
+ DELETE `pm`
6819
+ FROM `{$wpdb->postmeta}` AS `pm`
6820
+ LEFT JOIN `{$wpdb->posts}` AS `p`
6821
+ ON `p`.`post_type` = '_pods_field'
6822
+ AND `p`.`ID` = `pm`.`post_id`
6823
+ LEFT JOIN `{$wpdb->postmeta}` AS `pm2`
6824
+ ON `pm2`.`meta_key` = 'pick_object'
6825
+ AND `pm2`.`meta_value` = 'pod'
6826
+ AND `pm2`.`post_id` = `pm`.`post_id`
6827
+ WHERE
6828
+ `p`.`ID` IS NOT NULL
6829
+ AND `pm2`.`meta_id` IS NOT NULL
6830
+ AND `pm`.`meta_key` = 'pick_val'
6831
+ AND `pm`.`meta_value` = '{$type}'
6832
+ ";
6833
 
6834
+ pods_query( $sql );
 
 
 
 
 
 
 
 
 
 
 
 
 
6835
 
6836
+ $this->cache_flush_pods( $pod );
 
 
 
 
 
 
 
 
6837
 
6838
+ return true;
6839
  }
6840
 
6841
  /**
6842
+ * Drop a field within a Pod
 
 
 
 
 
 
 
6843
  *
6844
+ * $params['id'] int The field ID
6845
+ * $params['name'] int The field name
6846
+ * $params['pod'] string The Pod name
6847
+ * $params['pod_id'] string The Pod name
 
 
 
 
 
 
 
 
 
6848
  *
6849
+ * @param array|object|Field $params An associative array or object of parameters, or the Field object itself.
6850
+ * @param bool $table_operation Whether or not to handle table operations.
 
 
6851
  *
6852
+ * @uses PodsAPI::load_field
6853
+ * @uses wp_delete_post
6854
+ * @uses pods_query
6855
  *
6856
  * @return bool
6857
  * @since 1.7.9
6858
  */
6859
+ public function delete_field( $params, $table_operation = true ) {
 
 
 
 
 
 
 
 
 
 
6860
 
6861
+ /**
6862
+ * @var $wpdb wpdb
6863
+ */
6864
+ global $wpdb;
 
6865
 
6866
+ $tableless_field_types = PodsForm::tableless_field_types();
6867
+ $simple_tableless_objects = PodsForm::simple_tableless_objects();
6868
+ $field = null;
6869
+ $pod = null;
 
6870
 
6871
+ // Check if the params is a field.
6872
+ if ( $params instanceof Field ) {
6873
+ $field = $params;
6874
+ $pod = $field->get_parent_object();
 
 
6875
 
6876
+ $params = [
6877
+ 'name' => $field->get_name(),
6878
+ 'id' => $field->get_id(),
6879
+ 'pod' => $field->get_parent(),
6880
+ 'pod_id' => $field->get_parent_id(),
6881
+ ];
6882
  }
6883
 
6884
+ $params = (object) $params;
6885
 
6886
  if ( ! isset( $params->pod ) ) {
6887
  $params->pod = '';
6891
  $params->pod_id = 0;
6892
  }
6893
 
6894
+ if ( ! $pod ) {
6895
+ $pod = $params->pod;
 
 
 
 
 
 
 
 
 
 
 
 
6896
  }
6897
 
6898
+ $save_pod = false;
 
 
 
 
 
 
 
 
 
 
 
6899
 
6900
+ if ( ! ( is_array( $pod ) || $pod instanceof Pods\Whatsit ) ) {
6901
+ $load_params = array();
 
 
 
 
6902
 
6903
+ if ( ! empty( $params->pod_id ) ) {
6904
+ $load_params['id'] = $params->pod_id;
6905
+ } elseif ( is_int( $pod ) && ! empty( $pod ) ) {
6906
+ $load_params['id'] = $pod;
6907
+ } elseif ( ! empty( $params->pod ) ) {
6908
+ $load_params['name'] = $params->pod;
6909
+ } elseif ( is_string( $pod ) && 0 < strlen( $pod ) ) {
6910
+ $load_params['name'] = $pod;
6911
+ }
6912
 
6913
+ $pod = false;
 
6914
 
6915
+ if ( $load_params ) {
6916
+ $pod = $this->load_pod( $load_params, false );
 
 
 
6917
  }
6918
+ } else {
6919
+ $save_pod = true;
6920
  }
6921
 
6922
+ if ( empty( $pod ) && empty( $params->id ) ) {
6923
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
 
 
 
6924
  }
6925
 
6926
+ if ( $pod ) {
6927
+ $params->pod_id = $pod['id'];
6928
+ $params->pod = $pod['name'];
 
 
 
 
 
 
 
 
 
6929
  }
6930
 
6931
+ $params = pods_sanitize( $params );
 
 
 
 
 
 
 
 
 
 
 
6932
 
6933
+ if ( ! isset( $params->name ) ) {
6934
+ $params->name = '';
 
 
 
 
6935
  }
6936
 
6937
+ if ( ! isset( $params->id ) ) {
6938
+ $params->id = 0;
6939
+ }
6940
 
6941
+ if ( ! $field ) {
6942
+ $load_params = [];
6943
 
6944
+ if ( $params->pod_id ) {
6945
+ $load_params['parent'] = $params->pod_id;
6946
+ }
 
 
 
 
 
 
 
 
 
6947
 
6948
+ if ( ! empty( $params->id ) ) {
6949
+ $load_params['id'] = $params->id;
6950
+ } elseif ( ! empty( $params->name ) ) {
6951
+ $load_params['name'] = $params->name;
6952
+ }
6953
 
6954
+ $field = $this->load_field( $load_params );
6955
 
6956
+ if ( false === $field ) {
6957
+ return pods_error( __( 'Field not found', 'pods' ), $this );
6958
+ }
 
 
6959
  }
6960
+ $params->id = $field['id'];
6961
+ $params->name = $field['name'];
6962
 
6963
+ // Get the pod from the field if pod information not provided.
6964
+ if ( false === $pod ) {
6965
+ $pod = $field->get_parent_object();
6966
 
6967
+ if ( $pod ) {
6968
+ $params->pod_id = $pod['id'];
6969
+ $params->pod = $pod['name'];
6970
  }
6971
  }
6972
 
6973
+ $simple = ( 'pick' === $field['type'] && in_array( pods_v( 'pick_object', $field ), $simple_tableless_objects, true ) );
6974
+ $simple = (boolean) $this->do_hook( 'tableless_custom', $simple, $field, $pod, $params );
 
 
 
 
 
 
 
 
 
 
 
6975
 
6976
+ // @todo Push this logic into pods_object_storage_delete_pod action.
6977
+ if ( $table_operation && $pod && 'table' === $pod['storage'] && ( ! in_array( $field['type'], $tableless_field_types, true ) || $simple ) ) {
6978
+ pods_query( "ALTER TABLE `@wp_pods_{$params->pod}` DROP COLUMN `{$params->name}`", false );
 
 
6979
  }
6980
 
6981
+ $object_collection = Pods\Whatsit\Store::get_instance();
 
 
 
 
 
 
 
 
6982
 
6983
+ /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */
6984
+ $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() );
6985
 
6986
+ $success = false;
 
 
6987
 
6988
+ if ( $post_type_storage ) {
6989
+ $object = $post_type_storage->to_object( $params->id );
 
6990
 
6991
+ if ( $object ) {
6992
+ $success = $post_type_storage->delete( $object );
6993
+ }
6994
+ }
6995
 
6996
+ if ( ! $success ) {
6997
+ return pods_error( __( 'Field unable to be deleted', 'pods' ), $this );
6998
  }
6999
 
7000
+ // @todo Push this logic into pods_object_storage_delete_pod action.
7001
+ $wpdb->query( $wpdb->prepare( "DELETE pm FROM {$wpdb->postmeta} AS pm
7002
+ LEFT JOIN {$wpdb->posts} AS p
7003
+ ON p.post_type = '_pods_field' AND p.ID = pm.post_id
7004
+ WHERE p.ID IS NOT NULL AND pm.meta_key = 'sister_id' AND pm.meta_value = %d", $params->id ) );
 
 
 
 
 
 
 
 
 
 
7005
 
7006
+ if ( $table_operation && pods_podsrel_enabled() ) {
7007
+ 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 );
 
7008
  }
7009
 
7010
+ // @todo Delete tableless relationship meta
7011
+
7012
  return true;
7013
  }
7014
 
7015
  /**
7016
+ * Delete a Pod and all its content
7017
  *
7018
+ * $params['id'] int The Group ID
7019
+ * $params['name'] string The Group name
7020
+ * $params['pod'] string|Pods\Whatsit\Pod The Pod name or object.
7021
+ * $params['pod_id'] string The Pod ID.
7022
  *
7023
+ * @since 2.8.0
7024
  *
7025
+ * @param array|string|int $params An associative array of parameters, the pod name, or pod ID.
7026
+ * @param bool $strict (optional) Makes sure a group exists, if it doesn't throws an error.
7027
+ * @param bool $delete_all (optional) Whether to delete all fields from the group too.
7028
+ *
7029
+ * @return bool Whether the group was deleted successfully.
7030
  */
7031
+ public function delete_group( $params, $strict = false, $delete_all = false ) {
7032
+ /**
7033
+ * @var $wpdb wpdb
7034
+ */
7035
+ global $wpdb;
7036
 
7037
+ if ( ! is_object( $params ) && ! is_array( $params ) ) {
7038
+ if ( is_numeric( $params ) ) {
7039
+ $params = [ 'id' => $params ];
7040
+ } else {
7041
+ $params = [ 'name' => $params ];
7042
  }
7043
 
7044
+ $params = (object) pods_sanitize( $params );
7045
+ } else {
7046
+ $params = (object) pods_sanitize( $params );
7047
  }
7048
 
7049
+ if ( ! isset( $params->delete_all ) ) {
7050
+ $params->delete_all = (boolean) $delete_all;
 
 
 
 
7051
  }
7052
 
7053
+ $group = $this->load_group( $params, false );
 
 
 
 
7054
 
7055
+ if ( empty( $group ) ) {
7056
+ if ( false !== $strict ) {
7057
+ return pods_error( __( 'Group not found', 'pods' ), $this );
7058
+ }
7059
 
7060
+ return false;
 
 
 
7061
  }
7062
 
7063
+ $pod = $group->get_parent();
 
 
 
7064
 
7065
+ $params->id = (int) $group['id'];
7066
+ $params->name = $group['name'];
7067
 
7068
+ // Delete all fields.
7069
+ if ( true === $params->delete_all ) {
7070
+ foreach ( $group['fields'] as $field ) {
7071
+ $delete_field = [
7072
+ 'id' => $field->get_id(),
7073
+ 'name' => $field->get_name(),
7074
+ 'pod' => $pod,
7075
+ ];
7076
 
7077
+ $this->delete_field( $delete_field, false );
7078
+ }
7079
  }
7080
 
7081
+ $object_collection = Pods\Whatsit\Store::get_instance();
 
 
7082
 
7083
+ /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */
7084
+ $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() );
 
 
 
7085
 
7086
+ $object = $post_type_storage->to_object( $params->id );
7087
 
7088
+ $success = false;
 
7089
 
7090
+ if ( $object ) {
7091
+ $success = $post_type_storage->delete( $object );
 
 
 
 
 
 
 
 
 
 
 
7092
  }
7093
 
7094
+ if ( ! $success ) {
7095
+ return pods_error( __( 'Group unable to be deleted', 'pods' ), $this );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7096
  }
7097
 
7098
+ return true;
 
 
7099
  }
7100
 
7101
  /**
7102
+ * Drop a Pod Object
7103
  *
7104
+ * $params['id'] int The object ID
7105
+ * $params['name'] string The object name
7106
+ * $params['type'] string The object type
7107
  *
7108
+ * @param array|object $params An associative array of parameters
7109
  *
7110
+ * @uses wp_delete_post
7111
  *
7112
+ * @return bool
7113
+ * @since 2.0.0
7114
  */
7115
+ public function delete_object( $params ) {
7116
+ $object = $this->load_object( $params );
7117
 
7118
+ if ( empty( $object ) ) {
7119
+ return pods_error( sprintf( esc_html__( '%s Object not found', 'pods' ), ucwords( $params->type ) ), $this );
7120
  }
7121
 
7122
+ $object_collection = Pods\Whatsit\Store::get_instance();
7123
 
7124
+ /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */
7125
+ $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() );
 
 
 
 
 
 
 
 
7126
 
7127
+ $object = $post_type_storage->to_object( $params->id );
 
 
 
7128
 
7129
+ $success = false;
7130
+
7131
+ if ( $object ) {
7132
+ $success = $post_type_storage->delete( $object );
7133
+ }
7134
+
7135
+ if ( ! $success ) {
7136
+ return pods_error( sprintf( esc_html__( '%s Object not deleted', 'pods' ), ucwords( $params->type ) ), $this );
7137
  }
7138
 
7139
+ pods_transient_clear( 'pods_objects_' . $params->type );
7140
+
7141
+ return true;
7142
  }
7143
 
7144
  /**
7145
+ * @see PodsAPI::delete_object
7146
  *
7147
+ * Drop a Pod Template
7148
  *
7149
+ * $params['id'] int The template ID
7150
+ * $params['name'] string The template name
7151
  *
7152
+ * @param array $params An associative array of parameters
7153
+ *
7154
+ * @return bool
7155
+ * @since 1.7.9
7156
  */
7157
+ public function delete_template( $params ) {
7158
+ $params = (object) $params;
7159
+ $params->type = 'template';
7160
 
7161
+ return $this->delete_object( $params );
7162
+ }
 
 
 
 
 
 
 
 
 
 
7163
 
7164
+ /**
7165
+ * @see PodsAPI::delete_object
7166
+ *
7167
+ * Drop a Pod Page
7168
+ *
7169
+ * $params['id'] int The page ID
7170
+ * $params['uri'] string The page URI
7171
+ *
7172
+ * @param array $params An associative array of parameters
7173
+ *
7174
+ * @return bool
7175
+ * @since 1.7.9
7176
+ */
7177
+ public function delete_page( $params ) {
7178
+ $params = (object) $params;
7179
+
7180
+ if ( isset( $params->uri ) ) {
7181
+ $params->name = $params->uri;
7182
 
7183
+ unset( $params->uri );
7184
+ }
7185
+
7186
+ if ( isset( $params->name ) ) {
7187
+ $params->name = trim( $params->name, '/' );
7188
+ }
7189
+
7190
+ $params->type = 'page';
7191
 
7192
+ return $this->delete_object( $params );
7193
+ }
7194
 
7195
+ /**
7196
+ * @see PodsAPI::delete_object
7197
+ *
7198
+ * Drop a Pod Helper
7199
+ *
7200
+ * $params['id'] int The helper ID
7201
+ * $params['name'] string The helper name
7202
+ *
7203
+ * @param array $params An associative array of parameters
7204
+ *
7205
+ * @return bool
7206
+ * @since 1.7.9
7207
+ *
7208
+ * @deprecated since 2.8.0
7209
+ */
7210
+ public function delete_helper( $params ) {
7211
+ return false;
7212
  }
7213
 
7214
  /**
7215
+ * Drop a single pod item
7216
  *
7217
+ * $params['id'] int (optional) The item's ID from the wp_pod_* table (used with datatype parameter)
7218
+ * $params['pod'] string (optional) The Pod name (used with id parameter)
7219
+ * $params['pod_id'] int (optional) The Pod ID (used with id parameter)
7220
+ * $params['bypass_helpers'] bool Set to true to bypass running pre-save and post-save helpers
7221
  *
7222
+ * @param array $params An associative array of parameters
7223
+ * @param bool $wp Whether to run WP object delete action
7224
  *
7225
+ * @return bool
7226
  * @since 1.7.9
7227
  */
7228
+ public function delete_pod_item( $params, $wp = true ) {
7229
 
7230
+ $params = (object) $params;
 
 
 
 
7231
 
7232
+ if ( ! isset( $params->id ) ) {
7233
+ return pods_error( __( 'Pod Item not found', 'pods' ), $this );
7234
+ }
7235
 
7236
+ $params->id = pods_absint( $params->id );
 
7237
 
7238
+ if ( ! isset( $params->pod ) ) {
7239
+ $params->pod = '';
 
 
7240
  }
7241
 
7242
+ if ( ! isset( $params->pod_id ) ) {
7243
+ $params->pod_id = 0;
7244
  }
7245
 
7246
+ if ( ! isset( $params->strict ) ) {
7247
+ $params->strict = true;
 
 
7248
  }
7249
 
7250
+ $pod = $this->load_pod( array( 'name' => $params->pod, 'id' => $params->pod_id ), false );
7251
+
7252
+ if ( false === $pod ) {
7253
+ if ( $params->strict ) {
7254
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
7255
+ }
7256
 
7257
+ return false;
 
 
 
7258
  }
7259
 
7260
+ $params->pod_id = $pod['id'];
7261
+ $params->pod = $pod['name'];
7262
 
7263
+ $params = pods_sanitize( $params );
 
 
7264
 
7265
+ // Allow Helpers to bypass subsequent helpers in recursive delete_pod_item calls
7266
+ $bypass_helpers = false;
 
7267
 
7268
+ if ( isset( $params->bypass_helpers ) && false !== $params->bypass_helpers ) {
7269
+ $bypass_helpers = true;
7270
  }
7271
 
7272
+ $pre_delete_helpers = array();
7273
+ $post_delete_helpers = array();
7274
 
7275
+ if ( false === $bypass_helpers ) {
7276
+ // Plugin hook
7277
+ $this->do_hook( 'pre_delete_pod_item', $params, $pod );
7278
+ $this->do_hook( "pre_delete_pod_item_{$params->pod}", $params, $pod );
 
7279
 
7280
+ // Call any pre-save helpers (if not bypassed)
7281
+ if ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) {
7282
+ if ( ! empty( $pod ) ) {
7283
+ $helpers = array( 'pre_delete_helpers', 'post_delete_helpers' );
7284
 
7285
+ foreach ( $helpers as $helper ) {
7286
+ if ( isset( $pod[ $helper ] ) && ! empty( $pod[ $helper ] ) ) {
7287
+ ${$helper} = explode( ',', $pod[ $helper ] );
7288
+ }
7289
+ }
7290
+ }
7291
  }
7292
+ }
7293
 
7294
+ // Delete object from relationship fields
7295
+ $this->delete_object_from_relationships( $params->id, $pod );
 
 
 
 
 
 
7296
 
7297
+ if ( 'table' === $pod['storage'] ) {
7298
+ pods_query( "DELETE FROM `@wp_pods_{$params->pod}` WHERE `id` = {$params->id} LIMIT 1" );
7299
+ }
7300
 
7301
+ if ( $wp ) {
7302
+ if ( 'taxonomy' === $pod['type'] ) {
7303
+ $taxonomy = $pod['name'];
7304
 
7305
+ if ( ! empty( $pod['object'] ) ) {
7306
+ $taxonomy = $pod['object'];
 
7307
  }
7308
 
7309
+ wp_delete_term( $params->id, $taxonomy );
7310
+ } elseif ( ! in_array( $pod['type'], array( 'pod', 'table', '', 'taxonomy' ) ) ) {
7311
+ $this->delete_wp_object( $pod['type'], $params->id );
7312
  }
7313
+ }
7314
 
7315
+ if ( false === $bypass_helpers ) {
7316
+ // Plugin hook
7317
+ $this->do_hook( 'post_delete_pod_item', $params, $pod );
7318
+ $this->do_hook( "post_delete_pod_item_{$params->pod}", $params, $pod );
7319
+ }
7320
 
7321
+ pods_cache_clear( $params->id, 'pods_items_' . $params->pod );
 
7322
 
7323
+ return true;
7324
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7325
 
7326
+ /**
7327
+ * Delete an object from tableless fields.
7328
+ *
7329
+ * @param int $id
7330
+ * @param string $type
7331
+ * @param string $name
7332
+ *
7333
+ * @return bool
7334
+ *
7335
+ * @since 2.3.0
7336
+ */
7337
+ public function delete_object_from_relationships( $id, $object, $name = null ) {
7338
 
7339
+ /**
7340
+ * @var $pods_init \PodsInit
7341
+ * @todo Use pods_init() function?
7342
+ */
7343
+ global $pods_init;
7344
 
7345
+ $pod = false;
 
 
 
 
 
 
 
 
 
7346
 
7347
+ // Run any bidirectional delete operations
7348
+ if ( is_array( $object ) || $object instanceof Pods\Whatsit ) {
7349
+ $pod = $object;
7350
+ } elseif ( is_object( $pods_init ) ) {
7351
+ $pod = PodsInit::$meta->get_object( $object, $name );
7352
+ }
7353
 
7354
+ if ( ! empty( $pod ) ) {
7355
+ $object = $pod['type'];
7356
+ $name = $pod['name'];
7357
 
7358
+ foreach ( $pod['fields'] as $field ) {
7359
+ PodsForm::delete( $field['type'], $id, $field['name'], $field, $pod );
7360
  }
 
 
7361
  }
7362
 
7363
+ // Lookup related fields (non-bidirectional)
7364
+ $params = array(
7365
+ 'args' => array(
7366
+ 'type' => 'pick',
7367
+ 'pick_object' => $object,
7368
+ ),
7369
+ );
7370
 
7371
+ if ( ! empty( $name ) && $name !== $object ) {
7372
+ $params['args']['pick_val'] = $name;
7373
  }
7374
 
7375
+ try {
7376
+ $fields = $this->load_fields( $params );
7377
+
7378
+ if ( ! empty( $pod ) && 'media' === $pod['type'] ) {
7379
+ $params['args']['type'] = 'file';
7380
+
7381
+ $fields = pods_config_merge_fields( $fields, $this->load_fields( $params ) );
7382
  }
7383
 
7384
+ if ( is_array( $fields ) && ! empty( $fields ) ) {
7385
+ foreach ( $fields as $related_field ) {
7386
+ $related_pod = $this->load_pod( [ 'id' => $related_field['pod_id'] ], false );
7387
 
7388
+ if ( empty( $related_pod ) ) {
7389
+ continue;
7390
+ }
 
 
 
7391
 
7392
+ $related_from = $this->lookup_related_items_from( $related_field['id'], $related_pod['id'], $id, $related_field, $related_pod );
7393
+
7394
+ $this->delete_relationships( $related_from, $id, $related_pod, $related_field );
7395
+ }
7396
+ }
7397
+ } catch ( Exception $exception ) {
7398
+ // Nothing left to do here.
7399
  }
7400
 
7401
+ if ( ! empty( $pod ) ) {
7402
+ if ( pods_podsrel_enabled() ) {
7403
+ pods_query( '
7404
+ DELETE FROM `@wp_podsrel`
7405
+ WHERE
7406
+ (
7407
+ `pod_id` = %d
7408
+ AND `item_id` = %d
7409
+ )
7410
+ OR (
7411
+ `related_pod_id` = %d
7412
+ AND `related_item_id` = %d
7413
+ )
7414
+ ', [
7415
+ $pod['id'],
7416
+ $id,
7417
 
7418
+ $pod['id'],
7419
+ $id,
7420
+ ] );
7421
+ }
7422
 
7423
+ /**
7424
+ * Allow custom deletion actions for relationships.
7425
+ *
7426
+ * @since 2.8.0
7427
+ *
7428
+ * @param int $id ID to remove.
7429
+ * @param array|Pod $pod The Pod object.
7430
+ */
7431
+ do_action( 'pods_api_delete_object_from_relationships', $id, $pod );
7432
  }
7433
 
7434
+ return true;
7435
+ }
7436
 
7437
+ /**
7438
+ * Handle deletion of relationship data.
7439
+ *
7440
+ * @since 2.3.0
7441
+ *
7442
+ * @param int|array $related_id ID(s) for items to save.
7443
+ * @param int|array $id ID(s) to remove.
7444
+ * @param array|Pod $related_pod The related Pod object.
7445
+ * @param array|Field $related_field The related Field object.
7446
+ * @param bool $force Whether to force the deletion, even if found related IDs not set or matching.
7447
+ */
7448
+ public function delete_relationships( $related_id, $id, $related_pod, $related_field, $force = true ) {
7449
 
7450
+ if ( is_array( $related_id ) ) {
7451
+ foreach ( $related_id as $rid ) {
7452
+ $this->delete_relationships( $rid, $id, $related_pod, $related_field );
 
 
7453
  }
7454
 
7455
+ return;
7456
  }
7457
 
7458
+ if ( is_array( $id ) ) {
7459
+ foreach ( $id as $rid ) {
7460
+ $this->delete_relationships( $related_id, $rid, $related_pod, $related_field );
7461
+ }
7462
 
7463
+ return;
7464
+ }
 
 
7465
 
7466
+ $id = (int) $id;
 
 
 
7467
 
7468
+ if ( empty( $id ) ) {
7469
+ return;
7470
  }
7471
 
7472
+ $related_ids = $this->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod );
 
 
 
7473
 
7474
+ if ( ! $force ) {
7475
+ if ( empty( $related_ids ) ) {
7476
+ return;
7477
+ } elseif ( ! in_array( $id, $related_ids ) ) {
7478
+ return;
7479
+ }
7480
  }
7481
 
7482
+ $static_cache = tribe( Static_Cache::class );
7483
+
7484
+ $cache_key = $related_pod['id'] . '|' . $related_field['id'];
7485
+
7486
+ // Delete relationship from cache.
7487
+ $static_cache->delete( $cache_key, __CLASS__ . '/related_item_cache' );
7488
 
7489
+ // @codingStandardsIgnoreLine
7490
+ $key = array_search( $id, $related_ids );
7491
 
7492
+ if ( false !== $key ) {
7493
+ unset( $related_ids[ $key ] );
7494
  }
7495
 
7496
+ $no_conflict = pods_no_conflict_check( $related_pod['type'] );
 
 
 
 
 
 
 
7497
 
7498
+ if ( ! $no_conflict ) {
7499
+ pods_no_conflict_on( $related_pod['type'] );
7500
+ }
 
 
7501
 
7502
+ // Post Types, Media, Users, and Comments (meta-based)
7503
+ if ( pods_relationship_meta_storage_enabled( $related_field, $related_pod ) && in_array( $related_pod['type'], [
7504
+ 'post_type',
7505
+ 'media',
7506
+ 'taxonomy',
7507
+ 'user',
7508
+ 'comment',
7509
+ ], true ) ) {
7510
+ $object_type = $related_pod['type'];
7511
 
7512
+ if ( in_array( $object_type, [ 'post_type', 'media' ], true ) ) {
7513
+ $object_type = 'post';
7514
+ } elseif ( 'taxonomy' === $object_type ) {
7515
+ $object_type = 'term';
7516
+ }
7517
 
7518
+ delete_metadata( $object_type, $related_id, $related_field['name'] );
 
7519
 
7520
+ if ( ! empty( $related_ids ) ) {
7521
+ update_metadata( $object_type, $related_id, '_pods_' . $related_field['name'], $related_ids );
7522
+
7523
+ foreach ( $related_ids as $rel_id ) {
7524
+ add_metadata( $object_type, $related_id, $related_field['name'], $rel_id );
 
7525
  }
7526
+ } else {
7527
+ delete_metadata( $object_type, $related_id, '_pods_' . $related_field['name'] );
7528
+ }
7529
+ } elseif ( 'settings' === $related_pod['type'] ) {
7530
+ // Custom Settings Pages (options-based)
7531
+ if ( ! empty( $related_ids ) ) {
7532
+ update_option( $related_pod['name'] . '_' . $related_field['name'], $related_ids );
7533
+ } else {
7534
+ delete_option( $related_pod['name'] . '_' . $related_field['name'] );
7535
+ }
7536
+ }
7537
+
7538
+ // Relationships table
7539
+ if ( pods_podsrel_enabled() ) {
7540
+ pods_query( '
7541
+ DELETE FROM `@wp_podsrel`
7542
+ WHERE
7543
+ (
7544
+ `pod_id` = %d
7545
+ AND `field_id` = %d
7546
+ AND `item_id` = %d
7547
+ AND `related_item_id` = %d
7548
+ )
7549
+ OR (
7550
+ `related_pod_id` = %d
7551
+ AND `related_field_id` = %d
7552
+ AND `related_item_id` = %d
7553
+ AND `item_id` = %d
7554
+ )
7555
+ ', array(
7556
+ $related_pod['id'],
7557
+ $related_field['id'],
7558
+ $related_id,
7559
+ $id,
7560
 
7561
+ $related_pod['id'],
7562
+ $related_field['id'],
7563
+ $related_id,
7564
+ $id,
7565
+ ) );
7566
  }
7567
 
7568
+ /**
7569
+ * Allow custom deletion actions for relationships.
7570
+ *
7571
+ * @since 2.8.0
7572
+ *
7573
+ * @param int|array $related_id ID(s) for items to save.
7574
+ * @param int|array $id ID(s) to remove.
7575
+ * @param array|Pod $related_pod The related Pod object.
7576
+ * @param array|Field $related_field The related Field object.
7577
+ */
7578
+ do_action( 'pods_api_delete_relationships', $related_id, $id, $related_field, $related_pod );
7579
 
7580
+ if ( ! $no_conflict ) {
7581
+ pods_no_conflict_off( $related_pod['type'] );
7582
+ }
7583
  }
7584
 
7585
  /**
7586
+ * Check if a Pod exists
7587
  *
7588
+ * $params['id'] int Pod ID
7589
+ * $params['name'] string Pod name
 
 
 
 
 
 
 
 
 
 
 
7590
  *
7591
  * @param array $params An associative array of parameters
7592
  *
7593
+ * @return bool True if exists
 
 
7594
  *
7595
+ * @since 1.12
7596
  */
7597
+ public function pod_exists( $params, $type = null ) {
 
 
 
 
 
7598
 
7599
+ if ( is_string( $params ) ) {
7600
+ $params = array( 'name' => $params );
 
 
7601
  }
7602
 
7603
  $params = (object) pods_sanitize( $params );
7604
 
7605
+ if ( ! empty( $params->id ) || ! empty( $params->name ) ) {
7606
+ if ( ! isset( $params->name ) ) {
7607
+ $dummy = (int) $params->id;
7608
+ $pod = get_post( $dummy );
7609
+ } else {
7610
+ $pod = get_posts( array(
7611
+ 'name' => $params->name,
7612
+ 'post_type' => '_pods_pod',
7613
+ 'posts_per_page' => 1
7614
+ ) );
 
 
 
7615
 
7616
+ if ( is_array( $pod ) && ! empty( $pod[0] ) ) {
7617
+ $pod = $pod[0];
7618
+ }
7619
  }
7620
 
7621
+ if ( ! empty( $pod ) && ( empty( $type ) || $type == get_post_meta( $pod->ID, 'type', true ) ) ) {
7622
+ return true;
 
 
 
 
 
 
 
 
7623
  }
7624
  }
7625
 
7626
+ return false;
7627
+ }
 
 
 
 
 
 
 
 
 
 
 
 
7628
 
7629
+ /**
7630
+ * Get number of pods for a specific pod type
7631
+ *
7632
+ * @param string $type Type to get count
7633
+ *
7634
+ * @return int Total number of pods for a type
7635
+ *
7636
+ * @since 2.6.6
7637
+ */
7638
+ public function get_pod_type_count( $type ) {
7639
 
7640
+ $args = array(
7641
+ 'post_type' => '_pods_pod',
7642
+ 'posts_per_page' => - 1,
7643
+ 'nopaging' => true,
7644
+ 'fields' => 'ids',
7645
+ 'meta_query' => array(
7646
+ array(
7647
+ 'key' => 'type',
7648
+ 'value' => $type,
7649
+ ),
7650
+ ),
7651
+ );
7652
 
7653
+ $posts = get_posts( $args );
7654
 
7655
+ return count( $posts );
7656
 
7657
+ }
 
 
 
 
 
7658
 
7659
+ /**
7660
+ * Load a Pod.
7661
+ *
7662
+ * @param array|int|WP_Post|string $params {
7663
+ * An associative array of parameters.
7664
+ *
7665
+ * @type int $id The Pod ID.
7666
+ * @type string $name The Pod name.
7667
+ * @type boolean $bypass_cache Bypass the cache when getting data.
7668
+ * }
7669
+ *
7670
+ * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work.
7671
+ *
7672
+ * @return Pods\Whatsit\Pod|false Pod object or false if not found.
7673
+ *
7674
+ * @throws Exception
7675
+ * @since 1.7.9
7676
+ */
7677
+ public function load_pod( $params, $strict = false ) {
7678
+ if ( $params instanceof Pod ) {
7679
+ return $params;
7680
  }
7681
 
7682
+ if ( $params instanceof WP_Post ) {
7683
+ return $this->get_pods_object_from_wp_post( $params );
7684
  }
7685
 
7686
+ if ( is_numeric( $params ) ) {
7687
+ $params = [
7688
+ 'id' => $params,
7689
+ ];
7690
+ } elseif ( is_string( $params ) ) {
7691
+ $params = [
7692
+ 'name' => $params,
7693
+ ];
7694
  }
7695
 
7696
+ // Backwards compatibility handling.
7697
+ if ( is_object( $params ) ) {
7698
+ $params = get_object_vars( (object) $params );
7699
  }
7700
 
7701
+ if ( empty( $params ) ) {
7702
+ return false;
7703
  }
7704
 
7705
+ // Check if we need to bypass cache automatically.
7706
+ if ( ! isset( $params['bypass_cache'] ) ) {
7707
+ $api_cache = pods_api_cache();
7708
 
7709
+ if ( ! $api_cache ) {
7710
+ $params['bypass_cache'] = true;
7711
  }
7712
  }
7713
 
7714
+ if ( isset( $params['fields'] ) ) {
7715
+ unset( $params['fields'] );
7716
  }
7717
 
7718
+ if ( isset( $params['table_info'] ) ) {
7719
+ unset( $params['table_info'] );
 
 
7720
  }
7721
 
7722
+ $params['object_type'] = 'pod';
7723
+ $params['include_internal'] = true;
 
7724
 
7725
+ if ( isset( $params['name'] ) && '' === $params['name'] ) {
7726
+ unset( $params['name'] );
7727
  }
7728
 
7729
+ if ( isset( $params['id'] ) && in_array( $params['id'], array( '', 0 ), true ) ) {
7730
+ unset( $params['id'] );
 
 
7731
  }
7732
 
7733
+ $object = $this->_load_object( $params );
 
 
7734
 
7735
+ $pod = 'n/a';
 
 
7736
 
7737
+ if ( ! empty( $params['name'] ) ) {
7738
+ $pod = $params['name'];
7739
+ } elseif ( ! empty( $params['id'] ) ) {
7740
+ $pod = $params['id'];
7741
  }
7742
 
7743
+ if ( $object ) {
7744
+ return $object;
 
 
 
 
7745
  }
7746
 
7747
+ if ( $strict ) {
7748
+ return pods_error( __( 'Pod not found', 'pods' ), $this );
 
 
 
 
 
 
 
 
 
 
7749
  }
7750
 
7751
+ return false;
7752
+ }
 
 
 
 
 
 
 
 
7753
 
7754
+ /**
7755
+ * Load a list of Pods based on filters specified.
7756
+ *
7757
+ * @param array $params {
7758
+ * An associative array of parameters
7759
+ *
7760
+ * @type string|array $type Pod type(s) to filter by.
7761
+ * @type string|array $id ID(s) of Objects.
7762
+ * @type array $args Args(s) key=>value array to filter by.
7763
+ * @type boolean $count Return only a count of pods.
7764
+ * @type boolean $names Return only an array of name => label.
7765
+ * @type boolean $ids Return only an array of ID => label.
7766
+ * @type boolean $bypass_cache Bypass the cache when getting data.
7767
+ * }
7768
+ *
7769
+ * @return Pods\Whatsit\Pod[]|int List of pod objects or count.
7770
+ *
7771
+ * @throws Exception
7772
+ *
7773
+ * @since 2.0.0
7774
+ */
7775
+ public function load_pods( $params = [] ) {
7776
+ // Backwards compatibility handling.
7777
+ if ( is_object( $params ) ) {
7778
+ $params = get_object_vars( (object) $params );
7779
  }
7780
 
7781
+ $include_internal = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7782
 
7783
+ if ( isset( $params['include_internal'] ) ) {
7784
+ $include_internal = (boolean) $params['include_internal'];
 
 
 
7785
 
7786
+ unset( $params['include_internal'] );
7787
+ }
 
 
 
 
 
7788
 
7789
+ if ( ! $include_internal ) {
7790
+ $params['internal'] = false;
7791
+ }
 
 
 
7792
 
7793
+ if ( isset( $params['fields'] ) ) {
7794
+ unset( $params['fields'] );
7795
+ }
7796
 
7797
+ if ( isset( $params['table_info'] ) ) {
7798
+ unset( $params['table_info'] );
 
 
 
 
 
7799
  }
7800
 
7801
+ if ( isset( $params['object_fields'] ) ) {
7802
+ unset( $params['object_fields'] );
7803
+ }
 
 
7804
 
7805
+ // Backcompat handling.
7806
+ if ( ! empty( $params['ids'] ) ) {
7807
+ $params['id'] = $params['ids'];
 
 
 
 
 
 
7808
 
7809
+ unset( $params['ids'] );
 
 
 
 
 
 
 
7810
  }
7811
 
7812
+ $params['object_type'] = 'pod';
7813
+
7814
+ return $this->_load_objects( $params );
7815
  }
7816
 
7817
  /**
7821
  * $params['id'] int The field ID
7822
  * $params['name'] string The field name
7823
  *
7824
+ * @param array $params An associative array of parameters
7825
+ * @param boolean $allow_id Whether to allow the ID when checking if the group exists.
7826
  *
7827
  * @return bool
7828
  *
7829
  * @since 1.12
7830
  */
7831
+ public function field_exists( $params, $allow_id = true ) {
7832
+ $params = (object) $params;
7833
 
7834
+ $allowed = [
7835
+ 'name',
7836
+ 'pod_id',
7837
+ 'pod',
7838
+ ];
7839
 
7840
+ if ( $allow_id ) {
7841
+ $allowed[] = 'id';
7842
+ }
 
 
 
 
 
 
 
 
 
7843
 
7844
+ $load_params = [];
7845
+
7846
+ foreach ( $allowed as $param ) {
7847
+ if ( ! isset( $params->{$param} ) ) {
7848
+ continue;
7849
  }
7850
+
7851
+ $load_params[ $param ] = $params->{$param};
7852
  }
7853
 
7854
+ try {
7855
+ return (boolean) $this->load_field( $load_params );
7856
+ } catch ( Exception $exception ) {
7857
+ return false;
7858
+ }
7859
  }
7860
 
7861
  /**
7862
+ * Load a field.
7863
  *
7864
+ * @param array|int $params {
7865
+ * An associative array of parameters.
7866
+ *
7867
+ * @type int $pod_id The Pod ID.
7868
+ * @type string $pod The Pod name.
7869
+ * @type int $id The field ID.
7870
+ * @type string $name The field name.
7871
+ * @type boolean $bypass_cache Bypass the cache when getting data.
7872
+ * }
7873
  *
7874
+ * @param boolean $strict Whether to require a field exist or not when loading the info.
 
7875
  *
7876
+ * @return Pods\Whatsit\Field|bool Field object or false if not found.
7877
+ *
7878
+ * @throws Exception
7879
+ * @throws Exception
7880
  * @since 1.7.9
7881
  */
7882
  public function load_field( $params, $strict = false ) {
7883
+ if ( $params instanceof Field ) {
7884
+ return $params;
 
 
 
7885
  }
7886
 
7887
+ if ( $params instanceof WP_Post ) {
7888
+ return $this->get_pods_object_from_wp_post( $params );
 
 
7889
  }
7890
 
7891
+ if ( is_numeric( $params ) ) {
7892
+ $params = [
7893
+ 'id' => $params,
7894
+ ];
7895
+ } elseif ( is_string( $params ) ) {
7896
+ $params = [
7897
+ 'name' => $params,
7898
+ ];
7899
+ }
 
 
 
7900
 
7901
+ // Backwards compatibility handling.
7902
+ if ( is_object( $params ) ) {
7903
+ $params = get_object_vars( (object) $params );
7904
+ }
7905
 
7906
+ // Check if we need to bypass cache automatically.
7907
+ if ( ! isset( $params['bypass_cache'] ) ) {
7908
+ $api_cache = pods_api_cache();
 
 
 
 
 
 
 
 
 
 
 
7909
 
7910
+ if ( ! $api_cache ) {
7911
+ $params['bypass_cache'] = true;
7912
  }
7913
+ }
7914
 
7915
+ if ( isset( $params['table_info'] ) ) {
7916
+ unset( $params['table_info'] );
7917
+ }
7918
 
7919
+ if ( isset( $params['pod_id'] ) ) {
7920
+ $params['parent'] = (int) $params['pod_id'];
 
7921
 
7922
+ unset( $params['pod_id'] );
7923
+ }
7924
 
7925
+ if ( isset( $params['pod'] ) ) {
7926
+ if ( empty( $params['parent'] ) ) {
7927
+ $params['parent'] = 0;
7928
 
7929
+ $pod = $this->load_pod( $params['pod'], false );
7930
 
7931
+ if ( $pod ) {
7932
+ $params['parent'] = $pod->get_id();
7933
+ }
7934
  }
7935
 
7936
+ unset( $params['pod'] );
7937
+ }
 
 
 
 
 
7938
 
7939
+ if ( isset( $params['group_id'] ) ) {
7940
+ $params['group'] = (int) $params['group_id'];
 
 
7941
 
7942
+ unset( $params['group_id'] );
7943
+ }
7944
 
7945
+ if ( isset( $params['group'] ) ) {
7946
+ $group = $this->load_group( $params['group'], false );
7947
 
7948
+ if ( $group ) {
7949
+ $params['group'] = $group->get_id();
7950
  }
7951
  }
7952
 
7953
+ $params['object_type'] = 'field';
7954
+ $params['include_internal'] = true;
 
 
7955
 
7956
+ $object = $this->_load_object( $params );
7957
+
7958
+ if ( $object ) {
7959
+ return $object;
7960
  }
7961
 
7962
+ if ( $strict ) {
7963
+ return pods_error( __( 'Pod field not found', 'pods' ), $this );
7964
+ }
7965
 
7966
+ return false;
7967
+ }
 
 
7968
 
7969
+ /**
7970
+ * Traverse fields and load their information.
7971
+ *
7972
+ * @param array $params {
7973
+ * An associative array of parameters.
7974
+ *
7975
+ * @type string $pod The Pod name.
7976
+ * @type array $expand The field name(s) to expand.
7977
+ * @type array $types The field type(s).
7978
+ * @type boolean $bypass_cache Bypass the cache when getting data.
7979
+ * }
7980
+ *
7981
+ * @return Pods\Whatsit\Field[] List of field objects.
7982
+ *
7983
+ * @since 2.8.0
7984
+ */
7985
+ public function traverse_fields( array $params ) {
7986
+ $fields = array();
7987
 
7988
+ try {
7989
+ // pod and expand are required parameters.
7990
+ if ( empty( $params['pod'] ) || empty( $params['expand'] ) ) {
7991
+ return array();
7992
  }
 
7993
 
7994
+ // Check if we need to bypass cache automatically.
7995
+ if ( ! isset( $params['bypass_cache'] ) ) {
7996
+ $api_cache = pods_api_cache();
7997
+
7998
+ if ( ! $api_cache ) {
7999
+ $params['bypass_cache'] = true;
8000
+ }
8001
  }
8002
 
8003
+ $pod = $params['pod'];
8004
+ $expand = $params['expand'];
8005
+ $types = ! empty( $params['types'] ) ? (array) $params['types'] : PodsForm::tableless_field_types();
 
8006
 
8007
+ // For each in expand, load field, fall back to load pod if an object field.
8008
+ foreach ( $expand as $field_name ) {
8009
+ $args = array(
8010
+ 'pod' => $pod,
8011
+ 'name' => $field_name,
8012
+ 'type' => $types,
 
 
 
 
 
8013
  );
8014
 
8015
+ $field = $this->load_field( $args );
 
 
 
 
 
 
 
8016
 
8017
+ if ( ! $field instanceof Field ) {
8018
+ // Check if this is an object field.
8019
+ $pod_data = $this->load_pod( $pod );
8020
 
8021
+ if ( ! $pod_data instanceof Pod ) {
8022
+ break;
8023
+ }
8024
 
8025
+ $field = $pod_data->get_field( $field_name );
 
 
 
 
 
 
 
 
 
 
8026
 
8027
+ if ( ! $field instanceof Object_Field || ! in_array( $field['type'], $types, true ) ) {
8028
+ break;
 
8029
  }
8030
  }
8031
 
8032
+ $fields[] = $field;
 
 
 
 
 
 
8033
 
8034
+ $pod = $field->get_related_object_name();
 
 
 
 
 
8035
 
8036
+ if ( null === $pod ) {
8037
+ break;
8038
  }
8039
+ }
8040
+ } catch ( \Exception $e ) {
8041
+ // Do nothing.
8042
+ }
8043
 
8044
+ return $fields;
8045
+ }
8046
 
8047
+ /**
8048
+ * Load fields by Pod, ID, Name, and/or Type.
8049
+ *
8050
+ * @param array $params {
8051
+ * An associative array of parameters.
8052
+ *
8053
+ * @type int $pod_id The Pod ID.
8054
+ * @type string $pod The Pod name.
8055
+ * @type string|array $id The field ID(s).
8056
+ * @type string|array $name The field name(s).
8057
+ * @type string|array $type The field type(s).
8058
+ * @type array $args Arg(s) key=>value array to filter by.
8059
+ * @type boolean $count Return only a count of fields.
8060
+ * @type boolean $names Return only an array of name => label.
8061
+ * @type boolean $ids Return only an array of ID => label.
8062
+ * @type boolean $bypass_cache Bypass the cache when getting data.
8063
+ * }
8064
+ *
8065
+ * @return Pods\Whatsit\Field[]|int List of field objects or count.
8066
+ *
8067
+ * @throws Exception
8068
+ *
8069
+ * @since 1.7.9
8070
+ */
8071
+ public function load_fields( $params = [] ) {
8072
+ // Backwards compatibility handling.
8073
+ if ( is_object( $params ) ) {
8074
+ $params = get_object_vars( $params );
8075
+ }
8076
 
8077
+ $include_internal = false;
8078
 
8079
+ if ( isset( $params['include_internal'] ) ) {
8080
+ $include_internal = (boolean) $params['include_internal'];
8081
 
8082
+ unset( $params['include_internal'] );
8083
+ }
8084
 
8085
+ if ( ! $include_internal ) {
8086
+ $params['internal'] = false;
8087
+ }
8088
 
8089
+ if ( isset( $params['table_info'] ) ) {
8090
+ unset( $params['table_info'] );
8091
+ }
8092
 
8093
+ // Backcompat handling.
8094
+ if ( ! empty( $params['ids'] ) ) {
8095
+ $params['id'] = $params['ids'];
8096
 
8097
+ unset( $params['ids'] );
8098
+ }
8099
 
8100
+ if ( isset( $params['pod_id'] ) ) {
8101
+ $params['parent'] = (int) $params['pod_id'];
 
8102
 
8103
+ unset( $params['pod_id'] );
 
 
 
8104
  }
8105
 
8106
+ if ( isset( $params['pod'] ) ) {
8107
+ if ( empty( $params['parent'] ) ) {
8108
+ $params['parent'] = 0;
8109
+
8110
+ $pod = $this->load_pod( $params['pod'], false );
8111
+
8112
+ if ( $pod ) {
8113
+ $params['parent'] = $pod->get_id();
8114
+ }
8115
+ }
8116
 
8117
+ unset( $params['pod'] );
 
8118
  }
8119
 
8120
+ $params['object_type'] = 'field';
8121
+
8122
+ return $this->_load_objects( $params );
8123
  }
8124
 
8125
  /**
8126
+ * Check if a Pod's group exists
8127
  *
8128
+ * @param array|int|WP_Post $params {
8129
+ * An associative array of parameters.
 
 
 
 
 
 
8130
  *
8131
+ * @type int $pod_id The Pod ID.
8132
+ * @type string $pod The Pod name.
8133
+ * @type int $id The Group ID.
8134
+ * @type string $name The Group name.
8135
+ * @type boolean $bypass_cache Bypass the cache when getting data.
8136
+ * }
8137
+ * @param boolean $allow_id Whether to allow the ID when checking if the group exists.
8138
  *
8139
+ * @return bool
8140
  *
8141
+ * @since 2.8.0
8142
  */
8143
+ public function group_exists( $params, $allow_id = true ) {
8144
+ $params = (object) $params;
8145
+
8146
+ $allowed = [
8147
+ 'name',
8148
+ 'pod_id',
8149
+ 'pod',
8150
+ ];
8151
 
8152
+ if ( $allow_id ) {
8153
+ $allowed[] = 'id';
 
 
8154
  }
8155
 
8156
+ $load_params = [];
8157
 
8158
+ foreach ( $allowed as $param ) {
8159
+ if ( ! isset( $params->{$param} ) ) {
8160
+ continue;
8161
+ }
8162
 
8163
+ $load_params[ $param ] = $params->{$param};
 
8164
  }
8165
 
8166
+ try {
8167
+ return (boolean) $this->load_group( $load_params );
8168
+ } catch ( Exception $exception ) {
8169
+ return false;
8170
  }
8171
+ }
8172
 
8173
+ /**
8174
+ * Load a Group.
8175
+ *
8176
+ * @param array|int|WP_Post $params {
8177
+ * An associative array of parameters.
8178
+ *
8179
+ * @type int $pod_id The Pod ID.
8180
+ * @type string $pod The Pod name.
8181
+ * @type int $id The Group ID.
8182
+ * @type string $name The Group name.
8183
+ * @type boolean $bypass_cache Bypass the cache when getting data.
8184
+ * }
8185
+ *
8186
+ * @param bool $strict Makes sure the pod exists, throws an error if it doesn't work.
8187
+ *
8188
+ * @return Pods\Whatsit\Group|false Group object or false if not found.
8189
+ *
8190
+ * @throws Exception
8191
+ * @since 2.8.0
8192
+ */
8193
+ public function load_group( $params, $strict = false ) {
8194
+ if ( $params instanceof Group ) {
8195
+ return $params;
8196
  }
8197
 
8198
+ if ( $params instanceof WP_Post ) {
8199
+ return $this->get_pods_object_from_wp_post( $params );
 
 
8200
  }
8201
 
8202
+ if ( is_numeric( $params ) ) {
8203
+ $params = [
8204
+ 'id' => $params,
8205
+ ];
8206
+ } elseif ( is_string( $params ) ) {
8207
+ $params = [
8208
+ 'name' => $params,
8209
+ ];
8210
  }
8211
 
8212
+ // Backwards compatibility handling.
8213
+ if ( is_object( $params ) ) {
8214
+ $params = get_object_vars( (object) $params );
8215
+ }
 
 
 
 
 
 
 
 
 
8216
 
8217
+ // Check if we need to bypass cache automatically.
8218
+ if ( ! isset( $params['bypass_cache'] ) ) {
8219
+ $api_cache = pods_api_cache();
8220
 
8221
+ if ( ! $api_cache ) {
8222
+ $params['bypass_cache'] = true;
8223
  }
8224
+ }
8225
 
8226
+ if ( isset( $params['table_info'] ) ) {
8227
+ unset( $params['table_info'] );
8228
+ }
 
 
 
 
 
 
 
 
 
8229
 
8230
+ if ( isset( $params['pod_id'] ) ) {
8231
+ $params['parent'] = (int) $params['pod_id'];
8232
 
8233
+ unset( $params['pod_id'] );
8234
+ }
 
 
 
8235
 
8236
+ if ( isset( $params['pod'] ) ) {
8237
+ if ( empty( $params['parent'] ) ) {
8238
+ $params['parent'] = 0;
8239
 
8240
+ $pod = $this->load_pod( $params['pod'], false );
8241
 
8242
+ if ( $pod ) {
8243
+ $params['parent'] = $pod->get_id();
 
 
 
8244
  }
8245
  }
8246
 
8247
+ unset( $params['pod'] );
8248
+ }
 
8249
 
8250
+ $params['object_type'] = 'group';
8251
+ $params['include_internal'] = true;
 
 
 
 
 
 
8252
 
8253
+ $object = $this->_load_object( $params );
8254
+
8255
+ if ( $object ) {
8256
+ return $object;
8257
+ }
8258
 
8259
+ if ( $strict ) {
8260
+ return pods_error( __( 'Pod group not found', 'pods' ), $this );
8261
+ }
8262
 
8263
+ return false;
8264
+ }
8265
 
8266
+ /**
8267
+ * Load a list of Groups based on filters specified.
8268
+ *
8269
+ * @param array $params {
8270
+ * An associative array of parameters.
8271
+ *
8272
+ * @type int $pod_id The Pod ID.
8273
+ * @type string $pod The Pod name.
8274
+ * @type string|array $id The group ID(s).
8275
+ * @type array $name The group names.
8276
+ * @type array $type The group types.
8277
+ * @type array $args Arg(s) key=>value to filter by.
8278
+ * @type boolean $count Return only a count of objects.
8279
+ * @type boolean $names Return only an array of name => label.
8280
+ * @type boolean $ids Return only an array of ID => label.
8281
+ * @type boolean $bypass_cache Bypass the cache when getting data.
8282
+ * }
8283
+ *
8284
+ * @return Pods\Whatsit\Group[]|int List of group objects or count.
8285
+ *
8286
+ * @throws Exception
8287
+ *
8288
+ * @since 2.8.0
8289
+ */
8290
+ public function load_groups( $params = [] ) {
8291
+ // Backwards compatibility handling.
8292
+ if ( is_object( $params ) ) {
8293
+ $params = get_object_vars( $params );
8294
+ }
8295
 
8296
+ $include_internal = false;
 
 
 
 
 
 
 
8297
 
8298
+ if ( isset( $params['include_internal'] ) ) {
8299
+ $include_internal = (boolean) $params['include_internal'];
8300
 
8301
+ unset( $params['include_internal'] );
8302
+ }
8303
 
8304
+ if ( ! $include_internal ) {
8305
+ $params['internal'] = false;
8306
+ }
8307
 
8308
+ if ( isset( $params['table_info'] ) ) {
8309
+ unset( $params['table_info'] );
8310
+ }
8311
 
8312
+ if ( isset( $params['object_fields'] ) ) {
8313
+ unset( $params['object_fields'] );
8314
+ }
8315
 
8316
+ if ( isset( $params['pod_id'] ) ) {
8317
+ $params['parent'] = (int) $params['pod_id'];
8318
 
8319
+ unset( $params['pod_id'] );
8320
+ }
8321
 
8322
+ if ( isset( $params['pod'] ) ) {
8323
+ if ( empty( $params['parent'] ) ) {
8324
+ $params['parent'] = 0;
8325
 
8326
+ $pod = $this->load_pod( $params['pod'], false );
 
 
 
 
 
 
8327
 
8328
+ if ( $pod ) {
8329
+ $params['parent'] = $pod->get_id();
 
8330
  }
8331
  }
8332
+
8333
+ unset( $params['pod'] );
 
8334
  }
8335
 
8336
+ $params['object_type'] = 'group';
8337
+
8338
+ return $this->_load_objects( $params );
8339
  }
8340
 
8341
  /**
8352
  * @since 2.0.0
8353
  */
8354
  public function load_object( $params, $strict = false ) {
8355
+ // Backwards compatibility handling.
8356
+ if ( is_object( $params ) ) {
8357
+ $params = get_object_vars( (object) $params );
8358
+ }
8359
 
8360
+ if ( ! isset( $params['type'] ) ) {
8361
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8362
  }
8363
 
8364
+ $params['object_type'] = $params['type'];
 
 
 
 
 
 
8365
 
8366
+ unset( $params['type'] );
8367
 
8368
+ // Check if we need to bypass cache automatically.
8369
+ if ( ! isset( $params['bypass_cache'] ) ) {
8370
+ $api_cache = pods_api_cache();
8371
+
8372
+ if ( ! $api_cache ) {
8373
+ $params['bypass_cache'] = true;
8374
  }
8375
  }
8376
 
8377
+ return $this->_load_object( $params, $strict );
8378
  }
8379
 
8380
  /**
8393
  * @since 2.0.0
8394
  */
8395
  public function load_objects( $params ) {
8396
+ // Backwards compatibility handling.
8397
+ if ( is_object( $params ) ) {
8398
+ $params = get_object_vars( (object) $params );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8399
  }
8400
 
8401
+ if ( ! isset( $params['type'] ) ) {
8402
+ return array();
 
 
 
 
 
 
 
 
 
 
 
8403
  }
8404
 
8405
+ $params['object_type'] = $params['type'];
 
 
8406
 
8407
+ unset( $params['type'] );
 
8408
 
8409
+ if ( isset( $params['ids'] ) ) {
8410
+ $params['id'] = $params['ids'];
 
 
8411
 
8412
+ unset( $params['ids'] );
 
8413
  }
8414
 
8415
+ // Check if we need to bypass cache automatically.
8416
+ if ( ! isset( $params['bypass_cache'] ) ) {
8417
+ $api_cache = pods_api_cache();
8418
 
8419
+ if ( ! $api_cache ) {
8420
+ $params['bypass_cache'] = true;
 
 
8421
  }
8422
  }
8423
 
8424
+ return $this->_load_objects( $params );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8425
  }
8426
 
8427
  /**
8438
  * @since 1.7.9
8439
  */
8440
  public function load_template( $params ) {
 
8441
  if ( ! class_exists( 'Pods_Templates' ) ) {
8442
  return false;
8443
  }
8445
  $params = (object) $params;
8446
  $params->type = 'template';
8447
 
8448
+ if ( isset( $params->name ) ) {
8449
+ $params->title = $params->name;
8450
+
8451
+ unset( $params->name );
8452
+ }
8453
+
8454
  return $this->load_object( $params );
8455
  }
8456
 
8471
  * @since 2.0.0
8472
  */
8473
  public function load_templates( $params = null ) {
 
8474
  if ( ! class_exists( 'Pods_Templates' ) ) {
8475
  return array();
8476
  }
8496
  * @since 1.7.9
8497
  */
8498
  public function load_page( $params ) {
 
8499
  if ( ! class_exists( 'Pods_Pages' ) ) {
8500
  return false;
8501
  }
8502
 
8503
  $params = (object) $params;
8504
+
8505
+ if ( isset( $params->name ) ) {
8506
+ $params->title = $params->name;
8507
+
8508
+ unset( $params->name );
8509
+ }
8510
+
8511
+ if ( ! isset( $params->title ) && isset( $params->uri ) ) {
8512
+ $params->title = $params->uri;
8513
+
8514
  unset( $params->uri );
8515
  }
8516
+
8517
  $params->type = 'page';
8518
 
8519
  return $this->load_object( $params );
8536
  * @since 2.0.0
8537
  */
8538
  public function load_pages( $params = null ) {
 
8539
  if ( ! class_exists( 'Pods_Pages' ) ) {
8540
  return array();
8541
  }
8559
  * @return array|bool
8560
  *
8561
  * @since 1.7.9
8562
+ *
8563
+ * @deprecated since 2.8.0
8564
  */
8565
  public function load_helper( $params ) {
8566
+ return false;
 
 
 
 
 
 
 
 
8567
  }
8568
 
8569
  /**
8581
  * @return array
8582
  *
8583
  * @since 2.0.0
8584
+ *
8585
+ * @deprecated since 2.8.0
8586
  */
8587
  public function load_helpers( $params = null ) {
8588
+ return [];
 
 
 
 
 
 
 
 
8589
  }
8590
 
8591
  /**
8652
  $params = (object) pods_sanitize( $params );
8653
 
8654
  if ( empty( $pod ) ) {
8655
+ $pod = $this->load_pod( array( 'name' => $params->pod ), false );
8656
 
8657
  if ( false === $pod ) {
8658
  return pods_error( __( 'Pod not found', 'pods' ), $this );
8677
  $type = $params->related_pod;
8678
  }
8679
 
8680
+ $related_pod = $this->load_pod( array( 'name' => $params->related_pod ), false );
8681
 
8682
  if ( false === $related_pod || ( false !== $type && 'pod' !== $type && $type !== $related_pod['type'] ) ) {
8683
  return pods_error( __( 'Related Pod not found', 'pods' ), $this );
8691
  foreach ( $related_pod['fields'] as $field ) {
8692
  if ( 'pick' === $field['type'] && in_array( $field['pick_object'], array(
8693
  $pod['type'],
8694
+ 'pod',
8695
+ ), true ) && ( $params->pod == $field['pick_object'] || $params->pod == $field['pick_val'] ) ) {
8696
  $sister_fields[ $field['id'] ] = esc_html( $field['label'] . ' (' . $field['name'] . ')' );
8697
  }
8698
  }
8786
  *
8787
  * @since 2.0.0
8788
  */
8789
+ public function handle_field_validation( &$value, $field, $object_fields, $fields, $pod, $params = [] ) {
8790
 
8791
  $tableless_field_types = PodsForm::tableless_field_types();
8792
 
8793
+ $fields = pods_config_merge_fields( $fields, $object_fields );
8794
 
8795
  $options = $fields[ $field ];
8796
 
8797
+ if ( is_array( $params ) ) {
8798
+ $params = (object) $params;
8799
+ }
8800
+
8801
+ $id = 0;
8802
+
8803
+ if ( is_object( $params ) ) {
8804
+ $id = $params->id;
8805
+ } elseif ( $pod instanceof Pods ) {
8806
+ $id = $pod->id();
8807
+ }
8808
 
8809
+ // Normalize to Pod config object.
8810
+ if ( $pod instanceof Pods ) {
8811
  $pod = $pod->pod_data;
8812
+ } elseif ( ! is_array( $pod ) && ! $pod instanceof Pod ) {
8813
+ $pod = null;
8814
  }
8815
 
8816
  $type = $options['type'];
8818
  $label = empty( $label ) ? $field : $label;
8819
 
8820
  // Verify required fields
8821
+ if ( 'slug' !== $type && 1 === (int) pods_v( 'required', $options, 0 ) ) {
8822
  if ( '' === $value || null === $value || array() === $value ) {
8823
  return pods_error( sprintf( __( '%s is empty', 'pods' ), $label ), $this );
8824
  }
8825
 
8826
+ if ( 'multi' === pods_v( 'pick_format_type', $options ) && 'autocomplete' !== pods_v( 'pick_format_multi', $options ) ) {
8827
  $has_value = false;
8828
 
8829
  $check_value = (array) $value;
8845
 
8846
  // @todo move this to after pre-save preparations
8847
  // Verify unique fields
8848
+ if ( 1 === (int) pods_v( 'unique', $options, 0 ) && '' !== $value && null !== $value && array() !== $value ) {
8849
  if ( empty( $pod ) ) {
8850
  return false;
8851
  }
8852
 
8853
+ if ( ! in_array( $type, $tableless_field_types, true ) ) {
8854
  $exclude = '';
8855
 
8856
  if ( ! empty( $id ) ) {
8875
  }
8876
  }
8877
 
8878
+ $validate = PodsForm::validate( $options['type'], $value, $field, $options, $fields, $pod, $id, $params );
8879
 
8880
  $validate = $this->do_hook( 'field_validation', $validate, $value, $field, $object_fields, $fields, $pod, $params );
8881
 
8897
  *
8898
  * @uses pods_query()
8899
  */
8900
+ public function lookup_related_items( $field_id, $pod_id, $ids, $field = null, $pod = null, $force_meta = true ) {
8901
 
8902
  $related_ids = array();
8903
 
8911
 
8912
  $idstring = implode( ',', $ids );
8913
 
8914
+ $static_cache = tribe( Static_Cache::class );
8915
+
8916
+ $cache_key = $pod_id . '|' . $field_id;
8917
+
8918
+ // Check cache first, no point in running the same query multiple times
8919
+ if ( $pod_id && $field_id ) {
8920
+ $cache_value = $static_cache->get( $cache_key, __CLASS__ . '/related_item_cache' ) ?: [];
8921
+
8922
+ if ( isset( $cache_value[ $idstring ] ) ) {
8923
+ return $cache_value[ $idstring ];
8924
+ }
8925
  }
8926
 
8927
  $tableless_field_types = PodsForm::tableless_field_types();
8928
 
8929
  $field_type = pods_v( 'type', $field );
8930
 
8931
+ if ( empty( $ids ) || ! in_array( $field_type, $tableless_field_types, true ) ) {
8932
  return array();
8933
  }
8934
 
8935
  $related_pick_limit = 0;
8936
 
8937
  if ( empty( $field ) ) {
8938
+ $load_params = array(
8939
+ 'parent' => $pod_id,
8940
+ );
8941
+
8942
+ if ( ! empty( $field_id ) ) {
8943
+ $load_params['id'] = $field_id;
8944
+ }
8945
+
8946
+ $field = $this->load_field( $load_params );
8947
  }
8948
 
8949
  if ( ! empty( $field ) ) {
8950
+ $related_pick_limit = (int) pods_v( $field_type . '_limit', $field, 0 );
8951
 
8952
+ if ( 'single' === pods_v( $field_type . '_format_type', $field ) ) {
 
 
8953
  $related_pick_limit = 1;
8954
  }
8955
 
8974
  if ( ! is_wp_error( $related ) ) {
8975
  $related_ids = $related;
8976
  }
8977
+ } elseif ( ! pods_tableless() && pods_podsrel_enabled() ) {
8978
  $ids = implode( ', ', $ids );
8979
 
8980
  $field_id = (int) $field_id;
8981
+ $sister_id = (int) pods_v( 'sister_id', $field, 0 );
 
 
 
 
 
8982
 
8983
  $sql = "
8984
  SELECT item_id, related_item_id, related_field_id
8985
  FROM `@wp_podsrel`
8986
  WHERE
8987
+ `field_id` = {$field_id}
8988
+ AND `item_id` IN ( {$ids} )
8989
  ORDER BY `weight`
8990
  ";
8991
 
9001
  }
9002
  }
9003
  } else {
9004
+ if ( ! ( is_array( $pod ) || $pod instanceof Pods\Whatsit ) ) {
9005
+ $pod = $this->load_pod( array( 'id' => $pod_id ), false );
9006
  }
9007
 
9008
  if ( ! empty( $pod ) && in_array( $pod['type'], array(
9015
  ) ) ) {
9016
  $meta_type = $pod['type'];
9017
 
9018
+ if ( in_array( $meta_type, array( 'post_type', 'media' ), true ) ) {
9019
  $meta_type = 'post';
9020
  } elseif ( 'taxonomy' === $meta_type ) {
9021
  $meta_type = 'term';
9050
  }
9051
  }
9052
  }
9053
+ } elseif ( pods_relationship_meta_storage_enabled( $field, $pod ) ) {
9054
  $related_id = get_metadata( $meta_type, $id, '_pods_' . $field['name'], true );
9055
 
9056
  if ( empty( $related_id ) ) {
9092
  $related_ids = array_slice( $related_ids, 0, $related_pick_limit );
9093
  }
9094
  }
9095
+
9096
  if ( 0 != $pod_id && 0 != $field_id && ! empty( $related_ids ) ) {
9097
  // Only cache if $pod_id and $field_id were passed
9098
+ $cache_value = $static_cache->get( $cache_key, __CLASS__ . '/related_item_cache' ) ?: [];
9099
+
9100
+ $cache_value[ $idstring ] = $related_ids;
9101
+
9102
+ $static_cache->set( $cache_key, $cache_value, __CLASS__ . '/related_item_cache' );
9103
  }
9104
 
9105
  return $related_ids;
9135
  $related_pick_limit = 0;
9136
 
9137
  if ( ! empty( $field ) ) {
9138
+ $related_pick_limit = (int) pods_v( $field['type'] . '_limit', $field, 0 );
 
 
9139
 
9140
+ if ( 'single' === pods_v( $field['type'] . '_format_type', $field ) ) {
9141
  $related_pick_limit = 1;
9142
  }
9143
  }
9144
 
9145
  if ( ! pods_tableless() ) {
9146
  $field_id = (int) $field_id;
9147
+ $sister_id = (int) pods_v( 'sister_id', $field, 0 );
9148
 
9149
+ $relationships = array();
 
 
 
9150
 
9151
+ if ( pods_podsrel_enabled() ) {
9152
+ $sql = "
9153
+ SELECT *
9154
+ FROM `@wp_podsrel`
9155
+ WHERE
9156
+ `field_id` = {$field_id}
9157
+ AND `related_item_id` = {$id}
9158
+ ORDER BY `weight`
9159
+ ";
9160
 
9161
+ $relationships = pods_query( $sql );
9162
+ }
9163
 
9164
  if ( ! empty( $relationships ) ) {
9165
  $related_ids = array();
9176
  // @todo handle meta-based lookups
9177
  return false;
9178
 
9179
+ if ( ! ( is_array( $pod ) || $pod instanceof Pods\Whatsit ) ) {
9180
+ $pod = $this->load_pod( array( 'id' => $pod_id ), false );
9181
  }
9182
 
9183
  if ( ! empty( $pod ) && in_array( $pod['type'], array(
9192
 
9193
  $meta_type = $pod['type'];
9194
 
9195
+ if ( in_array( $meta_type, array( 'post_type', 'media' ), true ) ) {
9196
  $meta_type = 'post';
9197
  } elseif ( 'taxonomy' === $meta_type ) {
9198
  $meta_type = 'term';
9298
  $name = $object;
9299
  }
9300
 
9301
+ $pod = $this->load_pod( [
9302
+ 'name' => $name,
9303
+ 'auto_setup' => true,
9304
+ ] );
9305
 
9306
  if ( ! empty( $pod ) ) {
9307
  $object_type = $pod['type'];
9325
  }
9326
 
9327
  if ( ! empty( $name ) ) {
9328
+ $pod = $this->load_pod( [
9329
+ 'name' => $name,
9330
+ 'auto_setup' => true,
9331
+ ] );
9332
 
9333
  if ( ! empty( $pod ) && ( null === $object_type || $object_type == $pod['type'] ) ) {
9334
  $object_type = $pod['type'];
9358
  $info['meta_table'] = $wpdb->prefix . 'pods_' . ( empty( $object ) ? $name : $object );
9359
  $info['table'] = $info['meta_table'];
9360
 
9361
+ if ( ( is_array( $info['pod'] ) || $info['pod'] instanceof Pods\Whatsit ) && 'pod' === pods_v( 'type', $info['pod'] ) ) {
9362
+ $info['meta_field_value'] = pods_v( 'pod_index', $info['pod'], 'id', true );
9363
  $info['pod_field_index'] = $info['meta_field_value'];
9364
  $info['field_index'] = $info['meta_field_value'];
9365
  $info['meta_field_index'] = $info['meta_field_value'];
9386
  $info['field_slug'] = $slug_field->post_name;
9387
  }
9388
 
9389
+ if ( 1 == pods_v( 'hierarchical', $info['pod'], 0 ) ) {
9390
+ $parent_field = pods_v( 'pod_parent', $info['pod'], 'id', true );
9391
 
9392
  if ( ! empty( $parent_field ) && isset( $info['pod']['fields'][ $parent_field ] ) ) {
9393
  $info['object_hierarchical'] = true;
9436
  'type' => null,
9437
  'object_name' => $object,
9438
  'object_hierarchical' => false,
9439
+ 'storage' => null,
9440
 
9441
  'table' => $object,
9442
  'meta_table' => $object,
9474
  $object = 'post';
9475
  } elseif ( empty( $object ) && in_array( $object_type, array( 'user', 'media', 'comment' ), true ) ) {
9476
  $object = $object_type;
9477
+ } elseif ( 'post_type' === $object_type && 'attachment' === $object ) {
9478
+ $object_type = 'media';
9479
+ $object = $object_type;
9480
  }
9481
 
9482
  $pod_name = $pod;
9483
 
9484
+ if ( is_array( $pod_name ) || $pod_name instanceof Pods\Whatsit ) {
9485
+ $pod_name = pods_v( 'name', $pod_name, json_encode( $pod_name, JSON_UNESCAPED_UNICODE ), true );
9486
  } else {
9487
  $pod_name = $object;
9488
  }
9489
 
9490
  $field_name = $field;
9491
 
9492
+ if ( is_array( $field_name ) || $field_name instanceof Pods\Whatsit ) {
9493
+ $field_name = pods_v( 'name', $field_name, json_encode( $pod_name, JSON_UNESCAPED_UNICODE ), true );
9494
  }
9495
 
9496
+ $cache_key = 'pods_' . $wpdb->prefix . '_get_table_info_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9497
 
9498
+ $current_language = pods_i18n()->get_current_language();
9499
  if ( ! empty( $current_language ) ) {
9500
+ $cache_key = 'pods_' . $wpdb->prefix . '_get_table_info_' . $current_language . '_' . md5( $object_type . '_object_' . $object . '_name_' . $name . '_pod_' . $pod_name . '_field_' . $field_name );
9501
  }
9502
 
9503
  $_info = false;
 
9504
 
9505
+ $static_cache = tribe( Static_Cache::class );
9506
+
9507
+ $table_info_cache = $static_cache->get( $cache_key, __CLASS__ . '/table_info_cache' ) ?: [];
9508
+
9509
+ if ( $table_info_cache ) {
9510
  // Prefer info from the object internal cache
9511
+ $_info = $table_info_cache;
9512
  } elseif ( pods_api_cache() ) {
9513
+ if ( ! did_action( 'init' ) || doing_action( 'init' ) ) {
9514
+ $_info = pods_transient_get( $cache_key . '_pre_init' );
9515
+ } else {
9516
+ $_info = pods_transient_get( $cache_key );
9517
  }
 
9518
  }
9519
 
9520
  if ( false !== $_info && is_array( $_info ) ) {
9521
  // Data was cached, use that
9522
  $info = $_info;
9523
+
9524
+ /**
9525
+ * Allow filtering the table information for an object.
9526
+ *
9527
+ * @param array $info The table information.
9528
+ * @param string $object_type The object type.
9529
+ * @param string $object The object name.
9530
+ * @param string $name The pod name.
9531
+ * @param array|Pod $pod The pod config (if found).
9532
+ * @param array|Field $field The field config (if found).
9533
+ * @param self $obj The PodsAPI object.
9534
+ */
9535
+ return apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this );
9536
  } else {
9537
  // Data not cached, load it up
9538
  $_info = $this->get_table_info_load( $object_type, $object, $name, $pod );
9543
  $info = array_merge( $info, $_info );
9544
  }
9545
 
9546
+ if (
9547
+ 0 === strpos( $object_type, 'post_type' )
9548
+ || 'media' === $object_type
9549
+ || in_array( pods_v( 'type', $info['pod'] ), [
9550
  'post_type',
9551
+ 'media',
9552
+ ], true )
9553
+ ) {
9554
+ // Post type.
9555
  $info['table'] = $wpdb->posts;
9556
  $info['meta_table'] = $wpdb->postmeta;
9557
+ $info['storage'] = 'meta';
9558
 
9559
  $info['field_id'] = 'ID';
9560
  $info['field_index'] = 'post_title';
9561
  $info['field_slug'] = 'post_name';
9562
  $info['field_type'] = 'post_type';
9563
  $info['field_parent'] = 'post_parent';
9564
+ $info['field_parent_select'] = "`t`.`{$info['field_parent']}`";
9565
 
9566
  $info['meta_field_id'] = 'post_id';
9567
  $info['meta_field_index'] = 'meta_key';
9587
  $post_type = pods_sanitize( ( empty( $object ) ? $name : $object ) );
9588
 
9589
  if ( 'attachment' === $post_type || 'media' === $object_type ) {
9590
+ $info['pod_table'] = "{$wpdb->prefix}pods_media";
9591
  } else {
9592
+ $info['pod_table'] = "{$wpdb->prefix}pods_" . pods_clean_name( $post_type, true, false );
9593
  }
9594
 
9595
  $post_type_object = get_post_type_object( $post_type );
9602
  $post_status = array( 'publish' );
9603
 
9604
  // Pick field post_status option
9605
+ if ( ! empty( $field['pick_post_status'] ) ) {
 
 
9606
  $post_status = (array) $field['pick_post_status'];
9607
  }
9608
 
9623
  */
9624
  $post_status = apply_filters( 'pods_api_get_table_info_default_post_status', $post_status, $post_type, $info, $object_type, $object, $name, $pod, $field );
9625
 
9626
+ $info['where'] = [
9627
+ //'post_status' => "`t`.`post_status` IN ( 'inherit', 'publish' )", // @todo Figure out what statuses Attachments can be
9628
+ 'post_type' => "`t`.`{$info['field_type']}` = '" . pods_sanitize( $post_type ) . "'",
9629
+ ];
9630
 
9631
  if ( 'post_type' === $object_type ) {
9632
+ $info['where_default'] = "`t`.`post_status` IN ( '" . implode( "', '", pods_sanitize( $post_status ) ) . "' )";
9633
  }
9634
 
9635
+ $info['orderby'] = "`t`.`menu_order`, `t`.`{$info['field_index']}`, `t`.`post_date`";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9636
 
9637
  $info['object_fields'] = $this->get_wp_object_fields( $object_type, $info['pod'] );
9638
+ } elseif (
9639
+ 0 === strpos( $object_type, 'taxonomy' ) || in_array( $object_type, [
9640
  'nav_menu',
9641
+ 'post_format',
9642
+ ], true )
9643
+ || 'taxonomy' === pods_v( 'type', $info['pod'] )
9644
+ ) {
9645
+ // Taxonomy.
9646
  $info['table'] = $wpdb->terms;
9647
  $info['meta_table'] = $wpdb->terms;
9648
+ $info['storage'] = 'meta';
9649
 
9650
  $info['join']['tt'] = "LEFT JOIN `{$wpdb->term_taxonomy}` AS `tt` ON `tt`.`term_id` = `t`.`term_id`";
9651
  $info['join']['tr'] = "LEFT JOIN `{$wpdb->term_relationships}` AS `tr` ON `tr`.`term_taxonomy_id` = `tt`.`term_taxonomy_id`";
9657
  $info['field_slug'] = 'slug';
9658
  $info['field_type'] = 'taxonomy';
9659
  $info['field_parent'] = 'parent';
9660
+ $info['field_parent_select'] = "`tt`.`{$info['field_parent']}`";
9661
 
9662
  if ( ! empty( $wpdb->termmeta ) ) {
9663
  $info['meta_table'] = $wpdb->termmeta;
9682
  }
9683
  }
9684
 
9685
+ if ( ! in_array( $object_type, array( 'nav_menu', 'post_format' ), true ) ) {
9686
  $object_type = 'taxonomy';
9687
  }
9688
 
9689
  $taxonomy = pods_sanitize( ( empty( $object ) ? $name : $object ) );
9690
 
9691
+ $info['pod_table'] = "{$wpdb->prefix}pods_" . pods_clean_name( $taxonomy, true, false );
9692
 
9693
  $taxonomy_object = get_taxonomy( $taxonomy );
9694
 
9696
  $info['object_hierarchical'] = true;
9697
  }
9698
 
9699
+ $info['where'] = [
9700
+ 'tt.taxonomy' => "`tt`.`{$info['field_type']}` = '" . pods_sanitize( $taxonomy ) . "'",
9701
+ ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9702
 
9703
  $info['object_fields'] = $this->get_wp_object_fields( $object_type, $info['pod'] );
9704
+ } elseif ( 'user' === $object_type || 'user' === pods_v( 'type', $info['pod'] ) ) {
9705
+ // User.
9706
  $info['table'] = $wpdb->users;
9707
  $info['meta_table'] = $wpdb->usermeta;
9708
  $info['pod_table'] = $wpdb->prefix . 'pods_user';
9709
+ $info['storage'] = 'meta';
9710
 
9711
  $info['field_id'] = 'ID';
9712
  $info['field_index'] = 'display_name';
9716
  $info['meta_field_index'] = 'meta_key';
9717
  $info['meta_field_value'] = 'meta_value';
9718
 
9719
+ $info['where'] = [];
 
 
9720
 
9721
  $info['object_fields'] = $this->get_wp_object_fields( $object_type, $info['pod'] );
9722
+ } elseif ( 'comment' === $object_type || 'comment' === pods_v( 'type', $info['pod'] ) ) {
9723
+ // Comment type.
 
9724
  $info['table'] = $wpdb->comments;
9725
  $info['meta_table'] = $wpdb->commentmeta;
9726
  $info['pod_table'] = $wpdb->prefix . 'pods_comment';
9727
+ $info['storage'] = 'meta';
9728
 
9729
  $info['field_id'] = 'comment_ID';
9730
  $info['field_index'] = 'comment_date';
9738
 
9739
  $object = 'comment';
9740
 
9741
+ $comment_type = empty( $object ) ? $name : $object;
9742
 
9743
+ $comment_type_clause = "`t`.`{$info['field_type']}` = '" . pods_sanitize( $comment_type ) . "'";
9744
 
9745
  if ( 'comment' === $comment_type ) {
9746
+ $comment_type_clause = "( {$comment_type_clause} OR `t`.`{$info['field_type']}` = '' )";
9747
  }
9748
 
9749
+ $info['where'] = [
9750
  'comment_approved' => '`t`.`comment_approved` = 1',
9751
+ 'comment_type' => $comment_type_clause,
9752
+ ];
9753
 
9754
+ $info['orderby'] = "`t`.`{$info['field_index']}` DESC, `t`.`{$info['field_id']}`";
9755
+
9756
+ $info['object_fields'] = $this->get_wp_object_fields( $object_type, $info['pod'] );
9757
+ } elseif (
9758
+ in_array( $object_type, [
9759
  'option',
9760
+ 'settings',
9761
+ ], true )
9762
+ || 'settings' === pods_v( 'type', $info['pod'] )
9763
+ ) {
9764
+ // Setting.
9765
  $info['table'] = $wpdb->options;
9766
  $info['meta_table'] = $wpdb->options;
9767
+ $info['storage'] = 'option';
9768
 
9769
  $info['field_id'] = 'option_id';
9770
  $info['field_index'] = 'option_name';
9773
  $info['meta_field_index'] = 'option_name';
9774
  $info['meta_field_value'] = 'option_value';
9775
 
9776
+ $info['orderby'] = "`t`.`{$info['field_index']}` ASC";
9777
+ } elseif (
9778
+ is_multisite()
9779
+ && (
9780
+ in_array( $object_type, [
9781
  'site_option',
9782
+ 'site_settings',
9783
+ ], true )
9784
+ || 'site_settings' === pods_v( 'type', $info['pod'] )
9785
+ )
9786
+ ) {
9787
+ // Site meta.
9788
  $info['table'] = $wpdb->sitemeta;
9789
  $info['meta_table'] = $wpdb->sitemeta;
9790
+ $info['storage'] = 'meta';
9791
 
9792
  $info['field_id'] = 'site_id';
9793
  $info['field_index'] = 'meta_key';
9796
  $info['meta_field_index'] = 'meta_key';
9797
  $info['meta_field_value'] = 'meta_value';
9798
 
9799
+ $info['orderby'] = "`t`.`{$info['field_index']}` ASC";
9800
+ } elseif ( is_multisite() && 'network' === $object_type ) {
9801
+ // Network = Site.
9802
  $info['table'] = $wpdb->site;
9803
  $info['meta_table'] = $wpdb->sitemeta;
9804
+ $info['storage'] = 'meta';
9805
 
9806
  $info['field_id'] = 'id';
9807
  $info['field_index'] = 'domain';
9810
  $info['meta_field_index'] = 'meta_key';
9811
  $info['meta_field_value'] = 'meta_value';
9812
 
9813
+ $info['orderby'] = "`t`.`{$info['field_index']}` ASC, `t`.`path` ASC, `t`.`{$info['field_id']}`";
9814
+ } elseif ( is_multisite() && 'site' === $object_type ) {
9815
+ // Site = Blog.
9816
+ $info['table'] = $wpdb->blogs;
9817
+ $info['storage'] = 'none';
9818
 
9819
  $info['field_id'] = 'blog_id';
9820
  $info['field_index'] = 'domain';
9821
  $info['field_type'] = 'site_id';
9822
 
9823
+ $info['where'] = [
9824
  'archived' => '`t`.`archived` = 0',
9825
  'spam' => '`t`.`spam` = 0',
9826
  'deleted' => '`t`.`deleted` = 0',
9827
+ 'site_id' => "`t`.`{$info['field_type']}` = " . (int) get_current_site()->id,
9828
+ ];
9829
+
9830
+ $info['orderby'] = "`t`.`{$info['field_index']}` ASC, `t`.`path` ASC, `t`.`{$info['field_id']}`";
9831
+ } elseif ( 'table' === $object_type || 'table' === pods_v( 'type', $info['pod'] ) || ! empty( $info['pod']['table_custom'] ) ) {
9832
+ // Custom tables.
9833
+ $info['table'] = pods_v( 'table_custom', $info['pod'], ( empty( $object ) ? $name : $object ), true );
9834
+ $info['meta_table'] = pods_v( 'meta_table_custom', $info['pod'], $info['meta_table'], true );
9835
+ $info['pod_table'] = pods_v( 'pod_table_custom', $info['pod'], "{$wpdb->prefix}pods_" . $info['table'], true );
9836
+ $info['storage'] = 'table';
9837
+
9838
+ $info['field_id'] = pods_v( 'field_id_custom', $info['pod'], $info['field_id'], true );
9839
+ $info['field_index'] = pods_v( 'field_index_custom', $info['pod'], $info['field_index'], true );
9840
+ $info['field_slug'] = pods_v( 'field_slug_custom', $info['pod'], $info['field_slug'], true );
9841
+ $info['field_type'] = pods_v( 'field_type_custom', $info['pod'], $info['field_type'], true );
9842
+ $info['field_parent'] = pods_v( 'field_parent_custom', $info['pod'], $info['field_parent'], true );
9843
+ $info['field_parent_select'] = pods_v( 'field_parent_select_custom', $info['pod'], $info['field_parent_select'], true );
9844
 
9845
+ $info['meta_field_id'] = pods_v( 'meta_field_id_custom', $info['pod'], $info['meta_field_id'], true );
9846
+ $info['meta_field_index'] = pods_v( 'meta_field_index_custom', $info['pod'], $info['meta_field_index'], true );
9847
+ $info['meta_field_value'] = pods_v( 'meta_field_value_custom', $info['pod'], $info['meta_field_value'], true );
 
9848
 
9849
+ $info['join'] = (array) pods_v( 'join_custom', $info['pod'], $info['join'], true );
9850
+
9851
+ $info['orderby'] = pods_v( 'orderby_custom', $info['pod'], $info['orderby'], true );
9852
+
9853
+ $info['where'] = pods_v( 'where_custom', $info['pod'], $info['where'], true );
9854
+ $info['where_default'] = pods_v( 'where_default_custom', $info['pod'], $info['where_default'], true );
9855
 
9856
  if ( ! empty( $field ) ) {
9857
+ $is_field_object = $field instanceof Field;
9858
+
9859
+ if ( ! is_array( $field ) && ! $is_field_object ) {
9860
  if ( is_string( $pod ) ) {
9861
  $pod = pods( $pod );
9862
  }
9863
+
9864
+ if ( is_object( $pod ) && ! empty( $pod->fields[ $field ] ) ) {
9865
  $field = $pod->fields[ $field ];
9866
  }
9867
  }
9868
+
9869
+ $is_field_object = $field instanceof Field;
9870
+
9871
+ if ( is_array( $field ) || $is_field_object ) {
9872
+ $info['table'] = pods_v( 'pick_table', pods_v( 'options', $field, $field ) );
9873
+ $info['field_id'] = pods_v( 'pick_table_id', pods_v( 'options', $field, $field ) );
9874
+ $info['meta_field_value'] = pods_v( 'pick_table_index', pods_v( 'options', $field, $field ) );
9875
  $info['field_index'] = $info['meta_field_value'];
9876
  $info['meta_field_index'] = $info['meta_field_value'];
9877
  }
9891
  $info['meta_field_value'] = pods_clean_name( $info['meta_field_value'], false, false );
9892
 
9893
  if ( empty( $info['orderby'] ) ) {
9894
+ $info['orderby'] = "`t`.`{$info['field_index']}`, `t`.`{$info['field_id']}`";
9895
  }
9896
 
9897
+ if (
9898
+ 'table' === pods_v( 'storage', $info['pod'] )
9899
+ && ! in_array( $object_type, [
9900
  'pod',
9901
+ 'table',
9902
+ ], true )
9903
+ ) {
9904
+ $info['join']['d'] = "LEFT JOIN `{$info['pod_table']}` AS `d` ON `d`.`id` = `t`.`{$info['field_id']}`";
9905
  }
9906
 
9907
+ if ( ! empty( $info['pod'] ) && ( is_array( $info['pod'] ) || $info['pod'] instanceof Pods\Whatsit ) ) {
9908
  $info['recurse'] = true;
9909
+ $info['storage'] = $info['pod']['storage'];
9910
  }
9911
 
9912
  $info['type'] = $object_type;
9913
  $info['object_name'] = $object;
9914
 
9915
+ $static_cache->set( $cache_key, $info, __CLASS__ . '/table_info_cache' );
 
 
 
9916
 
9917
+ if ( pods_api_cache() ) {
9918
+ if ( ! did_action( 'init' ) || doing_action( 'init' ) ) {
9919
+ pods_transient_set( $cache_key . '_pre_init', $info, WEEK_IN_SECONDS );
9920
+ } else {
9921
+ pods_transient_set( $cache_key, $info, WEEK_IN_SECONDS );
9922
  }
9923
  }
9924
 
9925
+ /**
9926
+ * Allow filtering the table information for an object.
9927
+ *
9928
+ * @param array $info The table information.
9929
+ * @param string $object_type The object type.
9930
+ * @param string $object The object name.
9931
+ * @param string $name The pod name.
9932
+ * @param array|Pod $pod The pod config (if found).
9933
+ * @param array|Field $field The field config (if found).
9934
+ * @param self $obj The PodsAPI object.
9935
+ */
9936
+ return apply_filters( 'pods_api_get_table_info', $info, $object_type, $object, $name, $pod, $field, $this );
9937
  }
9938
 
9939
  /**
10051
  $import_data = array( $import_data );
10052
  }
10053
 
10054
+ $pod = $this->load_pod( array( 'name' => $this->pod ), false );
10055
 
10056
  if ( false === $pod ) {
10057
  return pods_error( __( 'Pod not found', 'pods' ), $this );
10087
  $pick_values = array();
10088
 
10089
  foreach ( $field_values as $pick_value ) {
10090
+ if ( in_array( $type, PodsForm::file_field_types(), true ) || in_array( $pick_object, [ 'media', 'attachment' ], true ) ) {
10091
  $where = "`guid` = '" . pods_sanitize( $pick_value ) . "'";
10092
 
10093
  if ( 0 < pods_absint( $pick_value ) && false !== $numeric_mode ) {
10105
 
10106
  if ( 'pod' === $pick_object ) {
10107
  $related_pod = $this->load_pod( array(
10108
+ 'name' => $pick_val,
 
10109
  ), false );
10110
  }
10111
 
10112
  if ( empty( $related_pod ) ) {
10113
  $related_pod = array(
10114
  'id' => 0,
10115
+ 'type' => $pick_object,
10116
  );
10117
  }
10118
 
10130
  }
10131
  } elseif ( in_array( 'post_type', array(
10132
  $pick_object,
10133
+ $related_pod['type'],
10134
  ) ) || in_array( 'media', array( $pick_object, $related_pod['type'] ) ) ) {
10135
  $where = "`post_title` = '" . pods_sanitize( $pick_value ) . "'";
10136
 
10163
  if ( ! empty( $result ) ) {
10164
  $pick_values[] = $result[0]->id;
10165
  }
10166
+ } elseif ( in_array( $pick_object, $simple_tableless_objects, true ) ) {
10167
  $pick_values[] = $pick_value;
10168
  } elseif ( ! empty( $related_pod['id'] ) ) {
10169
  $where = "`" . $related_pod['field_index'] . "` = '" . pods_sanitize( $pick_value ) . "'";
10280
 
10281
  pods_transient_clear( 'pods' );
10282
  pods_transient_clear( 'pods_components' );
10283
+ pods_transient_clear( 'pods_core_loader_objects' );
10284
 
10285
+ if ( is_array( $pod ) || $pod instanceof Pod ) {
10286
  pods_transient_clear( 'pods_pod_' . $pod['name'] );
10287
  pods_cache_clear( $pod['name'], 'pods-class' );
10288
 
 
 
 
 
10289
  if ( in_array( $pod['type'], array( 'post_type', 'taxonomy' ) ) ) {
10290
  pods_transient_clear( 'pods_wp_cpt_ct' );
10291
  }
10293
  pods_transient_clear( 'pods_wp_cpt_ct' );
10294
  }
10295
 
10296
+ $static_cache = tribe( Static_Cache::class );
10297
+
10298
+ $static_cache->flush( __CLASS__ . '/table_info_cache' );
10299
+ $static_cache->flush( __CLASS__ . '/related_item_cache' );
10300
+
10301
  // Delete transients in the database
10302
  $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_pods%'" );
10303
  $wpdb->query( "DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE '_transient_timeout_pods%'" );
10307
 
10308
  pods_cache_clear( true );
10309
 
10310
+ pods_transient_set( 'pods_flush_rewrites', 1, WEEK_IN_SECONDS );
10311
 
10312
  do_action( 'pods_cache_flushed' );
10313
  }
10330
 
10331
  $form = null;
10332
 
10333
+ $nonce = pods_v_sanitized( '_pods_nonce', $params );
10334
+ $pod = pods_v_sanitized( '_pods_pod', $params );
10335
+ $id = pods_v_sanitized( '_pods_id', $params );
10336
+ $uri = pods_v_sanitized( '_pods_uri', $params );
10337
+ $form = pods_v_sanitized( '_pods_form', $params );
10338
+ $location = pods_v_sanitized( '_pods_location', $params );
10339
 
10340
  if ( is_object( $obj ) ) {
10341
  $pod = $obj->pod;
10374
  $data = array();
10375
 
10376
  foreach ( $fields as $field ) {
10377
+ $data[ $field ] = pods_v( 'pods_field_' . $field, $params, '' );
10378
  }
10379
 
10380
  $params = array(
10425
  }
10426
 
10427
  /**
10428
+ * Handle variables that have been deprecated and PodsData vars
10429
+ *
10430
+ * @param string $name Property name.
10431
+ *
10432
+ * @return mixed
10433
  *
10434
  * @since 2.0.0
10435
  */
10437
 
10438
  $name = (string) $name;
10439
 
10440
+ // Handle alias Pods\Whatsit\Pod properties.
10441
+ $supported_pods_object = array(
10442
+ 'pod' => 'name',
10443
+ 'pod_id' => 'id',
10444
+ 'fields' => 'fields',
10445
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10446
 
10447
+ if ( isset( $supported_pods_object[ $name ] ) ) {
10448
+ if ( ! is_object( $this->pod_data ) ) {
10449
+ return null;
10450
+ }
10451
 
10452
+ return $this->pod_data->get_arg( $supported_pods_object[ $name ] );
 
 
10453
  }
10454
 
10455
+ return null;
 
 
 
 
10456
  }
10457
 
10458
  /**
10489
 
10490
  }
10491
 
10492
+ /**
10493
+ * Get default object storage type to use in Pods Object requests.
10494
+ *
10495
+ * @return string
10496
+ */
10497
+ public function get_default_object_storage_type() {
10498
+ /**
10499
+ * Filter the storage type to use for Pods Object requests.
10500
+ *
10501
+ * @param string $storage_type Storage type.
10502
+ *
10503
+ * @since 2.8.0
10504
+ */
10505
+ return apply_filters( 'pods_api_object_storage_type', 'post_type' );
10506
+ }
10507
+
10508
+ /**
10509
+ * Get Pods Object from WP_Post.
10510
+ *
10511
+ * @param WP_Post|array|int $post Post object, array, or ID.
10512
+ *
10513
+ * @return false|Pods\Whatsit Object or false if the post does not exist.
10514
+ *
10515
+ * @since 2.8.0
10516
+ */
10517
+ public function get_pods_object_from_wp_post( $post ) {
10518
+ if ( ! $post instanceof WP_Post ) {
10519
+ $post = get_post( $post );
10520
+ }
10521
+
10522
+ if ( ! $post || is_wp_error( $post ) ) {
10523
+ return false;
10524
+ }
10525
+
10526
+ $object_collection = Pods\Whatsit\Store::get_instance();
10527
+
10528
+ /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */
10529
+ $post_type_storage = $object_collection->get_storage_object( $this->get_default_object_storage_type() );
10530
+
10531
+ return $post_type_storage->to_object( $post );
10532
+ }
10533
+
10534
+ /**
10535
+ * Load an object.
10536
+ *
10537
+ * @param array $params {
10538
+ * An associative array of parameters.
10539
+ *
10540
+ * @type string $object_type The object type.
10541
+ * @type string $id The ID.
10542
+ * @type string $name The name.
10543
+ * @type boolean $bypass_cache Bypass the cache when getting data.
10544
+ * }
10545
+ *
10546
+ * @param boolean $strict Whether to require a field exist or not when loading the info.
10547
+ *
10548
+ * @return Pods\Whatsit|false Object or false if not found.
10549
+ *
10550
+ * @throws Exception
10551
+ *
10552
+ * @since 2.8.0
10553
+ */
10554
+ public function _load_object( array $params, $strict = false ) {
10555
+ if ( empty( $params['object_type'] ) ) {
10556
+ return false;
10557
+ }
10558
+
10559
+ if ( is_array( $params['object_type'] ) ) {
10560
+ $params['object_type'] = reset( $params['object_type'] );
10561
+ }
10562
+
10563
+ $object = false;
10564
+
10565
+ if ( isset( $params['title'] ) ) {
10566
+ $object = pods_by_title( $params['title'], ARRAY_A, '_pods_' . $params['object_type'], 'publish', 'id' );
10567
+
10568
+ // Normalize the response as Whatsit.
10569
+ if ( 0 < $object ) {
10570
+ $params['id'] = $object;
10571
+
10572
+ unset( $params['title'] );
10573
+
10574
+ $object = $this->_load_object( $params, $strict );
10575
+ }
10576
+ } else {
10577
+ $params['limit'] = 1;
10578
+
10579
+ $loaded = $this->_load_objects( $params );
10580
+
10581
+ if ( $loaded ) {
10582
+ $object = reset( $loaded );
10583
+ }
10584
+ }
10585
+
10586
+ if ( $object ) {
10587
+ return $object;
10588
+ }
10589
+
10590
+ if ( $strict ) {
10591
+ return pods_error( __( 'Object not found', 'pods' ), $this );
10592
+ }
10593
+
10594
+ return false;
10595
+ }
10596
+
10597
+ /**
10598
+ * Load objects.
10599
+ *
10600
+ * @param array $params {
10601
+ * An associative array of parameters.
10602
+ *
10603
+ * @type string|array $object_type The object type(s).
10604
+ * @type string|array $id The ID(s).
10605
+ * @type string|array $name The name(s).
10606
+ * @type string|array $type The type(s).
10607
+ * @type array $args Arg(s) key=>value to filter by.
10608
+ * @type boolean $count Return only a count of fields.
10609
+ * @type boolean $names Return only an array of name => label.
10610
+ * @type boolean $ids Return only an array of ID => label.
10611
+ * @type boolean $bypass_cache Bypass the cache when getting data.
10612
+ * }
10613
+ *
10614
+ * @return Pods\Whatsit[]|int List of objects or count.
10615
+ *
10616
+ * @since 2.8.0
10617
+ */
10618
+ public function _load_objects( array $params ) {
10619
+ if ( empty( $params['object_type'] ) ) {
10620
+ return array();
10621
+ }
10622
+
10623
+ // Check if we need to bypass cache automatically.
10624
+ if ( ! isset( $params['bypass_cache'] ) ) {
10625
+ $api_cache = pods_api_cache();
10626
+
10627
+ if ( ! $api_cache ) {
10628
+ $params['bypass_cache'] = true;
10629
+ }
10630
+ }
10631
+
10632
+ if ( isset( $params['options'] ) ) {
10633
+ $params['args'] = $params['options'];
10634
+
10635
+ unset( $params['options'] );
10636
+ }
10637
+
10638
+ if ( isset( $params['where'] ) ) {
10639
+ $where = $params['where'];
10640
+
10641
+ unset( $params['where'] );
10642
+
10643
+ if ( ! isset( $params['args'] ) ) {
10644
+ $params['args'] = array();
10645
+ }
10646
+
10647
+ foreach ( $where as $arg ) {
10648
+ if ( ! isset( $arg['key'], $arg['value'] ) ) {
10649
+ continue;
10650
+ }
10651
+
10652
+ $params['args'][ $arg['key'] ] = $arg['value'];
10653
+ }
10654
+ }
10655
+
10656
+ if ( ! empty( $params['return_type'] ) ) {
10657
+ $return_type = $params['return_type'];
10658
+
10659
+ if ( 'names' === $return_type ) {
10660
+ $params['names'] = true;
10661
+ } elseif ( 'names_ids' === $return_type ) {
10662
+ $params['names_ids'] = true;
10663
+ } elseif ( 'ids' === $return_type ) {
10664
+ $params['ids'] = true;
10665
+ } elseif ( 'count' === $return_type ) {
10666
+ $params['count'] = true;
10667
+ }
10668
+ }
10669
+
10670
+ $storage_type = ! empty( $params['storage_type'] ) ? $params['storage_type'] : $this->get_default_object_storage_type();
10671
+
10672
+ $object_collection = Pods\Whatsit\Store::get_instance();
10673
+
10674
+ /** @var Pods\Whatsit\Storage\Post_Type $post_type_storage */
10675
+ $post_type_storage = $object_collection->get_storage_object( $storage_type );
10676
+
10677
+ $objects = $post_type_storage->find( $params );
10678
+
10679
+ if ( ! empty( $params['auto_setup'] ) && ! $objects ) {
10680
+ $type = pods_v( 'type', $params, null );
10681
+
10682
+ $whatsit_args = null;
10683
+
10684
+ if ( 'user' === $params['name'] ) {
10685
+ // Detect user.
10686
+ $type = 'user';
10687
+
10688
+ // Setup the pod and return the request again.
10689
+ $whatsit_args = [
10690
+ 'object_type' => 'pod',
10691
+ 'type' => $type,
10692
+ 'name' => $type,
10693
+ 'label' => __( 'User', 'pods' ),
10694
+ 'storage' => 'meta',
10695
+ ];
10696
+ } elseif ( 'comment' === $params['name'] ) {
10697
+ // Detect comment.
10698
+ $type = 'comment';
10699
+
10700
+ $whatsit_args = [
10701
+ 'object_type' => 'pod',
10702
+ 'type' => $type,
10703
+ 'name' => $type,
10704
+ 'label' => __( 'Comment', 'pods' ),
10705
+ 'storage' => 'meta',
10706
+ ];
10707
+ } elseif ( 'media' === $params['name'] || 'attachment' === $params['name'] ) {
10708
+ // Detect media.
10709
+ $type = 'media';
10710
+
10711
+ $whatsit_args = [
10712
+ 'object_type' => 'pod',
10713
+ 'type' => $type,
10714
+ 'name' => $type,
10715
+ 'label' => __( 'Media', 'pods' ),
10716
+ 'storage' => 'meta',
10717
+ ];
10718
+ }
10719
+
10720
+ // Detect a post type.
10721
+ if ( 'post_type' === $type || null === $type ) {
10722
+ $post_type = get_post_type_object( $params['name'] );
10723
+
10724
+ if ( $post_type ) {
10725
+ $type = 'post_type';
10726
+
10727
+ $whatsit_args = [
10728
+ 'object_type' => 'pod',
10729
+ 'type' => $type,
10730
+ 'name' => $post_type->name,
10731
+ 'label' => $post_type->label,
10732
+ 'description' => $post_type->description,
10733
+ 'storage' => 'meta',
10734
+ ];
10735
+ }
10736
+ }
10737
+
10738
+ // Detect a taxonomy.
10739
+ if ( 'taxonomy' === $type || null === $type ) {
10740
+ $taxonomy = get_taxonomy( $params['name'] );
10741
+
10742
+ if ( $taxonomy ) {
10743
+ $type = 'taxonomy';
10744
+
10745
+ $whatsit_args = [
10746
+ 'object_type' => 'pod',
10747
+ 'type' => $type,
10748
+ 'name' => $taxonomy->name,
10749
+ 'label' => $taxonomy->label,
10750
+ 'description' => $taxonomy->description,
10751
+ 'storage' => 'meta',
10752
+ ];
10753
+ }
10754
+ }
10755
+
10756
+ // Setup the pod and return the request again.
10757
+ if ( null !== $whatsit_args ) {
10758
+ // Set up the params for the next call.
10759
+ $params['auto_setup'] = false;
10760
+ $params['storage_type'] = 'collection';
10761
+
10762
+ $pod = new Pod( $whatsit_args );
10763
+
10764
+ $object_collection->register_object( $pod );
10765
+
10766
+ return $this->_load_objects( $params );
10767
+ }
10768
+ }
10769
+
10770
+ if ( ! empty( $params['count'] ) ) {
10771
+ return count( $objects );
10772
+ }
10773
+
10774
+ if ( ! empty( $params['names'] ) ) {
10775
+ return wp_list_pluck( $objects, 'name' );
10776
+ }
10777
+
10778
+ if ( ! empty( $params['names_ids'] ) ) {
10779
+ return wp_list_pluck( $objects, 'name', 'id' );
10780
+ }
10781
+
10782
+ if ( ! empty( $params['ids'] ) ) {
10783
+ return wp_list_pluck( $objects, 'id' );
10784
+ }
10785
+
10786
+ return $objects;
10787
+ }
10788
+
10789
+ /**
10790
+ * Get the list of Pod types.
10791
+ *
10792
+ * @since 2.8.0
10793
+ *
10794
+ * @return string[] The list of pod types and their labels.
10795
+ */
10796
+ public function get_pod_types() {
10797
+ $pod_types = [
10798
+ 'post_type' => _x( 'Post Type (extended)', 'pod type label', 'pods' ),
10799
+ 'taxonomy' => _x( 'Taxonomy (extended)', 'pod type label', 'pods' ),
10800
+ 'cpt' => _x( 'Custom Post Type', 'pod type label', 'pods' ),
10801
+ 'ct' => _x( 'Custom Taxonomy', 'pod type label', 'pods' ),
10802
+ 'user' => _x( 'User (extended)', 'pod type label', 'pods' ),
10803
+ 'media' => _x( 'Media (extended)', 'pod type label', 'pods' ),
10804
+ 'comment' => _x( 'Comments (extended)', 'pod type label', 'pods' ),
10805
+ 'pod' => _x( 'Advanced Content Type', 'pod type label', 'pods' ),
10806
+ 'settings' => _x( 'Custom Settings Page', 'pod type label', 'pods' ),
10807
+ 'internal' => _x( 'Pods Internal', 'pod type label', 'pods' ),
10808
+ ];
10809
+
10810
+ /**
10811
+ * Allow filtering the list of pod types and their labels.
10812
+ *
10813
+ * @since 2.8.0
10814
+ *
10815
+ * @param string[] $pod_types The list of pod types and their labels.
10816
+ */
10817
+ return apply_filters( 'pods_api_pod_types', $pod_types );
10818
+ }
10819
+
10820
+ /**
10821
+ * Get the list of Pod types.
10822
+ *
10823
+ * @since 2.8.0
10824
+ *
10825
+ * @return string[] The list of storage types and their labels.
10826
+ */
10827
+ public function get_storage_types() {
10828
+ $storage_types = [
10829
+ 'none' => _x( 'None (No Fields)', 'storage type label', 'pods' ),
10830
+ 'options' => _x( 'Options', 'storage type label', 'pods' ),
10831
+ 'meta' => _x( 'Meta', 'storage type label', 'pods' ),
10832
+ 'table' => _x( 'Table', 'storage type label', 'pods' ),
10833
+ ];
10834
+
10835
+ /**
10836
+ * Allow filtering the list of pod types and their labels.
10837
+ *
10838
+ * @since 2.8.0
10839
+ *
10840
+ * @param string[] $storage_types The list of storage types and their labels.
10841
+ */
10842
+ return apply_filters( 'pods_api_storage_types', $storage_types );
10843
+ }
10844
+
10845
  }
classes/PodsAdmin.php CHANGED
@@ -1,5 +1,8 @@
1
  <?php
2
 
 
 
 
3
  /**
4
  * @package Pods
5
  */
@@ -60,6 +63,9 @@ class PodsAdmin {
60
  // Add our debug to Site Info.
61
  add_filter( 'debug_information', array( $this, 'add_debug_information' ) );
62
 
 
 
 
63
  $this->rest_admin();
64
 
65
  }
@@ -122,16 +128,23 @@ class PodsAdmin {
122
 
123
  wp_register_script( 'pods-migrate', PODS_URL . 'ui/js/jquery.pods.migrate.js', array(), PODS_VERSION );
124
 
 
 
125
  // @codingStandardsIgnoreLine
126
  if ( isset( $_GET['page'] ) ) {
127
  // @codingStandardsIgnoreLine
128
  $page = $_GET['page'];
129
  if ( 'pods' === $page || ( false !== strpos( $page, 'pods-' ) && 0 === strpos( $page, 'pods-' ) ) ) {
 
 
130
  ?>
131
- <script type="text/javascript">
132
- var PODS_URL = "<?php echo esc_js( PODS_URL ); ?>";
 
 
133
  </script>
134
  <?php
 
135
  wp_enqueue_script( 'jquery' );
136
  wp_enqueue_script( 'jquery-ui-core' );
137
  wp_enqueue_script( 'jquery-ui-sortable' );
@@ -177,22 +190,25 @@ class PodsAdmin {
177
  }//end if
178
  }//end if
179
 
180
- /**
181
- * Filter to disable default loading of the DFV script. By default, Pods
182
- * will always enqueue the DFV script if is_admin()
183
- *
184
- * Example: add_filter( 'pods_default_enqueue_dfv', '__return_false');
185
- *
186
- * @param bool Whether or not to enqueue by default
187
- *
188
- * @since 2.7.10
189
- */
190
- if ( apply_filters( 'pods_default_enqueue_dfv', true ) ) {
191
- wp_enqueue_script( 'pods-dfv' );
192
- }
 
 
193
 
194
- // New Styles Enqueue
195
- wp_enqueue_style( 'pods-styles' );
 
196
  }
197
 
198
  /**
@@ -206,8 +222,6 @@ class PodsAdmin {
206
  $taxonomies = PodsMeta::$taxonomies;
207
  $settings = PodsMeta::$settings;
208
 
209
- $all_pods = pods_api()->load_pods( array( 'count' => true ) );
210
-
211
  if ( ! PodsInit::$upgrade_needed || ( pods_is_admin() && 1 === (int) pods_v( 'pods_upgrade_bypass' ) ) ) {
212
  $submenu_items = array();
213
 
@@ -217,7 +231,7 @@ class PodsAdmin {
217
  $pods_pages = 0;
218
 
219
  foreach ( (array) $advanced_content_types as $pod ) {
220
- if ( ! isset( $pod['name'] ) || ! isset( $pod['options'] ) || empty( $pod['fields'] ) ) {
221
  continue;
222
  } elseif ( ! pods_is_admin(
223
  array(
@@ -574,19 +588,6 @@ class PodsAdmin {
574
  ),
575
  );
576
 
577
- if ( empty( $all_pods ) ) {
578
- unset( $admin_menus['pods'] );
579
-
580
- if ( 'pods' === pods_v( 'page', 'get' ) ) {
581
- // Replace `pods` page param with first existing pod page and redirect.
582
- $url = add_query_arg( 'page', key( $admin_menus ) );
583
- $url = get_site_url( null, $url );
584
-
585
- wp_safe_redirect( $url );
586
- die();
587
- }
588
- }
589
-
590
  add_filter( 'parent_file', array( $this, 'parent_file' ) );
591
  } else {
592
  $admin_menus = array(
@@ -742,6 +743,11 @@ class PodsAdmin {
742
 
743
  $pod = pods( $pod_name, pods_v( 'id', 'get', null, true ) );
744
 
 
 
 
 
 
745
  // @codingStandardsIgnoreLine
746
  if ( false !== strpos( $_GET['page'], 'pods-add-new-' ) ) {
747
  // @codingStandardsIgnoreLine
@@ -876,8 +882,9 @@ class PodsAdmin {
876
  * Handle main Pods Setup area for managing Pods and Fields
877
  */
878
  public function admin_setup() {
 
879
 
880
- $pods = pods_api()->load_pods( array( 'fields' => false ) );
881
 
882
  $view = pods_v( 'view', 'get', 'all', true );
883
 
@@ -887,16 +894,20 @@ class PodsAdmin {
887
  $_GET['action'] = 'add';
888
  }
889
 
 
 
 
 
890
  // @codingStandardsIgnoreLine
891
- if ( 'pods-add-new' === $_GET['page'] ) {
892
  // @codingStandardsIgnoreLine
893
  if ( isset( $_GET['action'] ) && 'add' !== $_GET['action'] ) {
894
  pods_redirect(
895
  pods_query_arg(
896
  array(
897
- 'page' => 'pods',
898
  // @codingStandardsIgnoreLine
899
- 'action' => $_GET['action'],
900
  )
901
  )
902
  );
@@ -909,84 +920,120 @@ class PodsAdmin {
909
  pods_redirect(
910
  pods_query_arg(
911
  array(
912
- 'page' => 'pods-add-new',
913
- 'action' => '',
 
 
 
914
  )
915
  )
916
  );
917
  }//end if
918
 
919
- $types = array(
920
- 'post_type' => __( 'Post Type (extended)', 'pods' ),
921
- 'taxonomy' => __( 'Taxonomy (extended)', 'pods' ),
922
- 'cpt' => __( 'Custom Post Type', 'pods' ),
923
- 'ct' => __( 'Custom Taxonomy', 'pods' ),
924
- 'user' => __( 'User (extended)', 'pods' ),
925
- 'media' => __( 'Media (extended)', 'pods' ),
926
- 'comment' => __( 'Comments (extended)', 'pods' ),
927
- 'pod' => __( 'Advanced Content Type', 'pods' ),
928
- 'settings' => __( 'Custom Settings Page', 'pods' ),
929
- );
930
 
931
  $row = false;
932
 
933
  $pod_types_found = array();
934
 
935
- $fields = array(
936
- 'label' => array( 'label' => __( 'Label', 'pods' ) ),
937
- 'name' => array( 'label' => __( 'Name', 'pods' ) ),
938
- 'type' => array( 'label' => __( 'Type', 'pods' ) ),
939
- 'storage' => array(
940
  'label' => __( 'Storage Type', 'pods' ),
941
  'width' => '10%',
942
- ),
943
- 'field_count' => array(
944
- 'label' => __( 'Number of Fields', 'pods' ),
945
  'width' => '8%',
946
- ),
947
- );
 
 
 
 
948
 
 
949
  $total_fields = 0;
950
 
 
 
 
 
 
 
 
 
 
 
 
951
  foreach ( $pods as $k => $pod ) {
952
- if ( isset( $types[ $pod['type'] ] ) ) {
953
- if ( in_array(
954
- $pod['type'], array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
955
  'post_type',
956
  'taxonomy',
957
- ), true
958
- ) ) {
959
- if ( empty( $pod['object'] ) ) {
960
- if ( 'post_type' === $pod['type'] ) {
961
- $pod['type'] = 'cpt';
962
- } else {
963
- $pod['type'] = 'ct';
964
- }
 
965
  }
966
  }
967
 
968
- if ( ! isset( $pod_types_found[ $pod['type'] ] ) ) {
969
- $pod_types_found[ $pod['type'] ] = 1;
970
  } else {
971
- $pod_types_found[ $pod['type'] ] ++;
972
  }
973
 
974
- if ( 'all' !== $view && $view !== $pod['type'] ) {
975
- unset( $pods[ $k ] );
976
-
977
  continue;
978
  }
979
 
980
- $pod['real_type'] = $pod['type'];
981
- $pod['type'] = $types[ $pod['type'] ];
982
  } elseif ( 'all' !== $view ) {
983
  continue;
984
  }//end if
985
 
986
- $pod['storage'] = ucwords( $pod['storage'] );
987
-
988
  // @codingStandardsIgnoreLine
989
- if ( $pod['id'] == pods_v( 'id' ) && 'delete' !== pods_v( 'action' ) ) {
990
  $row = $pod;
991
  }
992
 
@@ -994,16 +1041,18 @@ class PodsAdmin {
994
  'id' => $pod['id'],
995
  'label' => pods_v( 'label', $pod ),
996
  'name' => pods_v( 'name', $pod ),
997
- 'object' => pods_v( 'object', $pod ),
998
- 'type' => pods_v( 'type', $pod ),
999
- 'real_type' => pods_v( 'real_type', $pod ),
1000
- 'storage' => pods_v( 'storage', $pod ),
1001
- 'field_count' => count( $pod['fields'] ),
 
1002
  );
1003
 
 
1004
  $total_fields += $pod['field_count'];
1005
 
1006
- $pods[ $k ] = $pod;
1007
  }//end foreach
1008
 
1009
  if ( false === $row && 0 < pods_v( 'id' ) && 'delete' !== pods_v( 'action' ) ) {
@@ -1013,60 +1062,74 @@ class PodsAdmin {
1013
  unset( $_GET['id'], $_GET['action'] );
1014
  }
1015
 
1016
- $ui = array(
1017
- 'data' => $pods,
 
 
1018
  'row' => $row,
1019
- 'total' => count( $pods ),
1020
- 'total_found' => count( $pods ),
1021
  'items' => 'Pods',
1022
  'item' => 'Pod',
1023
- 'fields' => array(
1024
  'manage' => $fields,
1025
- ),
1026
- 'actions_disabled' => array( 'view', 'export' ),
1027
- 'actions_custom' => array(
1028
- 'add' => array( $this, 'admin_setup_add' ),
1029
- 'edit' => array( $this, 'admin_setup_edit' ),
1030
- 'duplicate' => array(
1031
- 'callback' => array( $this, 'admin_setup_duplicate' ),
1032
- 'restrict_callback' => array( $this, 'admin_setup_duplicate_restrict' ),
1033
- ),
1034
- 'reset' => array(
 
 
 
 
1035
  'label' => __( 'Delete All Items', 'pods' ),
1036
  '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' ),
1037
- 'callback' => array( $this, 'admin_setup_reset' ),
1038
- 'restrict_callback' => array( $this, 'admin_setup_reset_restrict' ),
1039
  'nonce' => true,
1040
- ),
1041
- 'delete' => array( $this, 'admin_setup_delete' ),
1042
- ),
1043
- 'action_links' => array(
1044
- 'add' => pods_query_arg(
1045
- array(
1046
- 'page' => 'pods-add-new',
1047
- 'action' => '',
1048
- 'id' => '',
1049
- 'do' => '',
1050
- )
1051
- ),
1052
- ),
 
 
 
 
 
 
1053
  'search' => false,
1054
  'searchable' => false,
1055
  'sortable' => true,
1056
  'pagination' => false,
1057
- 'extra' => array(
1058
- 'total' => ', ' . number_format_i18n( $total_fields ) . ' ' . _n( 'field', 'fields', $total_fields, 'pods' ),
1059
- ),
1060
- );
 
 
1061
 
1062
  if ( 1 < count( $pod_types_found ) ) {
1063
- $ui['views'] = array( 'all' => __( 'All', 'pods' ) );
1064
  $ui['view'] = $view;
1065
- $ui['heading'] = array( 'views' => __( 'Type', 'pods' ) );
1066
  $ui['filters_enhanced'] = true;
1067
 
1068
  foreach ( $pod_types_found as $pod_type => $number_found ) {
1069
- $ui['views'][ $pod_type ] = $types[ $pod_type ];
1070
  }
1071
  }
1072
 
@@ -1099,12 +1162,12 @@ class PodsAdmin {
1099
 
1100
  if ( ! $callouts ) {
1101
  $callouts = array(
1102
- 'friends_2021' => 1,
1103
  );
1104
  }
1105
 
1106
  // Handle Friends of Pods 2021 callout logic.
1107
- $callouts['friends_2021'] = ! isset( $callouts['friends_2021'] ) || $callouts['friends_2021'] || $force_callouts ? 1 : 0;
1108
 
1109
  /**
1110
  * Allow hooking into whether or not the specific callouts should show.
@@ -1132,7 +1195,7 @@ class PodsAdmin {
1132
 
1133
  $disable_pods = pods_v( 'pods_callout_dismiss' );
1134
 
1135
- // Disable Friends of Pods 2020 callout.
1136
  if ( 'friends_2021' === $disable_pods ) {
1137
  $callouts['friends_2021'] = 0;
1138
 
@@ -1182,68 +1245,8 @@ class PodsAdmin {
1182
 
1183
  $callouts = $this->get_callouts();
1184
 
1185
- if ( ! empty( $callouts['friends_2021'] ) ) {
1186
- $donor_count = 140;
1187
- $donor_goal = 200;
1188
- $progress_width = ( $donor_count / $donor_goal ) * 100;
1189
- ?>
1190
- <div class="pods-admin_friends-callout_container">
1191
- <?php if ( ! $force_callouts ) : ?>
1192
- <a href="<?php echo esc_url( add_query_arg( 'pods_callout_dismiss', 'friends_2021' ) ); ?>" class="pods-admin_friends-callout_close">
1193
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 125" enable-background="new 0 0 100 100" xml:space="preserve"><polygon points="95,17 83,5 50,38 17,5 5,17 38,50 5,83 17,95 50,62 83,95 95,83 62,50 "/></svg>
1194
- </a>
1195
- <?php endif; ?>
1196
- <div class="pods-admin_friends-callout_logo-container">
1197
- <svg version="1.1" viewBox="0 0 305 111" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>Friends of Pods Logo</title> <defs> <path id="a" d="m0.14762 49.116c0 27.103 21.919 49.075 48.956 49.075 19.888 0 37.007-11.888 44.669-28.962-2.1342-6.538-3.9812-18.041 3.3854-29.538-0.3152-1.624-0.71019-3.219-1.1807-4.781-22.589 22.49-40.827 24.596-54.558 24.229-0.12701-4e-3 -0.58883-0.079-0.71152-0.35667 0 0-0.20016-0.89933 0.38502-0.89933 26.307 0 41.29-15.518 53.531-26.865-0.66763-1.687-1.4264-3.3273-2.2695-4.9167-13.196-3.6393-18.267-14.475-20.067-20.221-6.9007-3.7267-14.796-5.8413-23.184-5.8413-27.037 0-48.956 21.972-48.956 49.076zm62.283-34.287s18.69-2.039 24.194 21.114c-20.424-1.412-24.194-21.114-24.194-21.114zm-7.4779 9.7423s16.57-0.55467 20.342 20.219c-17.938-2.602-20.342-20.219-20.342-20.219zm-9.1018 8.256s14.912-0.97567 18.728 17.626c-16.209-1.8273-18.728-17.626-18.728-17.626zm40.774 3.116c0.021279 0.0013333 0.040563 0.0026667 0.061842 0.0043333l-0.044886 0.067667c-0.0056523-0.024-0.011304-0.048-0.016957-0.072zm-48.709 3.445s13.103-0.859 16.456 15.486c-14.243-1.6047-16.456-15.486-16.456-15.486zm-10.498 1.6027s12.587-0.82333 15.808 14.877c-13.68-1.5417-15.808-14.877-15.808-14.877zm-10.391 0.72233s11.423-0.74667 14.347 13.502c-12.417-1.3997-14.347-13.502-14.347-13.502zm-11.298 2.0857s9.5832-2.526 13.712 9.0523c-0.44919 0.036667-0.88474 0.054333-1.3073 0.054333-9.6148-3.333e-4 -12.405-9.1067-12.405-9.1067zm81.565 0.964c-0.0073147-0.021333-0.014962-0.043667-0.021612-0.064667l0.066497 0.018333c-0.014962 0.015333-0.029924 0.030667-0.044886 0.046333 7.1338 21.557-5.5721 33.29-5.5721 33.29s-8.9279-18.395 5.5721-33.29zm-11.999 0.027333c0.017622 0.0023333 0.035576 5e-3 0.053198 0.0076667l-0.041561 0.056c-0.0036573-0.021667-0.0073147-0.042-0.011637-0.063667zm-10.716 5.6627c0.015959 2e-3 0.032916 0.0036666 0.048543 0.0056666l-0.036573 0.051c-0.0039899-0.019667-0.0076472-0.037333-0.01197-0.056667zm12.212 1.8693c-0.0023274-0.021-0.0046548-0.043333-0.0066497-0.064667l0.056523 0.035667c-0.016624 0.01-0.032916 0.019333-0.049873 0.029 2.2323 21.678-11.682 28.793-11.682 28.793s-4.4962-19.303 11.682-28.793zm-57.318 0.52633-0.018619 0.037333c-0.0039899-0.011667-0.0086447-0.023667-0.012302-0.034667 0.010307-1e-3 0.020614-0.0016667 0.030921-0.0026667zm34.9 2.0257c0.013964 0.0013333 0.027264 3e-3 0.041561 0.0043333l-0.031254 0.046333c-0.0036573-0.017-0.0069822-0.034-0.010307-0.050667zm-22.998 0.34067c0.012302 0.0016666 0.025269 3e-3 0.037571 0.0043333l-0.028594 0.039c-0.0029924-0.014667-0.0056523-0.028667-0.0089771-0.043333zm-16.9 3.542s8.0594-7.693 18.254 0.88467c-3.1137 2.6673-6.0605 3.5853-8.642 3.5853-5.6965 0-9.6125-4.47-9.6125-4.47zm28.752-2.8893c0.013632 0.0013334 0.027264 3e-3 0.040896 0.0043334l-0.030589 0.045c-0.0033249-0.016-0.0069822-0.033333-0.010307-0.049333zm21.183 2.4917c3.325e-4 -0.019 3.325e-4 -0.039333 6.65e-4 -0.058333l0.046548 0.039667c-0.015959 0.0063334-0.031254 0.012333-0.047213 0.018667-0.19118 19.436-13.172 23.733-13.172 23.733s-2.0415-17.662 13.172-23.733zm-31.651 1.257v0.05c-0.0099746-0.0083333-0.019617-0.016333-0.029259-0.024667 0.0093096-0.0086666 0.019284-0.017 0.029259-0.025333zm-6.6234 10.543s4.296-11.202 16.634-9.0197c-3.5273 8.062-9.0759 9.5947-12.782 9.5947-2.2719 0-3.8515-0.575-3.8515-0.575zm16.651-9.0593 0.018287 0.046c-0.01197-2e-3 -0.023606-0.0043334-0.035576-0.0063334 0.0059848-0.013333 0.011637-0.026333 0.017289-0.039667zm10.12 0.685c0.0029923-0.016333 0.0059847-0.033333 0.0089771-0.049667l0.034911 0.043c-0.014629 0.0023333-0.029259 0.0046667-0.043888 0.0066667-2.9518 16.71-14.755 17.762-14.755 17.762s0.77369-15.639 14.755-17.762z"/> </defs> <g fill="none" fill-rule="evenodd"> <g transform="translate(6.3172 6.3333)"> <mask id="b" fill="white"> <use xlink:href="#a"/> </mask> <polygon points="-3.1772 -3.2937 100.48 -3.2937 100.48 101.52 -3.1772 101.52" fill="#fff" mask="url(#b)"/> </g> <path d="m55.303 3.569c-28.538 0-51.754 23.273-51.754 51.88 0 28.607 23.216 51.88 51.754 51.88 28.538 0 51.754-23.273 51.754-51.88 0-28.607-23.217-51.88-51.754-51.88m0 107.18c-30.417 0-55.163-24.807-55.163-55.298 0-30.492 24.746-55.298 55.163-55.298 30.417 0 55.164 24.807 55.164 55.298 0 30.491-24.747 55.298-55.164 55.298" fill="#fff"/> <path d="m137.42 77.263-2.7699 22.725h-14.958l8.2174-67.434h22.252c4.001 0 7.4249 0.48597 10.272 1.4579 2.8469 0.97195 5.1859 2.3141 7.0171 4.0266 1.8312 1.7125 3.1777 3.7335 4.0395 6.0631 0.86176 2.3296 1.2926 4.8366 1.2926 7.521 0 3.6718-0.56167 7.0736-1.685 10.205-1.1234 3.1318-2.8392 5.8394-5.1474 8.1227s-5.232 4.0729-8.7714 5.3688-7.725 1.9439-12.557 1.9439h-7.2018zm4.1549-33.463-2.7238 22.123h7.248c2.1544 0 3.9625-0.31626 5.4244-0.9488 1.4619-0.63254 2.6468-1.5273 3.5547-2.6844 0.90792-1.1571 1.5619-2.5378 1.962-4.1423 0.4001-1.6045 0.60015-3.3632 0.60015-5.2763 0-1.3268-0.17696-2.5456-0.5309-3.6564-0.35394-1.1108-0.90022-2.0673-1.6389-2.8695-0.73865-0.80224-1.6696-1.4271-2.793-1.8745-1.1234-0.4474-2.4544-0.6711-3.9933-0.6711h-7.1095zm48.956 46.283c1.6004 0 3.0315-0.48597 4.2934-1.4579 1.2619-0.97195 2.3313-2.2987 3.2085-3.9803 0.87714-1.6816 1.5542-3.6409 2.0313-5.8779 0.47704-2.237 0.71556-4.6206 0.71556-7.1507 0-3.4867-0.46934-5.9782-1.408-7.4747-0.9387-1.4965-2.4698-2.2447-4.5934-2.2447-1.6004 0-3.0315 0.48597-4.2934 1.4579-1.2619 0.97195-2.3313 2.291-3.2085 3.9572s-1.5542 3.6255-2.0313 5.8779c-0.47704 2.2525-0.71556 4.6437-0.71556 7.1739 0 3.425 0.46934 5.9011 1.408 7.4284 0.9387 1.5273 2.4698 2.291 4.5934 2.291zm-1.2926 10.645c-2.6776 0-5.1782-0.4474-7.5019-1.3422-2.3237-0.89481-4.3395-2.1984-6.0477-3.9109-1.7081-1.7125-3.0469-3.8261-4.0164-6.3408-0.96948-2.5147-1.4542-5.4074-1.4542-8.6781 0-4.2581 0.70017-8.1689 2.1005-11.733 1.4004-3.5638 3.2854-6.6416 5.6552-9.2335s5.1166-4.6129 8.2405-6.0631 6.4093-2.1753 9.8563-2.1753c2.6776 0 5.1705 0.4474 7.4788 1.3422 2.3083 0.89481 4.3164 2.1984 6.0246 3.9109 1.7081 1.7125 3.0546 3.8261 4.0395 6.3408 0.98486 2.5147 1.4773 5.4074 1.4773 8.6781 0 4.1963-0.70017 8.0764-2.1005 11.64-1.4004 3.5638-3.2854 6.6493-5.6552 9.2566-2.3698 2.6073-5.1166 4.6437-8.2405 6.1094-3.1239 1.4656-6.4093 2.1984-9.8563 2.1984zm62.6-0.74053c-0.89253 0-1.6389-0.11571-2.239-0.34712-0.60015-0.23142-1.0772-0.54768-1.4311-0.9488s-0.60015-0.87937-0.73864-1.4348c-0.1385-0.5554-0.20774-1.1571-0.20774-1.805v-4.0266c-2.1852 2.9004-4.6011 5.176-7.248 6.8267-2.6468 1.6508-5.4629 2.4761-8.4482 2.4761-1.9697 0-3.7702-0.34712-5.4013-1.0414-1.6312-0.69425-3.0392-1.7819-4.2241-3.263s-2.1082-3.3709-2.7699-5.6697c-0.66171-2.2987-0.99255-5.0525-0.99255-8.2615 0-2.777 0.29238-5.4845 0.87714-8.1227 0.58476-2.6381 1.4003-5.1143 2.4468-7.4284s2.2929-4.4354 3.7394-6.3639c1.4465-1.9285 3.0392-3.5792 4.7781-4.9523 1.7389-1.3731 3.5778-2.4453 5.5168-3.2167s3.9394-1.1571 6.0015-1.1571c1.9697 0 3.7471 0.33169 5.3321 0.99508 1.585 0.66339 2.9777 1.535 4.178 2.615l3.0469-24.16h14.034l-8.5867 69.286h-7.6634zm-14.588-10.182c0.98486 0 2.0082-0.37026 3.07-1.1108s2.0928-1.7587 3.0931-3.0547 1.9312-2.8155 2.793-4.5589c0.86176-1.7433 1.6004-3.6178 2.2159-5.6234l1.4773-11.663c-0.89253-0.70968-1.8851-1.2188-2.9777-1.5273s-2.1313-0.46283-3.1162-0.46283c-1.662 0-3.1931 0.55539-4.5934 1.6662s-2.6083 2.5687-3.624 4.3737c-1.0156 1.805-1.8081 3.8646-2.3775 6.1788s-0.85406 4.6746-0.85406 7.0813c0 3.0547 0.44626 5.2685 1.3388 6.6416 0.89253 1.3731 2.0774 2.0596 3.5547 2.0596zm63.465-27.724c-0.43088 0.5554-0.83097 0.95651-1.2003 1.2034s-0.86175 0.37026-1.4773 0.37026-1.2234-0.13885-1.8235-0.41655-1.2465-0.59396-1.9389-0.9488c-0.69248-0.35484-1.4773-0.6711-2.3544-0.9488-0.87714-0.2777-1.8851-0.41655-3.0238-0.41655-2.1236 0-3.6394 0.40883-4.5473 1.2265-0.90792 0.81767-1.3619 1.8745-1.3619 3.1704 0 0.8331 0.25391 1.5428 0.76173 2.129 0.50782 0.58625 1.1772 1.1108 2.0082 1.5736 0.83098 0.46283 1.7774 0.88709 2.8392 1.2728 1.0618 0.38569 2.1467 0.81766 3.2547 1.2959 1.108 0.47826 2.1928 1.0259 3.2547 1.643s2.0082 1.3731 2.8392 2.2679c0.83098 0.89481 1.5004 1.9593 2.0082 3.1935 0.50782 1.2342 0.76173 2.6998 0.76173 4.3969 0 2.4067-0.47704 4.6823-1.4311 6.8267-0.95409 2.1445-2.3236 4.0112-4.1087 5.6002-1.7851 1.5891-3.9471 2.8541-6.4862 3.7952-2.5391 0.94109-5.3936 1.4116-8.5637 1.4116-1.5081 0-3.0007-0.15428-4.478-0.46283-1.4773-0.30856-2.8699-0.7251-4.178-1.2496s-2.5006-1.1494-3.5778-1.8745c-1.0772-0.7251-1.9543-1.5042-2.6314-2.3373l3.5086-5.2763c0.43088-0.61711 0.931-1.1031 1.5004-1.4579 0.56938-0.35484 1.2695-0.53225 2.1005-0.53225 0.76942 0 1.4311 0.18513 1.9851 0.5554 0.55399 0.37027 1.1541 0.77138 1.8004 1.2034s1.4157 0.83309 2.3083 1.2034c0.89253 0.37027 2.062 0.5554 3.5086 0.5554 2.0313 0 3.5393-0.45511 4.5242-1.3653 0.98486-0.91024 1.4773-1.9824 1.4773-3.2167 0-0.95652-0.25391-1.7433-0.76173-2.3604-0.50782-0.61711-1.1772-1.1494-2.0082-1.5968-0.83098-0.4474-1.7697-0.84852-2.8161-1.2034-1.0464-0.35484-2.1236-0.74824-3.2316-1.1802s-2.1852-0.93337-3.2316-1.5042c-1.0464-0.57083-1.9851-1.2882-2.8161-2.1522-0.83098-0.86395-1.5004-1.9285-2.0082-3.1935-0.50782-1.2651-0.76173-2.7924-0.76173-4.582 0-2.2216 0.40779-4.3814 1.2234-6.4796s2.0313-3.9572 3.6471-5.5771c1.6158-1.6199 3.624-2.9235 6.0246-3.9109s5.2013-1.4811 8.4021-1.4811c3.2008 0 6.0553 0.55539 8.5637 1.6662 2.5083 1.1108 4.578 2.4684 6.2092 4.0729l-3.6932 5.0911z" fill="#fff"/> <g transform="translate(128.86 3.5426)" fill="#fff"> <path d="m14.411 3.7958h-8.3873l-0.77821 6.399h7.0759l-0.3891 3.0104h-7.0471l-1.052 8.6095h-3.7613l2.5652-21.029h12.149l-0.37469 3.0104zm-0.59086 18.019 1.8014-14.936h1.8014c0.34587 0 0.62929 0.077562 0.85026 0.23269 0.22097 0.15513 0.33146 0.40236 0.33146 0.7417v0.050901c0 0.033934-0.0048037 0.13331-0.014411 0.29813s-0.019215 0.42417-0.028822 0.77806c-0.0096075 0.35388-0.028822 0.85077-0.057645 1.4907 0.60527-1.1732 1.2682-2.0797 1.9887-2.7196 0.72056-0.6399 1.4699-0.95985 2.2482-0.95985 0.39391 0 0.79262 0.087258 1.1961 0.26178l-0.6485 3.4322c-0.48038-0.2036-0.93673-0.30541-1.3691-0.30541-0.85507 0-1.6044 0.41205-2.2482 1.2362-0.6437 0.82411-1.1721 2.1136-1.5852 3.8685l-0.77821 6.5299h-3.4875zm16.083-14.921-1.7726 14.921h-3.5163l1.7726-14.921h3.5163zm0.8935-4.3484c0 0.31025-0.06485 0.60111-0.19455 0.87259-0.1297 0.27147-0.29783 0.50901-0.50439 0.71261-0.20656 0.2036-0.44434 0.366-0.71336 0.48719-0.26901 0.12119-0.54762 0.18179-0.83585 0.18179-0.27862 0-0.55003-0.060596-0.81423-0.18179-0.26421-0.12119-0.49719-0.28359-0.69894-0.48719s-0.36268-0.44114-0.48278-0.71261c-0.12009-0.27147-0.18014-0.56233-0.18014-0.87259s0.062448-0.60596 0.18735-0.88713 0.28822-0.52597 0.48998-0.73443c0.20176-0.20845 0.43474-0.37327 0.69894-0.49447 0.26421-0.12119 0.53562-0.18179 0.81423-0.18179 0.28823 0 0.56684 0.060596 0.83585 0.18179 0.26901 0.12119 0.50679 0.28359 0.71336 0.48719 0.20656 0.2036 0.37229 0.44599 0.49719 0.72716s0.18735 0.58172 0.18735 0.90167zm13.402 7.8097c0 0.66899-0.1321 1.2798-0.39631 1.8324-0.26421 0.55264-0.73737 1.0471-1.4195 1.4834-0.68213 0.4363-1.6068 0.81199-2.7742 1.1271-1.1673 0.3151-2.6541 0.56476-4.4603 0.74897v0.18906c0 2.3463 0.98476 3.5194 2.9543 3.5194 0.42273 0 0.79742-0.041205 1.1241-0.12362s0.61248-0.18179 0.85747-0.29813 0.46596-0.24723 0.66292-0.39266c0.19695-0.14543 0.37949-0.27632 0.54763-0.39266 0.16813-0.11635 0.33386-0.21572 0.49719-0.29813 0.16333-0.082411 0.34106-0.12362 0.53322-0.12362 0.11529 0 0.23058 0.026662 0.34587 0.079987 0.11529 0.053325 0.21136 0.13331 0.28822 0.23996l0.90791 1.1053c-0.5092 0.51386-1.0088 0.95984-1.4988 1.338-0.48998 0.37812-0.98957 0.68837-1.4988 0.93076-0.5092 0.24239-1.0472 0.42175-1.6141 0.5381-0.56684 0.11635-1.1865 0.17452-1.859 0.17452-0.86468 0-1.6477-0.14785-2.349-0.44356-0.70135-0.29571-1.3018-0.71261-1.8014-1.2507-0.49959-0.5381-0.88629-1.1877-1.1601-1.9488-0.27381-0.76109-0.41072-1.6119-0.41072-2.5523 0-0.78533 0.084065-1.5561 0.2522-2.3124 0.16813-0.75625 0.41072-1.4737 0.72777-2.1524 0.31705-0.67868 0.70615-1.304 1.1673-1.8761 0.46116-0.57203 0.98236-1.0665 1.5636-1.4834 0.58126-0.4169 1.2201-0.7417 1.9167-0.97439 0.69655-0.23269 1.4435-0.34903 2.2409-0.34903 0.77821 0 1.4579 0.1115 2.0392 0.33449 0.58126 0.223 1.0664 0.51143 1.4555 0.86532 0.3891 0.35388 0.67973 0.74897 0.87188 1.1853 0.19215 0.4363 0.28822 0.86289 0.28822 1.2798zm-4.8566-1.1634c-0.48038 0-0.92712 0.099377-1.3402 0.29813-0.41312 0.19876-0.78541 0.4775-1.1169 0.83623-0.33146 0.35873-0.61968 0.78775-0.86467 1.2871-0.24499 0.49932-0.43954 1.0447-0.58365 1.6361 1.1913-0.16482 2.1497-0.34419 2.875-0.5381 0.72537-0.19391 1.2874-0.40721 1.6861-0.6399 0.39871-0.23269 0.66292-0.47992 0.79262-0.7417 0.1297-0.26178 0.19455-0.54294 0.19455-0.8435 0-0.14543-0.031224-0.29571-0.093673-0.45084-0.062449-0.15513-0.15852-0.29329-0.28822-0.41448-0.1297-0.12119-0.29783-0.22299-0.50439-0.30541-0.20656-0.082411-0.45876-0.12362-0.75659-0.12362zm6.0095 12.623 1.7726-14.936h1.8158c0.37469 0 0.66532 0.092105 0.87188 0.27632 0.20656 0.18421 0.30984 0.47992 0.30984 0.88713l-0.10088 1.9342c0.74939-1.115 1.5804-1.9464 2.4931-2.4941 0.91272-0.54779 1.8542-0.82169 2.8246-0.82169 0.54763 0 1.0448 0.099377 1.4916 0.29813s0.82864 0.48962 1.1457 0.87259 0.56204 0.85319 0.73497 1.4107c0.17294 0.55749 0.2594 1.1998 0.2594 1.927 0 0.18421-0.0072055 0.37085-0.021617 0.55991s-0.031224 0.38539-0.050439 0.589l-1.1097 9.4967h-3.5596c0.19215-1.6385 0.35548-3.0274 0.48998-4.1666 0.13451-1.1392 0.24499-2.0869 0.33146-2.8432 0.086468-0.75625 0.15372-1.3501 0.20176-1.7815 0.048038-0.43145 0.084065-0.75866 0.10808-0.98166 0.024019-0.223 0.03843-0.37085 0.043234-0.44356s0.0072056-0.13331 0.0072056-0.18179c0-0.6399-0.11529-1.1029-0.34587-1.3889s-0.59086-0.42902-1.0808-0.42902c-0.39391 0-0.80222 0.11634-1.225 0.34903-0.42273 0.23269-0.82624 0.56233-1.2105 0.98893-0.3843 0.4266-0.73497 0.94045-1.052 1.5416-0.31705 0.60112-0.57645 1.2701-0.77821 2.0069l-0.80703 7.3297h-3.5596zm25.738 0c-0.43234 0-0.73497-0.1018-0.90791-0.30541-0.17294-0.2036-0.2594-0.46053-0.2594-0.77078l0.11529-2.1815c-0.71096 1.0665-1.5084 1.9124-2.3923 2.5378-0.88389 0.62536-1.8254 0.93803-2.8246 0.93803-0.61488 0-1.1745-0.11392-1.6789-0.34176-0.5044-0.22784-0.93433-0.5696-1.2898-1.0253s-0.62929-1.0326-0.82144-1.7306c-0.19215-0.69807-0.28822-1.5222-0.28822-2.4723 0-0.8435 0.086466-1.67 0.2594-2.4796 0.17294-0.80957 0.41792-1.5779 0.73497-2.3051 0.31705-0.72716 0.69414-1.3961 1.1313-2.0069 0.43714-0.61081 0.92472-1.1392 1.4627-1.5852 0.53802-0.44599 1.1121-0.79502 1.7221-1.0471s1.2418-0.37812 1.8951-0.37812c0.66292 0 1.2634 0.12119 1.8014 0.36358 0.53802 0.24239 1.0088 0.57203 1.4123 0.98893l0.96555-7.8097h3.4875l-2.6373 21.611h-1.8879zm-4.8854-2.6032c-0.60527 0-1.076-0.2545-1.4123-0.76351-0.33626-0.50901-0.50439-1.2871-0.50439-2.3342 0-0.80472 0.10088-1.607 0.30264-2.4069 0.20176-0.79988 0.48758-1.5198 0.85747-2.1597 0.36989-0.6399 0.81423-1.1586 1.333-1.5561 0.51881-0.39751 1.0952-0.59627 1.7293-0.59627 0.40352 0 0.81663 0.072715 1.2394 0.21815s0.79742 0.39751 1.1241 0.75624l-0.44675 3.6212c-0.23058 0.73685-0.50679 1.4228-0.82865 2.0579-0.32185 0.63505-0.67012 1.1877-1.0448 1.6579-0.37469 0.47023-0.76379 0.83865-1.1673 1.1053s-0.79742 0.39994-1.1817 0.39994zm19.549-9.5612c-0.10501 0.15274-0.20525 0.26014-0.30071 0.32219-0.095464 0.062051-0.21956 0.093077-0.37231 0.093077-0.16229 0-0.32935-0.047731-0.50118-0.14319-0.17183-0.095464-0.36992-0.20286-0.59426-0.32219-0.22434-0.11933-0.48209-0.22672-0.77325-0.32219s-0.64199-0.14319-1.0525-0.14319c-0.75416 0-1.3317 0.16945-1.7327 0.50834-0.40095 0.3389-0.60142 0.76132-0.60142 1.2673 0 0.29594 0.083529 0.54653 0.25059 0.75177s0.38424 0.38424 0.65154 0.53698c0.2673 0.15274 0.57278 0.29355 0.91645 0.42242s0.69688 0.2673 1.0596 0.41526 0.71597 0.31503 1.0596 0.50118c0.34367 0.18615 0.64915 0.41288 0.91645 0.68017 0.2673 0.2673 0.48447 0.58948 0.65154 0.96656s0.25059 0.82814 0.25059 1.3532c0 0.70643-0.14081 1.3794-0.42242 2.019-0.28162 0.63961-0.68495 1.2004-1.21 1.6825-0.52505 0.48209-1.1599 0.86394-1.9045 1.1456-0.74462 0.28162-1.5751 0.42242-2.4916 0.42242-0.46777 0-0.91883-0.045344-1.3532-0.13603-0.43436-0.09069-0.84246-0.21718-1.2243-0.37947-0.38185-0.16229-0.7279-0.35321-1.0382-0.57278-0.31026-0.21957-0.57516-0.45822-0.79473-0.71597l0.85917-1.346c0.10501-0.16229 0.2315-0.28639 0.37947-0.37231 0.14797-0.085917 0.32219-0.12888 0.52266-0.12888s0.38185 0.06205 0.54414 0.18615c0.16229 0.1241 0.35321 0.26014 0.57278 0.4081s0.48447 0.284 0.79473 0.4081 0.70881 0.18615 1.1957 0.18615c0.3914 0 0.73745-0.052504 1.0382-0.15751 0.30071-0.10501 0.55369-0.2482 0.75893-0.42958 0.20525-0.18138 0.36037-0.3914 0.46538-0.63006 0.10501-0.23866 0.15751-0.49163 0.15751-0.75893 0-0.32458-0.081143-0.59426-0.24343-0.80905-0.16229-0.21479-0.37946-0.40094-0.65154-0.55846-0.27207-0.15751-0.57994-0.29594-0.92361-0.41526s-0.69449-0.24582-1.0525-0.37947c-0.35799-0.13365-0.70643-0.28639-1.0453-0.45822s-0.64437-0.38901-0.91645-0.65154c-0.27207-0.26252-0.48925-0.58232-0.65154-0.9594-0.16229-0.37708-0.24343-0.83769-0.24343-1.3818 0-0.64915 0.1241-1.2816 0.37231-1.8973 0.24821-0.61574 0.61335-1.1599 1.0954-1.6324 0.48209-0.47254 1.074-0.85201 1.7756-1.1384 0.70166-0.28639 1.5059-0.42958 2.4128-0.42958 0.93554 0 1.7637 0.1599 2.4844 0.4797 0.72075 0.3198 1.3293 0.7279 1.8257 1.2243l-0.91645 1.2888z"/> <path d="m57.693 40.297c0.49639 0 0.94473-0.14341 1.345-0.43023 0.40031-0.28682 0.74258-0.6706 1.0268-1.1513 0.28422-0.48073 0.50239-1.0402 0.65451-1.6785 0.15212-0.63828 0.22818-1.3089 0.22818-2.0118 0-1.0099-0.17013-1.7533-0.5104-2.2299-0.34027-0.47669-0.85466-0.71504-1.5432-0.71504-0.49639 0-0.94473 0.14139-1.345 0.42417s-0.74058 0.66656-1.0208 1.1513c-0.28022 0.48477-0.49639 1.0463-0.6485 1.6846-0.15212 0.63828-0.22818 1.3129-0.22818 2.0239 0 1.0099 0.16813 1.7512 0.50439 2.2239s0.84866 0.70898 1.5372 0.70898zm-0.26421 2.3027c-0.68053 0-1.311-0.11513-1.8915-0.3454s-1.0808-0.56758-1.5012-1.012-0.75058-0.98974-0.99077-1.6361c-0.24019-0.64636-0.36028-1.3856-0.36028-2.2178 0-1.0746 0.17013-2.0764 0.5104-3.0056 0.34027-0.92915 0.80462-1.7331 1.3931-2.4117 0.58846-0.67868 1.275-1.2119 2.0596-1.5997 0.78461-0.38782 1.6213-0.58172 2.51-0.58172 0.68053 0 1.311 0.11513 1.8915 0.3454s1.0828 0.56758 1.5072 1.012c0.42433 0.44438 0.75659 0.98974 0.99678 1.6361 0.24019 0.64636 0.36028 1.3856 0.36028 2.2178 0 1.0665-0.17213 2.0623-0.5164 2.9874-0.34427 0.92511-0.81063 1.729-1.3991 2.4117-0.58846 0.68272-1.275 1.22-2.0596 1.6119-0.78461 0.39186-1.6213 0.58778-2.51 0.58778zm12.177-10.374-1.1649 9.6833-0.61248 2.2784c-0.11209 0.3959-0.28622 0.69888-0.52241 0.90894-0.23619 0.21007-0.57044 0.3151-1.0028 0.3151h-1.1889l1.5732-13.186-0.94874-0.16967c-0.17614-0.032318-0.32025-0.098973-0.43234-0.19997-0.11209-0.10099-0.16813-0.2444-0.16813-0.43023 0-0.0080796 0.0020015-0.024238 0.0060047-0.048477 0.0040031-0.024239 0.010008-0.078775 0.018014-0.16361 0.0080063-0.084835 0.022017-0.21411 0.042033-0.38782 0.020016-0.17371 0.050039-0.41811 0.09007-0.73322h1.6573l0.10808-0.92106c0.088069-0.711 0.27421-1.3493 0.55843-1.9148 0.28422-0.56557 0.6445-1.0463 1.0808-1.4422 0.43634-0.3959 0.93873-0.69888 1.5072-0.90894 0.56845-0.21007 1.1809-0.3151 1.8374-0.3151 0.5124 0 0.98476 0.076755 1.4171 0.23027l-0.26421 1.5513c-0.016013 0.088875-0.054042 0.15957-0.11409 0.21209-0.060047 0.052517-0.1341 0.090894-0.22217 0.11513s-0.18614 0.040398-0.29423 0.048477c-0.10808 0.0080796-0.21817 0.012119-0.33026 0.012119-0.32025 0-0.61448 0.044437-0.88269 0.13331s-0.50439 0.23228-0.70855 0.43023c-0.20416 0.19795-0.37229 0.45649-0.50439 0.77563-0.1321 0.31914-0.22618 0.70897-0.28222 1.1695l-0.096075 0.82411h2.7622l-0.27622 2.133h-2.6421z"/> </g> </g> </svg>
1198
- </div>
1199
- <div class="pods-admin_friends-callout_content-container">
1200
- <h2 class="pods-admin_friends-callout_headline">
1201
- <?php
1202
- printf(
1203
- esc_html__( 'We need %1$sYOU%2$s in 2021 and beyond', 'pods' ),
1204
- '<span class="pods-admin_friends-you">',
1205
- '</span>'
1206
- );
1207
- ?>
1208
- </h2>
1209
- <p class="pods-admin_friends-callout_text">
1210
- <?php
1211
- esc_html_e( 'Things are growing for Pods and we want you to be a part of it! Our intention is to be fully funded by users like you. Help us reach our continued goal of 200 recurring donors in 2021.', 'pods' );
1212
- ?>
1213
- </p>
1214
- <p class="pods-admin_friends-callout_text">
1215
- <?php
1216
- printf(
1217
- '<strong>%s:</strong> %s',
1218
- esc_html__( 'Goal Progress', 'pods' ),
1219
- // translators: %1$d: is the number of donors we have; %2$d: the number of donors for our goal.
1220
- sprintf(
1221
- esc_html__( '%1$d of %2$d donors', 'pods' ),
1222
- $donor_count,
1223
- $donor_goal
1224
- )
1225
- );
1226
- ?>
1227
- </p>
1228
- <div class="pods-admin_progress-bar_container">
1229
- <div class="pods-admin_progress-bar_fill" style="width:<?php echo esc_attr( $progress_width ); ?>%">
1230
- <?php echo esc_attr( $progress_width ); ?>%
1231
- </div>
1232
- </div>
1233
- <p class="pods-admin_friends-callout_text"><?php
1234
- // translators: %s: Pods Pro by SKCDEV link.
1235
- printf(
1236
- esc_html__( 'You can also check out the new add-ons available from %s which has partnered with Friends of Pods to bring in more donations.', 'pods' ),
1237
- '<a href="https://pods.io/2020/12/31/introducing-pods-pro-by-skcdev/?utm_source=pods_plugin_callout&utm_medium=link&utm_campaign=friends_of_pods_2021">Pods Pro by SKCDEV</a>'
1238
- );
1239
- ?></p>
1240
- <div class="pods-admin_friends-callout_button-group">
1241
- <a href="https://friends.pods.io/?utm_source=pods_plugin_callout&utm_medium=link&utm_campaign=friends_of_pods_2021" class="pods-admin_friends-callout_button"><?php esc_html_e( 'Learn More', 'pods' ); ?></a>
1242
- <a href="https://friends.pods.io/donations/become-a-friend/?utm_source=pods_plugin_callout&utm_medium=link&utm_campaign=friends_of_pods_2021" class="pods-admin_friends-callout_button--join"><?php esc_html_e( 'Join Now', 'pods' ); ?></a>
1243
- </div>
1244
- </div>
1245
- </div>
1246
- <?php
1247
  }
1248
  }
1249
 
@@ -1253,7 +1256,6 @@ class PodsAdmin {
1253
  * @param PodsUI $obj PodsUI object.
1254
  */
1255
  public function admin_setup_add( $obj ) {
1256
-
1257
  pods_view( PODS_DIR . 'ui/admin/setup-add.php', compact( array_keys( get_defined_vars() ) ) );
1258
  }
1259
 
@@ -1264,1488 +1266,496 @@ class PodsAdmin {
1264
  * @param PodsUI $obj PodsUI object.
1265
  */
1266
  public function admin_setup_edit( $duplicate, $obj ) {
 
1267
 
1268
- pods_view( PODS_DIR . 'ui/admin/setup-edit.php', compact( array_keys( get_defined_vars() ) ) );
1269
- }
1270
 
1271
- /**
1272
- * Get list of Pod option tabs
1273
- *
1274
- * @param array $pod Pod options.
1275
- *
1276
- * @return array
1277
- */
1278
- public function admin_setup_edit_tabs( $pod ) {
1279
-
1280
- $fields = true;
1281
- $labels = false;
1282
- $admin_ui = false;
1283
- $advanced = false;
1284
-
1285
- if ( 'post_type' === pods_v( 'type', $pod ) && '' === pods_v( 'object', $pod ) ) {
1286
- $labels = true;
1287
- $admin_ui = true;
1288
- $advanced = true;
1289
- } elseif ( 'taxonomy' === pods_v( 'type', $pod ) && '' === pods_v( 'object', $pod ) ) {
1290
- $labels = true;
1291
- $admin_ui = true;
1292
- $advanced = true;
1293
- } elseif ( 'pod' === pods_v( 'type', $pod ) ) {
1294
- $labels = true;
1295
- $admin_ui = true;
1296
- $advanced = true;
1297
- } elseif ( 'settings' === pods_v( 'type', $pod ) ) {
1298
- $labels = true;
1299
- $admin_ui = true;
1300
  }
1301
 
1302
- if ( ! function_exists( 'get_term_meta' ) && 'none' === pods_v( 'storage', $pod, 'none', true ) && 'taxonomy' === pods_v( 'type', $pod ) ) {
1303
- $fields = false;
1304
  }
1305
 
1306
- $tabs = array();
 
 
 
 
1307
 
1308
- if ( $fields ) {
1309
- $tabs['manage-fields'] = __( 'Manage Fields', 'pods' );
1310
- }
1311
 
1312
- if ( $labels ) {
1313
- $tabs['labels'] = __( 'Labels', 'pods' );
1314
  }
1315
 
1316
- if ( $admin_ui ) {
1317
- $tabs['admin-ui'] = __( 'Admin UI', 'pods' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1318
  }
1319
 
1320
- if ( $advanced ) {
1321
- $tabs['advanced'] = __( 'Advanced Options', 'pods' );
 
 
1322
  }
1323
 
1324
- if ( 'taxonomy' === pods_v( 'type', $pod ) && ! $fields ) {
1325
- $tabs['extra-fields'] = __( 'Extra Fields', 'pods' );
1326
  }
1327
 
1328
- $addtl_args = compact( array( 'fields', 'labels', 'admin_ui', 'advanced' ) );
1329
 
1330
- $pod_type = $pod['type'];
1331
- $pod_name = $pod['name'];
 
1332
 
1333
  /**
1334
- * Add or modify tabs in Pods editor for a specific Pod
1335
  *
1336
- * @param array $tabs Tabs to set.
1337
- * @param object $pod Current Pods object.
1338
- * @param array $addtl_args Additional args.
1339
  *
1340
- * @since unknown
 
 
1341
  */
1342
- $tabs = apply_filters( "pods_admin_setup_edit_tabs_{$pod_type}_{$pod_name}", $tabs, $pod, $addtl_args );
1343
 
1344
- /**
1345
- * Add or modify tabs for any Pod in Pods editor of a specific post type.
1346
- */
1347
- $tabs = apply_filters( "pods_admin_setup_edit_tabs_{$pod_type}", $tabs, $pod, $addtl_args );
1348
 
1349
- /**
1350
- * Add or modify tabs in Pods editor for all pods.
1351
- */
1352
- $tabs = apply_filters( 'pods_admin_setup_edit_tabs', $tabs, $pod, $addtl_args );
1353
 
1354
- return $tabs;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1355
  }
1356
 
1357
  /**
1358
- * Get list of Pod options
1359
  *
1360
- * @param array $pod Pod options.
1361
  *
1362
- * @return array
 
 
1363
  */
1364
- public function admin_setup_edit_options( $pod ) {
1365
-
1366
- $options = array();
1367
-
1368
- if ( '' === pods_v( 'object', $pod ) && 'settings' !== pods_v( 'type', $pod ) ) {
1369
- $labels = array(
1370
- 'label' => array(
1371
- 'label' => __( 'Label', 'pods' ),
1372
- 'help' => __( 'help', 'pods' ),
1373
- 'type' => 'text',
1374
- 'default' => str_replace( '_', ' ', pods_v( 'name', $pod ) ),
1375
- 'text_max_length' => 30,
1376
- ),
1377
- 'label_singular' => array(
1378
- 'label' => __( 'Singular Label', 'pods' ),
1379
- 'help' => __( 'help', 'pods' ),
1380
- 'type' => 'text',
1381
- 'default' => pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', pods_v( 'name', $pod ) ) ) ),
1382
- 'text_max_length' => 30,
1383
- ),
1384
- 'label_add_new' => array(
1385
- 'label' => __( 'Add New', 'pods' ),
1386
- 'help' => __( 'help', 'pods' ),
1387
- 'type' => 'text',
1388
- 'default' => '',
1389
- 'object_type' => array( 'post_type', 'pod' ),
1390
- ),
1391
- 'label_add_new_item' => array(
1392
- 'label' => __( 'Add new <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1393
- 'help' => __( 'help', 'pods' ),
1394
- 'type' => 'text',
1395
- 'default' => '',
1396
- ),
1397
- 'label_new_item' => array(
1398
- 'label' => __( 'New <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1399
- 'help' => __( 'help', 'pods' ),
1400
- 'type' => 'text',
1401
- 'default' => '',
1402
- 'object_type' => array( 'post_type', 'pod' ),
1403
- ),
1404
- 'label_new_item_name' => array(
1405
- 'label' => __( 'New <span class="pods-slugged" data-sluggable="label_singular">Item</span> Name', 'pods' ),
1406
- 'help' => __( 'help', 'pods' ),
1407
- 'type' => 'text',
1408
- 'default' => '',
1409
- 'object_type' => array( 'taxonomy' ),
1410
- ),
1411
- 'label_edit' => array(
1412
- 'label' => __( 'Edit', 'pods' ),
1413
- 'help' => __( 'help', 'pods' ),
1414
- 'type' => 'text',
1415
- 'default' => '',
1416
- 'object_type' => array( 'pod' ),
1417
- ),
1418
- 'label_edit_item' => array(
1419
- 'label' => __( 'Edit <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1420
- 'help' => __( 'help', 'pods' ),
1421
- 'type' => 'text',
1422
- 'default' => '',
1423
- ),
1424
- 'label_update_item' => array(
1425
- 'label' => __( 'Update <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1426
- 'help' => __( 'help', 'pods' ),
1427
- 'type' => 'text',
1428
- 'default' => '',
1429
- 'object_type' => array( 'taxonomy', 'pod' ),
1430
- ),
1431
- 'label_duplicate' => array(
1432
- 'label' => __( 'Duplicate', 'pods' ),
1433
- 'help' => __( 'help', 'pods' ),
1434
- 'type' => 'text',
1435
- 'default' => '',
1436
- 'object_type' => array( 'pod' ),
1437
- ),
1438
- 'label_duplicate_item' => array(
1439
- 'label' => __( 'Duplicate <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1440
- 'help' => __( 'help', 'pods' ),
1441
- 'type' => 'text',
1442
- 'default' => '',
1443
- 'object_type' => array( 'pod' ),
1444
- ),
1445
- 'label_delete_item' => array(
1446
- 'label' => __( 'Delete <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1447
- 'help' => __( 'help', 'pods' ),
1448
- 'type' => 'text',
1449
- 'default' => '',
1450
- 'object_type' => array( 'pod' ),
1451
- ),
1452
- 'label_view' => array(
1453
- 'label' => __( 'View', 'pods' ),
1454
- 'help' => __( 'help', 'pods' ),
1455
- 'type' => 'text',
1456
- 'default' => '',
1457
- 'object_type' => array( 'pod' ),
1458
- ),
1459
- 'label_view_item' => array(
1460
- 'label' => __( 'View <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1461
- 'help' => __( 'help', 'pods' ),
1462
- 'type' => 'text',
1463
- 'default' => '',
1464
- ),
1465
- 'label_view_items' => array(
1466
- 'label' => __( 'View <span class="pods-slugged" data-sluggable="label">Items</span>', 'pods' ),
1467
- 'help' => __( 'help', 'pods' ),
1468
- 'type' => 'text',
1469
- 'default' => '',
1470
- 'object_type' => array( 'post_type' ),
1471
- ),
1472
- 'label_back_to_manage' => array(
1473
- 'label' => __( 'Back to Manage', 'pods' ),
1474
- 'help' => __( 'help', 'pods' ),
1475
- 'type' => 'text',
1476
- 'default' => '',
1477
- 'object_type' => array( 'pod' ),
1478
- ),
1479
- 'label_manage' => array(
1480
- 'label' => __( 'Manage', 'pods' ),
1481
- 'help' => __( 'help', 'pods' ),
1482
- 'type' => 'text',
1483
- 'default' => '',
1484
- 'object_type' => array( 'pod' ),
1485
- ),
1486
- 'label_manage_items' => array(
1487
- 'label' => __( 'Manage <span class="pods-slugged" data-sluggable="label">Items</span>', 'pods' ),
1488
- 'help' => __( 'help', 'pods' ),
1489
- 'type' => 'text',
1490
- 'default' => '',
1491
- 'object_type' => array( 'pod' ),
1492
- ),
1493
- 'label_reorder' => array(
1494
- 'label' => __( 'Reorder', 'pods' ),
1495
- 'help' => __( 'help', 'pods' ),
1496
- 'type' => 'text',
1497
- 'default' => '',
1498
- 'object_type' => array( 'pod' ),
1499
- ),
1500
- 'label_reorder_items' => array(
1501
- 'label' => __( 'Reorder <span class="pods-slugged" data-sluggable="label">Items</span>', 'pods' ),
1502
- 'help' => __( 'help', 'pods' ),
1503
- 'type' => 'text',
1504
- 'default' => '',
1505
- 'object_type' => array( 'pod' ),
1506
- ),
1507
- 'label_all_items' => array(
1508
- 'label' => __( 'All <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1509
- 'help' => __( 'help', 'pods' ),
1510
- 'type' => 'text',
1511
- 'default' => '',
1512
- ),
1513
- 'label_search' => array(
1514
- 'label' => __( 'Search', 'pods' ),
1515
- 'help' => __( 'help', 'pods' ),
1516
- 'type' => 'text',
1517
- 'default' => '',
1518
- 'object_type' => array( 'pod' ),
1519
- ),
1520
- 'label_search_items' => array(
1521
- 'label' => __( 'Search <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1522
- 'help' => __( 'help', 'pods' ),
1523
- 'type' => 'text',
1524
- 'default' => '',
1525
- ),
1526
- 'label_popular_items' => array(
1527
- 'label' => __( 'Popular <span class="pods-slugged" data-sluggable="label">Items</span>', 'pods' ),
1528
- 'help' => __( 'help', 'pods' ),
1529
- 'type' => 'text',
1530
- 'default' => '',
1531
- 'object_type' => array( 'taxonomy' ),
1532
- ),
1533
- // @todo Why was label_parent added previously? Can't find it in WP
1534
- 'label_parent' => array(
1535
- 'label' => __( 'Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1536
- 'help' => __( 'help', 'pods' ),
1537
- 'type' => 'text',
1538
- 'default' => '',
1539
- 'object_type' => array( 'post_type', 'pod' ),
1540
- ),
1541
- 'label_parent_item' => array(
1542
- 'label' => __( 'Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1543
- 'help' => __( 'help', 'pods' ),
1544
- 'type' => 'text',
1545
- 'default' => '',
1546
- 'object_type' => array( 'taxonomy' ),
1547
- ),
1548
- 'label_parent_item_colon' => array(
1549
- 'label' => __( 'Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>:', 'pods' ),
1550
- 'help' => __( 'help', 'pods' ),
1551
- 'type' => 'text',
1552
- 'default' => '',
1553
- ),
1554
- 'label_not_found' => array(
1555
- 'label' => __( 'Not Found', 'pods' ),
1556
- 'help' => __( 'help', 'pods' ),
1557
- 'type' => 'text',
1558
- 'default' => '',
1559
- ),
1560
- 'label_no_items_found' => array(
1561
- 'label' => __( 'No <span class="pods-slugged" data-sluggable="label_singular">Item</span> Found', 'pods' ),
1562
- 'help' => __( 'help', 'pods' ),
1563
- 'type' => 'text',
1564
- 'default' => '',
1565
- 'object_type' => array( 'pod' ),
1566
- ),
1567
- 'label_not_found_in_trash' => array(
1568
- 'label' => __( 'Not Found in Trash', 'pods' ),
1569
- 'help' => __( 'help', 'pods' ),
1570
- 'type' => 'text',
1571
- 'default' => '',
1572
- 'object_type' => array( 'post_type', 'pod' ),
1573
- ),
1574
- 'label_archives' => array(
1575
- 'label' => __( '<span class="pods-slugged" data-sluggable="label_singular">Item</span> Archives', 'pods' ),
1576
- 'help' => __( 'help', 'pods' ),
1577
- 'type' => 'text',
1578
- 'default' => '',
1579
- 'object_type' => array( 'post_type' ),
1580
- ),
1581
- 'label_attributes' => array(
1582
- 'label' => __( '<span class="pods-slugged" data-sluggable="label_singular">Item</span> Attributes', 'pods' ),
1583
- 'help' => __( 'help', 'pods' ),
1584
- 'type' => 'text',
1585
- 'default' => '',
1586
- 'object_type' => array( 'post_type' ),
1587
- ),
1588
- 'label_insert_into_item' => array(
1589
- 'label' => __( 'Insert into <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1590
- 'help' => __( 'help', 'pods' ),
1591
- 'type' => 'text',
1592
- 'default' => '',
1593
- 'object_type' => array( 'post_type' ),
1594
- ),
1595
- 'label_uploaded_to_this_item' => array(
1596
- 'label' => __( 'Uploaded to this <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1597
- 'help' => __( 'help', 'pods' ),
1598
- 'type' => 'text',
1599
- 'default' => '',
1600
- 'object_type' => array( 'post_type' ),
1601
- ),
1602
- 'label_featured_image' => array(
1603
- 'label' => __( 'Featured Image', 'pods' ),
1604
- 'help' => __( 'help', 'pods' ),
1605
- 'type' => 'text',
1606
- 'default' => '',
1607
- // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working
1608
- 'object_type' => array( 'post_type' ),
1609
- ),
1610
- 'label_set_featured_image' => array(
1611
- 'label' => __( 'Set featured Image', 'pods' ),
1612
- 'help' => __( 'help', 'pods' ),
1613
- 'type' => 'text',
1614
- 'default' => '',
1615
- // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working
1616
- 'object_type' => array( 'post_type' ),
1617
- ),
1618
- 'label_remove_featured_image' => array(
1619
- 'label' => __( 'Remove featured Image', 'pods' ),
1620
- 'help' => __( 'help', 'pods' ),
1621
- 'type' => 'text',
1622
- 'default' => '',
1623
- // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working
1624
- 'object_type' => array( 'post_type' ),
1625
- ),
1626
- 'label_use_featured_image' => array(
1627
- 'label' => __( 'Use as featured Image', 'pods' ),
1628
- 'help' => __( 'help', 'pods' ),
1629
- 'type' => 'text',
1630
- 'default' => '',
1631
- // 'depends-on' => array( 'supports_thumbnail' => true ), // @todo Dependency from other tabs not working
1632
- 'object_type' => array( 'post_type' ),
1633
- ),
1634
- 'label_filter_items_list' => array(
1635
- 'label' => __( 'Filter <span class="pods-slugged" data-sluggable="label">Items</span> lists', 'pods' ),
1636
- 'help' => __( 'help', 'pods' ),
1637
- 'type' => 'text',
1638
- 'default' => '',
1639
- 'object_type' => array( 'post_type' ),
1640
- ),
1641
- 'label_items_list_navigation' => array(
1642
- 'label' => __( '<span class="pods-slugged" data-sluggable="label">Items</span> list navigation', 'pods' ),
1643
- 'help' => __( 'help', 'pods' ),
1644
- 'type' => 'text',
1645
- 'default' => '',
1646
- 'object_type' => array( 'post_type', 'taxonomy' ),
1647
- ),
1648
- 'label_items_list' => array(
1649
- 'label' => __( '<span class="pods-slugged" data-sluggable="label">Items</span> list', 'pods' ),
1650
- 'help' => __( 'help', 'pods' ),
1651
- 'type' => 'text',
1652
- 'default' => '',
1653
- 'object_type' => array( 'post_type', 'taxonomy' ),
1654
- ),
1655
- 'label_separate_items_with_commas' => array(
1656
- 'label' => __( 'Separate <span class="pods-slugged-lower" data-sluggable="label">items</span> with commas', 'pods' ),
1657
- 'help' => __( 'help', 'pods' ),
1658
- 'type' => 'text',
1659
- 'default' => '',
1660
- 'object_type' => array( 'taxonomy' ),
1661
- ),
1662
- 'label_add_or_remove_items' => array(
1663
- 'label' => __( 'Add or remove <span class="pods-slugged-lower" data-sluggable="label">items</span>', 'pods' ),
1664
- 'help' => __( 'help', 'pods' ),
1665
- 'type' => 'text',
1666
- 'default' => '',
1667
- 'object_type' => array( 'taxonomy' ),
1668
- ),
1669
- 'label_choose_from_the_most_used' => array(
1670
- 'label' => __( 'Choose from the most used <span class="pods-slugged-lower" data-sluggable="label">items</span>', 'pods' ),
1671
- 'help' => __( 'help', 'pods' ),
1672
- 'type' => 'text',
1673
- 'default' => '',
1674
- 'object_type' => array( 'taxonomy' ),
1675
- ),
1676
- 'label_no_terms' => array(
1677
- 'label' => __( 'No <span class="pods-slugged-lower" data-sluggable="label">items</span>', 'pods' ),
1678
- 'help' => __( 'help', 'pods' ),
1679
- 'type' => 'text',
1680
- 'default' => '',
1681
- 'object_type' => array( 'taxonomy' ),
1682
- ),
1683
- 'label_item_published' => array(
1684
- 'label' => __( '<span class="pods-slugged" data-sluggable="label_singular">Item</span> Published.', 'pods' ),
1685
- 'help' => __( 'help', 'pods' ),
1686
- 'type' => 'text',
1687
- 'default' => '',
1688
- 'object_type' => array( 'post_type' ),
1689
- ),
1690
- 'label_item_published_privately' => array(
1691
- 'label' => __( '<span class="pods-slugged" data-sluggable="label_singular">Item</span> published privately.', 'pods' ),
1692
- 'help' => __( 'help', 'pods' ),
1693
- 'type' => 'text',
1694
- 'default' => '',
1695
- 'object_type' => array( 'post_type' ),
1696
- ),
1697
- 'label_item_reverted_to_draft' => array(
1698
- 'label' => __( '<span class="pods-slugged" data-sluggable="label_singular">Item</span> reverted to draft.', 'pods' ),
1699
- 'help' => __( 'help', 'pods' ),
1700
- 'type' => 'text',
1701
- 'default' => '',
1702
- 'object_type' => array( 'post_type' ),
1703
- ),
1704
- 'label_item_scheduled' => array(
1705
- 'label' => __( '<span class="pods-slugged" data-sluggable="label_singular">Item</span> scheduled.', 'pods' ),
1706
- 'help' => __( 'help', 'pods' ),
1707
- 'type' => 'text',
1708
- 'default' => '',
1709
- 'object_type' => array( 'post_type' ),
1710
- ),
1711
- 'label_item_updated' => array(
1712
- 'label' => __( '<span class="pods-slugged" data-sluggable="label_singular">Item</span> updated.', 'pods' ),
1713
- 'help' => __( 'help', 'pods' ),
1714
- 'type' => 'text',
1715
- 'default' => '',
1716
- 'object_type' => array( 'post_type' ),
1717
- ),
1718
- 'filter_by_date' => array(
1719
- 'label' => __( 'Filter by date', 'pods' ),
1720
- 'help' => __( 'help', 'pods' ),
1721
- 'type' => 'text',
1722
- 'default' => '',
1723
- 'object_type' => array( 'post_type' ),
1724
- ),
1725
- 'filter_by_item' => array(
1726
- 'label' => __( 'Filter by <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1727
- 'help' => __( 'help', 'pods' ),
1728
- 'type' => 'text',
1729
- 'default' => '',
1730
- 'object_type' => array( 'taxonomy' ),
1731
- ),
1732
- );
1733
 
1734
- $options['labels'] = array();
1735
 
1736
- /**
1737
- * Filter through all labels if they have an object_type set and match it against the current object type
1738
- */
1739
- foreach ( $labels as $label => $labeldata ) {
1740
- if ( array_key_exists( 'object_type', $labeldata ) ) {
1741
- if ( in_array( pods_v( 'type', $pod ), $labeldata['object_type'], true ) ) {
1742
- // Do not add the object_type to the actual label data
1743
- unset( $labeldata['object_type'] );
1744
- $options['labels'][ $label ] = $labeldata;
1745
- }
1746
- } else {
1747
- $options['labels'][ $label ] = $labeldata;
 
 
 
 
 
 
1748
  }
1749
- }
1750
- } elseif ( 'settings' === pods_v( 'type', $pod ) ) {
1751
-
1752
- $options['labels'] = array(
1753
- 'label' => array(
1754
- 'label' => __( 'Page Title', 'pods' ),
1755
- 'help' => __( 'help', 'pods' ),
1756
- 'type' => 'text',
1757
- 'default' => str_replace( '_', ' ', pods_v( 'name', $pod ) ),
1758
- 'text_max_length' => 30,
1759
- ),
1760
- 'menu_name' => array(
1761
- 'label' => __( 'Menu Name', 'pods' ),
1762
- 'help' => __( 'help', 'pods' ),
1763
- 'type' => 'text',
1764
- 'default' => pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', pods_v( 'name', $pod ) ) ) ),
1765
- 'text_max_length' => 30,
1766
- ),
1767
- );
1768
- }//end if
1769
 
1770
- if ( 'post_type' === $pod['type'] ) {
1771
- $options['admin-ui'] = array(
1772
- 'description' => array(
1773
- 'label' => __( 'Post Type Description', 'pods' ),
1774
- 'help' => __( 'A short descriptive summary of what the post type is.', 'pods' ),
1775
- 'type' => 'text',
1776
- 'default' => '',
1777
- ),
1778
- 'show_ui' => array(
1779
- 'label' => __( 'Show Admin UI', 'pods' ),
1780
- 'help' => __( 'Whether to generate a default UI for managing this post type in the admin.', 'pods' ),
1781
- 'type' => 'boolean',
1782
- 'default' => pods_v( 'public', $pod, true ),
1783
- 'boolean_yes_label' => '',
1784
- ),
1785
- 'show_in_menu' => array(
1786
- 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ),
1787
- 'help' => __( 'Whether to show the post type in the admin menu.', 'pods' ),
1788
- 'type' => 'boolean',
1789
- 'default' => pods_v( 'public', $pod, true ),
1790
- 'dependency' => true,
1791
- 'boolean_yes_label' => '',
1792
- ),
1793
- 'menu_location_custom' => array(
1794
- 'label' => __( 'Parent Menu ID (optional)', 'pods' ),
1795
- 'help' => __( 'help', 'pods' ),
1796
- 'type' => 'text',
1797
- 'depends-on' => array( 'show_in_menu' => true ),
1798
- ),
1799
- 'menu_name' => array(
1800
- 'label' => __( 'Menu Name', 'pods' ),
1801
- 'help' => __( 'help', 'pods' ),
1802
- 'type' => 'text',
1803
- 'default' => '',
1804
- 'depends-on' => array( 'show_in_menu' => true ),
1805
- ),
1806
- 'menu_position' => array(
1807
- 'label' => __( 'Menu Position', 'pods' ),
1808
- 'help' => __( 'help', 'pods' ),
1809
- 'type' => 'number',
1810
- 'number_decimals' => 2,
1811
- 'number_format' => '9999.99',
1812
- 'number_format_soft' => 1,
1813
- 'default' => 0,
1814
- 'depends-on' => array( 'show_in_menu' => true ),
1815
- ),
1816
- 'menu_icon' => array(
1817
- 'label' => __( 'Menu Icon', 'pods' ),
1818
- 'help' => __( 'URL or Dashicon name for the menu icon. You may specify the path to the icon using one of the <a href="https://pods.io/docs/build/special-magic-tags/#site-tags" target="_blank" rel="noopener noreferrer">site tag</a> type <a href="https://pods.io/docs/build/special-magic-tags/" target="_blank" rel="noopener noreferrer">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" rel="noopener noreferrer">Dashicon</a>. For example, to use the empty star icon, use "dashicons-star-empty".', 'pods' ),
1819
- 'type' => 'text',
1820
- 'default' => '',
1821
- 'depends-on' => array( 'show_in_menu' => true ),
1822
- ),
1823
- 'show_in_nav_menus' => array(
1824
- 'label' => __( 'Show in Navigation Menus', 'pods' ),
1825
- 'help' => __( 'help', 'pods' ),
1826
- 'type' => 'boolean',
1827
- 'default' => true,
1828
- 'boolean_yes_label' => '',
1829
- ),
1830
- 'show_in_admin_bar' => array(
1831
- 'label' => __( 'Show in Admin Bar "New" Menu', 'pods' ),
1832
- 'help' => __( 'help', 'pods' ),
1833
- 'type' => 'boolean',
1834
- 'default' => true,
1835
- 'dependency' => true,
1836
- 'boolean_yes_label' => '',
1837
- ),
1838
- 'name_admin_bar' => array(
1839
- 'label' => __( 'Admin bar name', 'pods' ),
1840
- 'help' => __( 'Defaults to singular name', 'pods' ),
1841
- 'type' => 'text',
1842
- 'default' => '',
1843
- 'depends-on' => array( 'show_in_admin_bar' => true ),
1844
- ),
1845
- );
1846
 
1847
- $post_type_name = pods_v( 'name', $pod, 'post_type', true );
 
1848
 
1849
- $options['advanced'] = array(
1850
- 'public' => array(
1851
- 'label' => __( 'Public', 'pods' ),
1852
- 'help' => __( 'help', 'pods' ),
1853
- 'type' => 'boolean',
1854
- 'default' => true,
1855
- 'boolean_yes_label' => '',
1856
- ),
1857
- 'publicly_queryable' => array(
1858
- 'label' => __( 'Publicly Queryable', 'pods' ),
1859
- 'help' => __( 'help', 'pods' ),
1860
- 'type' => 'boolean',
1861
- 'default' => pods_v( 'public', $pod, true ),
1862
- 'boolean_yes_label' => '',
1863
- ),
1864
- 'exclude_from_search' => array(
1865
- 'label' => __( 'Exclude from Search', 'pods' ),
1866
- 'help' => __( 'help', 'pods' ),
1867
- 'type' => 'boolean',
1868
- 'default' => ! pods_v( 'public', $pod, true ),
1869
- 'boolean_yes_label' => '',
1870
- ),
1871
- 'capability_type' => array(
1872
- 'label' => __( 'User Capability', 'pods' ),
1873
- 'help' => __( 'Uses these capabilties for access to this post type: edit_{capability}, read_{capability}, and delete_{capability}', 'pods' ),
1874
- 'type' => 'pick',
1875
- 'default' => 'post',
1876
- 'data' => array(
1877
- 'post' => 'post',
1878
- 'page' => 'page',
1879
- 'custom' => __( 'Custom Capability', 'pods' ),
1880
- ),
1881
- 'dependency' => true,
1882
- ),
1883
- 'capability_type_custom' => array(
1884
- 'label' => __( 'Custom User Capability', 'pods' ),
1885
- 'help' => __( 'help', 'pods' ),
1886
- 'type' => 'text',
1887
- 'default' => pods_v( 'name', $pod ),
1888
- 'depends-on' => array( 'capability_type' => 'custom' ),
1889
- ),
1890
- 'capability_type_extra' => array(
1891
- 'label' => __( 'Additional User Capabilities', 'pods' ),
1892
- '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' ),
1893
- 'type' => 'boolean',
1894
- 'default' => true,
1895
- 'boolean_yes_label' => '',
1896
- ),
1897
- 'has_archive' => array(
1898
- 'label' => __( 'Enable Archive Page', 'pods' ),
1899
- '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' ),
1900
- 'type' => 'boolean',
1901
- 'default' => false,
1902
- 'dependency' => true,
1903
- 'boolean_yes_label' => '',
1904
- ),
1905
- 'has_archive_slug' => array(
1906
- 'label' => __( 'Archive Page Slug Override', 'pods' ),
1907
- 'help' => __( 'If archive page is enabled, you can override the slug used by WordPress, which defaults to the name of the post type.', 'pods' ),
1908
- 'type' => 'text',
1909
- 'default' => '',
1910
- 'depends-on' => array( 'has_archive' => true ),
1911
- ),
1912
- 'hierarchical' => array(
1913
- 'label' => __( 'Hierarchical', 'pods' ),
1914
- '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' ),
1915
- 'type' => 'boolean',
1916
- 'default' => false,
1917
- 'dependency' => true,
1918
- 'boolean_yes_label' => '',
1919
- ),
1920
- 'label_parent_item_colon' => array(
1921
- 'label' => __( '<strong>Label: </strong> Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
1922
- 'help' => __( 'help', 'pods' ),
1923
- 'type' => 'text',
1924
- 'default' => '',
1925
- 'depends-on' => array( 'hierarchical' => true ),
1926
- ),
1927
- 'label_parent' => array(
1928
- 'label' => __( '<strong>Label: </strong> Parent', 'pods' ),
1929
- 'help' => __( 'help', 'pods' ),
1930
- 'type' => 'text',
1931
- 'default' => '',
1932
- 'depends-on' => array( 'hierarchical' => true ),
1933
- ),
1934
- 'rewrite' => array(
1935
- 'label' => __( 'Rewrite', 'pods' ),
1936
- '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' ),
1937
- 'type' => 'boolean',
1938
- 'default' => true,
1939
- 'dependency' => true,
1940
- 'boolean_yes_label' => '',
1941
- ),
1942
- 'rewrite_custom_slug' => array(
1943
- 'label' => __( 'Custom Rewrite Slug', 'pods' ),
1944
- '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' ),
1945
- 'type' => 'text',
1946
- 'default' => '',
1947
- 'depends-on' => array( 'rewrite' => true ),
1948
- ),
1949
- 'rewrite_with_front' => array(
1950
- 'label' => __( 'Rewrite with Front', 'pods' ),
1951
- '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' ),
1952
- 'type' => 'boolean',
1953
- 'default' => true,
1954
- 'depends-on' => array( 'rewrite' => true ),
1955
- 'boolean_yes_label' => '',
1956
- ),
1957
- 'rewrite_feeds' => array(
1958
- 'label' => __( 'Rewrite Feeds', 'pods' ),
1959
- 'help' => __( 'help', 'pods' ),
1960
- 'type' => 'boolean',
1961
- 'default' => false,
1962
- 'depends-on' => array( 'rewrite' => true ),
1963
- 'boolean_yes_label' => '',
1964
- ),
1965
- 'rewrite_pages' => array(
1966
- 'label' => __( 'Rewrite Pages', 'pods' ),
1967
- 'help' => __( 'help', 'pods' ),
1968
- 'type' => 'boolean',
1969
- 'default' => true,
1970
- 'depends-on' => array( 'rewrite' => true ),
1971
- 'boolean_yes_label' => '',
1972
- ),
1973
- 'query_var' => array(
1974
- 'label' => __( 'Query Var', 'pods' ),
1975
- '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' ),
1976
- 'type' => 'boolean',
1977
- 'default' => true,
1978
- 'boolean_yes_label' => '',
1979
- ),
1980
- 'can_export' => array(
1981
- 'label' => __( 'Exportable', 'pods' ),
1982
- 'help' => __( 'help', 'pods' ),
1983
- 'type' => 'boolean',
1984
- 'default' => true,
1985
- 'boolean_yes_label' => '',
1986
- ),
1987
- 'default_status' => array(
1988
- 'label' => __( 'Default Status', 'pods' ),
1989
- 'help' => __( 'help', 'pods' ),
1990
- 'type' => 'pick',
1991
- 'pick_object' => 'post-status',
1992
- 'default' => apply_filters( "pods_api_default_status_{$post_type_name}", 'draft', $pod ),
1993
- ),
1994
- );
1995
- } elseif ( 'taxonomy' === $pod['type'] ) {
1996
- $options['admin-ui'] = array(
1997
- 'description' => array(
1998
- 'label' => __( 'Taxonomy Description', 'pods' ),
1999
- 'help' => __( 'A short descriptive summary of what the taxonomy is.', 'pods' ),
2000
- 'type' => 'text',
2001
- 'default' => '',
2002
- ),
2003
- 'show_ui' => array(
2004
- 'label' => __( 'Show Admin UI', 'pods' ),
2005
- 'help' => __( 'Whether to generate a default UI for managing this taxonomy.', 'pods' ),
2006
- 'type' => 'boolean',
2007
- 'default' => pods_v( 'public', $pod, true ),
2008
- 'dependency' => true,
2009
- 'boolean_yes_label' => '',
2010
- ),
2011
- 'show_in_menu' => array(
2012
- 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ),
2013
- 'help' => __( 'Whether to show the taxonomy in the admin menu.', 'pods' ),
2014
- 'type' => 'boolean',
2015
- 'default' => pods_v( 'public', $pod, true ),
2016
- 'dependency' => true,
2017
- 'depends-on' => array( 'show_ui' => true ),
2018
- 'boolean_yes_label' => '',
2019
- ),
2020
- 'menu_name' => array(
2021
- 'label' => __( 'Menu Name', 'pods' ),
2022
- 'help' => __( 'help', 'pods' ),
2023
- 'type' => 'text',
2024
- 'default' => '',
2025
- 'depends-on' => array( 'show_ui' => true ),
2026
- ),
2027
- 'menu_location' => array(
2028
- 'label' => __( 'Menu Location', 'pods' ),
2029
- 'help' => __( 'help', 'pods' ),
2030
- 'type' => 'pick',
2031
- 'default' => 'default',
2032
- 'depends-on' => array( 'show_ui' => true ),
2033
- 'data' => array(
2034
- 'default' => __( 'Default - Add to associated Post Type(s) menus', 'pods' ),
2035
- 'settings' => __( 'Add a submenu item to Settings menu', 'pods' ),
2036
- 'appearances' => __( 'Add a submenu item to Appearances menu', 'pods' ),
2037
- 'submenu' => __( 'Add a submenu item to another menu', 'pods' ),
2038
- 'objects' => __( 'Make a new menu item', 'pods' ),
2039
- 'top' => __( 'Make a new menu item below Settings', 'pods' ),
2040
- ),
2041
- 'dependency' => true,
2042
- ),
2043
- 'menu_location_custom' => array(
2044
- 'label' => __( 'Custom Menu Location', 'pods' ),
2045
- 'help' => __( 'help', 'pods' ),
2046
- 'type' => 'text',
2047
- 'depends-on' => array( 'menu_location' => 'submenu' ),
2048
- ),
2049
- 'menu_position' => array(
2050
- 'label' => __( 'Menu Position', 'pods' ),
2051
- 'help' => __( 'help', 'pods' ),
2052
- 'type' => 'number',
2053
- 'number_decimals' => 2,
2054
- 'number_format' => '9999.99',
2055
- 'number_format_soft' => 1,
2056
- 'default' => 0,
2057
- 'depends-on' => array( 'menu_location' => array( 'objects', 'top' ) ),
2058
- ),
2059
- 'menu_icon' => array(
2060
- 'label' => __( 'Menu Icon URL', 'pods' ),
2061
- 'help' => __( 'help', 'pods' ),
2062
- 'type' => 'text',
2063
- 'default' => '',
2064
- 'depends-on' => array( 'menu_location' => array( 'objects', 'top' ) ),
2065
- ),
2066
- 'show_in_nav_menus' => array(
2067
- 'label' => __( 'Show in Navigation Menus', 'pods' ),
2068
- 'help' => __( 'help', 'pods' ),
2069
- 'type' => 'boolean',
2070
- 'default' => pods_v( 'public', $pod, true ),
2071
- 'boolean_yes_label' => '',
2072
- ),
2073
- 'show_tagcloud' => array(
2074
- 'label' => __( 'Allow in Tagcloud Widget', 'pods' ),
2075
- 'help' => __( 'help', 'pods' ),
2076
- 'type' => 'boolean',
2077
- 'default' => pods_v( 'show_ui', $pod, pods_v( 'public', $pod, true ) ),
2078
- 'boolean_yes_label' => '',
2079
- ),
2080
- // @todo check https://core.trac.wordpress.org/ticket/36964
2081
- 'show_tagcloud_in_edit' => array(
2082
- 'label' => __( 'Allow Tagcloud on term edit pages', 'pods' ),
2083
- 'help' => __( 'help', 'pods' ),
2084
- 'type' => 'boolean',
2085
- 'default' => pods_v( 'show_ui', $pod, pods_v( 'show_tagcloud', $pod, true ) ),
2086
- 'boolean_yes_label' => '',
2087
- ),
2088
- 'show_in_quick_edit' => array(
2089
- 'label' => __( 'Allow in quick/bulk edit panel', 'pods' ),
2090
- 'help' => __( 'help', 'pods' ),
2091
- 'type' => 'boolean',
2092
- 'default' => pods_v( 'show_ui', $pod, pods_v( 'public', $pod, true ) ),
2093
- 'boolean_yes_label' => '',
2094
- ),
2095
- );
2096
 
2097
- $options['admin-ui']['show_admin_column'] = array(
2098
- 'label' => __( 'Show Taxonomy column on Post Types', 'pods' ),
2099
- 'help' => __( 'Whether to add a column for this taxonomy on the associated post types manage screens', 'pods' ),
2100
- 'type' => 'boolean',
2101
- 'default' => false,
2102
- 'boolean_yes_label' => '',
2103
- );
2104
 
2105
- // Integration for Single Value Taxonomy UI
2106
- if ( function_exists( 'tax_single_value_meta_box' ) ) {
2107
- $options['admin-ui']['single_value'] = array(
2108
- 'label' => __( 'Single Value Taxonomy', 'pods' ),
2109
- 'help' => __( 'Use a drop-down for the input instead of the WordPress default', 'pods' ),
2110
- 'type' => 'boolean',
2111
- 'default' => false,
2112
- 'boolean_yes_label' => '',
2113
- );
2114
 
2115
- $options['admin-ui']['single_value_required'] = array(
2116
- 'label' => __( 'Single Value Taxonomy - Required', 'pods' ),
2117
- 'help' => __( 'A term will be selected by default in the Post Editor, not optional', 'pods' ),
2118
- 'type' => 'boolean',
2119
- 'default' => false,
2120
- 'boolean_yes_label' => '',
2121
- );
2122
  }
2123
 
2124
- $options['advanced'] = array(
2125
- 'public' => array(
2126
- 'label' => __( 'Public', 'pods' ),
2127
- 'help' => __( 'help', 'pods' ),
2128
- 'type' => 'boolean',
2129
- 'default' => true,
2130
- 'boolean_yes_label' => '',
2131
- ),
2132
- 'hierarchical' => array(
2133
- 'label' => __( 'Hierarchical', 'pods' ),
2134
- 'help' => __( 'Hierarchical taxonomies will have a list with checkboxes to select an existing category in the taxonomy admin box on the post edit page (like default post categories). Non-hierarchical taxonomies will just have an empty text field to type-in taxonomy terms to associate with the post (like default post tags).', 'pods' ),
2135
- 'type' => 'boolean',
2136
- 'default' => true,
2137
- 'dependency' => true,
2138
- 'boolean_yes_label' => '',
2139
- ),
2140
- 'label_parent_item_colon' => array(
2141
- 'label' => __( '<strong>Label: </strong> Parent <span class="pods-slugged" data-sluggable="label_singular">Item</span>', 'pods' ),
2142
- 'help' => __( 'help', 'pods' ),
2143
- 'type' => 'text',
2144
- 'default' => '',
2145
- 'depends-on' => array( 'hierarchical' => true ),
2146
- ),
2147
- 'label_parent' => array(
2148
- 'label' => __( '<strong>Label: </strong> Parent', 'pods' ),
2149
- 'help' => __( 'help', 'pods' ),
2150
- 'type' => 'text',
2151
- 'default' => '',
2152
- 'depends-on' => array( 'hierarchical' => true ),
2153
- ),
2154
- 'label_no_terms' => array(
2155
- 'label' => __( '<strong>Label: </strong> No <span class="pods-slugged" data-sluggable="label">Items</span>', 'pods' ),
2156
- 'help' => __( 'help', 'pods' ),
2157
- 'type' => 'text',
2158
- 'default' => '',
2159
- 'depends-on' => array( 'hierarchical' => true ),
2160
- ),
2161
- 'rewrite' => array(
2162
- 'label' => __( 'Rewrite', 'pods' ),
2163
- 'help' => __( 'help', 'pods' ),
2164
- 'type' => 'boolean',
2165
- 'default' => true,
2166
- 'dependency' => true,
2167
- 'boolean_yes_label' => '',
2168
- ),
2169
- 'rewrite_custom_slug' => array(
2170
- 'label' => __( 'Custom Rewrite Slug', 'pods' ),
2171
- 'help' => __( 'help', 'pods' ),
2172
- 'type' => 'text',
2173
- 'default' => '',
2174
- 'depends-on' => array( 'rewrite' => true ),
2175
- ),
2176
- 'rewrite_with_front' => array(
2177
- 'label' => __( 'Rewrite with Front', 'pods' ),
2178
- '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' ),
2179
- 'type' => 'boolean',
2180
- 'default' => true,
2181
- 'boolean_yes_label' => '',
2182
- 'depends-on' => array( 'rewrite' => true ),
2183
- ),
2184
- 'rewrite_hierarchical' => array(
2185
- 'label' => __( 'Hierarchical Permalinks', 'pods' ),
2186
- 'help' => __( 'help', 'pods' ),
2187
- 'type' => 'boolean',
2188
- 'default' => true,
2189
- 'boolean_yes_label' => '',
2190
- 'depends-on' => array( 'rewrite' => true ),
2191
- ),
2192
- 'capability_type' => array(
2193
- 'label' => __( 'User Capability', 'pods' ),
2194
- 'help' => __( 'Uses WordPress term capabilities by default', 'pods' ),
2195
- 'type' => 'pick',
2196
- 'default' => 'default',
2197
- 'data' => array(
2198
- 'default' => 'Default',
2199
- 'custom' => __( 'Custom Capability', 'pods' ),
2200
- ),
2201
- 'dependency' => true,
2202
- ),
2203
- 'capability_type_custom' => array(
2204
- 'label' => __( 'Custom User Capability', 'pods' ),
2205
- 'help' => __( 'Enables additional capabilities for this Taxonomy including: manage_{capability}_terms, edit_{capability}_terms, assign_{capability}_terms, and delete_{capability}_terms', 'pods' ),
2206
- 'type' => 'text',
2207
- 'default' => pods_v( 'name', $pod ),
2208
- 'depends-on' => array( 'capability_type' => 'custom' ),
2209
- ),
2210
- 'query_var' => array(
2211
- 'label' => __( 'Query Var', 'pods' ),
2212
- 'help' => __( 'help', 'pods' ),
2213
- 'type' => 'boolean',
2214
- 'default' => false,
2215
- 'dependency' => true,
2216
- 'boolean_yes_label' => '',
2217
- ),
2218
- 'query_var_string' => array(
2219
- 'label' => __( 'Custom Query Var Name', 'pods' ),
2220
- 'help' => __( 'help', 'pods' ),
2221
- 'type' => 'text',
2222
- 'default' => '',
2223
- 'depends-on' => array( 'query_var' => true ),
2224
- ),
2225
- 'sort' => array(
2226
- 'label' => __( 'Remember order saved on Post Types', 'pods' ),
2227
- 'help' => __( 'help', 'pods' ),
2228
- 'type' => 'boolean',
2229
- 'default' => false,
2230
- 'boolean_yes_label' => '',
2231
- ),
2232
- 'update_count_callback' => array(
2233
- 'label' => __( 'Function to call when updating counts', 'pods' ),
2234
- 'help' => __( 'help', 'pods' ),
2235
- 'type' => 'text',
2236
- 'default' => '',
2237
- ),
2238
- );
2239
- } elseif ( 'settings' === $pod['type'] ) {
2240
- $options['admin-ui'] = array(
2241
- 'ui_style' => array(
2242
- 'label' => __( 'Admin UI Style', 'pods' ),
2243
- 'help' => __( 'help', 'pods' ),
2244
- 'type' => 'pick',
2245
- 'default' => 'settings',
2246
- 'data' => array(
2247
- 'settings' => __( 'Normal Settings Form', 'pods' ),
2248
- 'post_type' => __( 'Post Type UI', 'pods' ),
2249
- 'custom' => __( 'Custom (hook into pods_admin_ui_custom or pods_admin_ui_custom_{podname} action)', 'pods' ),
2250
- ),
2251
- 'dependency' => true,
2252
- ),
2253
- 'menu_location' => array(
2254
- 'label' => __( 'Menu Location', 'pods' ),
2255
- 'help' => __( 'help', 'pods' ),
2256
- 'type' => 'pick',
2257
- 'default' => 'settings',
2258
- 'data' => array(
2259
- 'settings' => __( 'Add a submenu item to Settings menu', 'pods' ),
2260
- 'appearances' => __( 'Add a submenu item to Appearances menu', 'pods' ),
2261
- 'submenu' => __( 'Add a submenu item to another menu', 'pods' ),
2262
- 'top' => __( 'Make a new menu item below Settings', 'pods' ),
2263
- ),
2264
- 'dependency' => true,
2265
- ),
2266
- 'menu_location_custom' => array(
2267
- 'label' => __( 'Custom Menu Location', 'pods' ),
2268
- 'help' => __( 'help', 'pods' ),
2269
- 'type' => 'text',
2270
- 'depends-on' => array( 'menu_location' => 'submenu' ),
2271
- ),
2272
- 'menu_position' => array(
2273
- 'label' => __( 'Menu Position', 'pods' ),
2274
- 'help' => __( 'help', 'pods' ),
2275
- 'type' => 'number',
2276
- 'number_decimals' => 2,
2277
- 'number_format' => '9999.99',
2278
- 'number_format_soft' => 1,
2279
- 'default' => 0,
2280
- 'depends-on' => array( 'menu_location' => 'top' ),
2281
- ),
2282
- 'menu_icon' => array(
2283
- 'label' => __( 'Menu Icon URL', 'pods' ),
2284
- 'help' => __( 'help', 'pods' ),
2285
- 'type' => 'text',
2286
- 'default' => '',
2287
- 'depends-on' => array( 'menu_location' => 'top' ),
2288
- ),
2289
- );
2290
-
2291
- // @todo fill this in
2292
- $options['advanced'] = array(
2293
- 'temporary' => 'This type has the fields hardcoded',
2294
- // :(
2295
- );
2296
- } elseif ( 'pod' === $pod['type'] ) {
2297
- $actions_enabled = array(
2298
- 'add',
2299
- 'edit',
2300
- 'duplicate',
2301
- 'delete',
2302
- );
2303
-
2304
- if ( 1 === (int) pods_v( 'ui_export', $pod ) ) {
2305
- $actions_enabled = array(
2306
- 'add',
2307
- 'edit',
2308
- 'duplicate',
2309
- 'delete',
2310
- 'export',
2311
- );
2312
- }
2313
-
2314
- $options['admin-ui'] = array(
2315
- 'ui_style' => array(
2316
- 'label' => __( 'Admin UI Style', 'pods' ),
2317
- 'help' => __( 'help', 'pods' ),
2318
- 'type' => 'pick',
2319
- 'default' => 'settings',
2320
- 'data' => array(
2321
- 'post_type' => __( 'Normal (Looks like the Post Type UI)', 'pods' ),
2322
- 'custom' => __( 'Custom (hook into pods_admin_ui_custom or pods_admin_ui_custom_{podname} action)', 'pods' ),
2323
- ),
2324
- 'dependency' => true,
2325
- ),
2326
- 'show_in_menu' => array(
2327
- 'label' => __( 'Show Admin Menu in Dashboard', 'pods' ),
2328
- 'help' => __( 'help', 'pods' ),
2329
- 'type' => 'boolean',
2330
- 'default' => false,
2331
- 'boolean_yes_label' => '',
2332
- 'dependency' => true,
2333
- ),
2334
- 'menu_location_custom' => array(
2335
- 'label' => __( 'Parent Menu ID (optional)', 'pods' ),
2336
- 'help' => __( 'help', 'pods' ),
2337
- 'type' => 'text',
2338
- 'depends-on' => array( 'show_in_menu' => true ),
2339
- ),
2340
- 'menu_position' => array(
2341
- 'label' => __( 'Menu Position', 'pods' ),
2342
- 'help' => __( 'help', 'pods' ),
2343
- 'type' => 'number',
2344
- 'number_decimals' => 2,
2345
- 'number_format' => '9999.99',
2346
- 'number_format_soft' => 1,
2347
- 'default' => 0,
2348
- 'depends-on' => array( 'show_in_menu' => true ),
2349
- ),
2350
- 'menu_icon' => array(
2351
- 'label' => __( 'Menu Icon URL', 'pods' ),
2352
- 'help' => __( 'This is the icon shown to the left of the menu text for this content type.', 'pods' ),
2353
- 'type' => 'text',
2354
- 'default' => '',
2355
- 'depends-on' => array( 'show_in_menu' => true ),
2356
- ),
2357
- 'ui_icon' => array(
2358
- 'label' => __( 'Header Icon', 'pods' ),
2359
- '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' ),
2360
- 'type' => 'file',
2361
- 'default' => '',
2362
- 'file_edit_title' => 0,
2363
- 'depends-on' => array( 'show_in_menu' => true ),
2364
- ),
2365
- 'ui_actions_enabled' => array(
2366
- 'label' => __( 'Actions Available', 'pods' ),
2367
- 'help' => __( 'help', 'pods' ),
2368
- 'type' => 'pick',
2369
- 'default' => $actions_enabled,
2370
- 'data' => array(
2371
- 'add' => __( 'Add New', 'pods' ),
2372
- 'edit' => __( 'Edit', 'pods' ),
2373
- 'duplicate' => __( 'Duplicate', 'pods' ),
2374
- 'delete' => __( 'Delete', 'pods' ),
2375
- 'reorder' => __( 'Reorder', 'pods' ),
2376
- 'export' => __( 'Export', 'pods' ),
2377
- ),
2378
- 'pick_format_type' => 'multi',
2379
- 'dependency' => true,
2380
- ),
2381
- 'ui_reorder_field' => array(
2382
- 'label' => __( 'Reorder Field', 'pods' ),
2383
- 'help' => __( 'This is the field that will be reordered on, it should be numeric.', 'pods' ),
2384
- 'type' => 'text',
2385
- 'default' => 'menu_order',
2386
- 'depends-on' => array( 'ui_actions_enabled' => 'reorder' ),
2387
- ),
2388
- 'ui_fields_manage' => array(
2389
- 'label' => __( 'Admin Table Columns', 'pods' ),
2390
- 'help' => __( 'help', 'pods' ),
2391
- 'type' => 'pick',
2392
- 'default' => array(),
2393
- 'data' => array(),
2394
- 'pick_format_type' => 'multi',
2395
- ),
2396
- 'ui_filters' => array(
2397
- 'label' => __( 'Search Filters', 'pods' ),
2398
- 'help' => __( 'help', 'pods' ),
2399
- 'type' => 'pick',
2400
- 'default' => array(),
2401
- 'data' => array(),
2402
- 'pick_format_type' => 'multi',
2403
- ),
2404
- );
2405
-
2406
- if ( ! empty( $pod['fields'] ) ) {
2407
- if ( isset( $pod['fields'][ pods_v( 'pod_index', $pod, 'name' ) ] ) ) {
2408
- $options['admin-ui']['ui_fields_manage']['default'][] = pods_v( 'pod_index', $pod, 'name' );
2409
- }
2410
-
2411
- if ( isset( $pod['fields']['modified'] ) ) {
2412
- $options['admin-ui']['ui_fields_manage']['default'][] = 'modified';
2413
- }
2414
-
2415
- foreach ( $pod['fields'] as $field ) {
2416
- $type = '';
2417
-
2418
- if ( isset( $field_types[ $field['type'] ] ) ) {
2419
- $type = ' <small>(' . $field_types[ $field['type'] ]['label'] . ')</small>';
2420
- }
2421
 
2422
- $options['admin-ui']['ui_fields_manage']['data'][ $field['name'] ] = $field['label'] . $type;
2423
- $options['admin-ui']['ui_filters']['data'][ $field['name'] ] = $field['label'] . $type;
2424
- }
 
 
 
 
2425
 
2426
- $options['admin-ui']['ui_fields_manage']['data']['id'] = 'ID';
2427
- } else {
2428
- unset( $options['admin-ui']['ui_fields_manage'] );
2429
- unset( $options['admin-ui']['ui_filters'] );
2430
- }//end if
2431
 
2432
- // @todo fill this in
2433
- $options['advanced'] = array(
2434
- 'temporary' => 'This type has the fields hardcoded',
2435
- // :(
2436
- );
2437
- }//end if
2438
 
2439
- $pod_type = $pod['type'];
2440
- $pod_name = $pod['name'];
2441
 
2442
- /**
2443
- * Add admin fields to the Pods editor for a specific Pod
2444
- *
2445
- * @param array $options The Options fields.
2446
- * @param object $pod Current Pods object.
2447
- *
2448
- * @since unkown
2449
- */
2450
- $options = apply_filters( "pods_admin_setup_edit_options_{$pod_type}_{$pod_name}", $options, $pod );
2451
 
2452
- /**
2453
- * Add admin fields to the Pods editor for any Pod of a specific content type.
2454
- *
2455
- * @param array $options The Options fields.
2456
- * @param object $pod Current Pods object.
2457
- */
2458
- $options = apply_filters( "pods_admin_setup_edit_options_{$pod_type}", $options, $pod );
2459
 
2460
- /**
2461
- * Add admin fields to the Pods editor for all Pods
2462
- *
2463
- * @param array $options The Options fields.
2464
- * @param object $pod Current Pods object.
2465
- */
2466
- $options = apply_filters( 'pods_admin_setup_edit_options', $options, $pod );
2467
 
2468
- return $options;
2469
  }
2470
 
2471
  /**
2472
- * Get list of Pod field option tabs
2473
  *
2474
- * @param array $pod Pod options.
2475
  *
2476
- * @return array
 
 
2477
  */
2478
- public function admin_setup_edit_field_tabs( $pod ) {
2479
-
2480
- $core_tabs = array(
2481
- 'basic' => __( 'Basic', 'pods' ),
2482
- 'additional-field' => __( 'Additional Field Options', 'pods' ),
2483
- 'advanced' => __( 'Advanced', 'pods' ),
2484
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2485
 
2486
  /**
2487
- * Field option tabs
2488
  *
2489
- * Use to add new tabs, default tabs are added after this filter (IE you can't remove/modify them with this, kthanksbye).
2490
- *
2491
- * @since unknown
2492
- *
2493
- * @param array $tabs Tabs to add, starts empty.
2494
- * @param object|Pod $pod Current Pods object.
2495
  */
2496
- $tabs = apply_filters( 'pods_admin_setup_edit_field_tabs', array(), $pod );
2497
-
2498
- $tabs = array_merge( $core_tabs, $tabs );
2499
 
2500
- return $tabs;
2501
  }
2502
 
2503
  /**
2504
- * Get list of Pod field options
2505
  *
2506
- * @param array $pod Pod options.
2507
  *
2508
- * @return array
 
 
 
 
2509
  */
2510
- public function admin_setup_edit_field_options( $pod ) {
 
2511
 
2512
- $options = array();
 
2513
 
2514
- $options['additional-field'] = array();
 
2515
 
2516
- $field_types = PodsForm::field_types();
 
 
 
2517
 
2518
- foreach ( $field_types as $type => $field_type_data ) {
2519
- /**
2520
- * @var $field_type PodsField
2521
- */
2522
- $field_type = PodsForm::field_loader( $type, $field_type_data['file'] );
 
 
 
 
 
2523
 
2524
- $field_type_vars = get_class_vars( get_class( $field_type ) );
2525
 
2526
- if ( ! isset( $field_type_vars['pod_types'] ) ) {
2527
- $field_type_vars['pod_types'] = true;
 
 
 
 
 
 
 
 
 
 
 
2528
  }
2529
 
2530
- $options['additional-field'][ $type ] = array();
2531
 
2532
- // Only show supported field types
2533
- if ( true !== $field_type_vars['pod_types'] ) {
2534
- if ( empty( $field_type_vars['pod_types'] ) ) {
2535
- continue;
2536
- } elseif ( is_array( $field_type_vars['pod_types'] ) && ! in_array( pods_v( 'type', $pod ), $field_type_vars['pod_types'], true ) ) {
2537
- continue;
2538
- } elseif ( ! is_array( $field_type_vars['pod_types'] ) && pods_v( 'type', $pod ) !== $field_type_vars['pod_types'] ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2539
  continue;
2540
  }
2541
- }
2542
 
2543
- $options['additional-field'][ $type ] = PodsForm::ui_options( $type );
 
 
2544
 
2545
- /**
2546
- * Modify Additional Field Options tab
2547
- *
2548
- * @since 2.7.0
2549
- *
2550
- * @param array $options Additional field type options,
2551
- * @param string $type Field type,
2552
- * @param array $options Tabs, indexed by label,
2553
- * @param object|Pods $pod Pods object for the Pod this UI is for.
2554
- */
2555
- $options['additional-field'][ $type ] = apply_filters( "pods_admin_setup_edit_{$type}_additional_field_options", $options['additional-field'][ $type ], $type, $options, $pod );
2556
- $options['additional-field'][ $type ] = apply_filters( 'pods_admin_setup_edit_additional_field_options', $options['additional-field'][ $type ], $type, $options, $pod );
2557
- }//end foreach
2558
 
2559
- $input_helpers = array(
2560
- '' => '-- Select --',
2561
- );
 
 
 
 
 
2562
 
2563
- if ( class_exists( 'Pods_Helpers' ) ) {
2564
- $helpers = pods_api()->load_helpers( array( 'options' => array( 'helper_type' => 'input' ) ) );
2565
 
2566
- foreach ( $helpers as $helper ) {
2567
- $input_helpers[ $helper['name'] ] = $helper['name'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2568
  }
2569
  }
2570
 
2571
- $options['advanced'] = array(
2572
- __( 'Visual', 'pods' ) => array(
2573
- 'class' => array(
2574
- 'name' => 'class',
2575
- 'label' => __( 'Additional CSS Classes', 'pods' ),
2576
- 'help' => __( 'help', 'pods' ),
2577
- 'type' => 'text',
2578
- 'default' => '',
2579
- ),
2580
- 'input_helper' => array(
2581
- 'name' => 'input_helper',
2582
- 'label' => __( 'Input Helper', 'pods' ),
2583
- 'help' => __( 'help', 'pods' ),
2584
- 'type' => 'pick',
2585
- 'default' => '',
2586
- 'data' => $input_helpers,
2587
- ),
2588
- ),
2589
- __( 'Values', 'pods' ) => array(
2590
- 'default_value' => array(
2591
- 'name' => 'default_value',
2592
- 'label' => __( 'Default Value', 'pods' ),
2593
- 'help' => __( 'help', 'pods' ),
2594
- 'type' => 'text',
2595
- 'default' => '',
2596
- 'options' => array(
2597
- 'text_max_length' => - 1,
2598
- ),
2599
- ),
2600
- 'default_value_parameter' => array(
2601
- 'name' => 'default_value_parameter',
2602
- 'label' => __( 'Set Default Value via Parameter', 'pods' ),
2603
- 'help' => __( 'help', 'pods' ),
2604
- 'type' => 'text',
2605
- 'default' => '',
2606
- ),
2607
- ),
2608
- __( 'Visibility', 'pods' ) => array(
2609
- 'restrict_access' => array(
2610
- 'name' => 'restrict_access',
2611
- 'label' => __( 'Restrict Access', 'pods' ),
2612
- 'group' => array(
2613
- 'admin_only' => array(
2614
- 'name' => 'admin_only',
2615
- 'label' => __( 'Restrict access to Admins?', 'pods' ),
2616
- 'default' => 0,
2617
- 'type' => 'boolean',
2618
- 'dependency' => true,
2619
- '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' ),
2620
- ),
2621
- 'restrict_role' => array(
2622
- 'name' => 'restrict_role',
2623
- 'label' => __( 'Restrict access by Role?', 'pods' ),
2624
- 'default' => 0,
2625
- 'type' => 'boolean',
2626
- 'dependency' => true,
2627
- ),
2628
- 'restrict_capability' => array(
2629
- 'name' => 'restrict_capability',
2630
- 'label' => __( 'Restrict access by Capability?', 'pods' ),
2631
- 'default' => 0,
2632
- 'type' => 'boolean',
2633
- 'dependency' => true,
2634
- ),
2635
- 'hidden' => array(
2636
- 'name' => 'hidden',
2637
- 'label' => __( 'Hide field from UI', 'pods' ),
2638
- 'default' => 0,
2639
- 'type' => 'boolean',
2640
- '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' ),
2641
- ),
2642
- 'read_only' => array(
2643
- 'name' => 'read_only',
2644
- 'label' => __( 'Make field "Read Only" in UI', 'pods' ),
2645
- 'default' => 0,
2646
- 'type' => 'boolean',
2647
- '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' ),
2648
- 'depends-on' => array(
2649
- 'type' => array(
2650
- 'boolean',
2651
- 'color',
2652
- 'currency',
2653
- 'date',
2654
- 'datetime',
2655
- 'email',
2656
- 'number',
2657
- 'paragraph',
2658
- 'password',
2659
- 'phone',
2660
- 'slug',
2661
- 'text',
2662
- 'time',
2663
- 'website',
2664
- ),
2665
- ),
2666
- ),
2667
- ),
2668
- ),
2669
- 'roles_allowed' => array(
2670
- 'name' => 'roles_allowed',
2671
- 'label' => __( 'Role(s) Allowed', 'pods' ),
2672
- 'help' => __( 'help', 'pods' ),
2673
- 'type' => 'pick',
2674
- 'pick_object' => 'role',
2675
- 'pick_format_type' => 'multi',
2676
- 'default' => 'administrator',
2677
- 'depends-on' => array(
2678
- 'restrict_role' => true,
2679
- ),
2680
- ),
2681
- 'capability_allowed' => array(
2682
- 'name' => 'capability_allowed',
2683
- 'label' => __( 'Capability Allowed', 'pods' ),
2684
- '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' ),
2685
- 'type' => 'text',
2686
- 'default' => '',
2687
- 'depends-on' => array(
2688
- 'restrict_capability' => true,
2689
- ),
2690
- ),
2691
- ),
2692
- );
2693
 
2694
- /*
2695
- $options['advanced'][ __( 'Visibility', 'pods' ) ]['search'] = array(
2696
- 'label' => __( 'Include in searches', 'pods' ),
2697
- 'help' => __( 'help', 'pods' ),
2698
- 'default' => 1,
2699
- 'type' => 'boolean',
2700
- );
2701
- */
2702
-
2703
- /*
2704
- $options['advanced'][ __( 'Validation', 'pods' ) ] = array(
2705
- 'regex_validation' => array(
2706
- 'label' => __( 'RegEx Validation', 'pods' ),
2707
- 'help' => __( 'help', 'pods' ),
2708
- 'type' => 'text',
2709
- 'default' => '',
2710
- ),
2711
- 'message_regex' => array(
2712
- 'label' => __( 'Message if field does not pass RegEx', 'pods' ),
2713
- 'help' => __( 'help', 'pods' ),
2714
- 'type' => 'text',
2715
- 'default' => '',
2716
- ),
2717
- 'message_required' => array(
2718
- 'label' => __( 'Message if field is blank', 'pods' ),
2719
- 'help' => __( 'help', 'pods' ),
2720
- 'type' => 'text',
2721
- 'default' => '',
2722
- 'depends-on' => array( 'required' => true ),
2723
- ),
2724
- 'message_unique' => array(
2725
- 'label' => __( 'Message if field is not unique', 'pods' ),
2726
- 'help' => __( 'help', 'pods' ),
2727
- 'type' => 'text',
2728
- 'default' => '',
2729
- 'depends-on' => array( 'unique' => true ),
2730
- ),
2731
- );
2732
- */
2733
 
2734
- if ( ! class_exists( 'Pods_Helpers' ) ) {
2735
- unset( $options['advanced']['input_helper'] );
2736
  }
2737
 
2738
- /**
2739
- * Modify tabs and their contents for field options
2740
- *
2741
- * @since unknown
2742
- *
2743
- * @param array $options Tabs, indexed by label.
2744
- * @param object|Pods $pod Pods object for the Pod this UI is for.
2745
- */
2746
- $options = apply_filters( 'pods_admin_setup_edit_field_options', $options, $pod );
 
 
 
 
 
 
 
 
2747
 
2748
- return $options;
2749
  }
2750
 
2751
  /**
@@ -2754,7 +1764,6 @@ class PodsAdmin {
2754
  * @param PodsUI $obj PodsUI object.
2755
  */
2756
  public function admin_setup_duplicate( $obj ) {
2757
-
2758
  $new_id = pods_api()->duplicate_pod( array( 'id' => $obj->id ) );
2759
 
2760
  if ( 0 < $new_id ) {
@@ -2767,7 +1776,11 @@ class PodsAdmin {
2767
  )
2768
  )
2769
  );
 
 
2770
  }
 
 
2771
  }
2772
 
2773
  /**
@@ -2851,12 +1864,12 @@ class PodsAdmin {
2851
  /**
2852
  * Delete a pod
2853
  *
2854
- * @param int|string $id Item ID.
2855
  * @param PodsUI $obj PodsUI object.
 
2856
  *
2857
  * @return mixed
2858
  */
2859
- public function admin_setup_delete( $id, $obj ) {
2860
 
2861
  $pod = pods_api()->load_pod( array( 'id' => $id ), false );
2862
 
@@ -2866,12 +1879,18 @@ class PodsAdmin {
2866
 
2867
  pods_api()->delete_pod( array( 'id' => $id ) );
2868
 
2869
- unset( $obj->data[ $pod['id'] ] );
 
 
 
 
2870
 
2871
  $obj->total = count( $obj->data );
2872
  $obj->total_found = count( $obj->data );
2873
 
2874
  $obj->message( __( 'Pod deleted successfully.', 'pods' ) );
 
 
2875
  }
2876
 
2877
  /**
@@ -2886,6 +1905,12 @@ class PodsAdmin {
2886
  * Get settings administration view
2887
  */
2888
  public function admin_settings() {
 
 
 
 
 
 
2889
 
2890
  // Add our custom callouts.
2891
  add_action( 'pods_admin_after_settings', array( $this, 'admin_manage_callouts' ) );
@@ -3015,6 +2040,9 @@ class PodsAdmin {
3015
  }//end foreach
3016
 
3017
  $ui = array(
 
 
 
3018
  'data' => $components,
3019
  'total' => count( $components ),
3020
  'total_found' => count( $components ),
@@ -3249,23 +2277,20 @@ class PodsAdmin {
3249
 
3250
  $pods = pods_api()->load_pods(
3251
  array(
3252
- 'type' => array(
3253
  'settings',
3254
  'post_type',
3255
  'taxonomy',
3256
  ),
3257
- 'fields' => false,
3258
- 'table_info' => false,
3259
  )
3260
  );
3261
 
3262
  $other_pods = pods_api()->load_pods(
3263
  array(
3264
- 'type' => array(
3265
  'pod',
3266
  'table',
3267
  ),
3268
- 'table_info' => false,
3269
  )
3270
  );
3271
 
@@ -3322,14 +2347,16 @@ class PodsAdmin {
3322
  } else {
3323
  $capabilities[] = 'pods_add_' . $pod['name'];
3324
  $capabilities[] = 'pods_edit_' . $pod['name'];
 
3325
 
3326
- if ( isset( $pod['fields']['author'] ) && 'pick' === $pod['fields']['author']['type'] && 'user' === $pod['fields']['author']['pick_object'] ) {
3327
- $capabilities[] = 'pods_edit_others_' . $pod['name'];
 
 
3328
  }
3329
 
3330
- $capabilities[] = 'pods_delete_' . $pod['name'];
3331
-
3332
- if ( isset( $pod['fields']['author'] ) && 'pick' === $pod['fields']['author']['type'] && 'user' === $pod['fields']['author']['pick_object'] ) {
3333
  $capabilities[] = 'pods_delete_others_' . $pod['name'];
3334
  }
3335
 
@@ -3536,8 +2563,10 @@ class PodsAdmin {
3536
  * @return array
3537
  *
3538
  * @since 2.7.0
 
3539
  */
3540
  public function configuration( $pod = null, $full_field_info = false ) {
 
3541
 
3542
  $api = pods_api();
3543
 
@@ -3612,7 +2641,7 @@ class PodsAdmin {
3612
  'add_rest_fields_to_field_editor',
3613
  ), 12, 2
3614
  );
3615
- add_filter( 'pods_admin_setup_edit_field_tabs', array( $this, 'add_rest_field_tab' ), 12 );
3616
  }
3617
 
3618
  add_filter( 'pods_admin_setup_edit_tabs', array( $this, 'add_rest_settings_tab' ), 12, 2 );
@@ -3657,6 +2686,9 @@ class PodsAdmin {
3657
  * @return array
3658
  */
3659
  public function add_rest_settings_tab( $tabs, $pod ) {
 
 
 
3660
 
3661
  $tabs['rest-api'] = __( 'REST API', 'pods' );
3662
 
@@ -3675,62 +2707,43 @@ class PodsAdmin {
3675
  * @return array
3676
  */
3677
  public function add_rest_settings_tab_fields( $options, $pod ) {
 
 
 
3678
 
3679
- if ( ! function_exists( 'register_rest_field' ) ) {
3680
- $options['rest-api'] = array(
3681
- 'no_dependencies' => array(
3682
- 'label' => sprintf( __( 'Pods REST API support requires WordPress 4.3.1 or later and the %s or later.', 'pods' ), '<a href="https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/" target="_blank" rel="noopener noreferrer">WordPress REST API 2.0-beta9</a>' ),
3683
- 'help' => sprintf( __( 'See %s for more information.', 'pods' ), '<a href="https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/" target="_blank" rel="noopener noreferrer">https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/</a>' ),
3684
- 'type' => 'html',
3685
- ),
3686
- );
3687
- } elseif ( $this->restable_pod( $pod ) ) {
3688
- $options['rest-api'] = array(
3689
- 'rest_enable' => array(
3690
- 'label' => __( 'Enable', 'pods' ),
3691
- 'help' => __( 'Add REST API support for this Pod.', 'pods' ),
3692
- 'type' => 'boolean',
3693
- 'default' => '',
3694
- 'dependency' => true,
3695
- ),
3696
- 'rest_base' => array(
3697
- 'label' => __( 'REST Base (if any)', 'pods' ),
3698
- 'help' => __( 'This will form the url for the route. Default / empty value here will use the pod name.', 'pods' ),
3699
- 'type' => 'text',
3700
- 'default' => '',
3701
- 'depends-on' => array( 'rest_enable' => true ),
3702
- ),
3703
- 'read_all' => array(
3704
- 'label' => __( 'Show All Fields (read-only)', 'pods' ),
3705
- 'help' => __( 'Show all fields in REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ),
3706
- 'type' => 'boolean',
3707
- 'default' => '',
3708
- 'depends-on' => array( 'rest_enable' => true ),
3709
- ),
3710
- 'write_all' => array(
3711
- 'label' => __( 'Allow All Fields To Be Updated', 'pods' ),
3712
- 'help' => __( 'Allow all fields to be updated via the REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ),
3713
- 'type' => 'boolean',
3714
- 'default' => pods_v( 'name', $pod ),
3715
- 'boolean_yes_label' => '',
3716
- 'depends-on' => array( 'rest_enable' => true ),
3717
- ),
3718
-
3719
- );
3720
-
3721
- } else {
3722
- $options['rest-api'] = array(
3723
- 'not_restable' => array(
3724
- 'label' => __( 'Pods REST API support covers post type, taxonomy and user Pods.', 'pods' ),
3725
- 'help' => sprintf( __( 'See %s for more information.', 'pods' ), '<a href="https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/" target="_blank" rel="noopener noreferrer">https://pods.io/docs/build/extending-core-wordpress-rest-api-routes-with-pods/"</a>' ),
3726
- 'type' => 'html',
3727
- ),
3728
- );
3729
-
3730
- }//end if
3731
 
3732
  return $options;
3733
-
3734
  }
3735
 
3736
  /**
@@ -3744,64 +2757,72 @@ class PodsAdmin {
3744
  * @return array
3745
  */
3746
  public function add_rest_fields_to_field_editor( $options, $pod ) {
 
 
 
3747
 
3748
- if ( $this->restable_pod( $pod ) ) {
3749
- $options['rest'][ __( 'Read/ Write', 'pods' ) ] = array(
3750
- 'rest_read' => array(
3751
- 'label' => __( 'Read via REST API?', 'pods' ),
3752
- 'help' => __( 'Should this field be readable via the REST API? You must enable REST API support for this Pod.', 'pods' ),
3753
- 'type' => 'boolean',
3754
- 'default' => '',
3755
- ),
3756
- 'rest_write' => array(
3757
- 'label' => __( 'Write via REST API?', 'pods' ),
3758
- 'help' => __( 'Should this field be writeable via the REST API? You must enable REST API support for this Pod. For relationship and file fields, you will always pass the ID of the related item/file. If this is a non-ID based relationship field, you will pass the related value (not label).', 'pods' ),
3759
- 'type' => 'boolean',
3760
- 'default' => '',
3761
- ),
3762
- );
3763
- $options['rest'][ __( 'Relationship Field Options', 'pods' ) ] = array(
3764
- 'rest_pick_response' => array(
3765
- 'label' => __( 'Response Type', 'pods' ),
3766
- 'help' => __( 'This will determine what amount of data for the related items will be returned.', 'pods' ),
3767
- 'type' => 'pick',
3768
- 'default' => 'array',
3769
- 'depends-on' => array( 'type' => 'pick' ),
3770
- 'dependency' => true,
3771
- 'data' => array(
3772
- 'array' => __( 'All fields', 'pods' ),
3773
- 'id' => __( 'ID only', 'pods' ),
3774
- 'name' => __( 'Name only', 'pods' ),
3775
- 'custom' => __( 'Custom return (specify field to return)', 'pods' ),
3776
- ),
3777
- ),
3778
- 'rest_pick_depth' => array(
3779
- 'label' => __( 'Depth', 'pods' ),
3780
- 'help' => __( 'How far to traverse relationships in response. 1 will get you all of the fields on the related item. 2 will get you all of those fields plus related items and their fields. The higher the depth, the more data will be returned and the slower performance the REST API calls will be. Updates to this field do NOT take depth into account, so you will always send the ID of the related item when saving.', 'pods' ),
3781
- 'type' => 'number',
3782
- 'default' => '1',
3783
- 'depends-on' => array(
3784
- 'type' => 'pick',
3785
- 'rest_pick_response' => 'array',
3786
- ),
3787
- ),
3788
- 'rest_pick_custom' => array(
3789
- 'label' => __( 'Custom return', 'pods' ),
3790
- 'help' => __( 'Specify the field to use following the established this_field_name.ID traversal pattern. You must include this field name in the selector for this to work properly.', 'pods' ),
3791
- 'type' => 'text',
3792
- 'default' => '',
3793
- 'placeholder' => 'this_field_name.ID',
3794
- 'depends-on' => array(
3795
- 'type' => 'pick',
3796
- 'rest_pick_response' => 'custom',
3797
- ),
3798
- ),
3799
- );
3800
-
3801
- }//end if
 
 
 
 
 
 
3802
 
3803
  return $options;
3804
-
3805
  }
3806
 
3807
  /**
@@ -3810,10 +2831,14 @@ class PodsAdmin {
3810
  * @since 2.5.6
3811
  *
3812
  * @param array $tabs Tab list.
 
3813
  *
3814
  * @return array
3815
  */
3816
- public function add_rest_field_tab( $tabs ) {
 
 
 
3817
 
3818
  $tabs['rest'] = __( 'REST API', 'pods' );
3819
 
@@ -3830,118 +2855,211 @@ class PodsAdmin {
3830
  * @return array Debug info with Pods-specific debug info added.
3831
  */
3832
  public function add_debug_information( $info ) {
3833
- $info['pods'] = array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3834
  'label' => 'Pods',
3835
  'description' => __( 'Debug information for Pods installations.', 'pods' ),
3836
- 'fields' => array(
3837
- 'pods-server-software' => array(
3838
  'label' => __( 'Server Software', 'pods' ),
3839
  'value' => ! empty( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : 'N/A',
3840
- ),
3841
- 'pods-user-agent' => array(
3842
  'label' => __( 'Your User Agent', 'pods' ),
3843
  'value' => ! empty( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : 'N/A',
3844
- ),
3845
- 'pods-session-save-path' => array(
3846
  'label' => __( 'Session Save Path', 'pods' ),
3847
  'value' => session_save_path(),
3848
- ),
3849
- 'pods-session-save-path-exists' => array(
3850
  'label' => __( 'Session Save Path Exists', 'pods' ),
3851
  'value' => file_exists( session_save_path() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3852
- ),
3853
- 'pods-session-save-path-writable' => array(
3854
  'label' => __( 'Session Save Path Writeable', 'pods' ),
3855
  'value' => is_writable( session_save_path() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3856
- ),
3857
- 'pods-session-max-lifetime' => array(
3858
  'label' => __( 'Session Max Lifetime', 'pods' ),
3859
  'value' => ini_get( 'session.gc_maxlifetime' ),
3860
- ),
3861
- 'pods-opcode-cache-apc' => array(
3862
  'label' => __( 'Opcode Cache: Apc', 'pods' ),
3863
  'value' => function_exists( 'apc_cache_info' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3864
- ),
3865
- 'pods-opcode-cache-memcached' => array(
3866
  'label' => __( 'Opcode Cache: Memcached', 'pods' ),
3867
  'value' => class_exists( 'eaccelerator_put' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3868
- ),
3869
- 'pods-opcode-cache-opcache' => array(
3870
  'label' => __( 'Opcode Cache: OPcache', 'pods' ),
3871
  'value' => function_exists( 'opcache_get_status' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3872
- ),
3873
- 'pods-opcode-cache-redis' => array(
3874
  'label' => __( 'Opcode Cache: Redis', 'pods' ),
3875
  'value' => class_exists( 'xcache_set' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3876
- ),
3877
- 'pods-object-cache-apc' => array(
3878
  'label' => __( 'Object Cache: APC', 'pods' ),
3879
  'value' => function_exists( 'apc_cache_info' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3880
- ),
3881
- 'pods-object-cache-apcu' => array(
3882
  'label' => __( 'Object Cache: APCu', 'pods' ),
3883
  'value' => function_exists( 'apcu_cache_info' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3884
- ),
3885
- 'pods-object-cache-memcache' => array(
3886
  'label' => __( 'Object Cache: Memcache', 'pods' ),
3887
  'value' => class_exists( 'Memcache' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3888
- ),
3889
- 'pods-object-cache-memcached' => array(
3890
  'label' => __( 'Object Cache: Memcached', 'pods' ),
3891
  'value' => class_exists( 'Memcached' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3892
- ),
3893
- 'pods-object-cache-redis' => array(
3894
  'label' => __( 'Object Cache: Redis', 'pods' ),
3895
  'value' => class_exists( 'Redis' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3896
- ),
3897
- 'pods-memory-current-usage' => array(
3898
  'label' => __( 'Current Memory Usage', 'pods' ),
3899
  'value' => number_format_i18n( memory_get_usage() / 1024 / 1024, 3 ) . 'M',
3900
- ),
3901
- 'pods-memory-current-usage-real' => array(
3902
  'label' => __( 'Current Memory Usage (real)', 'pods' ),
3903
  'value' => number_format_i18n( memory_get_usage( true ) / 1024 / 1024, 3 ) . 'M',
3904
- ),
3905
- 'pods-network-wide' => array(
3906
  'label' => __( 'Pods Network-Wide Activated', 'pods' ),
3907
  'value' => is_plugin_active_for_network( basename( PODS_DIR ) . '/init.php' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3908
- ),
3909
- 'pods-install-location' => array(
3910
  'label' => __( 'Pods Install Location', 'pods' ),
3911
  'value' => PODS_DIR,
3912
- ),
3913
- 'pods-developer' => array(
3914
  'label' => __( 'Pods Developer Activated' ),
3915
  'value' => ( pods_developer() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3916
- ),
3917
- 'pods-tableless-mode' => array(
3918
  'label' => __( 'Pods Tableless Mode Activated', 'pods' ),
3919
  'value' => ( pods_tableless() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3920
- ),
3921
- 'pods-light-mode' => array(
 
 
 
 
3922
  'label' => __( 'Pods Light Mode Activated', 'pods' ),
3923
  'value' => ( pods_light() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3924
- ),
3925
- 'pods-strict' => array(
3926
  'label' => __( 'Pods Strict Activated' ),
3927
- 'value' => ( pods_strict() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3928
- ),
3929
- 'pods-allow-deprecated' => array(
3930
  'label' => __( 'Pods Allow Deprecated' ),
3931
  'value' => ( pods_allow_deprecated() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3932
- ),
3933
- 'pods-api-cache' => array(
3934
  'label' => __( 'Pods API Cache Activated' ),
3935
  'value' => ( pods_api_cache() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3936
- ),
3937
- 'pods-shortcode-allow-evaluate-tags' => array(
3938
  'label' => __( 'Pods Shortcode Allow Evaluate Tags' ),
3939
  'value' => ( pods_shortcode_allow_evaluate_tags() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
3940
- ),
3941
- ),
3942
- );
 
 
 
 
 
 
 
 
3943
 
3944
  return $info;
3945
  }
3946
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3947
  }
1
  <?php
2
 
3
+ use Pods\Admin\Settings;
4
+ use Pods\Whatsit\Pod;
5
+
6
  /**
7
  * @package Pods
8
  */
63
  // Add our debug to Site Info.
64
  add_filter( 'debug_information', array( $this, 'add_debug_information' ) );
65
 
66
+ // Add our status tests.
67
+ add_filter( 'site_status_tests', [ $this, 'site_status_tests' ] );
68
+
69
  $this->rest_admin();
70
 
71
  }
128
 
129
  wp_register_script( 'pods-migrate', PODS_URL . 'ui/js/jquery.pods.migrate.js', array(), PODS_VERSION );
130
 
131
+ $load_pods_assets = false;
132
+
133
  // @codingStandardsIgnoreLine
134
  if ( isset( $_GET['page'] ) ) {
135
  // @codingStandardsIgnoreLine
136
  $page = $_GET['page'];
137
  if ( 'pods' === $page || ( false !== strpos( $page, 'pods-' ) && 0 === strpos( $page, 'pods-' ) ) ) {
138
+ $load_pods_assets = true;
139
+
140
  ?>
141
+ <script>
142
+ if ( 'undefined' === typeof PODS_URL ) {
143
+ const PODS_URL = '<?php echo esc_js( PODS_URL ); ?>';
144
+ }
145
  </script>
146
  <?php
147
+
148
  wp_enqueue_script( 'jquery' );
149
  wp_enqueue_script( 'jquery-ui-core' );
150
  wp_enqueue_script( 'jquery-ui-sortable' );
190
  }//end if
191
  }//end if
192
 
193
+ if ( $load_pods_assets ) {
194
+ /**
195
+ * Filter to disable default loading of the DFV script. By default, Pods
196
+ * will always enqueue the DFV script if is_admin()
197
+ *
198
+ * Example: add_filter( 'pods_default_enqueue_dfv', '__return_false');
199
+ *
200
+ * @since 2.7.10
201
+ *
202
+ * @param bool Whether or not to enqueue by default
203
+ *
204
+ */
205
+ if ( apply_filters( 'pods_default_enqueue_dfv', true ) ) {
206
+ wp_enqueue_script( 'pods-dfv' );
207
+ }
208
 
209
+ // New styles enqueue.
210
+ wp_enqueue_style( 'pods-styles' );
211
+ }
212
  }
213
 
214
  /**
222
  $taxonomies = PodsMeta::$taxonomies;
223
  $settings = PodsMeta::$settings;
224
 
 
 
225
  if ( ! PodsInit::$upgrade_needed || ( pods_is_admin() && 1 === (int) pods_v( 'pods_upgrade_bypass' ) ) ) {
226
  $submenu_items = array();
227
 
231
  $pods_pages = 0;
232
 
233
  foreach ( (array) $advanced_content_types as $pod ) {
234
+ if ( ! $pod instanceof Pod ) {
235
  continue;
236
  } elseif ( ! pods_is_admin(
237
  array(
588
  ),
589
  );
590
 
 
 
 
 
 
 
 
 
 
 
 
 
 
591
  add_filter( 'parent_file', array( $this, 'parent_file' ) );
592
  } else {
593
  $admin_menus = array(
743
 
744
  $pod = pods( $pod_name, pods_v( 'id', 'get', null, true ) );
745
 
746
+ if ( ! $pod->pod_data->has_fields() ) {
747
+ pods_message( 'error', __( 'This Pod does not have any fields defined.', 'pods' ) );
748
+ return;
749
+ }
750
+
751
  // @codingStandardsIgnoreLine
752
  if ( false !== strpos( $_GET['page'], 'pods-add-new-' ) ) {
753
  // @codingStandardsIgnoreLine
882
  * Handle main Pods Setup area for managing Pods and Fields
883
  */
884
  public function admin_setup() {
885
+ $api = pods_api();
886
 
887
+ $pods = $api->load_pods( array( 'fields' => false ) );
888
 
889
  $view = pods_v( 'view', 'get', 'all', true );
890
 
894
  $_GET['action'] = 'add';
895
  }
896
 
897
+ if ( 'pods' === $_GET['page'] && empty( $pods ) ) {
898
+ pods_ui_message( __( 'You do not have any Pods set up yet. You can set up your very first Pod below.', 'pods ' ) );
899
+ }
900
+
901
  // @codingStandardsIgnoreLine
902
+ if ( 'pods-add-new' === $_GET['page'] || empty( $pods ) ) {
903
  // @codingStandardsIgnoreLine
904
  if ( isset( $_GET['action'] ) && 'add' !== $_GET['action'] ) {
905
  pods_redirect(
906
  pods_query_arg(
907
  array(
908
+ 'page' => 'pods',
909
  // @codingStandardsIgnoreLine
910
+ 'action' => $_GET['action'],
911
  )
912
  )
913
  );
920
  pods_redirect(
921
  pods_query_arg(
922
  array(
923
+ 'page' => 'pods-add-new',
924
+ 'action' => '',
925
+ 'id' => '',
926
+ 'do' => '',
927
+ '_wpnonce' => '',
928
  )
929
  )
930
  );
931
  }//end if
932
 
933
+ $pod_types = $api->get_pod_types();
934
+ $storage_types = $api->get_storage_types();
 
 
 
 
 
 
 
 
 
935
 
936
  $row = false;
937
 
938
  $pod_types_found = array();
939
 
940
+ $fields = [
941
+ 'label' => [ 'label' => __( 'Label', 'pods' ) ],
942
+ 'name' => [ 'label' => __( 'Name', 'pods' ) ],
943
+ 'type' => [ 'label' => __( 'Type', 'pods' ) ],
944
+ 'storage' => [
945
  'label' => __( 'Storage Type', 'pods' ),
946
  'width' => '10%',
947
+ ],
948
+ 'group_count' => [
949
+ 'label' => __( 'Groups', 'pods' ),
950
  'width' => '8%',
951
+ ],
952
+ 'field_count' => [
953
+ 'label' => __( 'Fields', 'pods' ),
954
+ 'width' => '8%',
955
+ ],
956
+ ];
957
 
958
+ $total_groups = 0;
959
  $total_fields = 0;
960
 
961
+ /**
962
+ * Filters whether to extend internal Pods.
963
+ *
964
+ * @since 2.8.0
965
+ *
966
+ * @param bool $extend_internal Whether to extend internal Pods.
967
+ */
968
+ $extend_internal = apply_filters( 'pods_admin_setup_extend_pods_internal', false );
969
+
970
+ $pod_list = array();
971
+
972
  foreach ( $pods as $k => $pod ) {
973
+ $pod_type = $pod['type'];
974
+ $pod_type_label = null;
975
+ $pod_storage = $pod['storage'];
976
+
977
+ if ( ! empty( $pod['internal'] ) ) {
978
+ // Don't show internal if we aren't extending them.
979
+ if ( ! $extend_internal ) {
980
+ continue;
981
+ }
982
+
983
+ $pod_type = 'internal';
984
+ $pod_storage = 'meta';
985
+ }
986
+
987
+ if ( 'settings' === $pod_type ) {
988
+ $pod_storage = 'options';
989
+ }
990
+
991
+ if ( isset( $pod_types[ $pod_type ] ) ) {
992
+ $pod_type_label = $pod_types[ $pod_type ];
993
+ }
994
+
995
+ $pod_real_type = $pod_type;
996
+
997
+ $storage_type_label = ucwords( $pod_storage );
998
+
999
+ if ( isset( $storage_types[ $pod_type ] ) ) {
1000
+ $storage_type_label = $storage_types[ $pod_type ];
1001
+ }
1002
+
1003
+ if ( null !== $pod_type_label ) {
1004
+ if ( empty( $pod['object'] ) && in_array( $pod_type, array(
1005
  'post_type',
1006
  'taxonomy',
1007
+ ), true ) ) {
1008
+ if ( 'post_type' === $pod_type ) {
1009
+ $pod_type = 'cpt';
1010
+ } else {
1011
+ $pod_type = 'ct';
1012
+ }
1013
+
1014
+ if ( isset( $pod_types[ $pod_type ] ) ) {
1015
+ $pod_type_label = $pod_types[ $pod_type ];
1016
  }
1017
  }
1018
 
1019
+ if ( ! isset( $pod_types_found[ $pod_type ] ) ) {
1020
+ $pod_types_found[ $pod_type ] = 1;
1021
  } else {
1022
+ $pod_types_found[ $pod_type ] ++;
1023
  }
1024
 
1025
+ if ( 'all' !== $view && $view !== $pod_type ) {
 
 
1026
  continue;
1027
  }
1028
 
1029
+ $pod_real_type = $pod_type;
1030
+ $pod_type = $pod_type_label;
1031
  } elseif ( 'all' !== $view ) {
1032
  continue;
1033
  }//end if
1034
 
 
 
1035
  // @codingStandardsIgnoreLine
1036
+ if ( 'delete' !== pods_v( 'action' ) && $pod['id'] === (int) pods_v( 'id' ) ) {
1037
  $row = $pod;
1038
  }
1039
 
1041
  'id' => $pod['id'],
1042
  'label' => pods_v( 'label', $pod ),
1043
  'name' => pods_v( 'name', $pod ),
1044
+ 'object' => pods_v( 'object', $pod, '' ),
1045
+ 'type' => $pod_type,
1046
+ 'real_type' => $pod_real_type,
1047
+ 'storage' => $storage_type_label,
1048
+ 'group_count' => $pod->count_groups(),
1049
+ 'field_count' => $pod->count_fields(),
1050
  );
1051
 
1052
+ $total_groups += $pod['group_count'];
1053
  $total_fields += $pod['field_count'];
1054
 
1055
+ $pod_list[] = $pod;
1056
  }//end foreach
1057
 
1058
  if ( false === $row && 0 < pods_v( 'id' ) && 'delete' !== pods_v( 'action' ) ) {
1062
  unset( $_GET['id'], $_GET['action'] );
1063
  }
1064
 
1065
+ $total_pods = count( $pod_list );
1066
+
1067
+ $ui = [
1068
+ 'data' => $pod_list,
1069
  'row' => $row,
1070
+ 'total' => $total_pods,
1071
+ 'total_found' => $total_pods,
1072
  'items' => 'Pods',
1073
  'item' => 'Pod',
1074
+ 'fields' => [
1075
  'manage' => $fields,
1076
+ ],
1077
+ 'sql' => [
1078
+ 'field_id' => 'id',
1079
+ 'field_index' => 'label',
1080
+ ],
1081
+ 'actions_disabled' => [ 'view', 'export', 'delete' ],
1082
+ 'actions_custom' => [
1083
+ 'add' => [ $this, 'admin_setup_add' ],
1084
+ 'edit' => [ $this, 'admin_setup_edit' ],
1085
+ 'duplicate' => [
1086
+ 'callback' => [ $this, 'admin_setup_duplicate' ],
1087
+ 'restrict_callback' => [ $this, 'admin_setup_duplicate_restrict' ],
1088
+ ],
1089
+ 'reset' => [
1090
  'label' => __( 'Delete All Items', 'pods' ),
1091
  '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' ),
1092
+ 'callback' => [ $this, 'admin_setup_reset' ],
1093
+ 'restrict_callback' => [ $this, 'admin_setup_reset_restrict' ],
1094
  'nonce' => true,
1095
+ 'span_class' => 'delete',
1096
+ ],
1097
+ 'delete_pod' => [
1098
+ 'label' => __( 'Delete', 'pods' ),
1099
+ 'confirm' => __( 'Are you sure you want to delete this Pod? All of the content and items will remain in the database, you may want to Delete All Items first.', 'pods' ),
1100
+ 'callback' => [ $this, 'admin_setup_delete' ],
1101
+ 'nonce' => true,
1102
+ 'span_class' => 'delete',
1103
+ ],
1104
+ ],
1105
+ 'action_links' => [
1106
+ 'add' => pods_query_arg( [
1107
+ 'page' => 'pods-add-new',
1108
+ 'action' => '',
1109
+ 'id' => '',
1110
+ 'do' => '',
1111
+ '_wpnonce' => '',
1112
+ ] ),
1113
+ ],
1114
  'search' => false,
1115
  'searchable' => false,
1116
  'sortable' => true,
1117
  'pagination' => false,
1118
+ 'extra' => [
1119
+ 'total' =>
1120
+ ', ' . number_format_i18n( $total_groups ) . ' ' . _n( 'group', 'groups', $total_groups, 'pods' )
1121
+ . ', ' . number_format_i18n( $total_fields ) . ' ' . _n( 'field', 'fields', $total_fields, 'pods' ),
1122
+ ],
1123
+ ];
1124
 
1125
  if ( 1 < count( $pod_types_found ) ) {
1126
+ $ui['views'] = [ 'all' => __( 'All', 'pods' ) . ' (' . $total_pods . ')' ];
1127
  $ui['view'] = $view;
1128
+ $ui['heading'] = [ 'views' => __( 'Type', 'pods' ) ];
1129
  $ui['filters_enhanced'] = true;
1130
 
1131
  foreach ( $pod_types_found as $pod_type => $number_found ) {
1132
+ $ui['views'][ $pod_type ] = $pod_types[ $pod_type ] . ' (' . $number_found . ')';
1133
  }
1134
  }
1135
 
1162
 
1163
  if ( ! $callouts ) {
1164
  $callouts = array(
1165
+ 'friends_2021_29' => 1,
1166
  );
1167
  }
1168
 
1169
  // Handle Friends of Pods 2021 callout logic.
1170
+ $callouts['friends_2021_29'] = ! isset( $callouts['friends_2021_29'] ) || $callouts['friends_2021_29'] || $force_callouts ? 1 : 0;
1171
 
1172
  /**
1173
  * Allow hooking into whether or not the specific callouts should show.
1195
 
1196
  $disable_pods = pods_v( 'pods_callout_dismiss' );
1197
 
1198
+ // Disable Friends of Pods 2021 callout.
1199
  if ( 'friends_2021' === $disable_pods ) {
1200
  $callouts['friends_2021'] = 0;
1201
 
1245
 
1246
  $callouts = $this->get_callouts();
1247
 
1248
+ if ( ! empty( $callouts['friends_2021_29'] ) ) {
1249
+ pods_view( PODS_DIR . 'ui/admin/callouts/friends_2021_29.php', compact( array_keys( get_defined_vars() ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1250
  }
1251
  }
1252
 
1256
  * @param PodsUI $obj PodsUI object.
1257
  */
1258
  public function admin_setup_add( $obj ) {
 
1259
  pods_view( PODS_DIR . 'ui/admin/setup-add.php', compact( array_keys( get_defined_vars() ) ) );
1260
  }
1261
 
1266
  * @param PodsUI $obj PodsUI object.
1267
  */
1268
  public function admin_setup_edit( $duplicate, $obj ) {
1269
+ $api = pods_api();
1270
 
1271
+ $pod = $api->load_pod( [ 'id' => $obj->id ] );
 
1272
 
1273
+ if ( ! $pod instanceof Pod ) {
1274
+ $obj->id = null;
1275
+ $obj->row = [];
1276
+ $obj->action = 'manage';
1277
+
1278
+ $obj->error( __( 'Invalid Pod configuration detected.' ) );
1279
+ $obj->manage();
1280
+
1281
+ return null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1282
  }
1283
 
1284
+ if ( 1 !== (int) $pod->get_arg( '_migrated_28' ) ) {
1285
+ $pod = $this->maybe_migrate_pod_fields_into_group( $pod );
1286
  }
1287
 
1288
+ // Check again in case the pod migrated wrong.
1289
+ if ( ! $pod instanceof Pod ) {
1290
+ $obj->id = null;
1291
+ $obj->row = [];
1292
+ $obj->action = 'manage';
1293
 
1294
+ $obj->error( __( 'Invalid Pod configuration detected.' ) );
1295
+ $obj->manage();
 
1296
 
1297
+ return null;
 
1298
  }
1299
 
1300
+ $config = [
1301
+ 'currentPod' => $pod->export( [
1302
+ 'include_groups' => true,
1303
+ 'include_group_fields' => true,
1304
+ 'include_fields' => false,
1305
+ ] ),
1306
+ 'global' => $this->get_global_config( $pod ),
1307
+ 'fieldTypes' => PodsForm::field_types(),
1308
+ 'relatedObjects' => $this->get_field_related_objects(),
1309
+ 'podTypes' => $api->get_pod_types(),
1310
+ 'storageTypes' => $api->get_storage_types(),
1311
+ // @todo SKC: Remove these below and replace any references to podsDFVConfig
1312
+ 'wp_locale' => $GLOBALS['wp_locale'],
1313
+ 'currencies' => PodsField_Currency::$currencies,
1314
+ 'datetime' => [
1315
+ 'start_of_week' => (int) get_option( 'start_of_week', 0 ),
1316
+ 'gmt_offset' => (int) get_option( 'gmt_offset', 0 ),
1317
+ ],
1318
+ ];
1319
+
1320
+ $config['currentPod']['podType'] = [
1321
+ 'name' => $config['currentPod']['type'],
1322
+ ];
1323
+
1324
+ $config['currentPod']['storageType'] = [
1325
+ 'name' => $config['currentPod']['storage'],
1326
+ ];
1327
+
1328
+ if ( ! empty( $config['currentPod']['internal'] ) ) {
1329
+ $config['currentPod']['podType']['name'] = 'internal';
1330
+ } elseif ( empty( $config['currentPod']['object'] ) ) {
1331
+ if ( 'post_type' === $config['currentPod']['type'] ) {
1332
+ $config['currentPod']['podType']['name'] = 'cpt';
1333
+ } elseif ( 'taxonomy' === $config['currentPod']['type'] ) {
1334
+ $config['currentPod']['podType']['name'] = 'ct';
1335
+ }
1336
  }
1337
 
1338
+ $config['currentPod']['podType']['label'] = ucwords( str_replace( '_', ' ', $config['currentPod']['podType']['name'] ) );
1339
+
1340
+ if ( ! empty( $config['podTypes'][ $config['currentPod']['podType']['name'] ] ) ) {
1341
+ $config['currentPod']['podType']['label'] = $config['podTypes'][ $config['currentPod']['podType']['name'] ];
1342
  }
1343
 
1344
+ if ( 'settings' === $config['currentPod']['type'] ) {
1345
+ $config['currentPod']['storageType']['name'] = 'options';
1346
  }
1347
 
1348
+ $config['currentPod']['storageType']['label'] = ucwords( $config['currentPod']['storageType']['name'] );
1349
 
1350
+ if ( ! empty( $config['storageTypes'][ $config['currentPod']['storageType']['name'] ] ) ) {
1351
+ $config['currentPod']['storageType']['label'] = $config['storageTypes'][ $config['currentPod']['storageType']['name'] ];
1352
+ }
1353
 
1354
  /**
1355
+ * Allow filtering the admin config data.
1356
  *
1357
+ * @since 2.8.0
 
 
1358
  *
1359
+ * @param array $config The admin config data.
1360
+ * @param Pod $pod The pod object.
1361
+ * @param PodsUI $obj The PodsUI object.
1362
  */
1363
+ $config = apply_filters( 'pods_admin_setup_edit_pod_config', $config, $pod, $obj );
1364
 
1365
+ wp_localize_script( 'pods-dfv', 'podsAdminConfig', $config );
 
 
 
1366
 
1367
+ pods_view( PODS_DIR . 'ui/admin/setup-edit.php', compact( array_keys( get_defined_vars() ) ) );
1368
+ }
 
 
1369
 
1370
+ /**
1371
+ * Get list of field related objects.
1372
+ *
1373
+ * @since 2.8.0
1374
+ *
1375
+ * @return array List of field related objects.
1376
+ */
1377
+ protected function get_field_related_objects() {
1378
+ $related_object_groups = PodsForm::field_method( 'pick', 'related_objects', true );
1379
+
1380
+ $related_objects = [];
1381
+
1382
+ foreach ( $related_object_groups as $group => $group_objects ) {
1383
+ foreach ( $group_objects as $name => $label ) {
1384
+ $related_objects[ $name ] = [
1385
+ 'name' => $name,
1386
+ 'label' => $label,
1387
+ ];
1388
+ }
1389
+ }
1390
+
1391
+ return $related_objects;
1392
  }
1393
 
1394
  /**
1395
+ * Maybe migrate pod fields into a group (if they have no group).
1396
  *
1397
+ * @since 2.8.0
1398
  *
1399
+ * @param Pod $pod The pod object.
1400
+ *
1401
+ * @return Pod The pod object.
1402
  */
1403
+ public function maybe_migrate_pod_fields_into_group( $pod ) {
1404
+ $groups = $pod->get_groups( [
1405
+ 'fallback_mode' => false,
1406
+ ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1407
 
1408
+ $check_orphan_fields = ! $groups;
1409
 
1410
+ $api = pods_api();
1411
+
1412
+ $group_id = null;
1413
+
1414
+ // Only migrate if there are no groups or orphan fields.
1415
+ if ( ! $check_orphan_fields ) {
1416
+ $has_orphan_fields = $pod->has_fields( [
1417
+ 'fallback_mode' => false,
1418
+ 'group' => null,
1419
+ ] );
1420
+
1421
+ if ( ! $has_orphan_fields ) {
1422
+ $pod->set_arg( '_migrated_28', 1 );
1423
+
1424
+ try {
1425
+ $api->save_pod( $pod );
1426
+ } catch ( Exception $exception ) {
1427
+ // Nothing to do for now.
1428
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1429
 
1430
+ $pod->flush();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1431
 
1432
+ return $pod;
1433
+ }
1434
 
1435
+ $groups = wp_list_pluck( $groups, 'id' );
1436
+ $groups = array_filter( $groups );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1437
 
1438
+ if ( ! empty( $groups ) ) {
1439
+ $group_id = reset( $groups );
1440
+ }
1441
+ }
 
 
 
1442
 
1443
+ $fields = $pod->get_fields( [
1444
+ 'fallback_mode' => false,
1445
+ 'group' => null,
1446
+ ] );
 
 
 
 
 
1447
 
1448
+ if ( empty( $group_id ) ) {
1449
+ $label = __( 'Details', 'pods' );
1450
+
1451
+ if ( in_array( $pod->get_type(), [ 'post_type', 'taxonomy', 'user', 'comment', 'media' ], true ) ) {
1452
+ $label = __( 'More Fields', 'pods' );
 
 
1453
  }
1454
 
1455
+ /**
1456
+ * Filter the title of the Pods Metabox used in the post editor.
1457
+ *
1458
+ * @since unknown
1459
+ *
1460
+ * @param string $title The title to use, default is 'More Fields'.
1461
+ * @param obj|Pod $pod Current Pods Object.
1462
+ * @param array $fields Array of fields that will go in the metabox.
1463
+ * @param string $type The type of Pod.
1464
+ * @param string $name Name of the Pod.
1465
+ */
1466
+ $label = apply_filters( 'pods_meta_default_box_title', $label, $pod, $fields, $pod->get_type(), $pod->get_name() );
1467
+ $name = sanitize_key( pods_js_name( sanitize_title( $label ) ) );
1468
+
1469
+ // Setup first group.
1470
+ $group_id = $api->save_group( [
1471
+ 'pod' => $pod,
1472
+ 'name' => $name,
1473
+ 'label' => $label,
1474
+ ] );
1475
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1476
 
1477
+ foreach ( $fields as $field ) {
1478
+ $api->save_field( [
1479
+ 'id' => $field->get_id(),
1480
+ 'pod_data' => $pod,
1481
+ 'field' => $field,
1482
+ 'new_group_id' => $group_id,
1483
+ ], false );
1484
 
1485
+ $field->set_arg( 'group_id', $group_id );
1486
+ }
 
 
 
1487
 
1488
+ $pod->set_arg( '_migrated_28', 1 );
 
 
 
 
 
1489
 
1490
+ $api->save_pod( $pod );
 
1491
 
1492
+ $pod->flush();
 
 
 
 
 
 
 
 
1493
 
1494
+ $api->cache_flush_pods( $pod );
 
 
 
 
 
 
1495
 
1496
+ // Refresh pod object.
1497
+ $pod->flush();
 
 
 
 
 
1498
 
1499
+ return $pod;
1500
  }
1501
 
1502
  /**
1503
+ * Get the global config for Pods admin.
1504
  *
1505
+ * @since 2.8.0
1506
  *
1507
+ * @param null|\Pods\Whatsit $pod
1508
+ *
1509
+ * @return array Global config array.
1510
  */
1511
+ public function get_global_config( $pod = null ) {
1512
+ $config_pod = tribe( \Pods\Admin\Config\Pod::class );
1513
+ $config_group = tribe( \Pods\Admin\Config\Group::class );
1514
+ $config_field = tribe( \Pods\Admin\Config\Field::class );
1515
+
1516
+ // Pod: Backwards compatible configs and hooks.
1517
+ $pod_tabs = $config_pod->get_tabs( $pod );
1518
+ $pod_tab_options = $config_pod->get_fields( $pod, $pod_tabs );
1519
+
1520
+ $this->backcompat_convert_tabs_to_groups( $pod_tabs, $pod_tab_options, 'pod/_pods_pod' );
1521
+
1522
+ // Group: Backwards compatible methods and hooks.
1523
+ $group_tabs = $config_group->get_tabs( $pod );
1524
+ $group_tab_options = $config_group->get_fields( $pod, $group_tabs );
1525
+
1526
+ $this->backcompat_convert_tabs_to_groups( $group_tabs, $group_tab_options, 'pod/_pods_group' );
1527
+
1528
+ // Field: Backwards compatible methods and hooks.
1529
+ $field_tabs = $config_field->get_tabs( $pod );
1530
+ $field_tab_options = $config_field->get_fields( $pod, $field_tabs );
1531
+
1532
+ $this->backcompat_convert_tabs_to_groups( $field_tabs, $field_tab_options, 'pod/_pods_field' );
1533
+
1534
+ $object_collection = Pods\Whatsit\Store::get_instance();
1535
+
1536
+ /** @var Pods\Whatsit\Storage $storage */
1537
+ $storage = $object_collection->get_storage_object( 'collection' );
1538
+
1539
+ // Get objects from storage.
1540
+ $pod_object = $storage->get( [
1541
+ 'object_type' => 'pod',
1542
+ 'name' => '_pods_pod',
1543
+ ] );
1544
+
1545
+ $group_object = $storage->get( [
1546
+ 'object_type' => 'pod',
1547
+ 'name' => '_pods_group',
1548
+ ] );
1549
+
1550
+ $field_object = $storage->get( [
1551
+ 'object_type' => 'pod',
1552
+ 'name' => '_pods_field',
1553
+ ] );
1554
+
1555
+ $pod = [
1556
+ 'pod' => $pod_object->export( [
1557
+ 'include_groups' => true,
1558
+ 'include_group_fields' => true,
1559
+ 'include_fields' => false,
1560
+ 'include_field_data' => true,
1561
+ ] ),
1562
+ 'group' => $group_object->export( [
1563
+ 'include_groups' => true,
1564
+ 'include_group_fields' => true,
1565
+ 'include_fields' => false,
1566
+ 'include_field_data' => true,
1567
+ ] ),
1568
+ 'field' => $field_object->export( [
1569
+ 'include_groups' => true,
1570
+ 'include_group_fields' => true,
1571
+ 'include_fields' => false,
1572
+ 'include_field_data' => true,
1573
+ ] ),
1574
+ ];
1575
 
1576
  /**
1577
+ * Allow hooking into the global config setup for a Pod.
1578
  *
1579
+ * @param null|\Pods\Whatsit $pod The Pod object.
 
 
 
 
 
1580
  */
1581
+ $pod = apply_filters( 'pods_admin_setup_global_config', $pod );
 
 
1582
 
1583
+ return $pod;
1584
  }
1585
 
1586
  /**
1587
+ * Convert the tabs and their options to groups/fields in the collection storage.
1588
  *
1589
+ * @since 2.8.0
1590
  *
1591
+ * @param array $tabs List of registered tabs.
1592
+ * @param array $options List of tab options.
1593
+ * @param string $parent The parent object to register to.
1594
+ *
1595
+ * @return array Global config array.
1596
  */
1597
+ protected function backcompat_convert_tabs_to_groups( array $tabs, array $options, $parent ) {
1598
+ $object_collection = Pods\Whatsit\Store::get_instance();
1599
 
1600
+ /** @var Pods\Whatsit\Storage\Collection $storage */
1601
+ $storage = $object_collection->get_storage_object( 'collection' );
1602
 
1603
+ $groups = [];
1604
+ $fields = [];
1605
 
1606
+ foreach ( $tabs as $group_name => $group_label ) {
1607
+ if ( empty( $options[ $group_name ] ) ) {
1608
+ continue;
1609
+ }
1610
 
1611
+ if ( is_array( $group_label ) ) {
1612
+ $group_args = $group_label;
1613
+ } else {
1614
+ $group_args = [
1615
+ 'name' => $group_name,
1616
+ 'label' => $group_label,
1617
+ ];
1618
+ }
1619
+
1620
+ $group_args['parent'] = $parent;
1621
 
1622
+ $group = new \Pods\Whatsit\Group( $group_args );
1623
 
1624
+ $groups[] = $storage->add( $group );
1625
+
1626
+ $group_fields = $options[ $group_name ];
1627
+
1628
+ $sections = false;
1629
+
1630
+ foreach ( $group_fields as $field_name => $field_options ) {
1631
+ // Support sections.
1632
+ if ( ! isset( $field_options['label'] ) ) {
1633
+ $sections = true;
1634
+ }
1635
+
1636
+ break;
1637
  }
1638
 
1639
+ $group_sections = $group_fields;
1640
 
1641
+ // Store the same whether it's a section or not.
1642
+ if ( ! $sections ) {
1643
+ $group_sections = [
1644
+ $group_fields,
1645
+ ];
1646
+ }
1647
+
1648
+ foreach ( $group_sections as $section_label => $section_fields ) {
1649
+ // Add section field (maybe).
1650
+ if ( ! is_int( $section_label ) ) {
1651
+ $field_args = [
1652
+ 'name' => sanitize_title( $section_label ),
1653
+ 'label' => $section_label,
1654
+ 'type' => 'heading',
1655
+ 'parent' => $parent,
1656
+ 'group' => 'group/' . $parent . '/' . $group_name,
1657
+ ];
1658
+
1659
+ $field = new \Pods\Whatsit\Field( $field_args );
1660
+
1661
+ $fields[] = $storage->add( $field );
1662
+ }
1663
+
1664
+ if ( ! is_array( $section_fields ) ) {
1665
  continue;
1666
  }
 
1667
 
1668
+ // Add fields for section.
1669
+ foreach ( $section_fields as $field_name => $field_options ) {
1670
+ $boolean_group = [];
1671
 
1672
+ // Handle auto-formatting from shorthand.
1673
+ if ( ! empty( $field_options['boolean_group'] ) ) {
1674
+ $boolean_group = $field_options['boolean_group'];
 
 
 
 
 
 
 
 
 
 
1675
 
1676
+ foreach ( $boolean_group as $bgf_key => $boolean_group_field ) {
1677
+ // Make sure each field has a field name.
1678
+ if ( is_string( $bgf_key ) ) {
1679
+ $boolean_group[ $bgf_key ]['name'] = $bgf_key;
1680
+ }
1681
+ }
1682
+
1683
+ $boolean_group = array_values( $boolean_group );
1684
 
1685
+ $field_options['boolean_group'] = $boolean_group;
1686
+ }
1687
 
1688
+ if ( empty( $field_options['type'] ) ) {
1689
+ continue;
1690
+ }
1691
+
1692
+ // Set a unique field name for boolean group headings.
1693
+ if ( ! empty( $boolean_group ) ) {
1694
+ $field_options['name'] = $field_name . '_' . md5( json_encode( $boolean_group ) );
1695
+ }
1696
+
1697
+ $field = $this->backcompat_convert_tabs_to_groups_setup_field( [
1698
+ 'field_name' => $field_name,
1699
+ 'field_options' => $field_options,
1700
+ 'parent' => $parent,
1701
+ 'group_name' => $group_name,
1702
+ ] );
1703
+
1704
+ $fields[] = $storage->add( $field );
1705
+ }
1706
  }
1707
  }
1708
 
1709
+ return compact( 'groups', 'fields' );
1710
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1711
 
1712
+ /**
1713
+ * Setup field for backwards compatibility tabs to groups layer.
1714
+ *
1715
+ * @since 2.8.0
1716
+ *
1717
+ * @param array $args {
1718
+ * The field arguments.
1719
+ *
1720
+ * @type string $field_name The field name.
1721
+ * @type array $field_options The field options.
1722
+ * @type string|int $parent The parent group.
1723
+ * @type string $group_name The group name.
1724
+ * }
1725
+ *
1726
+ * @return \Pods\Whatsit\Field The field object.
1727
+ */
1728
+ public function backcompat_convert_tabs_to_groups_setup_field( $args ) {
1729
+ $field_name = $args['field_name'];
1730
+ $field_options = $args['field_options'];
1731
+ $parent = $args['parent'];
1732
+ $group_name = $args['group_name'];
1733
+
1734
+ $field_args = $field_options;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1735
 
1736
+ if ( ! isset( $field_args['name'] ) ) {
1737
+ $field_args['name'] = $field_name;
1738
  }
1739
 
1740
+ $field_args['parent'] = $parent;
1741
+ $field_args['group'] = 'group/' . $parent . '/' . $group_name;
1742
+
1743
+ $dfv_args = (object) [
1744
+ 'id' => 0,
1745
+ 'name' => $field_args['name'],
1746
+ 'value' => '',
1747
+ 'pod' => null,
1748
+ 'type' => pods_v( 'type', $field_args ),
1749
+ 'options' => array_merge( [
1750
+ 'id' => 0,
1751
+ ], $field_args )
1752
+ ];
1753
+
1754
+ if ( ! empty( $dfv_args->type ) ) {
1755
+ $field_args = PodsForm::field_method( $dfv_args->type, 'build_dfv_field_options', $field_args, $dfv_args );
1756
+ }
1757
 
1758
+ return new \Pods\Whatsit\Field( $field_args );
1759
  }
1760
 
1761
  /**
1764
  * @param PodsUI $obj PodsUI object.
1765
  */
1766
  public function admin_setup_duplicate( $obj ) {
 
1767
  $new_id = pods_api()->duplicate_pod( array( 'id' => $obj->id ) );
1768
 
1769
  if ( 0 < $new_id ) {
1776
  )
1777
  )
1778
  );
1779
+
1780
+ return;
1781
  }
1782
+
1783
+ $obj->error( __( 'An error occurred, the Pod was not duplicated.', 'pods' ) );
1784
  }
1785
 
1786
  /**
1864
  /**
1865
  * Delete a pod
1866
  *
 
1867
  * @param PodsUI $obj PodsUI object.
1868
+ * @param int|string $id Item ID.
1869
  *
1870
  * @return mixed
1871
  */
1872
+ public function admin_setup_delete( $obj, $id ) {
1873
 
1874
  $pod = pods_api()->load_pod( array( 'id' => $id ), false );
1875
 
1879
 
1880
  pods_api()->delete_pod( array( 'id' => $id ) );
1881
 
1882
+ foreach ( $obj->data as $key => $data_pod ) {
1883
+ if ( (int) $id === (int) $data_pod['id'] ) {
1884
+ unset( $obj->data[ $key ] );
1885
+ }
1886
+ }
1887
 
1888
  $obj->total = count( $obj->data );
1889
  $obj->total_found = count( $obj->data );
1890
 
1891
  $obj->message( __( 'Pod deleted successfully.', 'pods' ) );
1892
+
1893
+ $obj->manage();
1894
  }
1895
 
1896
  /**
1905
  * Get settings administration view
1906
  */
1907
  public function admin_settings() {
1908
+ /**
1909
+ * Allow hooking into our settings page to set up hooks.
1910
+ *
1911
+ * @since 2.8.0
1912
+ */
1913
+ do_action( 'pods_admin_settings_init' );
1914
 
1915
  // Add our custom callouts.
1916
  add_action( 'pods_admin_after_settings', array( $this, 'admin_manage_callouts' ) );
2040
  }//end foreach
2041
 
2042
  $ui = array(
2043
+ 'sql' => array(
2044
+ 'field_id' => 'id',
2045
+ ),
2046
  'data' => $components,
2047
  'total' => count( $components ),
2048
  'total_found' => count( $components ),
2277
 
2278
  $pods = pods_api()->load_pods(
2279
  array(
2280
+ 'type' => array(
2281
  'settings',
2282
  'post_type',
2283
  'taxonomy',
2284
  ),
 
 
2285
  )
2286
  );
2287
 
2288
  $other_pods = pods_api()->load_pods(
2289
  array(
2290
+ 'type' => array(
2291
  'pod',
2292
  'table',
2293
  ),
 
2294
  )
2295
  );
2296
 
2347
  } else {
2348
  $capabilities[] = 'pods_add_' . $pod['name'];
2349
  $capabilities[] = 'pods_edit_' . $pod['name'];
2350
+ $capabilities[] = 'pods_delete_' . $pod['name'];
2351
 
2352
+ if ( $pod instanceof Pod ) {
2353
+ $author_field = $pod->get_field( 'author', null, false );
2354
+ } else {
2355
+ $author_field = pods_v( 'author', $pod['fields'] );
2356
  }
2357
 
2358
+ if ( $author_field && 'pick' === $author_field['type'] && 'user' === $author_field['pick_object'] ) {
2359
+ $capabilities[] = 'pods_edit_others_' . $pod['name'];
 
2360
  $capabilities[] = 'pods_delete_others_' . $pod['name'];
2361
  }
2362
 
2563
  * @return array
2564
  *
2565
  * @since 2.7.0
2566
+ * @deprecated 2.8.0
2567
  */
2568
  public function configuration( $pod = null, $full_field_info = false ) {
2569
+ pods_deprecated( 'PodsAdmin::configuration', '2.8' );
2570
 
2571
  $api = pods_api();
2572
 
2641
  'add_rest_fields_to_field_editor',
2642
  ), 12, 2
2643
  );
2644
+ add_filter( 'pods_admin_setup_edit_field_tabs', array( $this, 'add_rest_field_tab' ), 12, 2 );
2645
  }
2646
 
2647
  add_filter( 'pods_admin_setup_edit_tabs', array( $this, 'add_rest_settings_tab' ), 12, 2 );
2686
  * @return array
2687
  */
2688
  public function add_rest_settings_tab( $tabs, $pod ) {
2689
+ if ( ! $this->restable_pod( $pod ) ) {
2690
+ return $tabs;
2691
+ }
2692
 
2693
  $tabs['rest-api'] = __( 'REST API', 'pods' );
2694
 
2707
  * @return array
2708
  */
2709
  public function add_rest_settings_tab_fields( $options, $pod ) {
2710
+ if ( ! $this->restable_pod( $pod ) ) {
2711
+ return $options;
2712
+ }
2713
 
2714
+ $options['rest-api'] = [
2715
+ 'rest_enable' => [
2716
+ 'label' => __( 'Enable', 'pods' ),
2717
+ 'help' => __( 'Add REST API support for this Pod.', 'pods' ),
2718
+ 'type' => 'boolean',
2719
+ 'default' => '',
2720
+ 'dependency' => true,
2721
+ ],
2722
+ 'rest_base' => [
2723
+ 'label' => __( 'REST Base (if any)', 'pods' ),
2724
+ 'help' => __( 'This will form the url for the route. Default / empty value here will use the pod name.', 'pods' ),
2725
+ 'type' => 'text',
2726
+ 'default' => '',
2727
+ 'depends-on' => [ 'rest_enable' => true ],
2728
+ ],
2729
+ 'read_all' => [
2730
+ 'label' => __( 'Show All Fields (read-only)', 'pods' ),
2731
+ 'help' => __( 'Show all fields in REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ),
2732
+ 'type' => 'boolean',
2733
+ 'default' => '',
2734
+ 'depends-on' => [ 'rest_enable' => true ],
2735
+ ],
2736
+ 'write_all' => [
2737
+ 'label' => __( 'Allow All Fields To Be Updated', 'pods' ),
2738
+ 'help' => __( 'Allow all fields to be updated via the REST API. If unchecked fields must be enabled on a field by field basis.', 'pods' ),
2739
+ 'type' => 'boolean',
2740
+ 'default' => pods_v( 'name', $pod ),
2741
+ 'boolean_yes_label' => '',
2742
+ 'depends-on' => [ 'rest_enable' => true ],
2743
+ ],
2744
+ ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2745
 
2746
  return $options;
 
2747
  }
2748
 
2749
  /**
2757
  * @return array
2758
  */
2759
  public function add_rest_fields_to_field_editor( $options, $pod ) {
2760
+ if ( ! $this->restable_pod( $pod ) ) {
2761
+ return $options;
2762
+ }
2763
 
2764
+ $options['rest'][ __( 'Read/ Write', 'pods' ) ] = [
2765
+ 'rest_read' => [
2766
+ 'label' => __( 'Read via REST API', 'pods' ),
2767
+ 'help' => __( 'Should this field be readable via the REST API? You must enable REST API support for this Pod.', 'pods' ),
2768
+ 'type' => 'boolean',
2769
+ 'default' => '',
2770
+ ],
2771
+ 'rest_write' => [
2772
+ 'label' => __( 'Write via REST API', 'pods' ),
2773
+ 'help' => __( 'Should this field be writeable via the REST API? You must enable REST API support for this Pod.', 'pods' ),
2774
+ 'type' => 'boolean',
2775
+ 'default' => '',
2776
+ ],
2777
+ ];
2778
+
2779
+ $options['rest'][ __( 'Relationship Field Options', 'pods' ) ] = [
2780
+ 'rest_pick_response' => [
2781
+ 'label' => __( 'Response Type', 'pods' ),
2782
+ 'help' => __( 'This will determine what amount of data for the related items will be returned.', 'pods' ),
2783
+ 'type' => 'pick',
2784
+ 'default' => 'array',
2785
+ 'depends-on' => [
2786
+ 'type' => 'pick',
2787
+ ],
2788
+ 'dependency' => true,
2789
+ 'data' => [
2790
+ 'array' => __( 'All fields', 'pods' ),
2791
+ 'id' => __( 'ID only', 'pods' ),
2792
+ 'name' => __( 'Name only', 'pods' ),
2793
+ 'custom' => __( 'Custom return (specify field to return)', 'pods' ),
2794
+ ],
2795
+ ],
2796
+ 'rest_pick_depth' => [
2797
+ 'label' => __( 'Depth', 'pods' ),
2798
+ 'help' => __( 'How far to traverse relationships in response. 1 will get you all of the fields on the related item. 2 will get you all of those fields plus related items and their fields. The higher the depth, the more data will be returned and the slower performance the REST API calls will be. Updates to this field do NOT take depth into account, so you will always send the ID of the related item when saving.', 'pods' ),
2799
+ 'type' => 'number',
2800
+ 'default' => '1',
2801
+ 'depends-on' => [
2802
+ 'type' => 'pick',
2803
+ 'rest_pick_response' => 'array',
2804
+ ],
2805
+ ],
2806
+ 'rest_pick_custom' => [
2807
+ 'label' => __( 'Custom return', 'pods' ),
2808
+ 'help' => __( 'Specify the field to use following the established this_field_name.ID traversal pattern. You must include this field name in the selector for this to work properly.', 'pods' ),
2809
+ 'type' => 'text',
2810
+ 'default' => '',
2811
+ 'placeholder' => 'this_field_name.ID',
2812
+ 'depends-on' => [
2813
+ 'type' => 'pick',
2814
+ 'rest_pick_response' => 'custom',
2815
+ ],
2816
+ ],
2817
+ 'rest_pick_notice' => [
2818
+ 'label' => 'Relationship Options',
2819
+ 'type' => 'html',
2820
+ 'html_content' => __( 'If you have a relationship field, you will see additional options to customize here.', 'pods' ),
2821
+ 'excludes-on' => [ 'type' => 'pick' ],
2822
+ ],
2823
+ ];
2824
 
2825
  return $options;
 
2826
  }
2827
 
2828
  /**
2831
  * @since 2.5.6
2832
  *
2833
  * @param array $tabs Tab list.
2834
+ * @param array $pod The ood object.
2835
  *
2836
  * @return array
2837
  */
2838
+ public function add_rest_field_tab( $tabs, $pod ) {
2839
+ if ( ! $this->restable_pod( $pod ) ) {
2840
+ return $tabs;
2841
+ }
2842
 
2843
  $tabs['rest'] = __( 'REST API', 'pods' );
2844
 
2855
  * @return array Debug info with Pods-specific debug info added.
2856
  */
2857
  public function add_debug_information( $info ) {
2858
+ $auto_start = pods_session_auto_start();
2859
+
2860
+ if ( 'auto' !== $auto_start ) {
2861
+ // Turn boolean into 0/1.
2862
+ $auto_start = (int) $auto_start;
2863
+ }
2864
+
2865
+ // Turn into a string.
2866
+ $auto_start = (string) $auto_start;
2867
+
2868
+ $settings = tribe( Settings::class );
2869
+
2870
+ $fields = $settings->get_setting_fields();
2871
+
2872
+ $auto_start = pods_v( $auto_start, $fields['session_auto_start']['data'], __( 'Unknown', 'pods' ) );
2873
+
2874
+ $info['pods'] = [
2875
  'label' => 'Pods',
2876
  'description' => __( 'Debug information for Pods installations.', 'pods' ),
2877
+ 'fields' => [
2878
+ 'pods-server-software' => [
2879
  'label' => __( 'Server Software', 'pods' ),
2880
  'value' => ! empty( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : 'N/A',
2881
+ ],
2882
+ 'pods-user-agent' => [
2883
  'label' => __( 'Your User Agent', 'pods' ),
2884
  'value' => ! empty( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : 'N/A',
2885
+ ],
2886
+ 'pods-session-save-path' => [
2887
  'label' => __( 'Session Save Path', 'pods' ),
2888
  'value' => session_save_path(),
2889
+ ],
2890
+ 'pods-session-save-path-exists' => [
2891
  'label' => __( 'Session Save Path Exists', 'pods' ),
2892
  'value' => file_exists( session_save_path() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2893
+ ],
2894
+ 'pods-session-save-path-writable' => [
2895
  'label' => __( 'Session Save Path Writeable', 'pods' ),
2896
  'value' => is_writable( session_save_path() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2897
+ ],
2898
+ 'pods-session-max-lifetime' => [
2899
  'label' => __( 'Session Max Lifetime', 'pods' ),
2900
  'value' => ini_get( 'session.gc_maxlifetime' ),
2901
+ ],
2902
+ 'pods-opcode-cache-apc' => [
2903
  'label' => __( 'Opcode Cache: Apc', 'pods' ),
2904
  'value' => function_exists( 'apc_cache_info' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2905
+ ],
2906
+ 'pods-opcode-cache-memcached' => [
2907
  'label' => __( 'Opcode Cache: Memcached', 'pods' ),
2908
  'value' => class_exists( 'eaccelerator_put' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2909
+ ],
2910
+ 'pods-opcode-cache-opcache' => [
2911
  'label' => __( 'Opcode Cache: OPcache', 'pods' ),
2912
  'value' => function_exists( 'opcache_get_status' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2913
+ ],
2914
+ 'pods-opcode-cache-redis' => [
2915
  'label' => __( 'Opcode Cache: Redis', 'pods' ),
2916
  'value' => class_exists( 'xcache_set' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2917
+ ],
2918
+ 'pods-object-cache-apc' => [
2919
  'label' => __( 'Object Cache: APC', 'pods' ),
2920
  'value' => function_exists( 'apc_cache_info' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2921
+ ],
2922
+ 'pods-object-cache-apcu' => [
2923
  'label' => __( 'Object Cache: APCu', 'pods' ),
2924
  'value' => function_exists( 'apcu_cache_info' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2925
+ ],
2926
+ 'pods-object-cache-memcache' => [
2927
  'label' => __( 'Object Cache: Memcache', 'pods' ),
2928
  'value' => class_exists( 'Memcache' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2929
+ ],
2930
+ 'pods-object-cache-memcached' => [
2931
  'label' => __( 'Object Cache: Memcached', 'pods' ),
2932
  'value' => class_exists( 'Memcached' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2933
+ ],
2934
+ 'pods-object-cache-redis' => [
2935
  'label' => __( 'Object Cache: Redis', 'pods' ),
2936
  'value' => class_exists( 'Redis' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2937
+ ],
2938
+ 'pods-memory-current-usage' => [
2939
  'label' => __( 'Current Memory Usage', 'pods' ),
2940
  'value' => number_format_i18n( memory_get_usage() / 1024 / 1024, 3 ) . 'M',
2941
+ ],
2942
+ 'pods-memory-current-usage-real' => [
2943
  'label' => __( 'Current Memory Usage (real)', 'pods' ),
2944
  'value' => number_format_i18n( memory_get_usage( true ) / 1024 / 1024, 3 ) . 'M',
2945
+ ],
2946
+ 'pods-network-wide' => [
2947
  'label' => __( 'Pods Network-Wide Activated', 'pods' ),
2948
  'value' => is_plugin_active_for_network( basename( PODS_DIR ) . '/init.php' ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2949
+ ],
2950
+ 'pods-install-location' => [
2951
  'label' => __( 'Pods Install Location', 'pods' ),
2952
  'value' => PODS_DIR,
2953
+ ],
2954
+ 'pods-developer' => [
2955
  'label' => __( 'Pods Developer Activated' ),
2956
  'value' => ( pods_developer() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2957
+ ],
2958
+ 'pods-tableless-mode' => [
2959
  'label' => __( 'Pods Tableless Mode Activated', 'pods' ),
2960
  'value' => ( pods_tableless() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2961
+ ],
2962
+ 'pods-relationship-table-enabled' => [
2963
+ 'label' => __( 'Pods Relationship Table Enabled', 'pods' ),
2964
+ 'value' => ( pods_podsrel_enabled() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2965
+ ],
2966
+ 'pods-light-mode' => [
2967
  'label' => __( 'Pods Light Mode Activated', 'pods' ),
2968
  'value' => ( pods_light() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2969
+ ],
2970
+ 'pods-strict' => [
2971
  'label' => __( 'Pods Strict Activated' ),
2972
+ 'value' => ( pods_strict( false ) ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2973
+ ],
2974
+ 'pods-allow-deprecated' => [
2975
  'label' => __( 'Pods Allow Deprecated' ),
2976
  'value' => ( pods_allow_deprecated() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2977
+ ],
2978
+ 'pods-api-cache' => [
2979
  'label' => __( 'Pods API Cache Activated' ),
2980
  'value' => ( pods_api_cache() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2981
+ ],
2982
+ 'pods-shortcode-allow-evaluate-tags' => [
2983
  'label' => __( 'Pods Shortcode Allow Evaluate Tags' ),
2984
  'value' => ( pods_shortcode_allow_evaluate_tags() ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2985
+ ],
2986
+ 'pods-sessions' => [
2987
+ 'label' => __( 'Pods Sessions' ),
2988
+ 'value' => $auto_start,
2989
+ ],
2990
+ 'pods-can-use-sessions' => [
2991
+ 'label' => __( 'Pods Can Use Sessions' ),
2992
+ 'value' => ( pods_can_use_sessions( true ) ) ? __( 'Yes', 'pods' ) : __( 'No', 'pods' ),
2993
+ ],
2994
+ ],
2995
+ ];
2996
 
2997
  return $info;
2998
  }
2999
 
3000
+ /**
3001
+ * Add our site status tests.
3002
+ *
3003
+ * @since 2.8.0
3004
+ *
3005
+ * @param array $tests The list of status tests.
3006
+ *
3007
+ * @return array The list of status tests.
3008
+ */
3009
+ public function site_status_tests( $tests ) {
3010
+ $plugin_search_url = 'plugin-install.php?tab=search&type=term&s=';
3011
+
3012
+ if ( is_multisite() && ! is_network_admin() ) {
3013
+ $plugin_search_url = network_admin_url( $plugin_search_url );
3014
+ } else {
3015
+ $plugin_search_url = self_admin_url( $plugin_search_url );
3016
+ }
3017
+
3018
+ if ( ! is_pods_alternative_cache_activated() ) {
3019
+ $tests['direct']['pods_alternative_cache'] = [
3020
+ 'label' => __( 'Pods Alternative Cache', 'pods' ),
3021
+ 'test' => static function () use ( $plugin_search_url ) {
3022
+ return [
3023
+ 'label' => __( 'The Pods Team recommends you install the Pods Alternative Cache plugin', 'pods' ),
3024
+ 'status' => 'recommended',
3025
+ 'badge' => [
3026
+ 'label' => __( 'Performance', 'pods' ),
3027
+ 'color' => 'blue',
3028
+ ],
3029
+ 'description' => sprintf( '<p>%s</p>', __( 'Pods Alternative Cache is usually useful for Pods installs that use Shared Hosting with limited Object Cache capabilities or limits.', 'pods' ) ),
3030
+ 'actions' => sprintf( '<p><a href="%s">%s</a></p>', esc_url( $plugin_search_url . urlencode( 'Pods Alternative Cache' ) ), __( 'Install Pods Alternative Cache', 'pods' ) ),
3031
+ 'test' => 'pods_alternative_cache',
3032
+ ];
3033
+ },
3034
+ ];
3035
+ }
3036
+
3037
+ // Check if any of the Pods Pro Page Builder Toolkit plugins are active.
3038
+ $bb_active = defined( 'FL_BUILDER_VERSION' );
3039
+ $divi_active = defined( 'ET_BUILDER_PRODUCT_VERSION' );
3040
+ $oxygen_active = defined( 'CT_VERSION' );
3041
+ $pods_pro_pbtk_active = class_exists( '\Pods_Pro\Page_Builder_Toolkit\Plugin' );
3042
+
3043
+ if ( ! $pods_pro_pbtk_active && ( $bb_active || $divi_active || $oxygen_active ) ) {
3044
+ $tests['direct']['pods_pro_page_builder_toolkit'] = [
3045
+ 'label' => __( 'Pods Pro Page Builder Toolkit', 'pods' ),
3046
+ 'test' => static function () {
3047
+ return [
3048
+ 'label' => __( 'The Pods Team recommends you use the Pods Pro Page Builder Toolkit by SKCDEV', 'pods' ),
3049
+ 'status' => 'recommended',
3050
+ 'badge' => [
3051
+ 'label' => __( 'Page Builder', 'pods' ),
3052
+ 'color' => 'blue',
3053
+ ],
3054
+ 'description' => sprintf( '<p>%s</p>', __( 'Pods Pro Page Builder Toolkit by SKCDEV integrates Pods directly with Beaver Builder Themer, Divi, and Oxygen Builder.', 'pods' ) ),
3055
+ 'actions' => sprintf( '<p><a href="%s" target="_blank" rel="noopener noreferrer">%s</a></p>', esc_url( 'https://pods-pro.skc.dev/?utm_source=pods_plugin_site_health_callout&utm_medium=link&utm_campaign=friends_of_pods_2021' ), __( 'Get Pods Pro by SKCDEV', 'pods' ) ),
3056
+ 'test' => 'pods_pro_page_builder_toolkit',
3057
+ ];
3058
+ },
3059
+ ];
3060
+ }
3061
+
3062
+ return $tests;
3063
+ }
3064
+
3065
  }
classes/PodsComponents.php CHANGED
@@ -496,9 +496,9 @@ class PodsComponents {
496
 
497
  ksort( $components );
498
 
499
- pods_transient_set( 'pods_components_refresh', 1, ( 60 * 60 * 12 ) );
500
 
501
- pods_transient_set( 'pods_components', $components );
502
  }//end if
503
 
504
  if ( 1 === (int) pods_v( 'pods_debug_components', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) {
496
 
497
  ksort( $components );
498
 
499
+ pods_transient_set( 'pods_components_refresh', 1, HOUR_IN_SECONDS * 12 );
500
 
501
+ pods_transient_set( 'pods_components', $components, WEEK_IN_SECONDS );
502
  }//end if
503
 
504
  if ( 1 === (int) pods_v( 'pods_debug_components', 'get', 0 ) && pods_is_admin( array( 'pods' ) ) ) {
classes/PodsData.php CHANGED
@@ -1,7 +1,31 @@
1
  <?php
2
 
 
 
 
 
3
  /**
 
 
4
  * @package Pods
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  */
6
  class PodsData {
7
 
@@ -31,80 +55,29 @@ class PodsData {
31
  public $api = null;
32
 
33
  /**
34
- * @var null
35
- */
36
- public $select = null;
37
-
38
- /**
39
- * @var null
40
- */
41
- public $table = null;
42
-
43
- /**
44
- * @var null
45
- */
46
- public $pod = null;
47
-
48
- /**
49
- * @var array|bool|mixed|null|void
50
  */
51
  public $pod_data = null;
52
 
53
  /**
54
- * @var int
55
- */
56
- public $id = 0;
57
-
58
- /**
59
- * @var string
60
- */
61
- public $field_id = 'id';
62
-
63
- /**
64
- * @var string
65
- */
66
- public $field_index = 'name';
67
-
68
- /**
69
- * @var string
70
- */
71
- public $field_slug = '';
72
-
73
- /**
74
- * @var string
75
- */
76
- public $join = '';
77
-
78
- /**
79
- * @var array
80
- */
81
- public $where = array();
82
-
83
- /**
84
  * @var array
85
  */
86
- public $where_default = array();
87
-
88
- /**
89
- * @var string
90
- */
91
- public $orderby = '';
92
 
93
  /**
94
- * @var array
95
  */
96
- public $fields = array();
97
 
98
  /**
99
  * @var array
100
  */
101
  public $aliases = array();
102
 
103
- /**
104
- * @var
105
- */
106
- public $detail_page;
107
-
108
  /**
109
  * @var int
110
  */
@@ -113,7 +86,7 @@ class PodsData {
113
  /**
114
  * @var
115
  */
116
- public $data;
117
 
118
  /**
119
  * @var
@@ -155,6 +128,11 @@ class PodsData {
155
  */
156
  public $limit = 15;
157
 
 
 
 
 
 
158
  /**
159
  * @var bool
160
  */
@@ -197,6 +175,11 @@ class PodsData {
197
  */
198
  public $filters = array();
199
 
 
 
 
 
 
200
  /**
201
  * Holds Traversal information about Pods
202
  *
@@ -228,19 +211,29 @@ class PodsData {
228
  /**
229
  * Singleton handling for a basic pods_data() request
230
  *
231
- * @param string $pod Pod name.
232
- * @param integer $id Pod Item ID.
233
- * @param bool $strict If true throws an error if a pod is not found.
 
 
234
  *
235
- * @return \PodsData
236
  *
237
  * @since 2.3.5
238
  */
239
- public static function init( $pod = null, $id = 0, $strict = true ) {
 
 
 
 
 
 
 
240
 
241
- if ( ( true !== $pod && null !== $pod ) || 0 != $id ) {
242
- return new PodsData( $pod, $id, $strict );
243
- } elseif ( ! is_object( self::$instance ) ) {
 
244
  self::$instance = new PodsData();
245
  } else {
246
  $vars = get_class_vars( __CLASS__ );
@@ -260,93 +253,83 @@ class PodsData {
260
  /**
261
  * Data Abstraction Class for Pods
262
  *
263
- * @param string $pod Pod name.
264
- * @param integer $id Pod Item ID.
265
- * @param bool $strict If true throws an error if a pod is not found.
266
- *
267
- * @return \PodsData
268
  *
269
  * @license http://www.gnu.org/licenses/gpl-2.0.html
270
  * @since 2.0.0
271
  */
272
- public function __construct( $pod = null, $id = 0, $strict = true ) {
273
 
274
  global $wpdb;
275
 
276
- if ( is_object( $pod ) && 'PodsAPI' === get_class( $pod ) ) {
277
- $this->api = $pod;
278
- $pod = $this->api->pod;
279
- } else {
280
- $this->api = pods_api( $pod );
281
- }
282
-
283
  $this->api->display_errors =& self::$display_errors;
284
 
285
- if ( ! empty( $pod ) ) {
286
- $this->pod_data =& $this->api->pod_data;
287
-
288
- if ( false === $this->pod_data ) {
289
- if ( true === $strict ) {
290
- return pods_error( __( 'Pod not found', 'pods' ), $this );
291
- } else {
292
- return $this;
293
- }
294
- }
295
-
296
- $this->pod_id = $this->pod_data['id'];
297
- $this->pod = $this->pod_data['name'];
298
- $this->fields = $this->pod_data['fields'];
299
-
300
- if ( isset( $this->pod_data['options']['detail_url'] ) ) {
301
- $this->detail_page = $this->pod_data['options']['detail_url'];
302
- }
303
-
304
- if ( isset( $this->pod_data['select'] ) ) {
305
- $this->select = $this->pod_data['select'];
306
- }
307
-
308
- if ( isset( $this->pod_data['table'] ) ) {
309
- $this->table = $this->pod_data['table'];
310
- }
311
 
312
- if ( isset( $this->pod_data['join'] ) ) {
313
- $this->join = $this->pod_data['join'];
314
- }
 
 
 
 
 
 
 
315
 
316
- if ( isset( $this->pod_data['field_id'] ) ) {
317
- $this->field_id = $this->pod_data['field_id'];
318
- }
 
 
 
 
 
319
 
320
- if ( isset( $this->pod_data['field_index'] ) ) {
321
- $this->field_index = $this->pod_data['field_index'];
322
  }
 
323
 
324
- if ( isset( $this->pod_data['field_slug'] ) ) {
325
- $this->field_slug = $this->pod_data['field_slug'];
 
 
 
 
 
326
  }
 
327
 
328
- if ( isset( $this->pod_data['where'] ) ) {
329
- $this->where = $this->pod_data['where'];
 
 
 
 
330
  }
 
331
 
332
- if ( isset( $this->pod_data['where_default'] ) ) {
333
- $this->where_default = $this->pod_data['where_default'];
334
- }
335
 
336
- if ( isset( $this->pod_data['orderby'] ) ) {
337
- $this->orderby = $this->pod_data['orderby'];
338
- }
339
 
340
- if ( 'settings' === $this->pod_data['type'] ) {
341
- $this->id = $this->pod_data['id'];
342
 
343
- $this->fetch( $this->id );
344
- } elseif ( null !== $id && ! is_array( $id ) && ! is_object( $id ) ) {
345
- $this->id = $id;
346
 
347
- $this->fetch( $this->id );
348
- }
349
- }//end if
350
  }
351
 
352
  /**
@@ -356,83 +339,61 @@ class PodsData {
356
  * @param string $object
357
  */
358
  public function table( $table, $object = '' ) {
359
-
360
  global $wpdb;
361
 
362
- if ( ! is_array( $table ) ) {
363
  $object_type = '';
364
 
365
- if ( $wpdb->users === $table ) {
366
- $object_type = 'user';
367
- } elseif ( $wpdb->posts === $table ) {
368
  $object_type = 'post_type';
369
  } elseif ( $wpdb->terms === $table ) {
370
  $object_type = 'taxonomy';
 
 
 
 
371
  } elseif ( $wpdb->options === $table ) {
372
  $object_type = 'settings';
373
  }
374
- }
375
-
376
- if ( ! empty( $object_type ) ) {
377
- $table = $this->api->get_table_info( $object_type, $object );
378
- }
379
-
380
- if ( ! empty( $table ) && is_array( $table ) ) {
381
- $table['id'] = pods_v( 'id', $table['pod'], 0, true );
382
- $table['name'] = pods_v( 'name', $table['pod'], $table['object_type'], true );
383
- $table['type'] = pods_v( 'type', $table['pod'], $table['object_type'], true );
384
-
385
- $default_storage = 'meta';
386
-
387
- if ( 'taxonomy' === $table['type'] && ! function_exists( 'get_term_meta' ) ) {
388
- $default_storage = 'none';
389
- }
390
-
391
- $table['storage'] = pods_v( 'storage', $table['pod'], $default_storage, true );
392
- $table['fields'] = pods_v( 'fields', $table['pod'], array() );
393
- $table['object_fields'] = pods_v( 'object_fields', $table['pod'], $this->api->get_wp_object_fields( $table['object_type'] ), true );
394
-
395
- $this->pod_data = $table;
396
- $this->pod_id = $this->pod_data['id'];
397
- $this->pod = $this->pod_data['name'];
398
- $this->fields = $this->pod_data['fields'];
399
-
400
- if ( isset( $this->pod_data['select'] ) ) {
401
- $this->select = $this->pod_data['select'];
402
- }
403
-
404
- if ( isset( $this->pod_data['table'] ) ) {
405
- $this->table = $this->pod_data['table'];
406
- }
407
-
408
- if ( isset( $this->pod_data['join'] ) ) {
409
- $this->join = $this->pod_data['join'];
410
- }
411
 
412
- if ( isset( $this->pod_data['field_id'] ) ) {
413
- $this->field_id = $this->pod_data['field_id'];
414
- }
415
-
416
- if ( isset( $this->pod_data['field_index'] ) ) {
417
- $this->field_index = $this->pod_data['field_index'];
418
  }
 
419
 
420
- if ( isset( $this->pod_data['field_slug'] ) ) {
421
- $this->field_slug = $this->pod_data['field_slug'];
422
- }
 
 
 
 
 
 
 
423
 
424
- if ( isset( $this->pod_data['where'] ) ) {
425
- $this->where = $this->pod_data['where'];
426
- }
 
 
 
 
 
427
 
428
- if ( isset( $this->pod_data['where_default'] ) ) {
429
- $this->where_default = $this->pod_data['where_default'];
 
 
430
  }
 
431
 
432
- if ( isset( $this->pod_data['orderby'] ) ) {
433
- $this->orderby = $this->pod_data['orderby'];
434
- }
435
- }//end if
 
 
436
  }
437
 
438
  /**
@@ -715,7 +676,11 @@ class PodsData {
715
 
716
  // Debug purposes.
717
  if ( ( 1 === (int) pods_v( 'pods_debug_sql', 'get', 0 ) || 1 === (int) pods_v( 'pods_debug_sql_all', 'get', 0 ) ) && pods_is_admin( array( 'pods' ) ) ) {
718
- echo '<textarea cols="100" rows="24">' . esc_textarea( $this->get_sql() ) . '</textarea>';
 
 
 
 
719
  }
720
 
721
  if ( empty( $this->sql ) ) {
@@ -742,32 +707,17 @@ class PodsData {
742
  */
743
  $results = apply_filters( 'pods_data_select', $results, $params, $this );
744
 
745
- $this->data = $results;
746
 
747
  $this->row_number = - 1;
748
  $this->row = null;
749
 
750
- // Fill in empty field data (if none provided).
751
- if ( ( ! isset( $this->fields ) || empty( $this->fields ) ) && ! empty( $this->data ) ) {
752
- $this->fields = array();
753
- $data = (array) @current( $this->data );
754
-
755
- foreach ( $data as $data_key => $data_value ) {
756
- $this->fields[ $data_key ] = array( 'label' => ucwords( str_replace( '-', ' ', str_replace( '_', ' ', $data_key ) ) ) );
757
- if ( isset( $this->pod_data['object_fields'][ $data_key ] ) ) {
758
- $this->fields[ $data_key ] = $this->pod_data['object_fields'][ $data_key ];
759
- }
760
- }
761
-
762
- $this->fields = PodsForm::fields_setup( $this->fields );
763
- }
764
-
765
  $this->total_found_calculated = false;
766
 
767
  $this->total = 0;
768
 
769
- if ( ! empty( $this->data ) ) {
770
- $this->total = count( (array) $this->data );
771
  }
772
 
773
  /**
@@ -784,7 +734,7 @@ class PodsData {
784
  $this->calculate_totals();
785
  }
786
 
787
- return $this->data;
788
  }
789
 
790
  /**
@@ -877,8 +827,10 @@ class PodsData {
877
 
878
  $pod = false;
879
 
880
- if ( is_array( $this->pod_data ) ) {
881
  $pod = $this->pod_data;
 
 
882
  }
883
 
884
  // Validate.
@@ -913,17 +865,45 @@ class PodsData {
913
 
914
  $merge_object_fields = false;
915
 
916
- if ( ( empty( $params->fields ) || ! is_array( $params->fields ) ) && ! empty( $pod ) && isset( $this->fields ) && ! empty( $this->fields ) ) {
 
 
 
 
 
 
917
  $params->fields = $this->fields;
918
 
 
 
 
 
919
  $merge_object_fields = true;
920
  }
921
 
922
- if ( ( empty( $params->object_fields ) || ! is_array( $params->object_fields ) ) && ! empty( $pod ) && isset( $pod['object_fields'] ) && ! empty( $pod['object_fields'] ) ) {
923
- $params->object_fields = $pod['object_fields'];
 
 
 
 
 
 
 
 
 
 
924
 
925
  if ( $merge_object_fields ) {
926
- $params->fields = array_merge( $params->object_fields, $params->fields );
 
 
 
 
 
 
 
 
927
  }
928
  }
929
 
@@ -941,7 +921,7 @@ class PodsData {
941
  $params->id = $this->field_id;
942
  }
943
 
944
- if ( empty( $params->table ) && ! empty( $pod ) && isset( $this->table ) && ! empty( $this->table ) ) {
945
  $params->table = $this->table;
946
  }
947
 
@@ -949,23 +929,30 @@ class PodsData {
949
  $params->pod_table_prefix = 't';
950
  }
951
 
952
- if ( ! empty( $pod ) && ! in_array(
953
- $pod['type'], array(
954
- 'pod',
955
- 'table',
956
- ), true
957
- ) && 'table' === $pod['storage'] ) {
 
958
  $params->pod_table_prefix = 'd';
959
  }
960
 
961
  $params->meta_fields = false;
962
 
963
- if ( ! empty( $pod ) && ! in_array(
964
- $pod['type'], array(
 
 
 
 
 
 
965
  'pod',
966
  'table',
967
- ), true
968
- ) && ( 'meta' === $pod['storage'] || ( 'none' === $pod['storage'] && function_exists( 'get_term_meta' ) ) ) ) {
969
  $params->meta_fields = true;
970
  }
971
 
@@ -1029,8 +1016,7 @@ class PodsData {
1029
  }
1030
 
1031
  if ( ! empty( $params->orderby ) ) {
1032
- if ( ! empty( $pod ) && 'post_type' === $pod['type'] && 'meta' === $pod['storage'] && is_array( $params->orderby ) ) {
1033
-
1034
  foreach ( $params->orderby as $i => $orderby ) {
1035
  if ( strpos( $orderby, '.meta_value_num' ) ) {
1036
  $params->orderby[ $i ] = 'CAST(' . str_replace( '.meta_value_num', '.meta_value', $orderby ) . ' AS DECIMAL)';
@@ -1126,118 +1112,136 @@ class PodsData {
1126
  // Search.
1127
  if ( ! empty( $params->search ) && ! empty( $params->fields ) ) {
1128
  if ( false !== $params->search_query && 0 < strlen( $params->search_query ) ) {
1129
- $where = array();
1130
- $having = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1131
 
1132
  if ( false !== $params->search_across ) {
1133
- foreach ( $params->fields as $key => $field ) {
1134
- if ( is_array( $field ) ) {
1135
- $attributes = $field;
1136
- $field = pods_v( 'name', $field, $key, true );
1137
- } else {
1138
- $attributes = array(
1139
- 'type' => '',
1140
- 'options' => array(),
1141
- );
1142
- }
1143
 
1144
- if ( isset( $attributes['options']['search'] ) && ! $attributes['options']['search'] ) {
1145
- continue;
1146
- }
 
 
 
1147
 
1148
- if ( in_array(
1149
- $attributes['type'], array(
1150
- 'date',
1151
- 'time',
1152
- 'datetime',
1153
- 'number',
1154
- 'decimal',
1155
- 'currency',
1156
- 'phone',
1157
- 'password',
1158
- 'boolean',
1159
- 'comment',
1160
- 'taxonomy',
1161
- ), true
1162
- ) ) {
1163
- continue;
1164
- }
1165
 
1166
- $fieldfield = '`' . $field . '`';
 
1167
 
1168
- $is_object_field = isset( $params->object_fields[ $field ] );
 
 
 
 
 
 
 
 
1169
 
1170
- if ( in_array( $attributes['type'], $pick_field_types, true ) && ! in_array( pods_v( 'pick_object', $attributes ), $simple_tableless_objects, true ) ) {
1171
- if ( false === $params->search_across_picks ) {
1172
- continue;
1173
- } else {
1174
- if ( empty( $attributes['table_info'] ) ) {
1175
- $attributes['table_info'] = $this->api->get_table_info( pods_v( 'pick_object', $attributes ), pods_v( 'pick_val', $attributes ) );
1176
- }
1177
 
1178
- if ( empty( $attributes['table_info']['field_index'] ) ) {
1179
- continue;
1180
- }
 
1181
 
1182
- $fieldfield = $fieldfield . '.`' . $attributes['table_info']['field_index'] . '`';
1183
- }
1184
- } elseif ( in_array( $attributes['type'], $file_field_types, true ) ) {
1185
- if ( false === $params->search_across_files ) {
1186
- continue;
1187
- } else {
1188
- $fieldfield = $fieldfield . '.`post_title`';
1189
- }
1190
- } elseif ( isset( $params->fields[ $field ] ) && ! $is_object_field ) {
1191
- if ( $params->meta_fields ) {
1192
- $fieldfield = $fieldfield . '.`meta_value`';
1193
- } else {
1194
- $fieldfield = '`' . $params->pod_table_prefix . '`.' . $fieldfield;
1195
- }
1196
- } elseif ( ( empty( $params->object_fields ) || ! $is_object_field ) && 'meta' === $pod['storage'] ) {
1197
- $fieldfield = $fieldfield . '.`meta_value`';
1198
- } else {
1199
- $fieldfield = '`t`.' . $fieldfield;
1200
- }//end if
1201
 
1202
- if ( isset( $this->aliases[ $field ] ) ) {
1203
- $fieldfield = '`' . $this->aliases[ $field ] . '`';
1204
- }
 
 
 
 
 
 
 
 
1205
 
1206
- if ( ! empty( $attributes['real_name'] ) ) {
1207
- $fieldfield = $attributes['real_name'];
 
 
 
 
 
1208
  }
1209
 
1210
- if ( isset( $attributes['group_related'] ) && false !== $attributes['group_related'] ) {
1211
- $having[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'";
1212
- } else {
1213
- $where[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'";
1214
  }
1215
- }//end foreach
1216
- } elseif ( ! empty( $params->index ) ) {
1217
- $attributes = array();
1218
 
1219
- $fieldfield = '`t`.`' . $params->index . '`';
 
 
 
 
 
 
1220
 
1221
- if ( isset( $params->fields[ $params->index ] ) ) {
1222
- if ( $params->meta_fields && ! isset( $params->object_fields[ $params->index ] ) ) {
1223
- $fieldfield = '`' . $params->index . '`.`meta_value`';
 
 
 
1224
  } else {
1225
- $fieldfield = '`' . $params->pod_table_prefix . '`.`' . $params->index . '`';
 
1226
  }
1227
- } elseif ( ! empty( $params->object_fields ) && ! isset( $params->object_fields[ $params->index ] ) && 'meta' === $pod['storage'] ) {
1228
- $fieldfield = '`' . $params->index . '`.`meta_value`';
 
 
 
 
 
 
 
 
1229
  }
1230
 
1231
- if ( isset( $attributes['real_name'] ) && false !== $attributes['real_name'] && ! empty( $attributes['real_name'] ) ) {
1232
- $fieldfield = $attributes['real_name'];
1233
  }
1234
 
 
 
1235
  if ( isset( $attributes['group_related'] ) && false !== $attributes['group_related'] ) {
1236
- $having[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'";
1237
  } else {
1238
- $where[] = "{$fieldfield} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'";
1239
  }
1240
- }//end if
1241
 
1242
  if ( ! empty( $where ) ) {
1243
  $params->where[] = '( ' . implode( ' OR ', $where ) . ' )';
@@ -1284,13 +1288,13 @@ class PodsData {
1284
  $filterfield = $filterfield . '.`term_id`';
1285
  } elseif ( in_array( $attributes['type'], $file_field_types, true ) ) {
1286
  $filterfield = $filterfield . '.`post_title`';
1287
- } elseif ( isset( $params->fields[ $field ] ) ) {
1288
- if ( $params->meta_fields && 'meta' === $pod['storage'] ) {
1289
  $filterfield = $filterfield . '.`meta_value`';
1290
  } else {
1291
  $filterfield = '`' . $params->pod_table_prefix . '`.' . $filterfield;
1292
  }
1293
- } elseif ( ! empty( $params->object_fields ) && ! isset( $params->object_fields[ $field ] ) && 'meta' === $pod['storage'] ) {
1294
  $filterfield = $filterfield . '.`meta_value`';
1295
  } else {
1296
  $filterfield = '`t`.' . $filterfield;
@@ -1332,9 +1336,9 @@ class PodsData {
1332
  $filterfield = '`' . $field . '`.`' . $attributes['table_info']['field_id'] . '`';
1333
 
1334
  if ( isset( $attributes['group_related'] ) && false !== $attributes['group_related'] ) {
1335
- $having[] = "{$filterfield} = " . $filter_v;
1336
  } else {
1337
- $where[] = "{$filterfield} = " . $filter_v;
1338
  }
1339
  }//end if
1340
  }//end foreach
@@ -1407,7 +1411,7 @@ class PodsData {
1407
  }//end if
1408
 
1409
  // Traverse the Rabbit Hole.
1410
- if ( ! empty( $this->pod ) ) {
1411
  $haystack = implode( ' ', (array) $params->select ) . ' ' . implode( ' ', (array) $params->where ) . ' ' . implode( ' ', (array) $params->groupby ) . ' ' . implode( ' ', (array) $params->having ) . ' ' . implode( ' ', (array) $params->orderby );
1412
  $haystack = preg_replace( '/\s/', ' ', $haystack );
1413
  $haystack = preg_replace( '/\w\(/', ' ', $haystack );
@@ -1975,35 +1979,28 @@ class PodsData {
1975
 
1976
  $this->row = false;
1977
 
1978
- if ( isset( $this->data[ $this->row_number ] ) ) {
1979
- $this->row = get_object_vars( $this->data[ $this->row_number ] );
 
 
 
 
1980
 
1981
  $current_row_id = false;
1982
 
1983
- if ( in_array(
1984
- $this->pod_data['type'], array(
1985
- 'post_type',
1986
- 'media',
1987
- ), true
1988
- ) ) {
1989
- $current_row_id = pods_v( 'ID', $this->row );
1990
- } elseif ( 'taxonomy' === $this->pod_data['type'] ) {
1991
- $current_row_id = pods_v( 'term_id', $this->row );
1992
- } elseif ( 'user' === $this->pod_data['type'] ) {
1993
- $current_row_id = pods_v( 'ID', $this->row );
1994
- } elseif ( 'comment' === $this->pod_data['type'] ) {
1995
- $current_row_id = pods_v( 'comment_ID', $this->row );
1996
- } elseif ( 'settings' === $this->pod_data['type'] ) {
1997
  $current_row_id = $this->pod_data['id'];
 
 
1998
  }
1999
 
2000
- if ( 0 < $current_row_id ) {
2001
  $row = $current_row_id;
2002
  }
2003
  }//end if
2004
  }//end if
2005
 
2006
- if ( null !== $row || 'settings' === $this->pod_data['type'] ) {
2007
  if ( $explicit_set ) {
2008
  $this->row_number = - 1;
2009
  }
@@ -2011,7 +2008,7 @@ class PodsData {
2011
  $mode = 'id';
2012
  $id = pods_absint( $row );
2013
 
2014
- if ( ! is_numeric( $row ) || 0 === strpos( $row, '0' ) || $row != preg_replace( '/[^0-9]/', '', $row ) ) {
2015
  if ( $this->id && is_numeric( $this->id ) ) {
2016
  $id = $this->id;
2017
  } else {
@@ -2024,8 +2021,11 @@ class PodsData {
2024
 
2025
  if ( ! empty( $this->pod ) ) {
2026
  $row = pods_cache_get( $id, 'pods_items_' . $this->pod );
2027
- if ( false !== $row ) {
 
2028
  $already_cached = true;
 
 
2029
  }
2030
  }
2031
 
@@ -2034,56 +2034,60 @@ class PodsData {
2034
 
2035
  $old_row = $this->row;
2036
 
2037
- if ( false !== $row && is_array( $row ) ) {
 
 
2038
  $this->row = $row;
2039
  } elseif ( in_array(
2040
- $this->pod_data['type'], array(
2041
  'post_type',
2042
  'media',
2043
  ), true
2044
  ) ) {
2045
- if ( 'post_type' === $this->pod_data['type'] ) {
2046
- if ( empty( $this->pod_data['object'] ) ) {
2047
- $post_type = $this->pod_data['name'];
2048
- } else {
2049
  $post_type = $this->pod_data['object'];
2050
  }
2051
  } else {
2052
  $post_type = 'attachment';
2053
  }
2054
 
 
 
2055
  if ( 'id' === $mode ) {
2056
  $this->row = get_post( $id, ARRAY_A );
2057
 
2058
- if ( is_array( $this->row ) && $this->row['post_type'] != $post_type ) {
2059
  $this->row = false;
2060
  }
2061
  } else {
2062
- $args = array(
2063
- 'post_type' => $post_type,
2064
- 'name' => $id,
2065
- 'numberposts' => 5,
2066
- );
2067
 
2068
  $find = get_posts( $args );
2069
 
2070
  if ( ! empty( $find ) ) {
2071
- $this->row = get_object_vars( $find[0] );
2072
  }
2073
  }
2074
 
2075
- if ( is_wp_error( $this->row ) || empty( $this->row ) ) {
2076
  $this->row = false;
2077
  } else {
2078
  $current_row_id = $this->row['ID'];
2079
  }
2080
 
2081
  $get_table_data = true;
2082
- } elseif ( 'taxonomy' === $this->pod_data['type'] ) {
2083
- $taxonomy = $this->pod_data['object'];
2084
 
2085
- if ( empty( $taxonomy ) ) {
2086
- $taxonomy = $this->pod_data['name'];
2087
  }
2088
 
2089
  // Taxonomies are registered during init, so they aren't available before then.
@@ -2112,6 +2116,8 @@ class PodsData {
2112
  $_term = apply_filters( "get_$taxonomy", $_term, $taxonomy );
2113
  $_term = sanitize_term( $_term, $taxonomy, $filter );
2114
 
 
 
2115
  if ( is_object( $_term ) ) {
2116
  $this->row = get_object_vars( $_term );
2117
  }
@@ -2121,21 +2127,21 @@ class PodsData {
2121
  $this->row = get_term_by( 'slug', $id, $taxonomy, ARRAY_A );
2122
  }//end if
2123
 
2124
- if ( is_wp_error( $this->row ) || empty( $this->row ) ) {
2125
  $this->row = false;
2126
  } else {
2127
  $current_row_id = $this->row['term_id'];
2128
  }
2129
 
2130
  $get_table_data = true;
2131
- } elseif ( 'user' === $this->pod_data['type'] ) {
2132
  if ( 'id' === $mode ) {
2133
  $this->row = get_userdata( $id );
2134
  } else {
2135
  $this->row = get_user_by( 'slug', $id );
2136
  }
2137
 
2138
- if ( is_wp_error( $this->row ) || empty( $this->row ) ) {
2139
  $this->row = false;
2140
  } else {
2141
  // Get other vars.
@@ -2156,21 +2162,21 @@ class PodsData {
2156
  }
2157
 
2158
  $get_table_data = true;
2159
- } elseif ( 'comment' === $this->pod_data['type'] ) {
2160
  $this->row = get_comment( $id, ARRAY_A );
2161
 
2162
  // No slug handling here.
2163
- if ( is_wp_error( $this->row ) || empty( $this->row ) ) {
2164
  $this->row = false;
2165
  } else {
2166
  $current_row_id = $this->row['comment_ID'];
2167
  }
2168
 
2169
  $get_table_data = true;
2170
- } elseif ( 'settings' === $this->pod_data['type'] ) {
2171
- $this->row = array();
2172
 
2173
- if ( empty( $this->fields ) ) {
2174
  $this->row = false;
2175
  } else {
2176
  foreach ( $this->fields as $field ) {
@@ -2198,7 +2204,9 @@ class PodsData {
2198
  $params['where'] = "`t`.`{$this->field_slug}` = '{$id}'";
2199
  }
2200
 
2201
- $this->row = pods_data()->select( $params );
 
 
2202
 
2203
  if ( empty( $this->row ) ) {
2204
  $this->row = false;
@@ -2212,7 +2220,7 @@ class PodsData {
2212
  $this->row = array_merge( $old_row, $this->row );
2213
  }
2214
 
2215
- if ( 'table' === $this->pod_data['storage'] && false !== $get_table_data && is_numeric( $current_row_id ) ) {
2216
  $params = array(
2217
  'table' => self::get_pods_prefix(),
2218
  'where' => "`t`.`id` = {$current_row_id}",
@@ -2223,13 +2231,17 @@ class PodsData {
2223
  'strict' => true,
2224
  );
2225
 
2226
- if ( empty( $this->pod_data['object'] ) ) {
2227
- $params['table'] .= $this->pod_data['name'];
2228
- } else {
2229
- $params['table'] .= $this->pod_data['object'];
2230
  }
2231
 
2232
- $row = pods_data()->select( $params );
 
 
 
 
2233
 
2234
  if ( ! empty( $row ) ) {
2235
  $current_row = (array) $row;
@@ -2244,12 +2256,17 @@ class PodsData {
2244
  }//end if
2245
 
2246
  if ( ! empty( $this->pod ) && ! $already_cached ) {
2247
- pods_cache_set( $id, $this->row, 'pods_items_' . $this->pod, 0 );
2248
  }
2249
  }//end if
2250
 
2251
  $this->row = apply_filters( 'pods_data_fetch', $this->row, $id, $this->row_number, $this );
2252
 
 
 
 
 
 
2253
  return $this->row;
2254
  }
2255
 
@@ -2268,8 +2285,12 @@ class PodsData {
2268
 
2269
  $this->row = false;
2270
 
2271
- if ( isset( $this->data[ $row ] ) ) {
2272
- $this->row = get_object_vars( $this->data[ $row ] );
 
 
 
 
2273
  }
2274
 
2275
  if ( empty( $row ) ) {
@@ -2511,9 +2532,9 @@ class PodsData {
2511
  /**
2512
  * Get the string to use in a query for WHERE/HAVING, uses WP_Query meta_query arguments
2513
  *
2514
- * @param array $fields Array of field matches for querying.
2515
- * @param array $pod Related Pod.
2516
- * @param object $params Parameters passed from select().
2517
  *
2518
  * @return string|null Query string for WHERE/HAVING
2519
  *
@@ -2578,7 +2599,7 @@ class PodsData {
2578
 
2579
  if ( ! empty( $query_fields ) ) {
2580
  // If post_status not sent, detect it.
2581
- if ( ! empty( $pod ) && 'post_type' === $pod['type'] && 1 === $current_level && ! $params->where_defaulted && ! empty( $params->where_default ) ) {
2582
  $post_status_found = false;
2583
 
2584
  if ( ! $params->query_field_syntax ) {
@@ -2587,20 +2608,24 @@ class PodsData {
2587
  $haystack = preg_replace( '/\w\(/', ' ', $haystack );
2588
  $haystack = str_replace( array( '(', ')', ' ', '\\\'', '\\"' ), ' ', $haystack );
2589
 
 
2590
  preg_match_all( '/`?[\w\-]+`?(?:\\.`?[\w\-]+`?)+(?=[^"\']*(?:"[^"]*"[^"]*|\'[^\']*\'[^\']*)*$)/', $haystack, $found, PREG_PATTERN_ORDER );
2591
 
2592
- $found = (array) @current( $found );
 
2593
 
2594
- foreach ( $found as $value ) {
2595
- $value = str_replace( '`', '', $value );
2596
- $value = explode( '.', $value );
2597
 
2598
- if ( ( 'post_status' === $value[0] && 1 === count( $value ) ) || ( 2 === count( $value ) && 't' === $value[0] && 'post_status' === $value[1] ) ) {
2599
- $post_status_found = true;
 
 
 
 
2600
 
2601
- break;
2602
- }
2603
- }
2604
  } elseif ( ! empty( $params->query_fields ) && in_array( 'post_status', $params->query_fields, true ) ) {
2605
  $post_status_found = true;
2606
  }//end if
@@ -2632,7 +2657,7 @@ class PodsData {
2632
  *
2633
  * @param string|int $field Field name or array index.
2634
  * @param array|string $q Query array (meta_query) or string for matching.
2635
- * @param array $pod Related Pod.
2636
  * @param object $params Parameters passed from select().
2637
  *
2638
  * @return string|null Query field string
@@ -2713,25 +2738,37 @@ class PodsData {
2713
  $field_type = 'CHAR';
2714
  }
2715
 
 
 
2716
  // Alias / Casting.
2717
  if ( empty( $field_cast ) ) {
2718
  // Setup field casting from field name.
2719
  if ( false === strpos( $field_name, '`' ) && false === strpos( $field_name, '(' ) && false === strpos( $field_name, ' ' ) ) {
2720
  // Handle field naming if Pod-based.
2721
- if ( ! empty( $pod ) && false === strpos( $field_name, '.' ) ) {
2722
  $field_cast = '';
2723
 
 
 
 
 
 
 
 
 
2724
  $tableless_field_types = PodsForm::tableless_field_types();
2725
 
2726
- if ( isset( $pod['fields'][ $field_name ] ) && in_array( $pod['fields'][ $field_name ]['type'], $tableless_field_types, true ) ) {
2727
- if ( in_array( $pod['fields'][ $field_name ]['pick_object'], $simple_tableless_objects, true ) ) {
2728
- if ( 'meta' === $pod['storage'] ) {
 
 
2729
  $field_cast = "`{$field_name}`.`meta_value`";
2730
  } else {
2731
  $field_cast = "`t`.`{$field_name}`";
2732
  }
2733
  } else {
2734
- $table = pods_api()->get_table_info( $pod['fields'][ $field_name ]['pick_object'], $pod['fields'][ $field_name ]['pick_val'] );
2735
 
2736
  if ( ! empty( $table ) ) {
2737
  $field_cast = "`{$field_name}`.`" . $table['field_index'] . '`';
@@ -2740,39 +2777,29 @@ class PodsData {
2740
  }
2741
 
2742
  if ( empty( $field_cast ) ) {
2743
- if ( ! in_array(
2744
- $pod['type'], array(
2745
- 'pod',
2746
- 'table',
2747
- ), true
2748
- ) ) {
2749
- if ( isset( $pod['object_fields'][ $field_name ] ) ) {
2750
- $field_cast = "`t`.`{$field_name}`";
2751
- } elseif ( isset( $pod['fields'][ $field_name ] ) ) {
2752
- if ( 'meta' === $pod['storage'] ) {
2753
  $field_cast = "`{$field_name}`.`meta_value`";
2754
  } else {
2755
  $field_cast = "`d`.`{$field_name}`";
2756
  }
2757
- } else {
2758
- foreach ( $pod['object_fields'] as $object_field => $object_field_opt ) {
2759
- if ( $object_field === $field_name || in_array( $field_name, $object_field_opt['alias'], true ) ) {
2760
- $field_cast = "`t`.`{$object_field}`";
2761
-
2762
- break;
2763
- }
2764
- }
2765
- }
2766
- } elseif ( isset( $pod['fields'][ $field_name ] ) ) {
2767
- if ( 'meta' === $pod['storage'] ) {
2768
  $field_cast = "`{$field_name}`.`meta_value`";
2769
  } else {
2770
  $field_cast = "`t`.`{$field_name}`";
2771
- }
2772
  }//end if
2773
 
2774
  if ( empty( $field_cast ) ) {
2775
- if ( 'meta' === $pod['storage'] ) {
2776
  $field_cast = "`{$field_name}`.`meta_value`";
2777
  } else {
2778
  $field_cast = "`t`.`{$field_name}`";
@@ -2918,74 +2945,77 @@ class PodsData {
2918
  );
2919
 
2920
  // Make the query.
2921
- if ( in_array(
2922
- $field_compare, array(
2923
- '=',
2924
- '!=',
2925
- '>',
2926
- '>=',
2927
- '<',
2928
- '<=',
2929
- 'REGEXP',
2930
- 'NOT REGEXP',
2931
- 'RLIKE',
2932
- ), true
2933
- ) ) {
2934
  if ( $field_sanitize ) {
2935
- $field_query = $wpdb->prepare( $field_cast . ' ' . $field_compare . ' ' . $field_sanitize_format, $field_value );
 
2936
  } else {
2937
- $field_query = $field_cast . ' ' . $field_compare . ' "' . $field_value . '"';
2938
  }
2939
- } elseif ( in_array(
2940
- $field_compare, array(
2941
- 'LIKE',
2942
- 'NOT LIKE',
2943
- ), true
2944
- ) ) {
2945
  if ( $field_sanitize ) {
2946
- $field_query = $field_cast . ' ' . $field_compare . ' "%' . pods_sanitize_like( $field_value ) . '%"';
2947
  } else {
2948
- $field_query = $field_cast . ' ' . $field_compare . ' "' . $field_value . '"';
2949
  }
2950
- } elseif ( in_array(
2951
- $field_compare, array(
2952
- 'IN',
2953
- 'NOT IN',
2954
- 'ALL',
2955
- ), true
2956
- ) ) {
2957
  if ( 'ALL' === $field_compare ) {
2958
  $field_compare = 'IN';
2959
 
2960
- if ( ! empty( $pod ) ) {
2961
  $params->having[] = 'COUNT( DISTINCT ' . $field_cast . ' ) = ' . count( $field_value );
2962
 
2963
- if ( empty( $params->groupby ) || ( ! in_array( '`t`.`' . $pod['field_id'] . '`', $params->groupby, true ) && ! in_array( 't.' . $pod['field_id'] . '', $params->groupby, true ) ) ) {
2964
- $params->groupby[] = '`t`.`' . $pod['field_id'] . '`';
 
 
 
 
 
 
2965
  }
2966
  }
2967
  }
2968
 
2969
  if ( $field_sanitize ) {
2970
- $field_query = $wpdb->prepare( $field_cast . ' ' . $field_compare . ' ( ' . substr( str_repeat( ', ' . $field_sanitize_format, count( $field_value ) ), 1 ) . ' )', $field_value );
 
2971
  } else {
2972
- $field_query = $field_cast . ' ' . $field_compare . ' ( "' . implode( '", "', $field_value ) . '" )';
2973
  }
2974
- } elseif ( in_array(
2975
- $field_compare, array(
2976
- 'BETWEEN',
2977
- 'NOT BETWEEN',
2978
- ), true
2979
- ) ) {
2980
  if ( $field_sanitize ) {
2981
- $field_query = $wpdb->prepare( $field_cast . ' ' . $field_compare . ' ' . $field_sanitize_format . ' AND ' . $field_sanitize_format, $field_value );
 
2982
  } else {
2983
- $field_query = $field_cast . ' ' . $field_compare . ' "' . $field_value[0] . '" AND "' . $field_value[1] . '"';
2984
  }
2985
  } elseif ( 'EXISTS' === $field_compare ) {
2986
- $field_query = $field_cast . ' IS NOT NULL';
2987
  } elseif ( 'NOT EXISTS' === $field_compare ) {
2988
- $field_query = $field_cast . ' IS NULL';
2989
  }//end if
2990
 
2991
  $field_query = apply_filters( 'pods_data_field_query', $field_query, $q );
@@ -3041,35 +3071,28 @@ class PodsData {
3041
  * @since 2.0.0
3042
  */
3043
  public function traverse_recurse( $traverse_recurse ) {
3044
-
3045
  global $wpdb;
3046
 
3047
- $defaults = array(
3048
  'pod' => null,
3049
- 'fields' => array(),
3050
  'joined' => 't',
3051
  'depth' => 0,
3052
  'joined_id' => 'id',
3053
  'joined_index' => 'id',
3054
  'params' => new stdClass(),
3055
- 'last_table_info' => array(),
3056
- );
3057
 
3058
  $traverse_recurse = array_merge( $defaults, $traverse_recurse );
3059
 
3060
- $joins = array();
3061
 
3062
  if ( 0 === $traverse_recurse['depth'] && ! empty( $traverse_recurse['pod'] ) && ! empty( $traverse_recurse ['last_table_info'] ) && isset( $traverse_recurse ['last_table_info']['id'] ) ) {
3063
- $pod_data = $traverse_recurse ['last_table_info'];
3064
  } elseif ( empty( $traverse_recurse['pod'] ) ) {
3065
- if (
3066
- ! empty( $traverse_recurse['params'] )
3067
- && ! empty( $traverse_recurse['params']->table )
3068
- && (
3069
- ! $wpdb->prefix // Make sure there is a prefix.
3070
- || 0 === strpos( $traverse_recurse['params']->table, $wpdb->prefix )
3071
- )
3072
- ) {
3073
  if ( $wpdb->posts === $traverse_recurse['params']->table ) {
3074
  $traverse_recurse['pod'] = 'post_type';
3075
  } elseif ( $wpdb->terms === $traverse_recurse['params']->table ) {
@@ -3082,43 +3105,42 @@ class PodsData {
3082
  return $joins;
3083
  }
3084
 
3085
- $pod_data = array();
3086
 
3087
- if ( in_array(
3088
- $traverse_recurse['pod'], array(
3089
- 'user',
3090
- 'comment',
3091
- ), true
3092
- ) ) {
3093
- $pod = $this->api->load_pod(
3094
- array(
3095
- 'name' => $traverse_recurse['pod'],
3096
- 'table_info' => true,
3097
- )
3098
- );
3099
-
3100
- if ( ! empty( $pod ) && $pod['type'] === $pod ) {
3101
- $pod_data = $pod;
3102
  }
3103
  }
3104
 
3105
  if ( empty( $pod_data ) ) {
 
3106
  $default_storage = 'meta';
3107
 
3108
  if ( 'taxonomy' === $traverse_recurse['pod'] && ! function_exists( 'get_term_meta' ) ) {
3109
  $default_storage = 'none';
3110
  }
3111
 
3112
- $pod_data = array(
3113
  'id' => 0,
3114
  'name' => '_table_' . $traverse_recurse['pod'],
3115
  'type' => $traverse_recurse['pod'],
3116
  'storage' => $default_storage,
3117
- 'fields' => array(),
3118
- 'object_fields' => $this->api->get_wp_object_fields( $traverse_recurse['pod'] ),
3119
- );
3120
 
3121
- $pod_data = array_merge( $this->api->get_table_info( $traverse_recurse['pod'], '' ), $pod_data );
 
 
3122
  } elseif ( 'taxonomy' === $pod_data['type'] && 'none' === $pod_data['storage'] && function_exists( 'get_term_meta' ) ) {
3123
  $pod_data['storage'] = 'meta';
3124
  }
@@ -3128,28 +3150,22 @@ class PodsData {
3128
  return $joins;
3129
  }//end if
3130
  } else {
3131
- $pod_data = $this->api->load_pod(
3132
- array(
3133
- 'name' => $traverse_recurse['pod'],
3134
- 'table_info' => true,
3135
- ), false
3136
- );
3137
 
3138
  if ( empty( $pod_data ) ) {
3139
  return $joins;
3140
  }
3141
  }//end if
3142
 
3143
- if ( isset( $pod_data['object_fields'] ) ) {
3144
- $pod_data['fields'] = array_merge( $pod_data['fields'], $pod_data['object_fields'] );
3145
- }
3146
-
3147
  $tableless_field_types = PodsForm::tableless_field_types();
3148
  $simple_tableless_objects = PodsForm::simple_tableless_objects();
3149
  $file_field_types = PodsForm::file_field_types();
3150
 
3151
  if ( ! isset( $this->traversal[ $traverse_recurse['pod'] ] ) ) {
3152
- $this->traversal[ $traverse_recurse['pod'] ] = array();
3153
  }
3154
 
3155
  if ( ( empty( $pod_data['meta_table'] ) || $pod_data['meta_table'] === $pod_data['table'] ) && ( empty( $traverse_recurse['fields'] ) || empty( $traverse_recurse['fields'][ $traverse_recurse['depth'] ] ) ) ) {
@@ -3158,12 +3174,17 @@ class PodsData {
3158
 
3159
  $field = $traverse_recurse['fields'][ $traverse_recurse['depth'] ];
3160
 
3161
- $ignore_aliases = array(
3162
- 'wpml_languages',
3163
- 'polylang_languages',
3164
- );
3165
-
3166
- $ignore_aliases = apply_filters( 'pods_data_traverse_recurse_ignore_aliases', $ignore_aliases, $field, $traverse_recurse, $this );
 
 
 
 
 
3167
 
3168
  if ( in_array( $field, $ignore_aliases, true ) ) {
3169
  return $joins;
@@ -3182,69 +3203,82 @@ class PodsData {
3182
  $field_type = $traverse_recurse['last_table_info']['pod']['object_fields'][ $field ]['type'];
3183
  }
3184
 
3185
- $pod_data['fields'][ $field ] = array(
3186
  'id' => 0,
3187
  'name' => $field,
3188
  'type' => $field_type,
3189
  'pick_object' => $traverse_recurse['last_table_info']['pod']['type'],
3190
  'pick_val' => $traverse_recurse['last_table_info']['pod']['name'],
3191
- );
3192
 
3193
  $meta_data_table = true;
3194
  }//end if
3195
 
 
 
3196
  // Fallback to meta table if the pod type supports it.
3197
- if ( ! isset( $pod_data['fields'][ $field ] ) ) {
3198
- $last = end( $traverse_recurse['fields'] );
3199
 
3200
- if ( 'post_type' === $pod_data['type'] && ! isset( $pod_data['object_fields'] ) ) {
3201
- $pod_data['object_fields'] = $this->api->get_wp_object_fields( 'post_type', $pod_data );
3202
- }
 
 
 
3203
 
3204
- if ( 'post_type' === $pod_data['type'] && isset( $pod_data['object_fields'][ $field ] ) && in_array( $pod_data['object_fields'][ $field ]['type'], $tableless_field_types, true ) ) {
3205
- $pod_data['fields'][ $field ] = $pod_data['object_fields'][ $field ];
3206
- } elseif ( 'meta_value' === $last && in_array(
3207
- $pod_data['type'], array(
3208
  'post_type',
3209
  'media',
3210
  'taxonomy',
3211
  'user',
3212
  'comment',
3213
- ), true
3214
- ) ) {
3215
- $pod_data['fields'][ $field ] = PodsForm::field_setup( array( 'name' => $field ) );
3216
- } else {
3217
- if ( 'post_type' === $pod_data['type'] ) {
3218
- $pod_data['object_fields'] = $this->api->get_wp_object_fields( 'post_type', $pod_data, true );
3219
 
3220
- if ( 'post_type' === $pod_data['type'] && isset( $pod_data['object_fields'][ $field ] ) && in_array( $pod_data['object_fields'][ $field ]['type'], $tableless_field_types, true ) ) {
3221
- $pod_data['fields'][ $field ] = $pod_data['object_fields'][ $field ];
3222
- } else {
3223
- return $joins;
3224
- }
3225
- } else {
3226
- return $joins;
3227
  }
3228
- }//end if
3229
- } elseif ( isset( $pod_data['object_fields'] ) && isset( $pod_data['object_fields'][ $field ] ) && ! in_array( $pod_data['object_fields'][ $field ]['type'], $tableless_field_types, true ) ) {
 
 
3230
  return $joins;
3231
- }//end if
 
 
3232
 
3233
- $traverse = $pod_data['fields'][ $field ];
3234
 
3235
- if ( in_array( $traverse['type'], $file_field_types, true ) ) {
3236
- $traverse['table_info'] = $this->api->get_table_info( 'post_type', 'attachment' );
 
 
 
 
 
 
 
 
3237
  } elseif ( ! in_array( $traverse['type'], $tableless_field_types, true ) ) {
3238
- $traverse['table_info'] = $this->api->get_table_info( $pod_data['type'], $pod_data['name'], $pod_data['name'], $pod_data );
3239
- } elseif ( empty( $traverse['table_info'] ) || ( in_array( $traverse['pick_object'], $simple_tableless_objects, true ) && ! empty( $traverse_recurse['last_table_info'] ) ) ) {
3240
- if ( in_array( $traverse['pick_object'], $simple_tableless_objects, true ) && ! empty( $traverse_recurse['last_table_info'] ) ) {
3241
- $traverse['table_info'] = $traverse_recurse['last_table_info'];
 
 
 
 
 
 
3242
 
3243
- if ( ! empty( $traverse['table_info']['meta_table'] ) ) {
3244
  $meta_data_table = true;
3245
  }
3246
- } elseif ( ! in_array( $traverse['type'], $tableless_field_types, true ) && ! empty( $traverse_recurse['last_table_info'] ) && 0 === $traverse_recurse['depth'] ) {
3247
- $traverse['table_info'] = $traverse_recurse['last_table_info'];
3248
  } else {
3249
  if ( ! isset( $traverse['pod'] ) ) {
3250
  $traverse['pod'] = null;
@@ -3254,17 +3288,19 @@ class PodsData {
3254
  $traverse['pick_val'] = null;
3255
  }
3256
 
3257
- $traverse['table_info'] = $this->api->get_table_info( $traverse['pick_object'], $traverse['pick_val'], null, $traverse['pod'], $traverse );
 
 
3258
  }
3259
  }//end if
3260
 
3261
  if ( isset( $this->traversal[ $traverse_recurse['pod'] ][ $traverse['name'] ] ) ) {
3262
- $traverse = array_merge( $traverse, (array) $this->traversal[ $traverse_recurse['pod'] ][ $traverse['name'] ] );
3263
  }
3264
 
3265
  $traverse = apply_filters( 'pods_data_traverse', $traverse, $traverse_recurse, $this );
3266
 
3267
- if ( empty( $traverse ) ) {
3268
  return $joins;
3269
  }
3270
 
@@ -3274,14 +3310,12 @@ class PodsData {
3274
  $traverse['id'] = $field;
3275
  }
3276
 
3277
- $table_info = $traverse['table_info'];
3278
-
3279
  $this->traversal[ $traverse_recurse['pod'] ][ $field ] = $traverse;
3280
 
3281
  $field_joined = $field;
3282
 
3283
  if ( 0 < $traverse_recurse['depth'] && 't' !== $traverse_recurse['joined'] ) {
3284
- if ( $meta_data_table && ( 'pick' !== $traverse['type'] || ! in_array( pods_v( 'pick_object', $traverse, true ), $simple_tableless_objects ) ) ) {
3285
  $field_joined = $traverse_recurse['joined'] . '_d';
3286
  } else {
3287
  $field_joined = $traverse_recurse['joined'] . '_' . $field;
@@ -3412,19 +3446,26 @@ class PodsData {
3412
  LEFT JOIN `{$table_info['pod_table']}` AS `{$field_joined}` ON
3413
  `{$field_joined}`.`{$table_info['pod_field_id']}` = `{$traverse_recurse['rel_alias']}`.`{$joined_id}`
3414
  ";
3415
- } else {
3416
  if ( ( $traverse_recurse['depth'] + 2 ) === count( $traverse_recurse['fields'] ) && ( 'pick' !== $traverse['type'] || ! in_array( pods_v( 'pick_object', $traverse ), $simple_tableless_objects, true ) ) && 'post_author' === $traverse_recurse['fields'][ $traverse_recurse['depth'] + 1 ] ) {
3417
  $table_info['recurse'] = false;
3418
  }
3419
 
3420
- $the_join = "
3421
- LEFT JOIN `@wp_podsrel` AS `{$rel_alias}` ON
3422
- `{$rel_alias}`.`field_id` = {$traverse[ 'id' ]}
3423
- AND `{$rel_alias}`.`item_id` = `{$traverse_recurse[ 'joined' ]}`.`{$traverse_recurse[ 'joined_id' ]}`
 
 
 
 
 
 
3424
 
3425
- LEFT JOIN `{$table_info[ 'table' ]}` AS `{$field_joined}` ON
3426
- `{$field_joined}`.`{$table_info[ 'field_id' ]}` = `{$rel_alias}`.`related_item_id`
3427
- ";
 
3428
  }//end if
3429
  } elseif ( 'meta' === $pod_data['storage'] ) {
3430
  if ( ( $traverse_recurse['depth'] + 2 ) === count( $traverse_recurse['fields'] ) && ( 'pick' !== $traverse['type'] || ! in_array( pods_v( 'pick_object', $traverse ), $simple_tableless_objects, true ) ) && $table_info['meta_field_value'] === $traverse_recurse['fields'][ $traverse_recurse['depth'] + 1 ] ) {
@@ -3485,38 +3526,30 @@ class PodsData {
3485
  * @return array Array of joins
3486
  */
3487
  public function traverse( $fields = null, $all_fields = null, $params = null ) {
3488
-
3489
- $joins = array();
3490
-
3491
  if ( null === $fields ) {
3492
  $fields = $this->traverse_build( $all_fields, $params );
3493
  }
3494
 
3495
- foreach ( (array) $fields as $field_group ) {
3496
- $traverse_recurse = array(
3497
- 'pod' => $this->pod,
3498
- 'fields' => $fields,
3499
- 'params' => $params,
3500
- 'last_table_info' => $this->pod_data,
3501
- 'joined_id' => $this->pod_data['field_id'],
3502
- 'joined_index' => $this->pod_data['field_index'],
3503
- );
3504
 
3505
- if ( is_array( $field_group ) ) {
3506
- $traverse_recurse['fields'] = $field_group;
3507
 
3508
- $joins = array_merge( $joins, $this->traverse_recurse( $traverse_recurse ) );
3509
- } else {
3510
- $joins = array_merge( $joins, $this->traverse_recurse( $traverse_recurse ) );
3511
- $joins = array_filter( $joins );
 
 
 
 
 
3512
 
3513
- return $joins;
3514
- }
3515
- }//end foreach
3516
 
3517
- $joins = array_filter( $joins );
3518
 
3519
- return $joins;
3520
  }
3521
 
3522
  /**
@@ -3581,4 +3614,131 @@ class PodsData {
3581
 
3582
  return $sql;
3583
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3584
  }
1
  <?php
2
 
3
+ use Pods\Whatsit\Pod;
4
+ use Pods\Whatsit\Field;
5
+ use Pods\Whatsit\Object_Field;
6
+
7
  /**
8
+ * The Pods DB related functionality needed for building queries and traversal.
9
+ *
10
  * @package Pods
11
+ *
12
+ * @property null|string $pod The Pod name.
13
+ * @property null|string $pod_id The Pod id.
14
+ * @property null|array $fields The list of Pod fields.
15
+ * @property null|array $object_fields The list of Pod object fields.
16
+ * @property null|string $detail_page The detail_url (if set), alias of detail_url.
17
+ * @property null|string $detail_url The detail_url (if set).
18
+ * @property null|string $select The select data.
19
+ * @property null|string $table The table data.
20
+ * @property null|string $field_id The field_id data.
21
+ * @property null|string $field_index The field_index data.
22
+ * @property null|string $field_slug The field_slug data.
23
+ * @property null|string $join The join data.
24
+ * @property null|array|string $where The where data.
25
+ * @property null|array|string $where_default The where_default data.
26
+ * @property null|string $orderby The orderby data.
27
+ * @property null|string $type The type data.
28
+ * @property null|string $storage The storage data.
29
  */
30
  class PodsData {
31
 
55
  public $api = null;
56
 
57
  /**
58
+ * @var Pod
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  */
60
  public $pod_data = null;
61
 
62
  /**
63
+ * The table information to fallback on when a Pod is not defined in $this->pod_data.
64
+ *
65
+ * @since 2.8.0
66
+ *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  * @var array
68
  */
69
+ public $table_info = null;
 
 
 
 
 
70
 
71
  /**
72
+ * @var int
73
  */
74
+ public $id = 0;
75
 
76
  /**
77
  * @var array
78
  */
79
  public $aliases = array();
80
 
 
 
 
 
 
81
  /**
82
  * @var int
83
  */
86
  /**
87
  * @var
88
  */
89
+ public $rows;
90
 
91
  /**
92
  * @var
128
  */
129
  public $limit = 15;
130
 
131
+ /**
132
+ * @var int
133
+ */
134
+ public $offset = 0;
135
+
136
  /**
137
  * @var bool
138
  */
175
  */
176
  public $filters = array();
177
 
178
+ /**
179
+ * @var array
180
+ */
181
+ public $params = array();
182
+
183
  /**
184
  * Holds Traversal information about Pods
185
  *
211
  /**
212
  * Singleton handling for a basic pods_data() request
213
  *
214
+ * @param string|null $pod Pod name.
215
+ * @param int|string $id Pod Item ID.
216
+ * @param bool $strict If true throws an error if a pod is not found.
217
+ *
218
+ * @return PodsData|false
219
  *
220
+ * @throws Exception
221
  *
222
  * @since 2.3.5
223
  */
224
+ public static function init( $pod = null, $id = null, $strict = true ) {
225
+
226
+ if ( ! in_array( $pod, array( null, false ), true ) || ! in_array( $id, array( null, 0 ), true ) ) {
227
+ $object = new PodsData( $pod, $id );
228
+
229
+ if ( empty( $object->pod_data ) && true === $strict ) {
230
+ return pods_error( 'Pod not found', $object );
231
+ }
232
 
233
+ return $object;
234
+ }
235
+
236
+ if ( ! is_object( self::$instance ) ) {
237
  self::$instance = new PodsData();
238
  } else {
239
  $vars = get_class_vars( __CLASS__ );
253
  /**
254
  * Data Abstraction Class for Pods
255
  *
256
+ * @param string|null $pod Pod name.
257
+ * @param int|string $id Pod Item ID.
 
 
 
258
  *
259
  * @license http://www.gnu.org/licenses/gpl-2.0.html
260
  * @since 2.0.0
261
  */
262
+ public function __construct( $pod = null, $id = 0 ) {
263
 
264
  global $wpdb;
265
 
266
+ $this->api = pods_api();
 
 
 
 
 
 
267
  $this->api->display_errors =& self::$display_errors;
268
 
269
+ if ( empty( $pod ) ) {
270
+ return;
271
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
 
273
+ if ( $pod instanceof Pod ) {
274
+ $this->pod_data = $pod;
275
+ } elseif ( $pod instanceof Pods ) {
276
+ $this->pod_data = $pod->pod_data;
277
+ } else {
278
+ $this->pod_data = $this->api->load_pod( [
279
+ 'name' => $pod,
280
+ 'auto_setup' => true,
281
+ ], false );
282
+ }
283
 
284
+ // Set up page variable.
285
+ if ( pods_strict( false ) ) {
286
+ $this->page = 1;
287
+ $this->pagination = false;
288
+ $this->search = false;
289
+ } else {
290
+ // Get the page variable.
291
+ $this->page = pods_v( $this->page_var, 'get', 1, true );
292
 
293
+ if ( ! empty( $this->page ) ) {
294
+ $this->page = max( 1, pods_absint( $this->page ) );
295
  }
296
+ }
297
 
298
+ // Set default pagination handling to on/off.
299
+ if ( defined( 'PODS_GLOBAL_POD_PAGINATION' ) ) {
300
+ if ( ! PODS_GLOBAL_POD_PAGINATION ) {
301
+ $this->page = 1;
302
+ $this->pagination = false;
303
+ } else {
304
+ $this->pagination = true;
305
  }
306
+ }
307
 
308
+ // Set default search to on/off.
309
+ if ( defined( 'PODS_GLOBAL_POD_SEARCH' ) ) {
310
+ if ( PODS_GLOBAL_POD_SEARCH ) {
311
+ $this->search = true;
312
+ } else {
313
+ $this->search = false;
314
  }
315
+ }
316
 
317
+ // Set default search mode.
318
+ $allowed_search_modes = array( 'int', 'text', 'text_like' );
 
319
 
320
+ if ( defined( 'PODS_GLOBAL_POD_SEARCH_MODE' ) && in_array( PODS_GLOBAL_POD_SEARCH_MODE, $allowed_search_modes, true ) ) {
321
+ $this->search_mode = PODS_GLOBAL_POD_SEARCH_MODE;
322
+ }
323
 
324
+ if ( $this->pod_data && 'settings' === $this->pod_data['type'] ) {
325
+ $this->id = $this->pod_data['id'];
326
 
327
+ $this->fetch( $this->id );
328
+ } elseif ( null !== $id && ! is_array( $id ) && ! is_object( $id ) ) {
329
+ $this->id = $id;
330
 
331
+ $this->fetch( $this->id );
332
+ }
 
333
  }
334
 
335
  /**
339
  * @param string $object
340
  */
341
  public function table( $table, $object = '' ) {
 
342
  global $wpdb;
343
 
344
+ if ( is_string( $table ) ) {
345
  $object_type = '';
346
 
347
+ if ( $wpdb->posts === $table ) {
 
 
348
  $object_type = 'post_type';
349
  } elseif ( $wpdb->terms === $table ) {
350
  $object_type = 'taxonomy';
351
+ } elseif ( $wpdb->users === $table ) {
352
+ $object_type = 'user';
353
+ } elseif ( $wpdb->comments === $table ) {
354
+ $object_type = 'comment';
355
  } elseif ( $wpdb->options === $table ) {
356
  $object_type = 'settings';
357
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
 
359
+ if ( ! empty( $object_type ) ) {
360
+ $table = $this->api->get_table_info( $object_type, $object );
 
 
 
 
361
  }
362
+ }
363
 
364
+ // Check if we received a pod object itself.
365
+ if ( $table instanceof Pod ) {
366
+ $table = [
367
+ 'pod' => $table,
368
+ ];
369
+ } elseif ( $table instanceof Pods ) {
370
+ $table = [
371
+ 'pod' => $table->pod_data,
372
+ ];
373
+ }
374
 
375
+ // No pod set.
376
+ if ( empty( $table['pod'] ) ) {
377
+ // No pod name to try to use.
378
+ if ( ! empty( $table['name'] ) ) {
379
+ $pod_data = $this->api->load_pod( [
380
+ 'name' => $table['name'],
381
+ 'auto_setup' => true,
382
+ ] );
383
 
384
+ // No pod data found.
385
+ if ( $pod_data ) {
386
+ $table['pod'] = $pod_data;
387
+ }
388
  }
389
+ }
390
 
391
+ // Check for pod object.
392
+ if ( $table['pod'] instanceof Pod ) {
393
+ $this->pod_data = $table['pod'];
394
+ } else {
395
+ $this->table_info = $table;
396
+ }
397
  }
398
 
399
  /**
676
 
677
  // Debug purposes.
678
  if ( ( 1 === (int) pods_v( 'pods_debug_sql', 'get', 0 ) || 1 === (int) pods_v( 'pods_debug_sql_all', 'get', 0 ) ) && pods_is_admin( array( 'pods' ) ) ) {
679
+ if ( function_exists( 'codecept_debug' ) ) {
680
+ pods_debug( $this->get_sql() );
681
+ } else {
682
+ echo '<textarea cols="100" rows="24">' . esc_textarea( $this->get_sql() ) . '</textarea>';
683
+ }
684
  }
685
 
686
  if ( empty( $this->sql ) ) {
707
  */
708
  $results = apply_filters( 'pods_data_select', $results, $params, $this );
709
 
710
+ $this->rows = $results;
711
 
712
  $this->row_number = - 1;
713
  $this->row = null;
714
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715
  $this->total_found_calculated = false;
716
 
717
  $this->total = 0;
718
 
719
+ if ( ! empty( $this->rows ) ) {
720
+ $this->total = count( (array) $this->rows );
721
  }
722
 
723
  /**
734
  $this->calculate_totals();
735
  }
736
 
737
+ return $this->rows;
738
  }
739
 
740
  /**
827
 
828
  $pod = false;
829
 
830
+ if ( $this->pod_data instanceof Pod ) {
831
  $pod = $this->pod_data;
832
+ } elseif ( $this->table_info ) {
833
+ $pod = $this->table_info;
834
  }
835
 
836
  // Validate.
865
 
866
  $merge_object_fields = false;
867
 
868
+ if (
869
+ $pod
870
+ && (
871
+ empty( $params->fields )
872
+ || ! is_array( $params->fields )
873
+ )
874
+ ) {
875
  $params->fields = $this->fields;
876
 
877
+ if ( null === $params->fields ) {
878
+ $params->fields = [];
879
+ }
880
+
881
  $merge_object_fields = true;
882
  }
883
 
884
+ if (
885
+ $pod
886
+ && (
887
+ empty( $params->object_fields )
888
+ || ! is_array( $params->object_fields )
889
+ )
890
+ ) {
891
+ $params->object_fields = $this->object_fields;
892
+
893
+ if ( null === $params->object_fields ) {
894
+ $params->object_fields = [];
895
+ }
896
 
897
  if ( $merge_object_fields ) {
898
+ if ( $pod instanceof Pod ) {
899
+ $params->fields = $pod->get_all_fields();
900
+ } elseif ( $params->object_fields ) {
901
+ if ( $params->fields ) {
902
+ $params->fields = array_merge( $params->fields, $params->object_fields );
903
+ } else {
904
+ $params->fields = $params->object_fields;
905
+ }
906
+ }
907
  }
908
  }
909
 
921
  $params->id = $this->field_id;
922
  }
923
 
924
+ if ( $pod && empty( $params->table ) ) {
925
  $params->table = $this->table;
926
  }
927
 
929
  $params->pod_table_prefix = 't';
930
  }
931
 
932
+ if (
933
+ 'table' === $this->storage
934
+ && ! in_array( $this->type, [
935
+ 'pod',
936
+ 'table',
937
+ ], true )
938
+ ) {
939
  $params->pod_table_prefix = 'd';
940
  }
941
 
942
  $params->meta_fields = false;
943
 
944
+ $is_pod_meta_storage = 'meta' === $this->storage;
945
+
946
+ if (
947
+ (
948
+ $is_pod_meta_storage
949
+ || 'none' === $this->storage
950
+ )
951
+ && ! in_array( $this->type, [
952
  'pod',
953
  'table',
954
+ ], true )
955
+ ) {
956
  $params->meta_fields = true;
957
  }
958
 
1016
  }
1017
 
1018
  if ( ! empty( $params->orderby ) ) {
1019
+ if ( $is_pod_meta_storage && is_array( $params->orderby ) ) {
 
1020
  foreach ( $params->orderby as $i => $orderby ) {
1021
  if ( strpos( $orderby, '.meta_value_num' ) ) {
1022
  $params->orderby[ $i ] = 'CAST(' . str_replace( '.meta_value_num', '.meta_value', $orderby ) . ' AS DECIMAL)';
1112
  // Search.
1113
  if ( ! empty( $params->search ) && ! empty( $params->fields ) ) {
1114
  if ( false !== $params->search_query && 0 < strlen( $params->search_query ) ) {
1115
+ $where = [];
1116
+ $having = [];
1117
+ $fields_to_search = [];
1118
+
1119
+ $excluded_field_types_from_search = [
1120
+ 'date',
1121
+ 'time',
1122
+ 'datetime',
1123
+ 'number',
1124
+ 'decimal',
1125
+ 'currency',
1126
+ 'phone',
1127
+ 'password',
1128
+ 'boolean',
1129
+ 'comment',
1130
+ 'taxonomy',
1131
+ ];
1132
 
1133
  if ( false !== $params->search_across ) {
1134
+ // Search all fields.
1135
+ $fields_to_search = $params->fields;
1136
+ } elseif ( ! empty( $params->index ) ) {
1137
+ $index_field = null;
 
 
 
 
 
 
1138
 
1139
+ // Search just the index field if we can find it.
1140
+ if ( isset( $params->fields[ $params->index ] ) ) {
1141
+ $index_field = $params->fields[ $params->index ];
1142
+ } elseif ( isset( $params->object_fields[ $params->index ] ) ) {
1143
+ $index_field = $params->object_fields[ $params->index ];
1144
+ }
1145
 
1146
+ if ( $index_field ) {
1147
+ $fields_to_search = [
1148
+ $params->index => $index_field,
1149
+ ];
1150
+ }
1151
+ }
 
 
 
 
 
 
 
 
 
 
 
1152
 
1153
+ foreach ( $fields_to_search as $key => $field ) {
1154
+ $is_field_object = $field instanceof Field;
1155
 
1156
+ if ( is_array( $field ) || $is_field_object ) {
1157
+ $attributes = $field;
1158
+ $field = pods_v( 'name', $field, $key, true );
1159
+ } else {
1160
+ $attributes = [
1161
+ 'type' => '',
1162
+ 'options' => [],
1163
+ ];
1164
+ }
1165
 
1166
+ if ( isset( $attributes['search'] ) && ! $attributes['search'] ) {
1167
+ continue;
1168
+ }
 
 
 
 
1169
 
1170
+ // Exclude certain field types from search.
1171
+ if ( in_array( $attributes['type'], $excluded_field_types_from_search, true ) ) {
1172
+ continue;
1173
+ }
1174
 
1175
+ $db_field_name = '`' . $field . '`';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1176
 
1177
+ $is_object_field = (
1178
+ isset( $params->object_fields[ $field ] )
1179
+ || $attributes instanceof Object_Field
1180
+ );
1181
+ $is_custom_field = (
1182
+ ! $is_object_field
1183
+ && ! isset( $params->fields[ $field ] )
1184
+ );
1185
+
1186
+ $pick_object = pods_v( $attributes['type'] . '_object', $attributes );
1187
+ $pick_val = pods_v( $attributes['type'] . '_val', $attributes );
1188
 
1189
+ if ( in_array( $attributes['type'], $pick_field_types, true ) && ! in_array( $pick_object, $simple_tableless_objects, true ) ) {
1190
+ // Search relationship fields.
1191
+ if ( false !== $params->search_across && false === $params->search_across_picks ) {
1192
+ // Skip if we are searching but not searching across relationship fields.
1193
+ continue;
1194
+ } elseif ( empty( $attributes['table_info'] ) ) {
1195
+ $attributes['table_info'] = $this->api->get_table_info( $pick_object, $pick_val );
1196
  }
1197
 
1198
+ // Check if we have index column information about the related table.
1199
+ if ( empty( $attributes['table_info']['field_index'] ) ) {
1200
+ continue;
 
1201
  }
 
 
 
1202
 
1203
+ $db_field_name .= '.`' . $attributes['table_info']['field_index'] . '`';
1204
+ } elseif ( in_array( $attributes['type'], $file_field_types, true ) ) {
1205
+ // Search file fields.
1206
+ if ( false !== $params->search_across && false === $params->search_across_files ) {
1207
+ // Skip if we are searching but not searching across file fields.
1208
+ continue;
1209
+ }
1210
 
1211
+ $db_field_name .= '.`post_title`';
1212
+ } elseif ( $is_custom_field ) {
1213
+ // Search custom fields (they are not a defined field or an object field).
1214
+ if ( $params->meta_fields ) {
1215
+ // If meta is enabled, this must be a meta field.
1216
+ $db_field_name .= '.`meta_value`';
1217
  } else {
1218
+ // Maybe this is just a field we don't know about on the table.
1219
+ $db_field_name = '`' . $params->pod_table_prefix . '`.' . $db_field_name;
1220
  }
1221
+ } elseif ( ! $is_object_field && $is_pod_meta_storage ) {
1222
+ // Search meta fields.
1223
+ $db_field_name .= '.`meta_value`';
1224
+ } else {
1225
+ // Search object fields.
1226
+ $db_field_name = '`t`.' . $db_field_name;
1227
+ }//end if
1228
+
1229
+ if ( isset( $this->aliases[ $field ] ) ) {
1230
+ $db_field_name = '`' . $this->aliases[ $field ] . '`';
1231
  }
1232
 
1233
+ if ( ! empty( $attributes['real_name'] ) ) {
1234
+ $db_field_name = $attributes['real_name'];
1235
  }
1236
 
1237
+ $filter_clause = "{$db_field_name} LIKE '%" . pods_sanitize_like( $params->search_query ) . "%'";
1238
+
1239
  if ( isset( $attributes['group_related'] ) && false !== $attributes['group_related'] ) {
1240
+ $having[] = $filter_clause;
1241
  } else {
1242
+ $where[] = $filter_clause;
1243
  }
1244
+ }//end foreach
1245
 
1246
  if ( ! empty( $where ) ) {
1247
  $params->where[] = '( ' . implode( ' OR ', $where ) . ' )';
1288
  $filterfield = $filterfield . '.`term_id`';
1289
  } elseif ( in_array( $attributes['type'], $file_field_types, true ) ) {
1290
  $filterfield = $filterfield . '.`post_title`';
1291
+ } elseif ( isset( $params->fields[ $field ] ) && $params->fields[ $field ] instanceof Object_Field ) {
1292
+ if ( $params->meta_fields && $is_pod_meta_storage ) {
1293
  $filterfield = $filterfield . '.`meta_value`';
1294
  } else {
1295
  $filterfield = '`' . $params->pod_table_prefix . '`.' . $filterfield;
1296
  }
1297
+ } elseif ( ! isset( $params->fields[ $field ] ) && $is_pod_meta_storage ) {
1298
  $filterfield = $filterfield . '.`meta_value`';
1299
  } else {
1300
  $filterfield = '`t`.' . $filterfield;
1336
  $filterfield = '`' . $field . '`.`' . $attributes['table_info']['field_id'] . '`';
1337
 
1338
  if ( isset( $attributes['group_related'] ) && false !== $attributes['group_related'] ) {
1339
+ $having[] = "{$filterfield} = {$filter_v}";
1340
  } else {
1341
+ $where[] = "{$filterfield} = {$filter_v}";
1342
  }
1343
  }//end if
1344
  }//end foreach
1411
  }//end if
1412
 
1413
  // Traverse the Rabbit Hole.
1414
+ if ( $this->pod_data || $this->table_info ) {
1415
  $haystack = implode( ' ', (array) $params->select ) . ' ' . implode( ' ', (array) $params->where ) . ' ' . implode( ' ', (array) $params->groupby ) . ' ' . implode( ' ', (array) $params->having ) . ' ' . implode( ' ', (array) $params->orderby );
1416
  $haystack = preg_replace( '/\s/', ' ', $haystack );
1417
  $haystack = preg_replace( '/\w\(/', ' ', $haystack );
1979
 
1980
  $this->row = false;
1981
 
1982
+ if ( isset( $this->rows[ $this->row_number ] ) ) {
1983
+ $this->row = $this->rows[ $this->row_number ];
1984
+
1985
+ if ( is_object( $this->row ) ) {
1986
+ $this->row = get_object_vars( $this->row );
1987
+ }
1988
 
1989
  $current_row_id = false;
1990
 
1991
+ if ( $this->pod_data && 'settings' === $this->pod_data['type'] ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
1992
  $current_row_id = $this->pod_data['id'];
1993
+ } else {
1994
+ $current_row_id = pods_v( $this->field_id, $this->row );
1995
  }
1996
 
1997
+ if ( ! in_array( $current_row_id, [ '', '0', 0, null, false ], true ) ) {
1998
  $row = $current_row_id;
1999
  }
2000
  }//end if
2001
  }//end if
2002
 
2003
+ if ( null !== $row || ( $this->pod_data && 'settings' === $this->pod_data['type'] ) ) {
2004
  if ( $explicit_set ) {
2005
  $this->row_number = - 1;
2006
  }
2008
  $mode = 'id';
2009
  $id = pods_absint( $row );
2010
 
2011
+ if ( ! is_numeric( $row ) || 0 === strpos( $row, '0' ) || (string) $row !== (string) preg_replace( '/[^0-9]/', '', $row ) ) {
2012
  if ( $this->id && is_numeric( $this->id ) ) {
2013
  $id = $this->id;
2014
  } else {
2021
 
2022
  if ( ! empty( $this->pod ) ) {
2023
  $row = pods_cache_get( $id, 'pods_items_' . $this->pod );
2024
+
2025
+ if ( is_array( $row ) ) {
2026
  $already_cached = true;
2027
+ } else {
2028
+ $row = false;
2029
  }
2030
  }
2031
 
2034
 
2035
  $old_row = $this->row;
2036
 
2037
+ $pod_type = $this->type;
2038
+
2039
+ if ( $already_cached ) {
2040
  $this->row = $row;
2041
  } elseif ( in_array(
2042
+ $pod_type, array(
2043
  'post_type',
2044
  'media',
2045
  ), true
2046
  ) ) {
2047
+ if ( 'post_type' === $pod_type ) {
2048
+ $post_type = $this->pod;
2049
+
2050
+ if ( $this->pod_data && ! empty( $this->pod_data['object'] ) ) {
2051
  $post_type = $this->pod_data['object'];
2052
  }
2053
  } else {
2054
  $post_type = 'attachment';
2055
  }
2056
 
2057
+ $this->row = [];
2058
+
2059
  if ( 'id' === $mode ) {
2060
  $this->row = get_post( $id, ARRAY_A );
2061
 
2062
+ if ( is_array( $this->row ) && $this->row['post_type'] !== $post_type ) {
2063
  $this->row = false;
2064
  }
2065
  } else {
2066
+ $args = [
2067
+ 'post_type' => $post_type,
2068
+ 'name' => $id,
2069
+ 'posts_per_page' => 5,
2070
+ ];
2071
 
2072
  $find = get_posts( $args );
2073
 
2074
  if ( ! empty( $find ) ) {
2075
+ $this->row = get_object_vars( reset( $find ) );
2076
  }
2077
  }
2078
 
2079
+ if ( empty( $this->row ) || is_wp_error( $this->row ) ) {
2080
  $this->row = false;
2081
  } else {
2082
  $current_row_id = $this->row['ID'];
2083
  }
2084
 
2085
  $get_table_data = true;
2086
+ } elseif ( 'taxonomy' === $pod_type ) {
2087
+ $taxonomy = $this->pod;
2088
 
2089
+ if ( $this->pod_data && ! empty( $this->pod_data['object'] ) ) {
2090
+ $taxonomy = $this->pod_data['object'];
2091
  }
2092
 
2093
  // Taxonomies are registered during init, so they aren't available before then.
2116
  $_term = apply_filters( "get_$taxonomy", $_term, $taxonomy );
2117
  $_term = sanitize_term( $_term, $taxonomy, $filter );
2118
 
2119
+ $this->row = [];
2120
+
2121
  if ( is_object( $_term ) ) {
2122
  $this->row = get_object_vars( $_term );
2123
  }
2127
  $this->row = get_term_by( 'slug', $id, $taxonomy, ARRAY_A );
2128
  }//end if
2129
 
2130
+ if ( empty( $this->row ) || is_wp_error( $this->row ) ) {
2131
  $this->row = false;
2132
  } else {
2133
  $current_row_id = $this->row['term_id'];
2134
  }
2135
 
2136
  $get_table_data = true;
2137
+ } elseif ( 'user' === $pod_type ) {
2138
  if ( 'id' === $mode ) {
2139
  $this->row = get_userdata( $id );
2140
  } else {
2141
  $this->row = get_user_by( 'slug', $id );
2142
  }
2143
 
2144
+ if ( empty( $this->row ) || is_wp_error( $this->row ) ) {
2145
  $this->row = false;
2146
  } else {
2147
  // Get other vars.
2162
  }
2163
 
2164
  $get_table_data = true;
2165
+ } elseif ( 'comment' === $pod_type ) {
2166
  $this->row = get_comment( $id, ARRAY_A );
2167
 
2168
  // No slug handling here.
2169
+ if ( empty( $this->row ) || is_wp_error( $this->row ) ) {
2170
  $this->row = false;
2171
  } else {
2172
  $current_row_id = $this->row['comment_ID'];
2173
  }
2174
 
2175
  $get_table_data = true;
2176
+ } elseif ( 'settings' === $pod_type ) {
2177
+ $this->row = [];
2178
 
2179
+ if ( empty( $this->fields ) || ! $this->pod_data ) {
2180
  $this->row = false;
2181
  } else {
2182
  foreach ( $this->fields as $field ) {
2204
  $params['where'] = "`t`.`{$this->field_slug}` = '{$id}'";
2205
  }
2206
 
2207
+ $new_data = new PodsData();
2208
+
2209
+ $this->row = $new_data->select( $params );
2210
 
2211
  if ( empty( $this->row ) ) {
2212
  $this->row = false;
2220
  $this->row = array_merge( $old_row, $this->row );
2221
  }
2222
 
2223
+ if ( false !== $get_table_data && is_numeric( $current_row_id ) && $this->pod_data && 'table' === $this->pod_data['storage'] ) {
2224
  $params = array(
2225
  'table' => self::get_pods_prefix(),
2226
  'where' => "`t`.`id` = {$current_row_id}",
2231
  'strict' => true,
2232
  );
2233
 
2234
+ $table_name = $this->pod;
2235
+
2236
+ if ( $this->pod_data && ! empty( $this->pod_data['object'] ) ) {
2237
+ $table_name = $this->pod_data['object'];
2238
  }
2239
 
2240
+ $params['table'] .= $table_name;
2241
+
2242
+ $new_data = new PodsData();
2243
+
2244
+ $row = $new_data->select( $params );
2245
 
2246
  if ( ! empty( $row ) ) {
2247
  $current_row = (array) $row;
2256
  }//end if
2257
 
2258
  if ( ! empty( $this->pod ) && ! $already_cached ) {
2259
+ pods_cache_set( $id, $this->row, 'pods_items_' . $this->pod, WEEK_IN_SECONDS );
2260
  }
2261
  }//end if
2262
 
2263
  $this->row = apply_filters( 'pods_data_fetch', $this->row, $id, $this->row_number, $this );
2264
 
2265
+ // Set the ID if the row was found.
2266
+ if ( $explicit_set && $this->row ) {
2267
+ $this->id = $id;
2268
+ }
2269
+
2270
  return $this->row;
2271
  }
2272
 
2285
 
2286
  $this->row = false;
2287
 
2288
+ if ( isset( $this->rows[ $row ] ) ) {
2289
+ $this->row = $this->rows[ $row ];
2290
+
2291
+ if ( is_object( $this->row ) ) {
2292
+ $this->row = get_object_vars( $this->row );
2293
+ }
2294
  }
2295
 
2296
  if ( empty( $row ) ) {
2532
  /**
2533
  * Get the string to use in a query for WHERE/HAVING, uses WP_Query meta_query arguments
2534
  *
2535
+ * @param array $fields Array of field matches for querying.
2536
+ * @param array|Pod $pod Related Pod.
2537
+ * @param object $params Parameters passed from select().
2538
  *
2539
  * @return string|null Query string for WHERE/HAVING
2540
  *
2599
 
2600
  if ( ! empty( $query_fields ) ) {
2601
  // If post_status not sent, detect it.
2602
+ if ( $pod && 'post_type' === $pod['type'] && 1 === $current_level && ! $params->where_defaulted && ! empty( $params->where_default ) ) {
2603
  $post_status_found = false;
2604
 
2605
  if ( ! $params->query_field_syntax ) {
2608
  $haystack = preg_replace( '/\w\(/', ' ', $haystack );
2609
  $haystack = str_replace( array( '(', ')', ' ', '\\\'', '\\"' ), ' ', $haystack );
2610
 
2611
+ // Find xyz.some_field and `xyz`.`some_field` variations.
2612
  preg_match_all( '/`?[\w\-]+`?(?:\\.`?[\w\-]+`?)+(?=[^"\']*(?:"[^"]*"[^"]*|\'[^\']*\'[^\']*)*$)/', $haystack, $found, PREG_PATTERN_ORDER );
2613
 
2614
+ // Find `some_field` variations but leave out some_field without backticks.
2615
+ preg_match_all( '/(?:`?[\w\-]+`?)+(?!\.)(?=[^"\']*(?:"[^"]*"[^"]*|\'[^\']*\'[^\']*)*$)/', $haystack, $found2, PREG_PATTERN_ORDER );
2616
 
2617
+ $found = (array) @current( $found );
2618
+ $found = array_merge( $found, (array) @current( $found2 ) );
2619
+ $found = array_unique( $found );
2620
 
2621
+ $post_status_patterns = [
2622
+ '`t`.`post_status`',
2623
+ 't.post_status',
2624
+ '`post_status`',
2625
+ 'post_status',
2626
+ ];
2627
 
2628
+ $post_status_found = 0 < count( array_intersect( $found, $post_status_patterns ) );
 
 
2629
  } elseif ( ! empty( $params->query_fields ) && in_array( 'post_status', $params->query_fields, true ) ) {
2630
  $post_status_found = true;
2631
  }//end if
2657
  *
2658
  * @param string|int $field Field name or array index.
2659
  * @param array|string $q Query array (meta_query) or string for matching.
2660
+ * @param array|Pod $pod Related Pod.
2661
  * @param object $params Parameters passed from select().
2662
  *
2663
  * @return string|null Query field string
2738
  $field_type = 'CHAR';
2739
  }
2740
 
2741
+ $is_pod_meta_storage = 'meta' === $pod['storage'];
2742
+
2743
  // Alias / Casting.
2744
  if ( empty( $field_cast ) ) {
2745
  // Setup field casting from field name.
2746
  if ( false === strpos( $field_name, '`' ) && false === strpos( $field_name, '(' ) && false === strpos( $field_name, ' ' ) ) {
2747
  // Handle field naming if Pod-based.
2748
+ if ( $pod && false === strpos( $field_name, '.' ) ) {
2749
  $field_cast = '';
2750
 
2751
+ $the_field = null;
2752
+
2753
+ if ( $pod instanceof Pod ) {
2754
+ $the_field = $pod->get_field( $field_name );
2755
+ } elseif ( isset( $pod[ $field_name ] ) ) {
2756
+ $the_field = $pod[ $field_name ];
2757
+ }
2758
+
2759
  $tableless_field_types = PodsForm::tableless_field_types();
2760
 
2761
+ if ( $the_field && in_array( $the_field['type'], $tableless_field_types, true ) ) {
2762
+ $related_object_type = $the_field->get_related_object_type();
2763
+
2764
+ if ( in_array( $related_object_type, $simple_tableless_objects, true ) ) {
2765
+ if ( $is_pod_meta_storage ) {
2766
  $field_cast = "`{$field_name}`.`meta_value`";
2767
  } else {
2768
  $field_cast = "`t`.`{$field_name}`";
2769
  }
2770
  } else {
2771
+ $table = $the_field->get_table_info();
2772
 
2773
  if ( ! empty( $table ) ) {
2774
  $field_cast = "`{$field_name}`.`" . $table['field_index'] . '`';
2777
  }
2778
 
2779
  if ( empty( $field_cast ) ) {
2780
+ if ( $the_field ) {
2781
+ if ( ! in_array(
2782
+ $pod['type'], array(
2783
+ 'pod',
2784
+ 'table',
2785
+ ), true
2786
+ ) ) {
2787
+ if ( $the_field instanceof Object_Field ) {
2788
+ $field_cast = "`t`.`{$field_name}`";
2789
+ } elseif ( $is_pod_meta_storage ) {
2790
  $field_cast = "`{$field_name}`.`meta_value`";
2791
  } else {
2792
  $field_cast = "`d`.`{$field_name}`";
2793
  }
2794
+ } elseif ( $is_pod_meta_storage ) {
 
 
 
 
 
 
 
 
 
 
2795
  $field_cast = "`{$field_name}`.`meta_value`";
2796
  } else {
2797
  $field_cast = "`t`.`{$field_name}`";
2798
+ }//end if
2799
  }//end if
2800
 
2801
  if ( empty( $field_cast ) ) {
2802
+ if ( $is_pod_meta_storage ) {
2803
  $field_cast = "`{$field_name}`.`meta_value`";
2804
  } else {
2805
  $field_cast = "`t`.`{$field_name}`";
2945
  );
2946
 
2947
  // Make the query.
2948
+ if ( in_array( $field_compare, [
2949
+ '=',
2950
+ '!=',
2951
+ '>',
2952
+ '>=',
2953
+ '<',
2954
+ '<=',
2955
+ 'REGEXP',
2956
+ 'NOT REGEXP',
2957
+ 'RLIKE',
2958
+ ], true ) ) {
 
 
2959
  if ( $field_sanitize ) {
2960
+ $field_query = "{$field_cast} {$field_compare} {$field_sanitize_format}";
2961
+ $field_query = $wpdb->prepare( $field_query, $field_value );
2962
  } else {
2963
+ $field_query = "{$field_cast} {$field_compare} '{$field_value}'";
2964
  }
2965
+ } elseif ( in_array( $field_compare, [
2966
+ 'LIKE',
2967
+ 'NOT LIKE',
2968
+ ], true ) ) {
 
 
2969
  if ( $field_sanitize ) {
2970
+ $field_query = "{$field_cast} {$field_compare} '%" . pods_sanitize_like( $field_value ) . "%'";
2971
  } else {
2972
+ $field_query = "{$field_cast} {$field_compare} '{$field_value}'";
2973
  }
2974
+ } elseif ( in_array( $field_compare, [
2975
+ 'IN',
2976
+ 'NOT IN',
2977
+ 'ALL',
2978
+ ], true ) ) {
2979
+ $field_value = (array) $field_value;
2980
+
2981
  if ( 'ALL' === $field_compare ) {
2982
  $field_compare = 'IN';
2983
 
2984
+ if ( $pod ) {
2985
  $params->having[] = 'COUNT( DISTINCT ' . $field_cast . ' ) = ' . count( $field_value );
2986
 
2987
+ if (
2988
+ empty( $params->groupby )
2989
+ || (
2990
+ ! in_array( "`t`.`{$pod['field_id']}`", $params->groupby, true )
2991
+ && ! in_array( "t.{$pod['field_id']}", $params->groupby, true )
2992
+ )
2993
+ ) {
2994
+ $params->groupby[] = "`t`.`{$pod['field_id']}`";
2995
  }
2996
  }
2997
  }
2998
 
2999
  if ( $field_sanitize ) {
3000
+ $field_query = "{$field_cast} {$field_compare} ( " . substr( str_repeat( ', ' . $field_sanitize_format, count( $field_value ) ), 1 ) . " )";
3001
+ $field_query = $wpdb->prepare( $field_query, $field_value );
3002
  } else {
3003
+ $field_query = "{$field_cast} {$field_compare} ( '" . implode( "', '", $field_value ) . "' )";
3004
  }
3005
+ } elseif ( in_array( $field_compare, [
3006
+ 'BETWEEN',
3007
+ 'NOT BETWEEN',
3008
+ ], true ) ) {
 
 
3009
  if ( $field_sanitize ) {
3010
+ $field_query = "{$field_cast} {$field_compare} {$field_sanitize_format} AND {$field_sanitize_format}";
3011
+ $field_query = $wpdb->prepare( $field_query, $field_value );
3012
  } else {
3013
+ $field_query = "{$field_cast} {$field_compare} '{$field_value[0]}' AND '{$field_value[1]}'";
3014
  }
3015
  } elseif ( 'EXISTS' === $field_compare ) {
3016
+ $field_query = "{$field_cast} IS NOT NULL";
3017
  } elseif ( 'NOT EXISTS' === $field_compare ) {
3018
+ $field_query = "{$field_cast} IS NULL";
3019
  }//end if
3020
 
3021
  $field_query = apply_filters( 'pods_data_field_query', $field_query, $q );
3071
  * @since 2.0.0
3072
  */
3073
  public function traverse_recurse( $traverse_recurse ) {
 
3074
  global $wpdb;
3075
 
3076
+ $defaults = [
3077
  'pod' => null,
3078
+ 'fields' => [],
3079
  'joined' => 't',
3080
  'depth' => 0,
3081
  'joined_id' => 'id',
3082
  'joined_index' => 'id',
3083
  'params' => new stdClass(),
3084
+ 'last_table_info' => [],
3085
+ ];
3086
 
3087
  $traverse_recurse = array_merge( $defaults, $traverse_recurse );
3088
 
3089
+ $joins = [];
3090
 
3091
  if ( 0 === $traverse_recurse['depth'] && ! empty( $traverse_recurse['pod'] ) && ! empty( $traverse_recurse ['last_table_info'] ) && isset( $traverse_recurse ['last_table_info']['id'] ) ) {
3092
+ $pod_data = $traverse_recurse['last_table_info'];
3093
  } elseif ( empty( $traverse_recurse['pod'] ) ) {
3094
+ if ( ! empty( $traverse_recurse['params'] ) && ! empty( $traverse_recurse['params']->table ) && ( ! $wpdb->prefix // Make sure there is a prefix.
3095
+ || 0 === strpos( $traverse_recurse['params']->table, $wpdb->prefix ) ) ) {
 
 
 
 
 
 
3096
  if ( $wpdb->posts === $traverse_recurse['params']->table ) {
3097
  $traverse_recurse['pod'] = 'post_type';
3098
  } elseif ( $wpdb->terms === $traverse_recurse['params']->table ) {
3105
  return $joins;
3106
  }
3107
 
3108
+ $pod_data = [];
3109
 
3110
+ if ( in_array( $traverse_recurse['pod'], [
3111
+ 'user',
3112
+ 'comment',
3113
+ ], true ) ) {
3114
+ $new_pod = $this->api->load_pod( [
3115
+ 'name' => $traverse_recurse['pod'],
3116
+ 'auto_setup' => true,
3117
+ ] );
3118
+
3119
+ if ( $new_pod && $new_pod['type'] === $traverse_recurse['pod'] ) {
3120
+ $pod_data = $new_pod;
 
 
 
 
3121
  }
3122
  }
3123
 
3124
  if ( empty( $pod_data ) ) {
3125
+ // @todo This logic is problematic with the new object based Pod configs.
3126
  $default_storage = 'meta';
3127
 
3128
  if ( 'taxonomy' === $traverse_recurse['pod'] && ! function_exists( 'get_term_meta' ) ) {
3129
  $default_storage = 'none';
3130
  }
3131
 
3132
+ $pod_data = [
3133
  'id' => 0,
3134
  'name' => '_table_' . $traverse_recurse['pod'],
3135
  'type' => $traverse_recurse['pod'],
3136
  'storage' => $default_storage,
3137
+ 'fields' => $this->api->get_wp_object_fields( $traverse_recurse['pod'] ),
3138
+ 'object_fields' => [],
3139
+ ];
3140
 
3141
+ $pod_data['object_fields'] = $pod_data['fields'];
3142
+
3143
+ $pod_data = pods_config_merge_data( $this->api->get_table_info( $traverse_recurse['pod'], '' ), $pod_data );
3144
  } elseif ( 'taxonomy' === $pod_data['type'] && 'none' === $pod_data['storage'] && function_exists( 'get_term_meta' ) ) {
3145
  $pod_data['storage'] = 'meta';
3146
  }
3150
  return $joins;
3151
  }//end if
3152
  } else {
3153
+ $pod_data = $this->api->load_pod( [
3154
+ 'name' => $traverse_recurse['pod'],
3155
+ 'auto_setup' => true,
3156
+ ] );
 
 
3157
 
3158
  if ( empty( $pod_data ) ) {
3159
  return $joins;
3160
  }
3161
  }//end if
3162
 
 
 
 
 
3163
  $tableless_field_types = PodsForm::tableless_field_types();
3164
  $simple_tableless_objects = PodsForm::simple_tableless_objects();
3165
  $file_field_types = PodsForm::file_field_types();
3166
 
3167
  if ( ! isset( $this->traversal[ $traverse_recurse['pod'] ] ) ) {
3168
+ $this->traversal[ $traverse_recurse['pod'] ] = [];
3169
  }
3170
 
3171
  if ( ( empty( $pod_data['meta_table'] ) || $pod_data['meta_table'] === $pod_data['table'] ) && ( empty( $traverse_recurse['fields'] ) || empty( $traverse_recurse['fields'][ $traverse_recurse['depth'] ] ) ) ) {
3174
 
3175
  $field = $traverse_recurse['fields'][ $traverse_recurse['depth'] ];
3176
 
3177
+ /**
3178
+ * Prevent aliases from being used in traversals.
3179
+ *
3180
+ * @since 2.3.0
3181
+ *
3182
+ * @param array $ignore_aliases Aliases to be ignored.
3183
+ * @param array $field Field data.
3184
+ * @param array $traverse_recurse Traverse params.
3185
+ * @param \PodsData $pods_data PodsData instance.
3186
+ */
3187
+ $ignore_aliases = apply_filters( 'pods_data_traverse_recurse_ignore_aliases', [], $field, $traverse_recurse, $this );
3188
 
3189
  if ( in_array( $field, $ignore_aliases, true ) ) {
3190
  return $joins;
3203
  $field_type = $traverse_recurse['last_table_info']['pod']['object_fields'][ $field ]['type'];
3204
  }
3205
 
3206
+ $pod_data['fields'][ $field ] = [
3207
  'id' => 0,
3208
  'name' => $field,
3209
  'type' => $field_type,
3210
  'pick_object' => $traverse_recurse['last_table_info']['pod']['type'],
3211
  'pick_val' => $traverse_recurse['last_table_info']['pod']['name'],
3212
+ ];
3213
 
3214
  $meta_data_table = true;
3215
  }//end if
3216
 
3217
+ $the_field = null;
3218
+
3219
  // Fallback to meta table if the pod type supports it.
3220
+ $last = end( $traverse_recurse['fields'] );
 
3221
 
3222
+ if ( $pod_data instanceof Pod ) {
3223
+ // Maybe get the field / object field from the pod.
3224
+ $the_field = $pod_data->get_field( $field );
3225
+ } elseif ( isset( $pod_data['fields'][ $field ] ) ) {
3226
+ $the_field = $pod_data['fields'][ $field ];
3227
+ }
3228
 
3229
+ if ( ! $the_field ) {
3230
+ if ( 'meta_value' === $last && in_array( $pod_data['type'], [
 
 
3231
  'post_type',
3232
  'media',
3233
  'taxonomy',
3234
  'user',
3235
  'comment',
3236
+ ], true ) ) {
3237
+ // Set up a faux-field and use meta table fallback.
3238
+ $the_field = PodsForm::field_setup( [ 'name' => $field ] );
3239
+ } elseif ( ! $pod_data instanceof Pod && 'post_type' === $pod_data['type'] ) {
3240
+ // Maybe fallback to object field if it is tableless.
3241
+ $pod_data['object_fields'] = $this->api->get_wp_object_fields( 'post_type', $pod_data, true );
3242
 
3243
+ if ( isset( $pod_data['object_fields'][ $field ] ) && in_array( $pod_data['object_fields'][ $field ]['type'], $tableless_field_types, true ) ) {
3244
+ $the_field = $pod_data['object_fields'][ $field ];
 
 
 
 
 
3245
  }
3246
+ }
3247
+ }
3248
+
3249
+ if ( null === $the_field ) {
3250
  return $joins;
3251
+ }
3252
+
3253
+ $traverse = $the_field;
3254
 
3255
+ $table_info = array();
3256
 
3257
+ if ( $the_field instanceof Field && $the_field->get_table_info() ) {
3258
+ $table_info = $the_field->get_table_info();
3259
+ } elseif (
3260
+ in_array( $traverse['type'], $file_field_types, true )
3261
+ || (
3262
+ 'pick' === $traverse['type']
3263
+ && in_array( $traverse['pick_object'], [ 'media', 'attachment' ], true )
3264
+ )
3265
+ ) {
3266
+ $table_info = $this->api->get_table_info( 'media', 'media' );
3267
  } elseif ( ! in_array( $traverse['type'], $tableless_field_types, true ) ) {
3268
+ if ( $pod_data instanceof Pod ) {
3269
+ $table_info = $pod_data->get_table_info();
3270
+ } else {
3271
+ $table_info = $this->api->get_table_info( $pod_data['type'], $pod_data['name'], $pod_data['name'], $pod_data );
3272
+ }
3273
+ } elseif ( in_array( $traverse['pick_object'], $simple_tableless_objects, true ) && ! empty( $traverse_recurse['last_table_info'] ) ) {
3274
+ $has_last_table_info = ! empty( $traverse_recurse['last_table_info'] );
3275
+
3276
+ if ( $has_last_table_info ) {
3277
+ $table_info = $traverse_recurse['last_table_info'];
3278
 
3279
+ if ( ! empty( $table_info['meta_table'] ) ) {
3280
  $meta_data_table = true;
3281
  }
 
 
3282
  } else {
3283
  if ( ! isset( $traverse['pod'] ) ) {
3284
  $traverse['pod'] = null;
3288
  $traverse['pick_val'] = null;
3289
  }
3290
 
3291
+ $table_info = $this->api->get_table_info( $traverse['pick_object'], $traverse['pick_val'], null, $traverse['pod'], $traverse );
3292
+
3293
+ $traverse['table_info'] = $table_info;
3294
  }
3295
  }//end if
3296
 
3297
  if ( isset( $this->traversal[ $traverse_recurse['pod'] ][ $traverse['name'] ] ) ) {
3298
+ $traverse = $this->traversal[ $traverse_recurse['pod'] ][ $traverse['name'] ];
3299
  }
3300
 
3301
  $traverse = apply_filters( 'pods_data_traverse', $traverse, $traverse_recurse, $this );
3302
 
3303
+ if ( empty( $traverse ) || empty( $table_info ) ) {
3304
  return $joins;
3305
  }
3306
 
3310
  $traverse['id'] = $field;
3311
  }
3312
 
 
 
3313
  $this->traversal[ $traverse_recurse['pod'] ][ $field ] = $traverse;
3314
 
3315
  $field_joined = $field;
3316
 
3317
  if ( 0 < $traverse_recurse['depth'] && 't' !== $traverse_recurse['joined'] ) {
3318
+ if ( $meta_data_table && ( 'pick' !== $traverse['type'] || ! in_array( pods_v( 'pick_object', $traverse, true ), $simple_tableless_objects, true ) ) ) {
3319
  $field_joined = $traverse_recurse['joined'] . '_d';
3320
  } else {
3321
  $field_joined = $traverse_recurse['joined'] . '_' . $field;
3446
  LEFT JOIN `{$table_info['pod_table']}` AS `{$field_joined}` ON
3447
  `{$field_joined}`.`{$table_info['pod_field_id']}` = `{$traverse_recurse['rel_alias']}`.`{$joined_id}`
3448
  ";
3449
+ } elseif ( pods_podsrel_enabled() ) {
3450
  if ( ( $traverse_recurse['depth'] + 2 ) === count( $traverse_recurse['fields'] ) && ( 'pick' !== $traverse['type'] || ! in_array( pods_v( 'pick_object', $traverse ), $simple_tableless_objects, true ) ) && 'post_author' === $traverse_recurse['fields'][ $traverse_recurse['depth'] + 1 ] ) {
3451
  $table_info['recurse'] = false;
3452
  }
3453
 
3454
+ if ( ! is_numeric( $traverse['id'] ) ) {
3455
+ $the_join = "
3456
+ LEFT JOIN `{$table_info[ 'table' ]}` AS `{$field_joined}` ON
3457
+ `{$field_joined}`.`{$table_info[ 'field_id' ]}` = `{$traverse_recurse[ 'joined' ]}`.`{$traverse['id']}`
3458
+ ";
3459
+ } else {
3460
+ $the_join = "
3461
+ LEFT JOIN `@wp_podsrel` AS `{$rel_alias}` ON
3462
+ `{$rel_alias}`.`field_id` = {$traverse[ 'id' ]}
3463
+ AND `{$rel_alias}`.`item_id` = `{$traverse_recurse[ 'joined' ]}`.`{$traverse_recurse[ 'joined_id' ]}`
3464
 
3465
+ LEFT JOIN `{$table_info[ 'table' ]}` AS `{$field_joined}` ON
3466
+ `{$field_joined}`.`{$table_info[ 'field_id' ]}` = `{$rel_alias}`.`related_item_id`
3467
+ ";
3468
+ }
3469
  }//end if
3470
  } elseif ( 'meta' === $pod_data['storage'] ) {
3471
  if ( ( $traverse_recurse['depth'] + 2 ) === count( $traverse_recurse['fields'] ) && ( 'pick' !== $traverse['type'] || ! in_array( pods_v( 'pick_object', $traverse ), $simple_tableless_objects, true ) ) && $table_info['meta_field_value'] === $traverse_recurse['fields'][ $traverse_recurse['depth'] + 1 ] ) {
3526
  * @return array Array of joins
3527
  */
3528
  public function traverse( $fields = null, $all_fields = null, $params = null ) {
 
 
 
3529
  if ( null === $fields ) {
3530
  $fields = $this->traverse_build( $all_fields, $params );
3531
  }
3532
 
3533
+ $fields = (array) $fields;
 
 
 
 
 
 
 
 
3534
 
3535
+ $recurse_joins = [];
 
3536
 
3537
+ foreach ( $fields as $field ) {
3538
+ $traverse_recurse = [
3539
+ 'pod' => $this->pod,
3540
+ 'fields' => (array) $field,
3541
+ 'params' => $params,
3542
+ 'last_table_info' => isset( $this->pod_data ) ? $this->pod_data : $this->table_info,
3543
+ 'joined_id' => $this->field_id,
3544
+ 'joined_index' => $this->field_index,
3545
+ ];
3546
 
3547
+ $recurse_joins[] = $this->traverse_recurse( $traverse_recurse );
3548
+ }
 
3549
 
3550
+ $joins = array_merge( ...$recurse_joins );
3551
 
3552
+ return array_filter( $joins );
3553
  }
3554
 
3555
  /**
3614
 
3615
  return $sql;
3616
  }
3617
+
3618
+ /**
3619
+ * Handle variables that have been deprecated and PodsData vars
3620
+ *
3621
+ * @param string $name Property name.
3622
+ *
3623
+ * @return mixed
3624
+ *
3625
+ * @since 2.8.0
3626
+ */
3627
+ public function __get( $name ) {
3628
+ $name = (string) $name;
3629
+
3630
+ // Map deprecated properties.
3631
+ $mapped = array(
3632
+ 'data' => 'rows',
3633
+ );
3634
+
3635
+ if ( isset( $mapped[ $name ] ) ) {
3636
+ return $this->{$mapped[$name]};
3637
+ }
3638
+
3639
+ // Handle alias Pod properties.
3640
+ $supported_pods_object = array(
3641
+ 'pod' => 'name',
3642
+ 'pod_id' => 'id',
3643
+ 'fields' => 'fields',
3644
+ 'object_fields' => 'object_fields',
3645
+ 'detail_page' => 'detail_url',
3646
+ 'detail_url' => 'detail_url',
3647
+ 'select' => 'select',
3648
+ 'table' => 'table',
3649
+ 'field_id' => 'field_id',
3650
+ 'field_index' => 'field_index',
3651
+ 'field_slug' => 'field_slug',
3652
+ 'join' => 'join',
3653
+ 'where' => 'where',
3654
+ 'where_default' => 'where_default',
3655
+ 'orderby' => 'orderby',
3656
+ 'type' => 'type',
3657
+ 'storage' => 'storage',
3658
+ );
3659
+
3660
+ if ( isset( $supported_pods_object[ $name ] ) ) {
3661
+ if ( ! $this->pod_data instanceof Pod ) {
3662
+ // Check if table info is set.
3663
+ if ( ! is_array( $this->table_info ) ) {
3664
+ return null;
3665
+ }
3666
+
3667
+ return pods_v( $supported_pods_object[ $name ], $this->table_info );
3668
+ }
3669
+
3670
+ return $this->pod_data->get_arg( $supported_pods_object[ $name ] );
3671
+ }
3672
+
3673
+ return null;
3674
+ }
3675
+
3676
+ /**
3677
+ * Handle variables that have been deprecated.
3678
+ *
3679
+ * @param string $name Property name.
3680
+ * @param mixed $value Property value.
3681
+ *
3682
+ * @since 2.8.0
3683
+ */
3684
+ public function __set( $name, $value ) {
3685
+ // Don't do anything.
3686
+ return;
3687
+ }
3688
+
3689
+ /**
3690
+ * Handle variables that have been deprecated.
3691
+ *
3692
+ * @param string $name Property name.
3693
+ *
3694
+ * @return bool Whether the variable is set or not.
3695
+ *
3696
+ * @since 2.8.0
3697
+ */
3698
+ public function __isset( $name ) {
3699
+ // Handle alias Pod properties.
3700
+ $supported_pods_object = array(
3701
+ 'pod' => 'name',
3702
+ 'pod_id' => 'id',
3703
+ 'fields' => 'fields',
3704
+ 'detail_page' => 'detail_url',
3705
+ 'detail_url' => 'detail_url',
3706
+ 'select' => 'select',
3707
+ 'table' => 'table',
3708
+ 'field_id' => 'field_id',
3709
+ 'field_index' => 'field_index',
3710
+ 'field_slug' => 'field_slug',
3711
+ 'join' => 'join',
3712
+ 'where' => 'where',
3713
+ 'where_default' => 'where_default',
3714
+ 'orderby' => 'orderby',
3715
+ );
3716
+
3717
+ if ( isset( $supported_pods_object[ $name ] ) ) {
3718
+ if ( ! $this->pod_data instanceof Pod ) {
3719
+ // Check if table info is set.
3720
+ if ( ! is_array( $this->table_info ) ) {
3721
+ return false;
3722
+ }
3723
+
3724
+ return null !== pods_v( $supported_pods_object[ $name ], $this->table_info );
3725
+ }
3726
+
3727
+ return null !== $this->pod_data->get_arg( $supported_pods_object[ $name ] );
3728
+ }
3729
+
3730
+ return false;
3731
+ }
3732
+
3733
+ /**
3734
+ * Handle variables that have been deprecated.
3735
+ *
3736
+ * @param string $name Property name.
3737
+ *
3738
+ * @since 2.8.0
3739
+ */
3740
+ public function __unset( $name ) {
3741
+ // Don't do anything.
3742
+ return;
3743
+ }
3744
  }
classes/PodsField.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  /**
4
  * Pods Field class for common type-specific methods.
5
  *
@@ -311,14 +313,14 @@ class PodsField {
311
  * @param string|null $name Field name.
312
  * @param mixed|null $value Current value.
313
  * @param array|null $options Field options.
314
- * @param array|null $pod Pod information.
315
  * @param int|string|null $id Current item ID.
316
  *
317
  * @since 2.0.0
318
  */
319
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
320
 
321
- $options = (array) $options;
322
 
323
  $form_field_type = PodsForm::$field_type;
324
 
@@ -348,26 +350,62 @@ class PodsField {
348
  * @param array|object $args {
349
  * Field information arguments.
350
  *
351
- * @type string $name Field name.
352
- * @type string $type Field type.
353
- * @type array $options Field options.
354
- * @type mixed $value Current value.
355
- * @type array $pod Pod information.
356
- * @type int|string $id Current item ID.
357
- * @type string $form_field_type HTML field type.
 
358
  * }
359
  */
360
  public function render_input_script( $args ) {
361
-
362
  if ( is_array( $args ) ) {
363
  $args = (object) $args;
364
  }
365
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
  $script_content = wp_json_encode( $this->build_dfv_field_data( $args ), JSON_HEX_TAG );
367
  ?>
368
- <div class="pods-form-ui-field pods-dfv-field">
 
 
 
369
  <?php // @codingStandardsIgnoreLine ?>
370
- <script type="application/json" class="pods-dfv-field-data"><?php echo $script_content; ?></script>
371
  </div>
372
  <?php
373
 
@@ -379,39 +417,49 @@ class PodsField {
379
  * @param object $args {
380
  * Field information arguments.
381
  *
382
- * @type string $name Field name.
383
- * @type string $type Field type.
384
- * @type array $options Field options.
385
- * @type mixed $value Current value.
386
- * @type array $pod Pod information.
387
- * @type int|string $id Current item ID.
388
- * @type string $form_field_type HTML field type.
 
389
  * }
390
  *
391
  * @return array
392
  */
393
  public function build_dfv_field_data( $args ) {
 
394
 
395
  // Handle DFV options.
396
- $args->options = $this->build_dfv_field_options( $args->options, $args );
397
 
398
  // Handle DFV attributes.
399
  $attributes = PodsForm::merge_attributes( array(), $args->name, $args->type, $args->options );
400
  $attributes = $this->build_dfv_field_attributes( $attributes, $args );
401
  $attributes = array_map( 'esc_attr', $attributes );
402
 
 
 
 
 
 
 
403
  // Build DFV field data.
404
- $data = array(
405
- 'htmlAttr' => array(
406
  'id' => $attributes['id'],
407
  'class' => $attributes['class'],
408
  'name' => $attributes['name'],
409
  'name_clean' => $attributes['data-name-clean'],
410
- ),
411
  'fieldType' => $args->type,
412
  'fieldItemData' => $this->build_dfv_field_item_data( $args ),
413
  'fieldConfig' => $this->build_dfv_field_config( $args ),
414
- );
 
 
415
 
416
  /**
417
  * Filter Pods DFV field data to further customize functionality.
@@ -495,25 +543,43 @@ class PodsField {
495
  * @param object $args {
496
  * Field information arguments.
497
  *
498
- * @type string $name Field name.
499
- * @type string $type Field type.
500
- * @type array $options Field options.
501
- * @type mixed $value Current value.
502
- * @type array $pod Pod information.
503
- * @type int|string $id Current item ID.
504
- * @type string $form_field_type HTML field type.
 
505
  * }
506
  *
507
  * @return array
508
  */
509
  public function build_dfv_field_config( $args ) {
510
-
511
- $config = $args->options;
 
 
 
512
 
513
  unset( $config['data'] );
514
 
515
  $config['item_id'] = (int) $args->id;
516
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
517
  return $config;
518
 
519
  }
@@ -539,8 +605,8 @@ class PodsField {
539
 
540
  $data = array();
541
 
542
- if ( ! empty( $args->options['data'] ) && is_array( $args->options['data'] ) ) {
543
- $data = $args->options['data'];
544
  }
545
 
546
  return $data;
@@ -774,48 +840,108 @@ class PodsField {
774
  * @return string
775
  */
776
  public function strip_html( $value, $options = null ) {
777
-
778
  if ( is_array( $value ) ) {
779
- // @codingStandardsIgnoreLine
780
- $value = @implode( ' ', $value );
781
- }
782
 
783
- $value = trim( $value );
 
784
 
785
  if ( empty( $value ) ) {
786
  return $value;
787
  }
788
 
789
- $options = (array) $options;
790
-
791
- // Strip HTML
792
- if ( 1 === (int) pods_v( static::$type . '_allow_html', $options, 0 ) ) {
793
- $allowed_html_tags = '';
794
 
795
- if ( 0 < strlen( pods_v( static::$type . '_allowed_html_tags', $options ) ) ) {
 
796
  $allowed_tags = pods_v( static::$type . '_allowed_html_tags', $options );
797
- $allowed_tags = trim( str_replace( array( '<', '>', ',' ), ' ', $allowed_tags ) );
798
- $allowed_tags = explode( ' ', $allowed_tags );
799
- $allowed_tags = array_unique( array_filter( $allowed_tags ) );
800
 
801
- if ( ! empty( $allowed_tags ) ) {
802
- $allowed_html_tags = '<' . implode( '><', $allowed_tags ) . '>';
 
 
 
 
 
 
 
 
803
  }
 
 
804
  }
 
 
 
 
805
 
806
- if ( ! empty( $allowed_html_tags ) ) {
807
- $value = strip_tags( $value, $allowed_html_tags );
 
 
 
 
 
 
 
 
 
 
 
 
808
  }
809
- } else {
810
- $value = strip_tags( $value );
811
  }
812
 
813
- // Strip shortcodes
814
- if ( 0 === (int) pods_v( static::$type . '_allow_shortcode', $options ) ) {
815
- $value = strip_shortcodes( $value );
816
  }
817
 
818
- return $value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
819
  }
820
 
821
  /**
1
  <?php
2
 
3
+ use Pods\Whatsit\Field;
4
+
5
  /**
6
  * Pods Field class for common type-specific methods.
7
  *
313
  * @param string|null $name Field name.
314
  * @param mixed|null $value Current value.
315
  * @param array|null $options Field options.
316
+ * @param array|Pods|null $pod Pod data or the Pods object.
317
  * @param int|string|null $id Current item ID.
318
  *
319
  * @since 2.0.0
320
  */
321
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
322
 
323
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
324
 
325
  $form_field_type = PodsForm::$field_type;
326
 
350
  * @param array|object $args {
351
  * Field information arguments.
352
  *
353
+ * @type string $name Field name.
354
+ * @type string $type Field type.
355
+ * @type array $options Field options.
356
+ * @type Field|null $field Field object (if provided).
357
+ * @type mixed $value Current value.
358
+ * @type array|Pods|null $pod Pod data or the Pods object.
359
+ * @type int|string $id Current item ID.
360
+ * @type string $form_field_type HTML field type.
361
  * }
362
  */
363
  public function render_input_script( $args ) {
 
364
  if ( is_array( $args ) ) {
365
  $args = (object) $args;
366
  }
367
 
368
+ // Detect field object being passed to the $options array upstream.
369
+ if ( ! empty( $args->options['_field_object'] ) ) {
370
+ $args->field = $args->options['_field_object'];
371
+
372
+ unset( $args->options['_field_object'] );
373
+ }
374
+
375
+ // Update options so it's as expected.
376
+ if ( ! empty( $args->field ) ) {
377
+ $args->options = pods_config_merge_data( $args->options, clone $args->field );
378
+ }
379
+
380
+ // Remove potential 2.8 beta fragments.
381
+ if ( ! empty( $args->options['pod_data'] ) ) {
382
+ unset( $args->options['pod_data'] );
383
+ }
384
+
385
+ $disable_dfv = ! empty( $args->options['disable_dfv'] );
386
+
387
+ $field_class = "pods-form-ui-field pods-dfv-field";
388
+
389
+ if ( ! $disable_dfv ) {
390
+ $field_class .= ' pods-dfv-field--unloaded';
391
+ }
392
+
393
+ $pod_name = '';
394
+
395
+ if ( $args->pod instanceof Pods ) {
396
+ $pod_name = $args->pod->pod_data['name'];
397
+ } elseif ( ! empty( $args->pod ) ) {
398
+ $pod_name = $args->pod['name'];
399
+ }
400
+
401
  $script_content = wp_json_encode( $this->build_dfv_field_data( $args ), JSON_HEX_TAG );
402
  ?>
403
+ <div class="<?php echo esc_attr( $field_class ); ?>">
404
+ <?php if ( ! $disable_dfv ) : ?>
405
+ <span class="pods-dfv-field__loading-indicator" role="progressbar"></span>
406
+ <?php endif; ?>
407
  <?php // @codingStandardsIgnoreLine ?>
408
+ <script type="application/json" class="pods-dfv-field-data" data-pod="<?php echo esc_attr( $pod_name ); ?>"><?php echo $script_content; ?></script>
409
  </div>
410
  <?php
411
 
417
  * @param object $args {
418
  * Field information arguments.
419
  *
420
+ * @type string $name Field name.
421
+ * @type string $type Field type.
422
+ * @type array $options Field options.
423
+ * @type Field|null $field Field object (if provided).
424
+ * @type mixed $value Current value.
425
+ * @type array $pod Pod information.
426
+ * @type int|string $id Current item ID.
427
+ * @type string $form_field_type HTML field type.
428
  * }
429
  *
430
  * @return array
431
  */
432
  public function build_dfv_field_data( $args ) {
433
+ $options = $args->options;
434
 
435
  // Handle DFV options.
436
+ $args->options = $this->build_dfv_field_options( $options, $args );
437
 
438
  // Handle DFV attributes.
439
  $attributes = PodsForm::merge_attributes( array(), $args->name, $args->type, $args->options );
440
  $attributes = $this->build_dfv_field_attributes( $attributes, $args );
441
  $attributes = array_map( 'esc_attr', $attributes );
442
 
443
+ $default_value = '';
444
+
445
+ if ( 'multi' === pods_v( $args->type . '_format_type' ) ) {
446
+ $default_value = [];
447
+ }
448
+
449
  // Build DFV field data.
450
+ $data = [
451
+ 'htmlAttr' => [
452
  'id' => $attributes['id'],
453
  'class' => $attributes['class'],
454
  'name' => $attributes['name'],
455
  'name_clean' => $attributes['data-name-clean'],
456
+ ],
457
  'fieldType' => $args->type,
458
  'fieldItemData' => $this->build_dfv_field_item_data( $args ),
459
  'fieldConfig' => $this->build_dfv_field_config( $args ),
460
+ 'fieldEmbed' => true,
461
+ 'fieldValue' => isset( $args->value ) ? $args->value : PodsForm::default_value( $default_value, $args->type, pods_v( 'name', $options, $args->name ), $options, $args->pod, $args->id ),
462
+ ];
463
 
464
  /**
465
  * Filter Pods DFV field data to further customize functionality.
543
  * @param object $args {
544
  * Field information arguments.
545
  *
546
+ * @type string $name Field name.
547
+ * @type string $type Field type.
548
+ * @type array $options Field options.
549
+ * @type Field|null $field Field object (if provided).
550
+ * @type mixed $value Current value.
551
+ * @type array $pod Pod information.
552
+ * @type int|string $id Current item ID.
553
+ * @type string $form_field_type HTML field type.
554
  * }
555
  *
556
  * @return array
557
  */
558
  public function build_dfv_field_config( $args ) {
559
+ if ( $args->options instanceof Field ) {
560
+ $config = $args->options->export();
561
+ } else {
562
+ $config = (array) $args->options;
563
+ }
564
 
565
  unset( $config['data'] );
566
 
567
  $config['item_id'] = (int) $args->id;
568
 
569
+ // Support passing missing options.
570
+ $check_missing = [
571
+ 'type',
572
+ 'name',
573
+ 'label',
574
+ 'id',
575
+ ];
576
+
577
+ foreach ( $check_missing as $missing_name ) {
578
+ if ( ! empty( $args->{$missing_name} ) ) {
579
+ $config[ $missing_name ] = $args->{$missing_name};
580
+ }
581
+ }
582
+
583
  return $config;
584
 
585
  }
605
 
606
  $data = array();
607
 
608
+ if ( ! empty( $args->options['fieldItemData'] ) && is_array( $args->options['fieldItemData'] ) ) {
609
+ $data = $args->options['fieldItemData'];
610
  }
611
 
612
  return $data;
840
  * @return string
841
  */
842
  public function strip_html( $value, $options = null ) {
 
843
  if ( is_array( $value ) ) {
844
+ foreach ( $value as $k => $v ) {
845
+ $value[ $k ] = $this->strip_html( $v, $options );
846
+ }
847
 
848
+ return $value;
849
+ }
850
 
851
  if ( empty( $value ) ) {
852
  return $value;
853
  }
854
 
855
+ if ( $options ) {
856
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
 
 
 
857
 
858
+ // Strip HTML
859
+ if ( 1 === (int) pods_v( static::$type . '_allow_html', $options, 0 ) ) {
860
  $allowed_tags = pods_v( static::$type . '_allowed_html_tags', $options );
 
 
 
861
 
862
+ if ( 0 < strlen( $allowed_tags ) ) {
863
+ $allowed_tags = trim( str_replace( [ '<', '>', ',' ], ' ', $allowed_tags ) );
864
+ $allowed_tags = explode( ' ', $allowed_tags );
865
+ $allowed_tags = array_unique( array_filter( $allowed_tags ) );
866
+
867
+ if ( ! empty( $allowed_tags ) ) {
868
+ $allowed_html_tags = '<' . implode( '><', $allowed_tags ) . '>';
869
+
870
+ $value = strip_tags( $value, $allowed_html_tags );
871
+ }
872
  }
873
+
874
+ return $value;
875
  }
876
+ }
877
+
878
+ return strip_tags( $value );
879
+ }
880
 
881
+ /**
882
+ * Strip shortcodes based on options.
883
+ *
884
+ * @since 2.8.0
885
+ *
886
+ * @param string|array $value The field value.
887
+ * @param array|Field|null $options The field options.
888
+ *
889
+ * @return string The field value.
890
+ */
891
+ public function strip_shortcodes( $value, $options = null ) {
892
+ if ( is_array( $value ) ) {
893
+ foreach ( $value as $k => $v ) {
894
+ $value[ $k ] = $this->strip_shortcodes( $v, $options );
895
  }
896
+
897
+ return $value;
898
  }
899
 
900
+ if ( empty( $value ) ) {
901
+ return $value;
 
902
  }
903
 
904
+ if ( $options ) {
905
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
906
+
907
+ // Check if we should strip shortcodes.
908
+ if ( 1 === (int) pods_v( static::$type . '_allow_shortcode', $options, 0 ) ) {
909
+ return $value;
910
+ }
911
+ }
912
+
913
+ return strip_shortcodes( $value );
914
+ }
915
+
916
+ /**
917
+ * Trim whitespace based on options.
918
+ *
919
+ * @since 2.8.0
920
+ *
921
+ * @param string|array $value The field value.
922
+ * @param array|Field|null $options The field options.
923
+ *
924
+ * @return string The field value.
925
+ */
926
+ public function trim_whitespace( $value, $options = null ) {
927
+ if ( is_array( $value ) ) {
928
+ foreach ( $value as $k => $v ) {
929
+ $value[ $k ] = $this->trim_whitespace( $v, $options );
930
+ }
931
+
932
+ return $value;
933
+ }
934
+
935
+ if ( $options ) {
936
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
937
+
938
+ // Check if we should trim the content.
939
+ if ( 0 === (int) pods_v( static::$type . '_trim', $options, 1 ) ) {
940
+ return $value;
941
+ }
942
+ }
943
+
944
+ return trim( $value );
945
  }
946
 
947
  /**
classes/PodsForm.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  /**
4
  * @package Pods
5
  */
@@ -174,12 +176,12 @@ class PodsForm {
174
  /**
175
  * Output a field
176
  *
177
- * @param string $name Field name
178
- * @param mixed $value Field value
179
- * @param string $type Field type
180
- * @param array $options Field options
181
- * @param array $pod Pod data
182
- * @param int $id Item ID
183
  *
184
  * @return string Field HTML
185
  *
@@ -234,7 +236,7 @@ class PodsForm {
234
  $helper = pods_api()->load_helper( array( 'name' => $options['input_helper'] ) );
235
  }
236
 
237
- // @todo Move into DFV field method or PodsObject later
238
  if ( ( ! isset( $options['data'] ) || empty( $options['data'] ) ) && is_object( self::$loaded[ $type ] ) && method_exists( self::$loaded[ $type ], 'data' ) ) {
239
  $options['data'] = self::$loaded[ $type ]->data( $name, $value, $options, $pod, $id, true );
240
  $data = $options['data'];
@@ -610,55 +612,44 @@ class PodsForm {
610
  * @since 2.0.0
611
  */
612
  public static function options( $type, $options ) {
613
-
614
- $options = (array) $options;
615
-
616
- if ( ! is_object( $options ) && isset( $options['options'] ) ) {
617
- $options_temp = $options['options'];
618
-
619
- unset( $options['options'] );
620
-
621
- $options = array_merge( $options_temp, $options );
622
-
623
- $override = array(
624
- 'class',
625
- );
626
-
627
- foreach ( $override as $check ) {
628
- if ( isset( $options_temp[ $check ] ) ) {
629
- $options[ $check ] = $options_temp[ $check ];
630
- }
631
- }
632
  }
633
 
634
- $defaults = self::options_setup( $type, $options );
635
 
636
- $core_defaults = array(
637
  'id' => 0,
638
  'label' => '',
639
  'description' => '',
640
  'help' => '',
641
  'default' => null,
642
- 'attributes' => array(),
643
  'class' => '',
644
  'grouped' => 0,
645
- );
646
 
647
  $defaults = array_merge( $core_defaults, $defaults );
648
 
649
  foreach ( $defaults as $option => $settings ) {
650
- $default = $settings;
651
 
652
- if ( is_array( $settings ) && isset( $settings['default'] ) ) {
 
 
653
  $default = $settings['default'];
654
  }
655
 
656
- if ( ! isset( $options[ $option ] ) ) {
657
- $options[ $option ] = $default;
658
  }
659
  }
660
 
661
- return $options;
662
  }
663
 
664
  /**
@@ -690,7 +681,9 @@ class PodsForm {
690
  'developer_mode' => false,
691
  'dependency' => false,
692
  'depends-on' => array(),
 
693
  'excludes-on' => array(),
 
694
  'options' => array(),
695
  );
696
 
@@ -704,23 +697,19 @@ class PodsForm {
704
  self::field_loader( $type );
705
  }
706
 
707
- $options = apply_filters( "pods_field_{$type}_options", (array) self::$loaded[ $type ]->options(), $type );
708
-
709
- $first_field = current( $options );
710
 
711
- if ( ! empty( $options ) && ! isset( $first_field['name'] ) && ! isset( $first_field['label'] ) ) {
712
- $all_options = array();
713
 
714
- foreach ( $options as $group => $group_options ) {
715
- $all_options = array_merge( $all_options, self::fields_setup( $group_options, $core_defaults ) );
 
716
  }
717
 
718
- $options = $all_options;
719
- } else {
720
- $options = self::fields_setup( $options, $core_defaults );
721
  }
722
 
723
- return $options;
724
  }
725
 
726
  /**
@@ -751,25 +740,27 @@ class PodsForm {
751
  'developer_mode' => false,
752
  'dependency' => false,
753
  'depends-on' => array(),
 
754
  'excludes-on' => array(),
 
755
  'options' => array(),
756
  );
757
 
758
  self::field_loader( $type );
759
 
760
- $options = apply_filters( "pods_field_{$type}_ui_options", (array) self::$loaded[ $type ]->ui_options(), $type );
761
 
762
- $first_field = current( $options );
763
 
764
- if ( ! empty( $options ) && ! isset( $first_field['name'] ) && ! isset( $first_field['label'] ) ) {
765
- foreach ( $options as $group => $group_options ) {
766
- $options[ $group ] = self::fields_setup( $group_options, $core_defaults );
767
  }
768
- } else {
769
- $options = self::fields_setup( $options, $core_defaults );
770
  }
771
 
772
- return $options;
773
  }
774
 
775
  /**
@@ -802,7 +793,9 @@ class PodsForm {
802
  'developer_mode' => false,
803
  'dependency' => false,
804
  'depends-on' => array(),
 
805
  'excludes-on' => array(),
 
806
  'options' => array(),
807
  );
808
  }
@@ -812,11 +805,11 @@ class PodsForm {
812
  }
813
 
814
  foreach ( $fields as $f => $field ) {
815
- $fields[ $f ] = self::field_setup( $field, $core_defaults, pods_v( 'type', $field, 'text' ) );
816
-
817
- if ( ! $single && strlen( $fields[ $f ]['name'] ) < 1 ) {
818
- $fields[ $f ]['name'] = $f;
819
  }
 
 
820
  }
821
 
822
  if ( $single ) {
@@ -831,9 +824,9 @@ class PodsForm {
831
  *
832
  * @static
833
  *
834
- * @param null $field
835
- * @param null $core_defaults
836
- * @param null $type
837
  *
838
  * @return array|null
839
  *
@@ -841,7 +834,7 @@ class PodsForm {
841
  */
842
  public static function field_setup( $field = null, $core_defaults = null, $type = null ) {
843
 
844
- $options = array();
845
 
846
  if ( empty( $core_defaults ) ) {
847
  $core_defaults = array(
@@ -859,7 +852,9 @@ class PodsForm {
859
  'developer_mode' => false,
860
  'dependency' => false,
861
  'depends-on' => array(),
 
862
  'excludes-on' => array(),
 
863
  'options' => array(),
864
  );
865
 
@@ -867,36 +862,55 @@ class PodsForm {
867
  self::field_loader( $type );
868
 
869
  if ( method_exists( self::$loaded[ $type ], 'options' ) ) {
870
- $options = apply_filters( "pods_field_{$type}_options", (array) self::$loaded[ $type ]->options(), $type );
871
  }
872
  }
873
  }//end if
874
 
875
- if ( ! is_array( $field ) ) {
876
- $field = array( 'default' => $field );
 
 
 
 
877
  }
878
 
 
879
  if ( isset( $field['group'] ) && is_array( $field['group'] ) ) {
880
- foreach ( $field['group'] as $g => $group_option ) {
881
- $field['group'][ $g ] = array_merge( $core_defaults, $group_option );
 
 
882
 
883
- if ( strlen( $field['group'][ $g ]['name'] ) < 1 ) {
884
- $field['group'][ $g ]['name'] = $g;
885
  }
886
  }
 
 
887
  }
888
 
889
- $field = array_merge( $core_defaults, $field );
 
 
 
 
 
890
 
891
- foreach ( $options as $option => $settings ) {
892
- $v = null;
893
 
894
  if ( isset( $settings['default'] ) ) {
895
- $v = $settings['default'];
896
  }
897
 
898
- if ( ! isset( $field['options'][ $option ] ) ) {
899
- $field['options'][ $option ] = $v;
 
 
 
 
 
 
900
  }
901
  }
902
 
@@ -913,53 +927,41 @@ class PodsForm {
913
  * @static
914
  * @since 2.0.0
915
  */
916
- public static function dependencies( $options, $prefix = '' ) {
917
-
918
- $options = (array) $options;
919
- $classes = array();
920
- $data = array();
921
- $depends_on = array();
922
- $excludes_on = array();
923
- $wildcard_on = array();
 
 
 
 
 
 
 
924
 
925
- if ( isset( $options['depends-on'] ) ) {
926
- $depends_on = (array) $options['depends-on'];
927
 
928
- if ( ! empty( $depends_on ) ) {
929
- $classes[] = 'pods-depends-on';
930
 
931
- foreach ( $depends_on as $depends => $on ) {
932
- $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true );
933
 
934
  if ( ! is_bool( $on ) ) {
935
  $on = (array) $on;
936
 
937
  foreach ( $on as $o ) {
938
- $classes[] = 'pods-depends-on-' . $prefix . self::clean( $depends, true ) . '-' . self::clean( $o, true );
939
  }
940
  }
941
  }
942
  }
943
  }
944
 
945
- if ( isset( $options['excludes-on'] ) ) {
946
- $excludes_on = (array) $options['excludes-on'];
947
-
948
- if ( ! empty( $excludes_on ) ) {
949
- $classes[] = 'pods-excludes-on';
950
-
951
- foreach ( $excludes_on as $excludes => $on ) {
952
- $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true );
953
-
954
- $on = (array) $on;
955
-
956
- foreach ( $on as $o ) {
957
- $classes[] = 'pods-excludes-on-' . $prefix . self::clean( $excludes, true ) . '-' . self::clean( $o, true );
958
- }
959
- }
960
- }
961
- }
962
-
963
  if ( isset( $options['wildcard-on'] ) ) {
964
  $wildcard_on = (array) $options['wildcard-on'];
965
 
@@ -1284,12 +1286,13 @@ class PodsForm {
1284
  * @return bool
1285
  */
1286
  public static function permission( $type, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
1287
-
1288
  $permission = pods_permission( $options );
1289
 
1290
- $permission = (boolean) apply_filters( 'pods_form_field_permission', $permission, $type, $name, $options, $fields, $pod, $id, $params );
1291
-
1292
- return $permission;
 
 
1293
  }
1294
 
1295
  /**
@@ -1317,21 +1320,29 @@ class PodsForm {
1317
  $default = pods_v( 'default', $options, $default_value, true );
1318
 
1319
  if ( is_string( $default ) ) {
1320
- $default_value = str_replace( array( '{@', '}' ), '', trim( $default ) );
1321
- }
1322
 
1323
- if ( $default != $default_value && 1 == (int) pods_v( 'default_evaluate_tags', $options, 1 ) ) {
1324
- $default = pods_evaluate_tags( $default );
 
1325
  }
1326
 
1327
- $default = pods_v( pods_v( 'default_value_parameter', $options ), 'request', $default, true );
 
 
 
 
 
 
 
 
1328
 
1329
  if ( $default != $value ) {
1330
  $value = $default;
1331
  }
1332
 
1333
- if ( is_array( $value ) ) {
1334
- $value = pods_serial_comma( $value );
1335
  }
1336
 
1337
  return apply_filters( 'pods_form_field_default_value', $value, $default, $type, $options, $pod, $id );
@@ -1402,7 +1413,7 @@ class PodsForm {
1402
  }
1403
  }
1404
 
1405
- pods_transient_set( 'pods_form_admin_init_field_types', $admin_field_types );
1406
  } else {
1407
  foreach ( $admin_field_types as $field_type ) {
1408
  self::field_method( $field_type, 'admin_init' );
@@ -1434,8 +1445,6 @@ class PodsForm {
1434
  }
1435
  }
1436
 
1437
- include_once PODS_DIR . 'classes/PodsField.php';
1438
-
1439
  $field_type = self::clean( $field_type, true, true );
1440
 
1441
  $class_name = ucfirst( $field_type );
@@ -1455,11 +1464,14 @@ class PodsForm {
1455
  if ( ! empty( $file ) && 0 === strpos( $file, $abspath_dir ) && file_exists( $file ) ) {
1456
  include_once $file;
1457
  } else {
1458
- $file = str_replace( '../', '', apply_filters( 'pods_form_field_include', PODS_DIR . 'classes/fields/' . basename( $field_type ) . '.php', $field_type ) );
1459
- $file = realpath( $file );
1460
 
1461
- 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 ) ) ) {
1462
- include_once $file;
 
 
 
 
1463
  }
1464
  }
1465
  }
@@ -1472,6 +1484,7 @@ class PodsForm {
1472
  }
1473
 
1474
  $class_vars = get_class_vars( $class_name );
 
1475
  // PHP 5.2.x workaround
1476
  self::$field_group = ( isset( $class_vars['group'] ) ? $class_vars['group'] : '' );
1477
  self::$field_type = $class_vars['type'];
@@ -1535,7 +1548,7 @@ class PodsForm {
1535
  self::$field_types[ $type ] = $class_vars;
1536
  self::$field_types[ $type ]['file'] = $file;
1537
 
1538
- pods_transient_set( 'pods_field_type_' . $type, self::$field_types[ $type ] );
1539
  } else {
1540
  self::$field_types[ $type ] = $field_type;
1541
  }
@@ -1544,15 +1557,43 @@ class PodsForm {
1544
  }
1545
 
1546
  /**
1547
- * Get a list of all available field types and include
1548
  *
1549
- * @return array Registered Field Types data
1550
  *
1551
- * @since 2.3.0
1552
  */
1553
- public static function field_types() {
 
 
 
 
 
 
 
 
 
 
1554
 
1555
- $field_types = array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1556
  'text',
1557
  'website',
1558
  // 'link',
@@ -1574,13 +1615,27 @@ class PodsForm {
1574
  'boolean',
1575
  'color',
1576
  'slug',
1577
- );
 
 
1578
 
1579
  $field_types = array_merge( $field_types, array_keys( self::$field_types ) );
1580
 
1581
  $field_types = array_filter( array_unique( $field_types ) );
1582
 
1583
- $types = apply_filters( 'pods_api_field_types', $field_types );
 
 
 
 
 
 
 
 
 
 
 
 
1584
 
1585
  $field_types = pods_transient_get( 'pods_field_types' );
1586
 
@@ -1608,7 +1663,7 @@ class PodsForm {
1608
 
1609
  self::$field_types = $field_types;
1610
 
1611
- pods_transient_set( 'pods_field_types', self::$field_types );
1612
  } else {
1613
  self::$field_types = array_merge( $field_types, self::$field_types );
1614
  }//end if
@@ -1617,24 +1672,24 @@ class PodsForm {
1617
  }
1618
 
1619
  /**
1620
- * Get list of available tableless field types
1621
- *
1622
- * @return array Tableless field types
1623
  *
1624
  * @since 2.3.0
 
 
1625
  */
1626
  public static function tableless_field_types() {
1627
-
1628
  static $field_types = null;
1629
 
1630
  if ( null === $field_types ) {
1631
- $field_types = array(
1632
  'pick',
1633
  'file',
1634
  'avatar',
1635
  'taxonomy',
1636
  'comment',
1637
- );
 
1638
 
1639
  $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1640
  }
@@ -1643,18 +1698,20 @@ class PodsForm {
1643
  }
1644
 
1645
  /**
1646
- * Get list of available file field types
1647
- *
1648
- * @return array File field types
1649
  *
1650
  * @since 2.3.0
 
 
1651
  */
1652
  public static function file_field_types() {
1653
-
1654
  static $field_types = null;
1655
 
1656
  if ( null === $field_types ) {
1657
- $field_types = array( 'file', 'avatar' );
 
 
 
1658
 
1659
  $field_types = apply_filters( 'pods_file_field_types', $field_types );
1660
  }
@@ -1663,18 +1720,17 @@ class PodsForm {
1663
  }
1664
 
1665
  /**
1666
- * Get list of available repeatable field types
1667
- *
1668
- * @return array Repeatable field types
1669
  *
1670
  * @since 2.3.0
 
 
1671
  */
1672
  public static function repeatable_field_types() {
1673
-
1674
  static $field_types = null;
1675
 
1676
  if ( null === $field_types ) {
1677
- $field_types = array(
1678
  'code',
1679
  'color',
1680
  'currency',
@@ -1688,7 +1744,7 @@ class PodsForm {
1688
  'time',
1689
  'website',
1690
  'wysiwyg',
1691
- );
1692
 
1693
  $field_types = apply_filters( 'pods_repeatable_field_types', $field_types );
1694
  }
@@ -1697,18 +1753,20 @@ class PodsForm {
1697
  }
1698
 
1699
  /**
1700
- * Get list of available number field types
1701
- *
1702
- * @return array Number field types
1703
  *
1704
  * @since 2.3.0
 
 
1705
  */
1706
  public static function number_field_types() {
1707
-
1708
  static $field_types = null;
1709
 
1710
  if ( null === $field_types ) {
1711
- $field_types = array( 'currency', 'number' );
 
 
 
1712
 
1713
  $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1714
  }
@@ -1717,18 +1775,21 @@ class PodsForm {
1717
  }
1718
 
1719
  /**
1720
- * Get list of available date field types
1721
- *
1722
- * @return array Date field types
1723
  *
1724
  * @since 2.3.0
 
 
1725
  */
1726
  public static function date_field_types() {
1727
-
1728
  static $field_types = null;
1729
 
1730
  if ( null === $field_types ) {
1731
- $field_types = array( 'date', 'datetime', 'time' );
 
 
 
 
1732
 
1733
  $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1734
  }
@@ -1737,18 +1798,24 @@ class PodsForm {
1737
  }
1738
 
1739
  /**
1740
- * Get list of available text field types
1741
- *
1742
- * @return array Text field types
1743
  *
1744
  * @since 2.3.0
 
 
1745
  */
1746
  public static function text_field_types() {
1747
-
1748
  static $field_types = null;
1749
 
1750
  if ( null === $field_types ) {
1751
- $field_types = array( 'code', 'paragraph', 'slug', 'password', 'text', 'wysiwyg' );
 
 
 
 
 
 
 
1752
 
1753
  $field_types = apply_filters( 'pods_text_field_types', $field_types );
1754
  }
@@ -1757,39 +1824,68 @@ class PodsForm {
1757
  }
1758
 
1759
  /**
1760
- * Get list of available text field types
1761
  *
1762
- * @return array Text field types
1763
  *
1764
- * @since 2.3.0
1765
  */
1766
- public static function block_field_types() {
1767
-
1768
  static $field_types = null;
1769
 
1770
  if ( null === $field_types ) {
1771
- $field_types = array( 'heading', 'html' );
 
 
 
1772
 
1773
  /**
1774
- * Returns the available text field types
1775
  *
1776
- * @since unknown
1777
  *
1778
- * @param object $field_types Outputs the field types
1779
  */
1780
-
1781
- $field_types = apply_filters( 'pods_block_field_types', $field_types );
1782
  }
1783
 
1784
  return $field_types;
1785
  }
1786
 
1787
  /**
1788
- * Get list of available text field types
1789
  *
1790
- * @return array Text field types
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1791
  *
1792
  * @since 2.3.0
 
 
1793
  */
1794
  public static function simple_tableless_objects() {
1795
 
1
  <?php
2
 
3
+ use Pods\Whatsit\Field;
4
+
5
  /**
6
  * @package Pods
7
  */
176
  /**
177
  * Output a field
178
  *
179
+ * @param string $name Field name
180
+ * @param mixed $value Field value
181
+ * @param string $type Field type
182
+ * @param array $options Field options
183
+ * @param array|Pods $pod Pod data or the Pods object.
184
+ * @param int $id Item ID
185
  *
186
  * @return string Field HTML
187
  *
236
  $helper = pods_api()->load_helper( array( 'name' => $options['input_helper'] ) );
237
  }
238
 
239
+ // @todo Move into DFV field method or Pods\Whatsit later
240
  if ( ( ! isset( $options['data'] ) || empty( $options['data'] ) ) && is_object( self::$loaded[ $type ] ) && method_exists( self::$loaded[ $type ], 'data' ) ) {
241
  $options['data'] = self::$loaded[ $type ]->data( $name, $value, $options, $pod, $id, true );
242
  $data = $options['data'];
612
  * @since 2.0.0
613
  */
614
  public static function options( $type, $options ) {
615
+ if ( is_object( $options ) ) {
616
+ $options_array = $options->get_args();
617
+ $options_array['_field_object'] = $options;
618
+ } else {
619
+ $options_array = (array) $options;
620
+ $options_array['_field_object'] = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
621
  }
622
 
623
+ $defaults = self::options_setup( $type );
624
 
625
+ $core_defaults = [
626
  'id' => 0,
627
  'label' => '',
628
  'description' => '',
629
  'help' => '',
630
  'default' => null,
631
+ 'attributes' => [],
632
  'class' => '',
633
  'grouped' => 0,
634
+ ];
635
 
636
  $defaults = array_merge( $core_defaults, $defaults );
637
 
638
  foreach ( $defaults as $option => $settings ) {
639
+ $default = $core_defaults['default'];
640
 
641
+ if ( ! is_array( $settings ) ) {
642
+ $default = $settings;
643
+ } elseif ( isset( $settings['default'] ) ) {
644
  $default = $settings['default'];
645
  }
646
 
647
+ if ( ! isset( $options_array[ $option ] ) ) {
648
+ $options_array[ $option ] = $default;
649
  }
650
  }
651
 
652
+ return $options_array;
653
  }
654
 
655
  /**
681
  'developer_mode' => false,
682
  'dependency' => false,
683
  'depends-on' => array(),
684
+ 'depends-on-any' => array(),
685
  'excludes-on' => array(),
686
+ 'wildcard-on' => array(),
687
  'options' => array(),
688
  );
689
 
697
  self::field_loader( $type );
698
  }
699
 
700
+ $ui_options = apply_filters( "pods_field_{$type}_options", (array) self::$loaded[ $type ]->options(), $type );
 
 
701
 
702
+ $first_field = reset( $ui_options );
 
703
 
704
+ if ( ! empty( $ui_options ) && ! isset( $first_field['name'] ) && ! isset( $first_field['label'] ) ) {
705
+ foreach ( $ui_options as $group => $group_options ) {
706
+ $ui_options[ $group ] = self::fields_setup( $group_options, $core_defaults );
707
  }
708
 
709
+ return $ui_options;
 
 
710
  }
711
 
712
+ return self::fields_setup( $ui_options, $core_defaults );
713
  }
714
 
715
  /**
740
  'developer_mode' => false,
741
  'dependency' => false,
742
  'depends-on' => array(),
743
+ 'depends-on-any' => array(),
744
  'excludes-on' => array(),
745
+ 'wildcard-on' => array(),
746
  'options' => array(),
747
  );
748
 
749
  self::field_loader( $type );
750
 
751
+ $ui_options = apply_filters( "pods_field_{$type}_ui_options", (array) self::$loaded[ $type ]->ui_options(), $type );
752
 
753
+ $first_field = reset( $ui_options );
754
 
755
+ if ( ! empty( $ui_options ) && ! isset( $first_field['name'] ) && ! isset( $first_field['label'] ) ) {
756
+ foreach ( $ui_options as $group => $group_options ) {
757
+ $ui_options[ $group ] = self::fields_setup( $group_options, $core_defaults );
758
  }
759
+
760
+ return $ui_options;
761
  }
762
 
763
+ return self::fields_setup( $ui_options, $core_defaults );
764
  }
765
 
766
  /**
793
  'developer_mode' => false,
794
  'dependency' => false,
795
  'depends-on' => array(),
796
+ 'depends-on-any' => array(),
797
  'excludes-on' => array(),
798
+ 'wildcard-on' => array(),
799
  'options' => array(),
800
  );
801
  }
805
  }
806
 
807
  foreach ( $fields as $f => $field ) {
808
+ if ( ! $single && empty( $field['name'] ) ) {
809
+ $field['name'] = $f;
 
 
810
  }
811
+
812
+ $fields[ $f ] = self::field_setup( $field, $core_defaults, pods_v( 'type', $field, 'text' ) );
813
  }
814
 
815
  if ( $single ) {
824
  *
825
  * @static
826
  *
827
+ * @param null|array|string|Field $field
828
+ * @param null|array $core_defaults
829
+ * @param null|string $type
830
  *
831
  * @return array|null
832
  *
834
  */
835
  public static function field_setup( $field = null, $core_defaults = null, $type = null ) {
836
 
837
+ $ui_options = array();
838
 
839
  if ( empty( $core_defaults ) ) {
840
  $core_defaults = array(
852
  'developer_mode' => false,
853
  'dependency' => false,
854
  'depends-on' => array(),
855
+ 'depends-on-any' => array(),
856
  'excludes-on' => array(),
857
+ 'wildcard-on' => array(),
858
  'options' => array(),
859
  );
860
 
862
  self::field_loader( $type );
863
 
864
  if ( method_exists( self::$loaded[ $type ], 'options' ) ) {
865
+ $ui_options = apply_filters( "pods_field_{$type}_options", (array) self::$loaded[ $type ]->options(), $type );
866
  }
867
  }
868
  }//end if
869
 
870
+ $is_field_object = $field instanceof Field;
871
+
872
+ if ( ! is_array( $field ) && ! $is_field_object ) {
873
+ $field = [
874
+ 'default' => $field,
875
+ ];
876
  }
877
 
878
+ // @todo Revisit this.
879
  if ( isset( $field['group'] ) && is_array( $field['group'] ) ) {
880
+ $group = $field['group'];
881
+
882
+ foreach ( $group as $g => $group_option ) {
883
+ $group[ $g ] = array_merge( $core_defaults, $group_option );
884
 
885
+ if ( ! isset( $group[ $g ] ) || '' === $group[ $g ]['name'] ) {
886
+ $group[ $g ]['name'] = $g;
887
  }
888
  }
889
+
890
+ $field['group'] = $group;
891
  }
892
 
893
+ $field = pods_config_merge_data( $core_defaults, $field );
894
+
895
+ foreach ( $ui_options as $option => $settings ) {
896
+ if ( ! is_string( $option ) ) {
897
+ $option = $settings['name'];
898
+ }
899
 
900
+ $default = null;
 
901
 
902
  if ( isset( $settings['default'] ) ) {
903
+ $default = $settings['default'];
904
  }
905
 
906
+ if ( $is_field_object ) {
907
+ $option_value = $field->get_arg( $option );
908
+
909
+ if ( null === $option_value ) {
910
+ $field->set_arg( $option, $default );
911
+ }
912
+ } elseif ( ! isset( $field['options'][ $option ] ) ) {
913
+ $field['options'][ $option ] = $default;
914
  }
915
  }
916
 
927
  * @static
928
  * @since 2.0.0
929
  */
930
+ public static function dependencies( $options, $prefix = 'pods-form-ui-' ) {
931
+ $options = (array) $options;
932
+ $classes = [];
933
+ $data = [];
934
+
935
+ $dependency_checks = [
936
+ 'depends-on',
937
+ 'depends-on-any',
938
+ 'excludes-on',
939
+ ];
940
+
941
+ foreach ( $dependency_checks as $dependency_check ) {
942
+ if ( ! isset( $options[ $dependency_check ] ) ) {
943
+ continue;
944
+ }
945
 
946
+ $dependency_list = (array) $options[ $dependency_check ];
 
947
 
948
+ if ( ! empty( $dependency_list ) ) {
949
+ $classes[] = 'pods-' . $dependency_check;
950
 
951
+ foreach ( $dependency_list as $depends => $on ) {
952
+ $classes[] = 'pods-' . $dependency_check . '-' . $prefix . self::clean( $depends, true );
953
 
954
  if ( ! is_bool( $on ) ) {
955
  $on = (array) $on;
956
 
957
  foreach ( $on as $o ) {
958
+ $classes[] = 'pods-' . $dependency_check . '-' . $prefix . self::clean( $depends, true ) . '-' . self::clean( $o, true );
959
  }
960
  }
961
  }
962
  }
963
  }
964
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
965
  if ( isset( $options['wildcard-on'] ) ) {
966
  $wildcard_on = (array) $options['wildcard-on'];
967
 
1286
  * @return bool
1287
  */
1288
  public static function permission( $type, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
 
1289
  $permission = pods_permission( $options );
1290
 
1291
+ /**
1292
+ * @since 2.0.0
1293
+ * @deprecated 2.8.0
1294
+ */
1295
+ return (boolean) apply_filters( 'pods_form_field_permission', $permission, $type, $name, $options, $fields, $pod, $id, $params );
1296
  }
1297
 
1298
  /**
1320
  $default = pods_v( 'default', $options, $default_value, true );
1321
 
1322
  if ( is_string( $default ) ) {
1323
+ $default_value = str_replace( array( '{@', '}' ), '', $default );
 
1324
 
1325
+ if ( $default !== $default_value && 1 === (int) pods_v( 'default_evaluate_tags', $options, 1 ) ) {
1326
+ $default = pods_evaluate_tags( $default );
1327
+ }
1328
  }
1329
 
1330
+ $default_value_parameter = pods_v( 'default_value_parameter', $options );
1331
+
1332
+ if ( $default_value_parameter ) {
1333
+ $default_value = pods_v( $default_value_parameter, 'request', $default );
1334
+
1335
+ if ( '' !== $default_value ) {
1336
+ $default = $default_value;
1337
+ }
1338
+ }
1339
 
1340
  if ( $default != $value ) {
1341
  $value = $default;
1342
  }
1343
 
1344
+ if ( is_array( $value ) && 'multi' !== pods_v( $args->type . '_format_type' ) ) {
1345
+ $value = pods_serial_comma( $value, $name, [ $name => $options ] );
1346
  }
1347
 
1348
  return apply_filters( 'pods_form_field_default_value', $value, $default, $type, $options, $pod, $id );
1413
  }
1414
  }
1415
 
1416
+ pods_transient_set( 'pods_form_admin_init_field_types', $admin_field_types, WEEK_IN_SECONDS );
1417
  } else {
1418
  foreach ( $admin_field_types as $field_type ) {
1419
  self::field_method( $field_type, 'admin_init' );
1445
  }
1446
  }
1447
 
 
 
1448
  $field_type = self::clean( $field_type, true, true );
1449
 
1450
  $class_name = ucfirst( $field_type );
1464
  if ( ! empty( $file ) && 0 === strpos( $file, $abspath_dir ) && file_exists( $file ) ) {
1465
  include_once $file;
1466
  } else {
1467
+ $file = str_replace( '../', '', apply_filters( 'pods_form_field_include', '', $field_type ) );
 
1468
 
1469
+ if ( ! empty( $file ) ) {
1470
+ $file = realpath( $file );
1471
+
1472
+ 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 ) ) ) {
1473
+ include_once $file;
1474
+ }
1475
  }
1476
  }
1477
  }
1484
  }
1485
 
1486
  $class_vars = get_class_vars( $class_name );
1487
+
1488
  // PHP 5.2.x workaround
1489
  self::$field_group = ( isset( $class_vars['group'] ) ? $class_vars['group'] : '' );
1490
  self::$field_type = $class_vars['type'];
1548
  self::$field_types[ $type ] = $class_vars;
1549
  self::$field_types[ $type ]['file'] = $file;
1550
 
1551
+ pods_transient_set( 'pods_field_type_' . $type, self::$field_types[ $type ], WEEK_IN_SECONDS );
1552
  } else {
1553
  self::$field_types[ $type ] = $field_type;
1554
  }
1557
  }
1558
 
1559
  /**
1560
+ * Get a list of all available Pod types.
1561
  *
1562
+ * @return string[] List of Pod types.
1563
  *
1564
+ * @since 2.8.0
1565
  */
1566
+ public static function pod_types_list() {
1567
+ $pod_types = [
1568
+ 'post_type',
1569
+ 'taxonomy',
1570
+ 'user',
1571
+ 'media',
1572
+ 'comment',
1573
+ 'settings',
1574
+ 'pod',
1575
+ 'table',
1576
+ ];
1577
 
1578
+ /**
1579
+ * Allow filtering of the supported Pod types.
1580
+ *
1581
+ * @since 2.8.0
1582
+ *
1583
+ * @param array $pod_types List of Pod types supported.
1584
+ */
1585
+ return apply_filters( 'pods_api_pod_types', $pod_types );
1586
+ }
1587
+
1588
+ /**
1589
+ * Get a list of all available Field types.
1590
+ *
1591
+ * @return string[] List of Field types.
1592
+ *
1593
+ * @since 2.8.0
1594
+ */
1595
+ public static function field_types_list() {
1596
+ $field_types = [
1597
  'text',
1598
  'website',
1599
  // 'link',
1615
  'boolean',
1616
  'color',
1617
  'slug',
1618
+ 'heading',
1619
+ 'html',
1620
+ ];
1621
 
1622
  $field_types = array_merge( $field_types, array_keys( self::$field_types ) );
1623
 
1624
  $field_types = array_filter( array_unique( $field_types ) );
1625
 
1626
+ return apply_filters( 'pods_api_field_types', $field_types );
1627
+ }
1628
+
1629
+ /**
1630
+ * Get a list of all available field types and include
1631
+ *
1632
+ * @return array Registered Field Types data
1633
+ *
1634
+ * @since 2.3.0
1635
+ */
1636
+ public static function field_types() {
1637
+
1638
+ $types = self::field_types_list();
1639
 
1640
  $field_types = pods_transient_get( 'pods_field_types' );
1641
 
1663
 
1664
  self::$field_types = $field_types;
1665
 
1666
+ pods_transient_set( 'pods_field_types', self::$field_types, WEEK_IN_SECONDS );
1667
  } else {
1668
  self::$field_types = array_merge( $field_types, self::$field_types );
1669
  }//end if
1672
  }
1673
 
1674
  /**
1675
+ * Get the list of available tableless field types.
 
 
1676
  *
1677
  * @since 2.3.0
1678
+ *
1679
+ * @return array The list of available tableless field types.
1680
  */
1681
  public static function tableless_field_types() {
 
1682
  static $field_types = null;
1683
 
1684
  if ( null === $field_types ) {
1685
+ $field_types = [
1686
  'pick',
1687
  'file',
1688
  'avatar',
1689
  'taxonomy',
1690
  'comment',
1691
+ 'author',
1692
+ ];
1693
 
1694
  $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1695
  }
1698
  }
1699
 
1700
  /**
1701
+ * Get the list of available file field types.
 
 
1702
  *
1703
  * @since 2.3.0
1704
+ *
1705
+ * @return array The list of available file field types.
1706
  */
1707
  public static function file_field_types() {
 
1708
  static $field_types = null;
1709
 
1710
  if ( null === $field_types ) {
1711
+ $field_types = [
1712
+ 'file',
1713
+ 'avatar',
1714
+ ];
1715
 
1716
  $field_types = apply_filters( 'pods_file_field_types', $field_types );
1717
  }
1720
  }
1721
 
1722
  /**
1723
+ * Get the list of available repeatable field types.
 
 
1724
  *
1725
  * @since 2.3.0
1726
+ *
1727
+ * @return array The list of available repeatable field types.
1728
  */
1729
  public static function repeatable_field_types() {
 
1730
  static $field_types = null;
1731
 
1732
  if ( null === $field_types ) {
1733
+ $field_types = [
1734
  'code',
1735
  'color',
1736
  'currency',
1744
  'time',
1745
  'website',
1746
  'wysiwyg',
1747
+ ];
1748
 
1749
  $field_types = apply_filters( 'pods_repeatable_field_types', $field_types );
1750
  }
1753
  }
1754
 
1755
  /**
1756
+ * Get the list of available number field types.
 
 
1757
  *
1758
  * @since 2.3.0
1759
+ *
1760
+ * @return array The list of available number field types.
1761
  */
1762
  public static function number_field_types() {
 
1763
  static $field_types = null;
1764
 
1765
  if ( null === $field_types ) {
1766
+ $field_types = [
1767
+ 'currency',
1768
+ 'number',
1769
+ ];
1770
 
1771
  $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1772
  }
1775
  }
1776
 
1777
  /**
1778
+ * Get the list of available date field types.
 
 
1779
  *
1780
  * @since 2.3.0
1781
+ *
1782
+ * @return array The list of available date field types.
1783
  */
1784
  public static function date_field_types() {
 
1785
  static $field_types = null;
1786
 
1787
  if ( null === $field_types ) {
1788
+ $field_types = [
1789
+ 'date',
1790
+ 'datetime',
1791
+ 'time',
1792
+ ];
1793
 
1794
  $field_types = apply_filters( 'pods_tableless_field_types', $field_types );
1795
  }
1798
  }
1799
 
1800
  /**
1801
+ * Get the list of available text field types.
 
 
1802
  *
1803
  * @since 2.3.0
1804
+ *
1805
+ * @return array The list of available text field types.
1806
  */
1807
  public static function text_field_types() {
 
1808
  static $field_types = null;
1809
 
1810
  if ( null === $field_types ) {
1811
+ $field_types = [
1812
+ 'code',
1813
+ 'paragraph',
1814
+ 'slug',
1815
+ 'password',
1816
+ 'text',
1817
+ 'wysiwyg',
1818
+ ];
1819
 
1820
  $field_types = apply_filters( 'pods_text_field_types', $field_types );
1821
  }
1824
  }
1825
 
1826
  /**
1827
+ * Get the list of available Layout field types.
1828
  *
1829
+ * @since 2.8.0
1830
  *
1831
+ * @return array The list of available Layout field types.
1832
  */
1833
+ public static function layout_field_types() {
 
1834
  static $field_types = null;
1835
 
1836
  if ( null === $field_types ) {
1837
+ $field_types = [
1838
+ 'heading',
1839
+ 'html',
1840
+ ];
1841
 
1842
  /**
1843
+ * Allow filtering of the list of Layout field types.
1844
  *
1845
+ * @since 2.8.0
1846
  *
1847
+ * @param array $field_types The list of Layout field types.
1848
  */
1849
+ $field_types = apply_filters( 'pods_layout_field_types', $field_types );
 
1850
  }
1851
 
1852
  return $field_types;
1853
  }
1854
 
1855
  /**
1856
+ * Get the list of available Non-Input field types.
1857
  *
1858
+ * @since 2.8.0
1859
+ *
1860
+ * @return array The list of available Non-Input field types.
1861
+ */
1862
+ public static function non_input_field_types() {
1863
+ static $field_types = null;
1864
+
1865
+ if ( null === $field_types ) {
1866
+ $field_types = [
1867
+ 'internal',
1868
+ ];
1869
+
1870
+ /**
1871
+ * Allow filtering of the list of Non-Input field types.
1872
+ *
1873
+ * @since 2.8.0
1874
+ *
1875
+ * @param array $field_types The list of Non-Input field types.
1876
+ */
1877
+ $field_types = apply_filters( 'pods_non_input_field_types', $field_types );
1878
+ }
1879
+
1880
+ return $field_types;
1881
+ }
1882
+
1883
+ /**
1884
+ * Get the list of simple tableless objects.
1885
  *
1886
  * @since 2.3.0
1887
+ *
1888
+ * @return array The list of simple tableless objects.
1889
  */
1890
  public static function simple_tableless_objects() {
1891
 
classes/PodsI18n.php CHANGED
@@ -24,7 +24,7 @@ final class PodsI18n {
24
  /**
25
  * @var mixed Current language data
26
  */
27
- private static $current_language_data = null;
28
 
29
  /**
30
  * Singleton handling for a basic pods_i18n() request
@@ -37,9 +37,6 @@ final class PodsI18n {
37
 
38
  // Hook all enqueue scripts actions
39
  add_action( 'pods_before_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
40
-
41
- // Polylang
42
- add_filter( 'pll_get_post_types', array( $this, 'pll_get_post_types' ), 10, 2 );
43
  }
44
 
45
  /**
@@ -236,25 +233,43 @@ final class PodsI18n {
236
  return self::$current_language;
237
  }
238
 
239
- $this->get_current_language_data( $args );
 
 
 
 
 
 
 
 
 
240
 
241
  return self::$current_language;
242
  }
243
 
244
  /**
245
- * Get current language information from Multilingual plugins
246
  *
247
  * @since 2.6.6
248
  * @since 2.7 Moved to this class from PodsAPI
 
249
  *
250
  * @param array $args (optional) {
251
- *
252
- * @type bool $refresh Rerun logic?
253
  * }
254
  *
255
- * @return array
 
 
 
 
 
 
 
 
 
256
  */
257
- public function get_current_language_data( $args = array() ) {
258
 
259
  $defaults = array(
260
  'refresh' => false,
@@ -262,58 +277,29 @@ final class PodsI18n {
262
 
263
  $args = wp_parse_args( $args, $defaults );
264
 
265
- if ( ! $args['refresh'] && ! empty( self::$current_language_data ) ) {
266
- return self::$current_language_data;
267
  }
268
 
269
- /**
270
- * @var \SitePress $sitepress object
271
- * @var \Polylang $polylang object
272
- */
273
- /*
274
- * @todo wpml-comp Remove global object usage
275
- */
276
- global $sitepress, $polylang;
277
-
278
- $lang_data = false;
279
- $translator = false;
280
- $current_language = false;
281
 
282
- // Multilingual support.
283
- if ( did_action( 'wpml_loaded' ) && apply_filters( 'wpml_setting', true, 'auto_adjust_ids' ) ) {
284
- // WPML support.
285
- $translator = 'WPML';
286
-
287
- // Get the global current language (if set).
288
- $wpml_language = apply_filters( 'wpml_current_language', null );
289
- $current_language = ( 'all' !== $wpml_language ) ? $wpml_language : '';
290
-
291
- } elseif ( ( function_exists( 'PLL' ) || is_object( $polylang ) ) && function_exists( 'pll_current_language' ) ) {
292
- // Polylang support.
293
- $translator = 'PLL';
294
-
295
- // Get the global current language (if set).
296
- $current_language = pll_current_language( 'slug' );
297
- }
298
 
299
  /**
300
- * Admin functions that overwrite the current language.
301
  *
302
  * @since 2.6.6
 
303
  */
304
- if ( is_admin() && ! empty( $translator ) ) {
305
- if ( 'PLL' === $translator ) {
306
- /**
307
- * Polylang support.
308
- * Get the current user's preferred language.
309
- * This is a user meta setting that will overwrite the language returned from pll_current_language().
310
- *
311
- * @see \PLL_Admin_Base::init_user() (polylang/admin/admin-base.php)
312
- */
313
- $current_language = get_user_meta( get_current_user_id(), 'pll_filter_content', true );
314
- }
315
-
316
- $pods_ajax = pods_v( 'pods_ajax', 'request', false );
317
 
318
  // Get current language based on the object language if available.
319
  $page = basename( pods_v( 'SCRIPT_NAME', $_SERVER, '' ) );
@@ -323,197 +309,93 @@ final class PodsI18n {
323
  $page = explode( '?', $page );
324
  $page = reset( $page );
325
 
326
- /**
327
- * Overwrite the current language if needed for post types.
328
- */
329
- if ( 'post.php' === $page || 'edit.php' === $page ) {
330
 
331
- $current_post = (int) pods_v( 'post', 'request', 0 );
332
- if ( $pods_ajax ) {
333
- $current_post = (int) pods_v( 'id', 'request', $current_post );
334
- }
335
 
336
- if ( $current_post ) {
 
 
337
 
338
- $current_post_type = get_post_type( $current_post );
 
 
 
339
 
340
- /**
341
- * WPML support.
342
- * In WPML the current language is always set to default on an edit screen.
343
- * We need to overwrite this when the current object is not-translatable to enable relationships with different languages.
344
- */
345
- if ( 'WPML' === $translator && ! apply_filters( 'wpml_is_translated_post_type', false, $current_post_type ) ) {
346
- // Overwrite the current language to nothing if this is a NOT-translatable post_type.
347
- $current_language = '';
348
  }
349
 
350
- /**
351
- * Polylang support.
352
- * In polylang the preferred language could be anything.
353
- */
354
- if ( 'PLL' === $translator && pll_is_translated_post_type( $current_post_type ) ) {
355
-
356
- /**
357
- * Polylang (1.5.4+).
358
- * We only want the related objects if they are not translatable OR the same language as the current object.
359
- */
360
- if ( function_exists( 'pll_get_post_language' ) ) {
361
- // Overwrite the current language if this is a translatable post_type.
362
- $current_language = pll_get_post_language( $current_post );
363
- }
364
-
365
- /**
366
- * Polylang (1.0.1+).
367
- * 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.
368
- */
369
- $current_language = pods_v( 'new_lang', 'request', $current_language );
370
  }
371
- }
372
- } //end if
373
-
374
- /**
375
- * Overwrite the current language if needed for taxonomies.
376
- */
377
- elseif ( 'term.php' === $page || 'edit-tags.php' === $page ) {
378
-
379
- $current_term_id = pods_v( 'tag_ID', 'request', 0 );
380
- if ( $pods_ajax ) {
381
- $current_term_id = (int) pods_v( 'id', 'request', $current_term_id );
382
- }
383
-
384
- $current_taxonomy = pods_v( 'taxonomy', 'request', '' );
385
- if ( ! $current_taxonomy && $current_term_id ) {
386
- $current_taxonomy = pods_v( 'taxonomy', get_term( $current_term_id ), null );
387
- }
388
-
389
- // @todo MAYBE: Similar function like get_post_type for taxonomies so we don't need to check for $_GET['taxonomy']
390
- if ( $current_taxonomy ) {
391
-
392
- /*
393
- * @todo wpml-comp API call for taxonomy needed!
394
- * Suggested API call:
395
- * add_filter( 'wpml_is_translated_taxonomy', $_GET['taxonomy'], 10, 2 );
396
- */
397
- /**
398
- * WPML support.
399
- * In WPML the current language is always set to default on an edit screen.
400
- * We need to overwrite this when the current object is not-translatable to enable relationships with different languages.
401
- */
402
- if ( 'WPML' === $translator && method_exists( $sitepress, 'is_translated_taxonomy' ) && ! $sitepress->is_translated_taxonomy( $current_taxonomy ) ) {
403
- // Overwrite the current language to nothing if this is a NOT-translatable taxonomy.
404
- $current_language = '';
405
  }
406
 
407
- /**
408
- * Polylang support.
409
- * In polylang the preferred language could be anything.
410
- */
411
- if ( 'PLL' === $translator && pll_is_translated_taxonomy( $current_taxonomy ) ) {
412
-
413
- /**
414
- * Polylang (1.5.4+).
415
- * We only want the related objects if they are not translatable OR the same language as the current object.
416
- */
417
- if ( $current_term_id && function_exists( 'pll_get_term_language' ) ) {
418
- // Overwrite the current language if this is a translatable taxonomy
419
- $current_language = pll_get_term_language( $current_term_id );
420
- }
421
-
422
- /**
423
- * Polylang (1.0.1+).
424
- * 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.
425
- */
426
- $current_language = pods_v( 'new_lang', 'request', $current_language );
427
  }
428
- }//end if
429
- }//end if
430
 
431
- }//end if (admin)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
 
433
- $current_language = pods_sanitize( sanitize_text_field( $current_language ) );
434
-
435
- if ( ! empty( $current_language ) ) {
436
- // We need to return language data
437
- $lang_data = array(
438
- 'language' => $current_language,
439
- 't_id' => 0,
440
- 'tt_id' => 0,
441
- 'term' => null,
442
- );
443
-
444
- /**
445
- * Polylang support.
446
- * Get the language taxonomy object for the current language.
447
- */
448
- if ( 'PLL' === $translator ) {
449
- $current_language_t = false;
450
-
451
- // Get the language term object.
452
- if ( function_exists( 'PLL' ) && isset( PLL()->model ) && method_exists( PLL()->model, 'get_language' ) ) {
453
- // Polylang 1.8 and newer.
454
- $current_language_t = PLL()->model->get_language( $current_language );
455
- } elseif ( is_object( $polylang ) && isset( $polylang->model ) && method_exists( $polylang->model, 'get_language' ) ) {
456
- // Polylang 1.2 - 1.7.x
457
- $current_language_t = $polylang->model->get_language( $current_language );
458
- } elseif ( is_object( $polylang ) && method_exists( $polylang, 'get_language' ) ) {
459
- // Polylang 1.1.x and older.
460
- $current_language_t = $polylang->get_language( $current_language );
461
- }
462
-
463
- // If the language object exists, add it!
464
- if ( $current_language_t && ! empty( $current_language_t->term_id ) ) {
465
- $lang_data['t_id'] = (int) $current_language_t->term_id;
466
- $lang_data['tt_id'] = (int) $current_language_t->term_taxonomy_id;
467
- $lang_data['tl_t_id'] = (int) $current_language_t->tl_term_id;
468
- $lang_data['tl_tt_id'] = (int) $current_language_t->tl_term_taxonomy_id;
469
- $lang_data['term'] = $current_language_t;
470
- }
471
- }//end if
472
- }//end if
473
 
474
  /**
475
- * Override language data used by Pods.
476
  *
477
- * @since 2.6.6
478
  *
479
- * @param array|false $lang_data {
480
- * Language data
481
- * @type string $language Language slug
482
- * @type int $t_id Language term_id
483
- * @type int $tt_id Language term_taxonomy_id
484
- * @type WP_Term $term Language term object
 
 
 
485
  * }
486
- *
487
- * @param string|boolean $translator Language plugin used.
488
  */
489
- $lang_data = apply_filters( 'pods_get_current_language', $lang_data, $translator );
490
-
491
- if ( $lang_data ) {
492
- self::$current_language = $lang_data['language'];
493
- self::$current_language_data = $lang_data;
494
- }
495
 
496
- return $lang_data;
497
-
498
- }
499
-
500
- /**
501
- * Add Pods templates to possible i18n enabled post-types (polylang settings).
502
- *
503
- * @since 2.7.0
504
- *
505
- * @param array $post_types
506
- * @param bool $is_settings
507
- *
508
- * @return array mixed
509
- */
510
- public function pll_get_post_types( $post_types, $is_settings = false ) {
511
-
512
- if ( $is_settings ) {
513
- $post_types['_pods_template'] = '_pods_template';
514
- }
515
 
516
- return $post_types;
517
  }
518
 
519
  }
24
  /**
25
  * @var mixed Current language data
26
  */
27
+ private static $current_language_context = null;
28
 
29
  /**
30
  * Singleton handling for a basic pods_i18n() request
37
 
38
  // Hook all enqueue scripts actions
39
  add_action( 'pods_before_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
 
 
 
40
  }
41
 
42
  /**
233
  return self::$current_language;
234
  }
235
 
236
+ /**
237
+ * Override language data used by Pods.
238
+ *
239
+ * @since 2.8.0
240
+ *
241
+ * @param string $language Language slug
242
+ * @param array $context Language context
243
+ * @param array $args Arguments
244
+ */
245
+ self::$current_language = apply_filters( 'pods_get_current_language', self::$current_language, self::get_current_language_context( $args ), $args );
246
 
247
  return self::$current_language;
248
  }
249
 
250
  /**
251
+ * Get current language context information.
252
  *
253
  * @since 2.6.6
254
  * @since 2.7 Moved to this class from PodsAPI
255
+ * @since 2.8.0 Refactored from get_current_language_data()
256
  *
257
  * @param array $args (optional) {
258
+ * @type bool $refresh Rerun logic?
 
259
  * }
260
  *
261
+ * @return array $context {
262
+ * Language data.
263
+ * @type bool $is_admin Is admin.
264
+ * @type bool $is_ajax Is AJAX call.
265
+ * @type bool $is_pods_ajax Is Pods AJAX call.
266
+ * @type string $current_page Current admin page.
267
+ * @type string $current_object_type Current object type (post / term / comment / user).
268
+ * @type int $current_item_id Current item id.
269
+ * @type string $current_item_type Current item type.
270
+ * }
271
  */
272
+ public function get_current_language_context( $args = array() ) {
273
 
274
  $defaults = array(
275
  'refresh' => false,
277
 
278
  $args = wp_parse_args( $args, $defaults );
279
 
280
+ if ( ! $args['refresh'] && ! empty( self::$current_language_context ) ) {
281
+ return self::$current_language_context;
282
  }
283
 
284
+ $pods_ajax = pods_v( 'pods_ajax', 'request', false );
 
 
 
 
 
 
 
 
 
 
 
285
 
286
+ $context = [
287
+ 'is_admin' => is_admin(),
288
+ 'is_ajax' => defined( 'DOING_AJAX' ) && DOING_AJAX,
289
+ 'is_pods_ajax' => $pods_ajax,
290
+ 'current_page' => '',
291
+ 'current_object_type' => '',
292
+ 'current_item_id' => '',
293
+ 'current_item_type' => '',
294
+ ];
 
 
 
 
 
 
 
295
 
296
  /**
297
+ * Admin functions that overwrite the current language context.
298
  *
299
  * @since 2.6.6
300
+ * @since 2.8.0 Refactored for current context instead of language data.
301
  */
302
+ if ( is_admin() ) {
 
 
 
 
 
 
 
 
 
 
 
 
303
 
304
  // Get current language based on the object language if available.
305
  $page = basename( pods_v( 'SCRIPT_NAME', $_SERVER, '' ) );
309
  $page = explode( '?', $page );
310
  $page = reset( $page );
311
 
312
+ $context['current_page'] = $page;
 
 
 
313
 
314
+ switch ( $page ) {
 
 
 
315
 
316
+ case 'post.php':
317
+ case 'edit.php':
318
+ $context['current_object_type'] = 'post';
319
 
320
+ $current_post_id = (int) pods_v( 'post', 'request', 0 );
321
+ if ( $pods_ajax ) {
322
+ $current_post_id = (int) pods_v( 'id', 'request', $current_post_id );
323
+ }
324
 
325
+ $current_post_type = pods_v( 'post_type', 'request', '' );
326
+ if ( ! $current_post_type && $current_post_id ) {
327
+ $current_post_type = get_post_type( $current_post_id );
 
 
 
 
 
328
  }
329
 
330
+ $context['current_item_id'] = $current_post_id;
331
+ $context['current_item_type'] = $current_post_type;
332
+ break;
333
+
334
+ case 'term.php':
335
+ case 'edit-tags.php':
336
+ $context['current_object_type'] = 'term';
337
+
338
+ $current_term_id = (int) pods_v( 'tag_ID', 'request', 0 );
339
+ if ( $pods_ajax ) {
340
+ $current_term_id = (int) pods_v( 'id', 'request', $current_term_id );
 
 
 
 
 
 
 
 
 
341
  }
342
+
343
+ $current_taxonomy = pods_v( 'taxonomy', 'request', '' );
344
+ if ( ! $current_taxonomy && $current_term_id ) {
345
+ $current_taxonomy = pods_v( 'taxonomy', get_term( $current_term_id ), null );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
  }
347
 
348
+ $context['current_item_id'] = $current_term_id;
349
+ $context['current_item_type'] = $current_taxonomy;
350
+ break;
351
+
352
+ case 'comment.php':
353
+ $context['current_object_type'] = 'comment';
354
+ $context['current_item_type'] = 'comment';
355
+
356
+ $current_comment_id = (int) pods_v( 'c', 'request', 0 );
357
+ if ( $pods_ajax ) {
358
+ $current_comment_id = (int) pods_v( 'id', 'request', $current_comment_id );
 
 
 
 
 
 
 
 
 
359
  }
 
 
360
 
361
+ $context['current_item_id'] = $current_comment_id;
362
+ break;
363
+
364
+ case 'user-edit.php':
365
+ $context['current_object_type'] = 'user';
366
+ $context['current_item_type'] = 'user';
367
+
368
+ $current_user_id = (int) pods_v( 'user_id', 'request', 0 );
369
+ if ( $pods_ajax ) {
370
+ $current_user_id = (int) pods_v( 'id', 'request', $current_user_id );
371
+ }
372
+
373
+ $context['current_item_id'] = $current_user_id;
374
+ break;
375
+ }
376
 
377
+ }//end if (admin)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
 
379
  /**
380
+ * Override language context used by Pods.
381
  *
382
+ * @since 2.8.0
383
  *
384
+ * @param array $context {
385
+ * Language data.
386
+ * @type bool $is_admin Is admin.
387
+ * @type bool $is_ajax Is AJAX call.
388
+ * @type bool $is_pods_ajax Is Pods AJAX call.
389
+ * @type string $current_page Current admin page.
390
+ * @type string $current_object_type Current object type (post / term / comment / user).
391
+ * @type int $current_item_id Current item id.
392
+ * @type string $current_item_type Current item type.
393
  * }
 
 
394
  */
395
+ self::$current_language_context = apply_filters( 'pods_get_current_language_context', $context );
 
 
 
 
 
396
 
397
+ return self::$current_language_context;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
 
 
399
  }
400
 
401
  }
classes/PodsInit.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  /**
4
  * @package Pods
5
  */
@@ -68,9 +70,9 @@ class PodsInit {
68
  /**
69
  * Whether an Upgrade for 1.x has happened
70
  *
71
- * @var bool
72
  */
73
- public static $upgraded;
74
 
75
  /**
76
  * Whether an Upgrade is needed
@@ -80,13 +82,13 @@ class PodsInit {
80
  public static $upgrade_needed = false;
81
 
82
  /**
83
- * Freemius object.
84
  *
85
- * @since 1.0.0
86
  *
87
- * @var \Freemius
88
  */
89
- protected $freemius;
90
 
91
  /**
92
  * Singleton handling for a basic pods_init() request
@@ -117,7 +119,17 @@ class PodsInit {
117
  self::$version = get_option( 'pods_framework_version' );
118
  self::$version_last = get_option( 'pods_framework_version_last' );
119
  self::$db_version = get_option( 'pods_framework_db_version' );
120
- self::$upgraded = (int) get_option( 'pods_framework_upgraded_1_x' );
 
 
 
 
 
 
 
 
 
 
121
 
122
  if ( empty( self::$version_last ) && 0 < strlen( get_option( 'pods_version' ) ) ) {
123
  $old_version = get_option( 'pods_version' );
@@ -127,7 +139,8 @@ class PodsInit {
127
  $old_version = pods_version_to_point( $old_version );
128
  }
129
 
130
- update_option( 'pods_framework_version_last', $old_version );
 
131
 
132
  self::$version_last = $old_version;
133
  }
@@ -135,21 +148,245 @@ class PodsInit {
135
 
136
  self::$upgrade_needed = $this->needs_upgrade();
137
 
138
- add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
139
- add_action( 'plugins_loaded', array( $this, 'activate_install' ), 9 );
140
- add_action( 'after_setup_theme', array( $this, 'after_setup_theme' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
- add_action( 'wp_loaded', array( $this, 'flush_rewrite_rules' ) );
 
 
 
 
143
 
144
- $this->run();
 
 
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  }
147
 
148
  /**
149
  * Load the plugin textdomain and set default constants
150
  */
151
  public function plugins_loaded() {
152
-
153
  if ( ! defined( 'PODS_LIGHT' ) ) {
154
  define( 'PODS_LIGHT', false );
155
  }
@@ -158,85 +395,168 @@ class PodsInit {
158
  define( 'PODS_TABLELESS', false );
159
  }
160
 
161
- load_plugin_textdomain( 'pods' );
162
-
163
- $this->freemius();
164
 
 
 
 
165
  }
166
 
167
  /**
168
- * Handle Freemius SDK registration.
 
 
169
  *
170
- * @since 1.0.0
 
171
  *
172
- * @return \Freemius
173
  */
174
- public function freemius() {
175
  // Admin only.
176
- if ( ! is_admin() ) {
 
 
 
177
  return;
178
  }
179
 
180
  global $pagenow;
181
 
 
 
182
  // Pods admin pages or plugins/update page only.
183
  if (
184
  'plugins.php' !== $pagenow
185
  && 'update-core.php' !== $pagenow
186
  && 'update.php' !== $pagenow
187
  && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
188
- && ( ! isset( $_GET['page'] ) || 0 !== strpos( $_GET['page'], 'pods' ) )
 
189
  ) {
190
  return;
191
  }
192
 
193
- if ( $this->freemius ) {
194
- return $this->freemius;
195
- }
196
-
197
- require_once dirname( __DIR__ ) . '/vendor/freemius/wordpress-sdk/start.php';
198
-
199
- try {
200
- $this->freemius = fs_dynamic_init( array(
201
- 'id' => '5347',
202
- 'slug' => 'pods',
203
- 'type' => 'plugin',
204
- 'public_key' => 'pk_737105490825babae220297e18920',
205
- 'is_premium' => false,
206
- 'has_addons' => false,
207
- 'has_paid_plans' => false,
208
- 'menu' => array(
209
- 'slug' => 'pods-settings',
210
- 'contact' => false,
211
- 'support' => false,
212
- 'affiliation' => false,
213
- 'account' => true,
214
- 'pricing' => false,
215
- 'addons' => false,
216
- 'parent' => array(
217
- 'slug' => 'pods',
218
- ),
219
- ),
220
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
 
222
- $this->override_freemius_strings();
223
 
224
- add_filter( 'fs_plugins_api', array( $this, 'filter_freemius_plugins_api_data' ), 15 );
 
 
225
 
226
- $this->freemius->add_filter( 'templates/add-ons.php', array( $this, 'filter_freemius_addons_html' ) );
227
- $this->freemius->add_filter( 'download_latest_url', array( $this, 'get_freemius_action_link' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
 
 
 
 
 
 
 
 
229
  /**
230
- * Allow hooking into the Freemius registration after Pods has registered it's own Freemius.
231
  *
232
- * @since 2.7.27
 
 
 
233
  */
234
- do_action( 'pods_freemius_after_init' );
235
- } catch ( \Exception $exception ) {
236
- return null;
237
  }
238
 
239
- return $this->freemius;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  }
241
 
242
  /**
@@ -353,13 +673,41 @@ class PodsInit {
353
  );
354
  }
355
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
  /**
357
  * Add compatibility for other plugins.
358
  *
359
  * @since 2.7.17
360
  */
361
  public function after_setup_theme() {
362
-
363
  if ( ! defined( 'PODS_COMPATIBILITY' ) ) {
364
  define( 'PODS_COMPATIBILITY', true );
365
  }
@@ -369,7 +717,6 @@ class PodsInit {
369
  }
370
 
371
  require_once PODS_DIR . 'includes/compatibility/acf.php';
372
-
373
  }
374
 
375
  /**
@@ -391,8 +738,9 @@ class PodsInit {
391
  * Load Pods Meta
392
  */
393
  public function load_meta() {
 
394
 
395
- self::$meta = pods_meta()->core();
396
  }
397
 
398
  /**
@@ -419,21 +767,14 @@ class PodsInit {
419
  add_shortcode( 'pods-form', 'pods_shortcode_form' );
420
 
421
  $security_settings = array(
422
- 'pods_disable_file_browser' => 0,
423
- 'pods_files_require_login' => 1,
424
  'pods_files_require_login_cap' => '',
425
- 'pods_disable_file_upload' => 0,
426
- 'pods_upload_require_login' => 1,
427
  'pods_upload_require_login_cap' => '',
428
  );
429
 
430
- foreach ( $security_settings as $security_setting => $setting ) {
431
- $setting = get_option( $security_setting );
432
- if ( ! empty( $setting ) ) {
433
- $security_settings[ $security_setting ] = $setting;
434
- }
435
- }
436
-
437
  foreach ( $security_settings as $security_setting => $setting ) {
438
  if ( 0 === (int) $setting ) {
439
  $setting = false;
@@ -481,6 +822,13 @@ class PodsInit {
481
  * Register Scripts and Styles
482
  */
483
  public function register_assets() {
 
 
 
 
 
 
 
484
 
485
  $suffix_min = SCRIPT_DEBUG ? '' : '.min';
486
 
@@ -596,7 +944,7 @@ class PodsInit {
596
 
597
  // Marionette dependencies for DFV/MV fields.
598
  wp_register_script(
599
- 'backbone.radio',
600
  PODS_URL . "ui/js/marionette/backbone.radio{$suffix_min}.js",
601
  array( 'backbone' ),
602
  '2.0.0',
@@ -607,7 +955,7 @@ class PodsInit {
607
  PODS_URL . "ui/js/marionette/backbone.marionette{$suffix_min}.js",
608
  array(
609
  'backbone',
610
- 'backbone.radio',
611
  ),
612
  '3.3.1',
613
  true
@@ -617,22 +965,56 @@ class PodsInit {
617
  'PodsMn = Backbone.Marionette.noConflict();'
618
  );
619
 
620
- // DFV/MV.
 
 
 
 
621
  wp_register_script(
622
- 'pods-dfv', PODS_URL . 'ui/js/pods-dfv/pods-dfv.min.js',
623
- array(
624
- 'jquery',
625
- 'jquery-ui-core',
626
- 'jquery-ui-sortable',
627
- 'pods-i18n',
628
- 'pods-marionette',
629
- 'media-views',
630
- 'media-models',
 
 
 
 
 
 
631
  ),
632
- PODS_VERSION,
633
  true
634
  );
635
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
636
  // Page builders.
637
  if (
638
  // @todo Finish Elementor & Divi support.
@@ -643,29 +1025,35 @@ class PodsInit {
643
  add_filter( 'pods_enqueue_dfv_on_front', '__return_true' );
644
  }
645
 
646
- // Check if Pod is a Modal Window.
647
- if ( pods_is_modal_window() ) {
648
- add_filter( 'body_class', array( $this, 'add_classes_to_modal_body' ) );
649
- add_filter( 'admin_body_class', array( $this, 'add_classes_to_modal_body' ) );
650
- }
651
 
652
  // Deal with specifics on admin pages.
653
- if ( is_admin() && function_exists( 'get_current_screen' ) ) {
654
  $screen = get_current_screen();
655
 
656
  // DFV must be enqueued on the media library page for items in grid mode (#4785)
657
  // and for posts due to the possibility that post-thumbnails are enabled (#4945)
658
- if ( $screen && $screen->base && in_array( $screen->base, array( 'upload', 'post' ), true ) ) {
659
- wp_enqueue_script( 'pods-dfv' );
 
 
 
 
 
 
 
 
 
 
660
  }
661
  }
662
 
663
  $this->maybe_register_handlebars();
664
 
665
  // As of 2.7 we combine styles to just three .css files
666
- wp_register_style( 'pods-styles', PODS_URL . 'ui/styles/dist/pods.css', array(), PODS_VERSION );
667
- wp_register_style( 'pods-wizard', PODS_URL . 'ui/styles/dist/pods-wizard.css', array(), PODS_VERSION );
668
- wp_register_style( 'pods-form', PODS_URL . 'ui/styles/dist/pods-form.css', array(), PODS_VERSION );
669
 
670
  /**
671
  * Filter to enabled loading of the DFV script on frontend.
@@ -677,11 +1065,19 @@ class PodsInit {
677
  *
678
  * @since 2.7.13
679
  */
680
- if ( apply_filters( 'pods_enqueue_dfv_on_front', false ) ) {
681
  wp_enqueue_script( 'pods-dfv' );
682
  wp_enqueue_style( 'pods-form' );
683
  }
684
 
 
 
 
 
 
 
 
 
685
  /**
686
  * Fires after Pods assets are registered.
687
  *
@@ -735,10 +1131,9 @@ class PodsInit {
735
  * Register internal Post Types
736
  */
737
  public function register_pods() {
738
-
739
  $args = array(
740
- 'label' => 'Pods',
741
- 'labels' => array( 'singular_name' => 'Pod' ),
742
  'public' => false,
743
  'can_export' => false,
744
  'query_var' => false,
@@ -755,8 +1150,26 @@ class PodsInit {
755
  register_post_type( '_pods_pod', apply_filters( 'pods_internal_register_post_type_pod', $args ) );
756
 
757
  $args = array(
758
- 'label' => 'Pod Fields',
759
- 'labels' => array( 'singular_name' => 'Pod Field' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
760
  'public' => false,
761
  'can_export' => false,
762
  'query_var' => false,
@@ -792,9 +1205,6 @@ class PodsInit {
792
  return;
793
  }
794
 
795
- require_once PODS_DIR . 'classes/PodsRESTHandlers.php';
796
- require_once PODS_DIR . 'classes/PodsRESTFields.php';
797
-
798
  $post_types = PodsMeta::$post_types;
799
  $taxonomies = PodsMeta::$taxonomies;
800
 
@@ -853,9 +1263,6 @@ class PodsInit {
853
  continue;
854
  }
855
 
856
- $post_type['options']['name'] = $post_type['name'];
857
- $post_type = array_merge( $post_type, (array) $post_type['options'] );
858
-
859
  $post_type_name = pods_v_sanitized( 'name', $post_type );
860
 
861
  // Labels
@@ -1016,6 +1423,7 @@ class PodsInit {
1016
  'rewrite' => $cpt_rewrite,
1017
  'query_var' => ( false !== (boolean) pods_v( 'query_var', $post_type, true ) ? pods_v( 'query_var_string', $post_type, $post_type_name, true ) : false ),
1018
  'can_export' => (boolean) pods_v( 'can_export', $post_type, true ),
 
1019
  );
1020
 
1021
  // REST API
@@ -1054,7 +1462,7 @@ class PodsInit {
1054
 
1055
  // Taxonomies
1056
  $cpt_taxonomies = array();
1057
- $_taxonomies = get_taxonomies();
1058
  $_taxonomies = array_merge_recursive( $_taxonomies, $pods_taxonomies );
1059
  $ignore = array( 'nav_menu', 'link_category', 'post_format' );
1060
 
@@ -1091,9 +1499,6 @@ class PodsInit {
1091
  continue;
1092
  }
1093
 
1094
- $taxonomy['options']['name'] = $taxonomy['name'];
1095
- $taxonomy = array_merge( $taxonomy, (array) $taxonomy['options'] );
1096
-
1097
  $taxonomy_name = pods_v( 'name', $taxonomy );
1098
 
1099
  // Labels
@@ -1223,7 +1628,7 @@ class PodsInit {
1223
 
1224
  // Post Types
1225
  $ct_post_types = array();
1226
- $_post_types = get_post_types();
1227
  $_post_types = array_merge_recursive( $_post_types, $pods_post_types );
1228
  $ignore = array( 'revision' );
1229
 
@@ -1277,7 +1682,7 @@ class PodsInit {
1277
 
1278
  $pods_cpt_ct['post_format_post_types'] = $post_format_post_types;
1279
 
1280
- pods_transient_set( 'pods_wp_cpt_ct', $pods_cpt_ct );
1281
  }//end if
1282
 
1283
  foreach ( $pods_cpt_ct['taxonomies'] as $taxonomy => $options ) {
@@ -1389,30 +1794,25 @@ class PodsInit {
1389
  // Handle existing post types / taxonomies settings (just REST for now)
1390
  global $wp_post_types, $wp_taxonomies;
1391
 
1392
- $post_type_names = wp_list_pluck( $post_types, 'name', 'id' );
1393
- $taxonomy_names = wp_list_pluck( $taxonomies, 'name', 'id' );
1394
-
1395
  foreach ( $existing_post_types as $post_type_name => $post_type_name_again ) {
1396
  if ( isset( self::$content_types_registered['post_types'] ) && in_array( $post_type_name, self::$content_types_registered['post_types'], true ) ) {
1397
  // Post type already registered / setup by Pods
1398
  continue;
1399
  }
1400
 
1401
- $pod_id = array_search( $post_type_name, $post_type_names, true );
1402
-
1403
- if ( ! $pod_id ) {
1404
  // Post type not a pod
1405
  continue;
1406
  }
1407
 
1408
- $pod = $post_types[ $pod_id ];
1409
 
1410
  // REST API
1411
- $rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1412
 
1413
  if ( $rest_enabled ) {
1414
  if ( empty( $wp_post_types[ $post_type_name ]->show_in_rest ) ) {
1415
- $rest_base = sanitize_title( pods_v( 'rest_base', $pod['options'], pods_v( 'rest_base', $wp_post_types[ $post_type_name ] ), true ) );
1416
 
1417
  $wp_post_types[ $post_type_name ]->show_in_rest = true;
1418
  $wp_post_types[ $post_type_name ]->rest_base = $rest_base;
@@ -1429,21 +1829,19 @@ class PodsInit {
1429
  continue;
1430
  }
1431
 
1432
- $pod_id = array_search( $taxonomy_name, $taxonomy_names, true );
1433
-
1434
- if ( ! $pod_id ) {
1435
  // Taxonomy not a pod
1436
  continue;
1437
  }
1438
 
1439
- $pod = $taxonomies[ $pod_id ];
1440
 
1441
  // REST API
1442
- $rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1443
 
1444
  if ( $rest_enabled ) {
1445
  if ( empty( $wp_taxonomies[ $taxonomy_name ]->show_in_rest ) ) {
1446
- $rest_base = sanitize_title( pods_v( 'rest_base', $pod['options'], pods_v( 'rest_base', $wp_taxonomies[ $taxonomy_name ] ), true ) );
1447
 
1448
  $wp_taxonomies[ $taxonomy_name ]->show_in_rest = true;
1449
  $wp_taxonomies[ $taxonomy_name ]->rest_base = $rest_base;
@@ -1457,7 +1855,7 @@ class PodsInit {
1457
  if ( ! empty( PodsMeta::$user ) ) {
1458
  $pod = current( PodsMeta::$user );
1459
 
1460
- $rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1461
 
1462
  if ( $rest_enabled ) {
1463
  new PodsRESTFields( $pod['name'] );
@@ -1467,13 +1865,25 @@ class PodsInit {
1467
  if ( ! empty( PodsMeta::$media ) ) {
1468
  $pod = current( PodsMeta::$media );
1469
 
1470
- $rest_enabled = (boolean) pods_v( 'rest_enable', $pod['options'], false );
1471
 
1472
  if ( $rest_enabled ) {
1473
  new PodsRESTFields( $pod['name'] );
1474
  }
1475
  }
1476
 
 
 
 
 
 
 
 
 
 
 
 
 
1477
  }
1478
 
1479
  /**
@@ -1497,7 +1907,7 @@ class PodsInit {
1497
  $wp_rewrite->flush_rules();
1498
  $wp_rewrite->init();
1499
 
1500
- pods_transient_set( 'pods_flush_rewrites', 0 );
1501
  }
1502
  }
1503
 
@@ -1760,7 +2170,7 @@ class PodsInit {
1760
  if ( '2.1.0' === $new_version && ( is_developer() ) )
1761
  continue;*/
1762
 
1763
- if ( version_compare( $last, $old_version, '>=' ) && version_compare( $last, $new_version, '<' ) && version_compare( $current, $new_version, '>=' ) && 1 !== self::$upgraded ) {
1764
  $upgrade_needed = true;
1765
 
1766
  break;
@@ -1885,12 +2295,7 @@ class PodsInit {
1885
 
1886
  $api = pods_api();
1887
 
1888
- $pods = $api->load_pods(
1889
- array(
1890
- 'names_ids' => true,
1891
- 'table_info' => false,
1892
- )
1893
- );
1894
 
1895
  foreach ( $pods as $pod_id => $pod_label ) {
1896
  $api->delete_pod( array( 'id' => $pod_id ) );
@@ -1970,6 +2375,20 @@ class PodsInit {
1970
 
1971
  $ran = true;
1972
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1973
  $this->load_i18n();
1974
 
1975
  if ( ! did_action( 'plugins_loaded' ) ) {
@@ -1984,25 +2403,32 @@ class PodsInit {
1984
  $this->load_meta();
1985
  }
1986
 
 
 
1987
  if ( ! did_action( 'init' ) ) {
1988
  add_action( 'init', array( $this, 'core' ), 11 );
1989
  add_action( 'init', array( $this, 'setup_content_types' ), 11 );
1990
 
1991
- if ( is_admin() ) {
1992
  add_action( 'init', array( $this, 'admin_init' ), 12 );
1993
  }
1994
  } else {
1995
  $this->core();
1996
  $this->setup_content_types();
1997
 
1998
- if ( is_admin() ) {
1999
  $this->admin_init();
2000
  }
2001
  }
2002
 
2003
- add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ), 15 );
2004
- add_action( 'admin_enqueue_scripts', array( $this, 'register_assets' ), 15 );
 
 
 
 
2005
  add_action( 'login_enqueue_scripts', array( $this, 'register_assets' ), 15 );
 
2006
  // @todo Elementor Page Builder.
2007
  //add_action( 'elementor/editor/before_enqueue_scripts', array( $this, 'register_assets' ), 15 );
2008
 
@@ -2021,12 +2447,32 @@ class PodsInit {
2021
  // Compatibility for Query Monitor conditionals
2022
  add_filter( 'query_monitor_conditionals', array( $this, 'filter_query_monitor_conditionals' ) );
2023
 
2024
- // Add WP-CLI commands
2025
- if ( defined( 'WP_CLI' ) && WP_CLI ) {
2026
- require_once PODS_DIR . 'classes/cli/Pods_CLI_Command.php';
2027
- require_once PODS_DIR . 'classes/cli/PodsAPI_CLI_Command.php';
 
 
 
 
 
 
 
 
 
2028
  }
 
2029
 
 
 
 
 
 
 
 
 
 
 
2030
  }
2031
 
2032
  /**
@@ -2044,7 +2490,7 @@ class PodsInit {
2044
 
2045
  $file_types = "'" . implode( "', '", PodsForm::file_field_types() ) . "'";
2046
 
2047
- if ( ! pods_tableless() ) {
2048
  $sql = "
2049
  DELETE `rel`
2050
  FROM `@wp_podsrel` AS `rel`
@@ -2060,14 +2506,16 @@ class PodsInit {
2060
  WHERE
2061
  `p`.`ID` IS NOT NULL
2062
  AND `pm`.`meta_id` IS NOT NULL
2063
- AND `rel`.`item_id` = {$_ID}";
 
2064
 
2065
  pods_query( $sql, false );
2066
  }
2067
 
2068
- // Post Meta
2069
- if ( ! empty( PodsMeta::$post_types ) ) {
2070
- $sql = "
 
2071
  DELETE `rel`
2072
  FROM `@wp_postmeta` AS `rel`
2073
  LEFT JOIN `{$wpdb->posts}` AS `p`
@@ -2084,12 +2532,12 @@ class PodsInit {
2084
  AND `rel`.`meta_key` = `p`.`post_name`
2085
  AND `rel`.`meta_value` = '{$_ID}'";
2086
 
2087
- pods_query( $sql, false );
2088
- }
2089
 
2090
- // User Meta
2091
- if ( ! empty( PodsMeta::$user ) ) {
2092
- $sql = "
2093
  DELETE `rel`
2094
  FROM `@wp_usermeta` AS `rel`
2095
  LEFT JOIN `{$wpdb->posts}` AS `p`
@@ -2106,12 +2554,12 @@ class PodsInit {
2106
  AND `rel`.`meta_key` = `p`.`post_name`
2107
  AND `rel`.`meta_value` = '{$_ID}'";
2108
 
2109
- pods_query( $sql, false );
2110
- }
2111
 
2112
- // Comment Meta
2113
- if ( ! empty( PodsMeta::$comment ) ) {
2114
- $sql = "
2115
  DELETE `rel`
2116
  FROM `@wp_commentmeta` AS `rel`
2117
  LEFT JOIN `{$wpdb->posts}` AS `p`
@@ -2128,8 +2576,18 @@ class PodsInit {
2128
  AND `rel`.`meta_key` = `p`.`post_name`
2129
  AND `rel`.`meta_value` = '{$_ID}'";
2130
 
2131
- pods_query( $sql, false );
 
2132
  }
 
 
 
 
 
 
 
 
 
2133
  }
2134
 
2135
  /**
@@ -2150,7 +2608,6 @@ class PodsInit {
2150
  continue;
2151
  }
2152
 
2153
- require_once PODS_DIR . 'classes/widgets/' . $widget . '.php';
2154
 
2155
  register_widget( $widget );
2156
  }
@@ -2167,17 +2624,11 @@ class PodsInit {
2167
  return;
2168
  }
2169
 
2170
- $all_pods = pods_api()->load_pods(
2171
- array(
2172
- 'type' => 'pod',
2173
- 'fields' => false,
2174
- 'table_info' => false,
2175
- )
2176
- );
2177
 
2178
  // Add New item links for all pods
2179
  foreach ( $all_pods as $pod ) {
2180
- if ( 0 === (int) $pod['options']['show_in_menu'] ) {
2181
  continue;
2182
  }
2183
 
@@ -2185,7 +2636,7 @@ class PodsInit {
2185
  continue;
2186
  }
2187
 
2188
- $singular_label = pods_v( 'label_singular', $pod['options'], pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true );
2189
 
2190
  $wp_admin_bar->add_node(
2191
  array(
@@ -2202,7 +2653,7 @@ class PodsInit {
2202
  $pod = $pods->pod_data;
2203
 
2204
  if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $pod['name'] ) ) ) {
2205
- $singular_label = pods_v( 'label_singular', $pod['options'], pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true );
2206
 
2207
  $wp_admin_bar->add_node(
2208
  array(
@@ -2266,6 +2717,7 @@ class PodsInit {
2266
  $conditionals[] = 'pods_allow_deprecated';
2267
  $conditionals[] = 'pods_api_cache';
2268
  $conditionals[] = 'pods_shortcode_allow_evaluate_tags';
 
2269
  return $conditionals;
2270
  }
2271
  }
1
  <?php
2
 
3
+ use Pods\Wisdom_Tracker;
4
+
5
  /**
6
  * @package Pods
7
  */
70
  /**
71
  * Whether an Upgrade for 1.x has happened
72
  *
73
+ * @var int
74
  */
75
+ public static $upgraded = 0;
76
 
77
  /**
78
  * Whether an Upgrade is needed
82
  public static $upgrade_needed = false;
83
 
84
  /**
85
+ * Stats Tracking object.
86
  *
87
+ * @since 2.8.0
88
  *
89
+ * @var Wisdom_Tracker
90
  */
91
+ public $stats_tracking;
92
 
93
  /**
94
  * Singleton handling for a basic pods_init() request
119
  self::$version = get_option( 'pods_framework_version' );
120
  self::$version_last = get_option( 'pods_framework_version_last' );
121
  self::$db_version = get_option( 'pods_framework_db_version' );
122
+
123
+ if ( ! pods_strict( false ) ) {
124
+ self::$upgraded = get_option( 'pods_framework_upgraded_1_x' );
125
+
126
+ if ( false === self::$upgraded ) {
127
+ self::$upgraded = 2;
128
+
129
+ delete_option( 'pods_framework_upgraded_1_x' );
130
+ add_option( 'pods_framework_upgraded_1_x', 2, '', 'yes' );
131
+ }
132
+ }
133
 
134
  if ( empty( self::$version_last ) && 0 < strlen( get_option( 'pods_version' ) ) ) {
135
  $old_version = get_option( 'pods_version' );
139
  $old_version = pods_version_to_point( $old_version );
140
  }
141
 
142
+ delete_option( 'pods_framework_version_last' );
143
+ add_option( 'pods_framework_version_last', $old_version, '', 'yes' );
144
 
145
  self::$version_last = $old_version;
146
  }
148
 
149
  self::$upgrade_needed = $this->needs_upgrade();
150
 
151
+ add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ], 0 );
152
+ add_action( 'plugins_loaded', [ $this, 'activate_install' ], 9 );
153
+ add_action( 'after_setup_theme', [ $this, 'after_setup_theme' ] );
154
+ add_action( 'wp_loaded', [ $this, 'flush_rewrite_rules' ] );
155
+
156
+ // Setup common info for after TEC/ET load.
157
+ add_action( 'plugins_loaded', [ $this, 'maybe_set_common_lib_info' ], 1 );
158
+ add_action( 'tribe_common_loaded', [ $this, 'run' ], 0 );
159
+ }
160
+
161
+ /**
162
+ * Setup of Common Library.
163
+ *
164
+ * @since 2.8.0
165
+ */
166
+ public function maybe_set_common_lib_info() {
167
+ // Set up the path for /tribe-common/ loading.
168
+ $common_version = file_get_contents( PODS_DIR . 'tribe-common/src/Tribe/Main.php' );
169
+
170
+ // If there isn't a tribe-common version, bail.
171
+ if ( ! preg_match( "/const\s+VERSION\s*=\s*'([^']+)'/m", $common_version, $matches ) ) {
172
+ add_action( 'admin_head', [ $this, 'missing_common_libs' ] );
173
+
174
+ return;
175
+ }
176
+
177
+ $common_version = $matches[1];
178
+
179
+ /**
180
+ * Attempt to load our Common if it's not already loaded.
181
+ */
182
+ if ( empty( $GLOBALS['tribe-common-info'] ) ) {
183
+ /**
184
+ * Custom tribe-common package:
185
+ *
186
+ * - Removed /vendor/freemius/ folder.
187
+ * - Removed /lang/ folder (for now).
188
+ * - Removed /src/resources/ folder (for now).
189
+ */
190
+ $solo_install = empty( $GLOBALS['tribe-common-info'] );
191
+
192
+ // Handle stopping anything we don't want to run in Tribe Common.
193
+ if ( $solo_install ) {
194
+ // Bypass Tribe-related options.
195
+ $tribe_options = [
196
+ 'tribe_settings_errors',
197
+ 'pue_install_key_promoter',
198
+ 'tribe_pue_key_notices',
199
+ 'tribe_events_calendar_options',
200
+ 'tribe_settings_major_error',
201
+ 'tribe_settings_sent_data',
202
+ 'tribe_events_calendar_network_options',
203
+ ];
204
+
205
+ $tribe_empty_options = [
206
+ 'pue_install_key_promoter',
207
+ 'tribe_settings_major_error',
208
+ '_tribe_admin_notices',
209
+ ];
210
+
211
+ foreach ( $tribe_options as $option_name ) {
212
+ $return_third_param = static function() {
213
+ return func_get_arg( 2 );
214
+ };
215
+ $return_fourth_param = static function() {
216
+ return func_get_arg( 3 );
217
+ };
218
+
219
+ add_filter( "pre_option_{$option_name}", $return_third_param, 10, 3 );
220
+ add_filter( "pre_site_option_{$option_name}", $return_fourth_param, 10, 4 );
221
+ }
222
+
223
+ foreach ( $tribe_empty_options as $option_name ) {
224
+ add_filter( "pre_option_{$option_name}", '__return_null' );
225
+ add_filter( "pre_site_option_{$option_name}", '__return_null' );
226
+ add_filter( "pre_transient_{$option_name}", '__return_null' );
227
+ }
228
+
229
+ // Remove hooks that are added and run before we can remove them.
230
+ add_action( 'tribe_common_loaded', static function() {
231
+ $main = Tribe__Main::instance();
232
+
233
+ remove_action( 'tribe_common_loaded', [ $main, 'load_assets' ], 1 );
234
+ remove_action( 'plugins_loaded', [ $main, 'tribe_plugins_loaded' ], PHP_INT_MAX );
235
+ remove_filter( 'body_class', [ $main, 'add_js_class' ] );
236
+ remove_action( 'wp_footer', [ $main, 'toggle_js_class' ] );
237
+ }, 0 );
238
+
239
+ if ( ! defined( 'TRIBE_HIDE_MARKETING_NOTICES' ) ) {
240
+ define( 'TRIBE_HIDE_MARKETING_NOTICES', true );
241
+ }
242
+ }
243
+
244
+ $GLOBALS['tribe-common-info'] = [
245
+ 'dir' => PODS_DIR . 'tribe-common/src/Tribe',
246
+ 'version' => $common_version,
247
+ ];
248
+
249
+ /**
250
+ * After this method we can use any `Tribe__` and `\Pods\...` classes
251
+ */
252
+ $this->init_autoloading();
253
+
254
+ // Start up Common.
255
+ $main = Tribe__Main::instance();
256
+ $main->plugins_loaded();
257
 
258
+ // Handle anything we want to unhook/stop in Tribe Common.
259
+ if ( $solo_install ) {
260
+ // Look into any others here.
261
+ remove_action( 'plugins_loaded', [ 'Tribe__App_Shop', 'instance' ] );
262
+ remove_action( 'plugins_loaded', [ 'Tribe__Admin__Notices', 'instance' ], 1 );
263
 
264
+ /** @var Tribe__Assets $assets */
265
+ $assets = tribe( 'assets' );
266
+ $assets->remove( 'tribe-tooltip' );
267
 
268
+ /** @var Tribe__Asset__Data $asset_data */
269
+ $asset_data = tribe( 'asset.data' );
270
+
271
+ remove_action( 'admin_footer', [ $asset_data, 'render_json' ] );
272
+ remove_action( 'customize_controls_print_footer_scripts', [ $asset_data, 'render_json' ] );
273
+ remove_action( 'wp_footer', [ $asset_data, 'render_json' ] );
274
+
275
+ /** @var Tribe__Assets_Pipeline $assets_pipeline */
276
+ $assets_pipeline = tribe( 'assets.pipeline' );
277
+ remove_filter( 'script_loader_tag', [ $assets_pipeline, 'prevent_underscore_conflict' ] );
278
+ }
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Display a missing-tribe-common library error.
284
+ *
285
+ * @since 2.8.0
286
+ */
287
+ public function missing_common_libs() {
288
+ ?>
289
+ <div class="error">
290
+ <p>
291
+ <?php
292
+ esc_html_e(
293
+ 'It appears as if the tribe-common libraries cannot be found! The directory should be in the "common/" directory in the Pods plugin.',
294
+ 'pods'
295
+ );
296
+ ?>
297
+ </p>
298
+ </div>
299
+ <?php
300
+ }
301
+
302
+ /**
303
+ * Autoloader for Pods classes.
304
+ *
305
+ * @param string $class Class name.
306
+ *
307
+ * @since 2.8.0
308
+ */
309
+ public static function autoload_class( $class ) {
310
+ // Bypass anything that doesn't start with Pods
311
+ if ( 0 !== strpos( $class, 'Pods' ) ) {
312
+ return;
313
+ }
314
+
315
+ $custom = array(
316
+ 'Pods_CLI_Command' => PODS_DIR . 'classes/cli/Pods_CLI_Command.php',
317
+ 'PodsAPI_CLI_Command' => PODS_DIR . 'classes/cli/PodsAPI_CLI_Command.php',
318
+ );
319
+
320
+ if ( isset( $custom[ $class ] ) ) {
321
+ $path = $custom[ $class ];
322
+
323
+ require_once $path;
324
+
325
+ return;
326
+ }
327
+
328
+ $loaders = array(
329
+ array(
330
+ 'prefix' => 'Pods',
331
+ 'separator' => '\\', // Namespace
332
+ 'path' => PODS_DIR . 'src',
333
+ ),
334
+ array(
335
+ 'prefix' => 'PodsField_',
336
+ 'filter' => 'strtolower',
337
+ 'exclude_prefix' => true,
338
+ 'path' => PODS_DIR . 'classes/fields',
339
+ ),
340
+ array(
341
+ 'prefix' => 'PodsWidget',
342
+ 'path' => PODS_DIR . 'classes/widgets',
343
+ ),
344
+ array(
345
+ 'prefix' => 'Pods',
346
+ 'path' => PODS_DIR . 'classes',
347
+ ),
348
+ );
349
+
350
+ foreach ( $loaders as $loader ) {
351
+ if ( 0 !== strpos( $class, $loader['prefix'] ) ) {
352
+ continue;
353
+ }
354
+
355
+ $path = array(
356
+ $loader['path'],
357
+ );
358
+
359
+ if ( ! empty( $loader['exclude_prefix'] ) ) {
360
+ $class = substr( $class, strlen( $loader['prefix'] ) );
361
+ }
362
+
363
+ if ( ! empty( $loader['filter'] ) ) {
364
+ $class = call_user_func( $loader['filter'], $class );
365
+ }
366
+
367
+ if ( ! isset( $loader['separator'] ) ) {
368
+ $path[] = $class;
369
+ } else {
370
+ $separated_path = explode( $loader['separator'], $class );
371
+
372
+ /** @noinspection SlowArrayOperationsInLoopInspection */
373
+ $path = array_merge( $path, $separated_path );
374
+ }
375
+
376
+ $path = implode( DIRECTORY_SEPARATOR, $path ) . '.php';
377
+
378
+ if ( file_exists( $path ) ) {
379
+ require_once $path;
380
+
381
+ break;
382
+ }
383
+ }
384
  }
385
 
386
  /**
387
  * Load the plugin textdomain and set default constants
388
  */
389
  public function plugins_loaded() {
 
390
  if ( ! defined( 'PODS_LIGHT' ) ) {
391
  define( 'PODS_LIGHT', false );
392
  }
395
  define( 'PODS_TABLELESS', false );
396
  }
397
 
398
+ if ( ! defined( 'PODS_TEXTDOMAIN' ) || PODS_TEXTDOMAIN ) {
399
+ load_plugin_textdomain( 'pods' );
400
+ }
401
 
402
+ if ( ! defined( 'PODS_STATS_TRACKING' ) || PODS_STATS_TRACKING ) {
403
+ $this->stats_tracking( PODS_FILE, 'pods' );
404
+ }
405
  }
406
 
407
  /**
408
+ * Handle Stats Tracking.
409
+ *
410
+ * @since 2.8.0
411
  *
412
+ * @param string $plugin_file The plugin file.
413
+ * @param string $plugin_slug The plugin slug.
414
  *
415
+ * @return Wisdom_Tracker The Stats Tracking object.
416
  */
417
+ public function stats_tracking( $plugin_file, $plugin_slug ) {
418
  // Admin only.
419
+ if (
420
+ ! is_admin()
421
+ && ! wp_doing_cron()
422
+ ) {
423
  return;
424
  }
425
 
426
  global $pagenow;
427
 
428
+ $is_pods_page = isset( $_GET['page'] ) && 0 === strpos( $_GET['page'], 'pods' );
429
+
430
  // Pods admin pages or plugins/update page only.
431
  if (
432
  'plugins.php' !== $pagenow
433
  && 'update-core.php' !== $pagenow
434
  && 'update.php' !== $pagenow
435
  && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX )
436
+ && ! $is_pods_page
437
+ && ! wp_doing_cron()
438
  ) {
439
  return;
440
  }
441
 
442
+ $is_main_plugin = PODS_FILE === $plugin_file;
443
+
444
+ if ( $is_main_plugin && $this->stats_tracking ) {
445
+ return $this->stats_tracking;
446
+ }
447
+
448
+ $settings = [];
449
+
450
+ if ( $is_main_plugin ) {
451
+ $settings[] = 'pods_settings';
452
+ }
453
+
454
+ $stats_tracking = new Wisdom_Tracker(
455
+ $plugin_file,
456
+ $plugin_slug,
457
+ 'https://stats.pods.io',
458
+ $settings,
459
+ true,
460
+ true,
461
+ 1
462
+ );
463
+
464
+ if ( $is_main_plugin ) {
465
+ add_action( 'update_option_wisdom_allow_tracking', static function ( $old_value, $value ) use ( $plugin_slug ) {
466
+ $opt_out = ! empty( $value[ $plugin_slug ] ) ? 0 : 1;
467
+
468
+ pods_update_setting( 'wisdom_opt_out', $opt_out );
469
+ }, 10, 2 );
470
+ }
471
+
472
+ add_action( 'update_option_pods_settings', static function ( $old_value, $value ) use ( $stats_tracking, $plugin_slug ) {
473
+ // Only handle opt in when needed.
474
+ if ( ! isset( $value['wisdom_opt_out'] ) || 0 !== (int) $value['wisdom_opt_out'] ) {
475
+ return;
476
+ }
477
+
478
+ // We are doing opt-in>
479
+ $stats_tracking->set_is_tracking_allowed( true, $plugin_slug );
480
+ $stats_tracking->set_can_collect_email( true, $plugin_slug );
481
+ }, 10, 2 );
482
+
483
+ add_filter( 'wisdom_is_local_' . $plugin_slug, static function ( $is_local = false ) {
484
+ if ( true === $is_local ) {
485
+ return $is_local;
486
+ }
487
 
488
+ $url = network_site_url( '/' );
489
 
490
+ $url = strtolower( trim( $url ) );
491
+ $url_parts = parse_url( $url );
492
+ $host = ! empty( $url_parts['host'] ) ? $url_parts['host'] : false;
493
 
494
+ if ( empty( $host ) ) {
495
+ return $is_local;
496
+ }
497
+
498
+ if ( 'localhost' === $host ) {
499
+ return true;
500
+ }
501
+
502
+ if ( false !== ip2long( $host ) && ! filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
503
+ return true;
504
+ }
505
+
506
+ $tlds_to_check = [
507
+ '.local',
508
+ '.test',
509
+ ];
510
+
511
+ foreach ( $tlds_to_check as $tld ) {
512
+ $minus_tld = strlen( $host ) - strlen( $tld );
513
+
514
+ if ( $minus_tld === strpos( $host, $tld ) ) {
515
+ return true;
516
+ }
517
+ }
518
+
519
+ return $is_local;
520
+ } );
521
+
522
+ add_filter( 'wisdom_notice_text_' . $plugin_slug, static function() {
523
+ return __( 'Thank you for installing our plugin. We\'d like your permission to track its usage on your site. We won\'t record any sensitive data, only information regarding the WordPress environment, your site admin email address, and plugin settings. We will only use this information help us make improvements to the plugin and provide better support when you reach out. Tracking is completely optional.', 'pods' );
524
+ } );
525
 
526
+ // Handle non-Pods pages, we don't want certain things happening.
527
+ if ( ! $is_pods_page ) {
528
+ remove_action( 'admin_notices', [ $stats_tracking, 'optin_notice' ] );
529
+ remove_action( 'admin_notices', [ $stats_tracking, 'marketing_notice' ] );
530
+ }
531
+
532
+ if ( ! $is_main_plugin ) {
533
  /**
534
+ * Allow hooking after the Stats Tracking object is setup for the main plugin.
535
  *
536
+ * @since 2.8.0
537
+ *
538
+ * @param Wisdom_Tracker $stats_tracking The Stats Tracking object.
539
+ * @param string $plugin_file The plugin file.
540
  */
541
+ do_action( 'pods_stats_tracking_after_init', $stats_tracking, $plugin_file );
 
 
542
  }
543
 
544
+ /**
545
+ * Allow hooking after the Stats Tracking object is setup.
546
+ *
547
+ * @since 2.8.0
548
+ *
549
+ * @param Wisdom_Tracker $stats_tracking The Stats Tracking object.
550
+ * @param string $plugin_file The plugin file.
551
+ */
552
+ do_action( 'pods_stats_tracking_object', $stats_tracking, $plugin_file );
553
+
554
+ // Maybe store the object.
555
+ if ( $is_main_plugin ) {
556
+ $this->stats_tracking = $stats_tracking;
557
+ }
558
+
559
+ return $stats_tracking;
560
  }
561
 
562
  /**
673
  );
674
  }
675
 
676
+ /**
677
+ * Sets up autoloading.
678
+ *
679
+ * @since 2.8.0
680
+ */
681
+ protected function init_autoloading() {
682
+ $autoloader = $this->get_autoloader_instance();
683
+ $autoloader->register_autoloader();
684
+ }
685
+
686
+ /**
687
+ * Returns the autoloader singleton instance to use in a context-aware manner.
688
+ *
689
+ * @since 2.8.0
690
+ *
691
+ * @return \Tribe__Autoloader The singleton common Autoloader instance.
692
+ */
693
+ public function get_autoloader_instance() {
694
+ if ( ! class_exists( 'Tribe__Autoloader' ) ) {
695
+ require_once $GLOBALS['tribe-common-info']['dir'] . '/Autoloader.php';
696
+
697
+ Tribe__Autoloader::instance()->register_prefixes( [
698
+ 'Tribe__' => $GLOBALS['tribe-common-info']['dir'],
699
+ ] );
700
+ }
701
+
702
+ return Tribe__Autoloader::instance();
703
+ }
704
+
705
  /**
706
  * Add compatibility for other plugins.
707
  *
708
  * @since 2.7.17
709
  */
710
  public function after_setup_theme() {
 
711
  if ( ! defined( 'PODS_COMPATIBILITY' ) ) {
712
  define( 'PODS_COMPATIBILITY', true );
713
  }
717
  }
718
 
719
  require_once PODS_DIR . 'includes/compatibility/acf.php';
 
720
  }
721
 
722
  /**
738
  * Load Pods Meta
739
  */
740
  public function load_meta() {
741
+ self::$meta = pods_meta();
742
 
743
+ self::$meta->core();
744
  }
745
 
746
  /**
767
  add_shortcode( 'pods-form', 'pods_shortcode_form' );
768
 
769
  $security_settings = array(
770
+ 'pods_disable_file_browser' => false,
771
+ 'pods_files_require_login' => true,
772
  'pods_files_require_login_cap' => '',
773
+ 'pods_disable_file_upload' => false,
774
+ 'pods_upload_require_login' => true,
775
  'pods_upload_require_login_cap' => '',
776
  );
777
 
 
 
 
 
 
 
 
778
  foreach ( $security_settings as $security_setting => $setting ) {
779
  if ( 0 === (int) $setting ) {
780
  $setting = false;
822
  * Register Scripts and Styles
823
  */
824
  public function register_assets() {
825
+ static $registered = false;
826
+
827
+ if ( $registered ) {
828
+ return;
829
+ }
830
+
831
+ $registered = true;
832
 
833
  $suffix_min = SCRIPT_DEBUG ? '' : '.min';
834
 
944
 
945
  // Marionette dependencies for DFV/MV fields.
946
  wp_register_script(
947
+ 'pods-backbone-radio',
948
  PODS_URL . "ui/js/marionette/backbone.radio{$suffix_min}.js",
949
  array( 'backbone' ),
950
  '2.0.0',
955
  PODS_URL . "ui/js/marionette/backbone.marionette{$suffix_min}.js",
956
  array(
957
  'backbone',
958
+ 'pods-backbone-radio',
959
  ),
960
  '3.3.1',
961
  true
965
  'PodsMn = Backbone.Marionette.noConflict();'
966
  );
967
 
968
+ // Dynamic Field Views / Marionette Views scripts.
969
+ $pods_dfv_options_file = file_get_contents( PODS_DIR . 'ui/js/dfv/pods-dfv.min.asset.json' );
970
+
971
+ $pods_dfv_options = json_decode( $pods_dfv_options_file, true );
972
+
973
  wp_register_script(
974
+ 'pods-dfv',
975
+ PODS_URL . 'ui/js/dfv/pods-dfv.min.js',
976
+ array_merge(
977
+ $pods_dfv_options['dependencies'],
978
+ [
979
+ 'jquery',
980
+ 'jquery-ui-core',
981
+ 'jquery-ui-sortable',
982
+ 'pods-marionette',
983
+ 'media-views',
984
+ 'media-models',
985
+ 'wp-components',
986
+ 'wp-block-library',
987
+ 'wp-tinymce',
988
+ ]
989
  ),
990
+ $pods_dfv_options['version'],
991
  true
992
  );
993
 
994
+ wp_set_script_translations( 'pods-dfv', 'pods' );
995
+
996
+ $config = [
997
+ 'wp_locale' => $GLOBALS['wp_locale'],
998
+ 'currencies' => PodsField_Currency::$currencies,
999
+ 'datetime' => [
1000
+ 'start_of_week' => (int) get_option( 'start_of_week', 0 ),
1001
+ 'gmt_offset' => (int) get_option( 'gmt_offset', 0 ),
1002
+ 'date_format' => get_option( 'date_format' ),
1003
+ 'time_format' => get_option( 'time_format' ),
1004
+ ],
1005
+ ];
1006
+
1007
+ /**
1008
+ * Allow filtering hte admin config data.
1009
+ *
1010
+ * @since 2.8.0
1011
+ *
1012
+ * @param array $config The admin config data.
1013
+ */
1014
+ $config = apply_filters( 'pods_admin_dfv_config', $config );
1015
+
1016
+ wp_localize_script( 'pods-dfv', 'podsDFVConfig', $config );
1017
+
1018
  // Page builders.
1019
  if (
1020
  // @todo Finish Elementor & Divi support.
1025
  add_filter( 'pods_enqueue_dfv_on_front', '__return_true' );
1026
  }
1027
 
1028
+ $is_admin = is_admin();
 
 
 
 
1029
 
1030
  // Deal with specifics on admin pages.
1031
+ if ( $is_admin && function_exists( 'get_current_screen' ) ) {
1032
  $screen = get_current_screen();
1033
 
1034
  // DFV must be enqueued on the media library page for items in grid mode (#4785)
1035
  // and for posts due to the possibility that post-thumbnails are enabled (#4945)
1036
+ if (
1037
+ $screen
1038
+ && $screen->base
1039
+ && in_array( $screen->base, [
1040
+ 'upload',
1041
+ 'post',
1042
+ ], true )
1043
+ ) {
1044
+ // Only load if we have a media pod.
1045
+ if ( ! empty( PodsMeta::$media ) ) {
1046
+ wp_enqueue_script( 'pods-dfv' );
1047
+ }
1048
  }
1049
  }
1050
 
1051
  $this->maybe_register_handlebars();
1052
 
1053
  // As of 2.7 we combine styles to just three .css files
1054
+ wp_register_style( 'pods-styles', PODS_URL . 'ui/styles/dist/pods.css', [ 'wp-components' ], PODS_VERSION );
1055
+ wp_register_style( 'pods-wizard', PODS_URL . 'ui/styles/dist/pods-wizard.css', [], PODS_VERSION );
1056
+ wp_register_style( 'pods-form', PODS_URL . 'ui/styles/dist/pods-form.css', [ 'wp-components' ], PODS_VERSION );
1057
 
1058
  /**
1059
  * Filter to enabled loading of the DFV script on frontend.
1065
  *
1066
  * @since 2.7.13
1067
  */
1068
+ if ( ! $is_admin && apply_filters( 'pods_enqueue_dfv_on_front', false ) ) {
1069
  wp_enqueue_script( 'pods-dfv' );
1070
  wp_enqueue_style( 'pods-form' );
1071
  }
1072
 
1073
+ // Check if Pod is a Modal Window.
1074
+ if ( pods_is_modal_window() ) {
1075
+ add_filter( 'body_class', array( $this, 'add_classes_to_modal_body' ) );
1076
+ add_filter( 'admin_body_class', array( $this, 'add_classes_to_modal_body' ) );
1077
+
1078
+ wp_enqueue_style( 'pods-styles' );
1079
+ }
1080
+
1081
  /**
1082
  * Fires after Pods assets are registered.
1083
  *
1131
  * Register internal Post Types
1132
  */
1133
  public function register_pods() {
 
1134
  $args = array(
1135
+ 'label' => __( 'Pods', 'pods' ),
1136
+ 'labels' => array( 'singular_name' => __( 'Pod', 'pods' ) ),
1137
  'public' => false,
1138
  'can_export' => false,
1139
  'query_var' => false,
1150
  register_post_type( '_pods_pod', apply_filters( 'pods_internal_register_post_type_pod', $args ) );
1151
 
1152
  $args = array(
1153
+ 'label' => __( 'Pod Groups', 'pods' ),
1154
+ 'labels' => array( 'singular_name' => __( 'Pod Group', 'pods' ) ),
1155
+ 'public' => false,
1156
+ 'can_export' => false,
1157
+ 'query_var' => false,
1158
+ 'rewrite' => false,
1159
+ 'capability_type' => 'pods_pod',
1160
+ 'has_archive' => false,
1161
+ 'hierarchical' => true,
1162
+ 'supports' => array( 'title', 'editor', 'author' ),
1163
+ 'menu_icon' => 'dashicons-pods',
1164
+ );
1165
+
1166
+ $args = self::object_label_fix( $args, 'post_type' );
1167
+
1168
+ register_post_type( '_pods_group', apply_filters( 'pods_internal_register_post_type_group', $args ) );
1169
+
1170
+ $args = array(
1171
+ 'label' => __( 'Pod Fields', 'pods' ),
1172
+ 'labels' => array( 'singular_name' => __( 'Pod Field', 'pods' ) ),
1173
  'public' => false,
1174
  'can_export' => false,
1175
  'query_var' => false,
1205
  return;
1206
  }
1207
 
 
 
 
1208
  $post_types = PodsMeta::$post_types;
1209
  $taxonomies = PodsMeta::$taxonomies;
1210
 
1263
  continue;
1264
  }
1265
 
 
 
 
1266
  $post_type_name = pods_v_sanitized( 'name', $post_type );
1267
 
1268
  // Labels
1423
  'rewrite' => $cpt_rewrite,
1424
  'query_var' => ( false !== (boolean) pods_v( 'query_var', $post_type, true ) ? pods_v( 'query_var_string', $post_type, $post_type_name, true ) : false ),
1425
  'can_export' => (boolean) pods_v( 'can_export', $post_type, true ),
1426
+ 'delete_with_user' => (boolean) pods_v( 'delete_with_user', $post_type, true ),
1427
  );
1428
 
1429
  // REST API
1462
 
1463
  // Taxonomies
1464
  $cpt_taxonomies = array();
1465
+ $_taxonomies = $existing_taxonomies;
1466
  $_taxonomies = array_merge_recursive( $_taxonomies, $pods_taxonomies );
1467
  $ignore = array( 'nav_menu', 'link_category', 'post_format' );
1468
 
1499
  continue;
1500
  }
1501
 
 
 
 
1502
  $taxonomy_name = pods_v( 'name', $taxonomy );
1503
 
1504
  // Labels
1628
 
1629
  // Post Types
1630
  $ct_post_types = array();
1631
+ $_post_types = $existing_post_types;
1632
  $_post_types = array_merge_recursive( $_post_types, $pods_post_types );
1633
  $ignore = array( 'revision' );
1634
 
1682
 
1683
  $pods_cpt_ct['post_format_post_types'] = $post_format_post_types;
1684
 
1685
+ pods_transient_set( 'pods_wp_cpt_ct', $pods_cpt_ct, WEEK_IN_SECONDS );
1686
  }//end if
1687
 
1688
  foreach ( $pods_cpt_ct['taxonomies'] as $taxonomy => $options ) {
1794
  // Handle existing post types / taxonomies settings (just REST for now)
1795
  global $wp_post_types, $wp_taxonomies;
1796
 
 
 
 
1797
  foreach ( $existing_post_types as $post_type_name => $post_type_name_again ) {
1798
  if ( isset( self::$content_types_registered['post_types'] ) && in_array( $post_type_name, self::$content_types_registered['post_types'], true ) ) {
1799
  // Post type already registered / setup by Pods
1800
  continue;
1801
  }
1802
 
1803
+ if ( ! isset( $post_types[ $post_type_name ] ) ) {
 
 
1804
  // Post type not a pod
1805
  continue;
1806
  }
1807
 
1808
+ $pod = $post_types[ $post_type_name ];
1809
 
1810
  // REST API
1811
+ $rest_enabled = (boolean) pods_v( 'rest_enable', $pod, false );
1812
 
1813
  if ( $rest_enabled ) {
1814
  if ( empty( $wp_post_types[ $post_type_name ]->show_in_rest ) ) {
1815
+ $rest_base = sanitize_title( pods_v( 'rest_base', $pod, pods_v( 'rest_base', $wp_post_types[ $post_type_name ] ), true ) );
1816
 
1817
  $wp_post_types[ $post_type_name ]->show_in_rest = true;
1818
  $wp_post_types[ $post_type_name ]->rest_base = $rest_base;
1829
  continue;
1830
  }
1831
 
1832
+ if ( ! isset( $taxonomies[ $taxonomy_name ] ) ) {
 
 
1833
  // Taxonomy not a pod
1834
  continue;
1835
  }
1836
 
1837
+ $pod = $taxonomies[ $taxonomy_name ];
1838
 
1839
  // REST API
1840
+ $rest_enabled = (boolean) pods_v( 'rest_enable', $pod, false );
1841
 
1842
  if ( $rest_enabled ) {
1843
  if ( empty( $wp_taxonomies[ $taxonomy_name ]->show_in_rest ) ) {
1844
+ $rest_base = sanitize_title( pods_v( 'rest_base', $pod, pods_v( 'rest_base', $wp_taxonomies[ $taxonomy_name ] ), true ) );
1845
 
1846
  $wp_taxonomies[ $taxonomy_name ]->show_in_rest = true;
1847
  $wp_taxonomies[ $taxonomy_name ]->rest_base = $rest_base;
1855
  if ( ! empty( PodsMeta::$user ) ) {
1856
  $pod = current( PodsMeta::$user );
1857
 
1858
+ $rest_enabled = (boolean) pods_v( 'rest_enable', $pod, false );
1859
 
1860
  if ( $rest_enabled ) {
1861
  new PodsRESTFields( $pod['name'] );
1865
  if ( ! empty( PodsMeta::$media ) ) {
1866
  $pod = current( PodsMeta::$media );
1867
 
1868
+ $rest_enabled = (boolean) pods_v( 'rest_enable', $pod, false );
1869
 
1870
  if ( $rest_enabled ) {
1871
  new PodsRESTFields( $pod['name'] );
1872
  }
1873
  }
1874
 
1875
+ do_action( 'pods_setup_content_types' );
1876
+
1877
+ if ( ! did_action( 'pods_init' ) ) {
1878
+ /**
1879
+ * Allow hooking into after Pods has been setup.
1880
+ *
1881
+ * @since 2.8.0
1882
+ *
1883
+ * @param PodsInit $init The PodsInit class object.
1884
+ */
1885
+ do_action( 'pods_init', $this );
1886
+ }
1887
  }
1888
 
1889
  /**
1907
  $wp_rewrite->flush_rules();
1908
  $wp_rewrite->init();
1909
 
1910
+ pods_transient_clear( 'pods_flush_rewrites' );
1911
  }
1912
  }
1913
 
2170
  if ( '2.1.0' === $new_version && ( is_developer() ) )
2171
  continue;*/
2172
 
2173
+ if ( version_compare( $last, $old_version, '>=' ) && version_compare( $last, $new_version, '<' ) && version_compare( $current, $new_version, '>=' ) && 1 !== self::$upgraded && 2 !== self::$upgraded ) {
2174
  $upgrade_needed = true;
2175
 
2176
  break;
2295
 
2296
  $api = pods_api();
2297
 
2298
+ $pods = $api->load_pods( array( 'names_ids' => true ) );
 
 
 
 
 
2299
 
2300
  foreach ( $pods as $pod_id => $pod_label ) {
2301
  $api->delete_pod( array( 'id' => $pod_id ) );
2375
 
2376
  $ran = true;
2377
 
2378
+ tribe_register_provider( \Pods\Service_Provider::class );
2379
+ tribe_register_provider( \Pods\Admin\Service_Provider::class );
2380
+ tribe_register_provider( \Pods\Blocks\Service_Provider::class );
2381
+ tribe_register_provider( \Pods\Integrations\Service_Provider::class );
2382
+ tribe_register_provider( \Pods\REST\V1\Service_Provider::class );
2383
+
2384
+ // Add WP-CLI commands.
2385
+ if ( defined( 'WP_CLI' ) && WP_CLI ) {
2386
+ //require_once PODS_DIR . 'classes/cli/Pods_CLI_Command.php';
2387
+ //require_once PODS_DIR . 'classes/cli/PodsAPI_CLI_Command.php';
2388
+
2389
+ tribe_register_provider( \Pods\CLI\Service_Provider::class );
2390
+ }
2391
+
2392
  $this->load_i18n();
2393
 
2394
  if ( ! did_action( 'plugins_loaded' ) ) {
2403
  $this->load_meta();
2404
  }
2405
 
2406
+ $is_admin = is_admin();
2407
+
2408
  if ( ! did_action( 'init' ) ) {
2409
  add_action( 'init', array( $this, 'core' ), 11 );
2410
  add_action( 'init', array( $this, 'setup_content_types' ), 11 );
2411
 
2412
+ if ( $is_admin ) {
2413
  add_action( 'init', array( $this, 'admin_init' ), 12 );
2414
  }
2415
  } else {
2416
  $this->core();
2417
  $this->setup_content_types();
2418
 
2419
+ if ( $is_admin ) {
2420
  $this->admin_init();
2421
  }
2422
  }
2423
 
2424
+ if ( ! $is_admin ) {
2425
+ add_action( 'wp_enqueue_scripts', [ $this, 'register_assets' ], 15 );
2426
+ } else {
2427
+ add_action( 'admin_enqueue_scripts', [ $this, 'register_assets' ], 15 );
2428
+ }
2429
+
2430
  add_action( 'login_enqueue_scripts', array( $this, 'register_assets' ), 15 );
2431
+
2432
  // @todo Elementor Page Builder.
2433
  //add_action( 'elementor/editor/before_enqueue_scripts', array( $this, 'register_assets' ), 15 );
2434
 
2447
  // Compatibility for Query Monitor conditionals
2448
  add_filter( 'query_monitor_conditionals', array( $this, 'filter_query_monitor_conditionals' ) );
2449
 
2450
+ // Remove Common menus
2451
+ add_action( 'admin_menu', array( $this, 'remove_common_menu' ), 11 );
2452
+ add_action( 'network_admin_menu', array( $this, 'remove_common_network_menu' ), 11 );
2453
+ }
2454
+
2455
+ /**
2456
+ * Remove Common menu.
2457
+ *
2458
+ * @since 2.8.0
2459
+ */
2460
+ public function remove_common_menu() {
2461
+ if ( ! class_exists( 'Tribe__Events__Main' ) && ! class_exists( 'Tribe__Tickets__Main' ) ) {
2462
+ remove_menu_page( 'tribe-common' );
2463
  }
2464
+ }
2465
 
2466
+ /**
2467
+ * Remove Common network menu.
2468
+ *
2469
+ * @since 2.8.0
2470
+ */
2471
+ public function remove_common_network_menu() {
2472
+ if ( ! class_exists( 'Tribe__Events__Main' ) && ! class_exists( 'Tribe__Tickets__Main' ) ) {
2473
+ remove_submenu_page( 'settings.php', 'tribe-common' );
2474
+ remove_submenu_page( 'settings.php', 'tribe-common-help' );
2475
+ }
2476
  }
2477
 
2478
  /**
2490
 
2491
  $file_types = "'" . implode( "', '", PodsForm::file_field_types() ) . "'";
2492
 
2493
+ if ( pods_podsrel_enabled() ) {
2494
  $sql = "
2495
  DELETE `rel`
2496
  FROM `@wp_podsrel` AS `rel`
2506
  WHERE
2507
  `p`.`ID` IS NOT NULL
2508
  AND `pm`.`meta_id` IS NOT NULL
2509
+ AND `rel`.`item_id` = {$_ID}
2510
+ ";
2511
 
2512
  pods_query( $sql, false );
2513
  }
2514
 
2515
+ if ( pods_relationship_meta_storage_enabled() ) {
2516
+ // Post Meta
2517
+ if ( ! empty( PodsMeta::$post_types ) ) {
2518
+ $sql = "
2519
  DELETE `rel`
2520
  FROM `@wp_postmeta` AS `rel`
2521
  LEFT JOIN `{$wpdb->posts}` AS `p`
2532
  AND `rel`.`meta_key` = `p`.`post_name`
2533
  AND `rel`.`meta_value` = '{$_ID}'";
2534
 
2535
+ pods_query( $sql, false );
2536
+ }
2537
 
2538
+ // User Meta
2539
+ if ( ! empty( PodsMeta::$user ) ) {
2540
+ $sql = "
2541
  DELETE `rel`
2542
  FROM `@wp_usermeta` AS `rel`
2543
  LEFT JOIN `{$wpdb->posts}` AS `p`
2554
  AND `rel`.`meta_key` = `p`.`post_name`
2555
  AND `rel`.`meta_value` = '{$_ID}'";
2556
 
2557
+ pods_query( $sql, false );
2558
+ }
2559
 
2560
+ // Comment Meta
2561
+ if ( ! empty( PodsMeta::$comment ) ) {
2562
+ $sql = "
2563
  DELETE `rel`
2564
  FROM `@wp_commentmeta` AS `rel`
2565
  LEFT JOIN `{$wpdb->posts}` AS `p`
2576
  AND `rel`.`meta_key` = `p`.`post_name`
2577
  AND `rel`.`meta_value` = '{$_ID}'";
2578
 
2579
+ pods_query( $sql, false );
2580
+ }
2581
  }
2582
+
2583
+ /**
2584
+ * Allow hooking into the attachment deletion process.
2585
+ *
2586
+ * @since 2.8.0
2587
+ *
2588
+ * @param int $_ID The attachment ID being deleted.
2589
+ */
2590
+ do_action( 'pods_init_delete_attachment', $_ID );
2591
  }
2592
 
2593
  /**
2608
  continue;
2609
  }
2610
 
 
2611
 
2612
  register_widget( $widget );
2613
  }
2624
  return;
2625
  }
2626
 
2627
+ $all_pods = pods_api()->load_pods( array( 'type' => 'pod' ) );
 
 
 
 
 
 
2628
 
2629
  // Add New item links for all pods
2630
  foreach ( $all_pods as $pod ) {
2631
+ if ( ! isset( $pod['show_in_menu'] ) || 0 === (int) $pod['show_in_menu'] ) {
2632
  continue;
2633
  }
2634
 
2636
  continue;
2637
  }
2638
 
2639
+ $singular_label = pods_v( 'label_singular', $pod, pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true );
2640
 
2641
  $wp_admin_bar->add_node(
2642
  array(
2653
  $pod = $pods->pod_data;
2654
 
2655
  if ( pods_is_admin( array( 'pods', 'pods_content', 'pods_edit_' . $pod['name'] ) ) ) {
2656
+ $singular_label = pods_v( 'label_singular', $pod, pods_v( 'label', $pod, ucwords( str_replace( '_', ' ', $pod['name'] ) ), true ), true );
2657
 
2658
  $wp_admin_bar->add_node(
2659
  array(
2717
  $conditionals[] = 'pods_allow_deprecated';
2718
  $conditionals[] = 'pods_api_cache';
2719
  $conditionals[] = 'pods_shortcode_allow_evaluate_tags';
2720
+ $conditionals[] = 'pods_session_auto_start';
2721
  return $conditionals;
2722
  }
2723
  }
classes/PodsMeta.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  /**
4
  * @package Pods
5
  */
@@ -93,9 +95,8 @@ class PodsMeta {
93
  * @since 2.3.5
94
  */
95
  public static function init() {
96
-
97
  if ( ! is_object( self::$instance ) ) {
98
- self::$instance = new PodsMeta();
99
  }
100
 
101
  return self::$instance;
@@ -114,207 +115,121 @@ class PodsMeta {
114
  * @return \PodsMeta
115
  */
116
  public function core() {
 
117
 
118
- self::$advanced_content_types = pods_api()->load_pods( array( 'type' => 'pod' ) );
119
- self::$post_types = pods_api()->load_pods( array( 'type' => 'post_type' ) );
120
- self::$taxonomies = pods_api()->load_pods( array( 'type' => 'taxonomy' ) );
121
- self::$media = pods_api()->load_pods( array( 'type' => 'media' ) );
122
- self::$user = pods_api()->load_pods( array( 'type' => 'user' ) );
123
- self::$comment = pods_api()->load_pods( array( 'type' => 'comment' ) );
124
- self::$settings = pods_api()->load_pods( array( 'type' => 'settings' ) );
125
-
126
- // Handle Post Type Editor (needed for Pods core)
127
-
128
- // Loop through and add meta boxes for individual types (can't use this, Tabify doesn't pick it up)
129
- /*
130
- foreach ( self::$post_types as $post_type ) {
131
- $post_type_name = $post_type[ 'name' ];
132
 
133
- if ( !empty( $post_type[ 'object' ] ) )
134
- $post_type_name = $post_type[ 'object' ];
135
-
136
- add_action( 'add_meta_boxes_' . $post_type_name, array( $this, 'meta_post_add' ) );
137
- }
138
- */
139
-
140
- add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
141
- add_action( 'transition_post_status', array( $this, 'save_post_detect_new' ), 10, 3 );
142
- add_action( 'save_post', array( $this, 'save_post' ), 10, 3 );
143
- add_filter( 'wp_insert_post_data', array( $this, 'save_post_track_changed_fields' ), 10, 2 );
144
-
145
- if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) {
146
- // Handle *_post_meta
147
- if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) {
148
- add_filter( 'get_post_metadata', array( $this, 'get_post_meta' ), 10, 4 );
149
- }
150
 
151
- if ( ! pods_tableless() ) {
152
- add_filter( 'add_post_metadata', array( $this, 'add_post_meta' ), 10, 5 );
153
- add_filter( 'update_post_metadata', array( $this, 'update_post_meta' ), 10, 5 );
154
- add_filter( 'delete_post_metadata', array( $this, 'delete_post_meta' ), 10, 5 );
155
- }
156
  }
157
 
158
- add_action( 'delete_post', array( $this, 'delete_post' ), 10, 1 );
159
-
160
- if ( ! empty( self::$taxonomies ) ) {
161
- $has_fields = false;
162
-
163
- // Handle Taxonomy Editor
164
- foreach ( self::$taxonomies as $taxonomy ) {
165
- if ( empty( $taxonomy['fields'] ) ) {
166
- continue;
167
- }
168
-
169
- $has_fields = true;
170
-
171
- $taxonomy_name = $taxonomy['name'];
172
-
173
- if ( ! empty( $taxonomy['object'] ) ) {
174
- $taxonomy_name = $taxonomy['object'];
175
- }
176
 
177
- add_action( $taxonomy_name . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 );
178
- add_action( $taxonomy_name . '_add_form_fields', array( $this, 'meta_taxonomy' ), 10, 1 );
179
- }
 
 
 
 
 
 
180
 
181
- if ( $has_fields ) {
182
- // Handle Term Editor
183
- add_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 );
184
- add_action( 'create_term', array( $this, 'save_taxonomy' ), 10, 3 );
185
- add_action( 'edit_terms', array( $this, 'save_taxonomy_track_changed_fields' ), 10, 2 );
186
 
187
- if ( apply_filters( 'pods_meta_handler', true, 'term' ) ) {
188
- // Handle *_term_meta
189
- if ( apply_filters( 'pods_meta_handler_get', true, 'term' ) ) {
190
- add_filter( 'get_term_metadata', array( $this, 'get_term_meta' ), 10, 4 );
191
  }
192
 
193
- if ( ! pods_tableless() ) {
194
- add_filter( 'add_term_metadata', array( $this, 'add_term_meta' ), 10, 5 );
195
- add_filter( 'update_term_metadata', array( $this, 'update_term_meta' ), 10, 5 );
196
- add_filter( 'delete_term_metadata', array( $this, 'delete_term_meta' ), 10, 5 );
197
- }
198
  }
199
  }
200
  }
201
 
202
- /**
203
- * Fires after a previously shared taxonomy term is split into two separate terms.
204
- *
205
- * @since 4.2.0
206
- *
207
- * @param int $term_id ID of the formerly shared term.
208
- * @param int $new_term_id ID of the new term created for the $term_taxonomy_id.
209
- * @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split.
210
- * @param string $taxonomy Taxonomy for the split term.
211
- */
212
- add_action( 'split_shared_term', array( $this, 'split_shared_term' ), 10, 4 );
213
-
214
- // Handle Delete
215
- add_action( 'delete_term_taxonomy', array( $this, 'delete_taxonomy' ), 10, 1 );
216
 
217
- if ( ! empty( self::$media ) ) {
218
- add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
219
- add_action( 'wp_ajax_save-attachment-compat', array( $this, 'save_media_ajax' ), 0 );
220
 
221
- add_filter( 'attachment_fields_to_edit', array( $this, 'meta_media' ), 10, 2 );
 
 
222
 
223
- add_filter( 'attachment_fields_to_save', array( $this, 'save_media' ), 10, 2 );
224
- add_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 );
225
- add_filter( 'wp_insert_attachment_data', array( $this, 'save_post_track_changed_fields' ), 10, 2 );
226
 
227
- if ( apply_filters( 'pods_meta_handler', true, 'post' ) ) {
228
- // Handle *_post_meta
229
- if ( ! has_filter( 'get_post_metadata', array( $this, 'get_post_meta' ) ) ) {
230
- if ( apply_filters( 'pods_meta_handler_get', true, 'post' ) ) {
231
- add_filter( 'get_post_metadata', array( $this, 'get_post_meta' ), 10, 4 );
 
 
 
232
  }
233
 
234
- if ( ! pods_tableless() ) {
235
- add_filter( 'add_post_metadata', array( $this, 'add_post_meta' ), 10, 5 );
236
- add_filter( 'update_post_metadata', array( $this, 'update_post_meta' ), 10, 5 );
237
- add_filter( 'delete_post_metadata', array( $this, 'delete_post_meta' ), 10, 5 );
238
- }
239
  }
240
  }
241
  }
242
 
243
- // Handle Delete
244
- add_action( 'delete_attachment', array( $this, 'delete_media' ), 10, 1 );
245
-
246
- if ( ! empty( self::$user ) ) {
247
- // Handle User Editor
248
- add_action( 'show_user_profile', array( $this, 'meta_user' ) );
249
- add_action( 'edit_user_profile', array( $this, 'meta_user' ) );
250
- add_action( 'user_register', array( $this, 'save_user' ) );
251
- add_action( 'profile_update', array( $this, 'save_user' ), 10, 2 );
252
- add_filter( 'pre_user_login', array( $this, 'save_user_track_changed_fields' ) );
253
 
254
- if ( apply_filters( 'pods_meta_handler', true, 'user' ) ) {
255
- // Handle *_user_meta
256
- if ( apply_filters( 'pods_meta_handler_get', true, 'user' ) ) {
257
- add_filter( 'get_user_metadata', array( $this, 'get_user_meta' ), 10, 4 );
258
- }
259
 
260
- if ( ! pods_tableless() ) {
261
- add_filter( 'add_user_metadata', array( $this, 'add_user_meta' ), 10, 5 );
262
- add_filter( 'update_user_metadata', array( $this, 'update_user_meta' ), 10, 5 );
263
- add_filter( 'delete_user_metadata', array( $this, 'delete_user_meta' ), 10, 5 );
264
- }
265
  }
 
 
 
266
  }
267
 
268
- // Handle Delete
269
- add_action( 'delete_user', array( $this, 'delete_user' ), 10, 1 );
 
 
 
 
270
 
271
- if ( ! empty( self::$comment ) ) {
272
- // Handle Comment Form / Editor
273
- add_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 );
274
- add_filter( 'comment_form_default_fields', array( $this, 'meta_comment_new' ) );
275
- add_action( 'add_meta_boxes_comment', array( $this, 'meta_comment_add' ) );
276
- add_filter( 'pre_comment_approved', array( $this, 'validate_comment' ), 10, 2 );
277
- add_action( 'comment_post', array( $this, 'save_comment' ) );
278
- add_action( 'edit_comment', array( $this, 'save_comment' ) );
279
- add_action( 'wp_update_comment_data', array( $this, 'save_comment_track_changed_fields' ), 10, 3 );
280
 
281
- if ( apply_filters( 'pods_meta_handler', true, 'comment' ) ) {
282
- // Handle *_comment_meta
283
- add_filter( 'get_comment_metadata', array( $this, 'get_comment_meta' ), 10, 4 );
 
 
 
284
 
285
- if ( ! pods_tableless() ) {
286
- add_filter( 'add_comment_metadata', array( $this, 'add_comment_meta' ), 10, 5 );
287
- add_filter( 'update_comment_metadata', array( $this, 'update_comment_meta' ), 10, 5 );
288
- add_filter( 'delete_comment_metadata', array( $this, 'delete_comment_meta' ), 10, 5 );
289
- }
290
  }
291
  }
292
 
293
- // Handle Delete
294
- add_action( 'delete_comment', array( $this, 'delete_comment' ), 10, 1 );
295
-
296
- // @todo Patch core to provide $option back in filters, patch core to add filter pre_add_option to add_option
297
- /*if ( !empty( self::$settings ) ) {
298
- foreach ( self::$settings as $setting_pod ) {
299
- foreach ( $setting_pod[ 'fields' ] as $option ) {
300
- add_filter( 'pre_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'get_option' ), 10, 1 );
301
- add_action( 'add_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'add_option' ), 10, 2 );
302
- add_filter( 'pre_update_option_' . $setting_pod[ 'name' ] . '_' . $option[ 'name' ], array( $this, 'update_option' ), 10, 2 );
303
- }
304
- }
305
- }*/
306
-
307
  if ( is_admin() ) {
308
  $this->integrations();
309
  }
310
 
311
  add_action( 'init', array( $this, 'enqueue' ), 9 );
312
 
313
- if ( function_exists( 'pll_current_language' ) ) {
314
- add_action( 'init', array( $this, 'cache_pods' ), 101 );
315
- }
316
-
317
- do_action( 'pods_meta_init' );
318
 
319
  return $this;
320
  }
@@ -326,7 +241,7 @@ class PodsMeta {
326
 
327
  foreach ( self::$queue as $type => $objects ) {
328
  foreach ( $objects as $pod_name => $pod ) {
329
- pods_transient_set( 'pods_pod_' . $pod_name, $pod );
330
  }
331
 
332
  self::${$type} = array_merge( self::${$type}, $objects );
@@ -334,17 +249,47 @@ class PodsMeta {
334
  }
335
 
336
  /**
337
- * Go back through and cache the Pods now that Polylang has loaded
 
 
338
  */
339
- public function cache_pods() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
 
341
- self::$advanced_content_types = pods_api()->load_pods( array( 'type' => 'pod', 'refresh' => true ) );
342
- self::$post_types = pods_api()->load_pods( array( 'type' => 'post_type', 'refresh' => true ) );
343
- self::$taxonomies = pods_api()->load_pods( array( 'type' => 'taxonomy', 'refresh' => true ) );
344
- self::$media = pods_api()->load_pods( array( 'type' => 'media', 'refresh' => true ) );
345
- self::$user = pods_api()->load_pods( array( 'type' => 'user', 'refresh' => true ) );
346
- self::$comment = pods_api()->load_pods( array( 'type' => 'comment', 'refresh' => true ) );
347
- self::$settings = pods_api()->load_pods( array( 'type' => 'settings', 'refresh' => true ) );
 
 
 
 
 
 
 
348
  }
349
 
350
  /**
@@ -612,7 +557,7 @@ class PodsMeta {
612
  }
613
  }
614
 
615
- $field = ( "cpachidden" === substr( $obj->get_option( 'field' ), 0, 10 ) ) ? str_replace( 'cpachidden', '', $obj->get_option( 'field' ) ) : $obj->get_option( 'field' );
616
  $field_type = $obj->get_option( 'field_type' );
617
 
618
  if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] !== $object ) {
@@ -652,7 +597,7 @@ class PodsMeta {
652
  $meta = $podterms->field( $field );
653
  }
654
 
655
- $meta = PodsForm::field_method( $pod['fields'][ $field ]['type'], 'ui', $id, $meta, $field, array_merge( $pod['fields'][ $field ], $pod['fields'][ $field ]['options'] ), $pod['fields'], $pod );
656
  }
657
 
658
  return $meta;
@@ -675,7 +620,6 @@ class PodsMeta {
675
  * @return mixed|void
676
  */
677
  public function group_add( $pod, $label, $fields, $context = 'normal', $priority = 'default' ) {
678
-
679
  if ( is_array( $pod ) && ! empty( $pod ) && ! isset( $pod['name'] ) ) {
680
  foreach ( $pod as $p ) {
681
  $this->group_add( $p, $label, $fields, $context, $priority );
@@ -757,7 +701,9 @@ class PodsMeta {
757
  'type' => 'text'
758
  );
759
 
760
- if ( ! is_array( $field ) ) {
 
 
761
  $name = trim( $field );
762
 
763
  $field = array(
@@ -766,12 +712,12 @@ class PodsMeta {
766
  );
767
  }
768
 
769
- $field = array_merge( $defaults, $field );
770
 
771
  $field['name'] = trim( $field['name'] );
772
 
773
  if ( isset( $pod['fields'] ) && isset( $pod['fields'][ $field['name'] ] ) ) {
774
- $field = array_merge( $field, $pod['fields'][ $field['name'] ] );
775
  }
776
 
777
  $_fields[ $k ] = $field;
@@ -800,45 +746,23 @@ class PodsMeta {
800
  // Hook it up!
801
  if ( 'post_type' == $pod['type'] ) {
802
  if ( ! has_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) ) ) {
803
- add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
804
  }
805
-
806
- /*if ( !has_action( 'save_post', array( $this, 'save_post' ), 10, 3 ) )
807
- add_action( 'save_post', array( $this, 'save_post' ), 10, 3 );*/
808
  } elseif ( 'taxonomy' == $pod['type'] ) {
809
- if ( ! has_action( $pod['object'] . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 ) ) {
810
- add_action( $pod['object'] . '_edit_form_fields', array( $this, 'meta_taxonomy' ), 10, 2 );
811
- add_action( $pod['object'] . '_add_form_fields', array( $this, 'meta_taxonomy' ), 10, 1 );
812
- }
813
-
814
- if ( ! has_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 ) ) {
815
- add_action( 'edited_term', array( $this, 'save_taxonomy' ), 10, 3 );
816
- add_action( 'create_term', array( $this, 'save_taxonomy' ), 10, 3 );
817
  }
818
  } elseif ( 'media' == $pod['type'] ) {
819
- if ( ! has_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 ) ) {
820
- add_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) );
821
- add_action( 'wp_ajax_save-attachment-compat', array( $this, 'save_media_ajax' ), 0 );
822
-
823
- add_filter( 'attachment_fields_to_edit', array( $this, 'meta_media' ), 10, 2 );
824
-
825
- add_filter( 'attachment_fields_to_save', array( $this, 'save_media' ), 10, 2 );
826
- add_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ), 10, 2 );
827
  }
828
  } elseif ( 'user' == $pod['type'] ) {
829
  if ( ! has_action( 'show_user_profile', array( $this, 'meta_user' ) ) ) {
830
- add_action( 'show_user_profile', array( $this, 'meta_user' ) );
831
- add_action( 'edit_user_profile', array( $this, 'meta_user' ) );
832
- add_action( 'user_register', array( $this, 'save_user' ) );
833
- add_action( 'profile_update', array( $this, 'save_user' ), 10, 2 );
834
  }
835
  } elseif ( 'comment' == $pod['type'] ) {
836
- if ( ! has_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 ) ) {
837
- add_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ), 10, 2 );
838
- add_filter( 'comment_form_default_fields', array( $this, 'meta_comment_new' ) );
839
- add_action( 'add_meta_boxes_comment', array( $this, 'meta_comment_add' ) );
840
- add_action( 'wp_insert_comment', array( $this, 'save_comment' ) );
841
- add_action( 'edit_comment', array( $this, 'save_comment' ) );
842
  }
843
  }
844
  }
@@ -867,7 +791,7 @@ class PodsMeta {
867
  $object = self::$comment;
868
  }
869
 
870
- if ( 'pod' != $type && ! empty( $object ) && is_array( $object ) && isset( $object[ $name ] ) ) {
871
  $pod = $object[ $name ];
872
  } else {
873
  if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] != $name ) {
@@ -887,7 +811,7 @@ class PodsMeta {
887
  'type' => 'post_type'
888
  );
889
 
890
- $pod = array_merge( $defaults, (array) $pod );
891
 
892
  if ( empty( $pod['name'] ) ) {
893
  $pod['name'] = $pod['object'];
@@ -903,15 +827,16 @@ class PodsMeta {
903
  }
904
 
905
  /**
906
- * @param $type
907
- * @param $name
908
- * @param $default_fields
909
  *
910
- * @return array
 
 
 
 
911
  */
912
  public function groups_get( $type, $name, $default_fields = null ) {
913
-
914
- static $groups_cache = array();
915
 
916
  if ( isset( $groups_cache[ $type . '/' . $name ] ) ) {
917
  return $groups_cache[ $type . '/' . $name ];
@@ -926,8 +851,8 @@ class PodsMeta {
926
 
927
  do_action( 'pods_meta_groups', $type, $name );
928
 
929
- $pod = array();
930
- $fields = array();
931
 
932
  $object = self::$post_types;
933
 
@@ -944,15 +869,16 @@ class PodsMeta {
944
  }
945
 
946
  if ( ! empty( $object ) && is_array( $object ) && isset( $object[ $name ] ) ) {
947
- $fields = $object[ $name ]['fields'];
 
948
  } else {
949
- if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] != $name ) {
950
- self::$current_pod_data = pods_api()->load_pod( array( 'name' => $name ), false );
951
  }
952
 
953
  $pod = self::$current_pod_data;
954
 
955
- if ( ! empty( $pod ) ) {
956
  $fields = $pod['fields'];
957
  }
958
  }
@@ -961,61 +887,86 @@ class PodsMeta {
961
  $fields = $default_fields;
962
  }
963
 
964
- $defaults = array(
965
- 'name' => 'post',
966
  'object' => 'post',
967
- 'type' => 'post_type'
968
- );
969
 
970
- $pod = array_merge( $defaults, (array) $pod );
 
971
 
972
- if ( empty( $pod['name'] ) ) {
973
- $pod['name'] = $pod['object'];
974
- } elseif ( empty( $pod['object'] ) ) {
975
- $pod['object'] = $pod['name'];
 
976
  }
977
 
978
- if ( $pod['type'] != $type ) {
979
- $groups_cache[ $type . '/' . $name ] = array();
980
 
981
  return $groups_cache[ $type . '/' . $name ];
982
  }
983
 
984
- $groups = array(
985
- array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
986
  'pod' => $pod,
987
- /**
988
- * Filter the title of the Pods Metabox In The Post Editor
989
- *
990
- * @param string $title The title to use, default is 'More Fields'
991
- * @param obj|Pod $pod Current Pods Object
992
- * @param array $fields Array of fields that will go in the metabox
993
- * @param string $type The type of Pod
994
- * @param string $name Name of the Pod
995
- *
996
- * @return string The title for the metabox.
997
- *
998
- * @since unknown
999
- */
1000
- 'label' => apply_filters( 'pods_meta_default_box_title', __( 'More Fields', 'pods' ), $pod, $fields, $type, $name ),
1001
  'fields' => $fields,
1002
  'context' => 'normal',
1003
- 'priority' => 'default'
1004
- )
1005
- );
1006
-
1007
- if ( isset( self::$groups[ $type ] ) && isset( self::$groups[ $type ][ $name ] ) ) {
1008
- $groups = self::$groups[ $type ][ $name ];
1009
  }
1010
 
1011
  /**
1012
  * Filter the array of field groups
1013
  *
1014
- * @param array $groups Array of groups
 
1015
  * @param string $type The type of Pod
1016
  * @param string $name Name of the Pod
1017
  *
1018
- * @since 2.6.6
1019
  */
1020
  $groups = apply_filters( 'pods_meta_groups_get', $groups, $type, $name );
1021
 
@@ -1046,14 +997,18 @@ class PodsMeta {
1046
  continue;
1047
  }
1048
 
 
 
 
 
1049
  $field_found = false;
1050
  $group_hidden = true;
1051
 
1052
  foreach ( $group['fields'] as $field ) {
1053
- if ( false !== PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'] ) ) {
1054
  $field_found = true;
1055
  }
1056
- if ( ! isset( $field['options']['hidden'] ) || 1 != (int) $field['options']['hidden'] ) {
1057
  $group_hidden = false;
1058
  }
1059
  }
@@ -1082,16 +1037,94 @@ class PodsMeta {
1082
  }
1083
  }
1084
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1085
  /**
1086
  *
1087
  * Called by 'post_edit_form_tag' action to include the classes in the <form> tag
1088
  *
1089
  */
1090
  public function add_class_submittable() {
1091
-
1092
  echo ' class="pods-submittable pods-form"';
1093
  }
1094
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1095
  /**
1096
  * @param $post
1097
  * @param $metabox
@@ -1109,21 +1142,13 @@ class PodsMeta {
1109
 
1110
  do_action( 'pods_meta_meta_post', $post );
1111
 
1112
- $hidden_fields = array();
1113
-
1114
  $id = null;
1115
 
1116
  if ( is_object( $post ) ) {
1117
  $id = $post->ID;
1118
  }
1119
 
1120
- if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod ) || self::$current_pod->pod != $metabox['args']['group']['pod']['name'] ) {
1121
- self::$current_pod = pods( $metabox['args']['group']['pod']['name'], $id, true );
1122
- } elseif ( self::$current_pod->id() != $id ) {
1123
- self::$current_pod->fetch( $id );
1124
- }
1125
-
1126
- $pod = self::$current_pod;
1127
 
1128
  $fields = $metabox['args']['group']['fields'];
1129
 
@@ -1141,34 +1166,26 @@ class PodsMeta {
1141
  $fields = apply_filters( 'pods_meta_post_fields', $fields, $id, $post, $metabox, $pod );
1142
 
1143
  if ( empty( $fields ) ) {
1144
- _e( 'There are no fields to display', 'pods' );
1145
 
1146
  return;
1147
  }
 
 
1148
  ?>
1149
  <table class="form-table pods-metabox pods-admin pods-dependency">
1150
  <?php
1151
- echo PodsForm::field( 'pods_meta', wp_create_nonce( 'pods_meta_' . $pod_type ), 'hidden' );
 
 
1152
 
1153
- foreach ( $fields as $field ) {
1154
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field['options'], $fields, $pod, $id ) ) {
1155
- if ( pods_var( 'hidden', $field['options'], false ) ) {
1156
- $field['type'] = 'hidden';
1157
- } else {
1158
- continue;
1159
- }
1160
- } elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
1161
- $field['type'] = 'hidden';
1162
- }
1163
 
1164
  $value = null;
1165
 
1166
  if ( ! empty( $pod ) ) {
1167
- pods_no_conflict_on( 'post' );
1168
-
1169
- $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
1170
-
1171
- pods_no_conflict_off( 'post' );
1172
  } elseif ( ! empty( $id ) ) {
1173
  $value = get_post_meta( $id, $field['name'], true );
1174
  }
@@ -1182,56 +1199,30 @@ class PodsMeta {
1182
  }
1183
  }
1184
 
1185
- if ( 'hidden' == $field['type'] ) {
1186
- $hidden_fields[] = array(
1187
- 'field' => $field,
1188
- 'value' => $value
1189
- );
1190
- } else {
1191
- $dep_options = PodsForm::dependencies( $field, 'pods-meta-' );
1192
- $dep_classes = $dep_options['classes'];
1193
- $dep_data = $dep_options['data'];
1194
-
1195
- $field_name = $field['name'];
1196
- do_action( "pods_meta_meta_post_{$field_name}", $post, $field, $pod );
1197
- ?>
1198
- <tr class="form-field pods-field pods-field-input <?php echo esc_attr( 'pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ) ); ?> <?php echo esc_attr( $dep_classes ); ?>" <?php PodsForm::data( $dep_data ); ?>">
1199
- <th scope="row" valign="top"><?php echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field ); ?></th>
1200
- <td>
1201
- <?php
1202
- // Remove any extra ? help icons
1203
- if ( isset( $field['help'] ) ) {
1204
- unset( $field['help'] );
1205
- }
1206
- ?>
1207
- <div class="pods-submittable-fields">
1208
- <?php echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id ); ?>
1209
- <?php echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field ); ?>
1210
- </div>
1211
- </td>
1212
- </tr>
1213
- <?php
1214
- do_action( "pods_meta_meta_post_{$field_name}_post", $post, $field, $pod );
1215
- }
1216
- }
1217
- ?>
1218
- </table>
1219
 
1220
- <?php
1221
- do_action( 'pods_meta_meta_post_post', $post );
1222
 
1223
- foreach ( $hidden_fields as $hidden_field ) {
1224
- $field_data = $hidden_field['field'];
 
 
1225
 
1226
- echo PodsForm::field( 'pods_meta_' . $field_data['name'], $hidden_field['value'], 'hidden', $field_data );
1227
- }
1228
- ?>
 
 
 
 
 
 
 
1229
 
1230
  <script type="text/javascript">
1231
  jQuery( function ( $ ) {
1232
- $( document ).Pods( 'validate' );
1233
  $( document ).Pods( 'submit_meta' );
1234
- $( document ).Pods( 'dependency', true );
1235
  } );
1236
  </script>
1237
  <?php
@@ -1295,7 +1286,8 @@ class PodsMeta {
1295
  $blacklisted_types = array(
1296
  'revision',
1297
  '_pods_pod',
1298
- '_pods_field'
 
1299
  );
1300
 
1301
  $blacklisted_types = apply_filters( 'pods_meta_save_post_blacklist_types', $blacklisted_types, $post_id, $post );
@@ -1303,7 +1295,7 @@ class PodsMeta {
1303
  // @todo Figure out how to hook into autosave for saving meta
1304
 
1305
  // Block Autosave and Revisions
1306
- if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || in_array( $post->post_type, $blacklisted_types ) ) {
1307
  return;
1308
  }
1309
 
@@ -1325,25 +1317,18 @@ class PodsMeta {
1325
 
1326
  $blacklisted_status = apply_filters( 'pods_meta_save_post_blacklist_status', $blacklisted_status, $post_id, $post );
1327
 
1328
- if ( in_array( $post->post_status, $blacklisted_status ) ) {
1329
  return;
1330
  }
1331
 
1332
  $groups = $this->groups_get( 'post_type', $post->post_type );
1333
 
1334
- $id = $post_id;
1335
-
1336
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod !== $post->post_type ) {
1337
- self::$current_pod = pods( $post->post_type, $id, true );
1338
- } elseif ( is_object( self::$current_pod ) && (int) self::$current_pod->id() !== (int) $id ) {
1339
- self::$current_pod->fetch( $id );
1340
- }
1341
-
1342
- $pod = self::$current_pod;
1343
- $data = array();
1344
 
1345
  if ( $pod ) {
1346
- $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false );
1347
 
1348
  // Block REST API saves, we handle those separately in PodsRESTHandlers
1349
  if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
@@ -1353,14 +1338,24 @@ class PodsMeta {
1353
  // The following code will run for all post_types (not just Pods)
1354
 
1355
  if ( false !== $nonced && ! empty( $groups ) ) {
 
 
1356
  foreach ( $groups as $group ) {
1357
  if ( empty( $group['fields'] ) ) {
1358
  continue;
1359
  }
1360
 
 
 
 
 
1361
  foreach ( $group['fields'] as $field ) {
1362
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1363
- if ( ! pods_v( 'hidden', $field['options'], false ) ) {
 
 
 
 
1364
  continue;
1365
  }
1366
  }
@@ -1389,7 +1384,10 @@ class PodsMeta {
1389
  // Fix for Pods doing it's own sanitizing.
1390
  $data = pods_unslash( (array) $data );
1391
 
1392
- $pod->save( $data, null, null, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) );
 
 
 
1393
  } elseif ( ! empty( $id ) ) {
1394
  foreach ( $data as $field => $value ) {
1395
  update_post_meta( $id, $field, $value );
@@ -1466,45 +1464,66 @@ class PodsMeta {
1466
  continue;
1467
  }
1468
 
1469
- if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
1470
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
1471
- self::$current_pod = pods( $group['pod']['name'], $id, true );
1472
- } elseif ( self::$current_pod->id() != $id ) {
1473
- self::$current_pod->fetch( $id );
1474
- }
1475
 
1476
- $pod = self::$current_pod;
 
1477
  }
1478
 
 
 
1479
  foreach ( $group['fields'] as $field ) {
1480
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1481
- if ( ! pods_var( 'hidden', $field['options'], false ) ) {
1482
  continue;
1483
  }
1484
  }
1485
 
 
 
 
 
 
1486
  $value = '';
1487
 
 
 
1488
  if ( ! empty( $pod ) ) {
1489
- $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
1490
  } elseif ( ! empty( $id ) ) {
1491
- pods_no_conflict_on( 'post' );
1492
-
1493
  $value = get_post_meta( $id, $field['name'], true );
1494
-
1495
- pods_no_conflict_off( 'post' );
1496
  }
1497
 
1498
- // Manually force DFV initialization. This is needed for attachments in "grid mode" in the
1499
- // media library. Note that this should only occur for attachment_fields_to_edit (see #4785)
1500
- $dfv_init_script = "<script>PodsDFV.init();</script>";
1501
 
1502
  $form_fields[ 'pods_meta_' . $field['name'] ] = array(
1503
  'label' => $field['label'],
1504
  'input' => 'html',
1505
- 'html' => PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id ) . $meta_nonce . $dfv_init_script,
1506
  'helps' => PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field )
1507
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1508
  }
1509
  }
1510
 
@@ -1546,25 +1565,28 @@ class PodsMeta {
1546
  $id = $post_id;
1547
  $pod = null;
1548
 
 
 
1549
  foreach ( $groups as $group ) {
1550
  if ( empty( $group['fields'] ) ) {
1551
  continue;
1552
  }
1553
 
1554
- if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
1555
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
1556
- self::$current_pod = pods( $group['pod']['name'], $id, true );
1557
- } elseif ( self::$current_pod->id() != $id ) {
1558
- self::$current_pod->fetch( $id );
1559
- }
1560
 
1561
- $pod = self::$current_pod;
 
1562
  }
1563
 
1564
  foreach ( $group['fields'] as $field ) {
 
 
 
1565
 
1566
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1567
- if ( ! pods_var( 'hidden', $field['options'], false ) ) {
1568
  continue;
1569
  }
1570
  }
@@ -1578,7 +1600,7 @@ class PodsMeta {
1578
  }
1579
 
1580
  if ( $pod ) {
1581
- $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false );
1582
 
1583
  // Block REST API saves, we handle those separately in PodsRESTHandlers
1584
  if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
@@ -1592,7 +1614,7 @@ class PodsMeta {
1592
  // Fix for Pods doing it's own sanitization
1593
  $data = pods_unslash( (array) $data );
1594
 
1595
- $pod->save( $data, null, null, array( 'podsmeta' => true ) );
1596
  } elseif ( ! empty( $id ) ) {
1597
  pods_no_conflict_on( 'post' );
1598
 
@@ -1684,56 +1706,54 @@ class PodsMeta {
1684
  continue;
1685
  }
1686
 
1687
- if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
1688
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
1689
- self::$current_pod = pods( $group['pod']['name'], $id, true );
1690
- } elseif ( self::$current_pod->id() != $id ) {
1691
- self::$current_pod->fetch( $id );
1692
- }
1693
 
1694
- $pod = self::$current_pod;
 
1695
  }
1696
 
1697
- foreach ( $group['fields'] as $field ) {
1698
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1699
- if ( pods_var( 'hidden', $field['options'], false ) ) {
1700
- $field['type'] = 'hidden';
1701
- } else {
1702
- continue;
1703
- }
1704
- } elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
1705
- $field['type'] = 'hidden';
1706
- }
 
1707
 
 
1708
  $value = '';
1709
 
 
 
1710
  if ( ! empty( $pod ) ) {
1711
- $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
 
 
1712
  }
1713
 
1714
- if ( ! is_object( $tag ) ) {
1715
- ?>
1716
- <div class="form-field pods-field" style="<?php echo esc_attr( 'hidden' == $field['type'] ? 'display:none;' : '' ); ?>">
1717
- <?php
1718
- echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field );
1719
- echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id );
1720
- echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field );
1721
- ?>
1722
- </div>
1723
- <?php
1724
- } else {
1725
- ?>
1726
- <tr class="form-field pods-field <?php echo esc_attr( 'pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ) ); ?>" style="<?php echo esc_attr( 'hidden' == $field['type'] ? 'display:none;' : '' ); ?>">
1727
- <th scope="row" valign="top"><?php echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field ); ?></th>
1728
- <td>
1729
- <?php
1730
- echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id );
1731
- echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field );
1732
- ?>
1733
- </td>
1734
- </tr>
1735
- <?php
1736
- }
1737
  }
1738
  }
1739
 
@@ -1775,11 +1795,17 @@ class PodsMeta {
1775
 
1776
  $has_fields = false;
1777
 
 
 
1778
  foreach ( $groups as $group ) {
1779
  if ( empty( $group['fields'] ) ) {
1780
  continue;
1781
  }
1782
 
 
 
 
 
1783
  if ( null === $term ) {
1784
  $term = get_term( $term_id, $taxonomy );
1785
 
@@ -1790,19 +1816,17 @@ class PodsMeta {
1790
 
1791
  $has_fields = true;
1792
 
1793
- if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
1794
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
1795
- self::$current_pod = pods( $group['pod']['name'], $id, true );
1796
- } elseif ( self::$current_pod->id() != $id ) {
1797
- self::$current_pod->fetch( $id );
1798
- }
1799
-
1800
- $pod = self::$current_pod;
1801
  }
1802
 
1803
  foreach ( $group['fields'] as $field ) {
1804
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1805
- if ( ! pods_var( 'hidden', $field['options'], false ) ) {
 
 
 
 
1806
  continue;
1807
  }
1808
  }
@@ -1816,7 +1840,7 @@ class PodsMeta {
1816
  }
1817
 
1818
  if ( $pod ) {
1819
- $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false );
1820
 
1821
  // Block REST API saves, we handle those separately in PodsRESTHandlers
1822
  if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
@@ -1842,7 +1866,7 @@ class PodsMeta {
1842
  // Fix for Pods doing it's own sanitization
1843
  $data = pods_unslash( (array) $data );
1844
 
1845
- $pod->save( $data, null, null, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) );
1846
  }
1847
 
1848
  pods_no_conflict_off( 'taxonomy' );
@@ -1890,7 +1914,10 @@ class PodsMeta {
1890
  $groups = $this->groups_get( 'user', 'user' );
1891
 
1892
  if ( is_object( $user_id ) ) {
 
1893
  $user_id = $user_id->ID;
 
 
1894
  }
1895
 
1896
  $id = $user_id;
@@ -1901,17 +1928,13 @@ class PodsMeta {
1901
  continue;
1902
  }
1903
 
1904
- if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
1905
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
1906
- self::$current_pod = pods( $group['pod']['name'], $id, true );
1907
- } elseif ( self::$current_pod->id() != $id ) {
1908
- self::$current_pod->fetch( $id );
1909
- }
1910
-
1911
- $pod = self::$current_pod;
1912
  }
1913
 
1914
- $hidden_fields = array();
 
 
1915
  ?>
1916
  <h3><?php echo $group['label']; ?></h3>
1917
 
@@ -1920,56 +1943,40 @@ class PodsMeta {
1920
  <table class="form-table pods-meta">
1921
  <tbody>
1922
  <?php
1923
- foreach ( $group['fields'] as $field ) {
1924
-
1925
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
1926
- if ( pods_var( 'hidden', $field['options'], false ) ) {
1927
- $field['type'] = 'hidden';
1928
- } else {
1929
- continue;
1930
- }
1931
- } elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
1932
- $field['type'] = 'hidden';
1933
- }
1934
 
 
1935
  $value = '';
1936
 
 
 
1937
  if ( ! empty( $pod ) ) {
1938
- $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
1939
  } elseif ( ! empty( $id ) ) {
1940
- pods_no_conflict_on( 'user' );
1941
-
1942
  $value = get_user_meta( $id, $field['name'], true );
1943
-
1944
- pods_no_conflict_off( 'user' );
1945
  }
1946
 
1947
- if ( 'hidden' == $field['type'] ) {
1948
- $hidden_fields[] = array(
1949
- 'field' => $field,
1950
- 'value' => $value
1951
- );
1952
- } else {
1953
- ?>
1954
- <tr class="form-field pods-field <?php echo esc_attr( 'pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ) ); ?>">
1955
- <th scope="row" valign="top"><?php echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field ); ?></th>
1956
- <td>
1957
- <?php echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id ); ?>
1958
- <?php echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field ); ?>
1959
- </td>
1960
- </tr>
1961
- <?php
1962
- }
1963
- }
1964
  ?>
1965
  </tbody>
1966
  </table>
1967
  <?php
1968
- foreach ( $hidden_fields as $hidden_field ) {
1969
- $field_data = $hidden_field['field'];
1970
-
1971
- echo PodsForm::field( 'pods_meta_' . $field_data['name'], $hidden_field['value'], 'hidden', $field_data );
1972
- }
1973
  }
1974
 
1975
  do_action( 'pods_meta_meta_user_post', $user_id );
@@ -1987,7 +1994,7 @@ class PodsMeta {
1987
 
1988
  $is_new_item = false;
1989
 
1990
- if ( 'user_register' == current_filter() ) {
1991
  $is_new_item = true;
1992
  }
1993
 
@@ -2003,19 +2010,12 @@ class PodsMeta {
2003
 
2004
  $groups = $this->groups_get( 'user', 'user' );
2005
 
2006
- $id = $user_id;
2007
-
2008
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod !== 'user' ) {
2009
- self::$current_pod = pods( 'user', $id, true );
2010
- } elseif ( is_object( self::$current_pod ) && (int) self::$current_pod->id() !== (int) $id ) {
2011
- self::$current_pod->fetch( $id );
2012
- }
2013
-
2014
- $pod = self::$current_pod;
2015
- $data = array();
2016
 
2017
  if ( $pod ) {
2018
- $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false );
2019
 
2020
  // Block REST API saves, we handle those separately in PodsRESTHandlers
2021
  if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
@@ -2024,14 +2024,24 @@ class PodsMeta {
2024
  }
2025
 
2026
  if ( false !== $nonced && ! empty( $groups ) ) {
 
 
2027
  foreach ( $groups as $group ) {
2028
  if ( empty( $group['fields'] ) ) {
2029
  continue;
2030
  }
2031
 
 
 
 
 
2032
  foreach ( $group['fields'] as $field ) {
2033
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
2034
- if ( ! pods_v( 'hidden', $field['options'], false ) ) {
 
 
 
 
2035
  continue;
2036
  }
2037
  }
@@ -2058,7 +2068,7 @@ class PodsMeta {
2058
  // Fix for Pods doing it's own sanitizing
2059
  $data = pods_unslash( (array) $data );
2060
 
2061
- $pod->save( $data, null, null, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) );
2062
  } elseif ( ! empty( $id ) ) {
2063
  foreach ( $data as $field => $value ) {
2064
  update_user_meta( $id, $field, $value );
@@ -2127,48 +2137,53 @@ class PodsMeta {
2127
  continue;
2128
  }
2129
 
2130
- if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
2131
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
2132
- self::$current_pod = pods( $group['pod']['name'], $id, true );
2133
- } elseif ( self::$current_pod->id() != $id ) {
2134
- self::$current_pod->fetch( $id );
2135
- }
2136
 
2137
- $pod = self::$current_pod;
 
2138
  }
2139
 
2140
- foreach ( $group['fields'] as $field ) {
2141
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
2142
- if ( pods_var( 'hidden', $field['options'], false ) ) {
2143
- $field['type'] = 'hidden';
2144
- } else {
2145
- continue;
2146
- }
2147
- } elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
2148
- $field['type'] = 'hidden';
2149
- }
2150
 
 
2151
  $value = '';
2152
 
 
 
2153
  if ( ! empty( $pod ) ) {
2154
- $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
2155
  } elseif ( ! empty( $id ) ) {
2156
- pods_no_conflict_on( 'comment' );
2157
-
2158
  $value = get_comment_meta( $id, $field['name'], true );
2159
-
2160
- pods_no_conflict_off( 'comment' );
2161
  }
2162
- ?>
2163
- <p class="comment-form-author comment-form-pods-meta-<?php echo esc_attr( $field['name'] ); ?> pods-field" style="<?php echo esc_attr( 'hidden' == $field['type'] ? 'display:none;' : '' ); ?>">
2164
- <?php
2165
- echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field );
2166
- echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id );
2167
- echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field );
2168
- ?>
2169
- </p>
2170
- <?php
2171
- }
 
 
 
 
 
 
 
 
2172
  }
2173
 
2174
  do_action( 'pods_meta_meta_comment_new_logged_in_post', $commenter, $user_identity );
@@ -2196,50 +2211,89 @@ class PodsMeta {
2196
  continue;
2197
  }
2198
 
2199
- if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
2200
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
2201
- self::$current_pod = pods( $group['pod']['name'], $id, true );
2202
- } elseif ( self::$current_pod->id() != $id ) {
2203
- self::$current_pod->fetch( $id );
2204
- }
2205
 
2206
- $pod = self::$current_pod;
 
2207
  }
2208
 
2209
- foreach ( $group['fields'] as $field ) {
 
 
 
 
 
 
 
 
 
2210
 
2211
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
2212
- if ( pods_var( 'hidden', $field['options'], false ) ) {
2213
- $field['type'] = 'hidden';
2214
- } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2215
  continue;
2216
  }
2217
- } elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
2218
  $field['type'] = 'hidden';
2219
  }
2220
 
2221
  $value = '';
2222
 
2223
- if ( ! empty( $pod ) ) {
2224
- $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
2225
- } elseif ( ! empty( $id ) ) {
2226
- pods_no_conflict_on( 'comment' );
 
2227
 
2228
- $value = get_comment_meta( $id, $field['name'], true );
 
2229
 
2230
- pods_no_conflict_off( 'comment' );
 
 
 
 
 
 
 
 
 
2231
  }
2232
 
2233
- ob_start();
2234
- ?>
2235
- <p class="comment-form-author comment-form-pods-meta-<?php echo esc_attr( $field['name'] ); ?> pods-field" style="<?php echo esc_attr( 'hidden' == $field['type'] ? 'display:none;' : '' ); ?>">
2236
- <?php
2237
- echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field );
2238
- echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id );
2239
- echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field );
2240
- ?>
2241
- </p>
2242
- <?php
2243
  $form_fields[ 'pods_meta_' . $field['name'] ] = ob_get_clean();
2244
  }
2245
  }
@@ -2277,11 +2331,15 @@ class PodsMeta {
2277
  continue;
2278
  }
2279
 
 
 
 
 
2280
  $field_found = false;
2281
 
2282
  foreach ( $group['fields'] as $field ) {
2283
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], null, null ) ) {
2284
- if ( pods_var( 'hidden', $field['options'], false ) ) {
2285
  $field_found = true;
2286
  break;
2287
  } else {
@@ -2325,57 +2383,40 @@ class PodsMeta {
2325
  $id = $comment->comment_ID;
2326
  }
2327
 
2328
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $metabox['args']['group']['pod']['name'] ) {
2329
- self::$current_pod = pods( $metabox['args']['group']['pod']['name'], $id, true );
2330
- } elseif ( self::$current_pod->id() != $id ) {
2331
- self::$current_pod->fetch( $id );
2332
- }
2333
-
2334
- $pod = self::$current_pod;
2335
 
2336
- foreach ( $metabox['args']['group']['fields'] as $field ) {
2337
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $metabox['args']['group']['fields'], $pod, $id ) ) {
2338
- if ( pods_var( 'hidden', $field['options'], false ) ) {
2339
- $field['type'] = 'hidden';
2340
- } else {
2341
- continue;
2342
- }
2343
- } elseif ( ! pods_has_permissions( $field['options'] ) && pods_var( 'hidden', $field['options'], false ) ) {
2344
- $field['type'] = 'hidden';
2345
- }
2346
 
 
2347
  $value = '';
2348
 
 
 
2349
  if ( ! empty( $pod ) ) {
2350
- $value = $pod->field( array( 'name' => $field['name'], 'in_form' => true ) );
 
 
2351
  }
2352
 
2353
- if ( 'hidden' == $field['type'] ) {
2354
- $hidden_fields[] = array(
2355
- 'field' => $field,
2356
- 'value' => $value
2357
- );
2358
- } else {
2359
- ?>
2360
- <tr class="form-field pods-field <?php echo esc_attr( 'pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true ) ); ?>">
2361
- <th scope="row" valign="top"><?php echo PodsForm::label( 'pods_meta_' . $field['name'], $field['label'], $field['help'], $field ); ?></th>
2362
- <td>
2363
- <?php echo PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id ); ?>
2364
- <?php echo PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field ); ?>
2365
- </td>
2366
- </tr>
2367
- <?php
2368
- }
2369
- }
2370
  ?>
2371
  </table>
2372
  <?php
2373
- foreach ( $hidden_fields as $hidden_field ) {
2374
- $field_data = $hidden_field['field'];
2375
-
2376
- echo PodsForm::field( 'pods_meta_' . $field_data['name'], $hidden_field['value'], 'hidden', $field_data );
2377
- }
2378
-
2379
  do_action( 'pods_meta_meta_comment_post', $comment, $metabox );
2380
  }
2381
 
@@ -2396,25 +2437,30 @@ class PodsMeta {
2396
  $pod = null;
2397
  $id = null;
2398
 
 
 
 
 
2399
  foreach ( $groups as $group ) {
2400
  if ( empty( $group['fields'] ) ) {
2401
  continue;
2402
  }
2403
 
2404
- if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
2405
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
2406
- self::$current_pod = pods( $group['pod']['name'], $id, true );
2407
- } elseif ( self::$current_pod->id() != $id ) {
2408
- self::$current_pod->fetch( $id );
2409
- }
2410
 
2411
- $pod = self::$current_pod;
 
2412
  }
2413
 
2414
  foreach ( $group['fields'] as $field ) {
 
 
 
2415
 
2416
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
2417
- if ( ! pods_var( 'hidden', $field['options'], false ) ) {
2418
  continue;
2419
  }
2420
  }
@@ -2425,7 +2471,7 @@ class PodsMeta {
2425
  $data[ $field['name'] ] = $_POST[ 'pods_meta_' . $field['name'] ];
2426
  }
2427
 
2428
- $validate = pods_api()->handle_field_validation( $data[ $field['name'] ], $field['name'], pods_api()->get_wp_object_fields( 'comment' ), $pod->fields(), $pod, array() );
2429
 
2430
  if ( false === $validate ) {
2431
  $validate = sprintf( __( 'There was an issue validating the field %s', 'pods' ), $field['label'] );
@@ -2460,24 +2506,28 @@ class PodsMeta {
2460
  $id = $comment_id;
2461
  $pod = null;
2462
 
 
 
2463
  foreach ( $groups as $group ) {
2464
  if ( empty( $group['fields'] ) ) {
2465
  continue;
2466
  }
2467
 
2468
- if ( null === $pod || ( is_object( $pod ) && $pod->id() != $id ) ) {
2469
- if ( ! is_object( self::$current_pod ) || self::$current_pod->pod != $group['pod']['name'] ) {
2470
- self::$current_pod = pods( $group['pod']['name'], $id, true );
2471
- } elseif ( self::$current_pod->id() != $id ) {
2472
- self::$current_pod->fetch( $id );
2473
- }
2474
 
2475
- $pod = self::$current_pod;
 
2476
  }
2477
 
2478
  foreach ( $group['fields'] as $field ) {
2479
- if ( false === PodsForm::permission( $field['type'], $field['name'], $field, $group['fields'], $pod, $id ) ) {
2480
- if ( ! pods_var( 'hidden', $field['options'], false ) ) {
 
 
 
 
2481
  continue;
2482
  }
2483
  }
@@ -2491,7 +2541,7 @@ class PodsMeta {
2491
  }
2492
 
2493
  if ( $pod ) {
2494
- $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data['options'], false );
2495
 
2496
  // Block REST API saves, we handle those separately in PodsRESTHandlers
2497
  if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
@@ -2505,7 +2555,7 @@ class PodsMeta {
2505
  // Fix for Pods doing it's own sanitization
2506
  $data = pods_unslash( (array) $data );
2507
 
2508
- $pod->save( $data, null, null, array( 'podsmeta' => true ) );
2509
  } elseif ( ! empty( $id ) ) {
2510
  pods_no_conflict_on( 'comment' );
2511
 
@@ -2545,13 +2595,70 @@ class PodsMeta {
2545
 
2546
  }
2547
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2548
  /**
2549
  * All *_*_meta filter handler aliases
2550
  *
2551
  * @return mixed
2552
  */
2553
  public function get_post_meta() {
2554
-
2555
  $args = func_get_args();
2556
 
2557
  array_unshift( $args, 'post_type' );
@@ -2569,7 +2676,6 @@ class PodsMeta {
2569
  * @return mixed
2570
  */
2571
  public function get_user_meta() {
2572
-
2573
  $args = func_get_args();
2574
 
2575
  array_unshift( $args, 'user' );
@@ -2587,7 +2693,6 @@ class PodsMeta {
2587
  * @return mixed
2588
  */
2589
  public function get_comment_meta() {
2590
-
2591
  $args = func_get_args();
2592
 
2593
  array_unshift( $args, 'comment' );
@@ -2605,7 +2710,6 @@ class PodsMeta {
2605
  * @return mixed
2606
  */
2607
  public function get_term_meta() {
2608
-
2609
  $args = func_get_args();
2610
 
2611
  array_unshift( $args, 'term' );
@@ -2625,9 +2729,12 @@ class PodsMeta {
2625
  * @return mixed
2626
  */
2627
  public function get_option() {
2628
-
2629
  $args = func_get_args();
2630
 
 
 
 
 
2631
  array_unshift( $args, 'settings' );
2632
 
2633
  $_null = apply_filters( 'pods_meta_get_option', null, $args );
@@ -2643,7 +2750,6 @@ class PodsMeta {
2643
  * @return mixed
2644
  */
2645
  public function add_post_meta() {
2646
-
2647
  $args = func_get_args();
2648
 
2649
  array_unshift( $args, 'post_type' );
@@ -2661,7 +2767,6 @@ class PodsMeta {
2661
  * @return mixed
2662
  */
2663
  public function add_user_meta() {
2664
-
2665
  $args = func_get_args();
2666
 
2667
  array_unshift( $args, 'user' );
@@ -2679,7 +2784,6 @@ class PodsMeta {
2679
  * @return mixed
2680
  */
2681
  public function add_comment_meta() {
2682
-
2683
  $args = func_get_args();
2684
 
2685
  array_unshift( $args, 'comment' );
@@ -2697,7 +2801,6 @@ class PodsMeta {
2697
  * @return mixed
2698
  */
2699
  public function add_term_meta() {
2700
-
2701
  $args = func_get_args();
2702
 
2703
  array_unshift( $args, 'term' );
@@ -2715,7 +2818,6 @@ class PodsMeta {
2715
  * @return mixed
2716
  */
2717
  public function add_option() {
2718
-
2719
  $args = func_get_args();
2720
 
2721
  array_unshift( $args, 'settings' );
@@ -2733,7 +2835,6 @@ class PodsMeta {
2733
  * @return mixed
2734
  */
2735
  public function update_post_meta() {
2736
-
2737
  $args = func_get_args();
2738
 
2739
  array_unshift( $args, 'post_type' );
@@ -2751,7 +2852,6 @@ class PodsMeta {
2751
  * @return mixed
2752
  */
2753
  public function update_user_meta() {
2754
-
2755
  $args = func_get_args();
2756
 
2757
  array_unshift( $args, 'user' );
@@ -2769,7 +2869,6 @@ class PodsMeta {
2769
  * @return mixed
2770
  */
2771
  public function update_comment_meta() {
2772
-
2773
  $args = func_get_args();
2774
 
2775
  array_unshift( $args, 'comment' );
@@ -2787,7 +2886,6 @@ class PodsMeta {
2787
  * @return mixed
2788
  */
2789
  public function update_term_meta() {
2790
-
2791
  $args = func_get_args();
2792
 
2793
  array_unshift( $args, 'term' );
@@ -2805,7 +2903,6 @@ class PodsMeta {
2805
  * @return mixed
2806
  */
2807
  public function update_option() {
2808
-
2809
  $args = func_get_args();
2810
 
2811
  array_unshift( $args, 'settings' );
@@ -2820,10 +2917,157 @@ class PodsMeta {
2820
  }
2821
 
2822
  /**
 
 
 
 
2823
  * @return mixed
2824
  */
2825
- public function delete_post_meta() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2826
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2827
  $args = func_get_args();
2828
 
2829
  array_unshift( $args, 'post_type' );
@@ -2841,7 +3085,6 @@ class PodsMeta {
2841
  * @return mixed
2842
  */
2843
  public function delete_user_meta() {
2844
-
2845
  $args = func_get_args();
2846
 
2847
  array_unshift( $args, 'user' );
@@ -2859,7 +3102,6 @@ class PodsMeta {
2859
  * @return mixed
2860
  */
2861
  public function delete_comment_meta() {
2862
-
2863
  $args = func_get_args();
2864
 
2865
  array_unshift( $args, 'comment' );
@@ -2877,7 +3119,6 @@ class PodsMeta {
2877
  * @return mixed
2878
  */
2879
  public function delete_term_meta() {
2880
-
2881
  $args = func_get_args();
2882
 
2883
  array_unshift( $args, 'term' );
@@ -2895,7 +3136,6 @@ class PodsMeta {
2895
  * @return mixed
2896
  */
2897
  public function delete_option() {
2898
-
2899
  $args = func_get_args();
2900
 
2901
  array_unshift( $args, 'settings' );
@@ -2909,6 +3149,122 @@ class PodsMeta {
2909
  return call_user_func_array( array( $this, 'delete_meta' ), $args );
2910
  }
2911
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2912
  /*
2913
  * The real meta functions
2914
  */
@@ -2920,7 +3276,6 @@ class PodsMeta {
2920
  * @return bool|mixed
2921
  */
2922
  public function get_object( $object_type, $object_id, $aux = '' ) {
2923
-
2924
  global $wpdb;
2925
 
2926
  if ( 'term' == $object_type ) {
@@ -3025,7 +3380,6 @@ class PodsMeta {
3025
  * @return array|bool|int|mixed|null|string|void
3026
  */
3027
  public function get_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $single = false ) {
3028
-
3029
  // Enforce boolean as it can be a string sometimes
3030
  $single = filter_var( $single, FILTER_VALIDATE_BOOLEAN );
3031
 
@@ -3037,6 +3391,14 @@ class PodsMeta {
3037
  $meta_type = 'term';
3038
  }
3039
 
 
 
 
 
 
 
 
 
3040
  if ( empty( $meta_key ) ) {
3041
  if ( ! defined( 'PODS_ALLOW_FULL_META' ) || ! PODS_ALLOW_FULL_META ) {
3042
  return $_null; // don't cover get_post_meta( $id )
@@ -3088,7 +3450,11 @@ class PodsMeta {
3088
 
3089
  $pod = self::$current_field_pod;
3090
 
3091
- $meta_keys = array( $meta_key );
 
 
 
 
3092
 
3093
  if ( empty( $meta_key ) ) {
3094
  $meta_keys = array_keys( $meta_cache );
@@ -3096,15 +3462,20 @@ class PodsMeta {
3096
 
3097
  $key_found = false;
3098
 
 
 
3099
  foreach ( $meta_keys as $meta_k ) {
3100
  if ( ! empty( $pod ) ) {
3101
  $first_meta_key = $meta_k;
 
3102
  if ( false !== strpos( $first_meta_key, '.' ) ) {
3103
  // Get the first meta key.
3104
  $first_meta_key = current( explode( '.', $first_meta_key ) );
3105
  }
3106
 
3107
- if ( isset( $pod->fields[ $first_meta_key ] ) ) {
 
 
3108
  $key_found = true;
3109
 
3110
  $meta_cache[ $meta_k ] = $pod->field( array(
@@ -3121,7 +3492,7 @@ class PodsMeta {
3121
  }
3122
  }
3123
 
3124
- if ( in_array( $pod->fields[ $first_meta_key ]['type'], PodsForm::tableless_field_types() ) && isset( $meta_cache[ '_pods_' . $first_meta_key ] ) ) {
3125
  unset( $meta_cache[ '_pods_' . $first_meta_key ] );
3126
  }
3127
  }
@@ -3175,11 +3546,18 @@ class PodsMeta {
3175
  * @return bool|int|null
3176
  */
3177
  public function add_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $unique = false ) {
3178
-
3179
  if ( pods_tableless() ) {
3180
  return $_null;
3181
  }
3182
 
 
 
 
 
 
 
 
 
3183
  $object = $this->get_object( $object_type, $object_id );
3184
 
3185
  if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) {
@@ -3223,38 +3601,47 @@ class PodsMeta {
3223
  * @return bool|int|null
3224
  */
3225
  public function update_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $prev_value = '' ) {
3226
-
3227
  if ( pods_tableless() ) {
3228
  return $_null;
3229
  }
3230
 
 
 
 
 
 
 
 
 
3231
  $object = $this->get_object( $object_type, $object_id );
3232
 
3233
  if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) {
3234
  return $_null;
3235
  }
3236
 
3237
- if ( ! is_object( self::$current_field_pod ) || self::$current_field_pod->pod != $object['name'] ) {
3238
  self::$current_field_pod = pods( $object['name'] );
3239
  }
3240
 
3241
  $pod = self::$current_field_pod;
3242
 
3243
- if ( ( isset( $pod->fields[ $meta_key ] ) || false !== strpos( $meta_key, '.' ) ) && $pod->row !== null ) {
 
3244
 
 
 
 
3245
  $key = $meta_key;
 
3246
  if ( false !== strpos( $meta_key, '.' ) ) {
3247
  $key = current( explode( '.', $meta_key ) );
3248
  }
3249
 
3250
- $pod->row[ $meta_key ] = $meta_value;
3251
 
3252
- if ( isset( $pod->fields[ $key ] ) ) {
3253
- if ( in_array( $pod->fields[ $key ]['type'], PodsForm::tableless_field_types() ) && isset( $meta_cache[ '_pods_' . $key ] ) ) {
3254
- unset( $meta_cache[ '_pods_' . $key ] );
3255
- }
3256
  }
3257
-
3258
  }
3259
 
3260
  $pod->save( $meta_key, $meta_value, $object_id, array( 'podsmeta_direct' => true, 'error_mode' => 'false' ) );
@@ -3262,6 +3649,38 @@ class PodsMeta {
3262
  return $object_id;
3263
  }
3264
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3265
  /**
3266
  * @param $object_type
3267
  * @param null $_null
@@ -3273,11 +3692,18 @@ class PodsMeta {
3273
  * @return null
3274
  */
3275
  public function delete_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $delete_all = false ) {
3276
-
3277
  if ( pods_tableless() ) {
3278
  return $_null;
3279
  }
3280
 
 
 
 
 
 
 
 
 
3281
  $object = $this->get_object( $object_type, $object_id );
3282
 
3283
  if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) {
@@ -3311,13 +3737,42 @@ class PodsMeta {
3311
  return $_null;
3312
  }
3313
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3314
  /**
3315
  * @param $id
3316
  *
3317
  * @return bool|void
3318
  */
3319
  public function delete_post( $id ) {
3320
-
3321
  $post = get_post( $id );
3322
 
3323
  if ( empty( $post ) ) {
@@ -3334,7 +3789,6 @@ class PodsMeta {
3334
  * @param $id
3335
  */
3336
  public function delete_taxonomy( $id ) {
3337
-
3338
  /**
3339
  * @var $wpdb WPDB
3340
  */
@@ -3366,7 +3820,6 @@ class PodsMeta {
3366
  */
3367
  public static function split_shared_term( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) {
3368
 
3369
- require_once( PODS_DIR . 'classes/PodsTermSplitting.php' );
3370
 
3371
  $term_splitting = new Pods_Term_Splitting( $term_id, $new_term_id, $taxonomy );
3372
  $term_splitting->split_shared_term();
@@ -3422,7 +3875,8 @@ class PodsMeta {
3422
  $params = array(
3423
  'pod' => pods_var( 'name', $object ),
3424
  'pod_id' => pods_var( 'id', $object ),
3425
- 'id' => $id
 
3426
  );
3427
 
3428
  return pods_api()->delete_pod_item( $params, false );
1
  <?php
2
 
3
+ use Pods\Whatsit\Pod;
4
+
5
  /**
6
  * @package Pods
7
  */
95
  * @since 2.3.5
96
  */
97
  public static function init() {
 
98
  if ( ! is_object( self::$instance ) ) {
99
+ self::$instance = new self();
100
  }
101
 
102
  return self::$instance;
115
  * @return \PodsMeta
116
  */
117
  public function core() {
118
+ $this->cache_pods( false );
119
 
120
+ $core_loader_objects = pods_transient_get( 'pods_core_loader_objects' );
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
+ $original_loader_objects = $core_loader_objects;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
+ if ( ! is_array( $core_loader_objects ) ) {
125
+ $core_loader_objects = [];
 
 
 
126
  }
127
 
128
+ if ( ! isset( $core_loader_objects['taxonomies'] ) ) {
129
+ $core_loader_objects['taxonomies'] = [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
+ if ( ! empty( self::$taxonomies ) ) {
132
+ foreach ( self::$taxonomies as $taxonomy ) {
133
+ if ( $taxonomy instanceof Pod ) {
134
+ if ( ! $taxonomy->has_fields() ) {
135
+ continue;
136
+ }
137
+ } elseif ( empty( $taxonomy['fields'] ) ) {
138
+ continue;
139
+ }
140
 
141
+ $taxonomy_name = $taxonomy['name'];
 
 
 
 
142
 
143
+ if ( ! empty( $taxonomy['object'] ) ) {
144
+ $taxonomy_name = $taxonomy['object'];
 
 
145
  }
146
 
147
+ $core_loader_objects['taxonomies'][] = $taxonomy_name;
 
 
 
 
148
  }
149
  }
150
  }
151
 
152
+ if ( ! isset( $core_loader_objects['media'] ) ) {
153
+ $core_loader_objects['media'] = ! empty( self::$media );
154
+ }
 
 
 
 
 
 
 
 
 
 
 
155
 
156
+ if ( ! isset( $core_loader_objects['user'] ) ) {
157
+ $core_loader_objects['user'] = ! empty( self::$user );
158
+ }
159
 
160
+ if ( ! isset( $core_loader_objects['comment'] ) ) {
161
+ $core_loader_objects['comment'] = ! empty( self::$comment );
162
+ }
163
 
164
+ if ( ! isset( $core_loader_objects['settings'] ) ) {
165
+ $core_loader_objects['settings'] = [];
 
166
 
167
+ if ( ! empty( self::$settings ) ) {
168
+ foreach ( self::$settings as $setting_pod ) {
169
+ if ( $setting_pod instanceof Pod ) {
170
+ if ( ! $setting_pod->has_fields() ) {
171
+ continue;
172
+ }
173
+ } elseif ( empty( $setting_pod['fields'] ) ) {
174
+ continue;
175
  }
176
 
177
+ $core_loader_objects['settings'][] = $setting_pod['name'];
 
 
 
 
178
  }
179
  }
180
  }
181
 
182
+ if ( $original_loader_objects !== $core_loader_objects ) {
183
+ pods_transient_set( 'pods_core_loader_objects', $core_loader_objects, WEEK_IN_SECONDS );
184
+ }
 
 
 
 
 
 
 
185
 
186
+ // Handle Post Type Editor (needed for Pods core).
187
+ pods_no_conflict_off( 'post', null, true );
 
 
 
188
 
189
+ // Handle Taxonomies.
190
+ if ( ! empty( $core_loader_objects['taxonomies'] ) ) {
191
+ foreach ( $core_loader_objects['taxonomies'] as $taxonomy_name ) {
192
+ pods_no_conflict_off( 'taxonomy', $taxonomy_name, true );
 
193
  }
194
+ } else {
195
+ // At least add the hook to delete.
196
+ add_action( 'delete_term_taxonomy', [ $this, 'delete_taxonomy' ], 10, 1 );
197
  }
198
 
199
+ if ( $core_loader_objects['media'] ) {
200
+ pods_no_conflict_off( 'media', null, true );
201
+ } else {
202
+ // At least add the hook to delete.
203
+ add_action( 'delete_attachment', [ $this, 'delete_media' ], 10, 1 );
204
+ }
205
 
206
+ if ( $core_loader_objects['user'] ) {
207
+ pods_no_conflict_off( 'user', null, true );
208
+ } else {
209
+ // At least add the hook to delete.
210
+ add_action( 'delete_user', [ $this, 'delete_user' ], 10, 1 );
211
+ }
 
 
 
212
 
213
+ if ( $core_loader_objects['comment'] ) {
214
+ pods_no_conflict_off( 'comment', null, true );
215
+ } else {
216
+ // At least add the hook to delete.
217
+ add_action( 'delete_comment', [ $this, 'delete_comment' ], 10, 1 );
218
+ }
219
 
220
+ if ( ! empty( $core_loader_objects['settings'] ) ) {
221
+ foreach ( $core_loader_objects['settings'] as $setting_pod_name ) {
222
+ pods_no_conflict_off( 'settings', $setting_pod_name, true );
 
 
223
  }
224
  }
225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  if ( is_admin() ) {
227
  $this->integrations();
228
  }
229
 
230
  add_action( 'init', array( $this, 'enqueue' ), 9 );
231
 
232
+ do_action( 'pods_meta_init', $this );
 
 
 
 
233
 
234
  return $this;
235
  }
241
 
242
  foreach ( self::$queue as $type => $objects ) {
243
  foreach ( $objects as $pod_name => $pod ) {
244
+ pods_transient_set( 'pods_pod_' . $pod_name, $pod, WEEK_IN_SECONDS );
245
  }
246
 
247
  self::${$type} = array_merge( self::${$type}, $objects );
249
  }
250
 
251
  /**
252
+ * Cache the Pods list.
253
+ *
254
+ * This is helpful to run to cache the Pods after Polylang has loaded.
255
  */
256
+ public function cache_pods( $refresh = true ) {
257
+ $api = pods_api();
258
+
259
+ self::$advanced_content_types = $api->load_pods( [
260
+ 'type' => 'pod',
261
+ 'refresh' => $refresh,
262
+ ] );
263
+
264
+ self::$post_types = $api->load_pods( [
265
+ 'type' => 'post_type',
266
+ 'refresh' => $refresh,
267
+ ] );
268
+
269
+ self::$taxonomies = $api->load_pods( [
270
+ 'type' => 'taxonomy',
271
+ 'refresh' => $refresh,
272
+ ] );
273
+
274
+ self::$media = $api->load_pods( [
275
+ 'type' => 'media',
276
+ 'refresh' => $refresh,
277
+ ] );
278
 
279
+ self::$user = $api->load_pods( [
280
+ 'type' => 'user',
281
+ 'refresh' => $refresh,
282
+ ] );
283
+
284
+ self::$comment = $api->load_pods( [
285
+ 'type' => 'comment',
286
+ 'refresh' => $refresh,
287
+ ] );
288
+
289
+ self::$settings = $api->load_pods( [
290
+ 'type' => 'settings',
291
+ 'refresh' => $refresh,
292
+ ] );
293
  }
294
 
295
  /**
557
  }
558
  }
559
 
560
+ $field = ( 'cpachidden' === substr( $obj->get_option( 'field' ), 0, 10 ) ) ? str_replace( 'cpachidden', '', $obj->get_option( 'field' ) ) : $obj->get_option( 'field' );
561
  $field_type = $obj->get_option( 'field_type' );
562
 
563
  if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] !== $object ) {
597
  $meta = $podterms->field( $field );
598
  }
599
 
600
+ $meta = PodsForm::field_method( $pod['fields'][ $field ]['type'], 'ui', $id, $meta, $field, $pod['fields'][ $field ], $pod['fields'], $pod );
601
  }
602
 
603
  return $meta;
620
  * @return mixed|void
621
  */
622
  public function group_add( $pod, $label, $fields, $context = 'normal', $priority = 'default' ) {
 
623
  if ( is_array( $pod ) && ! empty( $pod ) && ! isset( $pod['name'] ) ) {
624
  foreach ( $pod as $p ) {
625
  $this->group_add( $p, $label, $fields, $context, $priority );
701
  'type' => 'text'
702
  );
703
 
704
+ $is_field_object = $field instanceof Field;
705
+
706
+ if ( ! is_array( $field ) && ! $is_field_object ) {
707
  $name = trim( $field );
708
 
709
  $field = array(
712
  );
713
  }
714
 
715
+ $field = pods_config_merge_data( $defaults, $field );
716
 
717
  $field['name'] = trim( $field['name'] );
718
 
719
  if ( isset( $pod['fields'] ) && isset( $pod['fields'][ $field['name'] ] ) ) {
720
+ $field = pods_config_merge_data( $field, $pod['fields'][ $field['name'] ] );
721
  }
722
 
723
  $_fields[ $k ] = $field;
746
  // Hook it up!
747
  if ( 'post_type' == $pod['type'] ) {
748
  if ( ! has_action( 'add_meta_boxes', array( $this, 'meta_post_add' ) ) ) {
749
+ pods_no_conflict_off( $pod['type'], $pod['object'], true );
750
  }
 
 
 
751
  } elseif ( 'taxonomy' == $pod['type'] ) {
752
+ if ( ! has_action( $pod['object'] . '_edit_form_fields', array( $this, 'meta_taxonomy' ) ) ) {
753
+ pods_no_conflict_off( $pod['type'], $pod['object'], true );
 
 
 
 
 
 
754
  }
755
  } elseif ( 'media' == $pod['type'] ) {
756
+ if ( ! has_filter( 'wp_update_attachment_metadata', array( $this, 'save_media' ) ) ) {
757
+ pods_no_conflict_off( $pod['type'], null, true );
 
 
 
 
 
 
758
  }
759
  } elseif ( 'user' == $pod['type'] ) {
760
  if ( ! has_action( 'show_user_profile', array( $this, 'meta_user' ) ) ) {
761
+ pods_no_conflict_off( $pod['type'], null, true );
 
 
 
762
  }
763
  } elseif ( 'comment' == $pod['type'] ) {
764
+ if ( ! has_action( 'comment_form_logged_in_after', array( $this, 'meta_comment_new_logged_in' ) ) ) {
765
+ pods_no_conflict_off( $pod['type'], null, true );
 
 
 
 
766
  }
767
  }
768
  }
791
  $object = self::$comment;
792
  }
793
 
794
+ if ( 'pod' !== $type && ! empty( $object ) && is_array( $object ) && isset( $object[ $name ] ) ) {
795
  $pod = $object[ $name ];
796
  } else {
797
  if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] != $name ) {
811
  'type' => 'post_type'
812
  );
813
 
814
+ $pod = pods_config_merge_data( $defaults, $pod );
815
 
816
  if ( empty( $pod['name'] ) ) {
817
  $pod['name'] = $pod['object'];
827
  }
828
 
829
  /**
830
+ * Get groups of fields for the content type.
 
 
831
  *
832
+ * @param $type Content type.
833
+ * @param $name Content name.
834
+ * @param $default_fields List of default fields to include.
835
+ *
836
+ * @return array List of groups and their fields.
837
  */
838
  public function groups_get( $type, $name, $default_fields = null ) {
839
+ static $groups_cache = [];
 
840
 
841
  if ( isset( $groups_cache[ $type . '/' . $name ] ) ) {
842
  return $groups_cache[ $type . '/' . $name ];
851
 
852
  do_action( 'pods_meta_groups', $type, $name );
853
 
854
+ $pod = [];
855
+ $fields = [];
856
 
857
  $object = self::$post_types;
858
 
869
  }
870
 
871
  if ( ! empty( $object ) && is_array( $object ) && isset( $object[ $name ] ) ) {
872
+ $pod = $object[ $name ];
873
+ $fields = $pod['fields'];
874
  } else {
875
+ if ( empty( self::$current_pod_data ) || ! is_object( self::$current_pod_data ) || self::$current_pod_data['name'] !== $name ) {
876
+ self::$current_pod_data = pods_api()->load_pod( [ 'name' => $name ], false );
877
  }
878
 
879
  $pod = self::$current_pod_data;
880
 
881
+ if ( ! empty( $pod ) && empty( $pod['groups'] ) ) {
882
  $fields = $pod['fields'];
883
  }
884
  }
887
  $fields = $default_fields;
888
  }
889
 
890
+ $defaults = [
891
+ 'name' => $name,
892
  'object' => 'post',
893
+ 'type' => 'post_type',
894
+ ];
895
 
896
+ if ( is_array( $pod ) ) {
897
+ $pod = array_merge( $defaults, $pod );
898
 
899
+ if ( empty( $pod['name'] ) ) {
900
+ $pod['name'] = $pod['object'];
901
+ } elseif ( empty( $pod['object'] ) ) {
902
+ $pod['object'] = $pod['name'];
903
+ }
904
  }
905
 
906
+ if ( $pod && $pod['type'] !== $type ) {
907
+ $groups_cache[ $type . '/' . $name ] = [];
908
 
909
  return $groups_cache[ $type . '/' . $name ];
910
  }
911
 
912
+ /**
913
+ * Filter the title of the Pods Metabox used in the post editor.
914
+ *
915
+ * @since unknown
916
+ *
917
+ * @param string $title The title to use, default is 'More Fields'.
918
+ * @param obj|Pod $pod Current Pods Object.
919
+ * @param array $fields Array of fields that will go in the metabox.
920
+ * @param string $type The type of Pod.
921
+ * @param string $name Name of the Pod.
922
+ */
923
+ $title = apply_filters( 'pods_meta_default_box_title', __( 'More Fields', 'pods' ), $pod, $fields, $type, $name );
924
+
925
+ $groups = [];
926
+
927
+ $has_custom_groups = ! empty( self::$groups[ $type ][ $name ] );
928
+
929
+ if ( ! empty( $pod['groups'] ) ) {
930
+ foreach ( $pod['groups'] as $group ) {
931
+ if ( empty( $group['fields'] ) ) {
932
+ continue;
933
+ }
934
+
935
+ $groups[] = [
936
+ 'pod' => $pod,
937
+ 'label' => $group['label'],
938
+ 'fields' => $group['fields'],
939
+ 'context' => pods_v( 'meta_box_context', $group, 'normal', true ),
940
+ 'priority' => pods_v( 'meta_box_priority', $group, 'default', true ),
941
+ ];
942
+ }
943
+
944
+ if ( $has_custom_groups ) {
945
+ $groups = array_merge( $groups, self::$groups[ $type ][ $name ] );
946
+ }
947
+ } elseif ( $has_custom_groups ) {
948
+ $groups = self::$groups[ $type ][ $name ];
949
+ }
950
+
951
+ if ( empty( $groups ) && ! empty( $fields ) ) {
952
+ $groups[] = [
953
  'pod' => $pod,
954
+ 'label' => $title,
 
 
 
 
 
 
 
 
 
 
 
 
 
955
  'fields' => $fields,
956
  'context' => 'normal',
957
+ 'priority' => 'default',
958
+ ];
 
 
 
 
959
  }
960
 
961
  /**
962
  * Filter the array of field groups
963
  *
964
+ * @since 2.6.6
965
+ *
966
  * @param string $type The type of Pod
967
  * @param string $name Name of the Pod
968
  *
969
+ * @param array $groups Array of groups
970
  */
971
  $groups = apply_filters( 'pods_meta_groups_get', $groups, $type, $name );
972
 
997
  continue;
998
  }
999
 
1000
+ if ( ! pods_permission( $group ) ) {
1001
+ continue;
1002
+ }
1003
+
1004
  $field_found = false;
1005
  $group_hidden = true;
1006
 
1007
  foreach ( $group['fields'] as $field ) {
1008
+ if ( pods_permission( $field ) ) {
1009
  $field_found = true;
1010
  }
1011
+ if ( ! isset( $field['hidden'] ) || 1 !== (int) $field['hidden'] ) {
1012
  $group_hidden = false;
1013
  }
1014
  }
1037
  }
1038
  }
1039
 
1040
+ /**
1041
+ * Handle overriding the "Add title" placeholder.
1042
+ *
1043
+ * @since 2.8.0
1044
+ *
1045
+ * @param string $placeholder The "Add title" placeholder.
1046
+ * @param WP_Post $post The post object.
1047
+ *
1048
+ * @return string The "Add title" placeholder.
1049
+ */
1050
+ public function meta_post_enter_title_here( $placeholder, $post ) {
1051
+ $pod = $this->maybe_set_up_pod( $post->post_type, null, 'post_type' );
1052
+
1053
+ // Check if we have a valid pod.
1054
+ if ( ! $pod ) {
1055
+ return $placeholder;
1056
+ }
1057
+
1058
+ return pods_v( 'placeholder_enter_title_here', $pod->pod_data, $placeholder, true );
1059
+ }
1060
+
1061
+ /**
1062
+ * Handle overriding the number of revisions to keep.
1063
+ *
1064
+ * @since 2.8.0
1065
+ *
1066
+ * @param int $num Number of revisions to store.
1067
+ * @param WP_Post $post The post object.
1068
+ *
1069
+ * @return int The number of revisions to keep.
1070
+ */
1071
+ public function meta_post_revisions_to_keep( $num, $post ) {
1072
+ $pod = $this->maybe_set_up_pod( $post->post_type, null, 'post_type' );
1073
+
1074
+ // Check if we have a valid pod.
1075
+ if ( ! $pod ) {
1076
+ return $num;
1077
+ }
1078
+
1079
+ $revisions_to_keep_limit = pods_v( 'revisions_to_keep_limit', $pod->pod_data );
1080
+
1081
+ // Check if we have a valid limit.
1082
+ if ( ! is_numeric( $revisions_to_keep_limit ) ) {
1083
+ return $num;
1084
+ }
1085
+
1086
+ return (int) $revisions_to_keep_limit;
1087
+ }
1088
+
1089
  /**
1090
  *
1091
  * Called by 'post_edit_form_tag' action to include the classes in the <form> tag
1092
  *
1093
  */
1094
  public function add_class_submittable() {
 
1095
  echo ' class="pods-submittable pods-form"';
1096
  }
1097
 
1098
+ /**
1099
+ * Maybe set up the Pods object or return the current one.
1100
+ *
1101
+ * @since 2.8.0
1102
+ *
1103
+ * @param string $pod_name The pod name.
1104
+ * @param int|null $id The item ID or null to not check ID.
1105
+ * @param string|null $pod_type The pod type if we need to be strict on the check.
1106
+ *
1107
+ * @return bool|Pods The Pods object or false if the pod is invalid.
1108
+ */
1109
+ public function maybe_set_up_pod( $pod_name, $id = null, $pod_type = null ) {
1110
+ // Check if we have a pod object set up for this pod name yet.
1111
+ if ( ! is_object( self::$current_pod ) || self::$current_pod->pod !== $pod_name ) {
1112
+ self::$current_pod = pods( $pod_name, null, true );
1113
+ }
1114
+
1115
+ // Check if we need to strictly check the pod type.
1116
+ if ( self::$current_pod instanceof Pods && null !== $pod_type && self::$current_pod->pod_data['type'] !== $pod_type ) {
1117
+ self::$current_pod = false;
1118
+ }
1119
+
1120
+ // Check if we have a valid pod and if we need to fetch the new ID.
1121
+ if ( self::$current_pod instanceof Pods && null !== $id && (int) self::$current_pod->id() !== (int) $id ) {
1122
+ self::$current_pod->fetch( $id );
1123
+ }
1124
+
1125
+ return self::$current_pod;
1126
+ }
1127
+
1128
  /**
1129
  * @param $post
1130
  * @param $metabox
1142
 
1143
  do_action( 'pods_meta_meta_post', $post );
1144
 
 
 
1145
  $id = null;
1146
 
1147
  if ( is_object( $post ) ) {
1148
  $id = $post->ID;
1149
  }
1150
 
1151
+ $pod = $this->maybe_set_up_pod( $metabox['args']['group']['pod']['name'], $id, 'post_type' );
 
 
 
 
 
 
1152
 
1153
  $fields = $metabox['args']['group']['fields'];
1154
 
1166
  $fields = apply_filters( 'pods_meta_post_fields', $fields, $id, $post, $metabox, $pod );
1167
 
1168
  if ( empty( $fields ) ) {
1169
+ esc_html_e( 'There are no fields to display', 'pods' );
1170
 
1171
  return;
1172
  }
1173
+
1174
+ echo PodsForm::field( 'pods_meta', wp_create_nonce( 'pods_meta_' . $pod_type ), 'hidden' );
1175
  ?>
1176
  <table class="form-table pods-metabox pods-admin pods-dependency">
1177
  <?php
1178
+ $field_prefix = 'pods_meta_';
1179
+ $field_row_classes = 'form-field pods-field-input';
1180
+ $th_scope = 'row';
1181
 
1182
+ $value_callback = static function( $field_name, $id, $field, $pod ) {
1183
+ pods_no_conflict_on( 'post' );
 
 
 
 
 
 
 
 
1184
 
1185
  $value = null;
1186
 
1187
  if ( ! empty( $pod ) ) {
1188
+ $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true, 'single' => true ] );
 
 
 
 
1189
  } elseif ( ! empty( $id ) ) {
1190
  $value = get_post_meta( $id, $field['name'], true );
1191
  }
1199
  }
1200
  }
1201
 
1202
+ pods_no_conflict_off( 'post' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1203
 
1204
+ return $value;
1205
+ };
1206
 
1207
+ $pre_callback = static function( $field_name, $id, $field, $pod ) use ( $post ) {
1208
+ do_action( "pods_meta_meta_post_{$field_name}", $post, $field, $pod );
1209
+ do_action( "pods_meta_meta_post_pre_row_{$field_name}", $post, $field, $pod );
1210
+ };
1211
 
1212
+ $post_callback = static function( $field_name, $id, $field, $pod ) use ( $post ) {
1213
+ do_action( "pods_meta_meta_post_{$field_name}_post", $post, $field, $pod );
1214
+ do_action( "pods_meta_meta_post_post_row_{$field_name}", $post, $field, $pod );
1215
+ };
1216
+
1217
+ pods_view( PODS_DIR . 'ui/forms/table-rows.php', compact( array_keys( get_defined_vars() ) ) );
1218
+ ?>
1219
+ </table>
1220
+
1221
+ <?php do_action( 'pods_meta_meta_post_post', $post ); ?>
1222
 
1223
  <script type="text/javascript">
1224
  jQuery( function ( $ ) {
 
1225
  $( document ).Pods( 'submit_meta' );
 
1226
  } );
1227
  </script>
1228
  <?php
1286
  $blacklisted_types = array(
1287
  'revision',
1288
  '_pods_pod',
1289
+ '_pods_field',
1290
+ '_pods_group',
1291
  );
1292
 
1293
  $blacklisted_types = apply_filters( 'pods_meta_save_post_blacklist_types', $blacklisted_types, $post_id, $post );
1295
  // @todo Figure out how to hook into autosave for saving meta
1296
 
1297
  // Block Autosave and Revisions
1298
+ if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || in_array( $post->post_type, $blacklisted_types, true ) ) {
1299
  return;
1300
  }
1301
 
1317
 
1318
  $blacklisted_status = apply_filters( 'pods_meta_save_post_blacklist_status', $blacklisted_status, $post_id, $post );
1319
 
1320
+ if ( in_array( $post->post_status, $blacklisted_status, true ) ) {
1321
  return;
1322
  }
1323
 
1324
  $groups = $this->groups_get( 'post_type', $post->post_type );
1325
 
1326
+ $id = $post_id;
1327
+ $pod = $this->maybe_set_up_pod( $post->post_type, $id, 'post_type' );
1328
+ $data = [];
 
 
 
 
 
 
 
1329
 
1330
  if ( $pod ) {
1331
+ $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data, false );
1332
 
1333
  // Block REST API saves, we handle those separately in PodsRESTHandlers
1334
  if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
1338
  // The following code will run for all post_types (not just Pods)
1339
 
1340
  if ( false !== $nonced && ! empty( $groups ) ) {
1341
+ $layout_field_types = PodsForm::layout_field_types();
1342
+
1343
  foreach ( $groups as $group ) {
1344
  if ( empty( $group['fields'] ) ) {
1345
  continue;
1346
  }
1347
 
1348
+ if ( ! pods_permission( $group ) ) {
1349
+ continue;
1350
+ }
1351
+
1352
  foreach ( $group['fields'] as $field ) {
1353
+ if ( in_array( $field['type'], $layout_field_types, true ) ) {
1354
+ continue;
1355
+ }
1356
+
1357
+ if ( ! pods_permission( $field ) ) {
1358
+ if ( ! pods_v( 'hidden', $field, false ) ) {
1359
  continue;
1360
  }
1361
  }
1384
  // Fix for Pods doing it's own sanitizing.
1385
  $data = pods_unslash( (array) $data );
1386
 
1387
+ $pod->save( $data, null, $id, array(
1388
+ 'is_new_item' => $is_new_item,
1389
+ 'podsmeta' => true
1390
+ ) );
1391
  } elseif ( ! empty( $id ) ) {
1392
  foreach ( $data as $field => $value ) {
1393
  update_post_meta( $id, $field, $value );
1464
  continue;
1465
  }
1466
 
1467
+ if ( ! pods_permission( $group ) ) {
1468
+ continue;
1469
+ }
 
 
 
1470
 
1471
+ if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) {
1472
+ $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'media' );
1473
  }
1474
 
1475
+ $did_init = false;
1476
+
1477
  foreach ( $group['fields'] as $field ) {
1478
+ if ( ! pods_permission( $field ) ) {
1479
+ if ( ! pods_var( 'hidden', $field, false ) ) {
1480
  continue;
1481
  }
1482
  }
1483
 
1484
+ // Skip heavy fields.
1485
+ if ( in_array( $field['type'], [ 'wysiwyg', 'code', 'file', 'oembed' ], true ) ) {
1486
+ continue;
1487
+ }
1488
+
1489
  $value = '';
1490
 
1491
+ pods_no_conflict_on( 'post' );
1492
+
1493
  if ( ! empty( $pod ) ) {
1494
+ $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] );
1495
  } elseif ( ! empty( $id ) ) {
 
 
1496
  $value = get_post_meta( $id, $field['name'], true );
 
 
1497
  }
1498
 
1499
+ pods_no_conflict_off( 'post' );
 
 
1500
 
1501
  $form_fields[ 'pods_meta_' . $field['name'] ] = array(
1502
  'label' => $field['label'],
1503
  'input' => 'html',
1504
+ 'html' => PodsForm::field( 'pods_meta_' . $field['name'], $value, $field['type'], $field, $pod, $id ),
1505
  'helps' => PodsForm::comment( 'pods_meta_' . $field['name'], $field['description'], $field )
1506
  );
1507
+
1508
+ // Manually force DFV initialization. This is needed for attachments in "grid mode" in the
1509
+ // media library. Note that this should only occur for attachment_fields_to_edit (see #4785)
1510
+ $dfv_init_script = '<script>window.PodsDFV.init(\'script[data-pod="' . $group['pod']['name'] . '"]\');</script>';
1511
+
1512
+ // Only output nonce/init script on the very first field of the first group we have.
1513
+ if ( ! $did_init ) {
1514
+ $form_fields[ 'pods_meta_' . $field['name'] ]['html'] .= $meta_nonce;
1515
+ $form_fields[ 'pods_meta_' . $field['name'] ]['html'] .= $dfv_init_script;
1516
+
1517
+ $did_init = true;
1518
+ }
1519
+
1520
+ if ( 'heading' === $field['type'] ) {
1521
+ $form_fields[ 'pods_meta_' . $field['name'] ]['html'] = $form_fields[ 'pods_meta_' . $field['name'] ]['label'];
1522
+ $form_fields[ 'pods_meta_' . $field['name'] ]['label'] = '';
1523
+ } elseif ( 'html' === $field['type'] ) {
1524
+ $form_fields[ 'pods_meta_' . $field['name'] ]['label'] = '';
1525
+ $form_fields[ 'pods_meta_' . $field['name'] ]['helps'] = '';
1526
+ }
1527
  }
1528
  }
1529
 
1565
  $id = $post_id;
1566
  $pod = null;
1567
 
1568
+ $layout_field_types = PodsForm::layout_field_types();
1569
+
1570
  foreach ( $groups as $group ) {
1571
  if ( empty( $group['fields'] ) ) {
1572
  continue;
1573
  }
1574
 
1575
+ if ( ! pods_permission( $group ) ) {
1576
+ continue;
1577
+ }
 
 
 
1578
 
1579
+ if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) {
1580
+ $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'media' );
1581
  }
1582
 
1583
  foreach ( $group['fields'] as $field ) {
1584
+ if ( in_array( $field['type'], $layout_field_types, true ) ) {
1585
+ continue;
1586
+ }
1587
 
1588
+ if ( ! pods_permission( $field ) ) {
1589
+ if ( ! pods_var( 'hidden', $field, false ) ) {
1590
  continue;
1591
  }
1592
  }
1600
  }
1601
 
1602
  if ( $pod ) {
1603
+ $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data, false );
1604
 
1605
  // Block REST API saves, we handle those separately in PodsRESTHandlers
1606
  if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
1614
  // Fix for Pods doing it's own sanitization
1615
  $data = pods_unslash( (array) $data );
1616
 
1617
+ $pod->save( $data, null, $id, array( 'podsmeta' => true ) );
1618
  } elseif ( ! empty( $id ) ) {
1619
  pods_no_conflict_on( 'post' );
1620
 
1706
  continue;
1707
  }
1708
 
1709
+ if ( ! pods_permission( $group ) ) {
1710
+ continue;
1711
+ }
 
 
 
1712
 
1713
+ if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) {
1714
+ $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'taxonomy' );
1715
  }
1716
 
1717
+ $fields = array_merge( [
1718
+ '_group_title' => [
1719
+ 'name' => '_group_title',
1720
+ 'label' => $group['label'],
1721
+ 'type' => 'heading',
1722
+ 'heading_tag' => 'h2',
1723
+ ],
1724
+ ], $group['fields'] );
1725
+ $field_prefix = 'pods_meta_';
1726
+ $field_row_classes = 'form-field';
1727
+ $th_scope = 'row';
1728
 
1729
+ $value_callback = static function( $field_name, $id, $field, $pod ) {
1730
  $value = '';
1731
 
1732
+ pods_no_conflict_on( 'taxonomy' );
1733
+
1734
  if ( ! empty( $pod ) ) {
1735
+ $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] );
1736
+ } elseif ( ! empty( $id ) ) {
1737
+ $value = get_term_meta( $id, $field['name'], true );
1738
  }
1739
 
1740
+ pods_no_conflict_off( 'taxonomy' );
1741
+
1742
+ return $value;
1743
+ };
1744
+
1745
+ $pre_callback = static function( $field_name, $id, $field, $pod ) use ( $tag ) {
1746
+ do_action( "pods_meta_meta_taxonomy_pre_row_{$field_name}", $tag, $field, $pod );
1747
+ };
1748
+
1749
+ $post_callback = static function( $field_name, $id, $field, $pod ) use ( $tag ) {
1750
+ do_action( "pods_meta_meta_taxonomy_post_row_{$field_name}", $tag, $field, $pod );
1751
+ };
1752
+
1753
+ if ( null === $id ) {
1754
+ pods_view( PODS_DIR . 'ui/forms/div-rows.php', compact( array_keys( get_defined_vars() ) ) );
1755
+ } else {
1756
+ pods_view( PODS_DIR . 'ui/forms/table-rows.php', compact( array_keys( get_defined_vars() ) ) );
 
 
 
 
 
 
1757
  }
1758
  }
1759
 
1795
 
1796
  $has_fields = false;
1797
 
1798
+ $layout_field_types = PodsForm::layout_field_types();
1799
+
1800
  foreach ( $groups as $group ) {
1801
  if ( empty( $group['fields'] ) ) {
1802
  continue;
1803
  }
1804
 
1805
+ if ( ! pods_permission( $group ) ) {
1806
+ continue;
1807
+ }
1808
+
1809
  if ( null === $term ) {
1810
  $term = get_term( $term_id, $taxonomy );
1811
 
1816
 
1817
  $has_fields = true;
1818
 
1819
+ if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) {
1820
+ $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'taxonomy' );
 
 
 
 
 
 
1821
  }
1822
 
1823
  foreach ( $group['fields'] as $field ) {
1824
+ if ( in_array( $field['type'], $layout_field_types, true ) ) {
1825
+ continue;
1826
+ }
1827
+
1828
+ if ( ! pods_permission( $field ) ) {
1829
+ if ( ! pods_var( 'hidden', $field, false ) ) {
1830
  continue;
1831
  }
1832
  }
1840
  }
1841
 
1842
  if ( $pod ) {
1843
+ $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data, false );
1844
 
1845
  // Block REST API saves, we handle those separately in PodsRESTHandlers
1846
  if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
1866
  // Fix for Pods doing it's own sanitization
1867
  $data = pods_unslash( (array) $data );
1868
 
1869
+ $pod->save( $data, null, $id, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) );
1870
  }
1871
 
1872
  pods_no_conflict_off( 'taxonomy' );
1914
  $groups = $this->groups_get( 'user', 'user' );
1915
 
1916
  if ( is_object( $user_id ) ) {
1917
+ $user = $user_id;
1918
  $user_id = $user_id->ID;
1919
+ } else {
1920
+ $user = get_userdata( $user_id );
1921
  }
1922
 
1923
  $id = $user_id;
1928
  continue;
1929
  }
1930
 
1931
+ if ( ! pods_permission( $group ) ) {
1932
+ continue;
 
 
 
 
 
 
1933
  }
1934
 
1935
+ if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) {
1936
+ $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'user' );
1937
+ }
1938
  ?>
1939
  <h3><?php echo $group['label']; ?></h3>
1940
 
1943
  <table class="form-table pods-meta">
1944
  <tbody>
1945
  <?php
1946
+ $fields = $group['fields'];
1947
+ $field_prefix = 'pods_meta_';
1948
+ $field_row_classes = 'form-field pods-field-input';
1949
+ $th_scope = 'row';
 
 
 
 
 
 
 
1950
 
1951
+ $value_callback = static function( $field_name, $id, $field, $pod ) {
1952
  $value = '';
1953
 
1954
+ pods_no_conflict_on( 'user' );
1955
+
1956
  if ( ! empty( $pod ) ) {
1957
+ $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] );
1958
  } elseif ( ! empty( $id ) ) {
 
 
1959
  $value = get_user_meta( $id, $field['name'], true );
 
 
1960
  }
1961
 
1962
+ pods_no_conflict_off( 'user' );
1963
+
1964
+ return $value;
1965
+ };
1966
+
1967
+ $pre_callback = static function( $field_name, $id, $field, $pod ) use ( $user ) {
1968
+ do_action( "pods_meta_meta_user_pre_row_{$field_name}", $user, $field, $pod );
1969
+ };
1970
+
1971
+ $post_callback = static function( $field_name, $id, $field, $pod ) use ( $user ) {
1972
+ do_action( "pods_meta_meta_user_post_row_{$field_name}", $user, $field, $pod );
1973
+ };
1974
+
1975
+ pods_view( PODS_DIR . 'ui/forms/table-rows.php', compact( array_keys( get_defined_vars() ) ) );
 
 
 
1976
  ?>
1977
  </tbody>
1978
  </table>
1979
  <?php
 
 
 
 
 
1980
  }
1981
 
1982
  do_action( 'pods_meta_meta_user_post', $user_id );
1994
 
1995
  $is_new_item = false;
1996
 
1997
+ if ( 'user_register' === current_filter() ) {
1998
  $is_new_item = true;
1999
  }
2000
 
2010
 
2011
  $groups = $this->groups_get( 'user', 'user' );
2012
 
2013
+ $id = $user_id;
2014
+ $pod = $this->maybe_set_up_pod( 'user', $id, 'user' );
2015
+ $data = [];
 
 
 
 
 
 
 
2016
 
2017
  if ( $pod ) {
2018
+ $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data, false );
2019
 
2020
  // Block REST API saves, we handle those separately in PodsRESTHandlers
2021
  if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
2024
  }
2025
 
2026
  if ( false !== $nonced && ! empty( $groups ) ) {
2027
+ $layout_field_types = PodsForm::layout_field_types();
2028
+
2029
  foreach ( $groups as $group ) {
2030
  if ( empty( $group['fields'] ) ) {
2031
  continue;
2032
  }
2033
 
2034
+ if ( ! pods_permission( $group ) ) {
2035
+ continue;
2036
+ }
2037
+
2038
  foreach ( $group['fields'] as $field ) {
2039
+ if ( in_array( $field['type'], $layout_field_types, true ) ) {
2040
+ continue;
2041
+ }
2042
+
2043
+ if ( ! pods_permission( $field ) ) {
2044
+ if ( ! pods_v( 'hidden', $field, false ) ) {
2045
  continue;
2046
  }
2047
  }
2068
  // Fix for Pods doing it's own sanitizing
2069
  $data = pods_unslash( (array) $data );
2070
 
2071
+ $pod->save( $data, null, $id, array( 'is_new_item' => $is_new_item, 'podsmeta' => true ) );
2072
  } elseif ( ! empty( $id ) ) {
2073
  foreach ( $data as $field => $value ) {
2074
  update_user_meta( $id, $field, $value );
2137
  continue;
2138
  }
2139
 
2140
+ if ( ! pods_permission( $group ) ) {
2141
+ continue;
2142
+ }
 
 
 
2143
 
2144
+ if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) {
2145
+ $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'comment' );
2146
  }
2147
 
2148
+ $fields = array_merge( [
2149
+ '_group_title' => [
2150
+ 'name' => '_group_title',
2151
+ 'label' => $group['label'],
2152
+ 'type' => 'heading',
2153
+ 'heading_tag' => 'h2',
2154
+ ],
2155
+ ], $group['fields'] );
2156
+ $field_prefix = 'pods_meta_';
2157
+ $field_row_classes = 'comment-form-author comment-form-pods-meta';
2158
 
2159
+ $value_callback = static function( $field_name, $id, $field, $pod ) {
2160
  $value = '';
2161
 
2162
+ pods_no_conflict_on( 'comment' );
2163
+
2164
  if ( ! empty( $pod ) ) {
2165
+ $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] );
2166
  } elseif ( ! empty( $id ) ) {
 
 
2167
  $value = get_comment_meta( $id, $field['name'], true );
 
 
2168
  }
2169
+
2170
+ pods_no_conflict_off( 'comment' );
2171
+
2172
+ return $value;
2173
+ };
2174
+
2175
+ // There is no comment yet.
2176
+ $comment = null;
2177
+
2178
+ $pre_callback = static function( $field_name, $id, $field, $pod ) use ( $comment ) {
2179
+ do_action( "pods_meta_meta_comment_pre_row_{$field_name}", $comment, $field, $pod );
2180
+ };
2181
+
2182
+ $post_callback = static function( $field_name, $id, $field, $pod ) use ( $comment ) {
2183
+ do_action( "pods_meta_meta_comment_post_row_{$field_name}", $comment, $field, $pod );
2184
+ };
2185
+
2186
+ pods_view( PODS_DIR . 'ui/forms/table-rows.php', compact( array_keys( get_defined_vars() ) ) );
2187
  }
2188
 
2189
  do_action( 'pods_meta_meta_comment_new_logged_in_post', $commenter, $user_identity );
2211
  continue;
2212
  }
2213
 
2214
+ if ( ! pods_permission( $group ) ) {
2215
+ continue;
2216
+ }
 
 
 
2217
 
2218
+ if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) {
2219
+ $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'comment' );
2220
  }
2221
 
2222
+ $fields = array_merge( [
2223
+ '_group_title' => [
2224
+ 'name' => '_group_title',
2225
+ 'label' => $group['label'],
2226
+ 'type' => 'heading',
2227
+ 'heading_tag' => 'h2',
2228
+ ],
2229
+ ], $group['fields'] );
2230
+ $field_prefix = 'pods_meta_';
2231
+ $field_row_classes = 'comment-form-author comment-form-pods-meta';
2232
 
2233
+ $value_callback = static function( $field_name, $id, $field, $pod ) {
2234
+ $value = '';
2235
+
2236
+ pods_no_conflict_on( 'comment' );
2237
+
2238
+ if ( ! empty( $pod ) ) {
2239
+ $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] );
2240
+ } elseif ( ! empty( $id ) ) {
2241
+ $value = get_comment_meta( $id, $field['name'], true );
2242
+ }
2243
+
2244
+ pods_no_conflict_off( 'comment' );
2245
+
2246
+ return $value;
2247
+ };
2248
+
2249
+ // There is no comment yet.
2250
+ $comment = null;
2251
+
2252
+ $pre_callback = static function( $field_name, $id, $field, $pod ) use ( $comment ) {
2253
+ do_action( "pods_meta_meta_comment_pre_row_{$field_name}", $comment, $field, $pod );
2254
+ };
2255
+
2256
+ $post_callback = static function( $field_name, $id, $field, $pod ) use ( $comment ) {
2257
+ do_action( "pods_meta_meta_comment_post_row_{$field_name}", $comment, $field, $pod );
2258
+ };
2259
+
2260
+ foreach ( $fields as $field ) {
2261
+ $hidden_field = (boolean) pods_v( 'hidden', $field, false );
2262
+
2263
+ if (
2264
+ ! pods_permission( $field )
2265
+ || ( ! pods_has_permissions( $field ) && $hidden_field )
2266
+ ) {
2267
+ if ( ! $hidden_field ) {
2268
  continue;
2269
  }
2270
+
2271
  $field['type'] = 'hidden';
2272
  }
2273
 
2274
  $value = '';
2275
 
2276
+ if ( ! empty( $value_callback ) && is_callable( $value_callback ) ) {
2277
+ $value = $value_callback( $field['name'], $id, $field, $pod );
2278
+ } elseif ( ! empty( $pod ) ) {
2279
+ $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] );
2280
+ }
2281
 
2282
+ $row_classes = $field_row_classes . ' pods-form-ui-row-type-' . $field['type'] . ' pods-form-ui-row-name-' . PodsForm::clean( $field['name'], true );
2283
+ $row_classes = trim( $row_classes );
2284
 
2285
+ ob_start();
2286
+
2287
+ if ( ! empty( $pre_callback ) && is_callable( $pre_callback ) ) {
2288
+ $pre_callback( $field['name'], $id, $field, $pod );
2289
+ }
2290
+
2291
+ pods_view( PODS_DIR . 'ui/forms/p-row.php', compact( array_keys( get_defined_vars() ) ), false, 'cache', true );
2292
+
2293
+ if ( ! empty( $post_callback ) && is_callable( $post_callback ) ) {
2294
+ $post_callback( $field['name'], $id, $field, $pod );
2295
  }
2296
 
 
 
 
 
 
 
 
 
 
 
2297
  $form_fields[ 'pods_meta_' . $field['name'] ] = ob_get_clean();
2298
  }
2299
  }
2331
  continue;
2332
  }
2333
 
2334
+ if ( ! pods_permission( $group ) ) {
2335
+ continue;
2336
+ }
2337
+
2338
  $field_found = false;
2339
 
2340
  foreach ( $group['fields'] as $field ) {
2341
+ if ( ! PodsForm::permission( $field ) ) {
2342
+ if ( pods_v( 'hidden', $field, false ) ) {
2343
  $field_found = true;
2344
  break;
2345
  } else {
2383
  $id = $comment->comment_ID;
2384
  }
2385
 
2386
+ $pod = $this->maybe_set_up_pod( $metabox['args']['group']['pod']['name'], $id, 'comment' );
 
 
 
 
 
 
2387
 
2388
+ $fields = $metabox['args']['group']['fields'];
2389
+ $field_prefix = 'pods_meta_';
2390
+ $field_row_classes = 'comment-form-author comment-form-pods-meta';
 
 
 
 
 
 
 
2391
 
2392
+ $value_callback = static function( $field_name, $id, $field, $pod ) {
2393
  $value = '';
2394
 
2395
+ pods_no_conflict_on( 'comment' );
2396
+
2397
  if ( ! empty( $pod ) ) {
2398
+ $value = $pod->field( [ 'name' => $field['name'], 'in_form' => true ] );
2399
+ } elseif ( ! empty( $id ) ) {
2400
+ $value = get_comment_meta( $id, $field['name'], true );
2401
  }
2402
 
2403
+ pods_no_conflict_off( 'comment' );
2404
+
2405
+ return $value;
2406
+ };
2407
+
2408
+ $pre_callback = static function( $field_name, $id, $field, $pod ) use ( $comment ) {
2409
+ do_action( "pods_meta_meta_comment_pre_row_{$field_name}", $comment, $field, $pod );
2410
+ };
2411
+
2412
+ $post_callback = static function( $field_name, $id, $field, $pod ) use ( $comment ) {
2413
+ do_action( "pods_meta_meta_comment_post_row_{$field_name}", $comment, $field, $pod );
2414
+ };
2415
+
2416
+ pods_view( PODS_DIR . 'ui/forms/table-rows.php', compact( array_keys( get_defined_vars() ) ) );
 
 
 
2417
  ?>
2418
  </table>
2419
  <?php
 
 
 
 
 
 
2420
  do_action( 'pods_meta_meta_comment_post', $comment, $metabox );
2421
  }
2422
 
2437
  $pod = null;
2438
  $id = null;
2439
 
2440
+ $layout_field_types = PodsForm::layout_field_types();
2441
+
2442
+ $api = pods_api();
2443
+
2444
  foreach ( $groups as $group ) {
2445
  if ( empty( $group['fields'] ) ) {
2446
  continue;
2447
  }
2448
 
2449
+ if ( ! pods_permission( $group ) ) {
2450
+ continue;
2451
+ }
 
 
 
2452
 
2453
+ if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) {
2454
+ $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'comment' );
2455
  }
2456
 
2457
  foreach ( $group['fields'] as $field ) {
2458
+ if ( in_array( $field['type'], $layout_field_types, true ) ) {
2459
+ continue;
2460
+ }
2461
 
2462
+ if ( ! pods_permission( $field ) ) {
2463
+ if ( ! pods_var( 'hidden', $field, false ) ) {
2464
  continue;
2465
  }
2466
  }
2471
  $data[ $field['name'] ] = $_POST[ 'pods_meta_' . $field['name'] ];
2472
  }
2473
 
2474
+ $validate = $api->handle_field_validation( $data[ $field['name'] ], $field['name'], $api->get_wp_object_fields( 'comment' ), $pod->fields(), $pod, array() );
2475
 
2476
  if ( false === $validate ) {
2477
  $validate = sprintf( __( 'There was an issue validating the field %s', 'pods' ), $field['label'] );
2506
  $id = $comment_id;
2507
  $pod = null;
2508
 
2509
+ $layout_field_types = PodsForm::layout_field_types();
2510
+
2511
  foreach ( $groups as $group ) {
2512
  if ( empty( $group['fields'] ) ) {
2513
  continue;
2514
  }
2515
 
2516
+ if ( ! pods_permission( $group ) ) {
2517
+ continue;
2518
+ }
 
 
 
2519
 
2520
+ if ( null === $pod || ( is_object( $pod ) && (int) $pod->id() !== (int) $id ) ) {
2521
+ $pod = $this->maybe_set_up_pod( $group['pod']['name'], $id, 'comment' );
2522
  }
2523
 
2524
  foreach ( $group['fields'] as $field ) {
2525
+ if ( in_array( $field['type'], $layout_field_types, true ) ) {
2526
+ continue;
2527
+ }
2528
+
2529
+ if ( ! pods_permission( $field ) ) {
2530
+ if ( ! pods_var( 'hidden', $field, false ) ) {
2531
  continue;
2532
  }
2533
  }
2541
  }
2542
 
2543
  if ( $pod ) {
2544
+ $rest_enable = (boolean) pods_v( 'rest_enable', $pod->pod_data, false );
2545
 
2546
  // Block REST API saves, we handle those separately in PodsRESTHandlers
2547
  if ( defined( 'REST_REQUEST' ) && REST_REQUEST && $rest_enable ) {
2555
  // Fix for Pods doing it's own sanitization
2556
  $data = pods_unslash( (array) $data );
2557
 
2558
+ $pod->save( $data, null, $id, array( 'podsmeta' => true ) );
2559
  } elseif ( ! empty( $id ) ) {
2560
  pods_no_conflict_on( 'comment' );
2561
 
2595
 
2596
  }
2597
 
2598
+ /**
2599
+ * Get list of keys not covered for an object type.
2600
+ *
2601
+ * @param string $type The object type.
2602
+ *
2603
+ * @return array The list of keys not covered in key=>true format for isset() optimization.
2604
+ */
2605
+ public function get_keys_not_covered( $type ) {
2606
+ if ( 'post' === $type ) {
2607
+ $type = 'post_type';
2608
+ }
2609
+
2610
+ $keys_not_covered = [
2611
+ 'post_type' => [
2612
+ '_wp_attachment_metadata' => true,
2613
+ '_thumbnail_id' => true,
2614
+ ],
2615
+ 'user' => [
2616
+ 'capabilities' => true,
2617
+ 'session_tokens' => true,
2618
+ 'primary_blog' => true,
2619
+ 'default_password_nag' => true,
2620
+ 'tribe-dismiss-notice' => true,
2621
+ 'user-settings' => true,
2622
+ 'admin_color' => true,
2623
+ 'show_admin_bar_front' => true,
2624
+ 'show_admin_bar_admin' => true,
2625
+ ],
2626
+ 'settings' => [
2627
+ ],
2628
+ ];
2629
+
2630
+ // Add prefix-specific keys for user type.
2631
+ if ( 'user' === $type ) {
2632
+ global $wpdb;
2633
+
2634
+ $prefix = $wpdb->get_blog_prefix();
2635
+
2636
+ $keys = $keys_not_covered['user'];
2637
+
2638
+ foreach ( $keys as $key => $ignored ) {
2639
+ $keys_not_covered['user'][ $prefix . $key ] = true;
2640
+ }
2641
+ }
2642
+
2643
+ /**
2644
+ * Allow filtering the list of keys not covered.
2645
+ *
2646
+ * @since 2.8.0
2647
+ *
2648
+ * @param array $keys_not_covered The list of keys not covered in key=>true format for isset() optimization.
2649
+ * @param string $type The object type.
2650
+ */
2651
+ $keys_not_covered = apply_filters( 'pods_meta_keys_not_covered', $keys_not_covered, $type );
2652
+
2653
+ return isset( $keys_not_covered[ $type ] ) ? $keys_not_covered[ $type ] : [];
2654
+ }
2655
+
2656
  /**
2657
  * All *_*_meta filter handler aliases
2658
  *
2659
  * @return mixed
2660
  */
2661
  public function get_post_meta() {
 
2662
  $args = func_get_args();
2663
 
2664
  array_unshift( $args, 'post_type' );
2676
  * @return mixed
2677
  */
2678
  public function get_user_meta() {
 
2679
  $args = func_get_args();
2680
 
2681
  array_unshift( $args, 'user' );
2693
  * @return mixed
2694
  */
2695
  public function get_comment_meta() {
 
2696
  $args = func_get_args();
2697
 
2698
  array_unshift( $args, 'comment' );
2710
  * @return mixed
2711
  */
2712
  public function get_term_meta() {
 
2713
  $args = func_get_args();
2714
 
2715
  array_unshift( $args, 'term' );
2729
  * @return mixed
2730
  */
2731
  public function get_option() {
 
2732
  $args = func_get_args();
2733
 
2734
+ if ( 0 === strpos( $args[2], '_transient_' ) || 0 === strpos( $args[2], '_site_transient_' ) ) {
2735
+ return $args[0];
2736
+ }
2737
+
2738
  array_unshift( $args, 'settings' );
2739
 
2740
  $_null = apply_filters( 'pods_meta_get_option', null, $args );
2750
  * @return mixed
2751
  */
2752
  public function add_post_meta() {
 
2753
  $args = func_get_args();
2754
 
2755
  array_unshift( $args, 'post_type' );
2767
  * @return mixed
2768
  */
2769
  public function add_user_meta() {
 
2770
  $args = func_get_args();
2771
 
2772
  array_unshift( $args, 'user' );
2784
  * @return mixed
2785
  */
2786
  public function add_comment_meta() {
 
2787
  $args = func_get_args();
2788
 
2789
  array_unshift( $args, 'comment' );
2801
  * @return mixed
2802
  */
2803
  public function add_term_meta() {
 
2804
  $args = func_get_args();
2805
 
2806
  array_unshift( $args, 'term' );
2818
  * @return mixed
2819
  */
2820
  public function add_option() {
 
2821
  $args = func_get_args();
2822
 
2823
  array_unshift( $args, 'settings' );
2835
  * @return mixed
2836
  */
2837
  public function update_post_meta() {
 
2838
  $args = func_get_args();
2839
 
2840
  array_unshift( $args, 'post_type' );
2852
  * @return mixed
2853
  */
2854
  public function update_user_meta() {
 
2855
  $args = func_get_args();
2856
 
2857
  array_unshift( $args, 'user' );
2869
  * @return mixed
2870
  */
2871
  public function update_comment_meta() {
 
2872
  $args = func_get_args();
2873
 
2874
  array_unshift( $args, 'comment' );
2886
  * @return mixed
2887
  */
2888
  public function update_term_meta() {
 
2889
  $args = func_get_args();
2890
 
2891
  array_unshift( $args, 'term' );
2903
  * @return mixed
2904
  */
2905
  public function update_option() {
 
2906
  $args = func_get_args();
2907
 
2908
  array_unshift( $args, 'settings' );
2917
  }
2918
 
2919
  /**
2920
+ * Handle updating post meta by meta ID.
2921
+ *
2922
+ * @since 2.8.0
2923
+ *
2924
  * @return mixed
2925
  */
2926
+ public function update_post_meta_by_id() {
2927
+ $args = func_get_args();
2928
+
2929
+ array_unshift( $args, 'post_type' );
2930
+
2931
+ // WP core filter is weird and has meta value before meta key.
2932
+ $meta_value = $args[3];
2933
+ $meta_key = $args[4];
2934
+
2935
+ // Switch order of meta key / meta value.
2936
+ $args[3] = $meta_key;
2937
+ $args[4] = $meta_value;
2938
+
2939
+ /**
2940
+ * Allow circumventing the update meta handling by meta ID for Pods.
2941
+ *
2942
+ * @since 2.8.0
2943
+ *
2944
+ * @param null|bool $_null Whether to override the meta handling by Pods.
2945
+ * @param array $args The function arguments with the type added to the front.
2946
+ */
2947
+ $_null = apply_filters( 'pods_meta_update_post_meta_by_id', null, $args );
2948
+
2949
+ if ( null !== $_null ) {
2950
+ return $_null;
2951
+ }
2952
+
2953
+ return call_user_func_array( [ $this, 'update_meta_by_id' ], $args );
2954
+ }
2955
+
2956
+ /**
2957
+ * Handle updating user meta by meta ID.
2958
+ *
2959
+ * @since 2.8.0
2960
+ *
2961
+ * @return mixed
2962
+ */
2963
+ public function update_user_meta_by_id() {
2964
+ $args = func_get_args();
2965
+
2966
+ array_unshift( $args, 'user' );
2967
+
2968
+ // WP core filter is weird and has meta value before meta key.
2969
+ $meta_value = $args[3];
2970
+ $meta_key = $args[4];
2971
+
2972
+ // Switch order of meta key / meta value.
2973
+ $args[3] = $meta_key;
2974
+ $args[4] = $meta_value;
2975
+
2976
+ /**
2977
+ * Allow circumventing the update meta handling by meta ID for Pods.
2978
+ *
2979
+ * @since 2.8.0
2980
+ *
2981
+ * @param null|bool $_null Whether to override the meta handling by Pods.
2982
+ * @param array $args The function arguments with the type added to the front.
2983
+ */
2984
+ $_null = apply_filters( 'pods_meta_update_user_meta_by_id', null, $args );
2985
+
2986
+ if ( null !== $_null ) {
2987
+ return $_null;
2988
+ }
2989
+
2990
+ return call_user_func_array( [ $this, 'update_meta_by_id' ], $args );
2991
+ }
2992
+
2993
+ /**
2994
+ * Handle updating comment meta by meta ID.
2995
+ *
2996
+ * @since 2.8.0
2997
+ *
2998
+ * @return mixed
2999
+ */
3000
+ public function update_comment_meta_by_id() {
3001
+ $args = func_get_args();
3002
+
3003
+ array_unshift( $args, 'comment' );
3004
+
3005
+ // WP core filter is weird and has meta value before meta key.
3006
+ $meta_value = $args[3];
3007
+ $meta_key = $args[4];
3008
+
3009
+ // Switch order of meta key / meta value.
3010
+ $args[3] = $meta_key;
3011
+ $args[4] = $meta_value;
3012
+
3013
+ /**
3014
+ * Allow circumventing the update meta handling by meta ID for Pods.
3015
+ *
3016
+ * @since 2.8.0
3017
+ *
3018
+ * @param null|bool $_null Whether to override the meta handling by Pods.
3019
+ * @param array $args The function arguments with the type added to the front.
3020
+ */
3021
+ $_null = apply_filters( 'pods_meta_update_comment_meta_by_id', null, $args );
3022
 
3023
+ if ( null !== $_null ) {
3024
+ return $_null;
3025
+ }
3026
+
3027
+ return call_user_func_array( [ $this, 'update_meta_by_id' ], $args );
3028
+ }
3029
+
3030
+ /**
3031
+ * Handle updating term meta by meta ID.
3032
+ *
3033
+ * @since 2.8.0
3034
+ *
3035
+ * @return mixed
3036
+ */
3037
+ public function update_term_meta_by_id() {
3038
+ $args = func_get_args();
3039
+
3040
+ array_unshift( $args, 'term' );
3041
+
3042
+ // WP core filter is weird and has meta value before meta key.
3043
+ $meta_value = $args[3];
3044
+ $meta_key = $args[4];
3045
+
3046
+ // Switch order of meta key / meta value.
3047
+ $args[3] = $meta_key;
3048
+ $args[4] = $meta_value;
3049
+
3050
+ /**
3051
+ * Allow circumventing the update meta handling by meta ID for Pods.
3052
+ *
3053
+ * @since 2.8.0
3054
+ *
3055
+ * @param null|bool $_null Whether to override the meta handling by Pods.
3056
+ * @param array $args The function arguments with the type added to the front.
3057
+ */
3058
+ $_null = apply_filters( 'pods_meta_update_term_meta_by_id', null, $args );
3059
+
3060
+ if ( null !== $_null ) {
3061
+ return $_null;
3062
+ }
3063
+
3064
+ return call_user_func_array( [ $this, 'update_meta_by_id' ], $args );
3065
+ }
3066
+
3067
+ /**
3068
+ * @return mixed
3069
+ */
3070
+ public function delete_post_meta() {
3071
  $args = func_get_args();
3072
 
3073
  array_unshift( $args, 'post_type' );
3085
  * @return mixed
3086
  */
3087
  public function delete_user_meta() {
 
3088
  $args = func_get_args();
3089
 
3090
  array_unshift( $args, 'user' );
3102
  * @return mixed
3103
  */
3104
  public function delete_comment_meta() {
 
3105
  $args = func_get_args();
3106
 
3107
  array_unshift( $args, 'comment' );
3119
  * @return mixed
3120
  */
3121
  public function delete_term_meta() {
 
3122
  $args = func_get_args();
3123
 
3124
  array_unshift( $args, 'term' );
3136
  * @return mixed
3137
  */
3138
  public function delete_option() {
 
3139
  $args = func_get_args();
3140
 
3141
  array_unshift( $args, 'settings' );
3149
  return call_user_func_array( array( $this, 'delete_meta' ), $args );
3150
  }
3151
 
3152
+ /**
3153
+ * Handle deleting post meta by meta ID.
3154
+ *
3155
+ * @since 2.8.0
3156
+ *
3157
+ * @return mixed
3158
+ */
3159
+ public function delete_post_meta_by_id() {
3160
+ $args = func_get_args();
3161
+
3162
+ array_unshift( $args, 'post_type' );
3163
+
3164
+ /**
3165
+ * Allow circumventing the delete meta handling by meta ID for Pods.
3166
+ *
3167
+ * @since 2.8.0
3168
+ *
3169
+ * @param null|bool $_null Whether to override the meta handling by Pods.
3170
+ * @param array $args The function arguments with the type added to the front.
3171
+ */
3172
+ $_null = apply_filters( 'pods_meta_delete_post_meta_by_id', null, $args );
3173
+
3174
+ if ( null !== $_null ) {
3175
+ return $_null;
3176
+ }
3177
+
3178
+ return call_user_func_array( [ $this, 'delete_meta_by_id' ], $args );
3179
+ }
3180
+
3181
+ /**
3182
+ * Handle deleting user meta by meta ID.
3183
+ *
3184
+ * @since 2.8.0
3185
+ *
3186
+ * @return mixed
3187
+ */
3188
+ public function delete_user_meta_by_id() {
3189
+ $args = func_get_args();
3190
+
3191
+ array_unshift( $args, 'user' );
3192
+
3193
+ /**
3194
+ * Allow circumventing the delete meta handling by meta ID for Pods.
3195
+ *
3196
+ * @since 2.8.0
3197
+ *
3198
+ * @param null|bool $_null Whether to override the meta handling by Pods.
3199
+ * @param array $args The function arguments with the type added to the front.
3200
+ */
3201
+ $_null = apply_filters( 'pods_meta_delete_user_meta_by_id', null, $args );
3202
+
3203
+ if ( null !== $_null ) {
3204
+ return $_null;
3205
+ }
3206
+
3207
+ return call_user_func_array( [ $this, 'delete_meta_by_id' ], $args );
3208
+ }
3209
+
3210
+ /**
3211
+ * Handle deleting comment meta by meta ID.
3212
+ *
3213
+ * @since 2.8.0
3214
+ *
3215
+ * @return mixed
3216
+ */
3217
+ public function delete_comment_meta_by_id() {
3218
+ $args = func_get_args();
3219
+
3220
+ array_unshift( $args, 'comment' );
3221
+
3222
+ /**
3223
+ * Allow circumventing the delete meta handling by meta ID for Pods.
3224
+ *
3225
+ * @since 2.8.0
3226
+ *
3227
+ * @param null|bool $_null Whether to override the meta handling by Pods.
3228
+ * @param array $args The function arguments with the type added to the front.
3229
+ */
3230
+ $_null = apply_filters( 'pods_meta_delete_comment_meta_by_id', null, $args );
3231
+
3232
+ if ( null !== $_null ) {
3233
+ return $_null;
3234
+ }
3235
+
3236
+ return call_user_func_array( [ $this, 'delete_meta_by_id' ], $args );
3237
+ }
3238
+
3239
+ /**
3240
+ * Handle deleting term meta by meta ID.
3241
+ *
3242
+ * @since 2.8.0
3243
+ *
3244
+ * @return mixed
3245
+ */
3246
+ public function delete_term_meta_by_id() {
3247
+ $args = func_get_args();
3248
+
3249
+ array_unshift( $args, 'term' );
3250
+
3251
+ /**
3252
+ * Allow circumventing the delete meta handling by meta ID for Pods.
3253
+ *
3254
+ * @since 2.8.0
3255
+ *
3256
+ * @param null|bool $_null Whether to override the meta handling by Pods.
3257
+ * @param array $args The function arguments with the type added to the front.
3258
+ */
3259
+ $_null = apply_filters( 'pods_meta_delete_term_meta_by_id', null, $args );
3260
+
3261
+ if ( null !== $_null ) {
3262
+ return $_null;
3263
+ }
3264
+
3265
+ return call_user_func_array( [ $this, 'delete_meta_by_id' ], $args );
3266
+ }
3267
+
3268
  /*
3269
  * The real meta functions
3270
  */
3276
  * @return bool|mixed
3277
  */
3278
  public function get_object( $object_type, $object_id, $aux = '' ) {
 
3279
  global $wpdb;
3280
 
3281
  if ( 'term' == $object_type ) {
3380
  * @return array|bool|int|mixed|null|string|void
3381
  */
3382
  public function get_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $single = false ) {
 
3383
  // Enforce boolean as it can be a string sometimes
3384
  $single = filter_var( $single, FILTER_VALIDATE_BOOLEAN );
3385
 
3391
  $meta_type = 'term';
3392
  }
3393
 
3394
+ // List of keys we do not cover optimized for fastest isset() operation.
3395
+ $keys_not_covered = $this->get_keys_not_covered( $object_type );
3396
+
3397
+ // Skip keys we do not cover.
3398
+ if ( $meta_key && isset( $keys_not_covered[ $meta_key ] ) ) {
3399
+ return $_null;
3400
+ }
3401
+
3402
  if ( empty( $meta_key ) ) {
3403
  if ( ! defined( 'PODS_ALLOW_FULL_META' ) || ! PODS_ALLOW_FULL_META ) {
3404
  return $_null; // don't cover get_post_meta( $id )
3450
 
3451
  $pod = self::$current_field_pod;
3452
 
3453
+ $pod_object = $pod->pod_data;
3454
+
3455
+ $meta_keys = [
3456
+ $meta_key,
3457
+ ];
3458
 
3459
  if ( empty( $meta_key ) ) {
3460
  $meta_keys = array_keys( $meta_cache );
3462
 
3463
  $key_found = false;
3464
 
3465
+ $tableless_field_types = PodsForm::tableless_field_types();
3466
+
3467
  foreach ( $meta_keys as $meta_k ) {
3468
  if ( ! empty( $pod ) ) {
3469
  $first_meta_key = $meta_k;
3470
+
3471
  if ( false !== strpos( $first_meta_key, '.' ) ) {
3472
  // Get the first meta key.
3473
  $first_meta_key = current( explode( '.', $first_meta_key ) );
3474
  }
3475
 
3476
+ $field_object = $pod_object->get_field( $first_meta_key );
3477
+
3478
+ if ( $field_object ) {
3479
  $key_found = true;
3480
 
3481
  $meta_cache[ $meta_k ] = $pod->field( array(
3492
  }
3493
  }
3494
 
3495
+ if ( isset( $meta_cache[ '_pods_' . $first_meta_key ] ) && in_array( $field_object['type'], $tableless_field_types, true ) ) {
3496
  unset( $meta_cache[ '_pods_' . $first_meta_key ] );
3497
  }
3498
  }
3546
  * @return bool|int|null
3547
  */
3548
  public function add_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $unique = false ) {
 
3549
  if ( pods_tableless() ) {
3550
  return $_null;
3551
  }
3552
 
3553
+ // List of keys we do not cover optimized for fastest isset() operation.
3554
+ $keys_not_covered = $this->get_keys_not_covered( $object_type );
3555
+
3556
+ // Skip keys we do not cover.
3557
+ if ( $meta_key && isset( $keys_not_covered[ $meta_key ] ) ) {
3558
+ return $_null;
3559
+ }
3560
+
3561
  $object = $this->get_object( $object_type, $object_id );
3562
 
3563
  if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) {
3601
  * @return bool|int|null
3602
  */
3603
  public function update_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $prev_value = '' ) {
 
3604
  if ( pods_tableless() ) {
3605
  return $_null;
3606
  }
3607
 
3608
+ // List of keys we do not cover optimized for fastest isset() operation.
3609
+ $keys_not_covered = $this->get_keys_not_covered( $object_type );
3610
+
3611
+ // Skip keys we do not cover.
3612
+ if ( $meta_key && isset( $keys_not_covered[ $meta_key ] ) ) {
3613
+ return $_null;
3614
+ }
3615
+
3616
  $object = $this->get_object( $object_type, $object_id );
3617
 
3618
  if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) {
3619
  return $_null;
3620
  }
3621
 
3622
+ if ( ! is_object( self::$current_field_pod ) || self::$current_field_pod->pod !== $object['name'] ) {
3623
  self::$current_field_pod = pods( $object['name'] );
3624
  }
3625
 
3626
  $pod = self::$current_field_pod;
3627
 
3628
+ $pod_object = $pod->pod_data;
3629
+ $field_object = $pod_object->get_field( $meta_key );
3630
 
3631
+ $tableless_field_types = PodsForm::tableless_field_types();
3632
+
3633
+ if ( null !== $pod->data->row && ( $field_object || false !== strpos( $meta_key, '.' ) ) ) {
3634
  $key = $meta_key;
3635
+
3636
  if ( false !== strpos( $meta_key, '.' ) ) {
3637
  $key = current( explode( '.', $meta_key ) );
3638
  }
3639
 
3640
+ $pod->data->row[ $meta_key ] = $meta_value;
3641
 
3642
+ if ( isset( $meta_cache[ '_pods_' . $key ] ) && $field_object && in_array( $field_object['type'], $tableless_field_types, true ) ) {
3643
+ unset( $meta_cache[ '_pods_' . $key ] );
 
 
3644
  }
 
3645
  }
3646
 
3647
  $pod->save( $meta_key, $meta_value, $object_id, array( 'podsmeta_direct' => true, 'error_mode' => 'false' ) );
3649
  return $object_id;
3650
  }
3651
 
3652
+ /**
3653
+ * Handle updating the meta by meta ID.
3654
+ *
3655
+ * @since 2.8.0
3656
+ *
3657
+ * @param string $object_type The object type.
3658
+ * @param null $_null The default value for the filter.
3659
+ * @param int $meta_id The meta ID.
3660
+ * @param string $meta_value The meta value.
3661
+ * @param string $meta_key The meta key.
3662
+ *
3663
+ * @return bool|int|null
3664
+ */
3665
+ public function update_meta_by_id( $object_type, $_null = null, $meta_id = 0, $meta_key = '', $meta_value = '' ) {
3666
+ $meta_type = 'post_type' === $object_type ? 'post' : $object_type;
3667
+
3668
+ // Get the original meta record.
3669
+ $meta = get_metadata_by_mid( $meta_type, $meta_id );
3670
+
3671
+ // Stop overriding the saving process if the original meta record was not found.
3672
+ if ( ! $meta ) {
3673
+ return $_null;
3674
+ }
3675
+
3676
+ $column = sanitize_key( $meta_type . '_id' );
3677
+
3678
+ // Get the object ID from the original meta record.
3679
+ $object_id = $meta->{$column};
3680
+
3681
+ return $this->update_meta( $object_type, $_null, $object_id, $meta_key, $meta_value );
3682
+ }
3683
+
3684
  /**
3685
  * @param $object_type
3686
  * @param null $_null
3692
  * @return null
3693
  */
3694
  public function delete_meta( $object_type, $_null = null, $object_id = 0, $meta_key = '', $meta_value = '', $delete_all = false ) {
 
3695
  if ( pods_tableless() ) {
3696
  return $_null;
3697
  }
3698
 
3699
+ // List of keys we do not cover optimized for fastest isset() operation.
3700
+ $keys_not_covered = $this->get_keys_not_covered( $object_type );
3701
+
3702
+ // Skip keys we do not cover.
3703
+ if ( $meta_key && isset( $keys_not_covered[ $meta_key ] ) ) {
3704
+ return $_null;
3705
+ }
3706
+
3707
  $object = $this->get_object( $object_type, $object_id );
3708
 
3709
  if ( empty( $object_id ) || empty( $object ) || ! isset( $object['fields'][ $meta_key ] ) ) {
3737
  return $_null;
3738
  }
3739
 
3740
+ /**
3741
+ * Handle delete the meta by meta ID.
3742
+ *
3743
+ * @since 2.8.0
3744
+ *
3745
+ * @param string $object_type The object type.
3746
+ * @param null $_null The default value for the filter.
3747
+ * @param int $meta_id The meta ID.
3748
+ *
3749
+ * @return bool|int|null
3750
+ */
3751
+ public function delete_meta_by_id( $object_type, $_null = null, $meta_id = 0 ) {
3752
+ $meta_type = 'post_type' === $object_type ? 'post' : $object_type;
3753
+
3754
+ // Get the original meta record.
3755
+ $meta = get_metadata_by_mid( $meta_type, $meta_id );
3756
+
3757
+ // Stop overriding the saving process if the original meta record was not found.
3758
+ if ( ! $meta ) {
3759
+ return $_null;
3760
+ }
3761
+
3762
+ $column = sanitize_key( $meta_type . '_id' );
3763
+
3764
+ // Get the object ID from the original meta record.
3765
+ $object_id = $meta->{$column};
3766
+
3767
+ return $this->delete_meta( $object_type, $_null, $object_id, $meta->meta_key, $meta->meta_value );
3768
+ }
3769
+
3770
  /**
3771
  * @param $id
3772
  *
3773
  * @return bool|void
3774
  */
3775
  public function delete_post( $id ) {
 
3776
  $post = get_post( $id );
3777
 
3778
  if ( empty( $post ) ) {
3789
  * @param $id
3790
  */
3791
  public function delete_taxonomy( $id ) {
 
3792
  /**
3793
  * @var $wpdb WPDB
3794
  */
3820
  */
3821
  public static function split_shared_term( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) {
3822
 
 
3823
 
3824
  $term_splitting = new Pods_Term_Splitting( $term_id, $new_term_id, $taxonomy );
3825
  $term_splitting->split_shared_term();
3875
  $params = array(
3876
  'pod' => pods_var( 'name', $object ),
3877
  'pod_id' => pods_var( 'id', $object ),
3878
+ 'id' => $id,
3879
+ 'strict' => false,
3880
  );
3881
 
3882
  return pods_api()->delete_pod_item( $params, false );
classes/PodsMigrate.php CHANGED
@@ -111,7 +111,7 @@ class PodsMigrate {
111
 
112
  $this->data = array_merge( $defaults, (array) $data );
113
  }
114
-
115
  /**
116
  * Get items.
117
  *
@@ -120,9 +120,9 @@ class PodsMigrate {
120
  * @return array List of data items.
121
  */
122
  private function get_items() {
123
-
124
- return empty( $this->data['single'] ) ?
125
- $this->data['items'] :
126
  array( $this->data['items'] );
127
 
128
  }
@@ -1101,7 +1101,7 @@ class PodsMigrate {
1101
  $field_data = array();
1102
  }
1103
 
1104
- $field_data = array_merge( $default_field_data, $field_data );
1105
 
1106
  if ( null === $field_data['field'] ) {
1107
  $field_data['field'] = $field;
111
 
112
  $this->data = array_merge( $defaults, (array) $data );
113
  }
114
+
115
  /**
116
  * Get items.
117
  *
120
  * @return array List of data items.
121
  */
122
  private function get_items() {
123
+
124
+ return empty( $this->data['single'] ) ?
125
+ $this->data['items'] :
126
  array( $this->data['items'] );
127
 
128
  }
1101
  $field_data = array();
1102
  }
1103
 
1104
+ $field_data = pods_config_merge_data( $default_field_data, $field_data );
1105
 
1106
  if ( null === $field_data['field'] ) {
1107
  $field_data['field'] = $field;
classes/PodsRESTFields.php CHANGED
@@ -1,5 +1,8 @@
1
  <?php
2
 
 
 
 
3
  /**
4
  * Class PodsRESTFields
5
  *
@@ -11,13 +14,13 @@
11
  class PodsRESTFields {
12
 
13
  /**
14
- * Pods object
15
  *
16
  * @since 2.5.6
17
  *
18
  * @access protected
19
  *
20
- * @var Pods
21
  */
22
  protected $pod;
23
 
@@ -26,10 +29,9 @@ class PodsRESTFields {
26
  *
27
  * @since 2.5.6
28
  *
29
- * @param string|object|Pods $pod Pods object
30
  */
31
  public function __construct( $pod ) {
32
-
33
  if ( ! function_exists( 'register_rest_field' ) ) {
34
  return;
35
  }
@@ -37,9 +39,8 @@ class PodsRESTFields {
37
  $this->set_pod( $pod );
38
 
39
  if ( $this->pod ) {
40
- $this->add_fields();
41
  }
42
-
43
  }
44
 
45
  /**
@@ -52,63 +53,68 @@ class PodsRESTFields {
52
  * @param string|Pods $pod Pods object or name of Pods object
53
  */
54
  private function set_pod( $pod ) {
 
 
 
 
 
 
 
 
 
55
 
56
- if ( is_string( $pod ) ) {
57
- $pod = pods( $pod, null, true );
58
 
59
- $this->set_pod( $pod );
60
- } else {
61
- $type = $pod->pod_data['type'];
 
 
 
 
62
 
63
- $supported_pod_types = array(
64
- 'post_type',
65
- 'taxonomy',
66
- 'media',
67
- 'user',
68
- 'comment',
69
- );
70
 
71
- if ( in_array( $type, $supported_pod_types, true ) ) {
72
- $this->pod = $pod;
73
- } else {
74
- $this->pod = false;
75
- }
76
- }//end if
77
 
 
 
 
 
 
 
78
  }
79
 
80
  /**
81
  * Add fields, based on options to REST read/write requests
82
  *
83
  * @since 2.5.6
84
- *
85
- * @access protected
86
  */
87
- protected function add_fields() {
 
 
 
88
 
89
- $fields = $this->pod->fields();
90
 
91
- $rest_hook_name = $this->pod->pod_data['name'];
92
-
93
- if ( 'media' === $rest_hook_name ) {
94
  $rest_hook_name = 'attachment';
95
- } elseif ( 'comment' === $this->pod->pod_data['type'] ) {
96
  $rest_hook_name = 'comment';
97
  }
98
 
99
  $rest_hook_name = 'rest_insert_' . $rest_hook_name;
100
 
101
- if ( ! has_action( $rest_hook_name, array( 'PodsRESTHandlers', 'save_handler' ) ) ) {
102
- add_action( $rest_hook_name, array( 'PodsRESTHandlers', 'save_handler' ), 10, 3 );
103
  }
104
 
105
- foreach ( $fields as $field_name => $field ) {
106
- $read = self::field_allowed_to_extend( $field_name, $this->pod, 'read' );
107
- $write = self::field_allowed_to_extend( $field_name, $this->pod, 'write' );
108
-
109
- $this->register( $field_name, $read, $write );
110
  }
111
-
112
  }
113
 
114
  /**
@@ -118,32 +124,36 @@ class PodsRESTFields {
118
  *
119
  * @access protected
120
  *
121
- * @param string $field_name Name of field
122
- * @param bool $read Field allows REST API read access
123
- * @param bool $write Field allows REST API write access
124
  */
125
- protected function register( $field_name, $read, $write ) {
 
 
126
 
127
- $args = array();
 
 
 
 
 
128
 
129
- if ( $read ) {
130
- $args['get_callback'] = array( 'PodsRESTHandlers', 'get_handler' );
131
  }
132
 
133
- if ( $write ) {
134
- $args['pods_update'] = true;
135
  }
136
 
137
- $object_type = $this->pod->pod;
138
 
139
  if ( 'media' === $object_type ) {
140
  $object_type = 'attachment';
141
  }
142
 
143
- if ( $read || $write ) {
144
- register_rest_field( $object_type, $field_name, $args );
145
  }
146
-
147
  }
148
 
149
  /**
@@ -151,44 +161,39 @@ class PodsRESTFields {
151
  *
152
  * @since 2.5.6
153
  *
154
- * @param string $field_name The field name.
155
- * @param Pods $pod Pods object.
156
- * @param string $mode Are we checking read or write?
157
  *
158
  * @return bool If supports, true, else false.
159
  */
160
- public static function field_allowed_to_extend( $field_name, $pod, $mode = 'read' ) {
 
 
161
 
162
- $allowed = false;
163
-
164
- if ( is_object( $pod ) ) {
165
- $field = $pod->fields( $field_name );
166
-
167
- if ( $field ) {
168
- $pod_options = $pod->pod_data['options'];
169
 
170
- $read_all = (int) pods_v( 'read_all', $pod_options, 0 );
171
- $write_all = (int) pods_v( 'write_all', $pod_options, 0 );
172
 
173
- if ( 'read' === $mode && 1 === $read_all ) {
174
- $allowed = true;
175
- } elseif ( 'write' === $mode && 1 === $write_all ) {
176
- $allowed = true;
177
- } else {
178
- $rest_read = (int) $pod->fields( $field_name, 'rest_read' );
179
- $rest_write = (int) $pod->fields( $field_name, 'rest_write' );
180
 
181
- if ( 'read' === $mode && 1 === $rest_read ) {
182
- $allowed = true;
183
- } elseif ( 'write' === $mode && 1 === $rest_write ) {
184
- $allowed = true;
185
- }
186
- }
187
- }//end if
188
- }//end if
189
 
190
- return $allowed;
 
 
 
191
 
 
192
  }
193
 
194
  }
1
  <?php
2
 
3
+ use Pods\Whatsit\Pod;
4
+ use Pods\Whatsit\Field;
5
+
6
  /**
7
  * Class PodsRESTFields
8
  *
14
  class PodsRESTFields {
15
 
16
  /**
17
+ * Pod object
18
  *
19
  * @since 2.5.6
20
  *
21
  * @access protected
22
  *
23
+ * @var null|Pod
24
  */
25
  protected $pod;
26
 
29
  *
30
  * @since 2.5.6
31
  *
32
+ * @param string|object|Pods|Pod $pod Pods object
33
  */
34
  public function __construct( $pod ) {
 
35
  if ( ! function_exists( 'register_rest_field' ) ) {
36
  return;
37
  }
39
  $this->set_pod( $pod );
40
 
41
  if ( $this->pod ) {
42
+ add_action( 'rest_api_init', [ $this, 'add_fields' ] );
43
  }
 
44
  }
45
 
46
  /**
53
  * @param string|Pods $pod Pods object or name of Pods object
54
  */
55
  private function set_pod( $pod ) {
56
+ $this->pod = null;
57
+
58
+ // Normalize the $pod object.
59
+ $pod = pods_config_for_pod( $pod );
60
+
61
+ // Check if the $pod is valid.
62
+ if ( false === $pod ) {
63
+ return;
64
+ }
65
 
66
+ $type = $pod->get_type();
 
67
 
68
+ $supported_pod_types = [
69
+ 'post_type' => true,
70
+ 'taxonomy' => true,
71
+ 'media' => true,
72
+ 'user' => true,
73
+ 'comment' => true,
74
+ ];
75
 
76
+ // Check if the $type is supported.
77
+ if ( ! isset( $supported_pod_types[ $type ] ) ) {
78
+ return;
79
+ }
 
 
 
80
 
81
+ $rest_enable = filter_var( $pod->get_arg( 'rest_enable', false ), FILTER_VALIDATE_BOOLEAN );
 
 
 
 
 
82
 
83
+ // Check if this Pod has REST API integration enabled.
84
+ if ( ! $rest_enable ) {
85
+ return;
86
+ }
87
+
88
+ $this->pod = $pod;
89
  }
90
 
91
  /**
92
  * Add fields, based on options to REST read/write requests
93
  *
94
  * @since 2.5.6
 
 
95
  */
96
+ public function add_fields() {
97
+ $pod_name = $this->pod->get_name();
98
+ $pod_type = $this->pod->get_type();
99
+ $fields = $this->pod->get_fields();
100
 
101
+ $rest_hook_name = $pod_name;
102
 
103
+ if ( 'media' === $pod_name ) {
 
 
104
  $rest_hook_name = 'attachment';
105
+ } elseif ( 'comment' === $pod_type ) {
106
  $rest_hook_name = 'comment';
107
  }
108
 
109
  $rest_hook_name = 'rest_insert_' . $rest_hook_name;
110
 
111
+ if ( ! has_action( $rest_hook_name, [ 'PodsRESTHandlers', 'save_handler' ] ) ) {
112
+ add_action( $rest_hook_name, [ 'PodsRESTHandlers', 'save_handler' ], 10, 3 );
113
  }
114
 
115
+ foreach ( $fields as $field ) {
116
+ $this->register( $field );
 
 
 
117
  }
 
118
  }
119
 
120
  /**
124
  *
125
  * @access protected
126
  *
127
+ * @param Field $field The field object.
 
 
128
  */
129
+ protected function register( $field ) {
130
+ $rest_read = self::field_allowed_to_extend( $field, $this->pod, 'read' );
131
+ $rest_write = self::field_allowed_to_extend( $field, $this->pod, 'write' );
132
 
133
+ // Check if we have any access.
134
+ if ( ! $rest_read && ! $rest_write ) {
135
+ return;
136
+ }
137
+
138
+ $rest_args = [];
139
 
140
+ if ( $rest_read ) {
141
+ $rest_args['get_callback'] = [ 'PodsRESTHandlers', 'get_handler' ];
142
  }
143
 
144
+ if ( $rest_write ) {
145
+ $rest_args['pods_update'] = true;
146
  }
147
 
148
+ $object_type = $this->pod->get_type();
149
 
150
  if ( 'media' === $object_type ) {
151
  $object_type = 'attachment';
152
  }
153
 
154
+ if ( ! empty( $rest_args ) ) {
155
+ register_rest_field( $object_type, $field->get_name(), $rest_args );
156
  }
 
157
  }
158
 
159
  /**
161
  *
162
  * @since 2.5.6
163
  *
164
+ * @param string|Field $field The field object or name.
165
+ * @param Pod|Pods $pod The Pod object.
166
+ * @param string $mode The mode to use (read or write).
167
  *
168
  * @return bool If supports, true, else false.
169
  */
170
+ public static function field_allowed_to_extend( $field, $pod, $mode ) {
171
+ // Normalize the $pod object.
172
+ $pod = pods_config_for_pod( $pod );
173
 
174
+ // Check if the $pod is valid.
175
+ if ( false === $pod ) {
176
+ return false;
177
+ }
 
 
 
178
 
179
+ $all_fields_access = filter_var( $pod->get_arg( $mode . '_all', false ), FILTER_VALIDATE_BOOLEAN );
 
180
 
181
+ // Check for access on all fields.
182
+ if ( $all_fields_access ) {
183
+ return true;
184
+ }
 
 
 
185
 
186
+ // Maybe get the Field object from the Pod.
187
+ if ( is_string( $field ) ) {
188
+ $field = $pod->get_field( $field );
189
+ }
 
 
 
 
190
 
191
+ // Check if we have a valid $field.
192
+ if ( ! $field instanceof Field ) {
193
+ return false;
194
+ }
195
 
196
+ return filter_var( $field->get_arg( $mode, false ), FILTER_VALIDATE_BOOLEAN );
197
  }
198
 
199
  }
classes/PodsRESTHandlers.php CHANGED
@@ -149,20 +149,16 @@ class PodsRESTHandlers {
149
  * @var $related_pod Pods
150
  */
151
  foreach ( $related_pod_items as $related_pod ) {
152
- if ( ! is_object( $related_pod ) || ! is_a( $related_pod, 'Pods' ) ) {
153
  $items = $related_pod_items;
154
 
155
  break;
156
  }
157
 
158
  if ( false === $fields ) {
159
- $fields = $related_pod->fields();
160
  $fields = array_keys( $fields );
161
 
162
- if ( isset( $related_pod->pod_data['object_fields'] ) && ! empty( $related_pod->pod_data['object_fields'] ) ) {
163
- $fields = array_merge( $fields, array_keys( $related_pod->pod_data['object_fields'] ) );
164
- }
165
-
166
  /**
167
  * What fields to show in a related field REST response.
168
  *
@@ -229,19 +225,19 @@ class PodsRESTHandlers {
229
  */
230
  public static function save_handler( $object, $request, $creating ) {
231
 
232
- if ( is_a( $object, 'WP_Post' ) ) {
233
  $type = $object->post_type;
234
 
235
  $id = $object->ID;
236
- } elseif ( is_a( $object, 'WP_Term' ) ) {
237
  $type = $object->taxonomy;
238
 
239
  $id = $object->term_id;
240
- } elseif ( is_a( $object, 'WP_User' ) ) {
241
  $type = 'user';
242
 
243
  $id = $object->ID;
244
- } elseif ( is_a( $object, 'WP_Comment' ) ) {
245
  $type = 'comment';
246
 
247
  $id = $object->comment_ID;
@@ -252,7 +248,7 @@ class PodsRESTHandlers {
252
 
253
  $pod_name = $type;
254
 
255
- if ( 'attachment' === $type && is_a( $object, 'WP_Post' ) ) {
256
  $pod_name = 'media';
257
  }
258
 
149
  * @var $related_pod Pods
150
  */
151
  foreach ( $related_pod_items as $related_pod ) {
152
+ if ( ! is_object( $related_pod ) || ! $related_pod instanceof Pods ) {
153
  $items = $related_pod_items;
154
 
155
  break;
156
  }
157
 
158
  if ( false === $fields ) {
159
+ $fields = pods_config_get_all_fields( $related_pod );
160
  $fields = array_keys( $fields );
161
 
 
 
 
 
162
  /**
163
  * What fields to show in a related field REST response.
164
  *
225
  */
226
  public static function save_handler( $object, $request, $creating ) {
227
 
228
+ if ( $object instanceof WP_Post ) {
229
  $type = $object->post_type;
230
 
231
  $id = $object->ID;
232
+ } elseif ( $object instanceof WP_Term ) {
233
  $type = $object->taxonomy;
234
 
235
  $id = $object->term_id;
236
+ } elseif ( $object instanceof WP_User ) {
237
  $type = 'user';
238
 
239
  $id = $object->ID;
240
+ } elseif ( $object instanceof WP_Comment ) {
241
  $type = 'comment';
242
 
243
  $id = $object->comment_ID;
248
 
249
  $pod_name = $type;
250
 
251
+ if ( 'attachment' === $type && $object instanceof WP_Post ) {
252
  $pod_name = 'media';
253
  }
254
 
classes/PodsTermSplitting.php CHANGED
@@ -18,7 +18,7 @@ class Pods_Term_Splitting {
18
  private $progress_option_name;
19
 
20
  /** @var array */
21
- private $previous_progress = array();
22
 
23
  /**
24
  * @param int $term_id ID of the formerly shared term.
@@ -26,22 +26,20 @@ class Pods_Term_Splitting {
26
  * @param string $taxonomy Taxonomy for the split term.
27
  */
28
  public function __construct( $term_id, $new_term_id, $taxonomy ) {
29
-
30
  $this->term_id = $term_id;
31
  $this->new_term_id = $new_term_id;
32
  $this->taxonomy = $taxonomy;
33
 
34
  $this->progress_option_name = "_pods_term_split_{$term_id}_{$taxonomy}";
35
-
36
  }
37
 
38
  /**
39
  *
40
  */
41
  public function split_shared_term() {
42
-
43
  // Stash any previous progress
44
  $this->previous_progress = $this->get_progress();
 
45
  if ( empty( $this->previous_progress ) ) {
46
  $this->append_progress( 'started' );
47
  $this->append_progress( "new term ID: {$this->new_term_id}" );
@@ -51,7 +49,7 @@ class Pods_Term_Splitting {
51
  $taxonomy_pod = $this->get_pod_info();
52
 
53
  // Is the taxonomy a Pod?
54
- if ( is_array( $taxonomy_pod ) ) {
55
  $this->update_podsrel_taxonomy( $taxonomy_pod['id'] );
56
 
57
  // Update the Pods table if the taxonomy is a table based Pod
@@ -65,7 +63,6 @@ class Pods_Term_Splitting {
65
 
66
  // Clean up
67
  $this->delete_progress();
68
-
69
  }
70
 
71
  /**
@@ -74,93 +71,119 @@ class Pods_Term_Splitting {
74
  * @return array|bool|mixed|null
75
  */
76
  private function get_pod_info() {
77
-
78
  $pod_info = null;
79
 
80
- if ( pods_api()->pod_exists( $this->taxonomy ) ) {
 
81
 
82
- // Load the taxonomy Pod
83
- $params = array(
84
- 'name' => $this->taxonomy,
85
- 'table_info' => true,
86
- );
87
- $pod_info = pods_api()->load_pod( $params, false );
 
 
 
 
88
  }
89
 
90
  return $pod_info;
91
-
92
  }
93
 
94
  /**
95
  * @param int $pod_id
96
  */
97
  private function update_podsrel_taxonomy( $pod_id ) {
98
-
99
- /** @global wpdb $wpdb */
100
  global $wpdb;
101
 
102
  $task = "update_podsrel_taxonomy_{$pod_id}";
 
103
  if ( ! $this->have_done( $task ) ) {
 
 
 
104
 
105
- // UPDATE {$wpdb->prefix}podsrel SET item_id = {$new_term_id} WHERE pod_id = {$pod_id} AND item_id = {$term_id}
106
- $table = "{$wpdb->prefix}podsrel";
107
- $data = array( 'item_id' => $this->new_term_id );
108
- $where = array(
109
- 'pod_id' => $pod_id,
110
- 'item_id' => $this->term_id,
111
- );
112
- $format = '%d';
113
- $where_format = '%d';
114
 
115
- $wpdb->update( $table, $data, $where, $format, $where_format );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
  $this->append_progress( $task );
118
  }
119
-
120
  }
121
 
122
  /**
123
  * @param string $pod_table
124
  */
125
  private function update_pod_table( $pod_table ) {
126
-
127
- /** @global wpdb $wpdb */
128
  global $wpdb;
129
 
130
  $task = "update_pod_table_{$pod_table}";
131
- if ( ! $this->have_done( $task ) ) {
132
 
 
133
  // Prime the values and update
134
- $data = array( 'id' => $this->new_term_id );
135
- $where = array( 'id' => $this->term_id );
 
 
 
 
 
 
136
  $format = '%d';
137
  $where_format = '%d';
 
138
  $wpdb->update( $pod_table, $data, $where, $format, $where_format );
139
 
140
  $this->append_progress( $task );
141
  }
142
-
143
  }
144
 
145
  /**
146
  * Track down all fields related to the target taxonomy and update stored term IDs as necessary
147
  */
148
  private function update_relationships_to_term() {
149
-
150
  // Loop through all Pods
151
- $all_pods = pods_api()->load_pods();
 
 
 
 
152
 
153
  if ( ! is_array( $all_pods ) ) {
154
  return;
155
  }
156
 
157
  foreach ( $all_pods as $this_pod_id => $this_pod ) {
158
-
159
  // Loop through all fields in this Pod
160
  foreach ( $this_pod['fields'] as $this_field_name => $this_field ) {
161
-
162
  // Ignore everything except relationship fields to this taxonomy
163
- if ( 'pick' !== $this_field['type'] || 'taxonomy' !== $this_field['pick_object'] || $this->taxonomy != $this_field['pick_val'] ) {
164
  continue;
165
  }
166
 
@@ -169,7 +192,6 @@ class Pods_Term_Splitting {
169
 
170
  // Fix-up any special-case relationships that store term IDs in their own meta table and/or serialized
171
  switch ( $this_pod['type'] ) {
172
-
173
  case 'post_type':
174
  $this->update_postmeta( $this_pod['name'], $this_field_name );
175
  break;
@@ -195,29 +217,45 @@ class Pods_Term_Splitting {
195
  * @param int $field_id
196
  */
197
  private function update_podsrel_related_term( $field_id ) {
198
-
199
- /** @global wpdb $wpdb */
200
  global $wpdb;
201
 
202
  $task = "update_podsrel_related_term_{$field_id}";
 
203
  if ( ! $this->have_done( $task ) ) {
 
 
 
204
 
205
- // UPDATE {$wpdb->prefix}podsrel SET related_item_id = {$new_term_id} WHERE field_id = {$field_id} AND related_item_id = {$term_id}
206
- $table = "{$wpdb->prefix}podsrel";
207
- $data = array(
208
- 'related_item_id' => $this->new_term_id,
209
- );
210
- $where = array(
211
- 'field_id' => $field_id,
212
- 'related_item_id' => $this->term_id,
213
- );
214
- $format = '%d';
215
- $where_format = '%d';
216
- $wpdb->update( $table, $data, $where, $format, $where_format );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
 
218
  $this->append_progress( $task );
219
  }
220
-
221
  }
222
 
223
  /**
@@ -227,17 +265,13 @@ class Pods_Term_Splitting {
227
  * @param string $field_name
228
  */
229
  private function update_postmeta( $pod_name, $field_name ) {
230
-
231
- /** @global wpdb $wpdb */
232
  global $wpdb;
233
 
234
  // Fix up the unserialized data
235
  $task = "update_postmeta_{$pod_name}_{$field_name}_unserialized";
236
  if ( ! $this->have_done( $task ) ) {
237
-
238
- $wpdb->query(
239
- $wpdb->prepare(
240
- "
241
  UPDATE
242
  {$wpdb->postmeta} AS meta
243
  LEFT JOIN {$wpdb->posts} AS t
@@ -248,9 +282,7 @@ class Pods_Term_Splitting {
248
  meta_key = %s
249
  AND meta_value = %s
250
  AND t.post_type = %s
251
- ", $this->new_term_id, $field_name, $this->term_id, $pod_name
252
- )
253
- );
254
 
255
  $this->append_progress( $task );
256
  }//end if
@@ -258,14 +290,11 @@ class Pods_Term_Splitting {
258
  // Fix up the serialized data
259
  $task = "update_postmeta_{$pod_name}_{$field_name}_serialized";
260
  if ( ! $this->have_done( $task ) ) {
261
-
262
  $meta_key = sprintf( '_pods_%s', $field_name );
263
  $target_serialized = sprintf( ';i:%s;', $this->term_id );
264
  $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
265
 
266
- $wpdb->query(
267
- $wpdb->prepare(
268
- "
269
  UPDATE
270
  {$wpdb->postmeta} AS meta
271
  LEFT JOIN {$wpdb->posts} AS t
@@ -276,9 +305,7 @@ class Pods_Term_Splitting {
276
  meta.meta_key = %s
277
  AND t.post_type = %s
278
  AND meta_value LIKE '%%%s%%'
279
- ", $target_serialized, $replace_serialized, $meta_key, $pod_name, pods_sanitize_like( $target_serialized )
280
- )
281
- );
282
 
283
  $this->append_progress( $task );
284
  }//end if
@@ -291,22 +318,20 @@ class Pods_Term_Splitting {
291
  * @param string $field_name
292
  */
293
  private function update_commentmeta( $field_name ) {
294
-
295
- /** @global wpdb $wpdb */
296
  global $wpdb;
297
 
298
  // Fix up the unserialized data
299
  $task = "update_commentmeta_{$field_name}_unserialized";
300
  if ( ! $this->have_done( $task ) ) {
301
-
302
  $table = $wpdb->commentmeta;
303
- $data = array( 'meta_value' => $this->new_term_id );
304
- $where = array(
305
  'meta_key' => $field_name,
306
  'meta_value' => $this->term_id,
307
- );
308
  $format = '%s';
309
- $where_format = array( '%s', '%s' );
310
  $wpdb->update( $table, $data, $where, $format, $where_format );
311
 
312
  $this->append_progress( $task );
@@ -315,14 +340,11 @@ class Pods_Term_Splitting {
315
  // Fix up the serialized data
316
  $task = "update_commentmeta_{$field_name}_serialized";
317
  if ( ! $this->have_done( $task ) ) {
318
-
319
  $meta_key = sprintf( '_pods_%s', $field_name );
320
  $target_serialized = sprintf( ';i:%s;', $this->term_id );
321
  $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
322
 
323
- $wpdb->query(
324
- $wpdb->prepare(
325
- "
326
  UPDATE
327
  {$wpdb->commentmeta}
328
  SET
@@ -330,9 +352,7 @@ class Pods_Term_Splitting {
330
  WHERE
331
  meta_key = %s
332
  AND meta_value LIKE '%%%s%%'
333
- ", $target_serialized, $replace_serialized, $meta_key, pods_sanitize_like( $target_serialized )
334
- )
335
- );
336
 
337
  $this->append_progress( $task );
338
  }//end if
@@ -345,22 +365,20 @@ class Pods_Term_Splitting {
345
  * @param string $field_name
346
  */
347
  private function update_usermeta( $field_name ) {
348
-
349
- /** @global wpdb $wpdb */
350
  global $wpdb;
351
 
352
  // Fix up the unserialized data
353
  $task = "update_usermeta_{$field_name}_unserialized";
354
  if ( ! $this->have_done( $task ) ) {
355
-
356
  $table = $wpdb->usermeta;
357
- $data = array( 'meta_value' => $this->new_term_id );
358
- $where = array(
359
  'meta_key' => $field_name,
360
  'meta_value' => $this->term_id,
361
- );
362
  $format = '%s';
363
- $where_format = array( '%s', '%s' );
364
  $wpdb->update( $table, $data, $where, $format, $where_format );
365
 
366
  $this->append_progress( $task );
@@ -369,14 +387,11 @@ class Pods_Term_Splitting {
369
  // Fix up the serialized data
370
  $task = "update_usermeta_{$field_name}_serialized";
371
  if ( ! $this->have_done( $task ) ) {
372
-
373
  $meta_key = sprintf( '_pods_%s', $field_name );
374
  $target_serialized = sprintf( ';i:%s;', $this->term_id );
375
  $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
376
 
377
- $wpdb->query(
378
- $wpdb->prepare(
379
- "
380
  UPDATE
381
  {$wpdb->usermeta}
382
  SET
@@ -384,9 +399,7 @@ class Pods_Term_Splitting {
384
  WHERE
385
  meta_key = %s
386
  AND meta_value LIKE '%%%s%%'
387
- ", $target_serialized, $replace_serialized, $meta_key, pods_sanitize_like( $target_serialized )
388
- )
389
- );
390
 
391
  $this->append_progress( $task );
392
  }//end if
@@ -400,8 +413,7 @@ class Pods_Term_Splitting {
400
  * @param string $field_name
401
  */
402
  private function update_setting_meta( $pod_name, $field_name ) {
403
-
404
- /** @global wpdb $wpdb */
405
  global $wpdb;
406
 
407
  $option_name = "{$pod_name}_{$field_name}";
@@ -409,16 +421,15 @@ class Pods_Term_Splitting {
409
  // Fix up the unserialized data
410
  $task = "update_setting_meta_{$pod_name}_{$field_name}_unserialized";
411
  if ( ! $this->have_done( $task ) ) {
412
-
413
  // UPDATE {$wpdb->options} SET option_value = '{$new_term_id}' WHERE option_name = '{$pod_name}_{$field_name}' AND option_value = '{$term_id}'
414
  $table = $wpdb->options;
415
- $data = array( 'option_value' => $this->new_term_id );
416
- $where = array(
417
  'option_name' => $option_name,
418
  'option_value' => $this->term_id,
419
- );
420
  $format = '%s';
421
- $where_format = array( '%s', '%s' );
422
  $wpdb->update( $table, $data, $where, $format, $where_format );
423
 
424
  $this->append_progress( $task );
@@ -427,13 +438,10 @@ class Pods_Term_Splitting {
427
  // Fix up the serialized data
428
  $task = "update_setting_meta_{$pod_name}_{$field_name}_serialized";
429
  if ( ! $this->have_done( $task ) ) {
430
-
431
  $target_serialized = sprintf( ';i:%s;', $this->term_id );
432
  $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
433
 
434
- $wpdb->query(
435
- $wpdb->prepare(
436
- "
437
  UPDATE
438
  {$wpdb->options}
439
  SET
@@ -441,9 +449,7 @@ class Pods_Term_Splitting {
441
  WHERE
442
  option_name = %s
443
  AND option_value LIKE '%%%s%%'
444
- ", $target_serialized, $replace_serialized, $option_name, pods_sanitize_like( $target_serialized )
445
- )
446
- );
447
 
448
  $this->append_progress( $task );
449
  }//end if
@@ -456,32 +462,28 @@ class Pods_Term_Splitting {
456
  * @return bool
457
  */
458
  private function have_done( $task_name ) {
459
-
460
- return in_array( $task_name, $this->previous_progress );
461
-
462
  }
463
 
464
  /**
465
  * @return array
466
  */
467
  private function get_progress() {
468
-
469
- return get_option( $this->progress_option_name, array() );
470
  }
471
 
472
  /**
473
  * @param $data
474
  */
475
  private function append_progress( $data ) {
476
-
477
  // Get the current progress array
478
  $current_progress = $this->get_progress();
479
  if ( ! is_array( $current_progress ) ) {
480
- $current_progress = array();
481
  }
482
 
483
  // Tack on the new data
484
- $updated_progress = array_merge( $current_progress, array( $data ) );
485
 
486
  // Note: we don't want autoload set and you cannot specify autoload via update_option
487
  if ( ! empty( $current_progress ) && is_array( $current_progress ) ) {
@@ -489,16 +491,13 @@ class Pods_Term_Splitting {
489
  } else {
490
  add_option( $this->progress_option_name, $updated_progress, '', false );
491
  }
492
-
493
  }
494
 
495
  /**
496
  *
497
  */
498
  private function delete_progress() {
499
-
500
  delete_option( $this->progress_option_name );
501
-
502
  }
503
 
504
  }
18
  private $progress_option_name;
19
 
20
  /** @var array */
21
+ private $previous_progress = [];
22
 
23
  /**
24
  * @param int $term_id ID of the formerly shared term.
26
  * @param string $taxonomy Taxonomy for the split term.
27
  */
28
  public function __construct( $term_id, $new_term_id, $taxonomy ) {
 
29
  $this->term_id = $term_id;
30
  $this->new_term_id = $new_term_id;
31
  $this->taxonomy = $taxonomy;
32
 
33
  $this->progress_option_name = "_pods_term_split_{$term_id}_{$taxonomy}";
 
34
  }
35
 
36
  /**
37
  *
38
  */
39
  public function split_shared_term() {
 
40
  // Stash any previous progress
41
  $this->previous_progress = $this->get_progress();
42
+
43
  if ( empty( $this->previous_progress ) ) {
44
  $this->append_progress( 'started' );
45
  $this->append_progress( "new term ID: {$this->new_term_id}" );
49
  $taxonomy_pod = $this->get_pod_info();
50
 
51
  // Is the taxonomy a Pod?
52
+ if ( is_array( $taxonomy_pod ) || $taxonomy_pod instanceof Pods\Whatsit ) {
53
  $this->update_podsrel_taxonomy( $taxonomy_pod['id'] );
54
 
55
  // Update the Pods table if the taxonomy is a table based Pod
63
 
64
  // Clean up
65
  $this->delete_progress();
 
66
  }
67
 
68
  /**
71
  * @return array|bool|mixed|null
72
  */
73
  private function get_pod_info() {
 
74
  $pod_info = null;
75
 
76
+ try {
77
+ $api = pods_api();
78
 
79
+ if ( $api->pod_exists( [ 'name' => $this->taxonomy ] ) ) {
80
+ // Load the taxonomy Pod
81
+ $params = [
82
+ 'name' => $this->taxonomy,
83
+ ];
84
+
85
+ $pod_info = $api->load_pod( $params, false );
86
+ }
87
+ } catch ( Exception $exception ) {
88
+ // Do nothing.
89
  }
90
 
91
  return $pod_info;
 
92
  }
93
 
94
  /**
95
  * @param int $pod_id
96
  */
97
  private function update_podsrel_taxonomy( $pod_id ) {
98
+ /** @var wpdb $wpdb */
 
99
  global $wpdb;
100
 
101
  $task = "update_podsrel_taxonomy_{$pod_id}";
102
+
103
  if ( ! $this->have_done( $task ) ) {
104
+ if ( pods_podsrel_enabled() ) {
105
+ // UPDATE {$wpdb->prefix}podsrel SET item_id = {$new_term_id} WHERE pod_id = {$pod_id} AND item_id = {$term_id}
106
+ $table = "{$wpdb->prefix}podsrel";
107
 
108
+ $data = [
109
+ 'item_id' => $this->new_term_id,
110
+ ];
 
 
 
 
 
 
111
 
112
+ $where = [
113
+ 'pod_id' => $pod_id,
114
+ 'item_id' => $this->term_id,
115
+ ];
116
+
117
+ $format = '%d';
118
+ $where_format = '%d';
119
+
120
+ $wpdb->update( $table, $data, $where, $format, $where_format );
121
+ }
122
+
123
+ /**
124
+ * Allow hooking into the term splitting process for taxonomy.
125
+ *
126
+ * @since 2.8.0
127
+ *
128
+ * @param int $pod_id The pod ID for the taxonomy.
129
+ * @param int $term_id The current term ID being split.
130
+ * @param int $new_term_id The new term ID.
131
+ * @param string $task The task being done.
132
+ */
133
+ do_action( 'pods_term_splitting_update_taxonomy', $pod_id, $this->term_id, $this->new_term_id, $task );
134
 
135
  $this->append_progress( $task );
136
  }
 
137
  }
138
 
139
  /**
140
  * @param string $pod_table
141
  */
142
  private function update_pod_table( $pod_table ) {
143
+ /** @var wpdb $wpdb */
 
144
  global $wpdb;
145
 
146
  $task = "update_pod_table_{$pod_table}";
 
147
 
148
+ if ( ! $this->have_done( $task ) ) {
149
  // Prime the values and update
150
+ $data = [
151
+ 'id' => $this->new_term_id,
152
+ ];
153
+
154
+ $where = [
155
+ 'id' => $this->term_id,
156
+ ];
157
+
158
  $format = '%d';
159
  $where_format = '%d';
160
+
161
  $wpdb->update( $pod_table, $data, $where, $format, $where_format );
162
 
163
  $this->append_progress( $task );
164
  }
 
165
  }
166
 
167
  /**
168
  * Track down all fields related to the target taxonomy and update stored term IDs as necessary
169
  */
170
  private function update_relationships_to_term() {
 
171
  // Loop through all Pods
172
+ try {
173
+ $all_pods = pods_api()->load_pods();
174
+ } catch ( Exception $exception ) {
175
+ return;
176
+ }
177
 
178
  if ( ! is_array( $all_pods ) ) {
179
  return;
180
  }
181
 
182
  foreach ( $all_pods as $this_pod_id => $this_pod ) {
 
183
  // Loop through all fields in this Pod
184
  foreach ( $this_pod['fields'] as $this_field_name => $this_field ) {
 
185
  // Ignore everything except relationship fields to this taxonomy
186
+ if ( 'pick' !== $this_field['type'] || 'taxonomy' !== $this_field['pick_object'] || $this->taxonomy !== $this_field['pick_val'] ) {
187
  continue;
188
  }
189
 
192
 
193
  // Fix-up any special-case relationships that store term IDs in their own meta table and/or serialized
194
  switch ( $this_pod['type'] ) {
 
195
  case 'post_type':
196
  $this->update_postmeta( $this_pod['name'], $this_field_name );
197
  break;
217
  * @param int $field_id
218
  */
219
  private function update_podsrel_related_term( $field_id ) {
220
+ /** @var wpdb $wpdb */
 
221
  global $wpdb;
222
 
223
  $task = "update_podsrel_related_term_{$field_id}";
224
+
225
  if ( ! $this->have_done( $task ) ) {
226
+ if ( pods_podsrel_enabled() ) {
227
+ // UPDATE {$wpdb->prefix}podsrel SET related_item_id = {$new_term_id} WHERE field_id = {$field_id} AND related_item_id = {$term_id}
228
+ $table = "{$wpdb->prefix}podsrel";
229
 
230
+ $data = [
231
+ 'related_item_id' => $this->new_term_id,
232
+ ];
233
+
234
+ $where = [
235
+ 'field_id' => $field_id,
236
+ 'related_item_id' => $this->term_id,
237
+ ];
238
+
239
+ $format = '%d';
240
+ $where_format = '%d';
241
+
242
+ $wpdb->update( $table, $data, $where, $format, $where_format );
243
+ }
244
+
245
+ /**
246
+ * Allow hooking into the term splitting process for taxonomy by related term.
247
+ *
248
+ * @since 2.8.0
249
+ *
250
+ * @param int $field_id The field ID for the relationship.
251
+ * @param int $term_id The current term ID being split.
252
+ * @param int $new_term_id The new term ID.
253
+ * @param string $task The task being done.
254
+ */
255
+ do_action( 'pods_term_splitting_update_related_term', $field_id, $this->term_id, $this->new_term_id, $task );
256
 
257
  $this->append_progress( $task );
258
  }
 
259
  }
260
 
261
  /**
265
  * @param string $field_name
266
  */
267
  private function update_postmeta( $pod_name, $field_name ) {
268
+ /** @var wpdb $wpdb */
 
269
  global $wpdb;
270
 
271
  // Fix up the unserialized data
272
  $task = "update_postmeta_{$pod_name}_{$field_name}_unserialized";
273
  if ( ! $this->have_done( $task ) ) {
274
+ $wpdb->query( $wpdb->prepare( "
 
 
 
275
  UPDATE
276
  {$wpdb->postmeta} AS meta
277
  LEFT JOIN {$wpdb->posts} AS t
282
  meta_key = %s
283
  AND meta_value = %s
284
  AND t.post_type = %s
285
+ ", $this->new_term_id, $field_name, $this->term_id, $pod_name ) );
 
 
286
 
287
  $this->append_progress( $task );
288
  }//end if
290
  // Fix up the serialized data
291
  $task = "update_postmeta_{$pod_name}_{$field_name}_serialized";
292
  if ( ! $this->have_done( $task ) ) {
 
293
  $meta_key = sprintf( '_pods_%s', $field_name );
294
  $target_serialized = sprintf( ';i:%s;', $this->term_id );
295
  $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
296
 
297
+ $wpdb->query( $wpdb->prepare( "
 
 
298
  UPDATE
299
  {$wpdb->postmeta} AS meta
300
  LEFT JOIN {$wpdb->posts} AS t
305
  meta.meta_key = %s
306
  AND t.post_type = %s
307
  AND meta_value LIKE '%%%s%%'
308
+ ", $target_serialized, $replace_serialized, $meta_key, $pod_name, pods_sanitize_like( $target_serialized ) ) );
 
 
309
 
310
  $this->append_progress( $task );
311
  }//end if
318
  * @param string $field_name
319
  */
320
  private function update_commentmeta( $field_name ) {
321
+ /** @var wpdb $wpdb */
 
322
  global $wpdb;
323
 
324
  // Fix up the unserialized data
325
  $task = "update_commentmeta_{$field_name}_unserialized";
326
  if ( ! $this->have_done( $task ) ) {
 
327
  $table = $wpdb->commentmeta;
328
+ $data = [ 'meta_value' => $this->new_term_id ];
329
+ $where = [
330
  'meta_key' => $field_name,
331
  'meta_value' => $this->term_id,
332
+ ];
333
  $format = '%s';
334
+ $where_format = [ '%s', '%s' ];
335
  $wpdb->update( $table, $data, $where, $format, $where_format );
336
 
337
  $this->append_progress( $task );
340
  // Fix up the serialized data
341
  $task = "update_commentmeta_{$field_name}_serialized";
342
  if ( ! $this->have_done( $task ) ) {
 
343
  $meta_key = sprintf( '_pods_%s', $field_name );
344
  $target_serialized = sprintf( ';i:%s;', $this->term_id );
345
  $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
346
 
347
+ $wpdb->query( $wpdb->prepare( "
 
 
348
  UPDATE
349
  {$wpdb->commentmeta}
350
  SET
352
  WHERE
353
  meta_key = %s
354
  AND meta_value LIKE '%%%s%%'
355
+ ", $target_serialized, $replace_serialized, $meta_key, pods_sanitize_like( $target_serialized ) ) );
 
 
356
 
357
  $this->append_progress( $task );
358
  }//end if
365
  * @param string $field_name
366
  */
367
  private function update_usermeta( $field_name ) {
368
+ /** @var wpdb $wpdb */
 
369
  global $wpdb;
370
 
371
  // Fix up the unserialized data
372
  $task = "update_usermeta_{$field_name}_unserialized";
373
  if ( ! $this->have_done( $task ) ) {
 
374
  $table = $wpdb->usermeta;
375
+ $data = [ 'meta_value' => $this->new_term_id ];
376
+ $where = [
377
  'meta_key' => $field_name,
378
  'meta_value' => $this->term_id,
379
+ ];
380
  $format = '%s';
381
+ $where_format = [ '%s', '%s' ];
382
  $wpdb->update( $table, $data, $where, $format, $where_format );
383
 
384
  $this->append_progress( $task );
387
  // Fix up the serialized data
388
  $task = "update_usermeta_{$field_name}_serialized";
389
  if ( ! $this->have_done( $task ) ) {
 
390
  $meta_key = sprintf( '_pods_%s', $field_name );
391
  $target_serialized = sprintf( ';i:%s;', $this->term_id );
392
  $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
393
 
394
+ $wpdb->query( $wpdb->prepare( "
 
 
395
  UPDATE
396
  {$wpdb->usermeta}
397
  SET
399
  WHERE
400
  meta_key = %s
401
  AND meta_value LIKE '%%%s%%'
402
+ ", $target_serialized, $replace_serialized, $meta_key, pods_sanitize_like( $target_serialized ) ) );
 
 
403
 
404
  $this->append_progress( $task );
405
  }//end if
413
  * @param string $field_name
414
  */
415
  private function update_setting_meta( $pod_name, $field_name ) {
416
+ /** @var wpdb $wpdb */
 
417
  global $wpdb;
418
 
419
  $option_name = "{$pod_name}_{$field_name}";
421
  // Fix up the unserialized data
422
  $task = "update_setting_meta_{$pod_name}_{$field_name}_unserialized";
423
  if ( ! $this->have_done( $task ) ) {
 
424
  // UPDATE {$wpdb->options} SET option_value = '{$new_term_id}' WHERE option_name = '{$pod_name}_{$field_name}' AND option_value = '{$term_id}'
425
  $table = $wpdb->options;
426
+ $data = [ 'option_value' => $this->new_term_id ];
427
+ $where = [
428
  'option_name' => $option_name,
429
  'option_value' => $this->term_id,
430
+ ];
431
  $format = '%s';
432
+ $where_format = [ '%s', '%s' ];
433
  $wpdb->update( $table, $data, $where, $format, $where_format );
434
 
435
  $this->append_progress( $task );
438
  // Fix up the serialized data
439
  $task = "update_setting_meta_{$pod_name}_{$field_name}_serialized";
440
  if ( ! $this->have_done( $task ) ) {
 
441
  $target_serialized = sprintf( ';i:%s;', $this->term_id );
442
  $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
443
 
444
+ $wpdb->query( $wpdb->prepare( "
 
 
445
  UPDATE
446
  {$wpdb->options}
447
  SET
449
  WHERE
450
  option_name = %s
451
  AND option_value LIKE '%%%s%%'
452
+ ", $target_serialized, $replace_serialized, $option_name, pods_sanitize_like( $target_serialized ) ) );
 
 
453
 
454
  $this->append_progress( $task );
455
  }//end if
462
  * @return bool
463
  */
464
  private function have_done( $task_name ) {
465
+ return in_array( $task_name, $this->previous_progress, true );
 
 
466
  }
467
 
468
  /**
469
  * @return array
470
  */
471
  private function get_progress() {
472
+ return get_option( $this->progress_option_name, [] );
 
473
  }
474
 
475
  /**
476
  * @param $data
477
  */
478
  private function append_progress( $data ) {
 
479
  // Get the current progress array
480
  $current_progress = $this->get_progress();
481
  if ( ! is_array( $current_progress ) ) {
482
+ $current_progress = [];
483
  }
484
 
485
  // Tack on the new data
486
+ $updated_progress = array_merge( $current_progress, [ $data ] );
487
 
488
  // Note: we don't want autoload set and you cannot specify autoload via update_option
489
  if ( ! empty( $current_progress ) && is_array( $current_progress ) ) {
491
  } else {
492
  add_option( $this->progress_option_name, $updated_progress, '', false );
493
  }
 
494
  }
495
 
496
  /**
497
  *
498
  */
499
  private function delete_progress() {
 
500
  delete_option( $this->progress_option_name );
 
501
  }
502
 
503
  }
classes/PodsUI.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  /**
4
  * @package Pods
5
  */
@@ -468,23 +470,23 @@ class PodsUI {
468
  public $style = 'post_type';
469
 
470
  /**
 
 
471
  * @var bool
472
  */
473
  public $save = false;
474
- // Allow custom save handling for tables that aren't Pod-based
475
 
476
  /**
477
  * Generate UI for Data Management
478
  *
479
- * @param mixed $options Object, Array, or String containing Pod or Options to be used
480
- * @param bool $deprecated Set to true to support old options array from Pods UI plugin
481
  *
482
  * @return \PodsUI
483
  *
484
  * @license http://www.gnu.org/licenses/gpl-2.0.html
485
  * @since 2.0.0
486
  */
487
- public function __construct( $options, $deprecated = false ) {
488
 
489
  $this->_nonce = pods_v( $this->num_prefix . '_wpnonce' . $this->num, 'request' );
490
 
@@ -529,10 +531,6 @@ class PodsUI {
529
  $this->pod = $object;
530
  }
531
 
532
- if ( false !== $deprecated || ( is_object( $this->pod ) && 'Pod' == get_class( $this->pod ) ) ) {
533
- $options = $this->setup_deprecated( $options );
534
- }
535
-
536
  if ( is_object( $this->pod ) && 'Pod' == get_class( $this->pod ) && is_object( $this->pod->_data ) ) {
537
  $this->pods_data =& $this->pod->_data;
538
  } elseif ( is_object( $this->pod ) && 'Pods' == get_class( $this->pod ) && is_object( $this->pod->data ) ) {
@@ -563,370 +561,18 @@ class PodsUI {
563
 
564
  // Assign pod labels
565
  // @todo This is also done in setup(), maybe a better / more central way?
566
- if ( is_object( $this->pod ) && ! empty( $this->pod->pod_data['options'] ) ) {
567
- $pod_options = $this->pod->pod_data['options'];
568
- $pod_name = $this->pod->pod_data['name'];
569
- $pod_options = apply_filters( "pods_advanced_content_type_pod_data_{$pod_name}", $pod_options, $this->pod->pod_data['name'] );
570
- $pod_options = apply_filters( 'pods_advanced_content_type_pod_data', $pod_options, $this->pod->pod_data['name'] );
571
 
572
- $this->label = array_merge( $this->label, $pod_options );
573
  }
574
 
575
  $this->go();
576
  }
577
 
578
- /**
579
- * @param $deprecated_options
580
- *
581
- * @return array
582
- */
583
- public function setup_deprecated( $deprecated_options ) {
584
-
585
- $options = array();
586
-
587
- if ( isset( $deprecated_options['id'] ) ) {
588
- $options['id'] = $deprecated_options['id'];
589
- }
590
- if ( isset( $deprecated_options['action'] ) ) {
591
- $options['action'] = $deprecated_options['action'];
592
- }
593
- if ( isset( $deprecated_options['num'] ) ) {
594
- $options['num'] = $deprecated_options['num'];
595
- }
596
-
597
- if ( isset( $deprecated_options['title'] ) ) {
598
- $options['items'] = $deprecated_options['title'];
599
- }
600
- if ( isset( $deprecated_options['item'] ) ) {
601
- $options['item'] = $deprecated_options['item'];
602
- }
603
-
604
- if ( isset( $deprecated_options['label'] ) ) {
605
- $options['label'] = array(
606
- 'add' => $deprecated_options['label'],
607
- 'edit' => $deprecated_options['label'],
608
- 'duplicate' => $deprecated_options['label'],
609
- );
610
- }
611
- if ( isset( $deprecated_options['label_add'] ) ) {
612
- if ( isset( $options['label'] ) ) {
613
- $options['label']['add'] = $deprecated_options['label_add'];
614
- } else {
615
- $options['label'] = array( 'add' => $deprecated_options['label_add'] );
616
- }
617
- }
618
- if ( isset( $deprecated_options['label_edit'] ) ) {
619
- if ( isset( $options['label'] ) ) {
620
- $options['label']['edit'] = $deprecated_options['label_edit'];
621
- } else {
622
- $options['label'] = array( 'edit' => $deprecated_options['label_edit'] );
623
- }
624
- }
625
- if ( isset( $deprecated_options['label_duplicate'] ) ) {
626
- if ( isset( $options['label'] ) ) {
627
- $options['label']['duplicate'] = $deprecated_options['label_duplicate'];
628
- } else {
629
- $options['label'] = array( 'duplicate' => $deprecated_options['label_duplicate'] );
630
- }
631
- }
632
-
633
- if ( isset( $deprecated_options['icon'] ) ) {
634
- $options['icon'] = $deprecated_options['icon'];
635
- }
636
-
637
- if ( isset( $deprecated_options['columns'] ) ) {
638
- $options['fields'] = array( 'manage' => $deprecated_options['columns'] );
639
- }
640
- if ( isset( $deprecated_options['reorder_columns'] ) ) {
641
- if ( isset( $options['fields'] ) ) {
642
- $options['fields']['reorder'] = $deprecated_options['reorder_columns'];
643
- } else {
644
- $options['fields'] = array( 'reorder' => $deprecated_options['reorder_columns'] );
645
- }
646
- }
647
- if ( isset( $deprecated_options['add_fields'] ) ) {
648
- if ( isset( $options['fields'] ) ) {
649
- if ( ! isset( $options['fields']['add'] ) ) {
650
- $options['fields']['add'] = $deprecated_options['add_fields'];
651
- }
652
- if ( ! isset( $options['fields']['edit'] ) ) {
653
- $options['fields']['edit'] = $deprecated_options['add_fields'];
654
- }
655
- if ( ! isset( $options['fields']['duplicate'] ) ) {
656
- $options['fields']['duplicate'] = $deprecated_options['add_fields'];
657
- }
658
- } else {
659
- $options['fields'] = array(
660
- 'add' => $deprecated_options['add_fields'],
661
- 'edit' => $deprecated_options['add_fields'],
662
- 'duplicate' => $deprecated_options['add_fields'],
663
- );
664
- }
665
- }
666
- if ( isset( $deprecated_options['edit_fields'] ) ) {
667
- if ( isset( $options['fields'] ) ) {
668
- if ( ! isset( $options['fields']['add'] ) ) {
669
- $options['fields']['add'] = $deprecated_options['edit_fields'];
670
- }
671
- if ( ! isset( $options['fields']['edit'] ) ) {
672
- $options['fields']['edit'] = $deprecated_options['edit_fields'];
673
- }
674
- if ( ! isset( $options['fields']['duplicate'] ) ) {
675
- $options['fields']['duplicate'] = $deprecated_options['edit_fields'];
676
- }
677
- } else {
678
- $options['fields'] = array(
679
- 'add' => $deprecated_options['edit_fields'],
680
- 'edit' => $deprecated_options['edit_fields'],
681
- 'duplicate' => $deprecated_options['edit_fields'],
682
- );
683
- }
684
- }
685
- if ( isset( $deprecated_options['duplicate_fields'] ) ) {
686
- if ( isset( $options['fields'] ) ) {
687
- $options['fields']['duplicate'] = $deprecated_options['duplicate_fields'];
688
- } else {
689
- $options['fields'] = array( 'duplicate' => $deprecated_options['duplicate_fields'] );
690
- }
691
- }
692
-
693
- if ( isset( $deprecated_options['session_filters'] ) && false === $deprecated_options['session_filters'] ) {
694
- $options['session'] = false;
695
- }
696
- if ( isset( $deprecated_options['user_per_page'] ) ) {
697
- if ( isset( $options['user'] ) && ! empty( $options['user'] ) ) {
698
- $options['user'] = array( 'orderby' );
699
- } else {
700
- $options['user'] = false;
701
- }
702
- }
703
- if ( isset( $deprecated_options['user_sort'] ) ) {
704
- if ( isset( $options['user'] ) && ! empty( $options['user'] ) ) {
705
- $options['user'] = array( 'show_per_page' );
706
- } else {
707
- $options['user'] = false;
708
- }
709
- }
710
-
711
- if ( isset( $deprecated_options['custom_list'] ) ) {
712
- if ( isset( $options['actions_custom'] ) ) {
713
- $options['actions_custom']['manage'] = $deprecated_options['custom_list'];
714
- } else {
715
- $options['actions_custom'] = array( 'manage' => $deprecated_options['custom_list'] );
716
- }
717
- }
718
- if ( isset( $deprecated_options['custom_reorder'] ) ) {
719
- if ( isset( $options['actions_custom'] ) ) {
720
- $options['actions_custom']['reorder'] = $deprecated_options['custom_reorder'];
721
- } else {
722
- $options['actions_custom'] = array( 'reorder' => $deprecated_options['custom_reorder'] );
723
- }
724
- }
725
- if ( isset( $deprecated_options['custom_add'] ) ) {
726
- if ( isset( $options['actions_custom'] ) ) {
727
- $options['actions_custom']['add'] = $deprecated_options['custom_add'];
728
- } else {
729
- $options['actions_custom'] = array( 'add' => $deprecated_options['custom_add'] );
730
- }
731
- }
732
- if ( isset( $deprecated_options['custom_edit'] ) ) {
733
- if ( isset( $options['actions_custom'] ) ) {
734
- $options['actions_custom']['edit'] = $deprecated_options['custom_edit'];
735
- } else {
736
- $options['actions_custom'] = array( 'edit' => $deprecated_options['custom_edit'] );
737
- }
738
- }
739
- if ( isset( $deprecated_options['custom_duplicate'] ) ) {
740
- if ( isset( $options['actions_custom'] ) ) {
741
- $options['actions_custom']['duplicate'] = $deprecated_options['custom_duplicate'];
742
- } else {
743
- $options['actions_custom'] = array( 'duplicate' => $deprecated_options['custom_duplicate'] );
744
- }
745
- }
746
- if ( isset( $deprecated_options['custom_delete'] ) ) {
747
- if ( isset( $options['actions_custom'] ) ) {
748
- $options['actions_custom']['delete'] = $deprecated_options['custom_delete'];
749
- } else {
750
- $options['actions_custom'] = array( 'delete' => $deprecated_options['custom_delete'] );
751
- }
752
- }
753
- if ( isset( $deprecated_options['custom_save'] ) ) {
754
- if ( isset( $options['actions_custom'] ) ) {
755
- $options['actions_custom']['save'] = $deprecated_options['custom_save'];
756
- } else {
757
- $options['actions_custom'] = array( 'save' => $deprecated_options['custom_save'] );
758
- }
759
- }
760
-
761
- if ( isset( $deprecated_options['custom_actions'] ) ) {
762
- $options['actions_custom'] = $deprecated_options['custom_actions'];
763
- }
764
- if ( isset( $deprecated_options['action_after_save'] ) ) {
765
- $options['action_after'] = array(
766
- 'add' => $deprecated_options['action_after_save'],
767
- 'edit' => $deprecated_options['action_after_save'],
768
- 'duplicate' => $deprecated_options['action_after_save'],
769
- );
770
- }
771
- if ( isset( $deprecated_options['edit_link'] ) ) {
772
- if ( isset( $options['action_links'] ) ) {
773
- $options['action_links']['edit'] = $deprecated_options['edit_link'];
774
- } else {
775
- $options['action_links'] = array( 'edit' => $deprecated_options['edit_link'] );
776
- }
777
- }
778
- if ( isset( $deprecated_options['view_link'] ) ) {
779
- if ( isset( $options['action_links'] ) ) {
780
- $options['action_links']['view'] = $deprecated_options['view_link'];
781
- } else {
782
- $options['action_links'] = array( 'view' => $deprecated_options['view_link'] );
783
- }
784
- }
785
- if ( isset( $deprecated_options['duplicate_link'] ) ) {
786
- if ( isset( $options['action_links'] ) ) {
787
- $options['action_links']['duplicate'] = $deprecated_options['duplicate_link'];
788
- } else {
789
- $options['action_links'] = array( 'duplicate' => $deprecated_options['duplicate_link'] );
790
- }
791
- }
792
-
793
- if ( isset( $deprecated_options['reorder'] ) ) {
794
- $options['reorder'] = array(
795
- 'on' => $deprecated_options['reorder'],
796
- 'orderby' => $deprecated_options['reorder'],
797
- );
798
- }
799
- if ( isset( $deprecated_options['reorder_sort'] ) && isset( $options['reorder'] ) ) {
800
- $options['reorder']['orderby'] = $deprecated_options['reorder_sort'];
801
- }
802
- if ( isset( $deprecated_options['reorder_limit'] ) && isset( $options['reorder'] ) ) {
803
- $options['reorder']['limit'] = $deprecated_options['reorder_limit'];
804
- }
805
- if ( isset( $deprecated_options['reorder_sql'] ) && isset( $options['reorder'] ) ) {
806
- $options['reorder']['sql'] = $deprecated_options['reorder_sql'];
807
- }
808
-
809
- if ( isset( $deprecated_options['sort'] ) ) {
810
- $options['orderby'] = $deprecated_options['sort'];
811
- }
812
- if ( isset( $deprecated_options['sortable'] ) ) {
813
- $options['sortable'] = $deprecated_options['sortable'];
814
- }
815
- if ( isset( $deprecated_options['limit'] ) ) {
816
- $options['limit'] = $deprecated_options['limit'];
817
- }
818
-
819
- if ( isset( $deprecated_options['where'] ) ) {
820
- if ( isset( $options['where'] ) ) {
821
- $options['where']['manage'] = $deprecated_options['where'];
822
- } else {
823
- $options['where'] = array( 'manage' => $deprecated_options['where'] );
824
- }
825
- }
826
- if ( isset( $deprecated_options['edit_where'] ) ) {
827
- /*
828
- if ( isset( $options[ 'where' ] ) )
829
- $options[ 'where' ][ 'edit' ] = $deprecated_options[ 'edit_where' ];
830
- else
831
- $options[ 'where' ] = array( 'edit' => $deprecated_options[ 'edit_where' ] );*/
832
-
833
- if ( isset( $options['restrict'] ) ) {
834
- $options['restrict']['edit'] = (array) $deprecated_options['edit_where'];
835
- } else {
836
- $options['restrict'] = array( 'edit' => (array) $deprecated_options['edit_where'] );
837
- }
838
- }
839
- if ( isset( $deprecated_options['duplicate_where'] ) ) {
840
- /*
841
- if ( isset( $options[ 'where' ] ) )
842
- $options[ 'where' ][ 'duplicate' ] = $deprecated_options[ 'duplicate_where' ];
843
- else
844
- $options[ 'where' ] = array( 'duplicate' => $deprecated_options[ 'duplicate_where' ] );*/
845
-
846
- if ( isset( $options['restrict'] ) ) {
847
- $options['restrict']['duplicate'] = (array) $deprecated_options['duplicate_where'];
848
- } else {
849
- $options['restrict'] = array( 'duplicate' => (array) $deprecated_options['duplicate_where'] );
850
- }
851
- }
852
- if ( isset( $deprecated_options['delete_where'] ) ) {
853
- /*
854
- if ( isset( $options[ 'where' ] ) )
855
- $options[ 'where' ][ 'delete' ] = $deprecated_options[ 'delete_where' ];
856
- else
857
- $options[ 'where' ] = array( 'delete' => $deprecated_options[ 'delete_where' ] );*/
858
-
859
- if ( isset( $options['restrict'] ) ) {
860
- $options['restrict']['delete'] = (array) $deprecated_options['delete_where'];
861
- } else {
862
- $options['restrict'] = array( 'delete' => (array) $deprecated_options['delete_where'] );
863
- }
864
- }
865
- if ( isset( $deprecated_options['reorder_where'] ) ) {
866
- if ( isset( $options['where'] ) ) {
867
- $options['where']['reorder'] = $deprecated_options['reorder_where'];
868
- } else {
869
- $options['where'] = array( 'reorder' => $deprecated_options['reorder_where'] );
870
- }
871
- }
872
-
873
- if ( isset( $deprecated_options['sql'] ) ) {
874
- $options['sql'] = array( 'sql' => $deprecated_options['sql'] );
875
- }
876
-
877
- if ( isset( $deprecated_options['search'] ) ) {
878
- $options['searchable'] = $deprecated_options['search'];
879
- }
880
- if ( isset( $deprecated_options['search_across'] ) ) {
881
- $options['search_across'] = $deprecated_options['search_across'];
882
- }
883
- if ( isset( $deprecated_options['search_across_picks'] ) ) {
884
- $options['search_across_picks'] = $deprecated_options['search_across_picks'];
885
- }
886
- if ( isset( $deprecated_options['filters'] ) ) {
887
- $options['filters'] = $deprecated_options['filters'];
888
- }
889
- if ( isset( $deprecated_options['custom_filters'] ) ) {
890
- if ( is_callable( $deprecated_options['custom_filters'] ) ) {
891
- add_filter( 'pods_ui_filters', $deprecated_options['custom_filters'] );
892
- } else {
893
- global $pods_ui_custom_filters;
894
- $pods_ui_custom_filters = $deprecated_options['custom_filters'];
895
- add_filter( 'pods_ui_filters', array( $this, 'deprecated_filters' ) );
896
- }
897
- }
898
-
899
- if ( isset( $deprecated_options['disable_actions'] ) ) {
900
- $options['actions_disabled'] = $deprecated_options['disable_actions'];
901
- }
902
- if ( isset( $deprecated_options['hide_actions'] ) ) {
903
- $options['actions_hidden'] = $deprecated_options['hide_actions'];
904
- }
905
-
906
- if ( isset( $deprecated_options['wpcss'] ) ) {
907
- $options['wpcss'] = $deprecated_options['wpcss'];
908
- }
909
-
910
- $remaining_options = array_diff_assoc( $options, $deprecated_options );
911
-
912
- foreach ( $remaining_options as $option => $value ) {
913
- if ( isset( $deprecated_options[ $option ] ) && isset( $this->$option ) ) {
914
- $options[ $option ] = $value;
915
- }
916
- }
917
-
918
- return $options;
919
- }
920
-
921
- /**
922
- *
923
- */
924
- public function deprecated_filters() {
925
-
926
- global $pods_ui_custom_filters;
927
- echo $pods_ui_custom_filters;
928
- }
929
-
930
  /**
931
  * @param $options
932
  *
@@ -947,10 +593,10 @@ class PodsUI {
947
  $options->num = '';
948
  }
949
 
950
- $options->validate( 'id', pods_var( $options->num_prefix . 'id' . $options->num, 'get', $this->id ) );
951
 
952
  $options->validate(
953
- 'do', pods_var( $options->num_prefix . 'do' . $options->num, 'get', $this->do ), 'in_array', array(
954
  'save',
955
  'create',
956
  )
@@ -958,14 +604,14 @@ class PodsUI {
958
 
959
  $options->validate( 'excluded', self::$excluded, 'array_merge' );
960
 
961
- $options->validate( 'action', pods_var( $options->num_prefix . 'action' . $options->num, 'get', $this->action, null, true ), 'in_array', $this->actions );
962
  $options->validate( 'actions_bulk', $this->actions_bulk, 'array_merge' );
963
- $options->validate( 'action_bulk', pods_var( $options->num_prefix . 'action_bulk' . $options->num, 'get', $this->action_bulk, null, true ), 'isset', $this->actions_bulk );
964
 
965
- $bulk = pods_var( $options->num_prefix . 'action_bulk_ids' . $options->num, 'get', array(), null, true );
966
 
967
  if ( ! empty( $bulk ) ) {
968
- $bulk = (array) pods_var( $options->num_prefix . 'action_bulk_ids' . $options->num, 'get', array(), null, true );
969
  } else {
970
  $bulk = array();
971
  }
@@ -990,12 +636,13 @@ class PodsUI {
990
  $options->validate( 'limit', pods_v( $options->num_prefix . 'limit' . $options->num, 'get', $this->limit ), 'int' );
991
 
992
  if ( isset( $this->pods_data ) && is_object( $this->pods_data ) ) {
993
- $this->sql = array(
994
  'table' => $this->pods_data->table,
995
  'field_id' => $this->pods_data->field_id,
996
  'field_index' => $this->pods_data->field_index,
997
- );
998
  }
 
999
  $options->validate( 'sql', $this->sql, 'array_merge' );
1000
 
1001
  $options->validate(
@@ -1082,7 +729,7 @@ class PodsUI {
1082
 
1083
  $this->label = array_merge( $this->label, $pod_data['options'] );
1084
 
1085
- $item = pods_v( 'label_singular', $pod_data['options'], pods_v( 'label', $pod_data, $item, true ), true );
1086
  $items = pods_v( 'label', $pod_data, $items, true );
1087
  }
1088
 
@@ -1130,9 +777,16 @@ class PodsUI {
1130
 
1131
  // Set up default manage field.
1132
  if ( empty( $options->fields['manage'] ) ) {
1133
- $options->fields['manage'][ $options->sql['field_index'] ] = array(
1134
- 'label' => __( 'Name', 'pods' ),
1135
- );
 
 
 
 
 
 
 
1136
  }
1137
 
1138
  $options->validate( 'export', $this->export, 'array_merge' );
@@ -1225,7 +879,7 @@ class PodsUI {
1225
  }
1226
  }
1227
 
1228
- $unique_identifier = pods_var( 'page' );
1229
  // wp-admin page
1230
  if ( is_object( $this->pod ) && isset( $this->pod->pod ) ) {
1231
  $unique_identifier = '_' . $this->pod->pod;
@@ -1306,6 +960,8 @@ class PodsUI {
1306
  if ( is_int( $field ) ) {
1307
  $field = $attributes;
1308
  $attributes = array();
 
 
1309
  } else {
1310
  $attributes = array( 'label' => $attributes );
1311
  }
@@ -1315,17 +971,20 @@ class PodsUI {
1315
  $attributes['name'] = $field;
1316
  }
1317
 
1318
- if ( ! isset( $attributes['real_name'] ) ) {
1319
- $attributes['real_name'] = pods_var( 'name', $attributes, $field );
1320
- }
 
1321
 
1322
- if ( is_object( $this->pod ) && isset( $this->pod->fields ) && isset( $this->pod->fields[ $attributes['real_name'] ] ) ) {
1323
- $attributes = array_merge( $this->pod->fields[ $attributes['real_name'] ], $attributes );
 
1324
  }
1325
 
1326
- if ( ! isset( $attributes['options'] ) ) {
1327
- $attributes['options'] = array();
1328
  }
 
1329
  if ( ! isset( $attributes['id'] ) ) {
1330
  $attributes['id'] = '';
1331
  }
@@ -1335,8 +994,8 @@ class PodsUI {
1335
  if ( ! isset( $attributes['type'] ) ) {
1336
  $attributes['type'] = 'text';
1337
  }
1338
- if ( ! isset( $attributes['options']['date_format_type'] ) ) {
1339
- $attributes['options']['date_format_type'] = 'date';
1340
  }
1341
  if ( 'related' !== $attributes['type'] || ! isset( $attributes['related'] ) ) {
1342
  $attributes['related'] = false;
@@ -1388,25 +1047,25 @@ class PodsUI {
1388
  if ( ! isset( $attributes['sortable'] ) || false === $this->sortable ) {
1389
  $attributes['sortable'] = $this->sortable;
1390
  }
1391
- if ( ! isset( $attributes['options']['search'] ) || false === $this->searchable ) {
1392
- $attributes['options']['search'] = $this->searchable;
1393
  }
1394
- if ( ! isset( $attributes['options']['filter'] ) || false === $this->searchable ) {
1395
- $attributes['options']['filter'] = $this->searchable;
1396
  }
1397
  /*
1398
  if ( false !== $attributes[ 'options' ][ 'filter' ] && false !== $filterable )
1399
  $this->filters[] = $field;*/
1400
- if ( false === $attributes['options']['filter'] || ! isset( $attributes['filter_label'] ) || ! in_array( $field, $this->filters ) ) {
1401
  $attributes['filter_label'] = $attributes['label'];
1402
  }
1403
- if ( false === $attributes['options']['filter'] || ! isset( $attributes['filter_default'] ) || ! in_array( $field, $this->filters ) ) {
1404
  $attributes['filter_default'] = false;
1405
  }
1406
- if ( false === $attributes['options']['filter'] || ! isset( $attributes['date_ongoing'] ) || 'date' !== $attributes['type'] || ! in_array( $field, $this->filters ) ) {
1407
  $attributes['date_ongoing'] = false;
1408
  }
1409
- if ( false === $attributes['options']['filter'] || ! isset( $attributes['date_ongoing'] ) || 'date' !== $attributes['type'] || ! isset( $attributes['date_ongoing_default'] ) || ! in_array( $field, $this->filters ) ) {
1410
  $attributes['date_ongoing_default'] = false;
1411
  }
1412
  if ( ! isset( $attributes['export'] ) ) {
@@ -1443,7 +1102,7 @@ class PodsUI {
1443
  if ( ! isset( $attributes['css_values'] ) ) {
1444
  $attributes['css_values'] = true;
1445
  }
1446
- if ( 'search_columns' === $which && ! $attributes['options']['search'] ) {
1447
  continue;
1448
  }
1449
 
@@ -1679,7 +1338,7 @@ class PodsUI {
1679
  }
1680
  }//end if
1681
 
1682
- if ( ! in_array( 'manage', $this->actions_disabled ) ) {
1683
  // handle session / user persistent settings for show_per_page, orderby, search, and filters
1684
  $methods = array( 'session', 'user' );
1685
 
@@ -1701,7 +1360,15 @@ class PodsUI {
1701
  $value = $this->$setting;
1702
  }
1703
 
1704
- pods_v_set( $value, $setting, $method );
 
 
 
 
 
 
 
 
1705
  }
1706
  }
1707
 
@@ -1774,7 +1441,7 @@ class PodsUI {
1774
 
1775
  if ( $duplicate && false !== $this->callback_action( 'duplicate' ) ) {
1776
  return null;
1777
- } elseif ( false !== $this->callback_action( 'edit', $duplicate ) ) {
1778
  return null;
1779
  }
1780
 
@@ -1910,23 +1577,23 @@ class PodsUI {
1910
  }
1911
 
1912
  if ( is_object( $this->pod ) ) {
1913
- $object_fields = (array) pods_var_raw( 'object_fields', $this->pod->pod_data, array(), null, true );
1914
-
1915
- if ( empty( $object_fields ) && in_array(
1916
- $this->pod->pod_data['type'], array(
1917
- 'post_type',
1918
- 'taxonomy',
1919
- 'media',
1920
- 'user',
1921
- 'comment',
1922
- )
1923
- ) ) {
1924
  $object_fields = $this->pod->api->get_wp_object_fields( $this->pod->pod_data['type'], $this->pod->pod_data );
1925
  }
1926
 
1927
  if ( empty( $fields ) ) {
1928
  // Add core object fields if $fields is empty
1929
- $fields = array_merge( $object_fields, $this->pod->fields );
1930
  }
1931
  }
1932
 
@@ -1941,7 +1608,9 @@ class PodsUI {
1941
  'name' => $name,
1942
  );
1943
 
1944
- if ( ! is_array( $field ) ) {
 
 
1945
  $name = $field;
1946
 
1947
  $field = array(
@@ -1949,24 +1618,28 @@ class PodsUI {
1949
  );
1950
  }
1951
 
1952
- $field = array_merge( $defaults, $field );
1953
 
1954
  $field['name'] = trim( $field['name'] );
1955
 
1956
- $default_value = pods_var_raw( 'default', $field );
1957
- $value = pods_var_raw( 'value', $field );
1958
 
1959
  if ( empty( $field['name'] ) ) {
1960
  $field['name'] = trim( $name );
1961
  }
1962
 
1963
  if ( isset( $object_fields[ $field['name'] ] ) ) {
1964
- $field = array_merge( $field, $object_fields[ $field['name'] ] );
 
 
1965
  } elseif ( isset( $this->pod->fields[ $field['name'] ] ) ) {
1966
- $field = array_merge( $this->pod->fields[ $field['name'] ], $field );
 
 
1967
  }
1968
 
1969
- if ( pods_var_raw( 'hidden', $field, false, null, true ) ) {
1970
  $field['type'] = 'hidden';
1971
  }
1972
 
@@ -1990,11 +1663,15 @@ class PodsUI {
1990
  $singular_label = $this->item;
1991
  $plural_label = $this->items;
1992
 
1993
- if ( is_object( $this->pod ) && 'settings' === $this->pod->pod_data['type'] && 'settings' === $this->style ) {
1994
- pods_view( PODS_DIR . 'ui/admin/form-settings.php', compact( array_keys( get_defined_vars() ) ) );
1995
- } else {
1996
- pods_view( PODS_DIR . 'ui/admin/form.php', compact( array_keys( get_defined_vars() ) ) );
 
 
1997
  }
 
 
1998
  }
1999
 
2000
  /**
@@ -2025,7 +1702,7 @@ class PodsUI {
2025
  }
2026
 
2027
  if ( is_object( $this->pod ) ) {
2028
- $object_fields = (array) pods_var_raw( 'object_fields', $this->pod->pod_data, array(), null, true );
2029
 
2030
  $object_field_objects = array(
2031
  'post_type',
@@ -2035,13 +1712,13 @@ class PodsUI {
2035
  'comment',
2036
  );
2037
 
2038
- if ( empty( $object_fields ) && in_array( $this->pod->pod_data['type'], $object_field_objects ) ) {
2039
  $object_fields = $this->pod->api->get_wp_object_fields( $this->pod->pod_data['type'], $this->pod->pod_data );
2040
  }
2041
 
2042
  if ( empty( $fields ) ) {
2043
  // Add core object fields if $fields is empty
2044
- $fields = array_merge( $object_fields, $this->pod->fields );
2045
  }
2046
  }
2047
 
@@ -2058,7 +1735,9 @@ class PodsUI {
2058
  'options' => 'text',
2059
  );
2060
 
2061
- if ( ! is_array( $field ) ) {
 
 
2062
  $name = $field;
2063
 
2064
  $field = array(
@@ -2066,25 +1745,25 @@ class PodsUI {
2066
  );
2067
  }
2068
 
2069
- $field = array_merge( $defaults, $field );
2070
 
2071
  $field['name'] = trim( $field['name'] );
2072
 
2073
- $value = pods_var_raw( 'default', $field );
2074
 
2075
  if ( empty( $field['name'] ) ) {
2076
  $field['name'] = trim( $name );
2077
  }
2078
 
2079
- if ( isset( $object_fields[ $field['name'] ] ) ) {
2080
- $field = array_merge( $field, $object_fields[ $field['name'] ] );
2081
- } elseif ( isset( $this->pod->fields[ $field['name'] ] ) ) {
2082
- $field = array_merge( $this->pod->fields[ $field['name'] ], $field );
2083
  }
2084
 
2085
  if ( pods_v( 'hidden', $field, false, null, true ) || 'hidden' === $field['type'] ) {
2086
  continue;
2087
- } elseif ( ! PodsForm::permission( $field['type'], $field['name'], $field['options'], $fields, $pod, $pod->id() ) ) {
2088
  continue;
2089
  }
2090
 
@@ -2156,7 +1835,7 @@ class PodsUI {
2156
  public function reorder() {
2157
 
2158
  // loop through order
2159
- $order = (array) pods_var_raw( 'order', 'post', array(), null, true );
2160
 
2161
  $params = array(
2162
  'pod' => $this->pod->pod,
@@ -2197,8 +1876,8 @@ class PodsUI {
2197
  foreach ( $this->fields['form'] as $field => $attributes ) {
2198
  $vartype = '%s';
2199
  if ( 'bool' === $attributes['type'] ) {
2200
- $selected = ( 1 == pods_var( $field, 'post', 0 ) ) ? 1 : 0;
2201
- } elseif ( '' == pods_var( $field, 'post', '' ) ) {
2202
  continue;
2203
  }
2204
  if ( false === $attributes['display'] || false !== $attributes['readonly'] ) {
@@ -2220,29 +1899,29 @@ class PodsUI {
2220
  if ( false !== $attributes['date_touch'] || ( false !== $attributes['date_touch_on_create'] && true === $insert && $this->id < 1 ) ) {
2221
  $value = date_i18n( $format );
2222
  } else {
2223
- $value = date_i18n( $format, strtotime( ( 'time' === $attributes['type'] ) ? date_i18n( 'Y-m-d ' ) : pods_var( $field, 'post', '' ) ) );
2224
  }
2225
  } else {
2226
  if ( 'bool' === $attributes['type'] ) {
2227
  $vartype = '%d';
2228
  $value = 0;
2229
- if ( '' != pods_var( $field, 'post', '' ) ) {
2230
  $value = 1;
2231
  }
2232
  } elseif ( 'number' === $attributes['type'] ) {
2233
  $vartype = '%d';
2234
- $value = number_format( pods_var( $field, 'post', 0 ), 0, '', '' );
2235
  } elseif ( 'decimal' === $attributes['type'] ) {
2236
  $vartype = '%d';
2237
- $value = number_format( pods_var( $field, 'post', 0 ), 2, '.', '' );
2238
  } elseif ( 'related' === $attributes['type'] ) {
2239
- if ( is_array( pods_var( $field, 'post', '' ) ) ) {
2240
- $value = implode( ',', pods_var( $field, 'post', '' ) );
2241
  } else {
2242
- $value = pods_var( $field, 'post', '' );
2243
  }
2244
  } else {
2245
- $value = pods_var( $field, 'post', '' );
2246
  }//end if
2247
  }//end if
2248
 
@@ -2261,14 +1940,27 @@ class PodsUI {
2261
  $values[] = $value;
2262
  $data[ $field ] = $value;
2263
  }//end foreach
2264
- $field_sql = implode( ',', $field_sql );
2265
- if ( false === $insert && 0 < $this->id ) {
2266
- $this->insert_id = $this->id;
2267
- $values[] = $this->id;
2268
- $check = $wpdb->query( $wpdb->prepare( "UPDATE $this->sql['table'] SET $field_sql WHERE id=%d", $values ) );
 
 
 
 
2269
  } else {
2270
- $check = $wpdb->query( $wpdb->prepare( "INSERT INTO $this->sql['table'] SET $field_sql", $values ) );
 
 
 
 
 
 
 
 
2271
  }
 
2272
  if ( $check ) {
2273
  if ( empty( $this->insert_id ) ) {
2274
  $this->insert_id = $wpdb->insert_id;
@@ -2277,6 +1969,7 @@ class PodsUI {
2277
  } else {
2278
  $this->error( sprintf( __( '<strong>Error:</strong> %1\$s has not been %2\$s.', 'pods' ), $this->item, $action ) );
2279
  }
 
2280
  $this->do_hook( 'post_save', $this->insert_id, $data, $insert );
2281
  }
2282
 
@@ -2329,7 +2022,7 @@ class PodsUI {
2329
 
2330
  $this->do_hook( 'pre_delete_bulk' );
2331
 
2332
- if ( 1 != pods_var( 'deleted_bulk', 'get', 0 ) ) {
2333
  $ids = $this->bulk;
2334
 
2335
  $success = false;
@@ -2491,7 +2184,7 @@ class PodsUI {
2491
  public function export( $export_type = null ) {
2492
 
2493
  if ( empty( $export_type ) ) {
2494
- $export_type = pods_var( 'export_type', 'get', 'csv' );
2495
  }
2496
 
2497
  $export_type = trim( strtolower( $export_type ) );
@@ -2593,6 +2286,8 @@ class PodsUI {
2593
  $action = $this->action;
2594
  }
2595
 
 
 
2596
  $defaults = array(
2597
  'full' => false,
2598
  'flatten' => true,
@@ -2802,7 +2497,7 @@ class PodsUI {
2802
  $this->pods_data->select( $find_params );
2803
 
2804
  if ( ! $params->full ) {
2805
- $this->data = $this->pods_data->data;
2806
 
2807
  if ( ! empty( $this->data ) ) {
2808
  $this->data_keys = array_keys( $this->data );
@@ -2811,7 +2506,7 @@ class PodsUI {
2811
  $this->total = $this->pods_data->total();
2812
  $this->total_found = $this->pods_data->total_found();
2813
  } else {
2814
- $this->data_full = $this->pods_data->data;
2815
 
2816
  if ( ! empty( $this->data_full ) ) {
2817
  $this->data_keys = array_keys( $this->data_full );
@@ -3034,7 +2729,7 @@ class PodsUI {
3034
  $filter_field = $this->pod->fields[ $filter ];
3035
 
3036
  if ( isset( $this->fields['manage'][ $filter ] ) && is_array( $this->fields['manage'][ $filter ] ) ) {
3037
- $filter_field = array_merge( $filter_field, $this->fields['manage'][ $filter ] );
3038
  }
3039
  } elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
3040
  $filter_field = $this->fields['manage'][ $filter ];
@@ -3044,11 +2739,11 @@ class PodsUI {
3044
  }
3045
 
3046
  if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3047
- if ( '' == pods_var_raw( 'filter_' . $filter . '_start', 'get', '', null, true ) && '' == pods_var_raw( 'filter_' . $filter . '_end', 'get', '', null, true ) ) {
3048
  unset( $filters[ $k ] );
3049
  continue;
3050
  }
3051
- } elseif ( '' === pods_var_raw( 'filter_' . $filter, 'get', '' ) ) {
3052
  unset( $filters[ $k ] );
3053
  continue;
3054
  }
@@ -3088,24 +2783,26 @@ class PodsUI {
3088
  if ( isset( $this->pod->fields[ $filter ] ) ) {
3089
  $filter_field = $this->pod->fields[ $filter ];
3090
 
3091
- if ( isset( $this->fields['manage'][ $filter ] ) && is_array( $this->fields['manage'][ $filter ] ) ) {
3092
- $filter_field = array_merge( $filter_field, $this->fields['manage'][ $filter ] );
3093
  }
3094
  } elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
3095
  $filter_field = $this->fields['manage'][ $filter ];
3096
  } else {
3097
  continue;
3098
  }
 
 
3099
  ?>
3100
  <span class="pods-form-ui-filter-container pods-form-ui-filter-container-<?php echo esc_attr( $filter ); ?>">
3101
  <?php
3102
  if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3103
- $start = pods_var_raw( 'filter_' . $filter . '_start', 'get', pods_var_raw( 'filter_default', $filter_field, '', null, true ), null, true );
3104
- $end = pods_var_raw( 'filter_' . $filter . '_end', 'get', pods_var_raw( 'filter_ongoing_default', $filter_field, '', null, true ), null, true );
3105
 
3106
  // override default value
3107
- $filter_field['options']['default_value'] = '';
3108
- $filter_field['options'][ $filter_field['type'] . '_allow_empty' ] = 1;
3109
 
3110
  if ( ! empty( $start ) && ! in_array( $start, array( '0000-00-00', '0000-00-00 00:00:00', '00:00:00' ) ) ) {
3111
  $start = PodsForm::field_method( $filter_field['type'], 'convert_date', $start, 'n/j/Y' );
@@ -3150,22 +2847,22 @@ class PodsUI {
3150
  PodsForm::field( 'filter_' . $filter . '_end', $end, $filter_field['type'], $filter_field )
3151
  );
3152
  } elseif ( 'pick' === $filter_field['type'] ) {
3153
- $value = pods_var_raw( 'filter_' . $filter );
3154
 
3155
- if ( strlen( $value ) < 1 ) {
3156
- $value = pods_var_raw( 'filter_default', $filter_field );}
3157
 
3158
  // override default value
3159
- $filter_field['options']['default_value'] = '';
3160
 
3161
- $filter_field['options']['pick_format_type'] = 'single';
3162
- $filter_field['options']['pick_format_single'] = 'dropdown';
3163
- $filter_field['options']['pick_allow_add_new'] = 0;
3164
 
3165
- $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true );
3166
- $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', $filter_field['options'], $filter_field['options']['input_helper'], null, true );
3167
 
3168
- $options = array_merge( $filter_field, $filter_field['options'] );
3169
  ?>
3170
  <label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
3171
  <?php esc_html_e( $filter_field['label'] ); ?>
@@ -3184,28 +2881,28 @@ class PodsUI {
3184
  PodsForm::field( 'filter_' . $filter, $value, 'pick', $options )
3185
  );
3186
  } elseif ( 'boolean' === $filter_field['type'] ) {
3187
- $value = pods_var_raw( 'filter_' . $filter, 'get', '' );
3188
 
3189
- if ( strlen( $value ) < 1 ) {
3190
- $value = pods_var_raw( 'filter_default', $filter_field );}
3191
 
3192
  // override default value
3193
- $filter_field['options']['default_value'] = '';
3194
 
3195
- $filter_field['options']['pick_format_type'] = 'single';
3196
- $filter_field['options']['pick_format_single'] = 'dropdown';
3197
- $filter_field['options']['pick_allow_add_new'] = 0;
3198
 
3199
- $filter_field['options']['pick_object'] = 'custom-simple';
3200
- $filter_field['options']['pick_custom'] = array(
3201
- '1' => pods_var_raw( 'boolean_yes_label', $filter_field['options'], __( 'Yes', 'pods' ), null, true ),
3202
- '0' => pods_var_raw( 'boolean_no_label', $filter_field['options'], __( 'No', 'pods' ), null, true ),
3203
  );
3204
 
3205
- $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true );
3206
- $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', $filter_field['options'], $filter_field['options']['input_helper'], null, true );
3207
 
3208
- $options = array_merge( $filter_field, $filter_field['options'] );
3209
  ?>
3210
  <label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
3211
  <?php esc_html_e( $filter_field['label'] ); ?>
@@ -3224,17 +2921,18 @@ class PodsUI {
3224
  PodsForm::field( 'filter_' . $filter, $value, 'pick', $options )
3225
  );
3226
  } else {
3227
- $value = pods_var_raw( 'filter_' . $filter );
3228
 
3229
- if ( strlen( $value ) < 1 ) {
3230
- $value = pods_var_raw( 'filter_default', $filter_field );}
 
3231
 
3232
  // override default value
3233
- $filter_field['options']['default_value'] = '';
3234
 
3235
  $options = array();
3236
- $options['input_helper'] = pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true );
3237
- $options['input_helper'] = pods_var_raw( 'ui_input_helper', $options, $options['input_helper'], null, true );
3238
  ?>
3239
  <label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
3240
  <?php esc_html_e( $filter_field['label'] ); ?>
@@ -3262,7 +2960,7 @@ class PodsUI {
3262
  ?>
3263
  <span class="pods-form-ui-filter-container pods-form-ui-filter-container-search">
3264
  <label<?php echo ( empty( $this->filters ) ) ? ' class="screen-reader-text"' : ''; ?> for="<?php echo esc_attr( $this->num_prefix ); ?>page-search<?php echo esc_attr( $this->num ); ?>-input"><?php _e( 'Search', 'pods' ); ?>:</label>
3265
- <?php echo PodsForm::field( $this->num_prefix . 'search' . $this->num, $this->search, 'text', array( 'attributes' => array( 'id' => 'page-search' . $this->num . '-input' ) ) ); ?>
3266
  </span>
3267
  <?php
3268
  } else {
@@ -3434,8 +3132,8 @@ class PodsUI {
3434
  if ( isset( $this->pod->fields[ $filter ] ) ) {
3435
  $filter_field = $this->pod->fields[ $filter ];
3436
 
3437
- if ( isset( $this->fields['manage'][ $filter ] ) && is_array( $this->fields['manage'][ $filter ] ) ) {
3438
- $filter_field = array_merge( $filter_field, $this->fields['manage'][ $filter ] );
3439
  }
3440
  } elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
3441
  $filter_field = $this->fields['manage'][ $filter ];
@@ -3444,10 +3142,10 @@ class PodsUI {
3444
  }
3445
 
3446
  if ( isset( $filter_field ) && in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3447
- if ( '' == pods_var_raw( 'filter_' . $filter . '_start', 'get', '', null, true ) && '' == pods_var_raw( 'filter_' . $filter . '_end', 'get', '', null, true ) ) {
3448
  unset( $filters[ $k ] );
3449
  }
3450
- } elseif ( '' === pods_var_raw( 'filter_' . $filter, 'get', '' ) ) {
3451
  unset( $filters[ $k ] );
3452
  }
3453
  }
@@ -3505,7 +3203,7 @@ class PodsUI {
3505
  ?>
3506
  <p class="search-box">
3507
  <?php
3508
- if ( $filtered || '' != pods_var_raw( $this->num_prefix . 'search' . $this->num, 'get', '', null, true ) ) {
3509
  $clear_filters = array(
3510
  $this->num_prefix . 'search' . $this->num => false,
3511
  );
@@ -3537,7 +3235,7 @@ class PodsUI {
3537
  ?>
3538
  &nbsp;&nbsp;
3539
  <label class="screen-reader-text" for="<?php echo esc_attr( $this->num_prefix ); ?>page-search<?php echo esc_attr( $this->num ); ?>-input"><?php _e( 'Search', 'pods' ); ?>:</label>
3540
- <?php echo PodsForm::field( $this->num_prefix . 'search' . $this->num, $this->search, 'text', array( 'attributes' => array( 'id' => 'page-search' . $this->num . '-input' ) ) ); ?>
3541
  <?php
3542
  } else {
3543
  echo PodsForm::field( $this->num_prefix . 'search' . $this->num, '', 'hidden' );
@@ -3575,13 +3273,13 @@ class PodsUI {
3575
  }
3576
 
3577
  foreach ( $filters as $filter ) {
3578
- $value = pods_var_raw( 'filter_' . $filter );
3579
 
3580
  if ( isset( $this->pod->fields[ $filter ] ) ) {
3581
  $filter_field = $this->pod->fields[ $filter ];
3582
 
3583
- if ( isset( $this->fields['manage'][ $filter ] ) && is_array( $this->fields['manage'][ $filter ] ) ) {
3584
- $filter_field = array_merge( $filter_field, $this->fields['manage'][ $filter ] );
3585
  }
3586
  } elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
3587
  $filter_field = $this->fields['manage'][ $filter ];
@@ -3596,8 +3294,8 @@ class PodsUI {
3596
  $value_label = '';
3597
 
3598
  if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3599
- $start = pods_var_raw( 'filter_' . $filter . '_start', 'get', '', null, true );
3600
- $end = pods_var_raw( 'filter_' . $filter . '_end', 'get', '', null, true );
3601
 
3602
  if ( ! empty( $start ) && ! in_array(
3603
  $start, array(
@@ -3626,8 +3324,8 @@ class PodsUI {
3626
  $value_label = trim( PodsForm::field_method( 'pick', 'value_to_label', $filter, $value, $filter_field, $this->pod->pod_data, null ) );
3627
  } elseif ( 'boolean' === $filter_field['type'] ) {
3628
  $yesno_options = array(
3629
- '1' => pods_var_raw( 'boolean_yes_label', $filter_field['options'], __( 'Yes', 'pods' ), null, true ),
3630
- '0' => pods_var_raw( 'boolean_no_label', $filter_field['options'], __( 'No', 'pods' ), null, true ),
3631
  );
3632
 
3633
  if ( isset( $yesno_options[ (string) $value ] ) ) {
@@ -3737,24 +3435,26 @@ class PodsUI {
3737
  if ( isset( $this->pod->fields[ $filter ] ) ) {
3738
  $filter_field = $this->pod->fields[ $filter ];
3739
 
3740
- if ( isset( $this->fields['manage'][ $filter ] ) && is_array( $this->fields['manage'][ $filter ] ) ) {
3741
- $filter_field = array_merge( $filter_field, $this->fields['manage'][ $filter ] );
3742
  }
3743
  } elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
3744
  $filter_field = $this->fields['manage'][ $filter ];
3745
  } else {
3746
  continue;
3747
  }
 
 
3748
  ?>
3749
  <p class="pods-ui-posts-filter-toggled pods-ui-posts-filter-<?php echo esc_attr( $filter . ( $zebra ? ' clear' : '' ) ); ?>">
3750
  <?php
3751
  if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3752
- $start = pods_var_raw( 'filter_' . $filter . '_start', 'get', pods_var_raw( 'filter_default', $filter_field, '', null, true ), null, true );
3753
- $end = pods_var_raw( 'filter_' . $filter . '_end', 'get', pods_var_raw( 'filter_ongoing_default', $filter_field, '', null, true ), null, true );
3754
 
3755
  // override default value
3756
- $filter_field['options']['default_value'] = '';
3757
- $filter_field['options'][ $filter_field['type'] . '_allow_empty' ] = 1;
3758
 
3759
  if ( ! empty( $start ) && ! in_array(
3760
  $start, array(
@@ -3817,23 +3517,23 @@ class PodsUI {
3817
  </span>
3818
  <?php
3819
  } elseif ( 'pick' === $filter_field['type'] ) {
3820
- $value = pods_var_raw( 'filter_' . $filter, 'get', '' );
3821
 
3822
- if ( strlen( $value ) < 1 ) {
3823
- $value = pods_var_raw( 'filter_default', $filter_field );
3824
  }
3825
 
3826
  // override default value
3827
- $filter_field['options']['default_value'] = '';
3828
 
3829
- $filter_field['options']['pick_format_type'] = 'single';
3830
- $filter_field['options']['pick_format_single'] = 'dropdown';
3831
- $filter_field['options']['pick_allow_add_new'] = 0;
3832
 
3833
- $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true );
3834
- $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', $filter_field['options'], $filter_field['options']['input_helper'], null, true );
3835
 
3836
- $options = array_merge( $filter_field, $filter_field['options'] );
3837
  ?>
3838
  <span class="pods-ui-posts-filter-toggle toggle-on<?php esc_attr_e( empty( $value ) ? '' : ' pods-hidden' ); ?>">+</span>
3839
  <span class="pods-ui-posts-filter-toggle toggle-off<?php esc_attr_e( empty( $value ) ? ' pods-hidden' : '' ); ?>"><?php _e( 'Clear', 'pods' ); ?></span>
@@ -3842,7 +3542,7 @@ class PodsUI {
3842
  <?php esc_html_e( $filter_field['label'] ); ?>
3843
  </label>
3844
 
3845
- <span class="pods-ui-posts-filter<?php esc_attr_e( strlen( $value ) < 1 ? ' pods-hidden' : '' ); ?>">
3846
  <?php
3847
  // Prevent p div issues.
3848
  echo str_replace(
@@ -3860,29 +3560,29 @@ class PodsUI {
3860
  </span>
3861
  <?php
3862
  } elseif ( 'boolean' === $filter_field['type'] ) {
3863
- $value = pods_var_raw( 'filter_' . $filter, 'get', '' );
3864
 
3865
- if ( strlen( $value ) < 1 ) {
3866
- $value = pods_var_raw( 'filter_default', $filter_field );
3867
  }
3868
 
3869
  // override default value
3870
- $filter_field['options']['default_value'] = '';
3871
 
3872
- $filter_field['options']['pick_format_type'] = 'single';
3873
- $filter_field['options']['pick_format_single'] = 'dropdown';
3874
- $filter_field['options']['pick_allow_add_new'] = 0;
3875
 
3876
- $filter_field['options']['pick_object'] = 'custom-simple';
3877
- $filter_field['options']['pick_custom'] = array(
3878
- '1' => pods_var_raw( 'boolean_yes_label', $filter_field['options'], __( 'Yes', 'pods' ), null, true ),
3879
- '0' => pods_var_raw( 'boolean_no_label', $filter_field['options'], __( 'No', 'pods' ), null, true ),
3880
  );
3881
 
3882
- $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true );
3883
- $filter_field['options']['input_helper'] = pods_var_raw( 'ui_input_helper', $filter_field['options'], $filter_field['options']['input_helper'], null, true );
3884
 
3885
- $options = array_merge( $filter_field, $filter_field['options'] );
3886
  ?>
3887
  <span class="pods-ui-posts-filter-toggle toggle-on<?php esc_attr_e( empty( $value ) ? '' : ' pods-hidden' ); ?>">+</span>
3888
  <span class="pods-ui-posts-filter-toggle toggle-off<?php esc_attr_e( empty( $value ) ? ' pods-hidden' : '' ); ?>"><?php _e( 'Clear', 'pods' ); ?></span>
@@ -3891,7 +3591,7 @@ class PodsUI {
3891
  <?php esc_html_e( $filter_field['label'] ); ?>
3892
  </label>
3893
 
3894
- <span class="pods-ui-posts-filter<?php esc_attr_e( strlen( $value ) < 1 ? ' pods-hidden' : '' ); ?>">
3895
  <?php
3896
  // Prevent p div issues.
3897
  echo str_replace(
@@ -3909,18 +3609,18 @@ class PodsUI {
3909
  </span>
3910
  <?php
3911
  } else {
3912
- $value = pods_var_raw( 'filter_' . $filter );
3913
 
3914
- if ( strlen( $value ) < 1 ) {
3915
- $value = pods_var_raw( 'filter_default', $filter_field );
3916
  }
3917
 
3918
  $options = array(
3919
- 'input_helper' => pods_var_raw( 'ui_input_helper', pods_var_raw( 'options', pods_var_raw( $filter, $this->fields['search'], array(), null, true ), array(), null, true ), '', null, true ),
3920
  );
3921
 
3922
- if ( empty( $options['input_helper'] ) && isset( $filter_field['options'] ) && isset( $filter_field['options']['input_helper'] ) ) {
3923
- $options['input_helper'] = $filter_field['options']['input_helper'];
3924
  }
3925
  ?>
3926
  <span class="pods-ui-posts-filter-toggle toggle-on<?php esc_attr_e( empty( $value ) ? '' : ' pods-hidden' ); ?>">+</span>
@@ -3957,7 +3657,7 @@ class PodsUI {
3957
 
3958
  <p class="pods-ui-posts-filter-toggled pods-ui-posts-filter-search<?php echo esc_attr( $zebra ? ' clear' : '' ); ?>">
3959
  <label for="<?php echo esc_attr( $this->num_prefix ); ?>pods-form-ui-search<?php echo esc_attr( $this->num ); ?>"><?php _e( 'Search Text', 'pods' ); ?></label>
3960
- <?php echo PodsForm::field( $this->num_prefix . 'search' . $this->num, pods_var_raw( $this->num_prefix . 'search' . $this->num ), 'text' ); ?>
3961
  </p>
3962
 
3963
  <?php $zebra = empty( $zebra ); ?>
@@ -4048,7 +3748,7 @@ class PodsUI {
4048
  array(
4049
  $this->num_prefix . 'action' . $this->num => 'reorder',
4050
  $this->num_prefix . 'do' . $this->num => 'save',
4051
- 'page' => pods_var_raw( 'page' ),
4052
  ), self::$allowed, $this->exclusion()
4053
  )
4054
  );
@@ -4246,6 +3946,12 @@ class PodsUI {
4246
 
4247
  $toggle_class = '';
4248
 
 
 
 
 
 
 
4249
  if ( is_array( $this->actions_custom ) && isset( $this->actions_custom['toggle'] ) ) {
4250
  $toggle_class = ' pods-toggled-on';
4251
 
@@ -4254,12 +3960,12 @@ class PodsUI {
4254
  }
4255
  }
4256
  ?>
4257
- <tr id="item-<?php echo esc_attr( $row[ $this->sql['field_id'] ] ); ?>" class="iedit<?php echo esc_attr( $toggle_class ); ?>">
4258
  <?php
4259
  if ( ! empty( $this->actions_bulk ) ) {
4260
  ?>
4261
  <th scope="row" class="check-column">
4262
- <input type="checkbox" name="<?php echo esc_attr( $this->num_prefix ); ?>action_bulk_ids<?php echo esc_attr( $this->num ); ?>[]" value="<?php echo esc_attr( $row[ $this->sql['field_id'] ] ); ?>">
4263
  </th>
4264
  <?php
4265
  }
@@ -4288,13 +3994,11 @@ class PodsUI {
4288
  $attributes,
4289
  )
4290
  );
4291
- } elseif ( is_object( $this->pod ) && class_exists( 'Pods_Helpers' ) ) {
4292
- $row_value = $this->pod->helper( $attributes['custom_display'], $row_value, $field );
4293
  }
4294
  } else {
4295
  ob_start();
4296
 
4297
- $field_value = PodsForm::field_method( $attributes['type'], 'ui', $this->id, $row_value, $field, array_merge( $attributes, pods_var_raw( 'options', $attributes, array(), null, true ) ), $fields, $this->pod );
4298
 
4299
  $field_output = trim( (string) ob_get_clean() );
4300
 
@@ -4311,7 +4015,7 @@ class PodsUI {
4311
  global $wpdb;
4312
  $table = $attributes['custom_relate'];
4313
  $on = $this->sql['field_id'];
4314
- $is = $row[ $this->sql['field_id'] ];
4315
  $what = array( 'name' );
4316
  if ( is_array( $table ) ) {
4317
  if ( isset( $table['on'] ) ) {
@@ -4473,7 +4177,7 @@ class PodsUI {
4473
  $link = pods_query_arg(
4474
  array(
4475
  $this->num_prefix . 'action' . $this->num => 'edit',
4476
- $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ],
4477
  ), self::$allowed, $this->exclusion()
4478
  );
4479
 
@@ -4493,7 +4197,7 @@ class PodsUI {
4493
  $link = pods_query_arg(
4494
  array(
4495
  $this->num_prefix . 'action' . $this->num => 'view',
4496
- $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ],
4497
  ), self::$allowed, $this->exclusion()
4498
  );
4499
 
@@ -4528,7 +4232,7 @@ class PodsUI {
4528
  $toggle = false;
4529
 
4530
  $actions = $this->get_actions( $row );
4531
- $actions = $this->do_hook( 'row_actions', $actions, $row[ $this->sql['field_id'] ] );
4532
 
4533
  if ( ! empty( $actions ) ) {
4534
  ?>
@@ -4545,7 +4249,7 @@ class PodsUI {
4545
  }
4546
  } else {
4547
  ?>
4548
- <input type="hidden" name="order[]" value="<?php echo esc_attr( $row[ $this->sql['field_id'] ] ); ?>" />
4549
  <?php
4550
  }//end if
4551
 
@@ -4654,13 +4358,19 @@ class PodsUI {
4654
  */
4655
  public function get_actions( $row ) {
4656
 
 
 
 
 
 
 
4657
  $actions = array();
4658
 
4659
  if ( ! in_array( 'view', $this->actions_disabled ) && ! in_array( 'view', $this->actions_hidden ) ) {
4660
  $link = pods_query_arg(
4661
  array(
4662
  $this->num_prefix . 'action' . $this->num => 'view',
4663
- $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ],
4664
  ), self::$allowed, $this->exclusion()
4665
  );
4666
 
@@ -4675,7 +4385,7 @@ class PodsUI {
4675
  $link = pods_query_arg(
4676
  array(
4677
  $this->num_prefix . 'action' . $this->num => 'edit',
4678
- $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ],
4679
  ), self::$allowed, $this->exclusion()
4680
  );
4681
 
@@ -4690,7 +4400,7 @@ class PodsUI {
4690
  $link = pods_query_arg(
4691
  array(
4692
  $this->num_prefix . 'action' . $this->num => 'duplicate',
4693
- $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ],
4694
  ), self::$allowed, $this->exclusion()
4695
  );
4696
 
@@ -4705,7 +4415,7 @@ class PodsUI {
4705
  $link = pods_query_arg(
4706
  array(
4707
  $this->num_prefix . 'action' . $this->num => 'delete',
4708
- $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ],
4709
  $this->num_prefix . '_wpnonce' . $this->num => wp_create_nonce( 'pods-ui-action-delete' ),
4710
  ), self::$allowed, $this->exclusion()
4711
  );
@@ -4751,7 +4461,7 @@ class PodsUI {
4751
  if ( ! isset( $custom_data['link'] ) ) {
4752
  $vars = array(
4753
  $this->num_prefix . 'action' . $this->num => $custom_action,
4754
- $this->num_prefix . 'id' . $this->num => $row[ $this->sql['field_id'] ],
4755
  $this->num_prefix . '_wpnonce' . $this->num => wp_create_nonce( 'pods-ui-action-' . $custom_action ),
4756
  );
4757
 
@@ -4777,7 +4487,15 @@ class PodsUI {
4777
  continue;
4778
  }
4779
 
4780
- $actions[ $custom_action ] = '<span class="edit action-' . esc_attr( $custom_action ) . '"><a href="' . esc_url( $this->do_template( $custom_data['link'], $row ) ) . '" title="' . esc_attr( $custom_data['label'] ) . ' this item"' . $confirm . '>' . $custom_data['label'] . '</a></span>';
 
 
 
 
 
 
 
 
4781
  }//end if
4782
  }//end if
4783
  }//end foreach
@@ -5281,9 +4999,9 @@ class PodsUI {
5281
  // @todo Build 'edit', 'duplicate', 'delete' action support for 'where' which runs another find() query
5282
  /*
5283
  if ( !in_array( $action, array( 'manage', 'reorder' ) ) ) {
5284
- $where = pods_var_raw( $action, $this->where, null, null, true );
5285
 
5286
- if ( !empty( $where ) ) {
5287
  $restricted = true;
5288
 
5289
  $old_where = $this->where[ $action ];
@@ -5291,13 +5009,14 @@ class PodsUI {
5291
  $id = $this->row[ $this->sql[ 'field_id' ] ];
5292
 
5293
  if ( is_array( $where ) ) {
5294
- if ( 'OR' == pods_var( 'relation', $where ) )
5295
  $where = array( $where );
 
5296
 
5297
- $where[] = "`t`.`" . $this->sql[ 'field_id' ] . "` = " . (int) $id;
5298
- }
5299
- else
5300
- $where = "( {$where} ) AND `t`.`" . $this->sql[ 'field_id' ] . "` = " . (int) $id;
5301
 
5302
  $this->where[ $action ] = $where;
5303
 
@@ -5307,8 +5026,9 @@ class PodsUI {
5307
 
5308
  $this->where[ $action ] = $old_where;
5309
 
5310
- if ( empty( $data ) )
5311
  $restricted = true;
 
5312
  }
5313
  }*/
5314
 
@@ -5559,14 +5279,14 @@ class PodsUI {
5559
  *
5560
  * @since 2.7.28
5561
  *
5562
- * @param string|array $field The field data.
5563
  *
5564
- * @return array|false The field data or false if invalid / not found.
5565
  */
5566
  public function get_field_data( $field, $which = 'manage' ) {
5567
  $field_data = $field;
5568
 
5569
- if ( ! is_array( $field_data ) ) {
5570
  // Field is not set.
5571
  if ( ! isset( $this->fields[ $which ][ $field ] ) ) {
5572
  return false;
@@ -5586,7 +5306,7 @@ class PodsUI {
5586
  *
5587
  * @since 2.7.28
5588
  *
5589
- * @param string|array $field The field data.
5590
  *
5591
  * @return bool Whether a field is searchable.
5592
  */
@@ -5606,7 +5326,7 @@ class PodsUI {
5606
  }
5607
 
5608
  // Search is turned on individually and we don't have a list of search-only fields.
5609
- return ! empty( $field_data['options']['search'] ) && empty( $this->fields['search'] );
5610
  }
5611
 
5612
  /**
@@ -5614,7 +5334,7 @@ class PodsUI {
5614
  *
5615
  * @since 2.7.28
5616
  *
5617
- * @param string|array $field The field data.
5618
  *
5619
  * @return bool Whether a field is sortable.
5620
  */
1
  <?php
2
 
3
+ use Pods\Whatsit\Field;
4
+
5
  /**
6
  * @package Pods
7
  */
470
  public $style = 'post_type';
471
 
472
  /**
473
+ * Allow custom save handling for tables that aren't Pod-based.
474
+ *
475
  * @var bool
476
  */
477
  public $save = false;
 
478
 
479
  /**
480
  * Generate UI for Data Management
481
  *
482
+ * @param mixed $options Object, Array, or String containing Pod or Options to be used
 
483
  *
484
  * @return \PodsUI
485
  *
486
  * @license http://www.gnu.org/licenses/gpl-2.0.html
487
  * @since 2.0.0
488
  */
489
+ public function __construct( $options ) {
490
 
491
  $this->_nonce = pods_v( $this->num_prefix . '_wpnonce' . $this->num, 'request' );
492
 
531
  $this->pod = $object;
532
  }
533
 
 
 
 
 
534
  if ( is_object( $this->pod ) && 'Pod' == get_class( $this->pod ) && is_object( $this->pod->_data ) ) {
535
  $this->pods_data =& $this->pod->_data;
536
  } elseif ( is_object( $this->pod ) && 'Pods' == get_class( $this->pod ) && is_object( $this->pod->data ) ) {
561
 
562
  // Assign pod labels
563
  // @todo This is also done in setup(), maybe a better / more central way?
564
+ if ( is_object( $this->pod ) && ! empty( $this->pod->pod_data ) ) {
565
+ $pod_data = $this->pod->pod_data;
566
+ $pod_name = $this->pod->pod_data['name'];
567
+ $pod_data = apply_filters( "pods_advanced_content_type_pod_data_{$pod_name}", $pod_data, $this->pod->pod_data['name'] );
568
+ $pod_data = apply_filters( 'pods_advanced_content_type_pod_data', $pod_data, $this->pod->pod_data['name'] );
569
 
570
+ $this->label = array_merge( $this->label, $pod_data['options'] );
571
  }
572
 
573
  $this->go();
574
  }
575
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
576
  /**
577
  * @param $options
578
  *
593
  $options->num = '';
594
  }
595
 
596
+ $options->validate( 'id', pods_v( $options->num_prefix . 'id' . $options->num, 'get', $this->id ) );
597
 
598
  $options->validate(
599
+ 'do', pods_v( $options->num_prefix . 'do' . $options->num, 'get', $this->do ), 'in_array', array(
600
  'save',
601
  'create',
602
  )
604
 
605
  $options->validate( 'excluded', self::$excluded, 'array_merge' );
606
 
607
+ $options->validate( 'action', pods_v( $options->num_prefix . 'action' . $options->num, 'get', $this->action, true ), 'in_array', $this->actions );
608
  $options->validate( 'actions_bulk', $this->actions_bulk, 'array_merge' );
609
+ $options->validate( 'action_bulk', pods_v( $options->num_prefix . 'action_bulk' . $options->num, 'get', $this->action_bulk, true ), 'isset', $this->actions_bulk );
610
 
611
+ $bulk = pods_v( $options->num_prefix . 'action_bulk_ids' . $options->num, 'get', array(), true );
612
 
613
  if ( ! empty( $bulk ) ) {
614
+ $bulk = (array) pods_v( $options->num_prefix . 'action_bulk_ids' . $options->num, 'get', array(), true );
615
  } else {
616
  $bulk = array();
617
  }
636
  $options->validate( 'limit', pods_v( $options->num_prefix . 'limit' . $options->num, 'get', $this->limit ), 'int' );
637
 
638
  if ( isset( $this->pods_data ) && is_object( $this->pods_data ) ) {
639
+ $this->sql = array_merge( $this->sql, array_filter( [
640
  'table' => $this->pods_data->table,
641
  'field_id' => $this->pods_data->field_id,
642
  'field_index' => $this->pods_data->field_index,
643
+ ] ) );
644
  }
645
+
646
  $options->validate( 'sql', $this->sql, 'array_merge' );
647
 
648
  $options->validate(
729
 
730
  $this->label = array_merge( $this->label, $pod_data['options'] );
731
 
732
+ $item = pods_v( 'label_singular', $pod_data, pods_v( 'label', $pod_data, $item, true ), true );
733
  $items = pods_v( 'label', $pod_data, $items, true );
734
  }
735
 
777
 
778
  // Set up default manage field.
779
  if ( empty( $options->fields['manage'] ) ) {
780
+ // Make a local copy of the fields.
781
+ $fields = $options->fields;
782
+
783
+ // Change the info.
784
+ $fields['manage'][ $options->sql['field_index'] ] = [
785
+ 'label' => __( 'Name', 'pods' ),
786
+ ];
787
+
788
+ // Set the object fields property.
789
+ $options->fields = $fields;
790
  }
791
 
792
  $options->validate( 'export', $this->export, 'array_merge' );
879
  }
880
  }
881
 
882
+ $unique_identifier = pods_v( 'page' );
883
  // wp-admin page
884
  if ( is_object( $this->pod ) && isset( $this->pod->pod ) ) {
885
  $unique_identifier = '_' . $this->pod->pod;
960
  if ( is_int( $field ) ) {
961
  $field = $attributes;
962
  $attributes = array();
963
+ } elseif ( $attributes instanceof Field ) {
964
+ $attributes = $attributes->get_args();
965
  } else {
966
  $attributes = array( 'label' => $attributes );
967
  }
971
  $attributes['name'] = $field;
972
  }
973
 
974
+ $field_name = pods_v( 'real_name', $attributes, pods_v( 'name', $attributes, $field ) );
975
+
976
+ if ( is_object( $this->pod ) ) {
977
+ $field_attributes = $this->pod->fields( $field_name );
978
 
979
+ if ( $field_attributes ) {
980
+ $attributes = pods_config_merge_data( $field_attributes, $attributes );
981
+ }
982
  }
983
 
984
+ if ( ! empty( $attributes['options'] ) && is_array( $attributes['options'] ) ) {
985
+ $attributes = pods_config_merge_data( $attributes['options'], $attributes );
986
  }
987
+
988
  if ( ! isset( $attributes['id'] ) ) {
989
  $attributes['id'] = '';
990
  }
994
  if ( ! isset( $attributes['type'] ) ) {
995
  $attributes['type'] = 'text';
996
  }
997
+ if ( ! isset( $attributes['date_format_type'] ) ) {
998
+ $attributes['date_format_type'] = 'date';
999
  }
1000
  if ( 'related' !== $attributes['type'] || ! isset( $attributes['related'] ) ) {
1001
  $attributes['related'] = false;
1047
  if ( ! isset( $attributes['sortable'] ) || false === $this->sortable ) {
1048
  $attributes['sortable'] = $this->sortable;
1049
  }
1050
+ if ( ! isset( $attributes['search'] ) || false === $this->searchable ) {
1051
+ $attributes['search'] = $this->searchable;
1052
  }
1053
+ if ( ! isset( $attributes['filter'] ) || false === $this->searchable ) {
1054
+ $attributes['filter'] = $this->searchable;
1055
  }
1056
  /*
1057
  if ( false !== $attributes[ 'options' ][ 'filter' ] && false !== $filterable )
1058
  $this->filters[] = $field;*/
1059
+ if ( false === $attributes['filter'] || ! isset( $attributes['filter_label'] ) || ! in_array( $field, $this->filters ) ) {
1060
  $attributes['filter_label'] = $attributes['label'];
1061
  }
1062
+ if ( false === $attributes['filter'] || ! isset( $attributes['filter_default'] ) || ! in_array( $field, $this->filters ) ) {
1063
  $attributes['filter_default'] = false;
1064
  }
1065
+ if ( false === $attributes['filter'] || ! isset( $attributes['date_ongoing'] ) || 'date' !== $attributes['type'] || ! in_array( $field, $this->filters ) ) {
1066
  $attributes['date_ongoing'] = false;
1067
  }
1068
+ if ( false === $attributes['filter'] || ! isset( $attributes['date_ongoing'] ) || 'date' !== $attributes['type'] || ! isset( $attributes['date_ongoing_default'] ) || ! in_array( $field, $this->filters ) ) {
1069
  $attributes['date_ongoing_default'] = false;
1070
  }
1071
  if ( ! isset( $attributes['export'] ) ) {
1102
  if ( ! isset( $attributes['css_values'] ) ) {
1103
  $attributes['css_values'] = true;
1104
  }
1105
+ if ( 'search_columns' === $which && ! $attributes['search'] ) {
1106
  continue;
1107
  }
1108
 
1338
  }
1339
  }//end if
1340
 
1341
+ if ( ! in_array( 'manage', $this->actions_disabled, true ) ) {
1342
  // handle session / user persistent settings for show_per_page, orderby, search, and filters
1343
  $methods = array( 'session', 'user' );
1344
 
1360
  $value = $this->$setting;
1361
  }
1362
 
1363
+ $current_value = pods_v( $setting, $method );
1364
+
1365
+ if ( ! is_array( $current_value ) && ! is_array( $value ) ) {
1366
+ if ( (string) $current_value !== (string) $value ) {
1367
+ pods_v_set( $value, $setting, $method );
1368
+ }
1369
+ } elseif ( $current_value !== $value ) {
1370
+ pods_v_set( $value, $setting, $method );
1371
+ }
1372
  }
1373
  }
1374
 
1441
 
1442
  if ( $duplicate && false !== $this->callback_action( 'duplicate' ) ) {
1443
  return null;
1444
+ } elseif ( false !== $this->callback_action( $this->action, $duplicate ) ) {
1445
  return null;
1446
  }
1447
 
1577
  }
1578
 
1579
  if ( is_object( $this->pod ) ) {
1580
+ $object_fields = $this->pod->pod_data->get_object_fields();
1581
+
1582
+ $object_field_objects = array(
1583
+ 'post_type',
1584
+ 'taxonomy',
1585
+ 'media',
1586
+ 'user',
1587
+ 'comment',
1588
+ );
1589
+
1590
+ if ( empty( $object_fields ) && in_array( $this->pod->pod_data['type'], $object_field_objects, true ) ) {
1591
  $object_fields = $this->pod->api->get_wp_object_fields( $this->pod->pod_data['type'], $this->pod->pod_data );
1592
  }
1593
 
1594
  if ( empty( $fields ) ) {
1595
  // Add core object fields if $fields is empty
1596
+ $fields = $this->pod->pod_data->get_all_fields();
1597
  }
1598
  }
1599
 
1608
  'name' => $name,
1609
  );
1610
 
1611
+ $is_field_object = $field instanceof Field;
1612
+
1613
+ if ( ! is_array( $field ) && ! $is_field_object ) {
1614
  $name = $field;
1615
 
1616
  $field = array(
1618
  );
1619
  }
1620
 
1621
+ $field = pods_config_merge_data( $defaults, $field );
1622
 
1623
  $field['name'] = trim( $field['name'] );
1624
 
1625
+ $default_value = pods_v( 'default', $field );
1626
+ $value = pods_v( 'value', $field );
1627
 
1628
  if ( empty( $field['name'] ) ) {
1629
  $field['name'] = trim( $name );
1630
  }
1631
 
1632
  if ( isset( $object_fields[ $field['name'] ] ) ) {
1633
+ $field_attributes = $object_fields[ $field['name'] ];
1634
+
1635
+ $field = pods_config_merge_data( $field, $field_attributes );
1636
  } elseif ( isset( $this->pod->fields[ $field['name'] ] ) ) {
1637
+ $field_attributes = $this->pod->fields[ $field['name'] ];
1638
+
1639
+ $field = pods_config_merge_data( $field_attributes, $field );
1640
  }
1641
 
1642
+ if ( pods_v( 'hidden', $field, false ) ) {
1643
  $field['type'] = 'hidden';
1644
  }
1645
 
1663
  $singular_label = $this->item;
1664
  $plural_label = $this->items;
1665
 
1666
+ $is_settings_pod = is_object( $this->pod ) && 'settings' === $this->pod->pod_data['type'];
1667
+
1668
+ $form_type = 'post';
1669
+
1670
+ if ( 'settings' === $this->style || $is_settings_pod ) {
1671
+ $form_type = 'settings';
1672
  }
1673
+
1674
+ pods_view( PODS_DIR . 'ui/forms/form.php', compact( array_keys( get_defined_vars() ) ) );
1675
  }
1676
 
1677
  /**
1702
  }
1703
 
1704
  if ( is_object( $this->pod ) ) {
1705
+ $object_fields = $this->pod->pod_data->get_object_fields();
1706
 
1707
  $object_field_objects = array(
1708
  'post_type',
1712
  'comment',
1713
  );
1714
 
1715
+ if ( empty( $object_fields ) && in_array( $this->pod->pod_data['type'], $object_field_objects, true ) ) {
1716
  $object_fields = $this->pod->api->get_wp_object_fields( $this->pod->pod_data['type'], $this->pod->pod_data );
1717
  }
1718
 
1719
  if ( empty( $fields ) ) {
1720
  // Add core object fields if $fields is empty
1721
+ $fields = $this->pod->pod_data->get_all_fields();
1722
  }
1723
  }
1724
 
1735
  'options' => 'text',
1736
  );
1737
 
1738
+ $is_field_object = $field instanceof Field;
1739
+
1740
+ if ( ! is_array( $field ) && ! $is_field_object ) {
1741
  $name = $field;
1742
 
1743
  $field = array(
1745
  );
1746
  }
1747
 
1748
+ $field = pods_config_merge_data( $defaults, $field );
1749
 
1750
  $field['name'] = trim( $field['name'] );
1751
 
1752
+ $value = pods_v( 'default', $field );
1753
 
1754
  if ( empty( $field['name'] ) ) {
1755
  $field['name'] = trim( $name );
1756
  }
1757
 
1758
+ $found_field = pods_config_get_field_from_all_fields( $field['name'], $this->pod );
1759
+
1760
+ if ( $found_field ) {
1761
+ $field = pods_config_merge_data( $field, $found_field );
1762
  }
1763
 
1764
  if ( pods_v( 'hidden', $field, false, null, true ) || 'hidden' === $field['type'] ) {
1765
  continue;
1766
+ } elseif ( ! pods_permission( $field ) ) {
1767
  continue;
1768
  }
1769
 
1835
  public function reorder() {
1836
 
1837
  // loop through order
1838
+ $order = (array) pods_v( 'order', 'post', array(), true );
1839
 
1840
  $params = array(
1841
  'pod' => $this->pod->pod,
1876
  foreach ( $this->fields['form'] as $field => $attributes ) {
1877
  $vartype = '%s';
1878
  if ( 'bool' === $attributes['type'] ) {
1879
+ $selected = ( 1 == pods_v( $field, 'post', 0 ) ) ? 1 : 0;
1880
+ } elseif ( '' == pods_v( $field, 'post', '' ) ) {
1881
  continue;
1882
  }
1883
  if ( false === $attributes['display'] || false !== $attributes['readonly'] ) {
1899
  if ( false !== $attributes['date_touch'] || ( false !== $attributes['date_touch_on_create'] && true === $insert && $this->id < 1 ) ) {
1900
  $value = date_i18n( $format );
1901
  } else {
1902
+ $value = date_i18n( $format, strtotime( ( 'time' === $attributes['type'] ) ? date_i18n( 'Y-m-d ' ) : pods_v( $field, 'post', '' ) ) );
1903
  }
1904
  } else {
1905
  if ( 'bool' === $attributes['type'] ) {
1906
  $vartype = '%d';
1907
  $value = 0;
1908
+ if ( '' != pods_v( $field, 'post', '' ) ) {
1909
  $value = 1;
1910
  }
1911
  } elseif ( 'number' === $attributes['type'] ) {
1912
  $vartype = '%d';
1913
+ $value = number_format( pods_v( $field, 'post', 0 ), 0, '', '' );
1914
  } elseif ( 'decimal' === $attributes['type'] ) {
1915
  $vartype = '%d';
1916
+ $value = number_format( pods_v( $field, 'post', 0 ), 2, '.', '' );
1917
  } elseif ( 'related' === $attributes['type'] ) {
1918
+ if ( is_array( pods_v( $field, 'post', '' ) ) ) {
1919
+ $value = implode( ',', pods_v( $field, 'post', '' ) );
1920
  } else {
1921
+ $value = pods_v( $field, 'post', '' );
1922
  }
1923
  } else {
1924
+ $value = pods_v( $field, 'post', '' );
1925
  }//end if
1926
  }//end if
1927
 
1940
  $values[] = $value;
1941
  $data[ $field ] = $value;
1942
  }//end foreach
1943
+
1944
+ if ( $this->pod instanceof Pods ) {
1945
+ if ( false === $insert && 0 < $this->id ) {
1946
+ $this->insert_id = $this->pod->save( $data );
1947
+ } else {
1948
+ $this->insert_id = $this->pod->add( $data );
1949
+ }
1950
+
1951
+ $check = 0 < $this->insert_id;
1952
  } else {
1953
+ $field_sql = implode( ',', $field_sql );
1954
+
1955
+ if ( false === $insert && 0 < $this->id ) {
1956
+ $this->insert_id = $this->id;
1957
+ $values[] = $this->id;
1958
+ $check = $wpdb->query( $wpdb->prepare( "UPDATE $this->sql['table'] SET $field_sql WHERE id=%d", $values ) );
1959
+ } else {
1960
+ $check = $wpdb->query( $wpdb->prepare( "INSERT INTO $this->sql['table'] SET $field_sql", $values ) );
1961
+ }
1962
  }
1963
+
1964
  if ( $check ) {
1965
  if ( empty( $this->insert_id ) ) {
1966
  $this->insert_id = $wpdb->insert_id;
1969
  } else {
1970
  $this->error( sprintf( __( '<strong>Error:</strong> %1\$s has not been %2\$s.', 'pods' ), $this->item, $action ) );
1971
  }
1972
+
1973
  $this->do_hook( 'post_save', $this->insert_id, $data, $insert );
1974
  }
1975
 
2022
 
2023
  $this->do_hook( 'pre_delete_bulk' );
2024
 
2025
+ if ( 1 != pods_v( 'deleted_bulk', 'get', 0 ) ) {
2026
  $ids = $this->bulk;
2027
 
2028
  $success = false;
2184
  public function export( $export_type = null ) {
2185
 
2186
  if ( empty( $export_type ) ) {
2187
+ $export_type = pods_v( 'export_type', 'get', 'csv' );
2188
  }
2189
 
2190
  $export_type = trim( strtolower( $export_type ) );
2286
  $action = $this->action;
2287
  }
2288
 
2289
+ $params = (array) $params;
2290
+
2291
  $defaults = array(
2292
  'full' => false,
2293
  'flatten' => true,
2497
  $this->pods_data->select( $find_params );
2498
 
2499
  if ( ! $params->full ) {
2500
+ $this->data = $this->pods_data->rows;
2501
 
2502
  if ( ! empty( $this->data ) ) {
2503
  $this->data_keys = array_keys( $this->data );
2506
  $this->total = $this->pods_data->total();
2507
  $this->total_found = $this->pods_data->total_found();
2508
  } else {
2509
+ $this->data_full = $this->pods_data->rows;
2510
 
2511
  if ( ! empty( $this->data_full ) ) {
2512
  $this->data_keys = array_keys( $this->data_full );
2729
  $filter_field = $this->pod->fields[ $filter ];
2730
 
2731
  if ( isset( $this->fields['manage'][ $filter ] ) && is_array( $this->fields['manage'][ $filter ] ) ) {
2732
+ $filter_field = pods_config_merge_data( $filter_field, $this->fields['manage'][ $filter ] );
2733
  }
2734
  } elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
2735
  $filter_field = $this->fields['manage'][ $filter ];
2739
  }
2740
 
2741
  if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
2742
+ if ( '' == pods_v( 'filter_' . $filter . '_start', 'get', '', true ) && '' == pods_v( 'filter_' . $filter . '_end', 'get', '', true ) ) {
2743
  unset( $filters[ $k ] );
2744
  continue;
2745
  }
2746
+ } elseif ( '' === pods_v( 'filter_' . $filter, 'get', '' ) ) {
2747
  unset( $filters[ $k ] );
2748
  continue;
2749
  }
2783
  if ( isset( $this->pod->fields[ $filter ] ) ) {
2784
  $filter_field = $this->pod->fields[ $filter ];
2785
 
2786
+ if ( isset( $this->fields['manage'][ $filter ] ) ) {
2787
+ $filter_field = pods_config_merge_data( $filter_field, $this->fields['manage'][ $filter ] );
2788
  }
2789
  } elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
2790
  $filter_field = $this->fields['manage'][ $filter ];
2791
  } else {
2792
  continue;
2793
  }
2794
+
2795
+ $filter_field[ 'disable_dfv' ] = true;
2796
  ?>
2797
  <span class="pods-form-ui-filter-container pods-form-ui-filter-container-<?php echo esc_attr( $filter ); ?>">
2798
  <?php
2799
  if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
2800
+ $start = pods_v( 'filter_' . $filter . '_start', 'get', pods_v( 'filter_default', $filter_field, '', true ), true );
2801
+ $end = pods_v( 'filter_' . $filter . '_end', 'get', pods_v( 'filter_ongoing_default', $filter_field, '', true ), true );
2802
 
2803
  // override default value
2804
+ $filter_field['default_value'] = '';
2805
+ $filter_field[ $filter_field['type'] . '_allow_empty' ] = 1;
2806
 
2807
  if ( ! empty( $start ) && ! in_array( $start, array( '0000-00-00', '0000-00-00 00:00:00', '00:00:00' ) ) ) {
2808
  $start = PodsForm::field_method( $filter_field['type'], 'convert_date', $start, 'n/j/Y' );
2847
  PodsForm::field( 'filter_' . $filter . '_end', $end, $filter_field['type'], $filter_field )
2848
  );
2849
  } elseif ( 'pick' === $filter_field['type'] ) {
2850
+ $value = pods_v( 'filter_' . $filter );
2851
 
2852
+ if ( '' === $value ) {
2853
+ $value = pods_v( 'filter_default', $filter_field );}
2854
 
2855
  // override default value
2856
+ $filter_field['default_value'] = '';
2857
 
2858
+ $filter_field['pick_format_type'] = 'single';
2859
+ $filter_field['pick_format_single'] = 'dropdown';
2860
+ $filter_field['pick_allow_add_new'] = 0;
2861
 
2862
+ $filter_field['input_helper'] = pods_v( 'ui_input_helper', pods_v( $filter, $this->fields['search'] ?: $this->fields['manage'], array(), true ), '', true );
2863
+ $filter_field['input_helper'] = pods_v( 'ui_input_helper', $filter_field, $filter_field['input_helper'], true );
2864
 
2865
+ $options = $filter_field;
2866
  ?>
2867
  <label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
2868
  <?php esc_html_e( $filter_field['label'] ); ?>
2881
  PodsForm::field( 'filter_' . $filter, $value, 'pick', $options )
2882
  );
2883
  } elseif ( 'boolean' === $filter_field['type'] ) {
2884
+ $value = pods_v( 'filter_' . $filter, 'get', '' );
2885
 
2886
+ if ( '' === $value ) {
2887
+ $value = pods_v( 'filter_default', $filter_field );}
2888
 
2889
  // override default value
2890
+ $filter_field['default_value'] = '';
2891
 
2892
+ $filter_field['pick_format_type'] = 'single';
2893
+ $filter_field['pick_format_single'] = 'dropdown';
2894
+ $filter_field['pick_allow_add_new'] = 0;
2895
 
2896
+ $filter_field['pick_object'] = 'custom-simple';
2897
+ $filter_field['pick_custom'] = array(
2898
+ '1' => pods_v( 'boolean_yes_label', $filter_field, __( 'Yes', 'pods' ), true ),
2899
+ '0' => pods_v( 'boolean_no_label', $filter_field, __( 'No', 'pods' ), true ),
2900
  );
2901
 
2902
+ $filter_field['input_helper'] = pods_v( 'ui_input_helper', pods_v( $filter, $this->fields['search'] ?: $this->fields['manage'], array(), true ), '', true );
2903
+ $filter_field['input_helper'] = pods_v( 'ui_input_helper', $filter_field, $filter_field['input_helper'], true );
2904
 
2905
+ $options = $filter_field;
2906
  ?>
2907
  <label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
2908
  <?php esc_html_e( $filter_field['label'] ); ?>
2921
  PodsForm::field( 'filter_' . $filter, $value, 'pick', $options )
2922
  );
2923
  } else {
2924
+ $value = pods_v( 'filter_' . $filter );
2925
 
2926
+ if ( '' === $value ) {
2927
+ $value = pods_v( 'filter_default', $filter_field );
2928
+ }
2929
 
2930
  // override default value
2931
+ $filter_field['default_value'] = '';
2932
 
2933
  $options = array();
2934
+ $options['input_helper'] = pods_v( 'ui_input_helper', pods_v( $filter, $this->fields['search'] ?: $this->fields['manage'], array(), true ), '', true );
2935
+ $options['input_helper'] = pods_v( 'ui_input_helper', $options, $options['input_helper'], true );
2936
  ?>
2937
  <label for="pods-form-ui-filter-<?php echo esc_attr( $filter ); ?>">
2938
  <?php esc_html_e( $filter_field['label'] ); ?>
2960
  ?>
2961
  <span class="pods-form-ui-filter-container pods-form-ui-filter-container-search">
2962
  <label<?php echo ( empty( $this->filters ) ) ? ' class="screen-reader-text"' : ''; ?> for="<?php echo esc_attr( $this->num_prefix ); ?>page-search<?php echo esc_attr( $this->num ); ?>-input"><?php _e( 'Search', 'pods' ); ?>:</label>
2963
+ <?php echo PodsForm::field( $this->num_prefix . 'search' . $this->num, $this->search, 'text', array( 'attributes' => array( 'id' => 'page-search' . $this->num . '-input' ), 'disable_dfv' => true ) ); ?>
2964
  </span>
2965
  <?php
2966
  } else {
3132
  if ( isset( $this->pod->fields[ $filter ] ) ) {
3133
  $filter_field = $this->pod->fields[ $filter ];
3134
 
3135
+ if ( isset( $this->fields['manage'][ $filter ] ) ) {
3136
+ $filter_field = pods_config_merge_data( $filter_field, $this->fields['manage'][ $filter ] );
3137
  }
3138
  } elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
3139
  $filter_field = $this->fields['manage'][ $filter ];
3142
  }
3143
 
3144
  if ( isset( $filter_field ) && in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3145
+ if ( '' == pods_v( 'filter_' . $filter . '_start', 'get', '', true ) && '' == pods_v( 'filter_' . $filter . '_end', 'get', '', true ) ) {
3146
  unset( $filters[ $k ] );
3147
  }
3148
+ } elseif ( '' === pods_v( 'filter_' . $filter, 'get', '' ) ) {
3149
  unset( $filters[ $k ] );
3150
  }
3151
  }
3203
  ?>
3204
  <p class="search-box">
3205
  <?php
3206
+ if ( $filtered || '' != pods_v( $this->num_prefix . 'search' . $this->num, 'get', '', true ) ) {
3207
  $clear_filters = array(
3208
  $this->num_prefix . 'search' . $this->num => false,
3209
  );
3235
  ?>
3236
  &nbsp;&nbsp;
3237
  <label class="screen-reader-text" for="<?php echo esc_attr( $this->num_prefix ); ?>page-search<?php echo esc_attr( $this->num ); ?>-input"><?php _e( 'Search', 'pods' ); ?>:</label>
3238
+ <?php echo PodsForm::field( $this->num_prefix . 'search' . $this->num, $this->search, 'text', array( 'attributes' => array( 'id' => 'page-search' . $this->num . '-input' ), 'disable_dfv' => true ) ); ?>
3239
  <?php
3240
  } else {
3241
  echo PodsForm::field( $this->num_prefix . 'search' . $this->num, '', 'hidden' );
3273
  }
3274
 
3275
  foreach ( $filters as $filter ) {
3276
+ $value = pods_v( 'filter_' . $filter );
3277
 
3278
  if ( isset( $this->pod->fields[ $filter ] ) ) {
3279
  $filter_field = $this->pod->fields[ $filter ];
3280
 
3281
+ if ( isset( $this->fields['manage'][ $filter ] ) ) {
3282
+ $filter_field = pods_config_merge_data( $filter_field, $this->fields['manage'][ $filter ] );
3283
  }
3284
  } elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
3285
  $filter_field = $this->fields['manage'][ $filter ];
3294
  $value_label = '';
3295
 
3296
  if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3297
+ $start = pods_v( 'filter_' . $filter . '_start', 'get', '', true );
3298
+ $end = pods_v( 'filter_' . $filter . '_end', 'get', '', true );
3299
 
3300
  if ( ! empty( $start ) && ! in_array(
3301
  $start, array(
3324
  $value_label = trim( PodsForm::field_method( 'pick', 'value_to_label', $filter, $value, $filter_field, $this->pod->pod_data, null ) );
3325
  } elseif ( 'boolean' === $filter_field['type'] ) {
3326
  $yesno_options = array(
3327
+ '1' => pods_v( 'boolean_yes_label', $filter_field, __( 'Yes', 'pods' ), true ),
3328
+ '0' => pods_v( 'boolean_no_label', $filter_field, __( 'No', 'pods' ), true ),
3329
  );
3330
 
3331
  if ( isset( $yesno_options[ (string) $value ] ) ) {
3435
  if ( isset( $this->pod->fields[ $filter ] ) ) {
3436
  $filter_field = $this->pod->fields[ $filter ];
3437
 
3438
+ if ( isset( $this->fields['manage'][ $filter ] ) ) {
3439
+ $filter_field = pods_config_merge_data( $filter_field, $this->fields['manage'][ $filter ] );
3440
  }
3441
  } elseif ( isset( $this->fields['manage'][ $filter ] ) ) {
3442
  $filter_field = $this->fields['manage'][ $filter ];
3443
  } else {
3444
  continue;
3445
  }
3446
+
3447
+ $filter_field[ 'disable_dfv' ] = true;
3448
  ?>
3449
  <p class="pods-ui-posts-filter-toggled pods-ui-posts-filter-<?php echo esc_attr( $filter . ( $zebra ? ' clear' : '' ) ); ?>">
3450
  <?php
3451
  if ( in_array( $filter_field['type'], array( 'date', 'datetime', 'time' ) ) ) {
3452
+ $start = pods_v( 'filter_' . $filter . '_start', 'get', pods_v( 'filter_default', $filter_field, '', true ), true );
3453
+ $end = pods_v( 'filter_' . $filter . '_end', 'get', pods_v( 'filter_ongoing_default', $filter_field, '', true ), true );
3454
 
3455
  // override default value
3456
+ $filter_field['default_value'] = '';
3457
+ $filter_field[ $filter_field['type'] . '_allow_empty' ] = 1;
3458
 
3459
  if ( ! empty( $start ) && ! in_array(
3460
  $start, array(
3517
  </span>
3518
  <?php
3519
  } elseif ( 'pick' === $filter_field['type'] ) {
3520
+ $value = pods_v( 'filter_' . $filter, 'get', '' );
3521
 
3522
+ if ( '' === $value ) {
3523
+ $value = pods_v( 'filter_default', $filter_field );
3524
  }
3525
 
3526
  // override default value
3527
+ $filter_field['default_value'] = '';
3528
 
3529
+ $filter_field['pick_format_type'] = 'single';
3530
+ $filter_field['pick_format_single'] = 'dropdown';
3531
+ $filter_field['pick_allow_add_new'] = 0;
3532
 
3533
+ $filter_field['input_helper'] = pods_v( 'ui_input_helper', pods_v( $filter, $this->fields['search'] ?: $this->fields['manage'], array(), true ), '', true );
3534
+ $filter_field['input_helper'] = pods_v( 'ui_input_helper', $filter_field, $filter_field['input_helper'], true );
3535
 
3536
+ $options = $filter_field;
3537
  ?>
3538
  <span class="pods-ui-posts-filter-toggle toggle-on<?php esc_attr_e( empty( $value ) ? '' : ' pods-hidden' ); ?>">+</span>
3539
  <span class="pods-ui-posts-filter-toggle toggle-off<?php esc_attr_e( empty( $value ) ? ' pods-hidden' : '' ); ?>"><?php _e( 'Clear', 'pods' ); ?></span>
3542
  <?php esc_html_e( $filter_field['label'] ); ?>
3543
  </label>
3544
 
3545
+ <span class="pods-ui-posts-filter<?php esc_attr_e( '' === $value ? ' pods-hidden' : '' ); ?>">
3546
  <?php
3547
  // Prevent p div issues.
3548
  echo str_replace(
3560
  </span>
3561
  <?php
3562
  } elseif ( 'boolean' === $filter_field['type'] ) {
3563
+ $value = pods_v( 'filter_' . $filter, 'get', '' );
3564
 
3565
+ if ( '' === $value ) {
3566
+ $value = pods_v( 'filter_default', $filter_field );
3567
  }
3568
 
3569
  // override default value
3570
+ $filter_field['default_value'] = '';
3571
 
3572
+ $filter_field['pick_format_type'] = 'single';
3573
+ $filter_field['pick_format_single'] = 'dropdown';
3574
+ $filter_field['pick_allow_add_new'] = 0;
3575
 
3576
+ $filter_field['pick_object'] = 'custom-simple';
3577
+ $filter_field['pick_custom'] = array(
3578
+ '1' => pods_v( 'boolean_yes_label', $filter_field, __( 'Yes', 'pods' ), true ),
3579
+ '0' => pods_v( 'boolean_no_label', $filter_field, __( 'No', 'pods' ), true ),
3580
  );
3581
 
3582
+ $filter_field['input_helper'] = pods_v( 'ui_input_helper', pods_v( $filter, $this->fields['search'] ?: $this->fields['manage'], array(), true ), '', true );
3583
+ $filter_field['input_helper'] = pods_v( 'ui_input_helper', $filter_field, $filter_field['input_helper'], true );
3584
 
3585
+ $options = $filter_field;
3586
  ?>
3587
  <span class="pods-ui-posts-filter-toggle toggle-on<?php esc_attr_e( empty( $value ) ? '' : ' pods-hidden' ); ?>">+</span>
3588
  <span class="pods-ui-posts-filter-toggle toggle-off<?php esc_attr_e( empty( $value ) ? ' pods-hidden' : '' ); ?>"><?php _e( 'Clear', 'pods' ); ?></span>
3591
  <?php esc_html_e( $filter_field['label'] ); ?>
3592
  </label>
3593
 
3594
+ <span class="pods-ui-posts-filter<?php esc_attr_e( '' === $value ? ' pods-hidden' : '' ); ?>">
3595
  <?php
3596
  // Prevent p div issues.
3597
  echo str_replace(
3609
  </span>
3610
  <?php
3611
  } else {
3612
+ $value = pods_v( 'filter_' . $filter );
3613
 
3614
+ if ( '' === $value ) {
3615
+ $value = pods_v( 'filter_default', $filter_field );
3616
  }
3617
 
3618
  $options = array(
3619
+ 'input_helper' => pods_v( 'ui_input_helper', pods_v( 'options', pods_v( $filter, $this->fields['search'], array(), true ), array(), true ), '', true ),
3620
  );
3621
 
3622
+ if ( empty( $options['input_helper'] ) && isset( $filter_field['input_helper'] ) ) {
3623
+ $options['input_helper'] = $filter_field['input_helper'];
3624
  }
3625
  ?>
3626
  <span class="pods-ui-posts-filter-toggle toggle-on<?php esc_attr_e( empty( $value ) ? '' : ' pods-hidden' ); ?>">+</span>
3657
 
3658
  <p class="pods-ui-posts-filter-toggled pods-ui-posts-filter-search<?php echo esc_attr( $zebra ? ' clear' : '' ); ?>">
3659
  <label for="<?php echo esc_attr( $this->num_prefix ); ?>pods-form-ui-search<?php echo esc_attr( $this->num ); ?>"><?php _e( 'Search Text', 'pods' ); ?></label>
3660
+ <?php echo PodsForm::field( $this->num_prefix . 'search' . $this->num, pods_v( $this->num_prefix . 'search' . $this->num ), 'text', [ 'disable_dfv' => true ] ); ?>
3661
  </p>
3662
 
3663
  <?php $zebra = empty( $zebra ); ?>
3748
  array(
3749
  $this->num_prefix . 'action' . $this->num => 'reorder',
3750
  $this->num_prefix . 'do' . $this->num => 'save',
3751
+ 'page' => pods_v( 'page' ),
3752
  ), self::$allowed, $this->exclusion()
3753
  )
3754
  );
3946
 
3947
  $toggle_class = '';
3948
 
3949
+ $field_id = '';
3950
+
3951
+ if ( ! empty( $row[ $this->sql['field_id'] ] ) ) {
3952
+ $field_id = $row[ $this->sql['field_id'] ];
3953
+ }
3954
+
3955
  if ( is_array( $this->actions_custom ) && isset( $this->actions_custom['toggle'] ) ) {
3956
  $toggle_class = ' pods-toggled-on';
3957
 
3960
  }
3961
  }
3962
  ?>
3963
+ <tr id="item-<?php echo esc_attr( $field_id ); ?>" class="iedit<?php echo esc_attr( $toggle_class ); ?>">
3964
  <?php
3965
  if ( ! empty( $this->actions_bulk ) ) {
3966
  ?>
3967
  <th scope="row" class="check-column">
3968
+ <input type="checkbox" name="<?php echo esc_attr( $this->num_prefix ); ?>action_bulk_ids<?php echo esc_attr( $this->num ); ?>[]" value="<?php echo esc_attr( $field_id ); ?>">
3969
  </th>
3970
  <?php
3971
  }
3994
  $attributes,
3995
  )
3996
  );
 
 
3997
  }
3998
  } else {
3999
  ob_start();
4000
 
4001
+ $field_value = PodsForm::field_method( $attributes['type'], 'ui', $this->id, $row_value, $field, $attributes, $fields, $this->pod );
4002
 
4003
  $field_output = trim( (string) ob_get_clean() );
4004
 
4015
  global $wpdb;
4016
  $table = $attributes['custom_relate'];
4017
  $on = $this->sql['field_id'];
4018
+ $is = $field_id;
4019
  $what = array( 'name' );
4020
  if ( is_array( $table ) ) {
4021
  if ( isset( $table['on'] ) ) {
4177
  $link = pods_query_arg(
4178
  array(
4179
  $this->num_prefix . 'action' . $this->num => 'edit',
4180
+ $this->num_prefix . 'id' . $this->num => $field_id,
4181
  ), self::$allowed, $this->exclusion()
4182
  );
4183
 
4197
  $link = pods_query_arg(
4198
  array(
4199
  $this->num_prefix . 'action' . $this->num => 'view',
4200
+ $this->num_prefix . 'id' . $this->num => $field_id,
4201
  ), self::$allowed, $this->exclusion()
4202
  );
4203
 
4232
  $toggle = false;
4233
 
4234
  $actions = $this->get_actions( $row );
4235
+ $actions = $this->do_hook( 'row_actions', $actions, $field_id );
4236
 
4237
  if ( ! empty( $actions ) ) {
4238
  ?>
4249
  }
4250
  } else {
4251
  ?>
4252
+ <input type="hidden" name="order[]" value="<?php echo esc_attr( $field_id ); ?>" />
4253
  <?php
4254
  }//end if
4255
 
4358
  */
4359
  public function get_actions( $row ) {
4360
 
4361
+ $field_id = '';
4362
+
4363
+ if ( ! empty( $row[ $this->sql['field_id'] ] ) ) {
4364
+ $field_id = $row[ $this->sql['field_id'] ];
4365
+ }
4366
+
4367
  $actions = array();
4368
 
4369
  if ( ! in_array( 'view', $this->actions_disabled ) && ! in_array( 'view', $this->actions_hidden ) ) {
4370
  $link = pods_query_arg(
4371
  array(
4372
  $this->num_prefix . 'action' . $this->num => 'view',
4373
+ $this->num_prefix . 'id' . $this->num => $field_id,
4374
  ), self::$allowed, $this->exclusion()
4375
  );
4376
 
4385
  $link = pods_query_arg(
4386
  array(
4387
  $this->num_prefix . 'action' . $this->num => 'edit',
4388
+ $this->num_prefix . 'id' . $this->num => $field_id,
4389
  ), self::$allowed, $this->exclusion()
4390
  );
4391
 
4400
  $link = pods_query_arg(
4401
  array(
4402
  $this->num_prefix . 'action' . $this->num => 'duplicate',
4403
+ $this->num_prefix . 'id' . $this->num => $field_id,
4404
  ), self::$allowed, $this->exclusion()
4405
  );
4406
 
4415
  $link = pods_query_arg(
4416
  array(
4417
  $this->num_prefix . 'action' . $this->num => 'delete',
4418
+ $this->num_prefix . 'id' . $this->num => $field_id,
4419
  $this->num_prefix . '_wpnonce' . $this->num => wp_create_nonce( 'pods-ui-action-delete' ),
4420
  ), self::$allowed, $this->exclusion()
4421
  );
4461
  if ( ! isset( $custom_data['link'] ) ) {
4462
  $vars = array(
4463
  $this->num_prefix . 'action' . $this->num => $custom_action,
4464
+ $this->num_prefix . 'id' . $this->num => $field_id,
4465
  $this->num_prefix . '_wpnonce' . $this->num => wp_create_nonce( 'pods-ui-action-' . $custom_action ),
4466
  );
4467
 
4487
  continue;
4488
  }
4489
 
4490
+ $span_class = 'edit';
4491
+
4492
+ if ( isset( $custom_data['span_class'] ) ) {
4493
+ $span_class = $custom_data['span_class'];
4494
+ }
4495
+
4496
+ $span_class .= ' action-' . $custom_action;
4497
+
4498
+ $actions[ $custom_action ] = '<span class="' . esc_attr( $span_class ) . '"><a href="' . esc_url( $this->do_template( $custom_data['link'], $row ) ) . '" title="' . esc_attr( $custom_data['label'] ) . ' this item"' . $confirm . '>' . $custom_data['label'] . '</a></span>';
4499
  }//end if
4500
  }//end if
4501
  }//end foreach
4999
  // @todo Build 'edit', 'duplicate', 'delete' action support for 'where' which runs another find() query
5000
  /*
5001
  if ( !in_array( $action, array( 'manage', 'reorder' ) ) ) {
5002
+ $where = pods_v( $action, $this->where, null, true );
5003
 
5004
+ if ( ! empty( $where ) ) {
5005
  $restricted = true;
5006
 
5007
  $old_where = $this->where[ $action ];
5009
  $id = $this->row[ $this->sql[ 'field_id' ] ];
5010
 
5011
  if ( is_array( $where ) ) {
5012
+ if ( 'OR' == pods_v( 'relation', $where ) ) {
5013
  $where = array( $where );
5014
+ }
5015
 
5016
+ $where[] = "`t`.`" . $this->sql['field_id'] . "` = " . (int) $id;
5017
+ } else {
5018
+ $where = "( {$where} ) AND `t`.`" . $this->sql['field_id'] . "` = " . (int) $id;
5019
+ }
5020
 
5021
  $this->where[ $action ] = $where;
5022
 
5026
 
5027
  $this->where[ $action ] = $old_where;
5028
 
5029
+ if ( empty( $data ) ) {
5030
  $restricted = true;
5031
+ }
5032
  }
5033
  }*/
5034
 
5279
  *
5280
  * @since 2.7.28
5281
  *
5282
+ * @param string|array|Field $field The field data.
5283
  *
5284
+ * @return array|Field|false The field data or false if invalid / not found.
5285
  */
5286
  public function get_field_data( $field, $which = 'manage' ) {
5287
  $field_data = $field;
5288
 
5289
+ if ( ! is_array( $field_data ) && ! $field_data instanceof Field ) {
5290
  // Field is not set.
5291
  if ( ! isset( $this->fields[ $which ][ $field ] ) ) {
5292
  return false;
5306
  *
5307
  * @since 2.7.28
5308
  *
5309
+ * @param string|array|Field $field The field data.
5310
  *
5311
  * @return bool Whether a field is searchable.
5312
  */
5326
  }
5327
 
5328
  // Search is turned on individually and we don't have a list of search-only fields.
5329
+ return ! empty( $field_data['search'] ) && empty( $this->fields['search'] );
5330
  }
5331
 
5332
  /**
5334
  *
5335
  * @since 2.7.28
5336
  *
5337
+ * @param string|array|Field $field The field data.
5338
  *
5339
  * @return bool Whether a field is sortable.
5340
  */
classes/PodsView.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  /**
4
  * @package Pods
5
  */
@@ -8,7 +10,7 @@ class PodsView {
8
  /**
9
  * @var array $cache_modes Array of available cache modes
10
  */
11
- public static $cache_modes = array( 'none', 'transient', 'site-transient', 'cache', 'option-cache' );
12
 
13
  /**
14
  * @return \PodsView
@@ -261,6 +263,10 @@ class PodsView {
261
  if ( false !== $value ) {
262
  $value = apply_filters( "transient_{$key}", $value );
263
  }
 
 
 
 
264
  } else {
265
  $value = false;
266
  }//end if
@@ -358,6 +364,10 @@ class PodsView {
358
  do_action( "set_transient_{$key}" );
359
  do_action( 'setted_transient', $key );
360
  }
 
 
 
 
361
  }//end if
362
 
363
  do_action( "pods_view_set_{$cache_mode}", $original_key, $value, $expires, $group );
@@ -463,6 +473,14 @@ class PodsView {
463
  if ( $result ) {
464
  do_action( 'deleted_transient', $key );
465
  }
 
 
 
 
 
 
 
 
466
  }//end if
467
 
468
  do_action( "pods_view_clear_{$cache_mode}", $original_key, $group );
1
  <?php
2
 
3
+ use Pods\Static_Cache;
4
+
5
  /**
6
  * @package Pods
7
  */
10
  /**
11
  * @var array $cache_modes Array of available cache modes
12
  */
13
+ public static $cache_modes = array( 'none', 'transient', 'site-transient', 'cache', 'static-cache', 'option-cache' );
14
 
15
  /**
16
  * @return \PodsView
263
  if ( false !== $value ) {
264
  $value = apply_filters( "transient_{$key}", $value );
265
  }
266
+ } elseif ( 'static-cache' === $cache_mode && ! in_array( $cache_mode, $nocache ) ) {
267
+ $static_cache = tribe( Static_Cache::class );
268
+
269
+ $value = $static_cache->get( $key, ( empty( $group ) ? 'pods_view' : $group ) );
270
  } else {
271
  $value = false;
272
  }//end if
364
  do_action( "set_transient_{$key}" );
365
  do_action( 'setted_transient', $key );
366
  }
367
+ } elseif ( 'static-cache' === $cache_mode ) {
368
+ $static_cache = tribe( Static_Cache::class );
369
+
370
+ $static_cache->set( $key, $value, ( empty( $group ) ? 'pods_view' : $group ) );
371
  }//end if
372
 
373
  do_action( "pods_view_set_{$cache_mode}", $original_key, $value, $expires, $group );
473
  if ( $result ) {
474
  do_action( 'deleted_transient', $key );
475
  }
476
+ } elseif ( 'static-cache' === $cache_mode ) {
477
+ $static_cache = tribe( Static_Cache::class );
478
+
479
+ if ( true === $key ) {
480
+ $static_cache->flush( ( empty( $group ) ? 'pods_view' : $group ) );
481
+ } else {
482
+ $static_cache->delete( ( empty( $key ) ? 'pods_view' : $key ), ( empty( $group ) ? 'pods_view' : $group ) );
483
+ }
484
  }//end if
485
 
486
  do_action( "pods_view_clear_{$cache_mode}", $original_key, $group );
classes/fields/avatar.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
- require_once PODS_DIR . 'classes/fields/file.php';
3
 
4
  /**
5
  * PodsField_Avatar class.
@@ -35,7 +34,8 @@ class PodsField_Avatar extends PodsField_File {
35
  */
36
  public function setup() {
37
 
38
- self::$label = __( 'Avatar', 'pods' );
 
39
  }
40
 
41
  /**
@@ -56,7 +56,7 @@ class PodsField_Avatar extends PodsField_File {
56
  */
57
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
58
 
59
- $options = (array) $options;
60
 
61
  $options[ static::$type . '_type' ] = 'images';
62
  $options[ static::$type . '_field_template' ] = 'rows';
@@ -244,7 +244,7 @@ class PodsField_Avatar extends PodsField_File {
244
  if ( 'avatar' === $field['type'] ) {
245
  $avatar_field = $field['name'];
246
 
247
- pods_transient_set( 'pods_avatar_field', $avatar_field );
248
 
249
  break;
250
  }
1
  <?php
 
2
 
3
  /**
4
  * PodsField_Avatar class.
34
  */
35
  public function setup() {
36
 
37
+ static::$group = __( 'Relationships / Media', 'pods' );
38
+ static::$label = __( 'Avatar', 'pods' );
39
  }
40
 
41
  /**
56
  */
57
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
58
 
59
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
60
 
61
  $options[ static::$type . '_type' ] = 'images';
62
  $options[ static::$type . '_field_template' ] = 'rows';
244
  if ( 'avatar' === $field['type'] ) {
245
  $avatar_field = $field['name'];
246
 
247
+ pods_transient_set( 'pods_avatar_field', $avatar_field, WEEK_IN_SECONDS );
248
 
249
  break;
250
  }
classes/fields/boolean.php CHANGED
@@ -27,7 +27,7 @@ class PodsField_Boolean extends PodsField {
27
  */
28
  public function setup() {
29
 
30
- self::$label = __( 'Yes / No', 'pods' );
31
  }
32
 
33
  /**
@@ -45,6 +45,7 @@ class PodsField_Boolean extends PodsField {
45
  'radio' => __( 'Radio Buttons', 'pods' ),
46
  'dropdown' => __( 'Drop Down', 'pods' ),
47
  ),
 
48
  'dependency' => true,
49
  ),
50
  static::$type . '_yes_label' => array(
@@ -113,7 +114,7 @@ class PodsField_Boolean extends PodsField {
113
  */
114
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
115
 
116
- $options = (array) $options;
117
  $form_field_type = PodsForm::$field_type;
118
 
119
  if ( is_array( $value ) ) {
@@ -132,7 +133,7 @@ class PodsField_Boolean extends PodsField {
132
  $field_type = 'select';
133
  }
134
 
135
- if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) {
136
  if ( pods_v( 'read_only', $options, false ) ) {
137
  $options['readonly'] = true;
138
  } else {
@@ -148,7 +149,18 @@ class PodsField_Boolean extends PodsField {
148
  $value = 0;
149
  }
150
 
151
- pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
 
 
 
 
 
 
 
 
 
 
 
152
  }
153
 
154
  /**
@@ -242,4 +254,38 @@ class PodsField_Boolean extends PodsField {
242
 
243
  return $value;
244
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  }
27
  */
28
  public function setup() {
29
 
30
+ static::$label = __( 'Yes / No', 'pods' );
31
  }
32
 
33
  /**
45
  'radio' => __( 'Radio Buttons', 'pods' ),
46
  'dropdown' => __( 'Drop Down', 'pods' ),
47
  ),
48
+ 'pick_show_select_text' => 0,
49
  'dependency' => true,
50
  ),
51
  static::$type . '_yes_label' => array(
114
  */
115
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
116
 
117
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
118
  $form_field_type = PodsForm::$field_type;
119
 
120
  if ( is_array( $value ) ) {
133
  $field_type = 'select';
134
  }
135
 
136
+ if ( isset( $options['name'] ) && ! pods_permission( $options ) ) {
137
  if ( pods_v( 'read_only', $options, false ) ) {
138
  $options['readonly'] = true;
139
  } else {
149
  $value = 0;
150
  }
151
 
152
+ if ( ! empty( $options['disable_dfv'] ) ) {
153
+ return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
154
+ }
155
+
156
+ wp_enqueue_script( 'pods-dfv' );
157
+
158
+ $type = pods_v( 'type', $options, static::$type );
159
+
160
+ $args = compact( array_keys( get_defined_vars() ) );
161
+ $args = (object) $args;
162
+
163
+ $this->render_input_script( $args );
164
  }
165
 
166
  /**
254
 
255
  return $value;
256
  }
257
+
258
+ /**
259
+ * {@inheritdoc}
260
+ */
261
+ public function build_dfv_field_item_data( $args ) {
262
+ if ( empty( $args->options['data'] ) || ! is_array( $args->options['data'] ) ) {
263
+ return [];
264
+ }
265
+
266
+ $boolean_data = $args->options['data'];
267
+
268
+ $value = 0;
269
+
270
+ // If we have values, let's cast them.
271
+ if ( isset( $args->value ) ) {
272
+ $value = (int) $args->value;
273
+ }
274
+
275
+ $data = [];
276
+
277
+ foreach ( $boolean_data as $key => $label ) {
278
+ $data[] = [
279
+ 'id' => esc_html( $key ),
280
+ 'icon' => '',
281
+ 'name' => wp_strip_all_tags( html_entity_decode( $label ) ),
282
+ 'edit_link' => '',
283
+ 'link' => '',
284
+ 'download' => '',
285
+ 'selected' => (int) $key === $value,
286
+ ];
287
+ }
288
+
289
+ return $data;
290
+ }
291
  }
classes/fields/code.php CHANGED
@@ -32,7 +32,8 @@ class PodsField_Code extends PodsField {
32
  */
33
  public function setup() {
34
 
35
- self::$label = __( 'Code (Syntax Highlighting)', 'pods' );
 
36
  }
37
 
38
  /**
@@ -52,9 +53,16 @@ class PodsField_Code extends PodsField {
52
  ),
53
  'output_options' => array(
54
  'label' => __( 'Output Options', 'pods' ),
55
- 'group' => array(
 
 
 
 
 
 
 
56
  static::$type . '_allow_shortcode' => array(
57
- 'label' => __( 'Allow Shortcodes?', 'pods' ),
58
  'default' => 0,
59
  'type' => 'boolean',
60
  'dependency' => true,
@@ -63,7 +71,7 @@ class PodsField_Code extends PodsField {
63
  ),
64
  static::$type . '_max_length' => array(
65
  'label' => __( 'Maximum Length', 'pods' ),
66
- 'default' => 0,
67
  'type' => 'number',
68
  'help' => __( 'Set to -1 for no limit', 'pods' ),
69
  ),
@@ -105,7 +113,7 @@ class PodsField_Code extends PodsField {
105
  */
106
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
107
 
108
- $options = (array) $options;
109
  $form_field_type = PodsForm::$field_type;
110
 
111
  if ( is_array( $value ) ) {
@@ -117,13 +125,25 @@ class PodsField_Code extends PodsField {
117
  do_action( "pods_form_ui_field_code_{$field_type}", $name, $value, $options, $pod, $id );
118
  do_action( 'pods_form_ui_field_code', $field_type, $name, $value, $options, $pod, $id );
119
 
120
- pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
 
 
 
 
 
 
 
 
 
 
 
121
  }
122
 
123
  /**
124
  * {@inheritdoc}
125
  */
126
  public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
 
127
 
128
  $length = (int) pods_v( static::$type . '_max_length', $options, 0 );
129
 
32
  */
33
  public function setup() {
34
 
35
+ static::$group = __( 'Paragraph', 'pods' );
36
+ static::$label = __( 'Code (Syntax Highlighting)', 'pods' );
37
  }
38
 
39
  /**
53
  ),
54
  'output_options' => array(
55
  'label' => __( 'Output Options', 'pods' ),
56
+ 'type' => 'boolean_group',
57
+ 'boolean_group' => array(
58
+ static::$type . '_trim' => array(
59
+ 'label' => __( 'Trim extra whitespace before/after contents', 'pods' ),
60
+ 'default' => 1,
61
+ 'type' => 'boolean',
62
+ 'dependency' => true,
63
+ ),
64
  static::$type . '_allow_shortcode' => array(
65
+ 'label' => __( 'Allow Shortcodes', 'pods' ),
66
  'default' => 0,
67
  'type' => 'boolean',
68
  'dependency' => true,
71
  ),
72
  static::$type . '_max_length' => array(
73
  'label' => __( 'Maximum Length', 'pods' ),
74
+ 'default' => -1,
75
  'type' => 'number',
76
  'help' => __( 'Set to -1 for no limit', 'pods' ),
77
  ),
113
  */
114
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
115
 
116
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
117
  $form_field_type = PodsForm::$field_type;
118
 
119
  if ( is_array( $value ) ) {
125
  do_action( "pods_form_ui_field_code_{$field_type}", $name, $value, $options, $pod, $id );
126
  do_action( 'pods_form_ui_field_code', $field_type, $name, $value, $options, $pod, $id );
127
 
128
+ if ( ! empty( $options['disable_dfv'] ) ) {
129
+ return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
130
+ }
131
+
132
+ wp_enqueue_script( 'pods-dfv' );
133
+
134
+ $type = pods_v( 'type', $options, static::$type );
135
+
136
+ $args = compact( array_keys( get_defined_vars() ) );
137
+ $args = (object) $args;
138
+
139
+ $this->render_input_script( $args );
140
  }
141
 
142
  /**
143
  * {@inheritdoc}
144
  */
145
  public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
146
+ $value = $this->trim_whitespace( $value, $options );
147
 
148
  $length = (int) pods_v( static::$type . '_max_length', $options, 0 );
149
 
classes/fields/color.php CHANGED
@@ -25,7 +25,7 @@ class PodsField_Color extends PodsField {
25
  */
26
  public function setup() {
27
 
28
- self::$label = __( 'Color Picker', 'pods' );
29
  }
30
 
31
  /**
@@ -63,7 +63,7 @@ class PodsField_Color extends PodsField {
63
  */
64
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
65
 
66
- $options = (array) $options;
67
  $form_field_type = PodsForm::$field_type;
68
 
69
  if ( is_array( $value ) ) {
@@ -73,7 +73,7 @@ class PodsField_Color extends PodsField {
73
  // WP Color Picker for 3.5+
74
  $field_type = 'color';
75
 
76
- if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) {
77
  if ( pods_v( 'read_only', $options, false ) ) {
78
  $options['readonly'] = true;
79
 
@@ -87,7 +87,18 @@ class PodsField_Color extends PodsField {
87
  $field_type = 'text';
88
  }
89
 
90
- pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
 
 
 
 
 
 
 
 
 
 
 
91
  }
92
 
93
  /**
@@ -133,7 +144,7 @@ class PodsField_Color extends PodsField {
133
  */
134
  public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
135
 
136
- $options = (array) $options;
137
 
138
  $value = str_replace( '#', '', $value );
139
 
25
  */
26
  public function setup() {
27
 
28
+ static::$label = __( 'Color Picker', 'pods' );
29
  }
30
 
31
  /**
63
  */
64
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
65
 
66
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
67
  $form_field_type = PodsForm::$field_type;
68
 
69
  if ( is_array( $value ) ) {
73
  // WP Color Picker for 3.5+
74
  $field_type = 'color';
75
 
76
+ if ( isset( $options['name'] ) && ! pods_permission( $options ) ) {
77
  if ( pods_v( 'read_only', $options, false ) ) {
78
  $options['readonly'] = true;
79
 
87
  $field_type = 'text';
88
  }
89
 
90
+ if ( ! empty( $options['disable_dfv'] ) ) {
91
+ return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
92
+ }
93
+
94
+ wp_enqueue_script( 'pods-dfv' );
95
+
96
+ $type = pods_v( 'type', $options, static::$type );
97
+
98
+ $args = compact( array_keys( get_defined_vars() ) );
99
+ $args = (object) $args;
100
+
101
+ $this->render_input_script( $args );
102
  }
103
 
104
  /**
144
  */
145
  public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
146
 
147
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
148
 
149
  $value = str_replace( '#', '', $value );
150
 
classes/fields/comment.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
- require_once PODS_DIR . 'classes/fields/pick.php';
3
 
4
  /**
5
  * Create a faux pick field type for comment traversal.
1
  <?php
 
2
 
3
  /**
4
  * Create a faux pick field type for comment traversal.
classes/fields/currency.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
- require_once PODS_DIR . 'classes/fields/number.php';
3
 
4
  /**
5
  * @package Pods\Fields
@@ -39,7 +38,9 @@ class PodsField_Currency extends PodsField_Number {
39
  */
40
  public function setup() {
41
 
42
- self::$label = __( 'Currency', 'pods' );
 
 
43
  static::data_currencies();
44
  }
45
 
@@ -76,6 +77,7 @@ class PodsField_Currency extends PodsField_Number {
76
  'number' => __( 'Freeform Number', 'pods' ),
77
  'slider' => __( 'Slider', 'pods' ),
78
  ),
 
79
  'dependency' => true,
80
  ),
81
  static::$type . '_format_sign' => array(
@@ -83,6 +85,7 @@ class PodsField_Currency extends PodsField_Number {
83
  'default' => apply_filters( 'pods_form_ui_field_number_currency_default', 'usd' ),
84
  'type' => 'pick',
85
  'data' => apply_filters( 'pods_form_ui_field_number_currency_options', $currency_options ),
 
86
  ),
87
  static::$type . '_format_placement' => array(
88
  'label' => __( 'Currency Placement', 'pods' ),
@@ -97,25 +100,28 @@ class PodsField_Currency extends PodsField_Number {
97
  'beforeaftercode' => __( 'Before with Currency Code after (ex. $100 USD)', 'pods' ),
98
  'beforeaftercode_space' => __( 'Before with space and with Currency Code after (ex. $ 100 USD)', 'pods' ),
99
  ),
 
100
  ),
101
  static::$type . '_format' => array(
102
- 'label' => __( 'Format', 'pods' ),
103
  'default' => apply_filters( 'pods_form_ui_field_number_currency_format_default', 'i18n' ),
104
  'type' => 'pick',
105
  'data' => array(
106
  'i18n' => __( 'Localized Default', 'pods' ),
107
  '9,999.99' => '1,234.00',
108
- '9\'999.99' => '1\'234.00',
109
- '9.999,99' => '1.234,00',
110
- '9 999,99' => '1 234,00',
111
  '9999.99' => '1234.00',
 
112
  '9999,99' => '1234,00',
 
 
113
  ),
 
114
  ),
115
  static::$type . '_decimals' => array(
116
  'label' => __( 'Decimals', 'pods' ),
117
  'default' => 2,
118
  'type' => 'number',
 
119
  ),
120
  static::$type . '_decimal_handling' => array(
121
  'label' => __( 'Decimal handling when zero', 'pods' ),
@@ -126,6 +132,7 @@ class PodsField_Currency extends PodsField_Number {
126
  'remove' => __( 'Remove decimals', 'pods' ),
127
  'dash' => __( 'Convert to dash', 'pods' ) . ' (-)',
128
  ),
 
129
  ),
130
  static::$type . '_step' => array(
131
  'label' => __( 'Slider Increment (Step)', 'pods' ),
@@ -135,21 +142,32 @@ class PodsField_Currency extends PodsField_Number {
135
  ),
136
  static::$type . '_min' => array(
137
  'label' => __( 'Minimum Number', 'pods' ),
138
- 'depends-on' => array( static::$type . '_format_type' => 'slider' ),
 
 
 
139
  'default' => 0,
140
  'type' => 'text',
141
  ),
142
  static::$type . '_max' => array(
143
  'label' => __( 'Maximum Number', 'pods' ),
144
- 'depends-on' => array( static::$type . '_format_type' => 'slider' ),
 
 
 
145
  'default' => 1000,
146
  'type' => 'text',
147
  ),
148
  static::$type . '_max_length' => array(
149
- 'label' => __( 'Maximum Length', 'pods' ),
150
  'default' => 12,
151
  'type' => 'number',
152
- 'help' => __( 'Set to -1 for no limit', 'pods' ),
 
 
 
 
 
153
  ),
154
  static::$type . '_placeholder' => array(
155
  'label' => __( 'HTML Placeholder', 'pods' ),
1
  <?php
 
2
 
3
  /**
4
  * @package Pods\Fields
38
  */
39
  public function setup() {
40
 
41
+ static::$group = __( 'Number', 'pods' );
42
+ static::$label = __( 'Currency', 'pods' );
43
+
44
  static::data_currencies();
45
  }
46
 
77
  'number' => __( 'Freeform Number', 'pods' ),
78
  'slider' => __( 'Slider', 'pods' ),
79
  ),
80
+ 'pick_show_select_text' => 0,
81
  'dependency' => true,
82
  ),
83
  static::$type . '_format_sign' => array(
85
  'default' => apply_filters( 'pods_form_ui_field_number_currency_default', 'usd' ),
86
  'type' => 'pick',
87
  'data' => apply_filters( 'pods_form_ui_field_number_currency_options', $currency_options ),
88
+ 'pick_show_select_text' => 0,
89
  ),
90
  static::$type . '_format_placement' => array(
91
  'label' => __( 'Currency Placement', 'pods' ),
100
  'beforeaftercode' => __( 'Before with Currency Code after (ex. $100 USD)', 'pods' ),
101
  'beforeaftercode_space' => __( 'Before with space and with Currency Code after (ex. $ 100 USD)', 'pods' ),
102
  ),
103
+ 'pick_show_select_text' => 0,
104
  ),
105
  static::$type . '_format' => array(
106
+ 'label' => __( 'Number Format', 'pods' ),
107
  'default' => apply_filters( 'pods_form_ui_field_number_currency_format_default', 'i18n' ),
108
  'type' => 'pick',
109
  'data' => array(
110
  'i18n' => __( 'Localized Default', 'pods' ),
111
  '9,999.99' => '1,234.00',
 
 
 
112
  '9999.99' => '1234.00',
113
+ '9.999,99' => '1.234,00',
114
  '9999,99' => '1234,00',
115
+ '9 999,99' => '1 234,00',
116
+ '9\'999.99' => '1\'234.00',
117
  ),
118
+ 'pick_show_select_text' => 0,
119
  ),
120
  static::$type . '_decimals' => array(
121
  'label' => __( 'Decimals', 'pods' ),
122
  'default' => 2,
123
  'type' => 'number',
124
+ 'help' => __( 'Set to a positive number to enable decimals. The upper limit in the database for this field is 30 decimals.', 'pods' ),
125
  ),
126
  static::$type . '_decimal_handling' => array(
127
  'label' => __( 'Decimal handling when zero', 'pods' ),
132
  'remove' => __( 'Remove decimals', 'pods' ),
133
  'dash' => __( 'Convert to dash', 'pods' ) . ' (-)',
134
  ),
135
+ 'pick_show_select_text' => 0,
136
  ),
137
  static::$type . '_step' => array(
138
  'label' => __( 'Slider Increment (Step)', 'pods' ),
142
  ),
143
  static::$type . '_min' => array(
144
  'label' => __( 'Minimum Number', 'pods' ),
145
+ 'depends-on-any' => array(
146
+ static::$type . '_format_type' => 'slider',
147
+ static::$type . '_html5' => true,
148
+ ),
149
  'default' => 0,
150
  'type' => 'text',
151
  ),
152
  static::$type . '_max' => array(
153
  'label' => __( 'Maximum Number', 'pods' ),
154
+ 'depends-on-any' => array(
155
+ static::$type . '_format_type' => 'slider',
156
+ static::$type . '_html5' => true,
157
+ ),
158
  'default' => 1000,
159
  'type' => 'text',
160
  ),
161
  static::$type . '_max_length' => array(
162
+ 'label' => __( 'Maximum Digits', 'pods' ),
163
  'default' => 12,
164
  'type' => 'number',
165
+ 'help' => __( 'Set to -1 for no limit. The upper limit in the database for this field is 64 digits.', 'pods' ),
166
+ ),
167
+ static::$type . '_html5' => array(
168
+ 'label' => __( 'Enable HTML5 Input Field', 'pods' ),
169
+ 'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ),
170
+ 'type' => 'boolean',
171
  ),
172
  static::$type . '_placeholder' => array(
173
  'label' => __( 'HTML Placeholder', 'pods' ),
classes/fields/date.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
- require_once PODS_DIR . 'classes/fields/datetime.php';
3
 
4
  /**
5
  * @package Pods\Fields
@@ -41,6 +40,7 @@ class PodsField_Date extends PodsField_DateTime {
41
  */
42
  public function setup() {
43
 
 
44
  static::$label = __( 'Date', 'pods' );
45
  }
46
 
@@ -70,6 +70,7 @@ class PodsField_Date extends PodsField_DateTime {
70
  'format' => __( 'Predefined format', 'pods' ),
71
  'custom' => __( 'Custom format', 'pods' ),
72
  ),
 
73
  'dependency' => true,
74
  ),
75
  static::$type . '_format_custom' => array(
@@ -109,6 +110,7 @@ class PodsField_Date extends PodsField_DateTime {
109
  'fjsy' => date_i18n( 'F jS, Y' ),
110
  'y' => date_i18n( 'Y' ),
111
  ),
 
112
  'dependency' => true,
113
  ),
114
  static::$type . '_year_range_custom' => array(
@@ -126,12 +128,12 @@ class PodsField_Date extends PodsField_DateTime {
126
  ),
127
  ),
128
  static::$type . '_allow_empty' => array(
129
- 'label' => __( 'Allow empty value?', 'pods' ),
130
  'default' => 1,
131
  'type' => 'boolean',
132
  ),
133
  static::$type . '_html5' => array(
134
- 'label' => __( 'Enable HTML5 Input Field?', 'pods' ),
135
  'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ),
136
  'type' => 'boolean',
137
  ),
1
  <?php
 
2
 
3
  /**
4
  * @package Pods\Fields
40
  */
41
  public function setup() {
42
 
43
+ static::$group = __( 'Date / Time', 'pods' );
44
  static::$label = __( 'Date', 'pods' );
45
  }
46
 
70
  'format' => __( 'Predefined format', 'pods' ),
71
  'custom' => __( 'Custom format', 'pods' ),
72
  ),
73
+ 'pick_show_select_text' => 0,
74
  'dependency' => true,
75
  ),
76
  static::$type . '_format_custom' => array(
110
  'fjsy' => date_i18n( 'F jS, Y' ),
111
  'y' => date_i18n( 'Y' ),
112
  ),
113
+ 'pick_show_select_text' => 0,
114
  'dependency' => true,
115
  ),
116
  static::$type . '_year_range_custom' => array(
128
  ),
129
  ),
130
  static::$type . '_allow_empty' => array(
131
+ 'label' => __( 'Allow empty value', 'pods' ),
132
  'default' => 1,
133
  'type' => 'boolean',
134
  ),
135
  static::$type . '_html5' => array(
136
+ 'label' => __( 'Enable HTML5 Input Field', 'pods' ),
137
  'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ),
138
  'type' => 'boolean',
139
  ),
classes/fields/datetime.php CHANGED
@@ -46,6 +46,7 @@ class PodsField_DateTime extends PodsField {
46
  */
47
  public function setup() {
48
 
 
49
  static::$label = __( 'Date / Time', 'pods' );
50
  }
51
 
@@ -75,31 +76,32 @@ class PodsField_DateTime extends PodsField {
75
  'format' => __( 'Predefined format', 'pods' ),
76
  'custom' => __( 'Custom format', 'pods' ),
77
  ),
 
78
  'dependency' => true,
79
  ),
80
  static::$type . '_format_custom' => array(
81
- 'label' => __( 'Date format for display', 'pods' ),
82
  'depends-on' => array( static::$type . '_type' => 'custom' ),
83
  'default' => '',
84
  'type' => 'text',
85
  'help' => sprintf(
86
- '<a href="http://php.net/manual/function.date.php" target="_blank" rel="noopener noreferrer">%s</a>',
87
- esc_html__( 'PHP date documentation', 'pods' )
88
  ),
89
  ),
90
  static::$type . '_format_custom_js' => array(
91
- 'label' => __( 'Date format for input', 'pods' ),
92
  'depends-on' => array( static::$type . '_type' => 'custom' ),
93
  'default' => '',
94
  'type' => 'text',
95
  'help' => sprintf(
96
- '<a href="https://api.jqueryui.com/datepicker/" target="_blank" rel="noopener noreferrer">%1$s</a><br />%2$s',
97
- esc_html__( 'jQuery UI datepicker documentation', 'pods' ),
98
  esc_html__( 'Leave empty to auto-generate from PHP format.', 'pods' )
99
  ),
100
  ),
101
  static::$type . '_format' => array(
102
- 'label' => __( 'Date Format', 'pods' ),
103
  'depends-on' => array( static::$type . '_type' => 'format' ),
104
  'default' => 'mdy',
105
  'type' => 'pick',
@@ -114,6 +116,7 @@ class PodsField_DateTime extends PodsField {
114
  'fjsy' => date_i18n( 'F jS, Y' ),
115
  'c' => date_i18n( 'c' ),
116
  ),
 
117
  'dependency' => true,
118
  ),
119
  static::$type . '_time_type' => array(
@@ -129,30 +132,34 @@ class PodsField_DateTime extends PodsField {
129
  '24' => __( '24 hour', 'pods' ),
130
  'custom' => __( 'Custom', 'pods' ),
131
  ),
 
132
  'dependency' => true,
133
  ),
134
  static::$type . '_time_format_custom' => array(
135
- 'label' => __( 'Time format', 'pods' ),
136
  'depends-on' => array( static::$type . '_time_type' => 'custom' ),
137
  'excludes-on' => array( static::$type . '_format' => 'c' ),
138
  'default' => '',
139
  'type' => 'text',
140
- 'help' => '<a href="http://php.net/manual/function.date.php" target="_blank" rel="noopener noreferrer">' . __( 'PHP date documentation', 'pods' ) . '</a>',
 
 
 
141
  ),
142
  static::$type . '_time_format_custom_js' => array(
143
- 'label' => __( 'Time format field input', 'pods' ),
144
  'depends-on' => array( static::$type . '_time_type' => 'custom' ),
145
  'excludes-on' => array( static::$type . '_format' => 'c' ),
146
  'default' => '',
147
  'type' => 'text',
148
- 'help' => sprintf(
149
- '<a href="http://trentrichardson.com/examples/timepicker/#tp-formatting" target="_blank" rel="noopener noreferrer">%1$s</a><br />%2$s',
150
- esc_html__( 'jQuery UI timepicker documentation', 'pods' ),
151
  esc_html__( 'Leave empty to auto-generate from PHP format.', 'pods' )
152
  ),
153
  ),
154
  static::$type . '_time_format' => array(
155
- 'label' => __( 'Time Format', 'pods' ),
156
  'depends-on' => array( static::$type . '_time_type' => '12' ),
157
  'excludes-on' => array( static::$type . '_format' => 'c' ),
158
  'default' => 'h_mma',
@@ -169,9 +176,10 @@ class PodsField_DateTime extends PodsField {
169
  'hh_mm' => date_i18n( 'h:i' ),
170
  'hh_mm_ss' => date_i18n( 'h:i:s' ),
171
  ),
 
172
  ),
173
  static::$type . '_time_format_24' => array(
174
- 'label' => __( 'Time Format', 'pods' ),
175
  'depends-on' => array( static::$type . '_time_type' => '24' ),
176
  'excludes-on' => array( static::$type . '_format' => 'c' ),
177
  'default' => 'hh_mm',
@@ -180,28 +188,29 @@ class PodsField_DateTime extends PodsField {
180
  'hh_mm' => date_i18n( 'H:i' ),
181
  'hh_mm_ss' => date_i18n( 'H:i:s' ),
182
  ),
 
183
  ),
184
  static::$type . '_year_range_custom' => array(
185
- 'label' => __( 'Year range', 'pods' ),
186
  'default' => '',
187
  'type' => 'text',
188
  'help' => sprintf(
189
- '%1$s<br /><a href="https://api.jqueryui.com/datepicker/#option-yearRange" target="_blank" rel="noopener noreferrer">%2$s</a>',
190
  sprintf(
191
  esc_html__( 'Example: %1$s for specifying a hard coded year range or %2$s for the last and next 10 years.', 'pods' ),
192
  '<code>2010:2030</code>',
193
  '<code>-10:+10</code>'
194
  ),
195
- esc_html__( 'jQuery UI datepicker documentation', 'pods' )
196
  ),
197
  ),
198
  static::$type . '_allow_empty' => array(
199
- 'label' => __( 'Allow empty value?', 'pods' ),
200
  'default' => 1,
201
  'type' => 'boolean',
202
  ),
203
  static::$type . '_html5' => array(
204
- 'label' => __( 'Enable HTML5 Input Field?', 'pods' ),
205
  'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ),
206
  'type' => 'boolean',
207
  ),
@@ -274,7 +283,7 @@ class PodsField_DateTime extends PodsField {
274
  */
275
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
276
 
277
- $options = (array) $options;
278
  $form_field_type = PodsForm::$field_type;
279
 
280
  if ( is_array( $value ) ) {
@@ -286,21 +295,34 @@ class PodsField_DateTime extends PodsField {
286
 
287
  $field_type = static::$type;
288
 
289
- if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) {
290
- if ( pods_v( 'read_only', $options, false ) ) {
 
 
291
  $options['readonly'] = true;
292
 
293
  $field_type = 'text';
294
  } else {
295
  return;
296
  }
297
- } elseif ( ! pods_has_permissions( $options ) && pods_v( 'read_only', $options, false ) ) {
298
  $options['readonly'] = true;
299
 
300
  $field_type = 'text';
301
  }
302
 
303
- pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
 
 
 
 
 
 
 
 
 
 
 
304
  }
305
 
306
  /**
@@ -951,49 +973,61 @@ class PodsField_DateTime extends PodsField {
951
  * @since 2.7.0
952
  */
953
  public function enqueue_jquery_ui_i18n() {
 
954
 
955
- static $done = array();
956
 
957
  $types = array();
958
 
959
  switch ( static::$type ) {
960
  case 'time':
961
- $types[] = 'time';
962
 
963
  break;
964
  case 'date':
965
- $types[] = 'date';
966
 
967
  break;
968
  case 'datetime':
969
- $types[] = 'time';
970
- $types[] = 'date';
971
 
972
  break;
973
  }
974
 
975
- if ( in_array( 'date', $types, true ) && ! in_array( 'date', $done, true ) ) {
 
 
976
  if ( function_exists( 'wp_localize_jquery_ui_datepicker' ) ) {
977
  wp_localize_jquery_ui_datepicker();
978
  }
979
 
980
- $done[] = 'date';
981
  }
982
 
983
- if ( in_array( 'time', $types, true ) && ! in_array( 'time', $done, true ) ) {
984
- $locale = str_replace( '_', '-', get_locale() );
 
 
 
 
 
 
 
985
 
986
  // Local files.
987
- if ( ! file_exists( PODS_DIR . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js' ) ) {
988
  // Fallback to the base language (non-region specific).
989
  $locale = substr( $locale, 0, strpos( $locale, '-' ) );
 
 
990
  }
991
 
992
- if ( ! wp_script_is( 'jquery-ui-timepicker-i18n-' . $locale, 'registered' ) && file_exists( PODS_DIR . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js' ) ) {
993
- wp_enqueue_script( 'jquery-ui-timepicker-i18n-' . $locale, PODS_URL . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js', array( 'jquery-ui-timepicker' ), '1.6.3' );
994
  }
995
 
996
- $done[] = 'time';
997
  }
998
  }
999
  }
46
  */
47
  public function setup() {
48
 
49
+ static::$group = __( 'Date / Time', 'pods' );
50
  static::$label = __( 'Date / Time', 'pods' );
51
  }
52
 
76
  'format' => __( 'Predefined format', 'pods' ),
77
  'custom' => __( 'Custom format', 'pods' ),
78
  ),
79
+ 'pick_show_select_text' => 0,
80
  'dependency' => true,
81
  ),
82
  static::$type . '_format_custom' => array(
83
+ 'label' => __( 'Date Format for Display', 'pods' ),
84
  'depends-on' => array( static::$type . '_type' => 'custom' ),
85
  'default' => '',
86
  'type' => 'text',
87
  'help' => sprintf(
88
+ '<a href="https://docs.pods.io/fields/date-time-fields/datetime/" target="_blank" rel="noopener noreferrer">%1$s</a>',
89
+ esc_html__( 'Date / Time field documentation', 'pods' )
90
  ),
91
  ),
92
  static::$type . '_format_custom_js' => array(
93
+ 'label' => __( 'Date Format for Input', 'pods' ),
94
  'depends-on' => array( static::$type . '_type' => 'custom' ),
95
  'default' => '',
96
  'type' => 'text',
97
  'help' => sprintf(
98
+ '<a href="https://docs.pods.io/fields/date-time-fields/datetime/" target="_blank" rel="noopener noreferrer">%1$s</a><br />%2$s',
99
+ esc_html__( 'Date / Time field documentation', 'pods' ),
100
  esc_html__( 'Leave empty to auto-generate from PHP format.', 'pods' )
101
  ),
102
  ),
103
  static::$type . '_format' => array(
104
+ 'label' => __( 'Date Format (predefined)', 'pods' ),
105
  'depends-on' => array( static::$type . '_type' => 'format' ),
106
  'default' => 'mdy',
107
  'type' => 'pick',
116
  'fjsy' => date_i18n( 'F jS, Y' ),
117
  'c' => date_i18n( 'c' ),
118
  ),
119
+ 'pick_show_select_text' => 0,
120
  'dependency' => true,
121
  ),
122
  static::$type . '_time_type' => array(
132
  '24' => __( '24 hour', 'pods' ),
133
  'custom' => __( 'Custom', 'pods' ),
134
  ),
135
+ 'pick_show_select_text' => 0,
136
  'dependency' => true,
137
  ),
138
  static::$type . '_time_format_custom' => array(
139
+ 'label' => __( 'Time Format for Display', 'pods' ),
140
  'depends-on' => array( static::$type . '_time_type' => 'custom' ),
141
  'excludes-on' => array( static::$type . '_format' => 'c' ),
142
  'default' => '',
143
  'type' => 'text',
144
+ 'help' => sprintf(
145
+ '<a href="https://docs.pods.io/fields/date-time-fields/datetime/" target="_blank" rel="noopener noreferrer">%1$s</a>',
146
+ esc_html__( 'Date / Time field documentation', 'pods' )
147
+ ),
148
  ),
149
  static::$type . '_time_format_custom_js' => array(
150
+ 'label' => __( 'Time Format for Input', 'pods' ),
151
  'depends-on' => array( static::$type . '_time_type' => 'custom' ),
152
  'excludes-on' => array( static::$type . '_format' => 'c' ),
153
  'default' => '',
154
  'type' => 'text',
155
+ 'help' => sprintf(
156
+ '<a href="https://docs.pods.io/fields/date-time-fields/datetime/" target="_blank" rel="noopener noreferrer">%1$s</a><br />%2$s',
157
+ esc_html__( 'Date / Time field documentation', 'pods' ),
158
  esc_html__( 'Leave empty to auto-generate from PHP format.', 'pods' )
159
  ),
160
  ),
161
  static::$type . '_time_format' => array(
162
+ 'label' => __( 'Time Format (12 hour)', 'pods' ),
163
  'depends-on' => array( static::$type . '_time_type' => '12' ),
164
  'excludes-on' => array( static::$type . '_format' => 'c' ),
165
  'default' => 'h_mma',
176
  'hh_mm' => date_i18n( 'h:i' ),
177
  'hh_mm_ss' => date_i18n( 'h:i:s' ),
178
  ),
179
+ 'pick_show_select_text' => 0,
180
  ),
181
  static::$type . '_time_format_24' => array(
182
+ 'label' => __( 'Time Format (24 hour)', 'pods' ),
183
  'depends-on' => array( static::$type . '_time_type' => '24' ),
184
  'excludes-on' => array( static::$type . '_format' => 'c' ),
185
  'default' => 'hh_mm',
188
  'hh_mm' => date_i18n( 'H:i' ),
189
  'hh_mm_ss' => date_i18n( 'H:i:s' ),
190
  ),
191
+ 'pick_show_select_text' => 0,
192
  ),
193
  static::$type . '_year_range_custom' => array(
194
+ 'label' => __( 'Year Range', 'pods' ),
195
  'default' => '',
196
  'type' => 'text',
197
  'help' => sprintf(
198
+ '%1$s<br /><a href="https://docs.pods.io/fields/date-time-fields/datetime/" target="_blank" rel="noopener noreferrer">%2$s</a>',
199
  sprintf(
200
  esc_html__( 'Example: %1$s for specifying a hard coded year range or %2$s for the last and next 10 years.', 'pods' ),
201
  '<code>2010:2030</code>',
202
  '<code>-10:+10</code>'
203
  ),
204
+ esc_html__( 'Date / Time field documentation', 'pods' )
205
  ),
206
  ),
207
  static::$type . '_allow_empty' => array(
208
+ 'label' => __( 'Allow empty value', 'pods' ),
209
  'default' => 1,
210
  'type' => 'boolean',
211
  ),
212
  static::$type . '_html5' => array(
213
+ 'label' => __( 'Enable HTML5 Input Field', 'pods' ),
214
  'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ),
215
  'type' => 'boolean',
216
  ),
283
  */
284
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
285
 
286
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
287
  $form_field_type = PodsForm::$field_type;
288
 
289
  if ( is_array( $value ) ) {
295
 
296
  $field_type = static::$type;
297
 
298
+ $is_read_only = (boolean) pods_v( 'read_only', $options, false );
299
+
300
+ if ( isset( $options['name'] ) && ! pods_permission( $options ) ) {
301
+ if ( $is_read_only ) {
302
  $options['readonly'] = true;
303
 
304
  $field_type = 'text';
305
  } else {
306
  return;
307
  }
308
+ } elseif ( ! pods_has_permissions( $options ) && $is_read_only ) {
309
  $options['readonly'] = true;
310
 
311
  $field_type = 'text';
312
  }
313
 
314
+ if ( ! empty( $options['disable_dfv'] ) ) {
315
+ return pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
316
+ }
317
+
318
+ wp_enqueue_script( 'pods-dfv' );
319
+
320
+ $type = pods_v( 'type', $options, static::$type );
321
+
322
+ $args = compact( array_keys( get_defined_vars() ) );
323
+ $args = (object) $args;
324
+
325
+ $this->render_input_script( $args );
326
  }
327
 
328
  /**
973
  * @since 2.7.0
974
  */
975
  public function enqueue_jquery_ui_i18n() {
976
+ $static_cache = tribe( Static_Cache::class );
977
 
978
+ $done = (array) $static_cache->get( 'done', __METHOD__ );
979
 
980
  $types = array();
981
 
982
  switch ( static::$type ) {
983
  case 'time':
984
+ $types['time'] = true;
985
 
986
  break;
987
  case 'date':
988
+ $types['date'] = true;
989
 
990
  break;
991
  case 'datetime':
992
+ $types['time'] = true;
993
+ $types['date'] = true;
994
 
995
  break;
996
  }
997
 
998
+ $locale = str_replace( '_', '-', get_locale() );
999
+
1000
+ if ( isset( $types['date'] ) && ! isset( $done[ 'date-' . $locale ] ) ) {
1001
  if ( function_exists( 'wp_localize_jquery_ui_datepicker' ) ) {
1002
  wp_localize_jquery_ui_datepicker();
1003
  }
1004
 
1005
+ $done['date'] = true;
1006
  }
1007
 
1008
+ if ( isset( $types['time'] ) && ! isset( $done[ 'time-' . $locale ] ) ) {
1009
+ /**
1010
+ * @var $wp_filesystem WP_Filesystem_Base
1011
+ */
1012
+ global $wp_filesystem;
1013
+
1014
+ WP_Filesystem();
1015
+
1016
+ $locale_exists = $wp_filesystem->exists( PODS_DIR . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js' );
1017
 
1018
  // Local files.
1019
+ if ( ! $locale_exists ) {
1020
  // Fallback to the base language (non-region specific).
1021
  $locale = substr( $locale, 0, strpos( $locale, '-' ) );
1022
+
1023
+ $locale_exists = $wp_filesystem->exists( PODS_DIR . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js' );
1024
  }
1025
 
1026
+ if ( $locale_exists && ! wp_script_is( 'jquery-ui-timepicker-i18n-' . $locale ) ) {
1027
+ wp_enqueue_script( 'jquery-ui-timepicker-i18n-' . $locale, PODS_URL . 'ui/js/timepicker/i18n/jquery-ui-timepicker-' . $locale . '.js', [ 'jquery-ui-timepicker' ], '1.6.3' );
1028
  }
1029
 
1030
+ $done[ 'time-' . $locale ] = true;
1031
  }
1032
  }
1033
  }
classes/fields/email.php CHANGED
@@ -30,7 +30,8 @@ class PodsField_Email extends PodsField {
30
  */
31
  public function setup() {
32
 
33
- self::$label = __( 'E-mail', 'pods' );
 
34
  }
35
 
36
  /**
@@ -55,7 +56,7 @@ class PodsField_Email extends PodsField {
55
  'help' => __( 'Set to -1 for no limit', 'pods' ),
56
  ),
57
  static::$type . '_html5' => array(
58
- 'label' => __( 'Enable HTML5 Input Field?', 'pods' ),
59
  'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ),
60
  'type' => 'boolean',
61
  ),
@@ -94,7 +95,7 @@ class PodsField_Email extends PodsField {
94
  */
95
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
96
 
97
- $options = (array) $options;
98
  $form_field_type = PodsForm::$field_type;
99
 
100
  if ( is_array( $value ) ) {
@@ -103,7 +104,7 @@ class PodsField_Email extends PodsField {
103
 
104
  $field_type = 'email';
105
 
106
- if ( isset( $options['name'] ) && false === PodsForm::permission( static::$type, $options['name'], $options, null, $pod, $id ) ) {
107
  if ( pods_v( 'read_only', $options, false ) ) {
108
  $options['readonly'] = true;
109
 
@@ -117,7 +118,18 @@ class PodsField_Email extends PodsField {
117
  $field_type = 'text';
118
  }
119
 
120
- pods_view( PODS_DIR . 'ui/fields/' . $field_type . '.php', compact( array_keys( get_defined_vars() ) ) );
 
 
 
 
 
 
 
 
 
 
 
121
  }
122
 
123
  /**
@@ -160,7 +172,7 @@ class PodsField_Email extends PodsField {
160
  */
161
  public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
162
 
163
- $options = (array) $options;
164
 
165
  if ( ! is_email( $value ) ) {
166
  $value = '';
30
  */
31
  public function setup() {
32
 
33
+ static::$group = __( 'Text', 'pods' );
34
+ static::$label = __( 'E-mail', 'pods' );
35
  }
36
 
37
  /**
56
  'help' => __( 'Set to -1 for no limit', 'pods' ),
57
  ),
58
  static::$type . '_html5' => array(
59
+ 'label' => __( 'Enable HTML5 Input Field', 'pods' ),
60
  'default' => apply_filters( 'pods_form_ui_field_html5', 0, static::$type ),
61
  'type' => 'boolean',
62
  ),
95
  */
96
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
97
 
98
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
99
  $form_field_type = PodsForm::$field_type;
100
 
101
  if ( is_array( $value ) ) {
104
 
105
  $field_type = 'email';
106
 
107
+ if ( isset( $options['name'] ) && ! pods_permission( $options ) ) {
108
  if ( pods_v( 'read_only', $options, false ) ) {
109
  $options['readonly'] = true;
110
 
118
  $field_type = 'text';
119
  }
120
 
121
+ if ( ! empty( $options['disable_dfv'] ) ) {
122
+ return pods_view( PODS_DIR . 'ui/fields/email.php', compact( array_keys( get_defined_vars() ) ) );
123
+ }
124
+
125
+ wp_enqueue_script( 'pods-dfv' );
126
+
127
+ $type = pods_v( 'type', $options, static::$type );
128
+
129
+ $args = compact( array_keys( get_defined_vars() ) );
130
+ $args = (object) $args;
131
+
132
+ $this->render_input_script( $args );
133
  }
134
 
135
  /**
172
  */
173
  public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
174
 
175
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
176
 
177
  if ( ! is_email( $value ) ) {
178
  $value = '';
classes/fields/file.php CHANGED
@@ -36,7 +36,8 @@ class PodsField_File extends PodsField {
36
  */
37
  public function setup() {
38
 
39
- self::$label = __( 'File / Image / Video', 'pods' );
 
40
 
41
  }
42
 
@@ -75,6 +76,7 @@ class PodsField_File extends PodsField {
75
  'single' => __( 'Single File', 'pods' ),
76
  'multi' => __( 'Multiple Files', 'pods' ),
77
  ),
 
78
  'dependency' => true,
79
  ),
80
  static::$type . '_uploader' => array(
@@ -88,10 +90,11 @@ class PodsField_File extends PodsField {
88
  'plupload' => __( 'Upload only (Plupload)', 'pods' ),
89
  )
90
  ),
 
91
  'dependency' => true,
92
  ),
93
  static::$type . '_attachment_tab' => array(
94
- 'label' => __( 'Attachments Default Tab', 'pods' ),
95
  'depends-on' => array( static::$type . '_uploader' => 'attachment' ),
96
  'default' => 'upload',
97
  'type' => 'pick',
@@ -100,20 +103,22 @@ class PodsField_File extends PodsField {
100
  'upload' => __( 'Upload File', 'pods' ),
101
  'browse' => __( 'Media Library', 'pods' ),
102
  ),
 
103
  ),
104
  static::$type . '_upload_dir' => array(
105
- 'label' => __( 'Upload directory', 'pods' ),
106
  'default' => 'wp',
107
  'type' => 'pick',
108
  'data' => array(
109
- 'wp' => __( 'WordPress Default', 'pods' ) . ' (/yyyy/mm/)',
110
  'uploads' => __( 'Custom directory within the default uploads directory', 'pods' ),
111
  ),
 
112
  'depends-on' => array( static::$type . '_uploader' => 'plupload' ),
113
  'dependency' => true,
114
  ),
115
  static::$type . '_upload_dir_custom' => array(
116
- 'label' => __( 'Custom upload directory', 'pods' ),
117
  'help' => __( 'Magic tags are allowed for this field. The path is relative to the /wp-content/uploads/ folder on your site.', 'pods' ),
118
  'placeholder' => 'my-custom-folder',
119
  'depends-on' => array(
@@ -155,7 +160,8 @@ class PodsField_File extends PodsField {
155
  'label' => __( 'Restrict File Size', 'pods' ),
156
  'help' => __( 'Valid size suffixes are: GB (gigabytes), MB (megabytes), KB (kilobytes), or B (bytes). Defaults to the <a href="https://developer.wordpress.org/reference/functions/wp_max_upload_size/">wp_max_upload_size</a> setting.', 'pods' ),
157
  'depends-on' => array( static::$type . '_uploader' => 'plupload' ),
158
- 'default' => '10MB',
 
159
  'type' => 'text',
160
  ),
161
  static::$type . '_type' => array(
@@ -173,6 +179,7 @@ class PodsField_File extends PodsField {
173
  'other' => __( 'Other (customize allowed extensions)', 'pods' ),
174
  )
175
  ),
 
176
  'dependency' => true,
177
  ),
178
  static::$type . '_allowed_extensions' => array(
@@ -180,6 +187,7 @@ class PodsField_File extends PodsField {
180
  'description' => __( 'Separate file extensions with a comma (ex. jpg,png,mp4,mov)', 'pods' ),
181
  'depends-on' => array( static::$type . '_type' => 'other' ),
182
  'default' => apply_filters( "pods_form_ui_field_{$type}_extensions_default", '' ),
 
183
  'type' => 'text',
184
  ),
185
  static::$type . '_field_template' => array(
@@ -195,6 +203,7 @@ class PodsField_File extends PodsField {
195
  'tiles' => __( 'Tiles', 'pods' ),
196
  )
197
  ),
 
198
  ),
199
  static::$type . '_add_button' => array(
200
  'label' => __( 'Add Button Text', 'pods' ),
@@ -223,41 +232,44 @@ class PodsField_File extends PodsField {
223
  'type' => 'boolean',
224
  ),
225
  static::$type . '_wp_gallery_link' => array(
226
- 'label' => __( 'Gallery image links', 'pods' ),
227
- 'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ),
228
  'type' => 'pick',
229
  'data' => array(
230
  'post' => __( 'Attachment Page', 'pods' ),
231
  'file' => __( 'Media File', 'pods' ),
232
  'none' => __( 'None', 'pods' ),
233
  ),
 
234
  ),
235
  static::$type . '_wp_gallery_columns' => array(
236
- 'label' => __( 'Gallery image columns', 'pods' ),
237
- 'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ),
238
  'type' => 'pick',
239
  'data' => array(
240
- '1' => 1,
241
- '2' => 2,
242
- '3' => 3,
243
- '4' => 4,
244
- '5' => 5,
245
- '6' => 6,
246
- '7' => 7,
247
- '8' => 8,
248
- '9' => 9,
249
  ),
 
250
  ),
251
  static::$type . '_wp_gallery_random_sort' => array(
252
- 'label' => __( 'Gallery randomized order', 'pods' ),
253
- 'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ),
254
  'type' => 'boolean',
255
  ),
256
  static::$type . '_wp_gallery_size' => array(
257
- 'label' => __( 'Gallery image size', 'pods' ),
258
- 'depends-on' => array( static::$type . '_wp_gallery_output' => 1 ),
259
  'type' => 'pick',
260
  'data' => $this->data_image_sizes(),
 
261
  ),
262
  );
263
 
@@ -311,7 +323,7 @@ class PodsField_File extends PodsField {
311
  */
312
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
313
 
314
- $options = (array) $options;
315
 
316
  $type = pods_v( 'type', $options, static::$type );
317
 
@@ -351,14 +363,6 @@ class PodsField_File extends PodsField {
351
 
352
  // Ensure the media library is initialized
353
  $this->render_input_script( $args );
354
-
355
- // @todo: we're short-circuiting for prototyping above. The actions below will need to be woven in somehow.
356
- /**
357
- * $form_field_type . '_uploader' != attachment, plupload, media
358
- * Run this action 'pods_form_ui_field_' . static::$type . '_uploader_' . static::$type . '_uploader'
359
- * Run this action 'pods_form_ui_field_' . static::$type . '_uploader', static::$type . '_uploader'
360
- * Pass these args $name, $value, $options, $pod, $id
361
- */
362
  }
363
 
364
  /**
@@ -374,11 +378,26 @@ class PodsField_File extends PodsField {
374
  }
375
  }
376
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
  // Handle default template setting.
378
- $file_field_template = pods_v( $args->type . '_field_template', $options, 'rows', true );
379
 
380
  // Get which file types the field is limited to.
381
- $limit_file_type = pods_v( $args->type . '_type', $options, 'images' );
 
 
382
 
383
  // Non-image file types are forced to rows template right now.
384
  if ( 'images' !== $limit_file_type ) {
@@ -488,25 +507,23 @@ class PodsField_File extends PodsField {
488
  $is_user_logged_in = is_user_logged_in();
489
 
490
  // @todo: plupload sp
36
  */
37
  public function setup() {
38
 
39
+ static::$group = __( 'Relationships / Media', 'pods' );
40
+ static::$label = __( 'File / Image / Video', 'pods' );
41
 
42
  }
43
 
76
  'single' => __( 'Single File', 'pods' ),
77
  'multi' => __( 'Multiple Files', 'pods' ),
78
  ),
79
+ 'pick_show_select_text' => 0,
80
  'dependency' => true,
81
  ),
82
  static::$type . '_uploader' => array(
90
  'plupload' => __( 'Upload only (Plupload)', 'pods' ),
91
  )
92
  ),
93
+ 'pick_show_select_text' => 0,
94
  'dependency' => true,
95
  ),
96
  static::$type . '_attachment_tab' => array(
97
+ 'label' => __( 'Media Library Default Tab', 'pods' ),
98
  'depends-on' => array( static::$type . '_uploader' => 'attachment' ),
99
  'default' => 'upload',
100
  'type' => 'pick',
103
  'upload' => __( 'Upload File', 'pods' ),
104
  'browse' => __( 'Media Library', 'pods' ),
105
  ),
106
+ 'pick_show_select_text' => 0,
107
  ),
108
  static::$type . '_upload_dir' => array(
109
+ 'label' => __( 'Upload Directory', 'pods' ),
110
  'default' => 'wp',
111
  'type' => 'pick',
112
  'data' => array(
113
+ 'wp' => __( 'WordPress Default', 'pods' ) . ' (/wp-content/uploads/yyyy/mm/)',
114
  'uploads' => __( 'Custom directory within the default uploads directory', 'pods' ),
115
  ),
116
+ 'pick_show_select_text' => 0,
117
  'depends-on' => array( static::$type . '_uploader' => 'plupload' ),
118
  'dependency' => true,
119
  ),
120
  static::$type . '_upload_dir_custom' => array(
121
+ 'label' => __( 'Custom Upload Directory', 'pods' ),
122
  'help' => __( 'Magic tags are allowed for this field. The path is relative to the /wp-content/uploads/ folder on your site.', 'pods' ),
123
  'placeholder' => 'my-custom-folder',
124
  'depends-on' => array(
160
  'label' => __( 'Restrict File Size', 'pods' ),
161
  'help' => __( 'Valid size suffixes are: GB (gigabytes), MB (megabytes), KB (kilobytes), or B (bytes). Defaults to the <a href="https://developer.wordpress.org/reference/functions/wp_max_upload_size/">wp_max_upload_size</a> setting.', 'pods' ),
162
  'depends-on' => array( static::$type . '_uploader' => 'plupload' ),
163
+ 'default' => '',
164
+ 'text_placeholder' => '10MB',
165
  'type' => 'text',
166
  ),
167
  static::$type . '_type' => array(
179
  'other' => __( 'Other (customize allowed extensions)', 'pods' ),
180
  )
181
  ),
182
+ 'pick_show_select_text' => 0,
183
  'dependency' => true,
184
  ),
185
  static::$type . '_allowed_extensions' => array(
187
  'description' => __( 'Separate file extensions with a comma (ex. jpg,png,mp4,mov)', 'pods' ),
188
  'depends-on' => array( static::$type . '_type' => 'other' ),
189
  'default' => apply_filters( "pods_form_ui_field_{$type}_extensions_default", '' ),
190
+ 'text_placeholder' => 'jpg,png,mp4,mov',
191
  'type' => 'text',
192
  ),
193
  static::$type . '_field_template' => array(
203
  'tiles' => __( 'Tiles', 'pods' ),
204
  )
205
  ),
206
+ 'pick_show_select_text' => 0,
207
  ),
208
  static::$type . '_add_button' => array(
209
  'label' => __( 'Add Button Text', 'pods' ),
232
  'type' => 'boolean',
233
  ),
234
  static::$type . '_wp_gallery_link' => array(
235
+ 'label' => __( 'Gallery Image Links', 'pods' ),
236
+ 'depends-on' => array( static::$type . '_wp_gallery_output' => true ),
237
  'type' => 'pick',
238
  'data' => array(
239
  'post' => __( 'Attachment Page', 'pods' ),
240
  'file' => __( 'Media File', 'pods' ),
241
  'none' => __( 'None', 'pods' ),
242
  ),
243
+ 'pick_show_select_text' => 0,
244
  ),
245
  static::$type . '_wp_gallery_columns' => array(
246
+ 'label' => __( 'Gallery Image Columns', 'pods' ),
247
+ 'depends-on' => array( static::$type . '_wp_gallery_output' => true ),
248
  'type' => 'pick',
249
  'data' => array(
250
+ '1' => '1',
251
+ '2' => '2',
252
+ '3' => '3',
253
+ '4' => '4',
254
+ '5' => '5',
255
+ '6' => '6',
256
+ '7' => '7',
257
+ '8' => '8',
258
+ '9' => '9',
259
  ),
260
+ 'pick_show_select_text' => 0,
261
  ),
262
  static::$type . '_wp_gallery_random_sort' => array(
263
+ 'label' => __( 'Gallery Randomized Order', 'pods' ),
264
+ 'depends-on' => array( static::$type . '_wp_gallery_output' => true ),
265
  'type' => 'boolean',
266
  ),
267
  static::$type . '_wp_gallery_size' => array(
268
+ 'label' => __( 'Gallery Image Size', 'pods' ),
269
+ 'depends-on' => array( static::$type . '_wp_gallery_output' => true ),
270
  'type' => 'pick',
271
  'data' => $this->data_image_sizes(),
272
+ 'pick_show_select_text' => 0,
273
  ),
274
  );
275
 
323
  */
324
  public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
325
 
326
+ $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
327
 
328
  $type = pods_v( 'type', $options, static::$type );
329
 
363
 
364
  // Ensure the media library is initialized
365
  $this->render_input_script( $args );
 
 
 
 
 
 
 
 
366
  }
367
 
368
  /**
378
  }
379
  }
380
 
381
+ // Enforce defaults.
382
+ $all_options = static::options();
383
+
384
+ foreach ( $all_options as $option_name => $option ) {
385
+ $default = pods_v( 'default', $option, '' );
386
+
387
+ $options[ $option_name ] = pods_v( $option_name, $options, $default );
388
+
389
+ if ( '' === $options[ $option_name ] ) {
390
+ $options[ $option_name ] = $default;
391
+ }
392
+ }
393
+
394
  // Handle default template setting.
395
+ $file_field_template = pods_v( $args->type . '_field_template', $options );
396
 
397
  // Get which file types the field is limited to.
398
+ $limit_file_type = pods_v( $args->type . '_type', $options );
399
+
400
+ $options[ $args->type . '_type' ] = $limit_file_type;
401
 
402
  // Non-image file types are forced to rows template right now.
403
  if ( 'images' !== $limit_file_type ) {
507
  $is_user_logged_in = is_user_logged_in();
508
 
509
  // @todo: plupload sp