| @@ -294,8 +294,23 @@ | ||
| 294 | 294 | }//end foreach |
| 295 | 295 | |
| 296 | 296 | self::maybe_update_child_form_parent_id( $imported['forms'], $child_forms ); |
| 297 | 297 | |
| 298 | + /** | |
| 299 | + * Fires after all forms in the XML have been imported. | |
| 300 | + * | |
| 301 | + * Child forms are imported before their parent form, so per-form fix-ups | |
| 302 | + * cannot resolve conditional logic that references fields in a form | |
| 303 | + * imported later. Use this action for cross-form fix-ups that require | |
| 304 | + * the fully populated `$frm_duplicate_ids` map. | |
| 305 | + * | |
| 306 | + * @since 6.31 | |
| 307 | + * | |
| 308 | + * @param array $imported Summary of imported items, including | |
| 309 | + * 'forms' => array( old_form_id => new_form_id ). | |
| 310 | + */ | |
| 311 | + do_action( 'frm_after_import_forms', $imported ); | |
| 312 | + | |
| 298 | 313 | return $imported; |
| 299 | 314 | } |
| 300 | 315 | |
| 301 | 316 | /** |
| @@ -604,10 +619,37 @@ | ||
| 604 | 619 | 'field_order' => (int) $field->field_order, |
| 605 | 620 | 'form_id' => (int) $form_id, |
| 606 | 621 | 'required' => (int) $field->required, |
| 607 | 622 | 'options' => FrmAppHelper::maybe_json_decode( (string) $field->options ), |
| 608 | - 'field_options' => FrmAppHelper::maybe_json_decode( (string) $field->field_options ), | |
| 623 | + 'field_options' => self::fill_field_options( $field ), | |
| 609 | 624 | ); |
| 625 | + } | |
| 626 | + | |
| 627 | + /** | |
| 628 | + * Reads a field's options out of the file as an array. | |
| 629 | + * | |
| 630 | + * Field options are a settings map, and every step of the import reads them | |
| 631 | + * as one. A file whose value there cannot be read, because it is empty or | |
| 632 | + * was written by something other than an export, used to end the whole | |
| 633 | + * import with a fatal error on the first field it reached. An empty set of | |
| 634 | + * options is recoverable, since the defaults for the field type fill the | |
| 635 | + * gaps, so prefer that over stopping. | |
| 636 | + * | |
| 637 | + * Unserialize is tried as well as JSON so options written by an older | |
| 638 | + * version are still read rather than thrown away. | |
| 639 | + * | |
| 640 | + * @since 6.35 | |
| 641 | + * | |
| 642 | + * @param object $field Field element from the file. | |
| 643 | + * | |
| 644 | + * @return array | |
| 645 | + */ | |
| 646 | + private static function fill_field_options( $field ) { | |
| 647 | + $options = (string) $field->field_options; | |
| 648 | + | |
| 649 | + FrmAppHelper::unserialize_or_decode( $options ); | |
| 650 | + | |
| 651 | + return is_array( $options ) ? $options : array(); | |
| 610 | 652 | } |
| 611 | 653 | |
| 612 | 654 | /** |
| 613 | 655 | * @since 4.06 |