avatar.php
4 months ago
boolean.php
4 months ago
code.php
4 months ago
color.php
4 months ago
comment.php
4 months ago
currency.php
4 months ago
date.php
4 months ago
datetime.php
4 months ago
email.php
4 months ago
file.php
4 months ago
heading.php
4 months ago
html.php
4 months ago
link.php
4 months ago
number.php
4 months ago
oembed.php
4 months ago
paragraph.php
4 months ago
password.php
4 months ago
phone.php
4 months ago
pick.php
4 months ago
slug.php
4 months ago
taxonomy.php
4 months ago
text.php
4 months ago
time.php
4 months ago
website.php
4 months ago
wysiwyg.php
4 months ago
pick.php
4387 lines
| 1 | <?php |
| 2 | |
| 3 | // Don't load directly. |
| 4 | if ( ! defined( 'ABSPATH' ) ) { |
| 5 | die( '-1' ); |
| 6 | } |
| 7 | |
| 8 | use Pods\Static_Cache; |
| 9 | use Pods\Whatsit\Pod; |
| 10 | use Pods\Whatsit\Field; |
| 11 | use Pods\Whatsit\Object_Field; |
| 12 | use Pods\API\Whatsit\Value_Field; |
| 13 | use Pods\Whatsit\Store; |
| 14 | |
| 15 | /** |
| 16 | * @package Pods\Fields |
| 17 | */ |
| 18 | class PodsField_Pick extends PodsField { |
| 19 | |
| 20 | /** |
| 21 | * {@inheritdoc} |
| 22 | */ |
| 23 | public static $group = 'Relationships / Media'; |
| 24 | |
| 25 | /** |
| 26 | * {@inheritdoc} |
| 27 | */ |
| 28 | public static $type = 'pick'; |
| 29 | |
| 30 | /** |
| 31 | * {@inheritdoc} |
| 32 | */ |
| 33 | public static $label = 'Relationship'; |
| 34 | |
| 35 | /** |
| 36 | * {@inheritdoc} |
| 37 | */ |
| 38 | protected static $api = false; |
| 39 | |
| 40 | /** |
| 41 | * Available Related Objects. |
| 42 | * |
| 43 | * @var array |
| 44 | * @since 2.3.0 |
| 45 | */ |
| 46 | public static $related_objects = []; |
| 47 | |
| 48 | /** |
| 49 | * Custom Related Objects |
| 50 | * |
| 51 | * @var array |
| 52 | * @since 2.3.0 |
| 53 | */ |
| 54 | public static $custom_related_objects = []; |
| 55 | |
| 56 | /** |
| 57 | * Data used during validate / save to avoid extra queries. |
| 58 | * |
| 59 | * @var array |
| 60 | * @since 2.3.0 |
| 61 | */ |
| 62 | public static $related_data = []; |
| 63 | |
| 64 | /** |
| 65 | * Data used during input method (mainly for autocomplete). |
| 66 | * |
| 67 | * @var array |
| 68 | * @since 2.3.0 |
| 69 | */ |
| 70 | public static $field_data = []; |
| 71 | |
| 72 | /** |
| 73 | * Saved array of simple relationship names. |
| 74 | * |
| 75 | * @var array |
| 76 | * @since 2.5.0 |
| 77 | */ |
| 78 | private static $names_simple = null; |
| 79 | |
| 80 | /** |
| 81 | * Saved array of relationship names |
| 82 | * |
| 83 | * @var array |
| 84 | * @since 2.5.0 |
| 85 | */ |
| 86 | private static $names_related = null; |
| 87 | |
| 88 | /** |
| 89 | * Saved array of bidirectional relationship names |
| 90 | * |
| 91 | * @var array |
| 92 | * @since 2.5.0 |
| 93 | */ |
| 94 | private static $names_bidirectional = null; |
| 95 | |
| 96 | /** |
| 97 | * {@inheritdoc} |
| 98 | */ |
| 99 | public function setup() { |
| 100 | |
| 101 | static::$group = __( 'Relationships / Media', 'pods' ); |
| 102 | static::$label = __( 'Relationship', 'pods' ); |
| 103 | } |
| 104 | |
| 105 | /** |
| 106 | * {@inheritdoc} |
| 107 | */ |
| 108 | public function admin_init() { |
| 109 | |
| 110 | // AJAX for Relationship lookups. |
| 111 | add_action( 'wp_ajax_pods_relationship', [ $this, 'admin_ajax_relationship' ] ); |
| 112 | add_action( 'wp_ajax_nopriv_pods_relationship', [ $this, 'admin_ajax_relationship' ] ); |
| 113 | |
| 114 | // Handle modal input. |
| 115 | add_action( 'pods_meta_box_pre', [ $this, 'admin_modal_input' ] ); |
| 116 | add_action( 'edit_form_top', [ $this, 'admin_modal_input' ] ); |
| 117 | add_action( 'show_user_profile', [ $this, 'admin_modal_input' ] ); |
| 118 | add_action( 'edit_user_profile', [ $this, 'admin_modal_input' ] ); |
| 119 | |
| 120 | // Hook into every taxonomy form. |
| 121 | $taxonomies = get_taxonomies(); |
| 122 | |
| 123 | foreach ( $taxonomies as $taxonomy ) { |
| 124 | if ( $taxonomy instanceof WP_Term ) { |
| 125 | $taxonomy = $taxonomy->name; |
| 126 | } |
| 127 | |
| 128 | add_action( $taxonomy . '_add_form', [ $this, 'admin_modal_input' ] ); |
| 129 | add_action( $taxonomy . '_edit_form', [ $this, 'admin_modal_input' ] ); |
| 130 | } |
| 131 | |
| 132 | // Handle modal saving. |
| 133 | add_filter( 'redirect_post_location', [ $this, 'admin_modal_bail_post_redirect' ], 10, 2 ); |
| 134 | add_action( 'load-edit-tags.php', [ $this, 'admin_modal_bail_term_action' ] ); |
| 135 | add_action( 'load-categories.php', [ $this, 'admin_modal_bail_term_action' ] ); |
| 136 | add_action( 'load-edit-link-categories.php', [ $this, 'admin_modal_bail_term_action' ] ); |
| 137 | add_action( 'personal_options_update', [ $this, 'admin_modal_bail_user_action' ] ); |
| 138 | add_action( 'user_register', [ $this, 'admin_modal_bail_user_action' ] ); |
| 139 | add_action( 'pods_api_processed_form', [ $this, 'admin_modal_bail_pod' ], 10, 3 ); |
| 140 | |
| 141 | } |
| 142 | |
| 143 | /** |
| 144 | * {@inheritdoc} |
| 145 | */ |
| 146 | public function options() { |
| 147 | // translators: %s: is the Documentation linked text. |
| 148 | $fallback_help = __( 'More details on our %s.', 'pods' ); |
| 149 | |
| 150 | $fallback_help_link = sprintf( |
| 151 | '<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>', |
| 152 | esc_url( 'https://docs.pods.io/fields/relationship/' ), |
| 153 | __( 'Field Type Documentation', 'pods' ) |
| 154 | ); |
| 155 | |
| 156 | $fallback_help = sprintf( $fallback_help, $fallback_help_link ); |
| 157 | |
| 158 | $simple_objects = $this->simple_objects(); |
| 159 | |
| 160 | $slow_text = __( '(may be slow for large data sets)', 'pods' ); |
| 161 | |
| 162 | $options = [ |
| 163 | static::$type . '_format_type' => [ |
| 164 | 'label' => __( 'Selection Type', 'pods' ), |
| 165 | 'help' => $fallback_help, |
| 166 | 'default' => 'single', |
| 167 | 'required' => true, |
| 168 | 'type' => 'pick', |
| 169 | 'data' => [ |
| 170 | 'single' => __( 'Single Select', 'pods' ), |
| 171 | 'multi' => __( 'Multiple Select', 'pods' ), |
| 172 | ], |
| 173 | 'pick_format_single' => 'dropdown', |
| 174 | 'pick_show_select_text' => 0, |
| 175 | 'dependency' => true, |
| 176 | ], |
| 177 | static::$type . '_format_single' => [ |
| 178 | 'label' => __( 'Input Type', 'pods' ), |
| 179 | 'help' => $fallback_help, |
| 180 | 'depends-on' => [ |
| 181 | static::$type . '_format_type' => 'single', |
| 182 | ], |
| 183 | 'default' => 'dropdown', |
| 184 | 'required' => true, |
| 185 | 'type' => 'pick', |
| 186 | 'data' => apply_filters( 'pods_form_ui_field_pick_format_single_options', [ |
| 187 | 'dropdown' => __( 'Drop Down', 'pods' ) . ' ' . $slow_text, |
| 188 | 'radio' => __( 'Radio Buttons', 'pods' ) . ' ' . $slow_text, |
| 189 | 'autocomplete' => __( 'Autocomplete', 'pods' ), |
| 190 | 'list' => __( 'List View (single value)', 'pods' ), |
| 191 | ] ), |
| 192 | 'pick_format_single' => 'dropdown', |
| 193 | 'pick_show_select_text' => 0, |
| 194 | 'dependency' => true, |
| 195 | ], |
| 196 | static::$type . '_format_single_help' => [ |
| 197 | 'label' => '', |
| 198 | 'type' => 'html', |
| 199 | 'default' => 0, |
| 200 | 'html_content' => '<p><em>' . esc_html__( 'Please note: When relating to dynamic content with large amounts of data, Drop Down or Radio Buttons can cause the edit screen to load very slowly because it loads all data at once. Consider using the Autocomplete or List View instead.', 'pods' ) . '</em></p>', |
| 201 | 'dependency' => true, |
| 202 | 'wildcard-on' => [ |
| 203 | static::$type . '_format_single' => [ |
| 204 | '^dropdown$', |
| 205 | '^radio$', |
| 206 | ], |
| 207 | static::$type . '_object' => [ |
| 208 | '^post_type-(?!(custom_css|customize_changeset)).*$', |
| 209 | '^taxonomy-.*$', |
| 210 | '^user$', |
| 211 | '^pod-.*$', |
| 212 | ], |
| 213 | ], |
| 214 | ], |
| 215 | static::$type . '_format_multi' => [ |
| 216 | 'label' => __( 'Input Type', 'pods' ), |
| 217 | 'help' => $fallback_help, |
| 218 | 'depends-on' => [ |
| 219 | static::$type . '_format_type' => 'multi', |
| 220 | ], |
| 221 | 'default' => 'list', |
| 222 | 'required' => true, |
| 223 | 'type' => 'pick', |
| 224 | 'data' => apply_filters( 'pods_form_ui_field_pick_format_multi_options', [ |
| 225 | 'checkbox' => __( 'Checkboxes', 'pods' ) . ' ' . $slow_text, |
| 226 | 'multiselect' => __( 'Multi Select (basic selection)', 'pods' ) . ' ' . $slow_text, |
| 227 | 'autocomplete' => __( 'Autocomplete', 'pods' ), |
| 228 | 'list' => __( 'List View (with reordering)', 'pods' ), |
| 229 | ] ), |
| 230 | 'pick_format_single' => 'dropdown', |
| 231 | 'pick_show_select_text' => 0, |
| 232 | 'dependency' => true, |
| 233 | ], |
| 234 | static::$type . '_format_multi_help' => [ |
| 235 | 'label' => '', |
| 236 | 'type' => 'html', |
| 237 | 'default' => 0, |
| 238 | 'html_content' => '<p><em>' . esc_html__( 'Please note: When relating to dynamic content with large amounts of data, Checkboxes or Multi Select can cause the edit screen to load very slowly because it loads all data at once. Consider using the Autocomplete or List View instead.', 'pods' ) . '</em></p>', |
| 239 | 'dependency' => true, |
| 240 | 'wildcard-on' => [ |
| 241 | static::$type . '_format_multi' => [ |
| 242 | '^checkbox$', |
| 243 | '^multiselect$', |
| 244 | ], |
| 245 | static::$type . '_object' => [ |
| 246 | '^post_type-(?!(custom_css|customize_changeset)).*$', |
| 247 | '^taxonomy-.*$', |
| 248 | '^user$', |
| 249 | '^pod-.*$', |
| 250 | ], |
| 251 | ], |
| 252 | ], |
| 253 | static::$type . '_display_format_multi' => [ |
| 254 | 'label' => __( 'Display Format', 'pods' ), |
| 255 | 'help' => __( 'Used as format for front-end display', 'pods' ) . ' ' . $fallback_help, |
| 256 | 'depends-on' => [ |
| 257 | static::$type . '_format_type' => 'multi', |
| 258 | ], |
| 259 | 'default' => 'default', |
| 260 | 'required' => true, |
| 261 | 'type' => 'pick', |
| 262 | 'data' => [ |
| 263 | 'default' => __( 'Item 1, Item 2, and Item 3', 'pods' ), |
| 264 | 'non_serial' => __( 'Item 1, Item 2 and Item 3', 'pods' ), |
| 265 | 'br' => __( 'One per line (br HTML tags)', 'pods' ), |
| 266 | 'ul' => __( 'Unordered HTML list', 'pods' ), |
| 267 | 'ol' => __( 'Ordered HTML list', 'pods' ), |
| 268 | 'custom' => __( 'Custom separator (without "and")', 'pods' ), |
| 269 | ], |
| 270 | 'pick_format_single' => 'dropdown', |
| 271 | 'pick_show_select_text' => 0, |
| 272 | 'dependency' => true, |
| 273 | ], |
| 274 | static::$type . '_display_format_separator' => [ |
| 275 | 'label' => __( 'Display Format Separator', 'pods' ), |
| 276 | 'help' => __( 'Used as separator for front-end display. This also turns off the "and" portion of the formatting.', 'pods' ) . ' ' . $fallback_help, |
| 277 | 'depends-on' => [ |
| 278 | static::$type . '_display_format_multi' => 'custom', |
| 279 | static::$type . '_format_type' => 'multi', |
| 280 | ], |
| 281 | 'default' => ', ', |
| 282 | 'type' => 'text', |
| 283 | ], |
| 284 | static::$type . '_allow_add_new' => [ |
| 285 | 'label' => __( 'Allow Add New', 'pods' ), |
| 286 | 'help' => __( 'Allow new related records to be created in a modal window', 'pods' ) . ' ' . $fallback_help, |
| 287 | 'wildcard-on' => [ |
| 288 | static::$type . '_object' => [ |
| 289 | '^post_type-(?!(custom_css|customize_changeset)).*$', |
| 290 | //'^taxonomy-.*$', @todo We need to finish adding support for add new on term form. |
| 291 | '^user$', |
| 292 | '^pod-.*$', |
| 293 | ], |
| 294 | ], |
| 295 | 'type' => 'boolean', |
| 296 | 'default' => 1, |
| 297 | ], |
| 298 | static::$type . '_add_new_label' => [ |
| 299 | 'label' => __( 'Add New Label', 'pods' ), |
| 300 | 'placeholder' => __( 'Add New', 'pods' ), |
| 301 | 'default' => '', |
| 302 | 'type' => 'text', |
| 303 | 'depends-on' => [ static::$type . '_allow_add_new' => true ], |
| 304 | ], |
| 305 | static::$type . '_taggable' => [ |
| 306 | 'label' => __( 'Taggable', 'pods' ), |
| 307 | 'help' => __( 'Allow new values to be inserted when using an Autocomplete field', 'pods' ) . ' ' . $fallback_help, |
| 308 | 'depends-on-any' => [ |
| 309 | static::$type . '_format_single' => 'autocomplete', |
| 310 | static::$type . '_format_multi' => 'autocomplete', |
| 311 | ], |
| 312 | 'excludes-on' => [ |
| 313 | static::$type . '_object' => array_merge( [ |
| 314 | 'site', |
| 315 | 'network', |
| 316 | ], $simple_objects ), |
| 317 | static::$type . '_allow_add_new' => false, |
| 318 | ], |
| 319 | 'type' => 'boolean', |
| 320 | 'default' => 0, |
| 321 | ], |
| 322 | static::$type . '_show_icon' => [ |
| 323 | 'label' => __( 'Show Icons', 'pods' ), |
| 324 | 'help' => $fallback_help, |
| 325 | 'depends-on-any' => [ |
| 326 | static::$type . '_format_single' => 'list', |
| 327 | static::$type . '_format_multi' => 'list', |
| 328 | ], |
| 329 | 'excludes-on' => [ |
| 330 | static::$type . '_object' => array_merge( [ 'site', 'network' ], $simple_objects ), |
| 331 | ], |
| 332 | 'type' => 'boolean', |
| 333 | 'default' => 1, |
| 334 | ], |
| 335 | static::$type . '_show_edit_link' => [ |
| 336 | 'label' => __( 'Show Edit Links', 'pods' ), |
| 337 | 'help' => $fallback_help, |
| 338 | 'depends-on-any' => [ |
| 339 | static::$type . '_format_single' => 'list', |
| 340 | static::$type . '_format_multi' => 'list', |
| 341 | ], |
| 342 | 'excludes-on' => [ |
| 343 | static::$type . '_object' => array_merge( [ 'site', 'network' ], $simple_objects ), |
| 344 | ], |
| 345 | 'type' => 'boolean', |
| 346 | 'default' => 1, |
| 347 | ], |
| 348 | static::$type . '_show_view_link' => [ |
| 349 | 'label' => __( 'Show View Links', 'pods' ), |
| 350 | 'help' => $fallback_help, |
| 351 | 'depends-on-any' => [ |
| 352 | static::$type . '_format_single' => 'list', |
| 353 | static::$type . '_format_multi' => 'list', |
| 354 | ], |
| 355 | 'excludes-on' => [ |
| 356 | static::$type . '_object' => array_merge( [ 'site', 'network' ], $simple_objects ), |
| 357 | ], |
| 358 | 'type' => 'boolean', |
| 359 | 'default' => 1, |
| 360 | ], |
| 361 | static::$type . '_select_text' => [ |
| 362 | 'label' => __( 'Default Select Text', 'pods' ), |
| 363 | 'help' => __( 'This is the text used for the default "no selection" dropdown item. If left empty, it will default to "-- Select One --"', 'pods' ) . ' ' . $fallback_help, |
| 364 | 'depends-on' => [ |
| 365 | static::$type . '_format_type' => 'single', |
| 366 | static::$type . '_format_single' => 'dropdown', |
| 367 | ], |
| 368 | 'default' => '', |
| 369 | 'text_placeholder' => __( '-- Select One --', 'pods' ), |
| 370 | 'type' => 'text', |
| 371 | ], |
| 372 | static::$type . '_limit' => [ |
| 373 | 'label' => __( 'Selection Limit', 'pods' ), |
| 374 | 'help' => __( 'Default is "0" for no limit, but you can enter 1 or more to limit the number of items that can be selected.', 'pods' ) . ' ' . $fallback_help, |
| 375 | 'depends-on' => [ |
| 376 | static::$type . '_format_type' => 'multi', |
| 377 | ], |
| 378 | 'default' => 0, |
| 379 | 'type' => 'number', |
| 380 | ], |
| 381 | static::$type . '_table_id' => [ |
| 382 | 'label' => __( 'Table ID Column', 'pods' ), |
| 383 | 'help' => __( 'You must provide the ID column name for the table, this will be used to keep track of the relationship', 'pods' ) . ' ' . $fallback_help, |
| 384 | 'depends-on' => [ |
| 385 | static::$type . '_object' => 'table', |
| 386 | ], |
| 387 | 'required' => 1, |
| 388 | 'default' => '', |
| 389 | 'type' => 'text', |
| 390 | ], |
| 391 | static::$type . '_table_index' => [ |
| 392 | 'label' => __( 'Table Index Column', 'pods' ), |
| 393 | 'help' => __( 'You must provide the index column name for the table, this may optionally also be the ID column name', 'pods' ) . ' ' . $fallback_help, |
| 394 | 'depends-on' => [ |
| 395 | static::$type . '_object' => 'table', |
| 396 | ], |
| 397 | 'required' => 1, |
| 398 | 'default' => '', |
| 399 | 'type' => 'text', |
| 400 | ], |
| 401 | static::$type . '_display' => [ |
| 402 | 'label' => __( 'Display Field in Selection List', 'pods' ), |
| 403 | 'help' => __( 'Provide the name of a field on the related object to reference, example: {@post_title}', 'pods' ) . ' ' . $fallback_help, |
| 404 | 'excludes-on' => [ |
| 405 | static::$type . '_object' => array_merge( [ 'site', 'network' ], $simple_objects ), |
| 406 | ], |
| 407 | 'default' => '', |
| 408 | 'type' => 'text', |
| 409 | ], |
| 410 | static::$type . '_user_role' => [ |
| 411 | 'label' => __( 'Limit list by Role(s)', 'pods' ), |
| 412 | 'help' => __( 'You can choose to limit Users available for selection by specific role(s).', 'pods' ) . ' ' . $fallback_help, |
| 413 | 'default' => '', |
| 414 | 'type' => 'pick', |
| 415 | 'pick_object' => 'role', |
| 416 | 'pick_format_type' => 'multi', |
| 417 | 'pick_format_multi' => 'autocomplete', |
| 418 | 'depends-on' => [ |
| 419 | static::$type . '_object' => 'user', |
| 420 | ], |
| 421 | ], |
| 422 | static::$type . '_where' => [ |
| 423 | 'label' => __( 'Customized <em>WHERE</em>', 'pods' ), |
| 424 | 'help' => $fallback_help, |
| 425 | 'excludes-on' => [ |
| 426 | static::$type . '_object' => array_merge( [ 'site', 'network' ], $simple_objects ), |
| 427 | ], |
| 428 | 'default' => '', |
| 429 | 'type' => 'text', |
| 430 | ], |
| 431 | static::$type . '_orderby' => [ |
| 432 | 'label' => __( 'Customized <em>ORDER BY</em>', 'pods' ), |
| 433 | 'help' => $fallback_help, |
| 434 | 'excludes-on' => [ |
| 435 | static::$type . '_object' => array_merge( [ 'site', 'network' ], $simple_objects ), |
| 436 | ], |
| 437 | 'default' => '', |
| 438 | 'type' => 'text', |
| 439 | ], |
| 440 | static::$type . '_groupby' => [ |
| 441 | 'label' => __( 'Customized <em>GROUP BY</em>', 'pods' ), |
| 442 | 'help' => $fallback_help, |
| 443 | 'excludes-on' => [ |
| 444 | static::$type . '_object' => array_merge( [ 'site', 'network' ], $simple_objects ), |
| 445 | ], |
| 446 | 'default' => '', |
| 447 | 'type' => 'text', |
| 448 | ], |
| 449 | static::$type . '_sync_taxonomy' => [ |
| 450 | 'label' => __( 'Sync associated taxonomy with this relationship', 'pods' ), |
| 451 | 'help' => __( 'This will automatically sync the associated taxonomy terms with the value of this relationship if this field is on a Pod that is a Post Type. If the associated taxonomy terms are different, they will be overridden on save.', 'pods' ), |
| 452 | 'wildcard-on' => [ |
| 453 | static::$type . '_object' => [ |
| 454 | '^taxonomy-.*$', |
| 455 | ], |
| 456 | ], |
| 457 | 'type' => 'boolean', |
| 458 | 'default' => 0, |
| 459 | ], |
| 460 | static::$type . '_sync_taxonomy_hide_taxonomy_ui' => [ |
| 461 | 'label' => __( 'Hide the associated taxonomy UI from the Editor', 'pods' ), |
| 462 | 'help' => __( 'This will hide the taxonomy meta box from the Classic Editor and disable the taxonomy panel in the Block Editor.', 'pods' ), |
| 463 | 'depends-on' => [ |
| 464 | static::$type . '_sync_taxonomy' => true, |
| 465 | ], |
| 466 | 'wildcard-on' => [ |
| 467 | static::$type . '_object' => [ |
| 468 | '^taxonomy-.*$', |
| 469 | ], |
| 470 | ], |
| 471 | 'type' => 'boolean', |
| 472 | 'default' => 0, |
| 473 | ], |
| 474 | ]; |
| 475 | |
| 476 | $post_type_pick_objects = []; |
| 477 | |
| 478 | foreach ( get_post_types( '', 'names' ) as $post_type ) { |
| 479 | $post_type_pick_objects[] = 'post_type-' . $post_type; |
| 480 | } |
| 481 | |
| 482 | $options[ static::$type . '_post_status' ] = [ |
| 483 | 'label' => __( 'Limit list by Post Status', 'pods' ), |
| 484 | 'help' => __( 'You can choose to limit Posts available for selection by one or more specific post status.', 'pods' ), |
| 485 | 'type' => 'pick', |
| 486 | 'pick_object' => 'post-status-with-any', |
| 487 | 'pick_format_type' => 'multi', |
| 488 | 'default' => 'publish', |
| 489 | 'depends-on' => [ |
| 490 | static::$type . '_object' => $post_type_pick_objects, |
| 491 | ], |
| 492 | ]; |
| 493 | |
| 494 | $options[ static::$type . '_post_author' ] = [ |
| 495 | 'label' => __( 'Limit list to the same Post Author', 'pods' ), |
| 496 | 'help' => __( 'You can choose to limit Posts available for selection to those created by the same Post Author. This only works if this pod is a Post Type and this field is related to a Post Type.', 'pods' ), |
| 497 | 'type' => 'boolean', |
| 498 | 'default' => 0, |
| 499 | 'depends-on' => [ |
| 500 | // @todo Support being able to depend on the current pod type like _pod_type => post_type or something. |
| 501 | static::$type . '_object' => $post_type_pick_objects, |
| 502 | ], |
| 503 | ]; |
| 504 | |
| 505 | return $options; |
| 506 | |
| 507 | } |
| 508 | |
| 509 | /** |
| 510 | * {@inheritdoc} |
| 511 | */ |
| 512 | public function prepare( $options = null ) { |
| 513 | $format = static::$prepare; |
| 514 | |
| 515 | // Maybe use number format for storage if not a simple relationship and limit is one. |
| 516 | if ( $options instanceof Field && ! $options->is_simple_relationship() && 1 === $options->get_limit() ) { |
| 517 | $format = '%d'; |
| 518 | } |
| 519 | |
| 520 | return $format; |
| 521 | } |
| 522 | |
| 523 | /** |
| 524 | * Register a related object. |
| 525 | * |
| 526 | * @param string $name Object name. |
| 527 | * @param string $label Object label. |
| 528 | * @param array $options Object options. |
| 529 | * |
| 530 | * @return array|boolean Object array or false if unsuccessful |
| 531 | * @since 2.3.0 |
| 532 | */ |
| 533 | public function register_related_object( $name, $label, $options = null ) { |
| 534 | |
| 535 | if ( empty( $name ) || empty( $label ) ) { |
| 536 | return false; |
| 537 | } |
| 538 | |
| 539 | $related_object = [ |
| 540 | 'label' => $label, |
| 541 | 'group' => 'Custom Relationships', |
| 542 | 'simple' => true, |
| 543 | 'bidirectional' => false, |
| 544 | 'data' => [], |
| 545 | 'data_callback' => null, |
| 546 | ]; |
| 547 | |
| 548 | $related_object = array_merge( $related_object, $options ); |
| 549 | |
| 550 | if ( $related_object['data_callback'] instanceof Closure ) { |
| 551 | return pods_error( 'Pods does not support closures for data callbacks' ); |
| 552 | } |
| 553 | |
| 554 | self::$custom_related_objects[ $name ] = $related_object; |
| 555 | |
| 556 | return true; |
| 557 | |
| 558 | } |
| 559 | |
| 560 | /** |
| 561 | * Setup related objects. |
| 562 | * |
| 563 | * @param boolean $force Whether to force refresh of related objects. |
| 564 | * |
| 565 | * @return bool True when data has been loaded |
| 566 | * @since 2.3.0 |
| 567 | */ |
| 568 | public function setup_related_objects( $force = false ) { |
| 569 | |
| 570 | $new_data_loaded = false; |
| 571 | |
| 572 | if ( ! $force && empty( self::$related_objects ) ) { |
| 573 | // Only load transient if we aren't forcing a refresh. |
| 574 | self::$related_objects = pods_transient_get( 'pods_related_objects' ); |
| 575 | |
| 576 | if ( false !== self::$related_objects ) { |
| 577 | $new_data_loaded = true; |
| 578 | } |
| 579 | } elseif ( $force ) { |
| 580 | // If we are rebuilding, make sure we start with a clean slate. |
| 581 | self::$related_objects = []; |
| 582 | } |
| 583 | |
| 584 | if ( ! is_array( self::$related_objects ) ) { |
| 585 | self::$related_objects = []; |
| 586 | } |
| 587 | |
| 588 | if ( empty( self::$related_objects ) ) { |
| 589 | // Do a complete build of related_objects. |
| 590 | $new_data_loaded = true; |
| 591 | |
| 592 | // Custom simple relationship lists. |
| 593 | self::$related_objects['custom-simple'] = [ |
| 594 | 'label' => __( 'Simple (custom defined list)', 'pods' ), |
| 595 | 'group' => __( 'Custom', 'pods' ), |
| 596 | 'simple' => true, |
| 597 | ]; |
| 598 | |
| 599 | // Pods options. |
| 600 | $pod_options = []; |
| 601 | |
| 602 | // Include PodsMeta if not already included. |
| 603 | pods_meta(); |
| 604 | |
| 605 | // Advanced Content Types for relationships. |
| 606 | $_pods = PodsMeta::$advanced_content_types; |
| 607 | |
| 608 | foreach ( $_pods as $pod ) { |
| 609 | $pod_options[ $pod['name'] ] = $pod['label'] . ' (' . $pod['name'] . ')'; |
| 610 | } |
| 611 | |
| 612 | /** |
| 613 | * Allow filtering the list of Pods to show in the list of relationship objects. |
| 614 | * |
| 615 | * @since 2.8.0 |
| 616 | * |
| 617 | * @param array $pod_options List of Pods to show in the list of relationship objects. |
| 618 | */ |
| 619 | $pod_options = apply_filters( 'pods_field_pick_setup_related_objects_pods', $pod_options ); |
| 620 | |
| 621 | asort( $pod_options ); |
| 622 | |
| 623 | foreach ( $pod_options as $pod => $label ) { |
| 624 | self::$related_objects[ 'pod-' . $pod ] = [ |
| 625 | 'label' => $label, |
| 626 | 'group' => __( 'Advanced Content Types', 'pods' ), |
| 627 | 'bidirectional' => true, |
| 628 | ]; |
| 629 | } |
| 630 | |
| 631 | /** |
| 632 | * Prevent ability to extend core Pods content types. |
| 633 | * |
| 634 | * @param bool $ignore_internal Default is true, when set to false Pods internal content types can not be extended. |
| 635 | * |
| 636 | * @since 2.3.19 |
| 637 | */ |
| 638 | $ignore_internal = apply_filters( 'pods_pick_ignore_internal', true ); |
| 639 | |
| 640 | $pods_meta = pods_meta(); |
| 641 | |
| 642 | // Public Post Types for relationships. |
| 643 | $post_types = get_post_types( [ 'public' => true ] ); |
| 644 | asort( $post_types ); |
| 645 | |
| 646 | foreach ( $post_types as $post_type => $label ) { |
| 647 | $post_type = (string) $post_type; |
| 648 | |
| 649 | if ( |
| 650 | empty( $post_type ) |
| 651 | || 'attachment' === $post_type |
| 652 | || ( |
| 653 | $pods_meta |
| 654 | && ! $pods_meta->is_type_covered( 'post_type', $post_type ) |
| 655 | ) |
| 656 | ) { |
| 657 | unset( $post_types[ $post_type ] ); |
| 658 | |
| 659 | continue; |
| 660 | } elseif ( $ignore_internal && 0 === strpos( $post_type, '_pods_' ) ) { |
| 661 | unset( $post_types[ $post_type ] ); |
| 662 | |
| 663 | continue; |
| 664 | } |
| 665 | |
| 666 | $post_type = get_post_type_object( $post_type ); |
| 667 | |
| 668 | self::$related_objects[ 'post_type-' . $post_type->name ] = [ |
| 669 | 'label' => $post_type->label . ' (' . $post_type->name . ')', |
| 670 | 'group' => __( 'Post Types', 'pods' ), |
| 671 | 'bidirectional' => true, |
| 672 | ]; |
| 673 | } |
| 674 | |
| 675 | // Post Types for relationships. |
| 676 | $post_types = get_post_types( [ 'public' => false ] ); |
| 677 | asort( $post_types ); |
| 678 | |
| 679 | foreach ( $post_types as $post_type => $label ) { |
| 680 | if ( |
| 681 | empty( $post_type ) |
| 682 | || 'attachment' === $post_type |
| 683 | || ( |
| 684 | $pods_meta |
| 685 | && ! $pods_meta->is_type_covered( 'post_type', $post_type ) |
| 686 | ) |
| 687 | ) { |
| 688 | unset( $post_types[ $post_type ] ); |
| 689 | |
| 690 | continue; |
| 691 | } elseif ( $ignore_internal && 0 === strpos( $post_type, '_pods_' ) ) { |
| 692 | unset( $post_types[ $post_type ] ); |
| 693 | |
| 694 | continue; |
| 695 | } |
| 696 | |
| 697 | $post_type = get_post_type_object( $post_type ); |
| 698 | |
| 699 | self::$related_objects[ 'post_type-' . $post_type->name ] = [ |
| 700 | 'label' => $post_type->label . ' (' . $post_type->name . ')', |
| 701 | 'group' => __( 'Post Types (Private)', 'pods' ), |
| 702 | 'bidirectional' => true, |
| 703 | ]; |
| 704 | } |
| 705 | |
| 706 | // Taxonomies for relationships. |
| 707 | $taxonomies = get_taxonomies(); |
| 708 | asort( $taxonomies ); |
| 709 | |
| 710 | foreach ( $taxonomies as $taxonomy => $label ) { |
| 711 | $taxonomy = (string) $taxonomy; |
| 712 | |
| 713 | if ( |
| 714 | empty( $taxonomy ) |
| 715 | || ( |
| 716 | $pods_meta |
| 717 | && ! $pods_meta->is_type_covered( 'taxonomy', $taxonomy ) |
| 718 | ) |
| 719 | ) { |
| 720 | unset( $taxonomies[ $taxonomy ] ); |
| 721 | |
| 722 | continue; |
| 723 | } elseif ( $ignore_internal && 0 === strpos( $taxonomy, '_pods_' ) ) { |
| 724 | unset( $taxonomies[ $taxonomy ] ); |
| 725 | |
| 726 | continue; |
| 727 | } |
| 728 | |
| 729 | $taxonomy = get_taxonomy( $taxonomy ); |
| 730 | |
| 731 | self::$related_objects[ 'taxonomy-' . $taxonomy->name ] = [ |
| 732 | 'label' => $taxonomy->label . ' (' . $taxonomy->name . ')', |
| 733 | 'group' => __( 'Taxonomies', 'pods' ), |
| 734 | 'bidirectional' => true, |
| 735 | ]; |
| 736 | }//end foreach |
| 737 | |
| 738 | // Other WP Objects for relationships. |
| 739 | self::$related_objects['user'] = [ |
| 740 | 'label' => __( 'Users', 'pods' ), |
| 741 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 742 | 'bidirectional' => true, |
| 743 | ]; |
| 744 | |
| 745 | self::$related_objects['role'] = [ |
| 746 | 'label' => __( 'User Roles', 'pods' ), |
| 747 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 748 | 'simple' => true, |
| 749 | 'data_callback' => [ $this, 'data_roles' ], |
| 750 | ]; |
| 751 | |
| 752 | self::$related_objects['capability'] = [ |
| 753 | 'label' => __( 'User Capabilities', 'pods' ), |
| 754 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 755 | 'simple' => true, |
| 756 | 'data_callback' => [ $this, 'data_capabilities' ], |
| 757 | ]; |
| 758 | |
| 759 | self::$related_objects['media'] = [ |
| 760 | 'label' => __( 'Media', 'pods' ), |
| 761 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 762 | 'bidirectional' => true, |
| 763 | ]; |
| 764 | |
| 765 | self::$related_objects['comment'] = [ |
| 766 | 'label' => __( 'Comments', 'pods' ), |
| 767 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 768 | 'bidirectional' => true, |
| 769 | ]; |
| 770 | |
| 771 | self::$related_objects['image-size'] = [ |
| 772 | 'label' => __( 'Image Sizes', 'pods' ), |
| 773 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 774 | 'simple' => true, |
| 775 | 'data_callback' => [ $this, 'data_image_sizes' ], |
| 776 | ]; |
| 777 | |
| 778 | self::$related_objects['nav_menu'] = [ |
| 779 | 'label' => __( 'Navigation Menus', 'pods' ), |
| 780 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 781 | ]; |
| 782 | |
| 783 | self::$related_objects['post_format'] = [ |
| 784 | 'label' => __( 'Post Formats', 'pods' ), |
| 785 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 786 | ]; |
| 787 | |
| 788 | self::$related_objects['post-status'] = [ |
| 789 | 'label' => __( 'Post Status', 'pods' ), |
| 790 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 791 | 'simple' => true, |
| 792 | 'data_callback' => [ $this, 'data_post_stati' ], |
| 793 | ]; |
| 794 | |
| 795 | self::$related_objects['post-status-with-any'] = [ |
| 796 | 'label' => __( 'Post Status (with any)', 'pods' ), |
| 797 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 798 | 'simple' => true, |
| 799 | 'data_callback' => [ $this, 'data_post_stati_with_any' ], |
| 800 | ]; |
| 801 | |
| 802 | self::$related_objects['post-types'] = [ |
| 803 | 'label' => __( 'Post Type Objects', 'pods' ), |
| 804 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 805 | 'simple' => true, |
| 806 | 'data_callback' => [ $this, 'data_post_types' ], |
| 807 | ]; |
| 808 | |
| 809 | self::$related_objects['taxonomies'] = [ |
| 810 | 'label' => __( 'Taxonomy Objects', 'pods' ), |
| 811 | 'group' => __( 'Other WP Objects', 'pods' ), |
| 812 | 'simple' => true, |
| 813 | 'data_callback' => [ $this, 'data_taxonomies' ], |
| 814 | ]; |
| 815 | |
| 816 | do_action( 'pods_form_ui_field_pick_related_objects_other' ); |
| 817 | |
| 818 | self::$related_objects['country'] = [ |
| 819 | 'label' => __( 'Countries', 'pods' ), |
| 820 | 'group' => __( 'Predefined Lists', 'pods' ), |
| 821 | 'simple' => true, |
| 822 | 'data_callback' => [ $this, 'data_countries' ], |
| 823 | ]; |
| 824 | |
| 825 | self::$related_objects['us_state'] = [ |
| 826 | 'label' => __( 'US States', 'pods' ), |
| 827 | 'group' => __( 'Predefined Lists', 'pods' ), |
| 828 | 'simple' => true, |
| 829 | 'data_callback' => [ $this, 'data_us_states' ], |
| 830 | ]; |
| 831 | |
| 832 | self::$related_objects['ca_province'] = [ |
| 833 | 'label' => __( 'CA Provinces', 'pods' ), |
| 834 | 'group' => __( 'Predefined Lists', 'pods' ), |
| 835 | 'simple' => true, |
| 836 | 'data_callback' => [ $this, 'data_ca_provinces' ], |
| 837 | ]; |
| 838 | |
| 839 | self::$related_objects['days_of_week'] = [ |
| 840 | 'label' => __( 'Calendar - Days of Week', 'pods' ), |
| 841 | 'group' => __( 'Predefined Lists', 'pods' ), |
| 842 | 'simple' => true, |
| 843 | 'data_callback' => [ $this, 'data_days_of_week' ], |
| 844 | ]; |
| 845 | |
| 846 | self::$related_objects['months_of_year'] = [ |
| 847 | 'label' => __( 'Calendar - Months of Year', 'pods' ), |
| 848 | 'group' => __( 'Predefined Lists', 'pods' ), |
| 849 | 'simple' => true, |
| 850 | 'data_callback' => [ $this, 'data_months_of_year' ], |
| 851 | ]; |
| 852 | |
| 853 | do_action( 'pods_form_ui_field_pick_related_objects_predefined' ); |
| 854 | |
| 855 | if ( did_action( 'init' ) ) { |
| 856 | pods_transient_set( 'pods_related_objects', self::$related_objects, WEEK_IN_SECONDS ); |
| 857 | } |
| 858 | }//end if |
| 859 | |
| 860 | /** |
| 861 | * Allow custom related objects to be defined |
| 862 | */ |
| 863 | do_action( 'pods_form_ui_field_pick_related_objects_custom' ); |
| 864 | |
| 865 | foreach ( self::$custom_related_objects as $object => $related_object ) { |
| 866 | if ( ! isset( self::$related_objects[ $object ] ) ) { |
| 867 | $new_data_loaded = true; |
| 868 | |
| 869 | self::$related_objects[ $object ] = $related_object; |
| 870 | } |
| 871 | } |
| 872 | |
| 873 | if ( $new_data_loaded ) { |
| 874 | /** |
| 875 | * Allow hooking in when new data has been loaded. |
| 876 | * |
| 877 | * @since 2.8.0 |
| 878 | */ |
| 879 | do_action( 'pods_form_ui_field_pick_related_objects_new_data_loaded' ); |
| 880 | } |
| 881 | |
| 882 | return true; |
| 883 | |
| 884 | } |
| 885 | |
| 886 | /** |
| 887 | * Return available related objects |
| 888 | * |
| 889 | * @param boolean $force Whether to force refresh of related objects. |
| 890 | * |
| 891 | * @return array Field selection array |
| 892 | * @since 2.3.0 |
| 893 | */ |
| 894 | public function related_objects( $force = false ) { |
| 895 | if ( null !== self::$names_related ) { |
| 896 | return self::$names_related; |
| 897 | } |
| 898 | |
| 899 | $this->setup_related_objects( $force ); |
| 900 | |
| 901 | $related_objects = []; |
| 902 | |
| 903 | foreach ( self::$related_objects as $related_object_name => $related_object ) { |
| 904 | if ( ! isset( $related_objects[ $related_object['group'] ] ) ) { |
| 905 | $related_objects[ $related_object['group'] ] = []; |
| 906 | } |
| 907 | |
| 908 | $related_objects[ $related_object['group'] ][ $related_object_name ] = $related_object['label']; |
| 909 | } |
| 910 | |
| 911 | self::$names_related = (array) apply_filters( 'pods_form_ui_field_pick_related_objects', $related_objects ); |
| 912 | |
| 913 | return self::$names_related; |
| 914 | } |
| 915 | |
| 916 | /** |
| 917 | * Return available simple object names |
| 918 | * |
| 919 | * @return array Simple object names |
| 920 | * @since 2.3.0 |
| 921 | */ |
| 922 | public function simple_objects() { |
| 923 | if ( null !== self::$names_simple ) { |
| 924 | return self::$names_simple; |
| 925 | } |
| 926 | |
| 927 | $this->setup_related_objects(); |
| 928 | |
| 929 | $simple_objects = []; |
| 930 | |
| 931 | foreach ( self::$related_objects as $object => $related_object ) { |
| 932 | if ( ! isset( $related_object['simple'] ) || ! $related_object['simple'] ) { |
| 933 | continue; |
| 934 | } |
| 935 | |
| 936 | $simple_objects[] = $object; |
| 937 | } |
| 938 | |
| 939 | self::$names_simple = (array) apply_filters( 'pods_form_ui_field_pick_simple_objects', $simple_objects ); |
| 940 | |
| 941 | return self::$names_simple; |
| 942 | } |
| 943 | |
| 944 | /** |
| 945 | * Return available bidirectional object names |
| 946 | * |
| 947 | * @return array Bidirectional object names |
| 948 | * @since 2.3.4 |
| 949 | */ |
| 950 | public function bidirectional_objects() { |
| 951 | if ( null !== self::$names_bidirectional ) { |
| 952 | return self::$names_bidirectional; |
| 953 | } |
| 954 | |
| 955 | $this->setup_related_objects(); |
| 956 | |
| 957 | $bidirectional_objects = []; |
| 958 | |
| 959 | foreach ( self::$related_objects as $object => $related_object ) { |
| 960 | if ( ! isset( $related_object['bidirectional'] ) || ! $related_object['bidirectional'] ) { |
| 961 | continue; |
| 962 | } |
| 963 | |
| 964 | $bidirectional_objects[] = $object; |
| 965 | } |
| 966 | |
| 967 | self::$names_bidirectional = (array) apply_filters( 'pods_form_ui_field_pick_bidirectional_objects', $bidirectional_objects ); |
| 968 | |
| 969 | return self::$names_bidirectional; |
| 970 | } |
| 971 | |
| 972 | /** |
| 973 | * {@inheritdoc} |
| 974 | */ |
| 975 | public function schema( $options = null ) { |
| 976 | $field = pods_config_for_field( $options ); |
| 977 | |
| 978 | if ( $field && $field->is_simple_relationship() ) { |
| 979 | return 'LONGTEXT'; |
| 980 | } |
| 981 | |
| 982 | return false; |
| 983 | } |
| 984 | |
| 985 | /** |
| 986 | * {@inheritdoc} |
| 987 | */ |
| 988 | public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) { |
| 989 | |
| 990 | $fields = null; |
| 991 | |
| 992 | if ( is_object( $pod ) && isset( $pod->fields ) ) { |
| 993 | /** |
| 994 | * @var $pod Pods Pods object. |
| 995 | */ |
| 996 | $fields = pods_config_get_all_fields( $pod ); |
| 997 | } elseif ( is_array( $pod ) && isset( $pod['fields'] ) ) { |
| 998 | $fields = pods_config_get_all_fields( $pod ); |
| 999 | } |
| 1000 | |
| 1001 | $args = [ |
| 1002 | 'field' => $name, |
| 1003 | 'fields' => $fields, |
| 1004 | ]; |
| 1005 | |
| 1006 | $display_format = pods_v( static::$type . '_display_format_multi', $options, 'default' ); |
| 1007 | |
| 1008 | switch ( $display_format ) { |
| 1009 | case 'ul': |
| 1010 | case 'ol': |
| 1011 | $value = '<' . $display_format . '><li>' . implode( '</li><li>', (array) $value ) . '</li></' . $display_format . '>'; |
| 1012 | break; |
| 1013 | case 'br': |
| 1014 | $value = implode( '<br />', $value ); |
| 1015 | break; |
| 1016 | case 'non_serial': |
| 1017 | $args['serial'] = false; |
| 1018 | $value = pods_serial_comma( $value, $args ); |
| 1019 | break; |
| 1020 | case 'custom': |
| 1021 | $args['serial'] = false; |
| 1022 | |
| 1023 | $separator = pods_v( static::$type . '_display_format_separator', $options, ', ' ); |
| 1024 | if ( ! empty( $separator ) ) { |
| 1025 | $args['separator'] = $separator; |
| 1026 | |
| 1027 | // Replicate separator behavior. |
| 1028 | $args['and'] = $args['separator']; |
| 1029 | } |
| 1030 | $value = pods_serial_comma( $value, $args ); |
| 1031 | break; |
| 1032 | default: |
| 1033 | $value = pods_serial_comma( $value, $args ); |
| 1034 | break; |
| 1035 | } |
| 1036 | |
| 1037 | return $value; |
| 1038 | } |
| 1039 | |
| 1040 | /** |
| 1041 | * {@inheritdoc} |
| 1042 | */ |
| 1043 | public function input( $name, $value = null, $options = null, $pod = null, $id = null ) { |
| 1044 | $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options; |
| 1045 | |
| 1046 | // Do anything we need to do here with options setup / enforcement. |
| 1047 | |
| 1048 | // Default labels. |
| 1049 | if ( empty( $options[ static::$type . '_add_new_label' ] ) ) { |
| 1050 | $options[ static::$type . '_add_new_label' ] = __( 'Add New', 'pods' ); |
| 1051 | } |
| 1052 | |
| 1053 | parent::input( $name, $value, $options, $pod, $id ); |
| 1054 | } |
| 1055 | |
| 1056 | /** |
| 1057 | * {@inheritdoc} |
| 1058 | */ |
| 1059 | public function build_dfv_field_options( $options, $args ) { |
| 1060 | // Use field object if it was provided. |
| 1061 | if ( isset( $options['_field_object'] ) ) { |
| 1062 | $field = $options['_field_object']; |
| 1063 | |
| 1064 | unset( $options['_field_object'] ); |
| 1065 | |
| 1066 | $options = pods_config_merge_data( $field, $options ); |
| 1067 | } |
| 1068 | |
| 1069 | $field_options = $options instanceof \Pods\Whatsit ? $options->export() : $options; |
| 1070 | |
| 1071 | if ( ! isset( $field_options['id'] ) ) { |
| 1072 | $field_options['id'] = 0; |
| 1073 | } |
| 1074 | |
| 1075 | // Enforce defaults. |
| 1076 | $all_options = static::options(); |
| 1077 | |
| 1078 | foreach ( $all_options as $option_name => $option ) { |
| 1079 | $default = pods_v( 'default', $option, '' ); |
| 1080 | |
| 1081 | $field_options[ $option_name ] = pods_v( $option_name, $field_options, $default ); |
| 1082 | |
| 1083 | if ( '' === $field_options[ $option_name ] ) { |
| 1084 | $field_options[ $option_name ] = $default; |
| 1085 | } |
| 1086 | } |
| 1087 | |
| 1088 | $field_options['grouped'] = 1; |
| 1089 | |
| 1090 | if ( empty( $field_options[ $args->type . '_object' ] ) ) { |
| 1091 | $field_options[ $args->type . '_object' ] = ''; |
| 1092 | } |
| 1093 | |
| 1094 | if ( empty( $field_options[ $args->type . '_val' ] ) ) { |
| 1095 | $field_options[ $args->type . '_val' ] = ''; |
| 1096 | } |
| 1097 | |
| 1098 | // Unset the table info for now. |
| 1099 | $field_options['table_info'] = []; |
| 1100 | |
| 1101 | $custom = pods_v( $args->type . '_custom', $field_options, false ); |
| 1102 | |
| 1103 | $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $args->name, $args->value, $field_options, $args->pod, $args->id ); |
| 1104 | |
| 1105 | $ajax = false; |
| 1106 | |
| 1107 | if ( $this->can_ajax( $args->type, $field_options ) ) { |
| 1108 | $ajax = true; |
| 1109 | |
| 1110 | $field_data = pods_static_cache_get( $field_options['name'] . '/' . $field_options['id'], __CLASS__ . '/field_data' ) ?: []; |
| 1111 | |
| 1112 | if ( isset( $field_data['autocomplete'] ) ) { |
| 1113 | $ajax = (boolean) $field_data['autocomplete']; |
| 1114 | } |
| 1115 | } |
| 1116 | |
| 1117 | $ajax = apply_filters( 'pods_form_ui_field_pick_ajax', $ajax, $args->name, $args->value, $field_options, $args->pod, $args->id ); |
| 1118 | |
| 1119 | if ( 0 === (int) pods_v( $args->type . '_ajax', $field_options, 1 ) ) { |
| 1120 | $ajax = false; |
| 1121 | } |
| 1122 | |
| 1123 | $field_options[ $args->type . '_ajax' ] = (int) $ajax; |
| 1124 | |
| 1125 | $format_type = pods_v( $args->type . '_format_type', $field_options, 'single', true ); |
| 1126 | |
| 1127 | $limit = 1; |
| 1128 | |
| 1129 | if ( 'single' === $format_type ) { |
| 1130 | $format_single = pods_v( $args->type . '_format_single', $field_options, 'dropdown', true ); |
| 1131 | |
| 1132 | if ( ! empty( $args->value ) && is_array( $args->value ) ) { |
| 1133 | $args->value = reset( $args->value ); |
| 1134 | } |
| 1135 | |
| 1136 | if ( 'dropdown' === $format_single ) { |
| 1137 | $field_options['view_name'] = 'select'; |
| 1138 | } elseif ( 'radio' === $format_single ) { |
| 1139 | $field_options['view_name'] = 'radio'; |
| 1140 | } elseif ( 'autocomplete' === $format_single ) { |
| 1141 | $field_options['view_name'] = 'select2'; |
| 1142 | } elseif ( 'list' === $format_single ) { |
| 1143 | $field_options['view_name'] = 'list'; |
| 1144 | } else { |
| 1145 | $field_options['view_name'] = $format_single; |
| 1146 | } |
| 1147 | } elseif ( 'multi' === $format_type ) { |
| 1148 | $format_multi = pods_v( $args->type . '_format_multi', $field_options, 'checkbox', true ); |
| 1149 | |
| 1150 | if ( ! empty( $args->value ) && ! is_array( $args->value ) ) { |
| 1151 | $args->value = explode( ',', $args->value ); |
| 1152 | } |
| 1153 | |
| 1154 | if ( 'checkbox' === $format_multi ) { |
| 1155 | $field_options['view_name'] = 'checkbox'; |
| 1156 | } elseif ( 'multiselect' === $format_multi ) { |
| 1157 | $field_options['view_name'] = 'select'; |
| 1158 | } elseif ( 'autocomplete' === $format_multi ) { |
| 1159 | $field_options['view_name'] = 'select2'; |
| 1160 | } elseif ( 'list' === $format_multi ) { |
| 1161 | $field_options['view_name'] = 'list'; |
| 1162 | } else { |
| 1163 | $field_options['view_name'] = $format_multi; |
| 1164 | } |
| 1165 | |
| 1166 | $limit = 0; |
| 1167 | |
| 1168 | if ( ! empty( $field_options[ $args->type . '_limit' ] ) ) { |
| 1169 | $limit = absint( $field_options[ $args->type . '_limit' ] ); |
| 1170 | } |
| 1171 | } else { |
| 1172 | $field_options['view_name'] = $format_type; |
| 1173 | } |
| 1174 | |
| 1175 | $field_options[ $args->type . '_limit' ] = $limit; |
| 1176 | |
| 1177 | $field_options['ajax_data'] = $this->build_dfv_autocomplete_ajax_data( $field_options, $args, $ajax ); |
| 1178 | $field_options['select2_overrides'] = null; |
| 1179 | |
| 1180 | if ( 'select2' === $field_options['view_name'] ) { |
| 1181 | // @todo Revisit this, they probably aren't used anymore now since this is DFV. |
| 1182 | wp_enqueue_style( 'pods-select2' ); |
| 1183 | wp_enqueue_script( 'pods-select2' ); |
| 1184 | |
| 1185 | /** |
| 1186 | * Allow overriding some Select2/SelectWoo options used in the JS init. |
| 1187 | * |
| 1188 | * @since 2.7.0 |
| 1189 | * |
| 1190 | * @param array|null $select2_overrides Override options for Select2/SelectWoo. |
| 1191 | */ |
| 1192 | $field_options['select2_overrides'] = apply_filters( 'pods_pick_select2_overrides', $field_options['select2_overrides'] ); |
| 1193 | } |
| 1194 | |
| 1195 | if ( ! empty( $args->build_item_data ) ) { |
| 1196 | $field_options['item_data'] = $this->build_dfv_field_item_data( $args ); |
| 1197 | } |
| 1198 | |
| 1199 | return $field_options; |
| 1200 | } |
| 1201 | |
| 1202 | /** |
| 1203 | * Build DFV autocomplete AJAX data. |
| 1204 | * |
| 1205 | * @param array|Field $options DFV options. |
| 1206 | * @param object $args { |
| 1207 | * Field information arguments. |
| 1208 | * |
| 1209 | * @type string $name Field name. |
| 1210 | * @type string $type Field type. |
| 1211 | * @type array $options Field options. |
| 1212 | * @type mixed $value Current value. |
| 1213 | * @type array $pod Pod information. |
| 1214 | * @type int|string $id Current item ID. |
| 1215 | * } |
| 1216 | * |
| 1217 | * @param bool $ajax True if ajax mode should be used. |
| 1218 | * |
| 1219 | * @return array |
| 1220 | */ |
| 1221 | public function build_dfv_autocomplete_ajax_data( $options, $args, $ajax = false ) { |
| 1222 | |
| 1223 | if ( is_array( $args->pod ) ) { |
| 1224 | $pod_name = $args->pod['name']; |
| 1225 | } elseif ( $args->pod instanceof Pods ) { |
| 1226 | $pod_name = $args->pod->pod; |
| 1227 | } elseif ( $args->pod instanceof Pod ) { |
| 1228 | $pod_name = $args->pod->get_name(); |
| 1229 | } else { |
| 1230 | $pod_name = ''; |
| 1231 | } |
| 1232 | |
| 1233 | if ( is_array( $options ) ) { |
| 1234 | $field_name = pods_v( 'name', $options ); |
| 1235 | } elseif ( $options instanceof Field ) { |
| 1236 | $field_name = $options->get_name(); |
| 1237 | } else { |
| 1238 | $field_name = ''; |
| 1239 | } |
| 1240 | |
| 1241 | $id = (int) $args->id; |
| 1242 | |
| 1243 | if ( is_user_logged_in() ) { |
| 1244 | $uid = 'user_' . get_current_user_id(); |
| 1245 | } else { |
| 1246 | $uid = pods_session_id(); |
| 1247 | } |
| 1248 | |
| 1249 | $uri_hash = wp_create_nonce( 'pods_uri_' . $_SERVER['REQUEST_URI'] ); |
| 1250 | |
| 1251 | $nonce_name = 'pods_relationship:' . json_encode( compact( 'pod_name', 'field_name', 'uid', 'uri_hash', 'id' ) ); |
| 1252 | $field_nonce = wp_create_nonce( $nonce_name ); |
| 1253 | |
| 1254 | // Values can be overridden via the `pods_field_dfv_data` filter in $data['fieldConfig']['ajax_data']. |
| 1255 | return [ |
| 1256 | 'ajax' => $ajax, |
| 1257 | 'delay' => 300, |
| 1258 | 'minimum_input_length' => 1, |
| 1259 | 'pod_name' => $pod_name, |
| 1260 | 'field_name' => $field_name, |
| 1261 | 'id' => $id, |
| 1262 | 'uri_hash' => $uri_hash, |
| 1263 | '_wpnonce' => $field_nonce, |
| 1264 | ]; |
| 1265 | } |
| 1266 | |
| 1267 | /** |
| 1268 | * {@inheritdoc} |
| 1269 | */ |
| 1270 | public function build_dfv_field_config( $args ) { |
| 1271 | $config = parent::build_dfv_field_config( $args ); |
| 1272 | |
| 1273 | // Ensure data is passed in for relationship fields. |
| 1274 | if ( ! isset( $config['data'] ) && ! empty( $args->options['data'] ) ) { |
| 1275 | $config['data'] = $this->get_raw_data( $args->options ); |
| 1276 | } |
| 1277 | |
| 1278 | // Default optgroup handling to off. |
| 1279 | if ( ! isset( $config['optgroup'] ) ) { |
| 1280 | $config['optgroup'] = false; |
| 1281 | } |
| 1282 | |
| 1283 | /** |
| 1284 | * Filter on whether to allow modals to be used on the front of the site (in an non-admin area). |
| 1285 | * |
| 1286 | * @param boolean $show_on_front |
| 1287 | * @param array $config |
| 1288 | * @param object $args |
| 1289 | * |
| 1290 | * @since 2.7.0 |
| 1291 | */ |
| 1292 | $show_on_front = apply_filters( 'pods_ui_dfv_pick_modals_show_on_front', false, $config, $args ); |
| 1293 | |
| 1294 | /** |
| 1295 | * Filter on whether to allow nested modals to be used (modals within modals). |
| 1296 | * |
| 1297 | * @param boolean $allow_nested_modals |
| 1298 | * @param array $config |
| 1299 | * @param object $args |
| 1300 | * |
| 1301 | * @since 2.7.0 |
| 1302 | */ |
| 1303 | $allow_nested_modals = apply_filters( 'pods_ui_dfv_pick_modals_allow_nested', false, $config, $args ); |
| 1304 | |
| 1305 | // Disallow add/edit outside the admin and when we're already in a modal |
| 1306 | if ( ( ! $show_on_front && ! is_admin() ) || ( ! $allow_nested_modals && pods_is_modal_window() ) ) { |
| 1307 | $config[ $args->type . '_allow_add_new' ] = false; |
| 1308 | $config[ $args->type . '_show_edit_link' ] = false; |
| 1309 | } |
| 1310 | |
| 1311 | $config[ $args->type . '_taggable' ] = filter_var( pods_v( $args->type . '_taggable', $config ), FILTER_VALIDATE_BOOLEAN ); |
| 1312 | $config[ $args->type . '_allow_add_new' ] = filter_var( pods_v( $args->type . '_allow_add_new', $config ), FILTER_VALIDATE_BOOLEAN ); |
| 1313 | $config[ $args->type . '_show_edit_link' ] = filter_var( pods_v( $args->type . '_show_edit_link', $config ), FILTER_VALIDATE_BOOLEAN ); |
| 1314 | |
| 1315 | $iframe = [ |
| 1316 | 'src' => '', |
| 1317 | 'url' => '', |
| 1318 | 'query_args' => [], |
| 1319 | ]; |
| 1320 | |
| 1321 | // Set the file name and args based on the content type of the relationship |
| 1322 | switch ( $args->options['pick_object'] ) { |
| 1323 | case 'post_type': |
| 1324 | if ( ! empty( $args->options['pick_val'] ) ) { |
| 1325 | $post_type_obj = get_post_type_object( $args->options['pick_val'] ); |
| 1326 | |
| 1327 | if ( $post_type_obj && current_user_can( $post_type_obj->cap->create_posts ) ) { |
| 1328 | $iframe['url'] = admin_url( 'post-new.php' ); |
| 1329 | $iframe['query_args'] = [ |
| 1330 | 'post_type' => $args->options['pick_val'], |
| 1331 | ]; |
| 1332 | } |
| 1333 | } |
| 1334 | |
| 1335 | // Determine the default icon to use for this post type, |
| 1336 | // default to the dashicon for posts |
| 1337 | $config['default_icon'] = 'dashicons-admin-post'; |
| 1338 | |
| 1339 | // Any custom specified menu icon gets priority |
| 1340 | $post_type = get_post_type_object( $args->options['pick_val'] ); |
| 1341 | if ( ! empty( $post_type->menu_icon ) ) { |
| 1342 | $config['default_icon'] = $post_type->menu_icon; |
| 1343 | |
| 1344 | // Page and attachment have their own dashicons |
| 1345 | } elseif ( isset( $post_type->name ) ) { |
| 1346 | switch ( $post_type->name ) { |
| 1347 | case 'page': |
| 1348 | // Default for pages. |
| 1349 | $config['default_icon'] = 'dashicons-admin-page'; |
| 1350 | break; |
| 1351 | case 'attachment': |
| 1352 | // Default for attachments. |
| 1353 | $config['default_icon'] = 'dashicons-admin-media'; |
| 1354 | break; |
| 1355 | } |
| 1356 | } |
| 1357 | |
| 1358 | break; |
| 1359 | |
| 1360 | case 'taxonomy': |
| 1361 | /* |
| 1362 | * @todo Fix add new modal issues |
| 1363 | if ( ! empty( $args->options['pick_val'] ) ) { |
| 1364 | $taxonomy_obj = get_taxonomy( $args->options['pick_val'] ); |
| 1365 | |
| 1366 | if ( $taxonomy_obj && current_user_can( $taxonomy_obj->cap->edit_terms ) ) { |
| 1367 | $iframe['url'] = admin_url( 'edit-tags.php' ); |
| 1368 | $iframe['query_args'] = array( |
| 1369 | 'taxonomy' => $args->options['pick_val'], |
| 1370 | ); |
| 1371 | } |
| 1372 | } |
| 1373 | */ |
| 1374 | |
| 1375 | break; |
| 1376 | |
| 1377 | case 'user': |
| 1378 | if ( current_user_can( 'create_users' ) ) { |
| 1379 | $iframe['url'] = admin_url( 'user-new.php' ); |
| 1380 | } |
| 1381 | |
| 1382 | break; |
| 1383 | |
| 1384 | case 'pod': |
| 1385 | if ( ! empty( $args->options['pick_val'] ) ) { |
| 1386 | if ( pods_is_admin( [ 'pods', 'pods_content', 'pods_edit_' . $args->options['pick_val'] ] ) ) { |
| 1387 | $iframe['url'] = admin_url( 'admin.php' ); |
| 1388 | $iframe['query_args'] = [ |
| 1389 | 'page' => 'pods-manage-' . $args->options['pick_val'], |
| 1390 | 'action' => 'add', |
| 1391 | ]; |
| 1392 | |
| 1393 | } |
| 1394 | } |
| 1395 | |
| 1396 | break; |
| 1397 | }//end switch |
| 1398 | |
| 1399 | // Potential valid modal target if we've set the file name |
| 1400 | if ( ! empty( $iframe['url'] ) ) { |
| 1401 | // @todo: Replace string literal with defined constant |
| 1402 | $iframe['query_args']['pods_modal'] = 1; |
| 1403 | |
| 1404 | // Add args we always need |
| 1405 | $iframe['src'] = add_query_arg( $iframe['query_args'], $iframe['url'] ); |
| 1406 | } |
| 1407 | |
| 1408 | // translators: %s is the field label. |
| 1409 | $iframe['title_add'] = sprintf( __( '%s: Add New', 'pods' ), $args->options['label'] ); |
| 1410 | // translators: %s is the field label. |
| 1411 | $iframe['title_edit'] = sprintf( __( '%s: Edit', 'pods' ), $args->options['label'] ); |
| 1412 | |
| 1413 | /** |
| 1414 | * Allow filtering iframe configuration |
| 1415 | * |
| 1416 | * @param array $iframe |
| 1417 | * @param array $config |
| 1418 | * @param object $args |
| 1419 | * |
| 1420 | * @since 2.7.0 |
| 1421 | */ |
| 1422 | $iframe = apply_filters( 'pods_ui_dfv_pick_modals_iframe', $iframe, $config, $args ); |
| 1423 | |
| 1424 | if ( ! empty( $iframe['src'] ) ) { |
| 1425 | // We extend wp.media.view.Modal for modal add/edit, we must ensure we load the template for it |
| 1426 | wp_enqueue_media(); |
| 1427 | } |
| 1428 | |
| 1429 | $config['iframe_src'] = $iframe['src']; |
| 1430 | $config['iframe_title_add'] = $iframe['title_add']; |
| 1431 | $config['iframe_title_edit'] = $iframe['title_edit']; |
| 1432 | |
| 1433 | return $config; |
| 1434 | |
| 1435 | } |
| 1436 | |
| 1437 | /** |
| 1438 | * {@inheritdoc} |
| 1439 | */ |
| 1440 | public function build_dfv_field_item_data( $args ) { |
| 1441 | $args->options['supports_thumbnails'] = null; |
| 1442 | |
| 1443 | $item_data = []; |
| 1444 | $data = []; |
| 1445 | |
| 1446 | if ( ! empty( $args->options['data'] ) ) { |
| 1447 | $data = $this->get_raw_data( $args->options ); |
| 1448 | } elseif ( ! empty( $args->data ) ) { |
| 1449 | $data = $args->data; |
| 1450 | } else { |
| 1451 | $data = $this->data( $args->name, $args->value, $args->options, $args->pod, $args->id ); |
| 1452 | } |
| 1453 | |
| 1454 | if ( [] !== $data ) { |
| 1455 | $item_data = $this->build_dfv_field_item_data_recurse( $data, $args ); |
| 1456 | } |
| 1457 | |
| 1458 | return $item_data; |
| 1459 | |
| 1460 | } |
| 1461 | |
| 1462 | /** |
| 1463 | * Loop through relationship data and expand item data with additional information for DFV. |
| 1464 | * |
| 1465 | * @param array $data Item data to expand. |
| 1466 | * @param object $args { |
| 1467 | * Field information arguments. |
| 1468 | * |
| 1469 | * @type string $name Field name. |
| 1470 | * @type string $type Field type. |
| 1471 | * @type array $options Field options. |
| 1472 | * @type mixed $value Current value. |
| 1473 | * @type array $pod Pod information. |
| 1474 | * @type int|string $id Current item ID. |
| 1475 | * } |
| 1476 | * |
| 1477 | * @return array |
| 1478 | */ |
| 1479 | public function build_dfv_field_item_data_recurse( $data, $args ) { |
| 1480 | |
| 1481 | $item_data = []; |
| 1482 | |
| 1483 | foreach ( $data as $item_id => $item_title ) { |
| 1484 | if ( is_array( $item_title ) ) { |
| 1485 | $args->options['optgroup'] = true; |
| 1486 | |
| 1487 | $item_data[] = [ |
| 1488 | 'label' => $item_id, |
| 1489 | 'collection' => $this->build_dfv_field_item_data_recurse( $item_title, $args ), |
| 1490 | ]; |
| 1491 | } else { |
| 1492 | // Key by item_id temporarily to be able to sort based on $args->value |
| 1493 | $item_data[ $item_id ] = $this->build_dfv_field_item_data_recurse_item( $item_id, $item_title, $args ); |
| 1494 | } |
| 1495 | } |
| 1496 | |
| 1497 | // Maintain any saved sort order from $args->value |
| 1498 | if ( is_array( $args->value ) && 1 < count( $args->value ) && $this->is_autocomplete( $args->options ) ) { |
| 1499 | $new_item_data = []; |
| 1500 | |
| 1501 | foreach ( $args->value as $value_key => $value_item ) { |
| 1502 | if ( ! is_int( $value_key ) ) { |
| 1503 | if ( isset( $item_data[ $value_key ] ) ) { |
| 1504 | $value_item = $item_data[ $value_key ]; |
| 1505 | } |
| 1506 | |
| 1507 | $new_item_data[ $value_key ] = $value_item; |
| 1508 | } |
| 1509 | } |
| 1510 | |
| 1511 | $item_data = array_merge( $new_item_data, $item_data ); |
| 1512 | } |
| 1513 | |
| 1514 | // Convert from associative to numeric array |
| 1515 | return array_values( $item_data ); |
| 1516 | |
| 1517 | } |
| 1518 | |
| 1519 | /** |
| 1520 | * Loop through relationship data and expand item data with additional information for DFV. |
| 1521 | * |
| 1522 | * @param int|string $item_id Item ID. |
| 1523 | * @param string $item_title Item title. |
| 1524 | * @param object $args { |
| 1525 | * Field information arguments. |
| 1526 | * |
| 1527 | * @type string $name Field name. |
| 1528 | * @type string $type Field type. |
| 1529 | * @type array $options Field options. |
| 1530 | * @type mixed $value Current value. |
| 1531 | * @type array $pod Pod information. |
| 1532 | * @type int|string $id Current item ID. |
| 1533 | * } |
| 1534 | * |
| 1535 | * @return array |
| 1536 | */ |
| 1537 | public function build_dfv_field_item_data_recurse_item( $item_id, $item_title, $args ) { |
| 1538 | |
| 1539 | $icon = ''; |
| 1540 | $img_icon = ''; |
| 1541 | $edit_link = ''; |
| 1542 | $link = ''; |
| 1543 | |
| 1544 | if ( ! isset( $args->options['supports_thumbnails'] ) ) { |
| 1545 | $args->options['supports_thumbnails'] = null; |
| 1546 | } |
| 1547 | |
| 1548 | if ( ! isset( $args->options['pick_object'] ) ) { |
| 1549 | $args->options['pick_object'] = null; |
| 1550 | } |
| 1551 | |
| 1552 | switch ( $args->options['pick_object'] ) { |
| 1553 | case 'post_type': |
| 1554 | if ( null === $args->options['supports_thumbnails'] && ! empty( $args->options['pick_val'] ) ) { |
| 1555 | $args->options['supports_thumbnails'] = post_type_supports( $args->options['pick_val'], 'thumbnail' ); |
| 1556 | } |
| 1557 | |
| 1558 | if ( true === $args->options['supports_thumbnails'] ) { |
| 1559 | $post_thumbnail_id = get_post_thumbnail_id( $item_id ); |
| 1560 | |
| 1561 | if ( $post_thumbnail_id ) { |
| 1562 | $thumb = wp_get_attachment_image_src( $post_thumbnail_id, 'thumbnail', false ); |
| 1563 | } |
| 1564 | |
| 1565 | if ( ! empty( $thumb[0] ) ) { |
| 1566 | $img_icon = $thumb[0]; |
| 1567 | } |
| 1568 | } |
| 1569 | |
| 1570 | if ( empty( $img_icon ) ) { |
| 1571 | |
| 1572 | // Default icon for posts. |
| 1573 | $icon = 'dashicons-admin-post'; |
| 1574 | |
| 1575 | // Post type icons. |
| 1576 | $post_type = (array) get_post_type_object( get_post_type( $item_id ) ); |
| 1577 | |
| 1578 | if ( ! empty( $post_type['menu_icon'] ) ) { |
| 1579 | // Post specific icon. |
| 1580 | $icon = $post_type['menu_icon']; |
| 1581 | } elseif ( isset( $post_type['name'] ) && 'page' ) { |
| 1582 | switch ( $post_type['name'] ) { |
| 1583 | case 'page': |
| 1584 | // Default for pages. |
| 1585 | $icon = 'dashicons-admin-page'; |
| 1586 | break; |
| 1587 | case 'attachment': |
| 1588 | // Default for attachments. |
| 1589 | $icon = 'dashicons-admin-media'; |
| 1590 | break; |
| 1591 | } |
| 1592 | } |
| 1593 | }//end if |
| 1594 | |
| 1595 | $edit_link = get_edit_post_link( $item_id, 'raw' ); |
| 1596 | |
| 1597 | $link = get_permalink( $item_id ); |
| 1598 | |
| 1599 | break; |
| 1600 | |
| 1601 | case 'taxonomy': |
| 1602 | if ( ! empty( $args->options['pick_val'] ) ) { |
| 1603 | |
| 1604 | // Default icon for taxonomy. |
| 1605 | $icon = 'dashicons-category'; |
| 1606 | |
| 1607 | // Change icon for non-hierarchical taxonomies. |
| 1608 | $taxonomy = get_term( $item_id ); |
| 1609 | if ( isset( $taxonomy->taxonomy ) ) { |
| 1610 | $taxonomy = (array) get_taxonomy( $taxonomy->taxonomy ); |
| 1611 | if ( isset( $taxonomy['hierarchical'] ) && ! $taxonomy['hierarchical'] ) { |
| 1612 | $icon = 'dashicons-tag'; |
| 1613 | } |
| 1614 | } |
| 1615 | |
| 1616 | $edit_link = get_edit_term_link( $item_id, $args->options['pick_val'] ); |
| 1617 | |
| 1618 | $link = get_term_link( $item_id, $args->options['pick_val'] ); |
| 1619 | } |
| 1620 | |
| 1621 | break; |
| 1622 | |
| 1623 | case 'user': |
| 1624 | $args->options['supports_thumbnails'] = true; |
| 1625 | |
| 1626 | $icon = 'dashicons-admin-users'; |
| 1627 | $img_icon = get_avatar_url( $item_id, [ 'size' => 150 ] ); |
| 1628 | |
| 1629 | $edit_link = get_edit_user_link( $item_id ); |
| 1630 | |
| 1631 | $link = get_author_posts_url( $item_id ); |
| 1632 | |
| 1633 | break; |
| 1634 | |
| 1635 | case 'comment': |
| 1636 | $args->options['supports_thumbnails'] = true; |
| 1637 | |
| 1638 | $icon = 'dashicons-admin-comments'; |
| 1639 | $img_icon = get_avatar_url( get_comment( $item_id ), [ 'size' => 150 ] ); |
| 1640 | |
| 1641 | $edit_link = get_edit_comment_link( $item_id ); |
| 1642 | |
| 1643 | $link = get_comment_link( $item_id ); |
| 1644 | |
| 1645 | break; |
| 1646 | |
| 1647 | case 'pod': |
| 1648 | if ( ! empty( $args->options['pick_val'] ) ) { |
| 1649 | |
| 1650 | $icon = pods_svg_icon( 'pods' ); |
| 1651 | |
| 1652 | if ( pods_is_admin( [ 'pods', 'pods_content', 'pods_edit_' . $args->options['pick_val'] ] ) ) { |
| 1653 | $file_name = 'admin.php'; |
| 1654 | $query_args = [ |
| 1655 | 'page' => 'pods-manage-' . $args->options['pick_val'], |
| 1656 | 'action' => 'edit', |
| 1657 | 'id' => $item_id, |
| 1658 | ]; |
| 1659 | |
| 1660 | $edit_link = add_query_arg( $query_args, admin_url( $file_name ) ); |
| 1661 | } |
| 1662 | |
| 1663 | // @todo Add $link support |
| 1664 | $link = ''; |
| 1665 | } |
| 1666 | |
| 1667 | break; |
| 1668 | }//end switch |
| 1669 | |
| 1670 | // Image icons always overwrite default icons |
| 1671 | if ( ! empty( $img_icon ) ) { |
| 1672 | $icon = (string) $img_icon; |
| 1673 | } |
| 1674 | |
| 1675 | // Parse icon type |
| 1676 | if ( 'none' === $icon || 'div' === $icon ) { |
| 1677 | $icon = ''; |
| 1678 | } elseif ( 0 === strpos( (string) $icon, 'dashicons-' ) ) { |
| 1679 | $icon = sanitize_html_class( (string) $icon ); |
| 1680 | } |
| 1681 | |
| 1682 | // #5740 Check for WP_Error object. |
| 1683 | if ( ! is_string( $link ) ) { |
| 1684 | $link = ''; |
| 1685 | } |
| 1686 | |
| 1687 | // Support modal editing |
| 1688 | if ( ! empty( $edit_link ) ) { |
| 1689 | // @todo: Replace string literal with defined constant |
| 1690 | $edit_link = add_query_arg( [ 'pods_modal' => '1' ], $edit_link ); |
| 1691 | } |
| 1692 | |
| 1693 | // Determine if this is a selected item. |
| 1694 | // Issue history for setting selected: #4753, #4892, #5014. |
| 1695 | $selected = false; |
| 1696 | |
| 1697 | $values = []; |
| 1698 | |
| 1699 | // If we have values, let's cast them. |
| 1700 | if ( isset( $args->value ) ) { |
| 1701 | // The value may be a single non-array value. |
| 1702 | $values = (array) $args->value; |
| 1703 | } |
| 1704 | |
| 1705 | // Cast values in array as string. |
| 1706 | $values = array_map( static function ( $value ) { |
| 1707 | if ( ! is_scalar( $value ) ) { |
| 1708 | return $value; |
| 1709 | } |
| 1710 | |
| 1711 | return (string) $value; |
| 1712 | }, $values ); |
| 1713 | |
| 1714 | // If the value array has keys as IDs, let's check for matches from the keys first. |
| 1715 | if ( ! isset( $values[0] ) ) { |
| 1716 | // Get values from keys. |
| 1717 | $key_values = array_keys( $values ); |
| 1718 | |
| 1719 | // Cast key values in array as string. |
| 1720 | $key_values = array_map( static function ( $value ) { |
| 1721 | if ( ! is_scalar( $value ) ) { |
| 1722 | return $value; |
| 1723 | } |
| 1724 | |
| 1725 | return (string) $value; |
| 1726 | }, $key_values ); |
| 1727 | |
| 1728 | // Let's check to see if the current $item_id matches any key values. |
| 1729 | if ( in_array( (string) $item_id, $key_values, true ) ) { |
| 1730 | $selected = true; |
| 1731 | } |
| 1732 | } |
| 1733 | |
| 1734 | // If we do not have a key match, the normal values may still match. |
| 1735 | if ( ! $selected ) { |
| 1736 | // Let's check to see if the current $item_id matches any values. |
| 1737 | if ( in_array( (string) $item_id, $values, true ) ) { |
| 1738 | $selected = true; |
| 1739 | } |
| 1740 | } |
| 1741 | |
| 1742 | $item = [ |
| 1743 | 'id' => null !== $item_id ? html_entity_decode( esc_html( $item_id ), ENT_COMPAT ) : '', |
| 1744 | 'icon' => null !== $icon ? esc_attr( (string) $icon ) : '', |
| 1745 | 'name' => null !== $item_title ? wp_strip_all_tags( html_entity_decode( $item_title, ENT_COMPAT ) ) : '', |
| 1746 | 'edit_link' => null !== $edit_link ? html_entity_decode( esc_url( $edit_link ), ENT_COMPAT ) : '', |
| 1747 | 'link' => null !== $link ? html_entity_decode( esc_url( $link ), ENT_COMPAT ) : '', |
| 1748 | 'selected' => $selected, |
| 1749 | ]; |
| 1750 | |
| 1751 | return $item; |
| 1752 | |
| 1753 | } |
| 1754 | |
| 1755 | /** |
| 1756 | * {@inheritdoc} |
| 1757 | */ |
| 1758 | public function validate( $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) { |
| 1759 | $validate = parent::validate( $value, $name, $options, $fields, $pod, $id, $params ); |
| 1760 | |
| 1761 | $errors = []; |
| 1762 | |
| 1763 | if ( is_array( $validate ) ) { |
| 1764 | $errors = $validate; |
| 1765 | } |
| 1766 | |
| 1767 | if ( empty( self::$api ) ) { |
| 1768 | self::$api = pods_api(); |
| 1769 | } |
| 1770 | |
| 1771 | $field = pods_config_for_field( $options, $pod ); |
| 1772 | |
| 1773 | $related_pick_limit = 0; |
| 1774 | $related_field = false; |
| 1775 | $related_pod = false; |
| 1776 | $current_related_ids = false; |
| 1777 | |
| 1778 | // Bidirectional relationship requirement checks |
| 1779 | $related_object = pods_v( static::$type . '_object', $options, '' ); |
| 1780 | // pod, post_type, taxonomy, etc.. |
| 1781 | $related_val = pods_v( static::$type . '_val', $options, $related_object, null, true ); |
| 1782 | // pod name, post type name, taxonomy name, etc.. |
| 1783 | if ( empty( $related_val ) ) { |
| 1784 | $related_val = $related_object; |
| 1785 | } |
| 1786 | |
| 1787 | $related_sister_id = pods_v( 'sister_id', $options, 0 ); |
| 1788 | |
| 1789 | if ( is_numeric( $related_sister_id ) ) { |
| 1790 | $related_sister_id = (int) $related_sister_id; |
| 1791 | } else { |
| 1792 | $related_sister_id = 0; |
| 1793 | } |
| 1794 | |
| 1795 | $options['id'] = (int) $options['id']; |
| 1796 | |
| 1797 | $related_data = pods_static_cache_get( $options['name'] . '/' . $options['id'], __CLASS__ . '/related_data' ) ?: []; |
| 1798 | |
| 1799 | if ( |
| 1800 | ! empty( $related_sister_id ) |
| 1801 | && ! empty( $related_object ) |
| 1802 | && $field |
| 1803 | && ! $field->is_simple_relationship() |
| 1804 | ) { |
| 1805 | $related_pod = self::$api->load_pod( [ |
| 1806 | 'name' => $related_val, |
| 1807 | 'auto_setup' => true, |
| 1808 | ] ); |
| 1809 | |
| 1810 | if ( false !== $related_pod && ( 'pod' === $related_object || $related_object === $related_pod['type'] ) ) { |
| 1811 | $related_field = false; |
| 1812 | |
| 1813 | // Ensure sister_id exists on related Pod. |
| 1814 | foreach ( $related_pod['fields'] as $related_pod_field ) { |
| 1815 | if ( 'pick' === $related_pod_field['type'] && $related_sister_id === $related_pod_field['id'] ) { |
| 1816 | $related_field = $related_pod_field; |
| 1817 | |
| 1818 | break; |
| 1819 | } |
| 1820 | } |
| 1821 | |
| 1822 | if ( ! empty( $related_field ) ) { |
| 1823 | $current_ids = self::$api->lookup_related_items( $options['id'], $pod['id'], $id, $options, $pod ); |
| 1824 | |
| 1825 | $related_data[ 'current_ids_' . $id ] = $current_ids; |
| 1826 | |
| 1827 | $value_ids = $value; |
| 1828 | |
| 1829 | // Convert values from a comma-separated string into an array. |
| 1830 | if ( ! is_array( $value_ids ) ) { |
| 1831 | $value_ids = explode( ',', $value_ids ); |
| 1832 | } |
| 1833 | |
| 1834 | $value_ids = array_unique( array_filter( $value_ids ) ); |
| 1835 | |
| 1836 | // Get ids to remove. |
| 1837 | $remove_ids = array_diff( $current_ids, $value_ids ); |
| 1838 | |
| 1839 | $related_data[ 'remove_ids_' . $id ] = $remove_ids; |
| 1840 | |
| 1841 | $related_required = (boolean) pods_v( 'required', $related_field, 0 ); |
| 1842 | $related_pick_limit = (int) pods_v( static::$type . '_limit', $related_field, 0 ); |
| 1843 | |
| 1844 | if ( 'single' === pods_v( static::$type . '_format_type', $related_field ) ) { |
| 1845 | $related_pick_limit = 1; |
| 1846 | } |
| 1847 | |
| 1848 | // Validate Required fields. |
| 1849 | if ( $related_required && ! empty( $remove_ids ) ) { |
| 1850 | foreach ( $remove_ids as $related_id ) { |
| 1851 | $bidirectional_ids = self::$api->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod ); |
| 1852 | |
| 1853 | $related_data[ 'related_ids_' . $related_id ] = $bidirectional_ids; |
| 1854 | |
| 1855 | if ( empty( $bidirectional_ids ) || ( in_array( (int) $id, $bidirectional_ids, true ) && 1 === count( $bidirectional_ids ) ) ) { |
| 1856 | // Translators: %1$s and %2$s stand for field labels. |
| 1857 | $errors[] = sprintf( esc_html__( 'The %1$s field is required and cannot be removed by the %2$s field', 'pods' ), $related_field['label'], $options['label'] ); |
| 1858 | |
| 1859 | return $errors; |
| 1860 | } |
| 1861 | } |
| 1862 | } |
| 1863 | } else { |
| 1864 | $related_pod = false; |
| 1865 | }//end if |
| 1866 | } else { |
| 1867 | $related_pod = false; |
| 1868 | }//end if |
| 1869 | }//end if |
| 1870 | |
| 1871 | if ( ! empty( $related_data ) ) { |
| 1872 | $related_data['related_pod'] = $related_pod; |
| 1873 | $related_data['related_field'] = $related_field; |
| 1874 | $related_data['related_pick_limit'] = $related_pick_limit; |
| 1875 | |
| 1876 | pods_static_cache_set( $options['name'] . '/' . $options['id'], $related_data, __CLASS__ . '/related_data' ); |
| 1877 | |
| 1878 | $pick_limit = (int) pods_v( static::$type . '_limit', $options, 0 ); |
| 1879 | |
| 1880 | if ( 'single' === pods_v( static::$type . '_format_type', $options ) ) { |
| 1881 | $pick_limit = 1; |
| 1882 | } |
| 1883 | |
| 1884 | $related_field['id'] = (int) $related_field['id']; |
| 1885 | |
| 1886 | $bidirectional_related_data = pods_static_cache_get( $related_field['name'] . '/' . $related_field['id'], __CLASS__ . '/related_data' ) ?: []; |
| 1887 | |
| 1888 | if ( empty( $bidirectional_related_data ) ) { |
| 1889 | $bidirectional_related_data = [ |
| 1890 | 'related_pod' => $pod, |
| 1891 | 'related_field' => $options, |
| 1892 | 'related_pick_limit' => $pick_limit, |
| 1893 | ]; |
| 1894 | |
| 1895 | pods_static_cache_set( $related_field['name'] . '/' . $related_field['id'], $bidirectional_related_data, __CLASS__ . '/related_data' ); |
| 1896 | } |
| 1897 | }//end if |
| 1898 | |
| 1899 | if ( ! empty( $errors ) ) { |
| 1900 | return $errors; |
| 1901 | } |
| 1902 | |
| 1903 | return $validate; |
| 1904 | |
| 1905 | } |
| 1906 | |
| 1907 | /** |
| 1908 | * {@inheritdoc} |
| 1909 | */ |
| 1910 | public function save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) { |
| 1911 | |
| 1912 | if ( empty( self::$api ) ) { |
| 1913 | self::$api = pods_api(); |
| 1914 | } |
| 1915 | |
| 1916 | $options['id'] = (int) $options['id']; |
| 1917 | |
| 1918 | $related_pod = null; |
| 1919 | $related_field = null; |
| 1920 | $related_pick_limit = 0; |
| 1921 | $current_ids = []; |
| 1922 | $remove_ids = []; |
| 1923 | |
| 1924 | if ( null === $value ) { |
| 1925 | $value = []; |
| 1926 | } elseif ( ! is_array( $value ) ) { |
| 1927 | $value = [ |
| 1928 | $value, |
| 1929 | ]; |
| 1930 | } |
| 1931 | |
| 1932 | $current_ids = isset( $params->current_ids ) ? $params->current_ids : null; |
| 1933 | $value_ids = isset( $params->value_ids ) ? $params->value_ids : null; |
| 1934 | $remove_ids = isset( $params->remove_ids ) ? $params->remove_ids : null; |
| 1935 | |
| 1936 | if ( null === $value_ids ) { |
| 1937 | $value_ids = array_unique( array_filter( $value ) ); |
| 1938 | } |
| 1939 | |
| 1940 | $related_data = pods_static_cache_get( $options['name'] . '/' . $options['id'], __CLASS__ . '/related_data' ) ?: []; |
| 1941 | |
| 1942 | if ( ! empty( $related_data ) && isset( $related_data[ 'current_ids_' . $id ], $related_data[ 'remove_ids_' . $id ] ) ) { |
| 1943 | $related_pod = $related_data['related_pod']; |
| 1944 | $related_field = $related_data['related_field']; |
| 1945 | $related_pick_limit = $related_data['related_pick_limit']; |
| 1946 | |
| 1947 | if ( null === $current_ids ) { |
| 1948 | $current_ids = $related_data[ 'current_ids_' . $id ]; |
| 1949 | } |
| 1950 | |
| 1951 | if ( null === $remove_ids ) { |
| 1952 | $remove_ids = $related_data[ 'remove_ids_' . $id ]; |
| 1953 | } |
| 1954 | } elseif ( $options instanceof Field || $options instanceof Value_Field ) { |
| 1955 | $related_field = $options->get_bidirectional_field(); |
| 1956 | |
| 1957 | if ( $related_field ) { |
| 1958 | $related_pod = $related_field->get_parent_object(); |
| 1959 | $related_pick_limit = $related_field->get_limit(); |
| 1960 | |
| 1961 | if ( null === $current_ids ) { |
| 1962 | $current_ids = self::$api->lookup_related_items( $options['id'], $pod['id'], $id, $options, $pod ); |
| 1963 | } |
| 1964 | |
| 1965 | // Get ids to remove. |
| 1966 | if ( null === $remove_ids ) { |
| 1967 | $remove_ids = array_diff( $current_ids, $value_ids ); |
| 1968 | } |
| 1969 | } |
| 1970 | } |
| 1971 | |
| 1972 | // Handle syncing of taxonomy terms first (doesn't require bidirectional relationship). |
| 1973 | if ( ! empty( $pod['type'] ) && 'post_type' === $pod['type'] && pods_v_bool( static::$type . '_sync_taxonomy', $options ) ) { |
| 1974 | // Check if post type has the same attached taxonomy. |
| 1975 | $taxonomies_available = get_object_taxonomies( $pod['name'] ); |
| 1976 | $taxonomies_available = array_flip( $taxonomies_available ); |
| 1977 | |
| 1978 | if ( $options instanceof Field || $options instanceof Value_Field ) { |
| 1979 | $taxonomy_name = $options->get_related_object_name(); |
| 1980 | |
| 1981 | if ( isset( $taxonomies_available[ $taxonomy_name ] ) ) { |
| 1982 | /** |
| 1983 | * Allow filtering the list of term IDs that will be synced for a field. |
| 1984 | * |
| 1985 | * @since 3.2.4 |
| 1986 | * |
| 1987 | * @param array $term_ids_to_sync The list of term IDs to sync. |
| 1988 | * @param Field $field The field object. |
| 1989 | * @param int $id The post ID. |
| 1990 | * @param string $taxonomy_name The taxonomy name being synced. |
| 1991 | */ |
| 1992 | $term_ids_to_sync = apply_filters( 'pods_field_pick_save_sync_taxonomy_term_ids', $value_ids, $options, $id, $taxonomy_name ); |
| 1993 | |
| 1994 | // Update the taxonomy terms for the current post. |
| 1995 | wp_set_post_terms( $id, $term_ids_to_sync, $taxonomy_name ); |
| 1996 | } |
| 1997 | } |
| 1998 | } |
| 1999 | |
| 2000 | // Exit early if no bidirectional relationship to handle. |
| 2001 | if ( empty( $related_field ) || empty( $related_pod ) ) { |
| 2002 | return; |
| 2003 | } |
| 2004 | |
| 2005 | // Handle the bi-directional relationship updates. |
| 2006 | |
| 2007 | $no_conflict = true; |
| 2008 | |
| 2009 | // Only check no conflict mode if this isn't the current pod type. |
| 2010 | if ( $related_pod['type'] !== $pod['type'] ) { |
| 2011 | $no_conflict = pods_no_conflict_check( $related_pod['type'] ); |
| 2012 | } |
| 2013 | |
| 2014 | if ( ! $no_conflict ) { |
| 2015 | pods_no_conflict_on( $related_pod['type'] ); |
| 2016 | } |
| 2017 | |
| 2018 | if ( empty( $value_ids ) ) { |
| 2019 | // Remove all bidirectional relationships. |
| 2020 | if ( ! empty( $remove_ids ) ) { |
| 2021 | // Remove this ID from the related IDS. |
| 2022 | self::$api->delete_relationships( $remove_ids, $id, $related_pod, $related_field ); |
| 2023 | |
| 2024 | // Remove the related IDs from this ID. |
| 2025 | self::$api->delete_relationships( $id, $remove_ids, $pod, $options ); |
| 2026 | } |
| 2027 | |
| 2028 | if ( ! $no_conflict ) { |
| 2029 | pods_no_conflict_off( $related_pod['type'] ); |
| 2030 | } |
| 2031 | |
| 2032 | return; |
| 2033 | } |
| 2034 | |
| 2035 | foreach ( $value_ids as $related_id ) { |
| 2036 | if ( ! empty( $related_data[ 'related_ids_' . $related_id ] ) ) { |
| 2037 | $bidirectional_ids = $related_data[ 'related_ids_' . $related_id ]; |
| 2038 | } else { |
| 2039 | $bidirectional_ids = self::$api->lookup_related_items( $related_field['id'], $related_pod['id'], $related_id, $related_field, $related_pod ); |
| 2040 | } |
| 2041 | |
| 2042 | $bidirectional_ids = array_filter( $bidirectional_ids ); |
| 2043 | |
| 2044 | if ( empty( $bidirectional_ids ) ) { |
| 2045 | $bidirectional_ids = []; |
| 2046 | } |
| 2047 | |
| 2048 | $bidirectional_remove_ids = []; |
| 2049 | |
| 2050 | if ( 0 < $related_pick_limit && ! empty( $bidirectional_ids ) && ! in_array( $id, $bidirectional_ids, true ) ) { |
| 2051 | $total_bidirectional_ids = count( $bidirectional_ids ); |
| 2052 | |
| 2053 | while ( $related_pick_limit <= $total_bidirectional_ids ) { |
| 2054 | $bidirectional_remove_ids[] = (int) array_pop( $bidirectional_ids ); |
| 2055 | |
| 2056 | $total_bidirectional_ids = count( $bidirectional_ids ); |
| 2057 | } |
| 2058 | } |
| 2059 | |
| 2060 | // Remove this item from related items no longer related to. |
| 2061 | $bidirectional_remove_ids = array_unique( array_filter( $bidirectional_remove_ids ) ); |
| 2062 | |
| 2063 | if ( ! in_array( $id, $bidirectional_ids, true ) ) { |
| 2064 | // Add to related items. |
| 2065 | $bidirectional_ids[] = $id; |
| 2066 | } elseif ( empty( $bidirectional_remove_ids ) ) { |
| 2067 | // Nothing to change. |
| 2068 | continue; |
| 2069 | } |
| 2070 | |
| 2071 | self::$api->save_relationships( $related_id, $bidirectional_ids, $related_pod, $related_field ); |
| 2072 | |
| 2073 | if ( ! empty( $bidirectional_remove_ids ) ) { |
| 2074 | self::$api->delete_relationships( $bidirectional_remove_ids, $related_id, $pod, $options ); |
| 2075 | } |
| 2076 | }//end foreach |
| 2077 | |
| 2078 | // Remove this ID from the related IDs. |
| 2079 | if ( ! empty( $remove_ids ) ) { |
| 2080 | self::$api->delete_relationships( $remove_ids, $id, $related_pod, $related_field ); |
| 2081 | } |
| 2082 | |
| 2083 | if ( ! $no_conflict ) { |
| 2084 | pods_no_conflict_off( $related_pod['type'] ); |
| 2085 | } |
| 2086 | } |
| 2087 | |
| 2088 | /** |
| 2089 | * Delete the value from the DB |
| 2090 | * |
| 2091 | * @param int|null $id Item ID. |
| 2092 | * @param string|null $name Field name. |
| 2093 | * @param array|null $options Field options. |
| 2094 | * @param array|null $pod Pod options. |
| 2095 | * |
| 2096 | * @since 2.3.0 |
| 2097 | */ |
| 2098 | public function delete( $id = null, $name = null, $options = null, $pod = null ) { |
| 2099 | |
| 2100 | if ( empty( self::$api ) ) { |
| 2101 | self::$api = pods_api(); |
| 2102 | } |
| 2103 | |
| 2104 | $field = pods_config_for_field( $options, $pod ); |
| 2105 | |
| 2106 | // Bidirectional relationship requirement checks. |
| 2107 | $related_object = pods_v( static::$type . '_object', $options, '' ); |
| 2108 | |
| 2109 | // pod, post_type, taxonomy, etc.. |
| 2110 | $related_val = pods_v( static::$type . '_val', $options, $related_object, true ); |
| 2111 | |
| 2112 | // pod name, post type name, taxonomy name, etc.. |
| 2113 | $related_sister_id = pods_v( 'sister_id', $options, 0 ); |
| 2114 | |
| 2115 | if ( is_numeric( $related_sister_id ) ) { |
| 2116 | $related_sister_id = (int) $related_sister_id; |
| 2117 | } else { |
| 2118 | $related_sister_id = 0; |
| 2119 | } |
| 2120 | |
| 2121 | if ( |
| 2122 | ! empty( $related_sister_id ) |
| 2123 | && ! empty( $related_object ) |
| 2124 | && $field |
| 2125 | && ! $field->is_simple_relationship() |
| 2126 | ) { |
| 2127 | $related_pod = self::$api->load_pod( [ |
| 2128 | 'name' => $related_val, |
| 2129 | 'auto_setup' => true, |
| 2130 | ] ); |
| 2131 | |
| 2132 | if ( false !== $related_pod && ( 'pod' === $related_object || $related_object === $related_pod['type'] ) ) { |
| 2133 | $related_field = false; |
| 2134 | |
| 2135 | // Ensure sister_id exists on related Pod. |
| 2136 | foreach ( $related_pod['fields'] as $related_pod_field ) { |
| 2137 | if ( 'pick' === $related_pod_field['type'] && (int) $related_sister_id === (int) $related_pod_field['id'] ) { |
| 2138 | $related_field = $related_pod_field; |
| 2139 | |
| 2140 | break; |
| 2141 | } |
| 2142 | } |
| 2143 | |
| 2144 | if ( ! empty( $related_field ) ) { |
| 2145 | $values = self::$api->lookup_related_items( $options['id'], $pod['id'], $id, $options, $pod ); |
| 2146 | |
| 2147 | if ( ! empty( $values ) ) { |
| 2148 | $no_conflict = pods_no_conflict_check( $related_pod['type'] ); |
| 2149 | |
| 2150 | if ( ! $no_conflict ) { |
| 2151 | pods_no_conflict_on( $related_pod['type'] ); |
| 2152 | } |
| 2153 | |
| 2154 | self::$api->delete_relationships( $values, $id, $related_pod, $related_field ); |
| 2155 | |
| 2156 | if ( ! $no_conflict ) { |
| 2157 | pods_no_conflict_off( $related_pod['type'] ); |
| 2158 | } |
| 2159 | } |
| 2160 | } |
| 2161 | }//end if |
| 2162 | }//end if |
| 2163 | |
| 2164 | } |
| 2165 | |
| 2166 | /** |
| 2167 | * {@inheritdoc} |
| 2168 | */ |
| 2169 | public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) { |
| 2170 | |
| 2171 | $value = $this->simple_value( $name, $value, $options, $pod, $id ); |
| 2172 | |
| 2173 | return $this->display( $value, $name, $options, $pod, $id ); |
| 2174 | |
| 2175 | } |
| 2176 | |
| 2177 | /** |
| 2178 | * Get the raw data from the field data provided. |
| 2179 | * |
| 2180 | * @since 2.9.9 |
| 2181 | * |
| 2182 | * @param array|Field $field The field data. |
| 2183 | * |
| 2184 | * @return array|mixed |
| 2185 | */ |
| 2186 | public function get_raw_data( $field ) { |
| 2187 | $data = pods_v( 'data', $field, null, true ); |
| 2188 | |
| 2189 | if ( null !== $data ) { |
| 2190 | // Support late-initializing the data from a callback function passed in. |
| 2191 | if ( ! is_array( $data ) && ! is_string( $data ) && is_callable( $data ) ) { |
| 2192 | $data = $data(); |
| 2193 | } |
| 2194 | |
| 2195 | $data = (array) $data; |
| 2196 | } |
| 2197 | |
| 2198 | return $data; |
| 2199 | } |
| 2200 | |
| 2201 | /** |
| 2202 | * {@inheritdoc} |
| 2203 | */ |
| 2204 | public function data( $name, $value = null, $options = null, $pod = null, $id = null, $in_form = true ) { |
| 2205 | $data = $this->get_raw_data( $options ); |
| 2206 | |
| 2207 | $object_params = [ |
| 2208 | // The name of the field. |
| 2209 | 'name' => $name, |
| 2210 | // The value of the field. |
| 2211 | 'value' => $value, |
| 2212 | // Field options. |
| 2213 | 'options' => $options, |
| 2214 | // Pod data. |
| 2215 | 'pod' => $pod, |
| 2216 | // Item ID. |
| 2217 | 'id' => $id, |
| 2218 | // Data context. |
| 2219 | 'context' => 'data', |
| 2220 | ]; |
| 2221 | |
| 2222 | if ( null !== $data ) { |
| 2223 | $data = (array) $data; |
| 2224 | } else { |
| 2225 | $data = (array) $this->get_object_data( $object_params ); |
| 2226 | } |
| 2227 | |
| 2228 | /** |
| 2229 | * Allow filtering whether to always show default select text for the Single select Dropdown field even if |
| 2230 | * the field is required. |
| 2231 | * |
| 2232 | * @since 2.8.9 |
| 2233 | * |
| 2234 | * @param bool $always_show_default_select_text Whether to always show default select text. |
| 2235 | * @param array $data The object data. |
| 2236 | * @param string|null $name Field name. |
| 2237 | * @param mixed|null $value Current value. |
| 2238 | * @param array|null $options Field options. |
| 2239 | * @param array|null $pod Pod information. |
| 2240 | * @param int|string|null $id Current item ID. |
| 2241 | */ |
| 2242 | $always_show_default_select_text = (bool) apply_filters( 'pods_field_pick_always_show_default_select_text', (bool) pods_v( static::$type . '_select_text_always_show', $options, false ), $data, $name, $value, $options, $pod, $id ); |
| 2243 | |
| 2244 | if ( |
| 2245 | 'single' === pods_v( static::$type . '_format_type', $options, 'single' ) |
| 2246 | && 'dropdown' === pods_v( static::$type . '_format_single', $options, 'dropdown' ) |
| 2247 | //&& 0 !== (int) pods_v( static::$type . '_show_select_text', $options, 1 ) |
| 2248 | && ( |
| 2249 | $always_show_default_select_text |
| 2250 | || empty( $value ) |
| 2251 | || 0 === (int) pods_v( 'required', $options, 0 ) |
| 2252 | ) |
| 2253 | ) { |
| 2254 | $default_select = [ |
| 2255 | '' => pods_v( static::$type . '_select_text', $options, __( '-- Select One --', 'pods' ), true ), |
| 2256 | ]; |
| 2257 | |
| 2258 | // Unset to prevent conflict. |
| 2259 | if ( isset( $data[''] ) ) { |
| 2260 | unset( $data[''] ); |
| 2261 | } |
| 2262 | |
| 2263 | // Prevent resetting the numeric ID keys when adding the empty option via array_merge, use union instead. |
| 2264 | $data = $default_select + $data; |
| 2265 | } |
| 2266 | |
| 2267 | $data = apply_filters( 'pods_field_pick_data', $data, $name, $value, $options, $pod, $id ); |
| 2268 | |
| 2269 | return $data; |
| 2270 | |
| 2271 | } |
| 2272 | |
| 2273 | /** |
| 2274 | * Convert a simple value to the correct value |
| 2275 | * |
| 2276 | * @param string $name The name of the field. |
| 2277 | * @param string|array|null $value The value of the field. |
| 2278 | * @param array|null $options Field options. |
| 2279 | * @param array|null $pod Pod data. |
| 2280 | * @param int|null $id Item ID. |
| 2281 | * @param boolean $raw Whether to return the raw list of keys (true) or convert to key=>value (false). |
| 2282 | * |
| 2283 | * @return mixed Corrected value |
| 2284 | */ |
| 2285 | public function simple_value( $name, $value = null, $options = null, $pod = null, $id = null, $raw = false ) { |
| 2286 | |
| 2287 | if ( in_array( pods_v( static::$type . '_object', $options ), $this->simple_objects(), true ) ) { |
| 2288 | if ( ! is_array( $value ) && 0 < strlen( (string) $value ) ) { |
| 2289 | $simple = @json_decode( $value, true ); |
| 2290 | |
| 2291 | if ( is_array( $simple ) ) { |
| 2292 | $value = (array) $simple; |
| 2293 | } |
| 2294 | } |
| 2295 | |
| 2296 | $data = $this->get_raw_data( $options ); |
| 2297 | |
| 2298 | $object_params = [ |
| 2299 | // The name of the field. |
| 2300 | 'name' => $name, |
| 2301 | // The value of the field. |
| 2302 | 'value' => $value, |
| 2303 | // Field options. |
| 2304 | 'options' => $options, |
| 2305 | // Pod data. |
| 2306 | 'pod' => $pod, |
| 2307 | // Item ID. |
| 2308 | 'id' => $id, |
| 2309 | // Data context. |
| 2310 | 'context' => 'simple_value', |
| 2311 | ]; |
| 2312 | |
| 2313 | if ( null !== $data ) { |
| 2314 | $data = (array) $data; |
| 2315 | } else { |
| 2316 | $data = (array) $this->get_object_data( $object_params ); |
| 2317 | } |
| 2318 | |
| 2319 | $key = 0; |
| 2320 | |
| 2321 | if ( is_array( $value ) ) { |
| 2322 | if ( ! empty( $data ) ) { |
| 2323 | $val = []; |
| 2324 | |
| 2325 | foreach ( $value as $k => $v ) { |
| 2326 | if ( is_scalar( $v ) && isset( $data[ $v ] ) ) { |
| 2327 | if ( false === $raw ) { |
| 2328 | $k = $v; |
| 2329 | $v = $data[ $v ]; |
| 2330 | } |
| 2331 | |
| 2332 | $val[ $k ] = $v; |
| 2333 | } |
| 2334 | } |
| 2335 | |
| 2336 | $value = $val; |
| 2337 | } |
| 2338 | } elseif ( isset( $data[ $value ] ) && false === $raw ) { |
| 2339 | $key = $value; |
| 2340 | $value = $data[ $value ]; |
| 2341 | }//end if |
| 2342 | |
| 2343 | $single_multi = pods_v( static::$type . '_format_type', $options, 'single' ); |
| 2344 | |
| 2345 | if ( 'multi' === $single_multi ) { |
| 2346 | $limit = (int) pods_v( static::$type . '_limit', $options, 0 ); |
| 2347 | } else { |
| 2348 | $limit = 1; |
| 2349 | } |
| 2350 | |
| 2351 | if ( is_array( $value ) && 0 < $limit ) { |
| 2352 | if ( 1 === $limit ) { |
| 2353 | $value = current( $value ); |
| 2354 | } else { |
| 2355 | $value = array_slice( $value, 0, $limit, true ); |
| 2356 | } |
| 2357 | } elseif ( ! is_array( $value ) && null !== $value && 0 < strlen( (string) $value ) ) { |
| 2358 | if ( 1 !== $limit || ( true === $raw && 'multi' === $single_multi ) ) { |
| 2359 | $value = [ |
| 2360 | $key => $value, |
| 2361 | ]; |
| 2362 | } |
| 2363 | } |
| 2364 | }//end if |
| 2365 | |
| 2366 | return $value; |
| 2367 | |
| 2368 | } |
| 2369 | |
| 2370 | /** |
| 2371 | * Get the label from a pick value. |
| 2372 | * |
| 2373 | * @param string $name The name of the field. |
| 2374 | * @param string|array|null $value The value of the field. |
| 2375 | * @param array|null $options Field options. |
| 2376 | * @param array|null $pod Pod data. |
| 2377 | * @param int|null $id Item ID. |
| 2378 | * |
| 2379 | * @return string |
| 2380 | * |
| 2381 | * @since 2.2.0 |
| 2382 | */ |
| 2383 | public function value_to_label( $name, $value = null, $options = null, $pod = null, $id = null ) { |
| 2384 | $data = $this->get_raw_data( $options ); |
| 2385 | |
| 2386 | $object_params = [ |
| 2387 | // The name of the field. |
| 2388 | 'name' => $name, |
| 2389 | // The value of the field. |
| 2390 | 'value' => $value, |
| 2391 | // Field options. |
| 2392 | 'options' => $options, |
| 2393 | // Pod data. |
| 2394 | 'pod' => $pod, |
| 2395 | // Item ID. |
| 2396 | 'id' => $id, |
| 2397 | // Data context. |
| 2398 | 'context' => 'value_to_label', |
| 2399 | ]; |
| 2400 | |
| 2401 | if ( null !== $data ) { |
| 2402 | $data = (array) $data; |
| 2403 | } else { |
| 2404 | $data = (array) $this->get_object_data( $object_params ); |
| 2405 | } |
| 2406 | |
| 2407 | $labels = []; |
| 2408 | |
| 2409 | foreach ( $data as $v => $l ) { |
| 2410 | if ( ! in_array( (string) $l, $labels, true ) && ( (string) $value === (string) $v || ( is_array( $value ) && in_array( (string) $v, $value, true ) ) ) ) { |
| 2411 | $labels[] = (string) $l; |
| 2412 | } |
| 2413 | } |
| 2414 | |
| 2415 | $labels = apply_filters( 'pods_field_pick_value_to_label', $labels, $name, $value, $options, $pod, $id ); |
| 2416 | |
| 2417 | $labels = pods_serial_comma( $labels ); |
| 2418 | |
| 2419 | return $labels; |
| 2420 | |
| 2421 | } |
| 2422 | |
| 2423 | /** |
| 2424 | * Get available items from a relationship field. |
| 2425 | * |
| 2426 | * @param array|string $field Field array or field name. |
| 2427 | * @param array $deprecated Field options array overrides. |
| 2428 | * @param array $object_params Additional get_object_data options. |
| 2429 | * |
| 2430 | * @return array An array of available items from a relationship field |
| 2431 | */ |
| 2432 | public function get_field_data( $field, $deprecated = null, $object_params = [] ) { |
| 2433 | $options = []; |
| 2434 | |
| 2435 | $is_field_object = $field instanceof Field; |
| 2436 | |
| 2437 | if ( is_array( $field ) || $is_field_object ) { |
| 2438 | $options = $field; |
| 2439 | } |
| 2440 | |
| 2441 | // Get field name from array. |
| 2442 | $field = pods_v( 'name', $options, $field, true ); |
| 2443 | |
| 2444 | // Field name or options not set. |
| 2445 | if ( empty( $field ) || empty( $options ) ) { |
| 2446 | return []; |
| 2447 | } |
| 2448 | |
| 2449 | // Setup object params. |
| 2450 | $object_params = array_merge( |
| 2451 | [ |
| 2452 | // The name of the field. |
| 2453 | 'name' => $field, |
| 2454 | // Field options. |
| 2455 | 'options' => $options, |
| 2456 | ], $object_params |
| 2457 | ); |
| 2458 | |
| 2459 | // Get data override. |
| 2460 | $data = $this->get_raw_data( $options ); |
| 2461 | |
| 2462 | if ( null !== $data ) { |
| 2463 | // Return data override. |
| 2464 | $data = (array) $data; |
| 2465 | } else { |
| 2466 | // Get object data. |
| 2467 | $data = $this->get_object_data( $object_params ); |
| 2468 | } |
| 2469 | |
| 2470 | return $data; |
| 2471 | |
| 2472 | } |
| 2473 | |
| 2474 | /** |
| 2475 | * Get data from relationship objects. |
| 2476 | * |
| 2477 | * @param array $object_params Object data parameters. |
| 2478 | * |
| 2479 | * @return array|bool Object data |
| 2480 | */ |
| 2481 | public function get_object_data( $object_params = null ) { |
| 2482 | |
| 2483 | /** |
| 2484 | * @var $wpdb wpdb |
| 2485 | */ |
| 2486 | global $wpdb; |
| 2487 | |
| 2488 | $object_params = array_merge( |
| 2489 | [ |
| 2490 | // The name of the field. |
| 2491 | 'name' => '', |
| 2492 | // The value of the field. |
| 2493 | 'value' => '', |
| 2494 | // Field options. |
| 2495 | 'options' => [], |
| 2496 | // Pod data. |
| 2497 | 'pod' => '', |
| 2498 | // Item ID. |
| 2499 | 'id' => '', |
| 2500 | // Data context. |
| 2501 | 'context' => '', |
| 2502 | // Data parameters. |
| 2503 | 'data_params' => [ |
| 2504 | // Query being searched. |
| 2505 | 'query' => '', |
| 2506 | ], |
| 2507 | // Page number of results to get. |
| 2508 | 'page' => 1, |
| 2509 | // How many data items to limit to (autocomplete defaults to 30, set to -1 or 1+ to override). |
| 2510 | 'limit' => 0, |
| 2511 | ], $object_params |
| 2512 | ); |
| 2513 | |
| 2514 | /** |
| 2515 | * Overwrite parameters used by PodsField_Pick::get_object_data. |
| 2516 | * |
| 2517 | * @since 2.7.21 |
| 2518 | * |
| 2519 | * @param array $object_params { |
| 2520 | * Get object parameters |
| 2521 | * |
| 2522 | * @type string $name Field name. |
| 2523 | * @type mixed $value Current value. |
| 2524 | * @type array $options Field options. |
| 2525 | * @type array $pod Pod data. |
| 2526 | * @type int|string $id Current item ID. |
| 2527 | * @type string $context Data context. |
| 2528 | * @type array $data_params Data parameters. |
| 2529 | * @type int $page Page number of results to get. |
| 2530 | * @type int $limit How many data items to limit to (autocomplete defaults to 30, set to -1 or 1+ to override). |
| 2531 | * } |
| 2532 | */ |
| 2533 | $object_params = apply_filters( 'pods_field_pick_object_data_params', $object_params ); |
| 2534 | |
| 2535 | $object_params['data_params'] = (array) $object_params['data_params']; |
| 2536 | |
| 2537 | $name = $object_params['name']; |
| 2538 | $value = $object_params['value']; |
| 2539 | $options = $object_params['options']; |
| 2540 | $pod = $object_params['pod']; |
| 2541 | $id = $object_params['id']; |
| 2542 | $context = $object_params['context']; |
| 2543 | $data_params = $object_params['data_params']; |
| 2544 | $page = min( 1, (int) $object_params['page'] ); |
| 2545 | $limit = (int) $object_params['limit']; |
| 2546 | $autocomplete = false; |
| 2547 | |
| 2548 | // Use field object if it was provided. |
| 2549 | if ( isset( $options['_field_object'] ) ) { |
| 2550 | $options = $options['_field_object']; |
| 2551 | |
| 2552 | $name = $options->get_name(); |
| 2553 | } |
| 2554 | |
| 2555 | $data = apply_filters( 'pods_field_pick_object_data', null, $name, $value, $options, $pod, $id, $object_params ); |
| 2556 | $items = []; |
| 2557 | |
| 2558 | if ( ! isset( $options[ static::$type . '_object' ] ) ) { |
| 2559 | $data = $this->get_raw_data( $options ); |
| 2560 | } |
| 2561 | |
| 2562 | $simple = false; |
| 2563 | |
| 2564 | if ( null === $data ) { |
| 2565 | $data = []; |
| 2566 | |
| 2567 | $pick_object = pods_v( static::$type . '_object', $options, null, true ); |
| 2568 | |
| 2569 | // No pick object means this has no configuration to work from. |
| 2570 | if ( empty( $pick_object ) ) { |
| 2571 | return $data; |
| 2572 | } |
| 2573 | |
| 2574 | if ( 'custom-simple' === $pick_object ) { |
| 2575 | $custom = pods_v( static::$type . '_custom', $options, '' ); |
| 2576 | |
| 2577 | $custom = apply_filters( 'pods_form_ui_field_pick_custom_values', $custom, $name, $value, $options, $pod, $id, $object_params ); |
| 2578 | |
| 2579 | if ( ! empty( $custom ) ) { |
| 2580 | if ( ! is_array( $custom ) ) { |
| 2581 | $data = []; |
| 2582 | |
| 2583 | $custom = explode( "\n", trim( $custom ) ); |
| 2584 | |
| 2585 | foreach ( $custom as $custom_value ) { |
| 2586 | $custom_value = trim( trim( $custom_value, '|' ) ); |
| 2587 | $custom_label = explode( '|', $custom_value ); |
| 2588 | |
| 2589 | if ( empty( $custom_label ) ) { |
| 2590 | continue; |
| 2591 | } |
| 2592 | |
| 2593 | if ( 1 === count( $custom_label ) ) { |
| 2594 | $custom_label = $custom_value; |
| 2595 | } else { |
| 2596 | $custom_value = $custom_label[0]; |
| 2597 | $custom_label = $custom_label[1]; |
| 2598 | } |
| 2599 | |
| 2600 | $custom_value = trim( (string) $custom_value ); |
| 2601 | $custom_label = trim( (string) $custom_label ); |
| 2602 | |
| 2603 | $data[ $custom_value ] = $custom_label; |
| 2604 | } |
| 2605 | } else { |
| 2606 | $data = $custom; |
| 2607 | }//end if |
| 2608 | |
| 2609 | $simple = true; |
| 2610 | }//end if |
| 2611 | } elseif ( |
| 2612 | $pick_object |
| 2613 | && $this->setup_related_objects() |
| 2614 | && isset( self::$related_objects[ $pick_object ] ) |
| 2615 | && ! empty( self::$related_objects[ $pick_object ]['data'] ) |
| 2616 | ) { |
| 2617 | $data = self::$related_objects[ $options[ static::$type . '_object' ] ]['data']; |
| 2618 | |
| 2619 | $simple = true; |
| 2620 | } elseif ( |
| 2621 | $pick_object |
| 2622 | && $this->setup_related_objects() |
| 2623 | && isset( self::$related_objects[ $pick_object ] ) |
| 2624 | && isset( self::$related_objects[ $pick_object ]['data_callback'] ) |
| 2625 | && is_callable( self::$related_objects[ $pick_object ]['data_callback'] ) |
| 2626 | ) { |
| 2627 | $data = call_user_func_array( |
| 2628 | self::$related_objects[ $options[ static::$type . '_object' ] ]['data_callback'], [ |
| 2629 | $name, |
| 2630 | $value, |
| 2631 | $options, |
| 2632 | $pod, |
| 2633 | $id, |
| 2634 | ] |
| 2635 | ); |
| 2636 | |
| 2637 | if ( 'data' === $context ) { |
| 2638 | pods_static_cache_set( $name . '/' . $options['id'], [ |
| 2639 | 'autocomplete' => false, |
| 2640 | ], __CLASS__ . '/field_data' ); |
| 2641 | } |
| 2642 | |
| 2643 | $simple = true; |
| 2644 | |
| 2645 | // Cache data from callback. |
| 2646 | if ( ! empty( $data ) ) { |
| 2647 | self::$related_objects[ $options[ static::$type . '_object' ] ]['data'] = $data; |
| 2648 | } |
| 2649 | } elseif ( 'simple_value' !== $context ) { |
| 2650 | $pick_val = pods_v( static::$type . '_val', $options ); |
| 2651 | |
| 2652 | if ( 'table' === $pick_object ) { |
| 2653 | $pick_val = pods_v( static::$type . '_table', $options, $pick_val, true ); |
| 2654 | } |
| 2655 | |
| 2656 | $current_pod = null; |
| 2657 | |
| 2658 | if ( $pod instanceof Pod ) { |
| 2659 | $current_pod = $pod; |
| 2660 | } elseif ( $pod instanceof Pods ) { |
| 2661 | $current_pod = $pod->pod_data; |
| 2662 | } elseif ( is_array( $pod ) ) { |
| 2663 | $current_pod = $pod; |
| 2664 | } |
| 2665 | |
| 2666 | $related_pod = null; |
| 2667 | |
| 2668 | if ( '__current__' === $pick_val ) { |
| 2669 | if ( $pod instanceof Pod ) { |
| 2670 | $pick_val = $pod->get_name(); |
| 2671 | |
| 2672 | $related_pod = $pod; |
| 2673 | } elseif ( $pod instanceof Pods ) { |
| 2674 | $pick_val = $pod->pod_data->get_name(); |
| 2675 | |
| 2676 | $related_pod = $pod->pod_data; |
| 2677 | } elseif ( is_array( $pod ) ) { |
| 2678 | $pick_val = $pod['name']; |
| 2679 | } elseif ( is_string( $pod ) && 0 < strlen( $pod ) ) { |
| 2680 | $pick_val = $pod; |
| 2681 | } |
| 2682 | } |
| 2683 | |
| 2684 | $table_info = pods_v( 'table_info', $options ); |
| 2685 | |
| 2686 | if ( empty( $table_info ) && ! empty( $pick_object ) ) { |
| 2687 | $table_info = pods_api()->get_table_info( $pick_object, $pick_val, null, null, $options ); |
| 2688 | } |
| 2689 | |
| 2690 | // If the ACT was not found, return nothing. |
| 2691 | if ( 'pod' === $pick_object && $table_info && ! $table_info['pod'] ) { |
| 2692 | return []; |
| 2693 | } |
| 2694 | |
| 2695 | if ( null === $related_pod && $table_info && $table_info['pod'] ) { |
| 2696 | $related_pod = $table_info['pod']; |
| 2697 | } |
| 2698 | |
| 2699 | $search_data = pods_data( $related_pod ); |
| 2700 | $search_data->table( $table_info ); |
| 2701 | |
| 2702 | $default_field_index = $search_data->field_index; |
| 2703 | |
| 2704 | $params = [ |
| 2705 | 'select' => "`t`.`{$search_data->field_id}`, `t`.`{$search_data->field_index}`", |
| 2706 | 'table' => $search_data->table, |
| 2707 | 'where' => pods_v( static::$type . '_where', $options, null, true ), |
| 2708 | 'orderby' => pods_v( static::$type . '_orderby', $options, null, true ), |
| 2709 | 'having' => pods_v( static::$type . '_having', $options, null, true ), |
| 2710 | 'groupby' => pods_v( static::$type . '_groupby', $options, null, true ), |
| 2711 | 'pagination' => false, |
| 2712 | 'search' => false, |
| 2713 | ]; |
| 2714 | |
| 2715 | if ( ! pods_can_use_dynamic_feature_sql_clauses( 'simple' ) ) { |
| 2716 | $params['where'] = $params['where'] ? '0=1 /* Dynamic SQL clauses disabled in Pods */' : (array) $table_info['where_default']; |
| 2717 | $params['orderby'] = null; |
| 2718 | } |
| 2719 | |
| 2720 | if ( ! pods_can_use_dynamic_feature_sql_clauses( 'all' ) ) { |
| 2721 | $params['having'] = null; |
| 2722 | $params['groupby'] = null; |
| 2723 | } |
| 2724 | |
| 2725 | if ( null === $params['where'] ) { |
| 2726 | $params['where'] = (array) $table_info['where_default']; |
| 2727 | } |
| 2728 | |
| 2729 | if ( in_array( $options[ static::$type . '_object' ], [ 'site', 'network' ], true ) ) { |
| 2730 | $params['select'] .= ', `t`.`path`'; |
| 2731 | } |
| 2732 | |
| 2733 | if ( ! empty( $params['where'] ) && (array) $table_info['where_default'] !== $params['where'] ) { |
| 2734 | $params['where'] = pods_evaluate_tags( $params['where'], true ); |
| 2735 | } |
| 2736 | |
| 2737 | if ( ! empty( $params['having'] ) ) { |
| 2738 | $params['having'] = pods_evaluate_tags( $params['having'], true ); |
| 2739 | } |
| 2740 | |
| 2741 | if ( empty( $params['where'] ) || ( ! is_array( $params['where'] ) && '' === trim( $params['where'] ) ) ) { |
| 2742 | $params['where'] = []; |
| 2743 | } |
| 2744 | |
| 2745 | $params['where'] = (array) $params['where']; |
| 2746 | |
| 2747 | if ( 'value_to_label' === $context ) { |
| 2748 | $params['where'][] = "`t`.`{$search_data->field_id}` = " . number_format( $value, 0, '', '' ); |
| 2749 | } |
| 2750 | |
| 2751 | // Check if we need to limit by the current post author. |
| 2752 | if ( |
| 2753 | 1 === (int) pods_v( static::$type . '_post_author', $options, 0 ) |
| 2754 | && $current_pod |
| 2755 | && 'post_type' === $current_pod['type'] |
| 2756 | && 'post_type' === $options[ static::$type . '_object' ] |
| 2757 | ) { |
| 2758 | $post_author_id = 0; |
| 2759 | |
| 2760 | if ( empty( $id ) ) { |
| 2761 | if ( is_user_logged_in() ) { |
| 2762 | $post_author_id = get_current_user_id(); |
| 2763 | } |
| 2764 | } else { |
| 2765 | $post = get_post( $id ); |
| 2766 | |
| 2767 | if ( $post ) { |
| 2768 | $post_author_id = $post->post_author; |
| 2769 | } |
| 2770 | } |
| 2771 | |
| 2772 | $params['where'][] = '`t`.`post_author` = ' . (int) $post_author_id; |
| 2773 | } |
| 2774 | |
| 2775 | $display = trim( (string) pods_v( static::$type . '_display', $options ), ' {@}' ); |
| 2776 | |
| 2777 | $display_field = "`t`.`{$search_data->field_index}`"; |
| 2778 | $display_field_name = $search_data->field_index; |
| 2779 | $display_field_alias = false; |
| 2780 | |
| 2781 | if ( is_string( $display ) && 0 < strlen( $display ) ) { |
| 2782 | if ( ! empty( $table_info['pod'] ) ) { |
| 2783 | /** @var Pod $related_pod */ |
| 2784 | $related_pod = $table_info['pod']; |
| 2785 | |
| 2786 | $related_storage = $related_pod->get_storage(); |
| 2787 | $related_type = $related_pod->get_type(); |
| 2788 | $found_display_field = $related_pod->get_field( $display ); |
| 2789 | |
| 2790 | if ( $found_display_field ) { |
| 2791 | $display_field_name = $found_display_field->get_name(); |
| 2792 | } |
| 2793 | |
| 2794 | if ( $found_display_field instanceof Object_Field ) { |
| 2795 | $display_field = "`t`.`{$display_field_name}`"; |
| 2796 | } elseif ( |
| 2797 | 'table' === $related_storage |
| 2798 | && ! in_array( |
| 2799 | $related_type, [ |
| 2800 | 'pod', |
| 2801 | 'table', |
| 2802 | ], true |
| 2803 | ) |
| 2804 | ) { |
| 2805 | $display_field = "`d`.`{$display_field_name}`"; |
| 2806 | } elseif ( 'meta' === $related_storage ) { |
| 2807 | $display_field = "`{$display_field_name}`.`meta_value`"; |
| 2808 | |
| 2809 | $display_field_alias = true; |
| 2810 | } else { |
| 2811 | $display_field = "`t`.`{$display_field_name}`"; |
| 2812 | } |
| 2813 | } elseif ( isset( $table_info['object_fields'] ) && isset( $table_info['object_fields'][ $display ]['name'] ) ) { |
| 2814 | $display_field_name = $table_info['object_fields'][ $display ]['name']; |
| 2815 | |
| 2816 | $display_field = "`t`.`{$display_field_name}`"; |
| 2817 | }//end if |
| 2818 | }//end if |
| 2819 | |
| 2820 | if ( false === strpos( (string) $params['select'], $display_field ) ) { |
| 2821 | $params['select'] .= ', ' . $display_field . ( $display_field_alias ? " AS `{$display_field_name}`" : '' ); |
| 2822 | } |
| 2823 | |
| 2824 | $autocomplete = $this->is_autocomplete( $options ); |
| 2825 | |
| 2826 | $hierarchy = false; |
| 2827 | |
| 2828 | if ( 'data' === $context && ! $autocomplete ) { |
| 2829 | if ( 'single' === pods_v( static::$type . '_format_type', $options, 'single' ) && in_array( |
| 2830 | pods_v( static::$type . '_format_single', $options, 'dropdown' ), [ |
| 2831 | 'dropdown', |
| 2832 | 'radio', |
| 2833 | ], true |
| 2834 | ) |
| 2835 | ) { |
| 2836 | $hierarchy = true; |
| 2837 | } elseif ( 'multi' === pods_v( static::$type . '_format_type', $options, 'single' ) && in_array( |
| 2838 | pods_v( static::$type . '_format_multi', $options, 'checkbox' ), [ |
| 2839 | 'multiselect', |
| 2840 | 'checkbox', |
| 2841 | ], true |
| 2842 | ) |
| 2843 | ) { |
| 2844 | $hierarchy = true; |
| 2845 | } |
| 2846 | } |
| 2847 | |
| 2848 | if ( $hierarchy && $table_info['object_hierarchical'] && ! empty( $table_info['field_parent'] ) ) { |
| 2849 | if ( false === strpos( (string) $params['select'], $table_info['field_parent_select'] ) ) { |
| 2850 | $params['select'] .= ', ' . $table_info['field_parent_select']; |
| 2851 | } |
| 2852 | } |
| 2853 | |
| 2854 | if ( $autocomplete ) { |
| 2855 | if ( 0 === $limit ) { |
| 2856 | $limit = 30; |
| 2857 | } |
| 2858 | |
| 2859 | $autocomplete_limit = pods_get_setting( 'autocomplete_limit' ); |
| 2860 | |
| 2861 | if ( 'admin_ajax_relationship' === $context && ! empty( $data_params['query'] ) && null !== $autocomplete_limit ) { |
| 2862 | $limit = max( (int) $autocomplete_limit, - 1 ); |
| 2863 | |
| 2864 | if ( 0 === $limit ) { |
| 2865 | $limit = - 1; |
| 2866 | } |
| 2867 | } |
| 2868 | |
| 2869 | $params['limit'] = apply_filters( 'pods_form_ui_field_pick_autocomplete_limit', $limit, $name, $value, $options, $pod, $id, $object_params ); |
| 2870 | |
| 2871 | if ( - 1 !== (int) $params['limit'] && is_array( $value ) && $params['limit'] < count( $value ) ) { |
| 2872 | $params['limit'] = count( $value ); |
| 2873 | } |
| 2874 | |
| 2875 | $params['page'] = $page; |
| 2876 | |
| 2877 | if ( 'admin_ajax_relationship' === $context ) { |
| 2878 | $query_sanitized_like = pods_sanitize_like( $data_params['query'] ); |
| 2879 | |
| 2880 | $lookup_where = [ |
| 2881 | $search_data->field_index => "`t`.`{$search_data->field_index}` LIKE '%{$query_sanitized_like}%'", |
| 2882 | ]; |
| 2883 | |
| 2884 | if ( $display_field_name !== $search_data->field_index ) { |
| 2885 | $lookup_where[ $display_field_name ] = "{$display_field} LIKE '%{$query_sanitized_like}%'"; |
| 2886 | } |
| 2887 | |
| 2888 | // @todo Hook into WPML for each table |
| 2889 | if ( $wpdb->users === $search_data->table ) { |
| 2890 | $lookup_where['display_name'] = "`t`.`display_name` LIKE '%{$query_sanitized_like}%'"; |
| 2891 | $lookup_where['user_login'] = "`t`.`user_login` LIKE '%{$query_sanitized_like}%'"; |
| 2892 | $lookup_where['user_email'] = "`t`.`user_email` LIKE '%{$query_sanitized_like}%'"; |
| 2893 | } elseif ( $wpdb->posts === $search_data->table ) { |
| 2894 | $lookup_where['post_title'] = "`t`.`post_title` LIKE '%{$query_sanitized_like}%'"; |
| 2895 | $lookup_where['post_name'] = "`t`.`post_name` LIKE '%{$query_sanitized_like}%'"; |
| 2896 | $lookup_where['post_content'] = "`t`.`post_content` LIKE '%{$query_sanitized_like}%'"; |
| 2897 | $lookup_where['post_excerpt'] = "`t`.`post_excerpt` LIKE '%{$query_sanitized_like}%'"; |
| 2898 | } elseif ( $wpdb->terms === $search_data->table ) { |
| 2899 | $lookup_where['name'] = "`t`.`name` LIKE '%{$query_sanitized_like}%'"; |
| 2900 | $lookup_where['slug'] = "`t`.`slug` LIKE '%{$query_sanitized_like}%'"; |
| 2901 | } elseif ( $wpdb->comments === $search_data->table ) { |
| 2902 | $lookup_where['comment_content'] = "`t`.`comment_content` LIKE '%{$query_sanitized_like}%'"; |
| 2903 | $lookup_where['comment_author'] = "`t`.`comment_author` LIKE '%{$query_sanitized_like}%'"; |
| 2904 | $lookup_where['comment_author_email'] = "`t`.`comment_author_email` LIKE '%{$query_sanitized_like}%'"; |
| 2905 | } |
| 2906 | |
| 2907 | $lookup_where = apply_filters( 'pods_form_ui_field_pick_autocomplete_lookup', $lookup_where, $data_params['query'], $name, $value, $options, $pod, $id, $object_params, $search_data ); |
| 2908 | |
| 2909 | if ( ! empty( $lookup_where ) ) { |
| 2910 | $params['where'][] = implode( ' OR ', $lookup_where ); |
| 2911 | } |
| 2912 | |
| 2913 | $orderby = []; |
| 2914 | $orderby[] = "( {$display_field} LIKE '%{$query_sanitized_like}%' ) DESC"; |
| 2915 | |
| 2916 | $pick_orderby = pods_v( static::$type . '_orderby', $options, null, true ); |
| 2917 | |
| 2918 | if ( ! pods_can_use_dynamic_feature_sql_clauses( 'simple' ) ) { |
| 2919 | $pick_orderby = null; |
| 2920 | } |
| 2921 | |
| 2922 | if ( is_string( $pick_orderby ) && 0 < strlen( $pick_orderby ) ) { |
| 2923 | $orderby[] = $pick_orderby; |
| 2924 | } |
| 2925 | |
| 2926 | if ( ! in_array( $search_data->field_index, $orderby, true ) ) { |
| 2927 | $orderby[] = "`t`.`{$search_data->field_index}`"; |
| 2928 | } |
| 2929 | |
| 2930 | if ( ! in_array( $search_data->field_id, $orderby, true ) ) { |
| 2931 | $orderby[] = "`t`.`{$search_data->field_id}`"; |
| 2932 | } |
| 2933 | |
| 2934 | $params['orderby'] = $orderby; |
| 2935 | }//end if |
| 2936 | } elseif ( 0 < $limit ) { |
| 2937 | $params['limit'] = $limit; |
| 2938 | $params['page'] = $page; |
| 2939 | }//end if |
| 2940 | |
| 2941 | $extra = ''; |
| 2942 | |
| 2943 | if ( $wpdb->posts === $search_data->table ) { |
| 2944 | $extra = '`t`.`post_type`, `t`.`menu_order`, `t`.`post_date`'; |
| 2945 | } elseif ( $wpdb->terms === $search_data->table ) { |
| 2946 | $extra = '`tt`.`taxonomy`'; |
| 2947 | } elseif ( $wpdb->comments === $search_data->table ) { |
| 2948 | $extra = '`t`.`comment_type`'; |
| 2949 | } elseif ( $wpdb->site === $search_data->table ) { |
| 2950 | $extra = '`t`.`path`'; |
| 2951 | } elseif ( $wpdb->blogs === $search_data->table ) { |
| 2952 | $extra = '`t`.`path`'; |
| 2953 | } |
| 2954 | |
| 2955 | if ( '' !== $extra && false === strpos( (string) $params['select'], $extra ) ) { |
| 2956 | $params['select'] .= ', ' . $extra; |
| 2957 | } |
| 2958 | |
| 2959 | if ( 'user' === pods_v( static::$type . '_object', $options ) ) { |
| 2960 | $roles = pods_v( static::$type . '_user_role', $options ); |
| 2961 | |
| 2962 | if ( ! empty( $roles ) ) { |
| 2963 | $where = []; |
| 2964 | |
| 2965 | foreach ( (array) $roles as $role ) { |
| 2966 | if ( empty( $role ) || ( pods_clean_name( $role ) !== $role && sanitize_title( $role ) !== $role ) ) { |
| 2967 | continue; |
| 2968 | } |
| 2969 | |
| 2970 | $role_sanitized_like = pods_sanitize_like( $role ); |
| 2971 | |
| 2972 | $where[] = "{$wpdb->prefix}capabilities.meta_value LIKE '%\"{$role_sanitized_like}\"%'"; |
| 2973 | } |
| 2974 | |
| 2975 | if ( ! empty( $where ) ) { |
| 2976 | $params['where'][] = implode( ' OR ', $where ); |
| 2977 | } |
| 2978 | }//end if |
| 2979 | }//end if |
| 2980 | |
| 2981 | if ( empty( $params['where'] ) ) { |
| 2982 | $params['where'] = null; |
| 2983 | } |
| 2984 | |
| 2985 | try { |
| 2986 | $results = $search_data->select( $params ); |
| 2987 | } catch ( Exception $exception ) { |
| 2988 | if ( pods_is_debug_display() ) { |
| 2989 | pods_error_exception( $exception ); |
| 2990 | } |
| 2991 | |
| 2992 | $results = []; |
| 2993 | } |
| 2994 | |
| 2995 | if ( $autocomplete && 0 < $params['limit'] && $params['limit'] < $search_data->total_found() ) { |
| 2996 | if ( ! empty( $value ) ) { |
| 2997 | $ids = $value; |
| 2998 | |
| 2999 | if ( is_array( $ids ) ) { |
| 3000 | if ( isset( $ids[0] ) && is_array( $ids[0] ) ) { |
| 3001 | $ids = wp_list_pluck( $ids, $search_data->field_id ); |
| 3002 | } |
| 3003 | |
| 3004 | if ( $params['limit'] < count( $ids ) ) { |
| 3005 | $params['limit'] = count( $ids ); |
| 3006 | } |
| 3007 | |
| 3008 | $ids = array_map( 'absint', $ids ); |
| 3009 | $ids = implode( ', ', $ids ); |
| 3010 | } else { |
| 3011 | $ids = (int) $ids; |
| 3012 | } |
| 3013 | |
| 3014 | if ( is_array( $params['where'] ) ) { |
| 3015 | $params['where'] = implode( ' AND ', $params['where'] ); |
| 3016 | } |
| 3017 | if ( ! empty( $params['where'] ) ) { |
| 3018 | $params['where'] = '(' . $params['where'] . ') AND '; |
| 3019 | } |
| 3020 | |
| 3021 | $params['where'] .= "`t`.`{$search_data->field_id}` IN ( {$ids} )"; |
| 3022 | |
| 3023 | try { |
| 3024 | $results = array_merge( $results, $search_data->select( $params ) ); |
| 3025 | } catch ( Exception $exception ) { |
| 3026 | if ( pods_is_debug_display() ) { |
| 3027 | pods_error_exception( $exception ); |
| 3028 | } |
| 3029 | |
| 3030 | $results = []; |
| 3031 | } |
| 3032 | }//end if |
| 3033 | } else { |
| 3034 | $autocomplete = false; |
| 3035 | }//end if |
| 3036 | |
| 3037 | if ( 'data' === $context ) { |
| 3038 | pods_static_cache_set( $name . '/' . $options['id'], [ |
| 3039 | 'autocomplete' => $autocomplete, |
| 3040 | ], __CLASS__ . '/field_data' ); |
| 3041 | } |
| 3042 | |
| 3043 | if ( $hierarchy && ! $autocomplete && ! empty( $results ) && $table_info['object_hierarchical'] && ! empty( $table_info['field_parent'] ) ) { |
| 3044 | $select_args = [ |
| 3045 | 'id' => $table_info['field_id'], |
| 3046 | 'index' => $display_field_name, |
| 3047 | 'parent' => $table_info['field_parent'], |
| 3048 | ]; |
| 3049 | |
| 3050 | $results = pods_hierarchical_select( $results, $select_args ); |
| 3051 | } |
| 3052 | |
| 3053 | $ids = []; |
| 3054 | |
| 3055 | if ( ! empty( $results ) ) { |
| 3056 | foreach ( $results as $result ) { |
| 3057 | $result = get_object_vars( $result ); |
| 3058 | $field_id = $search_data->field_id; |
| 3059 | $field_index = $display_field_name; |
| 3060 | |
| 3061 | if ( ! isset( $result[ $field_index ] ) ) { |
| 3062 | $field_index = $default_field_index; |
| 3063 | } |
| 3064 | |
| 3065 | if ( ! isset( $result[ $field_id ], $result[ $field_index ] ) ) { |
| 3066 | continue; |
| 3067 | } |
| 3068 | |
| 3069 | $result[ $field_index ] = trim( $result[ $field_index ] ); |
| 3070 | |
| 3071 | $object = ''; |
| 3072 | $object_type = ''; |
| 3073 | |
| 3074 | if ( $wpdb->posts === $search_data->table && isset( $result['post_type'] ) ) { |
| 3075 | $object = $result['post_type']; |
| 3076 | $object_type = 'post_type'; |
| 3077 | } elseif ( $wpdb->terms === $search_data->table && isset( $result['taxonomy'] ) ) { |
| 3078 | $object = $result['taxonomy']; |
| 3079 | $object_type = 'taxonomy'; |
| 3080 | } |
| 3081 | |
| 3082 | $field_index_data_to_use = pods_v( $field_index, $search_data->object_fields ); |
| 3083 | |
| 3084 | $display_filter = pods_v( 'display_filter', $field_index_data_to_use ); |
| 3085 | |
| 3086 | if ( is_string( $display_filter ) && 0 < strlen( $display_filter ) ) { |
| 3087 | $display_filter_args = pods_v( 'display_filter_args', $field_index_data_to_use ); |
| 3088 | |
| 3089 | $filter_args = [ |
| 3090 | $display_filter, |
| 3091 | $result[ $field_index ], |
| 3092 | ]; |
| 3093 | |
| 3094 | if ( ! empty( $display_filter_args ) ) { |
| 3095 | foreach ( (array) $display_filter_args as $display_filter_arg ) { |
| 3096 | // Manual solution to a problem that won't map correctly. |
| 3097 | if ( 'post_ID' === $display_filter_arg ) { |
| 3098 | $display_filter_arg = 'ID'; |
| 3099 | } |
| 3100 | |
| 3101 | if ( isset( $result[ $display_filter_arg ] ) ) { |
| 3102 | $filter_args[] = $result[ $display_filter_arg ]; |
| 3103 | } |
| 3104 | } |
| 3105 | } |
| 3106 | |
| 3107 | $result[ $field_index ] = call_user_func_array( 'apply_filters', $filter_args ); |
| 3108 | } |
| 3109 | |
| 3110 | if ( in_array( $options[ static::$type . '_object' ], [ 'site', 'network' ], true ) ) { |
| 3111 | $result[ $field_index ] = $result[ $field_index ] . $result['path']; |
| 3112 | } elseif ( '' === $result[ $field_index ] ) { |
| 3113 | $result[ $field_index ] = '(No Title)'; |
| 3114 | } |
| 3115 | |
| 3116 | if ( 'admin_ajax_relationship' === $context ) { |
| 3117 | $items[] = $this->build_dfv_field_item_data_recurse_item( $result[ $field_id ], $result[ $field_index ], (object) $object_params ); |
| 3118 | } else { |
| 3119 | $data[ $result[ $field_id ] ] = $result[ $field_index ]; |
| 3120 | } |
| 3121 | |
| 3122 | $ids[] = $result[ $field_id ]; |
| 3123 | }//end foreach |
| 3124 | }//end if |
| 3125 | }//end if |
| 3126 | |
| 3127 | if ( $simple && 'admin_ajax_relationship' === $context ) { |
| 3128 | $found_data = []; |
| 3129 | |
| 3130 | foreach ( $data as $k => $v ) { |
| 3131 | if ( false !== stripos( $v, $data_params['query'] ) || false !== stripos( $k, $data_params['query'] ) ) { |
| 3132 | $found_data[ $k ] = $v; |
| 3133 | } |
| 3134 | } |
| 3135 | |
| 3136 | $data = $found_data; |
| 3137 | } |
| 3138 | }//end if |
| 3139 | |
| 3140 | if ( 'admin_ajax_relationship' === $context ) { |
| 3141 | if ( empty( $items ) && ! empty( $data ) ) { |
| 3142 | foreach ( $data as $k => $v ) { |
| 3143 | $items[] = [ |
| 3144 | 'id' => $k, |
| 3145 | 'text' => $v, |
| 3146 | ]; |
| 3147 | } |
| 3148 | } |
| 3149 | |
| 3150 | $data = $items; |
| 3151 | } |
| 3152 | |
| 3153 | return $data; |
| 3154 | |
| 3155 | } |
| 3156 | |
| 3157 | /** |
| 3158 | * Check if field is autocomplete enabled. |
| 3159 | * |
| 3160 | * @param array $options Field options. |
| 3161 | * |
| 3162 | * @return bool |
| 3163 | * |
| 3164 | * @since 2.7.0 |
| 3165 | */ |
| 3166 | private function is_autocomplete( $options ) { |
| 3167 | |
| 3168 | $autocomplete = false; |
| 3169 | |
| 3170 | if ( 'single' === pods_v( static::$type . '_format_type', $options, 'single' ) ) { |
| 3171 | if ( in_array( pods_v( static::$type . '_format_single', $options, 'dropdown' ), [ |
| 3172 | 'autocomplete', |
| 3173 | 'list', |
| 3174 | ], true ) ) { |
| 3175 | $autocomplete = true; |
| 3176 | } |
| 3177 | } elseif ( 'multi' === pods_v( static::$type . '_format_type', $options, 'single' ) ) { |
| 3178 | if ( in_array( pods_v( static::$type . '_format_multi', $options, 'checkbox' ), [ |
| 3179 | 'autocomplete', |
| 3180 | 'list', |
| 3181 | ], true ) ) { |
| 3182 | $autocomplete = true; |
| 3183 | } |
| 3184 | } |
| 3185 | |
| 3186 | return $autocomplete; |
| 3187 | } |
| 3188 | |
| 3189 | /** |
| 3190 | * Check if a field type is a tableless text field type. |
| 3191 | * |
| 3192 | * @since 2.7.4 |
| 3193 | * |
| 3194 | * @param string $type Field type. |
| 3195 | * @param array $options Field options. |
| 3196 | * |
| 3197 | * @return bool True if the field type is a tableless text field type, false otherwise. |
| 3198 | */ |
| 3199 | private function is_simple_tableless( $type, array $options ) { |
| 3200 | $field_object = pods_v( $type . '_object', $options ); |
| 3201 | |
| 3202 | return in_array( $field_object, PodsForm::simple_tableless_objects(), true ); |
| 3203 | } |
| 3204 | |
| 3205 | /** |
| 3206 | * Check if a field supports AJAX mode |
| 3207 | * |
| 3208 | * @param string $type Field type. |
| 3209 | * @param array $options Field options. |
| 3210 | * |
| 3211 | * @return bool |
| 3212 | * @since 2.7.4 |
| 3213 | */ |
| 3214 | private function can_ajax( $type, $options ) { |
| 3215 | return $this->is_autocomplete( $options ) && ! $this->is_simple_tableless( $type, $options ); |
| 3216 | } |
| 3217 | |
| 3218 | |
| 3219 | /** |
| 3220 | * Handle autocomplete AJAX. |
| 3221 | * |
| 3222 | * @since 2.3.0 |
| 3223 | */ |
| 3224 | public function admin_ajax_relationship() { |
| 3225 | |
| 3226 | pods_session_start(); |
| 3227 | |
| 3228 | // Sanitize input. |
| 3229 | // @codingStandardsIgnoreLine |
| 3230 | $params = pods_unslash( (array) $_POST ); |
| 3231 | |
| 3232 | foreach ( $params as $key => $value ) { |
| 3233 | if ( 'action' === $key ) { |
| 3234 | continue; |
| 3235 | } |
| 3236 | |
| 3237 | unset( $params[ $key ] ); |
| 3238 | |
| 3239 | $params[ str_replace( '_podsfix_', '', $key ) ] = $value; |
| 3240 | } |
| 3241 | |
| 3242 | $params = (object) $params; |
| 3243 | |
| 3244 | if ( ! isset( $params->_wpnonce, $params->pod_name, $params->field_name, $params->uri_hash, $params->id ) ) { |
| 3245 | pods_error( __( 'Unauthorized request', 'pods' ), PodsInit::$admin ); |
| 3246 | } |
| 3247 | |
| 3248 | if ( ! isset( $params->query ) || '' === trim( $params->query ) ) { |
| 3249 | pods_error( __( 'Invalid field request', 'pods' ), PodsInit::$admin ); |
| 3250 | } |
| 3251 | |
| 3252 | $_wpnonce = $params->_wpnonce; |
| 3253 | $pod_name = $params->pod_name; |
| 3254 | $field_name = $params->field_name; |
| 3255 | $uri_hash = $params->uri_hash; |
| 3256 | $id = (int) $params->id; |
| 3257 | |
| 3258 | $query = $params->query; |
| 3259 | $limit = pods_v( 'limit', $params, 15, true ); |
| 3260 | $page = pods_v( 'page', $params, 1, true ); |
| 3261 | |
| 3262 | $uid = pods_session_id(); |
| 3263 | |
| 3264 | if ( is_user_logged_in() ) { |
| 3265 | $uid = 'user_' . get_current_user_id(); |
| 3266 | } |
| 3267 | |
| 3268 | $nonce_name = 'pods_relationship:' . json_encode( compact( 'pod_name', 'field_name', 'uid', 'uri_hash', 'id' ) ); |
| 3269 | |
| 3270 | if ( false === wp_verify_nonce( $_wpnonce, $nonce_name ) ) { |
| 3271 | pods_error( __( 'Unauthorized request', 'pods' ), PodsInit::$admin ); |
| 3272 | } |
| 3273 | |
| 3274 | if ( empty( self::$api ) ) { |
| 3275 | self::$api = pods_api(); |
| 3276 | } |
| 3277 | |
| 3278 | $pod = self::$api->load_pod( [ |
| 3279 | 'name' => $pod_name, |
| 3280 | ] ); |
| 3281 | |
| 3282 | if ( ! $pod ) { |
| 3283 | pods_error( __( 'Invalid Pod configuration', 'pods' ), PodsInit::$admin ); |
| 3284 | } |
| 3285 | |
| 3286 | $field = $pod->get_field( $field_name ); |
| 3287 | |
| 3288 | if ( ! $field ) { |
| 3289 | pods_error( __( 'Invalid Field configuration', 'pods' ), PodsInit::$admin ); |
| 3290 | } |
| 3291 | |
| 3292 | if ( ! $field->is_autocomplete_relationship() ) { |
| 3293 | pods_error( __( 'Invalid field', 'pods' ), PodsInit::$admin ); |
| 3294 | } |
| 3295 | |
| 3296 | $object_params = [ |
| 3297 | // The name of the field. |
| 3298 | 'name' => $field['name'], |
| 3299 | // The value of the field. |
| 3300 | 'value' => null, |
| 3301 | // Field options. |
| 3302 | 'options' => $field, |
| 3303 | // Pod data. |
| 3304 | 'pod' => $pod, |
| 3305 | // Item ID. |
| 3306 | 'id' => $id, |
| 3307 | // Data context. |
| 3308 | 'context' => 'admin_ajax_relationship', |
| 3309 | 'data_params' => $params, |
| 3310 | 'page' => $page, |
| 3311 | 'limit' => $limit, |
| 3312 | ]; |
| 3313 | |
| 3314 | $pick_data = apply_filters( 'pods_field_pick_data_ajax', null, $field['name'], null, $field, $pod, $id ); |
| 3315 | |
| 3316 | if ( null !== $pick_data ) { |
| 3317 | $items = $pick_data; |
| 3318 | } else { |
| 3319 | $items = $this->get_object_data( $object_params ); |
| 3320 | } |
| 3321 | |
| 3322 | if ( ! empty( $items ) && isset( $items[0] ) && ! is_array( $items[0] ) ) { |
| 3323 | $new_items = []; |
| 3324 | |
| 3325 | foreach ( $items as $id => $text ) { |
| 3326 | $new_items[] = [ |
| 3327 | 'id' => $id, |
| 3328 | 'text' => $text, |
| 3329 | 'image' => '', |
| 3330 | ]; |
| 3331 | } |
| 3332 | |
| 3333 | $items = $new_items; |
| 3334 | } |
| 3335 | |
| 3336 | $items = apply_filters( 'pods_field_pick_data_ajax_items', $items, $field['name'], null, $field, $pod, $id ); |
| 3337 | |
| 3338 | $items = [ |
| 3339 | 'results' => $items, |
| 3340 | ]; |
| 3341 | |
| 3342 | wp_send_json( $items ); |
| 3343 | |
| 3344 | die(); |
| 3345 | // KBAI! |
| 3346 | } |
| 3347 | |
| 3348 | /** |
| 3349 | * Data callback for Post Stati. |
| 3350 | * |
| 3351 | * @param string|null $name The name of the field. |
| 3352 | * @param string|array|null $value The value of the field. |
| 3353 | * @param array|null $options Field options. |
| 3354 | * @param array|null $pod Pod data. |
| 3355 | * @param int|null $id Item ID. |
| 3356 | * |
| 3357 | * @return array |
| 3358 | * |
| 3359 | * @since 2.3.0 |
| 3360 | */ |
| 3361 | public function data_post_stati( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 3362 | $data = []; |
| 3363 | |
| 3364 | $post_stati = get_post_stati( [], 'objects' ); |
| 3365 | |
| 3366 | foreach ( $post_stati as $post_status ) { |
| 3367 | $data[ $post_status->name ] = $post_status->label; |
| 3368 | } |
| 3369 | |
| 3370 | return (array) apply_filters( 'pods_form_ui_field_pick_data_post_stati', $data, $name, $value, $options, $pod, $id ); |
| 3371 | } |
| 3372 | |
| 3373 | /** |
| 3374 | * Data callback for Post Stati (with any). |
| 3375 | * |
| 3376 | * @param string|null $name The name of the field. |
| 3377 | * @param string|array|null $value The value of the field. |
| 3378 | * @param array|null $options Field options. |
| 3379 | * @param array|null $pod Pod data. |
| 3380 | * @param int|null $id Item ID. |
| 3381 | * |
| 3382 | * @return array |
| 3383 | * |
| 3384 | * @since 2.9.10 |
| 3385 | */ |
| 3386 | public function data_post_stati_with_any( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 3387 | $data = [ |
| 3388 | '_pods_any' => esc_html__( 'Any Status (excluding Auto-Draft and Trashed)', 'pods' ), |
| 3389 | ]; |
| 3390 | |
| 3391 | $data = array_merge( $data, $this->data_post_stati( $name, $value, $options, $pod, $id ) ); |
| 3392 | |
| 3393 | /** |
| 3394 | * Allow filtering the list of post stati with any. |
| 3395 | * |
| 3396 | * @since 2.9.10 |
| 3397 | * |
| 3398 | * @param array $data The list of post stati with any. |
| 3399 | * @param string|null $name The name of the field. |
| 3400 | * @param string|array|null $value The value of the field. |
| 3401 | * @param array|null $options Field options. |
| 3402 | * @param array|null $pod Pod data. |
| 3403 | * @param int|null $id Item ID. |
| 3404 | */ |
| 3405 | return (array) apply_filters( 'pods_form_ui_field_pick_data_post_stati_with_any', $data, $name, $value, $options, $pod, $id ); |
| 3406 | } |
| 3407 | |
| 3408 | /** |
| 3409 | * Data callback for User Roles. |
| 3410 | * |
| 3411 | * @param string|null $name The name of the field. |
| 3412 | * @param string|array|null $value The value of the field. |
| 3413 | * @param array|null $options Field options. |
| 3414 | * @param array|null $pod Pod data. |
| 3415 | * @param int|null $id Item ID. |
| 3416 | * |
| 3417 | * @return array |
| 3418 | * |
| 3419 | * @since 2.3.0 |
| 3420 | */ |
| 3421 | public function data_roles( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 3422 | |
| 3423 | $data = []; |
| 3424 | |
| 3425 | global $wp_roles; |
| 3426 | |
| 3427 | foreach ( $wp_roles->role_objects as $key => $role ) { |
| 3428 | $data[ $key ] = $wp_roles->role_names[ $key ]; |
| 3429 | } |
| 3430 | |
| 3431 | return apply_filters( 'pods_form_ui_field_pick_data_roles', $data, $name, $value, $options, $pod, $id ); |
| 3432 | |
| 3433 | } |
| 3434 | |
| 3435 | /** |
| 3436 | * Data callback for User Capabilities. |
| 3437 | * |
| 3438 | * @param string|null $name The name of the field. |
| 3439 | * @param string|array|null $value The value of the field. |
| 3440 | * @param array|null $options Field options. |
| 3441 | * @param array|null $pod Pod data. |
| 3442 | * @param int|null $id Item ID. |
| 3443 | * |
| 3444 | * @return array |
| 3445 | * |
| 3446 | * @since 2.3.0 |
| 3447 | */ |
| 3448 | public function data_capabilities( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 3449 | |
| 3450 | $data = []; |
| 3451 | |
| 3452 | global $wp_roles; |
| 3453 | |
| 3454 | $default_caps = [ |
| 3455 | 'activate_plugins', |
| 3456 | 'add_users', |
| 3457 | 'create_users', |
| 3458 | 'delete_others_pages', |
| 3459 | 'delete_others_posts', |
| 3460 | 'delete_pages', |
| 3461 | 'delete_plugins', |
| 3462 | 'delete_posts', |
| 3463 | 'delete_private_pages', |
| 3464 | 'delete_private_posts', |
| 3465 | 'delete_published_pages', |
| 3466 | 'delete_published_posts', |
| 3467 | 'delete_users', |
| 3468 | 'edit_dashboard', |
| 3469 | 'edit_files', |
| 3470 | 'edit_others_pages', |
| 3471 | 'edit_others_posts', |
| 3472 | 'edit_pages', |
| 3473 | 'edit_plugins', |
| 3474 | 'edit_posts', |
| 3475 | 'edit_private_pages', |
| 3476 | 'edit_private_posts', |
| 3477 | 'edit_published_pages', |
| 3478 | 'edit_published_posts', |
| 3479 | 'edit_theme_options', |
| 3480 | 'edit_themes', |
| 3481 | 'edit_users', |
| 3482 | 'import', |
| 3483 | 'install_plugins', |
| 3484 | 'install_themes', |
| 3485 | 'list_users', |
| 3486 | 'manage_categories', |
| 3487 | 'manage_links', |
| 3488 | 'manage_options', |
| 3489 | 'moderate_comments', |
| 3490 | 'promote_users', |
| 3491 | 'publish_pages', |
| 3492 | 'publish_posts', |
| 3493 | 'read', |
| 3494 | 'read_private_pages', |
| 3495 | 'read_private_posts', |
| 3496 | 'remove_users', |
| 3497 | 'switch_themes', |
| 3498 | 'unfiltered_html', |
| 3499 | 'unfiltered_upload', |
| 3500 | 'update_core', |
| 3501 | 'update_plugins', |
| 3502 | 'update_themes', |
| 3503 | 'upload_files', |
| 3504 | ]; |
| 3505 | |
| 3506 | $role_caps = []; |
| 3507 | |
| 3508 | foreach ( $wp_roles->role_objects as $key => $role ) { |
| 3509 | if ( is_array( $role->capabilities ) ) { |
| 3510 | foreach ( $role->capabilities as $cap => $grant ) { |
| 3511 | $role_caps[ $cap ] = $cap; |
| 3512 | } |
| 3513 | } |
| 3514 | } |
| 3515 | |
| 3516 | $role_caps = array_unique( $role_caps ); |
| 3517 | |
| 3518 | $capabilities = array_merge( $default_caps, $role_caps ); |
| 3519 | |
| 3520 | // To support Members filters. |
| 3521 | $capabilities = apply_filters( 'members_get_capabilities', $capabilities ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound |
| 3522 | |
| 3523 | $capabilities = apply_filters( 'pods_roles_get_capabilities', $capabilities ); |
| 3524 | |
| 3525 | sort( $capabilities ); |
| 3526 | |
| 3527 | $capabilities = array_unique( $capabilities ); |
| 3528 | |
| 3529 | global $wp_roles; |
| 3530 | |
| 3531 | foreach ( $capabilities as $capability ) { |
| 3532 | $data[ $capability ] = $capability; |
| 3533 | } |
| 3534 | |
| 3535 | return apply_filters( 'pods_form_ui_field_pick_data_capabilities', $data, $name, $value, $options, $pod, $id ); |
| 3536 | |
| 3537 | } |
| 3538 | |
| 3539 | /** |
| 3540 | * Data callback for Image Sizes. |
| 3541 | * |
| 3542 | * @param string|null $name The name of the field. |
| 3543 | * @param string|array|null $value The value of the field. |
| 3544 | * @param array|null $options Field options. |
| 3545 | * @param array|null $pod Pod data. |
| 3546 | * @param int|null $id Item ID. |
| 3547 | * |
| 3548 | * @return array |
| 3549 | * |
| 3550 | * @since 2.3.0 |
| 3551 | */ |
| 3552 | public function data_image_sizes( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 3553 | |
| 3554 | $data = []; |
| 3555 | |
| 3556 | $image_sizes = get_intermediate_image_sizes(); |
| 3557 | |
| 3558 | foreach ( $image_sizes as $image_size ) { |
| 3559 | $data[ $image_size ] = ucwords( str_replace( '-', ' ', $image_size ) ); |
| 3560 | } |
| 3561 | |
| 3562 | return apply_filters( 'pods_form_ui_field_pick_data_image_sizes', $data, $name, $value, $options, $pod, $id ); |
| 3563 | |
| 3564 | } |
| 3565 | |
| 3566 | /** |
| 3567 | * Data callback for Post Types |
| 3568 | * |
| 3569 | * @param string $name The name of the field |
| 3570 | * @param string|array $value The value of the field |
| 3571 | * @param array $options Field options |
| 3572 | * @param array $pod Pod data |
| 3573 | * @param int $id Item ID |
| 3574 | * |
| 3575 | * @return array |
| 3576 | * |
| 3577 | * @since 2.3.0 |
| 3578 | */ |
| 3579 | public function data_post_types( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 3580 | |
| 3581 | $data = []; |
| 3582 | |
| 3583 | $post_types = get_post_types( [], 'objects' ); |
| 3584 | |
| 3585 | $ignore = [ |
| 3586 | 'revision', |
| 3587 | 'nav_menu_item', |
| 3588 | 'custom_css', |
| 3589 | 'customize_changeset', |
| 3590 | 'attachment', |
| 3591 | 'oembed_cache', |
| 3592 | 'user_request', |
| 3593 | 'wp_block', |
| 3594 | 'wp_template', |
| 3595 | 'wp_template_part', |
| 3596 | 'wp_global_styles', |
| 3597 | 'wp_navigation', |
| 3598 | ]; |
| 3599 | |
| 3600 | foreach ( $post_types as $post_type ) { |
| 3601 | if ( in_array( $post_type->name, $ignore, true ) || 0 === strpos( $post_type->name, '_pods_' ) ) { |
| 3602 | continue; |
| 3603 | } |
| 3604 | |
| 3605 | $data[ $post_type->name ] = $post_type->label; |
| 3606 | } |
| 3607 | |
| 3608 | return apply_filters( 'pods_form_ui_field_pick_data_post_types', $data, $name, $value, $options, $pod, $id ); |
| 3609 | } |
| 3610 | |
| 3611 | /** |
| 3612 | * Data callback for Taxonomies |
| 3613 | * |
| 3614 | * @param string $name The name of the field |
| 3615 | * @param string|array $value The value of the field |
| 3616 | * @param array $options Field options |
| 3617 | * @param array $pod Pod data |
| 3618 | * @param int $id Item ID |
| 3619 | * |
| 3620 | * @return array |
| 3621 | * |
| 3622 | * @since 2.3.0 |
| 3623 | */ |
| 3624 | public function data_taxonomies( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 3625 | |
| 3626 | $data = []; |
| 3627 | |
| 3628 | $taxonomies = get_taxonomies( [], 'objects' ); |
| 3629 | |
| 3630 | $ignore = [ 'nav_menu', 'post_format' ]; |
| 3631 | |
| 3632 | foreach ( $taxonomies as $taxonomy ) { |
| 3633 | if ( in_array( $taxonomy->name, $ignore, true ) ) { |
| 3634 | continue; |
| 3635 | } |
| 3636 | |
| 3637 | $data[ $taxonomy->name ] = $taxonomy->label; |
| 3638 | } |
| 3639 | |
| 3640 | return apply_filters( 'pods_form_ui_field_pick_data_taxonomies', $data, $name, $value, $options, $pod, $id ); |
| 3641 | } |
| 3642 | |
| 3643 | /** |
| 3644 | * Data callback for Countries. |
| 3645 | * |
| 3646 | * @param string|null $name The name of the field. |
| 3647 | * @param string|array|null $value The value of the field. |
| 3648 | * @param array|null $options Field options. |
| 3649 | * @param array|null $pod Pod data. |
| 3650 | * @param int|null $id Item ID. |
| 3651 | * |
| 3652 | * @return array |
| 3653 | * |
| 3654 | * @since 2.3.0 |
| 3655 | */ |
| 3656 | public function data_countries( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 3657 | |
| 3658 | $data = [ |
| 3659 | 'AF' => __( 'Afghanistan', 'pods' ), |
| 3660 | 'AL' => __( 'Albania', 'pods' ), |
| 3661 | 'DZ' => __( 'Algeria', 'pods' ), |
| 3662 | 'AS' => __( 'American Samoa', 'pods' ), |
| 3663 | 'AD' => __( 'Andorra', 'pods' ), |
| 3664 | 'AO' => __( 'Angola', 'pods' ), |
| 3665 | 'AI' => __( 'Anguilla', 'pods' ), |
| 3666 | 'AQ' => __( 'Antarctica', 'pods' ), |
| 3667 | 'AG' => __( 'Antigua and Barbuda', 'pods' ), |
| 3668 | 'AR' => __( 'Argentina', 'pods' ), |
| 3669 | 'AM' => __( 'Armenia', 'pods' ), |
| 3670 | 'AW' => __( 'Aruba', 'pods' ), |
| 3671 | 'AU' => __( 'Australia', 'pods' ), |
| 3672 | 'AT' => __( 'Austria', 'pods' ), |
| 3673 | 'AZ' => __( 'Azerbaijan', 'pods' ), |
| 3674 | 'BS' => __( 'Bahamas', 'pods' ), |
| 3675 | 'BH' => __( 'Bahrain', 'pods' ), |
| 3676 | 'BD' => __( 'Bangladesh', 'pods' ), |
| 3677 | 'BB' => __( 'Barbados', 'pods' ), |
| 3678 | 'BY' => __( 'Belarus', 'pods' ), |
| 3679 | 'BE' => __( 'Belgium', 'pods' ), |
| 3680 | 'BZ' => __( 'Belize', 'pods' ), |
| 3681 | 'BJ' => __( 'Benin', 'pods' ), |
| 3682 | 'BM' => __( 'Bermuda', 'pods' ), |
| 3683 | 'BT' => __( 'Bhutan', 'pods' ), |
| 3684 | 'BO' => __( 'Bolivia', 'pods' ), |
| 3685 | 'BA' => __( 'Bosnia and Herzegovina', 'pods' ), |
| 3686 | 'BW' => __( 'Botswana', 'pods' ), |
| 3687 | 'BV' => __( 'Bouvet Island', 'pods' ), |
| 3688 | 'BR' => __( 'Brazil', 'pods' ), |
| 3689 | 'BQ' => __( 'British Antarctic Territory', 'pods' ), |
| 3690 | 'IO' => __( 'British Indian Ocean Territory', 'pods' ), |
| 3691 | 'VG' => __( 'British Virgin Islands', 'pods' ), |
| 3692 | 'BN' => __( 'Brunei', 'pods' ), |
| 3693 | 'BG' => __( 'Bulgaria', 'pods' ), |
| 3694 | 'BF' => __( 'Burkina Faso', 'pods' ), |
| 3695 | 'BI' => __( 'Burundi', 'pods' ), |
| 3696 | 'KH' => __( 'Cambodia', 'pods' ), |
| 3697 | 'CM' => __( 'Cameroon', 'pods' ), |
| 3698 | 'CA' => __( 'Canada', 'pods' ), |
| 3699 | 'CT' => __( 'Canton and Enderbury Islands', 'pods' ), |
| 3700 | 'CV' => __( 'Cape Verde', 'pods' ), |
| 3701 | 'KY' => __( 'Cayman Islands', 'pods' ), |
| 3702 | 'CF' => __( 'Central African Republic', 'pods' ), |
| 3703 | 'TD' => __( 'Chad', 'pods' ), |
| 3704 | 'CL' => __( 'Chile', 'pods' ), |
| 3705 | 'CN' => __( 'China', 'pods' ), |
| 3706 | 'CX' => __( 'Christmas Island', 'pods' ), |
| 3707 | 'CC' => __( 'Cocos [Keeling] Islands', 'pods' ), |
| 3708 | 'CO' => __( 'Colombia', 'pods' ), |
| 3709 | 'KM' => __( 'Comoros', 'pods' ), |
| 3710 | 'CG' => __( 'Congo - Brazzaville', 'pods' ), |
| 3711 | 'CD' => __( 'Congo - Kinshasa', 'pods' ), |
| 3712 | 'CK' => __( 'Cook Islands', 'pods' ), |
| 3713 | 'CR' => __( 'Costa Rica', 'pods' ), |
| 3714 | 'HR' => __( 'Croatia', 'pods' ), |
| 3715 | 'CU' => __( 'Cuba', 'pods' ), |
| 3716 | 'CY' => __( 'Cyprus', 'pods' ), |
| 3717 | 'CZ' => __( 'Czech Republic', 'pods' ), |
| 3718 | 'CI' => __( 'Côte d’Ivoire', 'pods' ), |
| 3719 | 'DK' => __( 'Denmark', 'pods' ), |
| 3720 | 'DJ' => __( 'Djibouti', 'pods' ), |
| 3721 | 'DM' => __( 'Dominica', 'pods' ), |
| 3722 | 'DO' => __( 'Dominican Republic', 'pods' ), |
| 3723 | 'NQ' => __( 'Dronning Maud Land', 'pods' ), |
| 3724 | 'DD' => __( 'East Germany', 'pods' ), |
| 3725 | 'EC' => __( 'Ecuador', 'pods' ), |
| 3726 | 'EG' => __( 'Egypt', 'pods' ), |
| 3727 | 'SV' => __( 'El Salvador', 'pods' ), |
| 3728 | 'GQ' => __( 'Equatorial Guinea', 'pods' ), |
| 3729 | 'ER' => __( 'Eritrea', 'pods' ), |
| 3730 | 'EE' => __( 'Estonia', 'pods' ), |
| 3731 | 'ET' => __( 'Ethiopia', 'pods' ), |
| 3732 | 'FK' => __( 'Falkland Islands', 'pods' ), |
| 3733 | 'FO' => __( 'Faroe Islands', 'pods' ), |
| 3734 | 'FJ' => __( 'Fiji', 'pods' ), |
| 3735 | 'FI' => __( 'Finland', 'pods' ), |
| 3736 | 'FR' => __( 'France', 'pods' ), |
| 3737 | 'GF' => __( 'French Guiana', 'pods' ), |
| 3738 | 'PF' => __( 'French Polynesia', 'pods' ), |
| 3739 | 'TF' => __( 'French Southern Territories', 'pods' ), |
| 3740 | 'FQ' => __( 'French Southern and Antarctic Territories', 'pods' ), |
| 3741 | 'GA' => __( 'Gabon', 'pods' ), |
| 3742 | 'GM' => __( 'Gambia', 'pods' ), |
| 3743 | 'GE' => __( 'Georgia', 'pods' ), |
| 3744 | 'DE' => __( 'Germany', 'pods' ), |
| 3745 | 'GH' => __( 'Ghana', 'pods' ), |
| 3746 | 'GI' => __( 'Gibraltar', 'pods' ), |
| 3747 | 'GR' => __( 'Greece', 'pods' ), |
| 3748 | 'GL' => __( 'Greenland', 'pods' ), |
| 3749 | 'GD' => __( 'Grenada', 'pods' ), |
| 3750 | 'GP' => __( 'Guadeloupe', 'pods' ), |
| 3751 | 'GU' => __( 'Guam', 'pods' ), |
| 3752 | 'GT' => __( 'Guatemala', 'pods' ), |
| 3753 | 'GG' => __( 'Guernsey', 'pods' ), |
| 3754 | 'GN' => __( 'Guinea', 'pods' ), |
| 3755 | 'GW' => __( 'Guinea-Bissau', 'pods' ), |
| 3756 | 'GY' => __( 'Guyana', 'pods' ), |
| 3757 | 'HT' => __( 'Haiti', 'pods' ), |
| 3758 | 'HM' => __( 'Heard Island and McDonald Islands', 'pods' ), |
| 3759 | 'HN' => __( 'Honduras', 'pods' ), |
| 3760 | 'HK' => __( 'Hong Kong SAR China', 'pods' ), |
| 3761 | 'HU' => __( 'Hungary', 'pods' ), |
| 3762 | 'IS' => __( 'Iceland', 'pods' ), |
| 3763 | 'IN' => __( 'India', 'pods' ), |
| 3764 | 'ID' => __( 'Indonesia', 'pods' ), |
| 3765 | 'IR' => __( 'Iran', 'pods' ), |
| 3766 | 'IQ' => __( 'Iraq', 'pods' ), |
| 3767 | 'IE' => __( 'Ireland', 'pods' ), |
| 3768 | 'IM' => __( 'Isle of Man', 'pods' ), |
| 3769 | 'IL' => __( 'Israel', 'pods' ), |
| 3770 | 'IT' => __( 'Italy', 'pods' ), |
| 3771 | 'JM' => __( 'Jamaica', 'pods' ), |
| 3772 | 'JP' => __( 'Japan', 'pods' ), |
| 3773 | 'JE' => __( 'Jersey', 'pods' ), |
| 3774 | 'JT' => __( 'Johnston Island', 'pods' ), |
| 3775 | 'JO' => __( 'Jordan', 'pods' ), |
| 3776 | 'KZ' => __( 'Kazakhstan', 'pods' ), |
| 3777 | 'KE' => __( 'Kenya', 'pods' ), |
| 3778 | 'KI' => __( 'Kiribati', 'pods' ), |
| 3779 | 'KW' => __( 'Kuwait', 'pods' ), |
| 3780 | 'KG' => __( 'Kyrgyzstan', 'pods' ), |
| 3781 | 'LA' => __( 'Laos', 'pods' ), |
| 3782 | 'LV' => __( 'Latvia', 'pods' ), |
| 3783 | 'LB' => __( 'Lebanon', 'pods' ), |
| 3784 | 'LS' => __( 'Lesotho', 'pods' ), |
| 3785 | 'LR' => __( 'Liberia', 'pods' ), |
| 3786 | 'LY' => __( 'Libya', 'pods' ), |
| 3787 | 'LI' => __( 'Liechtenstein', 'pods' ), |
| 3788 | 'LT' => __( 'Lithuania', 'pods' ), |
| 3789 | 'LU' => __( 'Luxembourg', 'pods' ), |
| 3790 | 'MO' => __( 'Macau SAR China', 'pods' ), |
| 3791 | 'MK' => __( 'Macedonia', 'pods' ), |
| 3792 | 'MG' => __( 'Madagascar', 'pods' ), |
| 3793 | 'MW' => __( 'Malawi', 'pods' ), |
| 3794 | 'MY' => __( 'Malaysia', 'pods' ), |
| 3795 | 'MV' => __( 'Maldives', 'pods' ), |
| 3796 | 'ML' => __( 'Mali', 'pods' ), |
| 3797 | 'MT' => __( 'Malta', 'pods' ), |
| 3798 | 'MH' => __( 'Marshall Islands', 'pods' ), |
| 3799 | 'MQ' => __( 'Martinique', 'pods' ), |
| 3800 | 'MR' => __( 'Mauritania', 'pods' ), |
| 3801 | 'MU' => __( 'Mauritius', 'pods' ), |
| 3802 | 'YT' => __( 'Mayotte', 'pods' ), |
| 3803 | 'FX' => __( 'Metropolitan France', 'pods' ), |
| 3804 | 'MX' => __( 'Mexico', 'pods' ), |
| 3805 | 'FM' => __( 'Micronesia', 'pods' ), |
| 3806 | 'MI' => __( 'Midway Islands', 'pods' ), |
| 3807 | 'MD' => __( 'Moldova', 'pods' ), |
| 3808 | 'MC' => __( 'Monaco', 'pods' ), |
| 3809 | 'MN' => __( 'Mongolia', 'pods' ), |
| 3810 | 'ME' => __( 'Montenegro', 'pods' ), |
| 3811 | 'MS' => __( 'Montserrat', 'pods' ), |
| 3812 | 'MA' => __( 'Morocco', 'pods' ), |
| 3813 | 'MZ' => __( 'Mozambique', 'pods' ), |
| 3814 | 'MM' => __( 'Myanmar [Burma]', 'pods' ), |
| 3815 | 'NA' => __( 'Namibia', 'pods' ), |
| 3816 | 'NR' => __( 'Nauru', 'pods' ), |
| 3817 | 'NP' => __( 'Nepal', 'pods' ), |
| 3818 | 'NL' => __( 'Netherlands', 'pods' ), |
| 3819 | 'AN' => __( 'Netherlands Antilles', 'pods' ), |
| 3820 | 'NT' => __( 'Neutral Zone', 'pods' ), |
| 3821 | 'NC' => __( 'New Caledonia', 'pods' ), |
| 3822 | 'NZ' => __( 'New Zealand', 'pods' ), |
| 3823 | 'NI' => __( 'Nicaragua', 'pods' ), |
| 3824 | 'NE' => __( 'Niger', 'pods' ), |
| 3825 | 'NG' => __( 'Nigeria', 'pods' ), |
| 3826 | 'NU' => __( 'Niue', 'pods' ), |
| 3827 | 'NF' => __( 'Norfolk Island', 'pods' ), |
| 3828 | 'KP' => __( 'North Korea', 'pods' ), |
| 3829 | 'VD' => __( 'North Vietnam', 'pods' ), |
| 3830 | 'MP' => __( 'Northern Mariana Islands', 'pods' ), |
| 3831 | 'NO' => __( 'Norway', 'pods' ), |
| 3832 | 'OM' => __( 'Oman', 'pods' ), |
| 3833 | 'PC' => __( 'Pacific Islands Trust Territory', 'pods' ), |
| 3834 | 'PK' => __( 'Pakistan', 'pods' ), |
| 3835 | 'PW' => __( 'Palau', 'pods' ), |
| 3836 | 'PS' => __( 'Palestinian Territories', 'pods' ), |
| 3837 | 'PA' => __( 'Panama', 'pods' ), |
| 3838 | 'PZ' => __( 'Panama Canal Zone', 'pods' ), |
| 3839 | 'PG' => __( 'Papua New Guinea', 'pods' ), |
| 3840 | 'PY' => __( 'Paraguay', 'pods' ), |
| 3841 | 'YD' => __( "People's Democratic Republic of Yemen", 'pods' ), |
| 3842 | 'PE' => __( 'Peru', 'pods' ), |
| 3843 | 'PH' => __( 'Philippines', 'pods' ), |
| 3844 | 'PN' => __( 'Pitcairn Islands', 'pods' ), |
| 3845 | 'PL' => __( 'Poland', 'pods' ), |
| 3846 | 'PT' => __( 'Portugal', 'pods' ), |
| 3847 | 'PR' => __( 'Puerto Rico', 'pods' ), |
| 3848 | 'QA' => __( 'Qatar', 'pods' ), |
| 3849 | 'RO' => __( 'Romania', 'pods' ), |
| 3850 | 'RU' => __( 'Russia', 'pods' ), |
| 3851 | 'RW' => __( 'Rwanda', 'pods' ), |
| 3852 | 'RE' => __( 'Réunion', 'pods' ), |
| 3853 | 'BL' => __( 'Saint Barthélemy', 'pods' ), |
| 3854 | 'SH' => __( 'Saint Helena', 'pods' ), |
| 3855 | 'KN' => __( 'Saint Kitts and Nevis', 'pods' ), |
| 3856 | 'LC' => __( 'Saint Lucia', 'pods' ), |
| 3857 | 'MF' => __( 'Saint Martin', 'pods' ), |
| 3858 | 'PM' => __( 'Saint Pierre and Miquelon', 'pods' ), |
| 3859 | 'VC' => __( 'Saint Vincent and the Grenadines', 'pods' ), |
| 3860 | 'WS' => __( 'Samoa', 'pods' ), |
| 3861 | 'SM' => __( 'San Marino', 'pods' ), |
| 3862 | 'SA' => __( 'Saudi Arabia', 'pods' ), |
| 3863 | 'SN' => __( 'Senegal', 'pods' ), |
| 3864 | 'RS' => __( 'Serbia', 'pods' ), |
| 3865 | 'CS' => __( 'Serbia and Montenegro', 'pods' ), |
| 3866 | 'SC' => __( 'Seychelles', 'pods' ), |
| 3867 | 'SL' => __( 'Sierra Leone', 'pods' ), |
| 3868 | 'SG' => __( 'Singapore', 'pods' ), |
| 3869 | 'SK' => __( 'Slovakia', 'pods' ), |
| 3870 | 'SI' => __( 'Slovenia', 'pods' ), |
| 3871 | 'SB' => __( 'Solomon Islands', 'pods' ), |
| 3872 | 'SO' => __( 'Somalia', 'pods' ), |
| 3873 | 'ZA' => __( 'South Africa', 'pods' ), |
| 3874 | 'GS' => __( 'South Georgia and the South Sandwich Islands', 'pods' ), |
| 3875 | 'KR' => __( 'South Korea', 'pods' ), |
| 3876 | 'ES' => __( 'Spain', 'pods' ), |
| 3877 | 'LK' => __( 'Sri Lanka', 'pods' ), |
| 3878 | 'SD' => __( 'Sudan', 'pods' ), |
| 3879 | 'SR' => __( 'Suriname', 'pods' ), |
| 3880 | 'SJ' => __( 'Svalbard and Jan Mayen', 'pods' ), |
| 3881 | 'SZ' => __( 'Swaziland', 'pods' ), |
| 3882 | 'SE' => __( 'Sweden', 'pods' ), |
| 3883 | 'CH' => __( 'Switzerland', 'pods' ), |
| 3884 | 'SY' => __( 'Syria', 'pods' ), |
| 3885 | 'ST' => __( 'São Tomé and Príncipe', 'pods' ), |
| 3886 | 'TW' => __( 'Taiwan', 'pods' ), |
| 3887 | 'TJ' => __( 'Tajikistan', 'pods' ), |
| 3888 | 'TZ' => __( 'Tanzania', 'pods' ), |
| 3889 | 'TH' => __( 'Thailand', 'pods' ), |
| 3890 | 'TL' => __( 'Timor-Leste', 'pods' ), |
| 3891 | 'TG' => __( 'Togo', 'pods' ), |
| 3892 | 'TK' => __( 'Tokelau', 'pods' ), |
| 3893 | 'TO' => __( 'Tonga', 'pods' ), |
| 3894 | 'TT' => __( 'Trinidad and Tobago', 'pods' ), |
| 3895 | 'TN' => __( 'Tunisia', 'pods' ), |
| 3896 | 'TR' => __( 'Turkey', 'pods' ), |
| 3897 | 'TM' => __( 'Turkmenistan', 'pods' ), |
| 3898 | 'TC' => __( 'Turks and Caicos Islands', 'pods' ), |
| 3899 | 'TV' => __( 'Tuvalu', 'pods' ), |
| 3900 | 'UM' => __( 'U.S. Minor Outlying Islands', 'pods' ), |
| 3901 | 'PU' => __( 'U.S. Miscellaneous Pacific Islands', 'pods' ), |
| 3902 | 'VI' => __( 'U.S. Virgin Islands', 'pods' ), |
| 3903 | 'UG' => __( 'Uganda', 'pods' ), |
| 3904 | 'UA' => __( 'Ukraine', 'pods' ), |
| 3905 | 'SU' => __( 'Union of Soviet Socialist Republics', 'pods' ), |
| 3906 | 'AE' => __( 'United Arab Emirates', 'pods' ), |
| 3907 | 'GB' => __( 'United Kingdom', 'pods' ), |
| 3908 | 'US' => __( 'United States', 'pods' ), |
| 3909 | 'ZZ' => __( 'Unknown or Invalid Region', 'pods' ), |
| 3910 | 'UY' => __( 'Uruguay', 'pods' ), |
| 3911 | 'UZ' => __( 'Uzbekistan', 'pods' ), |
| 3912 | 'VU' => __( 'Vanuatu', 'pods' ), |
| 3913 | 'VA' => __( 'Vatican City', 'pods' ), |
| 3914 | 'VE' => __( 'Venezuela', 'pods' ), |
| 3915 | 'VN' => __( 'Vietnam', 'pods' ), |
| 3916 | 'WK' => __( 'Wake Island', 'pods' ), |
| 3917 | 'WF' => __( 'Wallis and Futuna', 'pods' ), |
| 3918 | 'EH' => __( 'Western Sahara', 'pods' ), |
| 3919 | 'YE' => __( 'Yemen', 'pods' ), |
| 3920 | 'ZM' => __( 'Zambia', 'pods' ), |
| 3921 | 'ZW' => __( 'Zimbabwe', 'pods' ), |
| 3922 | 'AX' => __( '� |
| 3923 | land Islands', 'pods' ), |
| 3924 | ]; |
| 3925 | |
| 3926 | return apply_filters( 'pods_form_ui_field_pick_data_countries', $data, $name, $value, $options, $pod, $id ); |
| 3927 | |
| 3928 | } |
| 3929 | |
| 3930 | /** |
| 3931 | * Data callback for US States. |
| 3932 | * |
| 3933 | * @param string|null $name The name of the field. |
| 3934 | * @param string|array|null $value The value of the field. |
| 3935 | * @param array|null $options Field options. |
| 3936 | * @param array|null $pod Pod data. |
| 3937 | * @param int|null $id Item ID. |
| 3938 | * |
| 3939 | * @return array |
| 3940 | * |
| 3941 | * @since 2.3.0 |
| 3942 | */ |
| 3943 | public function data_us_states( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 3944 | |
| 3945 | $data = [ |
| 3946 | 'AL' => __( 'Alabama', 'pods' ), |
| 3947 | 'AK' => __( 'Alaska', 'pods' ), |
| 3948 | 'AZ' => __( 'Arizona', 'pods' ), |
| 3949 | 'AR' => __( 'Arkansas', 'pods' ), |
| 3950 | 'CA' => __( 'California', 'pods' ), |
| 3951 | 'CO' => __( 'Colorado', 'pods' ), |
| 3952 | 'CT' => __( 'Connecticut', 'pods' ), |
| 3953 | 'DE' => __( 'Delaware', 'pods' ), |
| 3954 | 'DC' => __( 'District Of Columbia', 'pods' ), |
| 3955 | 'FL' => __( 'Florida', 'pods' ), |
| 3956 | 'GA' => __( 'Georgia', 'pods' ), |
| 3957 | 'HI' => __( 'Hawaii', 'pods' ), |
| 3958 | 'ID' => __( 'Idaho', 'pods' ), |
| 3959 | 'IL' => __( 'Illinois', 'pods' ), |
| 3960 | 'IN' => __( 'Indiana', 'pods' ), |
| 3961 | 'IA' => __( 'Iowa', 'pods' ), |
| 3962 | 'KS' => __( 'Kansas', 'pods' ), |
| 3963 | 'KY' => __( 'Kentucky', 'pods' ), |
| 3964 | 'LA' => __( 'Louisiana', 'pods' ), |
| 3965 | 'ME' => __( 'Maine', 'pods' ), |
| 3966 | 'MD' => __( 'Maryland', 'pods' ), |
| 3967 | 'MA' => __( 'Massachusetts', 'pods' ), |
| 3968 | 'MI' => __( 'Michigan', 'pods' ), |
| 3969 | 'MN' => __( 'Minnesota', 'pods' ), |
| 3970 | 'MS' => __( 'Mississippi', 'pods' ), |
| 3971 | 'MO' => __( 'Missouri', 'pods' ), |
| 3972 | 'MT' => __( 'Montana', 'pods' ), |
| 3973 | 'NE' => __( 'Nebraska', 'pods' ), |
| 3974 | 'NV' => __( 'Nevada', 'pods' ), |
| 3975 | 'NH' => __( 'New Hampshire', 'pods' ), |
| 3976 | 'NJ' => __( 'New Jersey', 'pods' ), |
| 3977 | 'NM' => __( 'New Mexico', 'pods' ), |
| 3978 | 'NY' => __( 'New York', 'pods' ), |
| 3979 | 'NC' => __( 'North Carolina', 'pods' ), |
| 3980 | 'ND' => __( 'North Dakota', 'pods' ), |
| 3981 | 'OH' => __( 'Ohio', 'pods' ), |
| 3982 | 'OK' => __( 'Oklahoma', 'pods' ), |
| 3983 | 'OR' => __( 'Oregon', 'pods' ), |
| 3984 | 'PA' => __( 'Pennsylvania', 'pods' ), |
| 3985 | 'RI' => __( 'Rhode Island', 'pods' ), |
| 3986 | 'SC' => __( 'South Carolina', 'pods' ), |
| 3987 | 'SD' => __( 'South Dakota', 'pods' ), |
| 3988 | 'TN' => __( 'Tennessee', 'pods' ), |
| 3989 | 'TX' => __( 'Texas', 'pods' ), |
| 3990 | 'UT' => __( 'Utah', 'pods' ), |
| 3991 | 'VT' => __( 'Vermont', 'pods' ), |
| 3992 | 'VA' => __( 'Virginia', 'pods' ), |
| 3993 | 'WA' => __( 'Washington', 'pods' ), |
| 3994 | 'WV' => __( 'West Virginia', 'pods' ), |
| 3995 | 'WI' => __( 'Wisconsin', 'pods' ), |
| 3996 | 'WY' => __( 'Wyoming', 'pods' ), |
| 3997 | ]; |
| 3998 | |
| 3999 | return apply_filters( 'pods_form_ui_field_pick_data_us_states', $data, $name, $value, $options, $pod, $id ); |
| 4000 | |
| 4001 | } |
| 4002 | |
| 4003 | /** |
| 4004 | * Data callback for CA Provinces. |
| 4005 | * |
| 4006 | * @param string|null $name The name of the field. |
| 4007 | * @param string|array|null $value The value of the field. |
| 4008 | * @param array|null $options Field options. |
| 4009 | * @param array|null $pod Pod data. |
| 4010 | * @param int|null $id Item ID. |
| 4011 | * |
| 4012 | * @return array |
| 4013 | * |
| 4014 | * @since 2.3.0 |
| 4015 | */ |
| 4016 | public function data_ca_provinces( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 4017 | |
| 4018 | $data = [ |
| 4019 | 'AB' => __( 'Alberta', 'pods' ), |
| 4020 | 'BC' => __( 'British Columbia', 'pods' ), |
| 4021 | 'MB' => __( 'Manitoba', 'pods' ), |
| 4022 | 'NB' => __( 'New Brunswick', 'pods' ), |
| 4023 | 'NL' => __( 'Newfoundland and Labrador', 'pods' ), |
| 4024 | 'NT' => __( 'Northwest Territories', 'pods' ), |
| 4025 | 'NS' => __( 'Nova Scotia', 'pods' ), |
| 4026 | 'NU' => __( 'Nunavut', 'pods' ), |
| 4027 | 'ON' => __( 'Ontario', 'pods' ), |
| 4028 | 'PE' => __( 'Prince Edward Island', 'pods' ), |
| 4029 | 'QC' => __( 'Quebec', 'pods' ), |
| 4030 | 'SK' => __( 'Saskatchewan', 'pods' ), |
| 4031 | 'YT' => __( 'Yukon', 'pods' ), |
| 4032 | ]; |
| 4033 | |
| 4034 | return apply_filters( 'pods_form_ui_field_pick_data_ca_provinces', $data, $name, $value, $options, $pod, $id ); |
| 4035 | |
| 4036 | } |
| 4037 | |
| 4038 | /** |
| 4039 | * Data callback for Days of the Week. |
| 4040 | * |
| 4041 | * @param string|null $name The name of the field. |
| 4042 | * @param string|array|null $value The value of the field. |
| 4043 | * @param array|null $options Field options. |
| 4044 | * @param array|null $pod Pod data. |
| 4045 | * @param int|null $id Item ID. |
| 4046 | * |
| 4047 | * @return array |
| 4048 | * |
| 4049 | * @since 2.3.0 |
| 4050 | */ |
| 4051 | public function data_days_of_week( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 4052 | |
| 4053 | /** |
| 4054 | * @var WP_Locale |
| 4055 | */ |
| 4056 | global $wp_locale; |
| 4057 | |
| 4058 | return $wp_locale->weekday; |
| 4059 | |
| 4060 | } |
| 4061 | |
| 4062 | /** |
| 4063 | * Data callback for Months of the Year. |
| 4064 | * |
| 4065 | * @param string|null $name The name of the field. |
| 4066 | * @param string|array|null $value The value of the field. |
| 4067 | * @param array|null $options Field options. |
| 4068 | * @param array|null $pod Pod data. |
| 4069 | * @param int|null $id Item ID. |
| 4070 | * |
| 4071 | * @return array |
| 4072 | * |
| 4073 | * @since 2.3.0 |
| 4074 | */ |
| 4075 | public function data_months_of_year( $name = null, $value = null, $options = null, $pod = null, $id = null ) { |
| 4076 | |
| 4077 | /** |
| 4078 | * @var WP_Locale |
| 4079 | */ |
| 4080 | global $wp_locale; |
| 4081 | |
| 4082 | return $wp_locale->month; |
| 4083 | |
| 4084 | } |
| 4085 | |
| 4086 | /** |
| 4087 | * Add our modal input to the form so we can track whether we're in our modal during saving or not. |
| 4088 | */ |
| 4089 | public function admin_modal_input() { |
| 4090 | |
| 4091 | if ( ! pods_is_modal_window() ) { |
| 4092 | return; |
| 4093 | } |
| 4094 | |
| 4095 | echo '<input name="pods_modal" type="hidden" value="1" />'; |
| 4096 | |
| 4097 | } |
| 4098 | |
| 4099 | /** |
| 4100 | * Bail to send new saved data back to our modal handler. |
| 4101 | * |
| 4102 | * @param int $item_id Item ID. |
| 4103 | * @param string $item_title Item title. |
| 4104 | * @param object $field_args Field arguments. |
| 4105 | */ |
| 4106 | public function admin_modal_bail( $item_id, $item_title, $field_args ) { |
| 4107 | |
| 4108 | $model_data = $this->build_dfv_field_item_data_recurse_item( $item_id, $item_title, $field_args ); |
| 4109 | ?> |
| 4110 | <script type="text/javascript"> |
| 4111 | window.parent.postMessage( { |
| 4112 | type: 'PODS_MESSAGE', |
| 4113 | data: <?php echo wp_json_encode( $model_data, JSON_HEX_TAG ); ?>, |
| 4114 | }, window.location.origin ); |
| 4115 | </script> |
| 4116 | <?php |
| 4117 | |
| 4118 | die(); |
| 4119 | |
| 4120 | } |
| 4121 | |
| 4122 | /** |
| 4123 | * Bail to send new saved data back to our modal handler. |
| 4124 | * |
| 4125 | * @param int $item_id Item ID. |
| 4126 | * @param string $item_title Item title. |
| 4127 | * @param object $field_args Field arguments. |
| 4128 | */ |
| 4129 | public function admin_modal_bail_JSON( $item_id, $item_title, $field_args ) { |
| 4130 | |
| 4131 | $model_data = $this->build_dfv_field_item_data_recurse_item( $item_id, $item_title, $field_args ); |
| 4132 | echo wp_json_encode( $model_data, JSON_HEX_TAG ); |
| 4133 | |
| 4134 | die(); |
| 4135 | } |
| 4136 | |
| 4137 | /** |
| 4138 | * Bail on Post save redirect for Admin modal. |
| 4139 | * |
| 4140 | * @param string $location The destination URL. |
| 4141 | * @param int $post_id The post ID. |
| 4142 | * |
| 4143 | * @return string |
| 4144 | */ |
| 4145 | public function admin_modal_bail_post_redirect( $location, $post_id ) { |
| 4146 | |
| 4147 | if ( ! pods_is_modal_window() ) { |
| 4148 | return $location; |
| 4149 | } |
| 4150 | |
| 4151 | $post_title = get_the_title( $post_id ); |
| 4152 | |
| 4153 | $field_args = (object) [ |
| 4154 | 'options' => [ |
| 4155 | 'pick_object' => 'post_type', |
| 4156 | 'pick_val' => get_post_type( $post_id ), |
| 4157 | ], |
| 4158 | 'value' => [ |
| 4159 | $post_id => $post_title, |
| 4160 | ], |
| 4161 | ]; |
| 4162 | |
| 4163 | $this->admin_modal_bail( $post_id, $post_title, $field_args ); |
| 4164 | |
| 4165 | return $location; |
| 4166 | |
| 4167 | } |
| 4168 | |
| 4169 | /** |
| 4170 | * Hook into term updating process to bail on redirect. |
| 4171 | */ |
| 4172 | public function admin_modal_bail_term_action() { |
| 4173 | |
| 4174 | if ( ! pods_is_modal_window() ) { |
| 4175 | return; |
| 4176 | } |
| 4177 | |
| 4178 | if ( function_exists( 'get_current_screen' ) ) { |
| 4179 | $screen = get_current_screen(); |
| 4180 | |
| 4181 | if ( 'edit-tags' === $screen->base ) { |
| 4182 | // @todo Need more effort on the solution for add new handling. |
| 4183 | //add_action( 'admin_footer', [ $this, 'admin_modal_bail_term_action_add_new' ], 20 ); |
| 4184 | } |
| 4185 | } |
| 4186 | |
| 4187 | add_action( 'created_term', [ $this, 'admin_modal_bail_term' ], 10, 3 ); |
| 4188 | add_action( 'edited_term', [ $this, 'admin_modal_bail_term' ], 10, 3 ); |
| 4189 | |
| 4190 | } |
| 4191 | |
| 4192 | /** |
| 4193 | * Hook into term creation process to bail after success. |
| 4194 | * |
| 4195 | * @todo Try and catch the added tr node on the table tbody. |
| 4196 | */ |
| 4197 | public function admin_modal_bail_term_action_add_new() { |
| 4198 | ?> |
| 4199 | <script type="text/javascript"> |
| 4200 | jQuery( function( $ ) { |
| 4201 | /** @var {jQuery.Event} e */ |
| 4202 | $( '.tags' ).on( 'DOMSubtreeModified', function( e ) { |
| 4203 | console.log( e ); |
| 4204 | |
| 4205 | if ( !== |
| 4206 | e.target.is( 'tbody#the-list' ); |
| 4207 | ) |
| 4208 | { |
| 4209 | return; |
| 4210 | } |
| 4211 | |
| 4212 | const $theTermRow = $( e.target.innerHTML() ); |
| 4213 | const titleRow = $theTermRow.find( '.column-name .row-title' ); |
| 4214 | const actionView = $theTermRow.find( '.row-actions span.view a' ); |
| 4215 | |
| 4216 | const termData = { |
| 4217 | id: $theTermRow.find( '.check-column input' ).val(), |
| 4218 | icon: '', |
| 4219 | name: titleRow.text(), |
| 4220 | edit_link: titleRow.prop( 'href' ), |
| 4221 | link: actionView[ 0 ] ? actionView.prop( 'href' ) : '', |
| 4222 | selected: true, |
| 4223 | }; |
| 4224 | |
| 4225 | console.log( termData ); |
| 4226 | |
| 4227 | window.parent.postMessage( { |
| 4228 | type: 'PODS_MESSAGE', |
| 4229 | data: termData, |
| 4230 | }, window.location.origin ); |
| 4231 | } ); |
| 4232 | } ); |
| 4233 | </script> |
| 4234 | <?php |
| 4235 | } |
| 4236 | |
| 4237 | /** |
| 4238 | * Bail on Term save redirect for Admin modal. |
| 4239 | * |
| 4240 | * @param int $term_id Term ID. |
| 4241 | * @param int $tt_id Term taxonomy ID. |
| 4242 | * @param string $taxonomy Taxonomy slug. |
| 4243 | */ |
| 4244 | public function admin_modal_bail_term( $term_id, $tt_id, $taxonomy ) { |
| 4245 | |
| 4246 | if ( ! pods_is_modal_window() ) { |
| 4247 | return; |
| 4248 | } |
| 4249 | |
| 4250 | $term = get_term( $term_id ); |
| 4251 | |
| 4252 | if ( ! $term || is_wp_error( $term ) ) { |
| 4253 | return; |
| 4254 | } |
| 4255 | |
| 4256 | $field_args = (object) [ |
| 4257 | 'options' => [ |
| 4258 | 'pick_object' => 'taxonomy', |
| 4259 | 'pick_val' => $term->taxonomy, |
| 4260 | ], |
| 4261 | 'value' => [ |
| 4262 | $term->term_id => $term->name, |
| 4263 | ], |
| 4264 | ]; |
| 4265 | |
| 4266 | $this->admin_modal_bail( $term->term_id, $term->name, $field_args ); |
| 4267 | |
| 4268 | } |
| 4269 | |
| 4270 | /** |
| 4271 | * Hook into user updating process to bail on redirect. |
| 4272 | */ |
| 4273 | public function admin_modal_bail_user_action() { |
| 4274 | |
| 4275 | if ( ! pods_is_modal_window() ) { |
| 4276 | return; |
| 4277 | } |
| 4278 | |
| 4279 | add_filter( 'wp_redirect', [ $this, 'admin_modal_bail_user_redirect' ] ); |
| 4280 | |
| 4281 | } |
| 4282 | |
| 4283 | /** |
| 4284 | * Bail on User save redirect for Admin modal. |
| 4285 | * |
| 4286 | * @param string $location The destination URL. |
| 4287 | * |
| 4288 | * @return string |
| 4289 | */ |
| 4290 | public function admin_modal_bail_user_redirect( $location ) { |
| 4291 | |
| 4292 | if ( ! pods_is_modal_window() ) { |
| 4293 | return $location; |
| 4294 | } |
| 4295 | |
| 4296 | global $user_id; |
| 4297 | |
| 4298 | $user = get_userdata( $user_id ); |
| 4299 | |
| 4300 | if ( ! $user ) { |
| 4301 | return $location; |
| 4302 | } |
| 4303 | |
| 4304 | $field_args = (object) [ |
| 4305 | 'options' => [ |
| 4306 | 'pick_object' => 'user', |
| 4307 | 'pick_val' => '', |
| 4308 | ], |
| 4309 | 'value' => [ |
| 4310 | $user->ID => $user->display_name, |
| 4311 | ], |
| 4312 | ]; |
| 4313 | |
| 4314 | $this->admin_modal_bail( $user->ID, $user->display_name, $field_args ); |
| 4315 | |
| 4316 | return $location; |
| 4317 | |
| 4318 | } |
| 4319 | |
| 4320 | /** |
| 4321 | * Bail on Pod item save for Admin modal. |
| 4322 | * |
| 4323 | * @param int $id Item ID. |
| 4324 | * @param array $params save_pod_item parameters. |
| 4325 | * @param null|Pods $obj Pod object (if set). |
| 4326 | */ |
| 4327 | public function admin_modal_bail_pod( $id, $params, $obj ) { |
| 4328 | |
| 4329 | if ( ! pods_is_modal_window() ) { |
| 4330 | return; |
| 4331 | } |
| 4332 | |
| 4333 | if ( ! $obj ) { |
| 4334 | $obj = pods_get_instance( $params['pod'] ); |
| 4335 | } |
| 4336 | |
| 4337 | if ( ! $obj || ! $obj->fetch( $id ) ) { |
| 4338 | return; |
| 4339 | } |
| 4340 | |
| 4341 | $item_id = $obj->id(); |
| 4342 | $item_title = $obj->index(); |
| 4343 | |
| 4344 | $field_args = (object) [ |
| 4345 | 'options' => [ |
| 4346 | 'pick_object' => $obj->pod_data['type'], |
| 4347 | 'pick_val' => $obj->pod, |
| 4348 | ], |
| 4349 | 'value' => [ |
| 4350 | $obj->id() => $item_title, |
| 4351 | ], |
| 4352 | ]; |
| 4353 | |
| 4354 | $this->admin_modal_bail_JSON( $item_id, $item_title, $field_args ); |
| 4355 | |
| 4356 | } |
| 4357 | |
| 4358 | /** |
| 4359 | * Build field data for Pods DFV. |
| 4360 | * |
| 4361 | * @param object $args { |
| 4362 | * Field information arguments. |
| 4363 | * |
| 4364 | * @type string $name Field name. |
| 4365 | * @type string $type Field type. |
| 4366 | * @type array $options Field options. |
| 4367 | * @type mixed $value Current value. |
| 4368 | * @type array $pod Pod information. |
| 4369 | * @type int|string $id Current item ID. |
| 4370 | * @type string $form_field_type HTML field type. |
| 4371 | * } |
| 4372 | * |
| 4373 | * @return array |
| 4374 | */ |
| 4375 | public function build_dfv_field_data( $args ) { |
| 4376 | $data = parent::build_dfv_field_data( $args ); |
| 4377 | |
| 4378 | // Normalize arrays for multiple select. |
| 4379 | if ( is_array( $data['fieldValue'] ) ) { |
| 4380 | $data['fieldValue'] = array_values( $data['fieldValue'] ); |
| 4381 | } |
| 4382 | |
| 4383 | return $data; |
| 4384 | } |
| 4385 | |
| 4386 | } |
| 4387 |