From 0da4b5f2368e5d270eba04efbfdc370ba436399d Mon Sep 17 00:00:00 2001 From: Scott Kingsley Clark Date: Mon, 13 Jun 2016 09:56:32 -0500 Subject: [PATCH] Pods GF 1.1 --- includes/Pods_GF.php | 257 ++++++++++++++++++++++++++----------- includes/Pods_GF_Addon.php | 19 ++- includes/Pods_GF_UI.php | 2 +- includes/functions.php | 2 +- pods-gravity-forms.php | 4 +- readme.txt | 16 ++- 6 files changed, 217 insertions(+), 83 deletions(-) mode change 100644 => 100755 includes/Pods_GF_Addon.php mode change 100644 => 100755 includes/Pods_GF_UI.php diff --git a/includes/Pods_GF.php b/includes/Pods_GF.php index b7bce8e..761f7ca 100644 --- a/includes/Pods_GF.php +++ b/includes/Pods_GF.php @@ -5,32 +5,32 @@ class Pods_GF { /** - * GF Actions / Filters that have already run + * Instances of Pods_GF * - * @var array + * @var Pods_GF[] */ - public static $actioned = array(); + private static $instances = array(); /** - * Last ID for inserted item added by GF to Pods mapping + * Pods object or GF entry * - * @var int + * @var Pods|array */ - public static $gf_to_pods_id = 0; + public $pod; /** - * Pods object + * Item ID * - * @var Pods + * @var int */ - public $pod; + public $id; /** - * Item ID + * Entry ID (if editing an GF entry or just saved one) * * @var int */ - public $id; + public $entry_id; /** * GF Form ID @@ -53,12 +53,26 @@ class Pods_GF { */ public $gf_validation_message; + /** + * GF Actions / Filters that have already run + * + * @var array + */ + public static $actioned = array(); + + /** + * Last ID for inserted item added by GF to Pods mapping + * + * @var int[] + */ + public static $gf_to_pods_id = array(); + /** * To keep or delete files when deleting GF entries * - * @var bool + * @var bool[] */ - public static $keep_files = false; + public static $keep_files = array(); /** * Array of options for Dynamic Select @@ -109,6 +123,27 @@ class Pods_GF { */ public static $read_only = array(); + /** + * Get Pods_GF instance unique to $form_id + * + * @param $pod + * @param $form_id + * @param $options + * + * @return Pods_GF + */ + public static function get_instance( $pod, $form_id, $options ) { + + if ( ! isset( self::$instances[ $form_id ] ) ) { + self::$instances[ $form_id ] = new self( $pod, $form_id ); + } + + self::$instances[ $form_id ]->setup_options( $options ); + + return self::$instances[ $form_id ]; + + } + /** * Add Pods GF integration for a specific form * @@ -116,7 +151,7 @@ class Pods_GF { * @param int $form_id GF Form ID * @param array $options Form options for integration */ - public function __construct ( $pod, $form_id, $options = array() ) { + private function __construct ( $pod, $form_id ) { // Pod object if ( is_object( $pod ) ) { @@ -130,12 +165,27 @@ public function __construct ( $pod, $form_id, $options = array() ) { } // GF entry elseif ( isset( $pod['id'] ) ) { - $this->pod = $pod; - $this->id = $pod['id']; + $this->pod = $pod; + $this->id = $pod['id']; + $this->entry_id = $this->id; } $this->form_id = $form_id; - $this->options = $options; + + } + + /** + * Setup options for Pods_GF + * + * @param array $options + */ + public function setup_options( $options ) { + + // Merge options together + $this->options = array_merge( $this->options, $options ); + + $form_id = $this->form_id; + $options = $this->options; if ( ! wp_script_is( 'pods-gf', 'registered' ) ) { wp_register_script( 'pods-gf', PODS_GF_URL . 'ui/pods-gf.js', array( 'jquery' ), PODS_GF_VERSION, true ); @@ -146,11 +196,11 @@ public function __construct ( $pod, $form_id, $options = array() ) { } // Save for Later setup - if ( isset( $this->options['save_for_later'] ) && ! empty( $this->options['save_for_later'] ) ) { - self::save_for_later( $form_id, $this->options['save_for_later'] ); + if ( isset( $options['save_for_later'] ) && ! empty( $options['save_for_later'] ) ) { + self::save_for_later( $form_id, $options['save_for_later'] ); } - if ( ! pods_v( 'admin', $this->options, 0 ) && ( is_admin() && RGForms::is_gravity_page() ) ) { + if ( ! pods_v( 'admin', $options, 0 ) && ( is_admin() && RGForms::is_gravity_page() ) ) { return; } @@ -166,8 +216,8 @@ public function __construct ( $pod, $form_id, $options = array() ) { add_filter( 'gform_validation_' . $form_id, array( $this, '_gf_validation' ), 11, 1 ); add_filter( 'gform_validation_message_' . $form_id, array( $this, '_gf_validation_message' ), 11, 2 ); - if ( isset( $this->options['fields'] ) && ! empty( $this->options['fields'] ) ) { - foreach ( $this->options['fields'] as $field => $field_options ) { + if ( isset( $options['fields'] ) && ! empty( $options['fields'] ) ) { + foreach ( $options['fields'] as $field => $field_options ) { if ( is_array( $field_options ) && isset( $field_options['gf_field'] ) ) { $field = $field_options['gf_field']; } @@ -180,12 +230,12 @@ public function __construct ( $pod, $form_id, $options = array() ) { } // Confirmation handling - if ( isset( $this->options['confirmation'] ) && ! empty( $this->options['confirmation'] ) ) { - self::confirmation( $form_id, $this->options['confirmation'] ); + if ( isset( $options['confirmation'] ) && ! empty( $options['confirmation'] ) ) { + self::confirmation( $form_id, $options['confirmation'] ); } // Read Only handling - if ( isset( $this->options['read_only'] ) && ! empty( $this->options['read_only'] ) ) { + if ( isset( $options['read_only'] ) && ! empty( $options['read_only'] ) ) { if ( ! has_filter( 'gform_pre_submission_filter_' . $form_id, array( 'Pods_GF', 'gf_read_only_pre_submission' ) ) ) { add_filter( 'gform_pre_submission_filter_' . $form_id, array( 'Pods_GF', 'gf_read_only_pre_submission' ), 10, 1 ); } @@ -623,7 +673,7 @@ public static function condition_validate_value ( $condition, $value ) { public static function auto_delete ( $form_id = null, $keep_files = null ) { if ( null !== $keep_files ) { - self::$keep_files = (boolean) $keep_files; + self::$keep_files[ $form_id ] = (boolean) $keep_files; } $form = ( ! empty( $form_id ) ? '_' . (int) $form_id : '' ); @@ -1301,23 +1351,27 @@ public static function gf_remember_save ( $entry, $form ) { */ public function _gf_to_pods_handler( $form ) { - $id = (int) pods_v( 'id', $this->pod, 0 ); - - $save_action = 'add'; + $id = 0; - if ( ! empty( $id ) ) { - $save_action = 'edit'; + if ( isset( $this->options['edit'] ) && $this->options['edit'] ) { + $id = $this->get_current_id(); } if ( isset( $this->options['save_id'] ) && ! empty( $this->options['save_id'] ) ) { $id = (int) $this->options['save_id']; } + $save_action = 'add'; + + if ( ! empty( $id ) ) { + $save_action = 'save'; + } + if ( isset( $this->options['save_action'] ) ) { $save_action = $this->options['save_action']; } - if ( empty( $id ) || !in_array( $save_action, array( 'add', 'save', 'bypass' ) ) ) { + if ( empty( $id ) || ! in_array( $save_action, array( 'add', 'save', 'bypass' ) ) ) { $save_action = 'add'; } @@ -1332,11 +1386,21 @@ public function _gf_to_pods_handler( $form ) { ); if ( 'save' == $save_action ) { - $args[] = null; // Value - $args[] = $id; // ID + $args[1] = null; // Value + $args[2] = $id; // ID } if ( is_object( $this->pod ) ) { + if ( ! empty( $this->pod->data->field_id ) && ! empty( $data[ $this->pod->data->field_id ] ) ) { + $save_action = 'save'; + + $args[1] = null; // Value + $args[2] = $data[ $this->pod->data->field_id ]; // ID + + // Remove field, not saving it + unset( $data[ $this->pod->data->field_id ] ); + } + if ( 'post_type' == $this->pod->pod_data['type'] ) { if ( ! empty( $form['postStatus'] ) && empty( $args[0]['post_status'] ) ) { $args[0]['post_status'] = $form['postStatus']; @@ -1355,10 +1419,12 @@ public function _gf_to_pods_handler( $form ) { } } - $id = call_user_func_array( array( $this->pod, $save_action ), $args ); + if ( ! empty( $this->pod->pod_data ) ) { + $id = call_user_func_array( array( $this->pod, $save_action ), $args ); - $this->pod->id = $id; - $this->pod->fetch( $id ); + $this->pod->id = $id; + $this->pod->fetch( $id ); + } do_action( 'pods_gf_to_pods_' . $form['id'] . '_' . $this->pod->pod, $this->pod, $args, $save_action, $data, $id, $this ); do_action( 'pods_gf_to_pods_' . $this->pod->pod, $this->pod, $args, $save_action, $data, $id, $this ); @@ -1369,7 +1435,7 @@ public function _gf_to_pods_handler( $form ) { $this->id = $id = apply_filters( 'pods_gf_to_pod_' . $save_action, $id, $this->pod, $data, $this ); } - self::$gf_to_pods_id = $id; + self::$gf_to_pods_id[ $this->form_id ] = $id; do_action( 'pods_gf_to_pods', $this->pod, $save_action, $data, $id, $this ); @@ -1890,9 +1956,11 @@ public static function gf_prepopulate ( $form, $ajax, $prepopulate = null ) { } } + $basic_array = isset( $prepopulate['fields'][0] ); + // Prepopulate values foreach ( $prepopulate['fields'] as $field => $field_options ) { - if ( is_int( $field ) && is_string( $field_options ) ) { + if ( $basic_array && is_string( $field_options ) ) { $field_options = array( 'gf_field' => $field_options, 'field' => $field_options, @@ -2075,7 +2143,7 @@ public static function confirmation ( $form_id, $options = array() ) { self::$confirmation[$form_id] = $options; - if ( ! add_filter( 'gform_confirmation_' . $form_id, array( 'Pods_GF', 'gf_confirmation' ) ) ) { + if ( ! has_filter( 'gform_confirmation_' . $form_id, array( 'Pods_GF', 'gf_confirmation' ) ) ) { add_filter( 'gform_confirmation_' . $form_id, array( 'Pods_GF', 'gf_confirmation' ), 10, 4 ); } @@ -2159,11 +2227,29 @@ public static function gf_confirmation ( $confirmation, $form, $lead, $ajax = fa $url = get_permalink( $confirmation['pageId'] ); } else { - $url = GFCommon::replace_variables( trim( $confirmation['url'] ), $form, $lead, false, true ); - $url_info = parse_url( $url ); - $query_string = $url_info['query']; - $dynamic_query = GFCommon::replace_variables( trim( $confirmation['queryString'] ), $form, $lead, true ); - $query_string .= empty( $url_info['query'] ) || empty( $dynamic_query ) ? $dynamic_query : '&' . $dynamic_query; + $gf_to_pods_id = 0; + + if ( ! empty( self::$gf_to_pods_id[ $form['id'] ] ) ) { + $gf_to_pods_id = self::$gf_to_pods_id[ $form['id'] ]; + } + + $confirmation['url'] = str_replace( '{@gf_to_pods_id}', $gf_to_pods_id, $confirmation['url'] ); + + $url = trim( GFCommon::replace_variables( trim( $confirmation['url'] ), $form, $lead, false, true ) ); + $url_info = parse_url( $url ); + $query_string = trim( $url_info['query'] ); + + if ( ! empty( $confirmation['queryString'] ) ) { + $dynamic_query = trim( GFCommon::replace_variables( trim( $confirmation['queryString'] ), $form, $lead, true ) ); + + if ( ! empty( $dynamic_query ) ) { + if ( ! empty( $url_info['query'] ) ) { + $query_string .= '&'; + } + + $query_string .= $dynamic_query; + } + } if ( ! empty( $url_info['fragment'] ) ) { $query_string .= '#' . $url_info['fragment']; @@ -2191,16 +2277,13 @@ public static function gf_confirmation ( $confirmation, $form, $lead, $ajax = fa $confirmation = array( 'redirect' => $url ); } } - - if ( ! is_array( $confirmation ) ) { - $confirmation = GFCommon::gform_do_shortcode( $confirmation ); //enabling shortcodes - } - elseif ( headers_sent() || $ajax ) { - //Perform client side redirect for AJAX forms, of if headers have already been sent - $confirmation = self::gf_get_js_redirect_confirmation( $confirmation[ 'redirect' ], $ajax ); //redirecting via client side - } } + // @todo Is this needed still? + /*if ( ! is_array( $confirmation ) ) { + $confirmation = GFCommon::gform_do_shortcode( $confirmation ); //enabling shortcodes + }*/ + return $confirmation; } @@ -2733,7 +2816,7 @@ public function _gf_pre_render ( $form, $ajax ) { if ( isset( $this->options['prepopulate'] ) && ! empty( $this->options['prepopulate'] ) ) { $prepopulate = array( 'pod' => $this->pod, - 'id' => pods_v( 'save_id', $this->options, pods_v( 'id', $this->pod, $this->id, true ), true ), + 'id' => pods_v( 'save_id', $this->options, $this->get_current_id(), true ), 'fields' => $this->options['fields'] ); @@ -2999,17 +3082,21 @@ public function _gf_field_validation ( $validation_result, $value, $form, $field $validate = true; if ( is_object( $this->pod ) ) { - $field_data = $this->pod->fields( $field_options['field'] ); + if ( empty( $this->pod->pod_data ) ) { + $validate = 'Invalid pod for mapping'; + } else { + $field_data = $this->pod->fields( $field_options['field'] ); - if ( empty( $field_data ) ) { - return $validation_result; - } + if ( empty( $field_data ) ) { + return $validation_result; + } - $pods_api = pods_api(); + $pods_api = pods_api(); - $gf_value = self::get_gf_field_value( $value, $field, $form, $this->options ); + $gf_value = self::get_gf_field_value( $value, $field, $form, $this->options ); - $validate = $pods_api->handle_field_validation( $gf_value, $field_options['field'], $this->pod->pod_data['object_fields'], $this->pod->pod_data['fields'], $this->pod, null ); + $validate = $pods_api->handle_field_validation( $gf_value, $field_options['field'], $this->pod->pod_data['object_fields'], $this->pod->pod_data['fields'], $this->pod, null ); + } } $validate = apply_filters( 'pods_gf_field_validation_' . $form['id'] . '_' . (string) $field['id'], $validate, $field['id'], $field_options, $value, $form, $field, $this ); @@ -3128,21 +3215,16 @@ public function _gf_validation_message ( $validation_message, $form ) { public function _gf_entry_pre_save_id( $lead_id, $form ) { if ( empty( $this->gf_validation_message ) ) { - if ( isset( self::$actioned[$form['id']] ) && in_array( __FUNCTION__, self::$actioned[$form['id']] ) ) { - return $lead_id; - } - elseif ( ! isset( self::$actioned[$form['id']] ) ) { - self::$actioned[$form['id']] = array(); - } - - self::$actioned[$form['id']][] = __FUNCTION__; - if ( empty( $this->options ) ) { return $lead_id; } - if ( isset( $this->options['edit'] ) && $this->options['edit'] && is_array( $this->pod ) && 0 < $this->id && empty( $entry ) ) { - $lead_id = $this->id; + if ( isset( $this->options['edit'] ) && $this->options['edit'] && is_array( $this->pod ) && empty( $entry ) ) { + if ( 0 < $this->entry_id ) { + $lead_id = $this->entry_id; + } elseif ( 0 < $this->id ) { + $lead_id = $this->id; + } } } @@ -3265,7 +3347,11 @@ public function _gf_after_submission ( $entry, $form ) { self::$actioned[$form['id']][] = __FUNCTION__; - $this->id = $entry['id']; + if ( is_array( $this->pod ) ) { + $this->id = $entry['id']; + } + + $this->entry_id = $entry['id']; if ( empty( $this->options ) ) { return $entry; @@ -3336,7 +3422,7 @@ public function _gf_after_submission ( $entry, $form ) { $confirmation = self::gf_confirmation( $form['confirmation'], $form, $entry, false, true ); if ( 'redirect' != $confirmation['type'] || ! is_array( $confirmation ) || ( ! isset( $confirmation['url'] ) && ! isset( $confirmation['redirect'] ) ) ) { - pods_redirect( pods_var_update( array( 'action' => 'edit', 'id' => $this->id ) ) ); + pods_redirect( pods_var_update( array( 'action' => 'edit', 'id' => $this->get_current_id() ) ) ); } elseif ( isset( $confirmation['url'] ) ) { pods_redirect( $confirmation['url'] ); @@ -3351,6 +3437,29 @@ public function _gf_after_submission ( $entry, $form ) { } + /** + * Get current ID + * + * @return int + */ + public function get_current_id() { + + $id = (int) $this->id; + + if ( empty( $id ) ) { + if ( is_object( $this->pod ) ) { + // Pod object + $id = (int) $this->pod->id(); + } elseif ( is_array( $this->pod ) ) { + // GF entry + $id = (int) pods_v( 'id', $this->pod, $id ); + } + } + + return $id; + + } + /** * Get the value of a variable key, with a default fallback * diff --git a/includes/Pods_GF_Addon.php b/includes/Pods_GF_Addon.php old mode 100644 new mode 100755 index 7075eea..2b1e660 --- a/includes/Pods_GF_Addon.php +++ b/includes/Pods_GF_Addon.php @@ -345,9 +345,20 @@ public function _gf_pre_process( $form ) { 'gf_to_pods_priority' => 'submission', ); - $options = apply_filters( 'pods_gf_addon_options', $options, $feed['meta']['pod'], $form['id'], $feed, $form ); + $edit_id = (int) apply_filters( 'pods_gf_addon_edit_id', 0, $feed['meta']['pod'], $form['id'], $feed, $form, $options ); - pods_gf( $feed['meta']['pod'], $form['id'], $options ); + if ( 0 < $edit_id ) { + $options['edit'] = true; + + // Setup pod object + $pod = pods( $feed['meta']['pod'], $edit_id ); + } else { + $pod = pods( $feed['meta']['pod'] ); + } + + $options = apply_filters( 'pods_gf_addon_options', $options, $feed['meta']['pod'], $form['id'], $feed, $form, $pod ); + + pods_gf( $pod, $form['id'], $options ); } } @@ -389,8 +400,8 @@ public function get_entry_meta( $entry_meta, $form_id ) { public function update_entry_meta_pod_id( $key, $entry, $form ) { - if ( ! empty( Pods_GF::$gf_to_pods_id ) ) { - $value = Pods_GF::$gf_to_pods_id; + if ( ! empty( Pods_GF::$gf_to_pods_id[ $form['id'] ] ) ) { + $value = Pods_GF::$gf_to_pods_id[ $form['id'] ]; } else { $value = 0; } diff --git a/includes/Pods_GF_UI.php b/includes/Pods_GF_UI.php old mode 100644 new mode 100755 index 90d1913..4d9ad1a --- a/includes/Pods_GF_UI.php +++ b/includes/Pods_GF_UI.php @@ -10,7 +10,7 @@ class Pods_GF_UI { public static $pods_gf; /** - * @var Pods_UI + * @var PodsUI */ public static $pods_ui; diff --git a/includes/functions.php b/includes/functions.php index 4d623bf..4c77d4a 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -12,7 +12,7 @@ function pods_gf( $pod = null, $form_id = null, $options = array() ) { require_once( PODS_GF_DIR . 'includes/Pods_GF_UI.php' ); if ( null !== $pod || null !== $form_id || array() !== $options ) { - return new Pods_GF( $pod, $form_id, $options ); + return Pods_GF::get_instance( $pod, $form_id, $options ); } } diff --git a/pods-gravity-forms.php b/pods-gravity-forms.php index cc2f912..4b7eac0 100644 --- a/pods-gravity-forms.php +++ b/pods-gravity-forms.php @@ -3,7 +3,7 @@ Plugin Name: Pods Gravity Forms Add-On Plugin URI: http://pods.io/ Description: Integration with Gravity Forms (http://www.gravityforms.com/); Provides a UI for mapping a Form's submissions into a Pod -Version: 1.0 +Version: 1.1 Author: Pods Framework Team Author URI: http://pods.io/about/ Text Domain: pods-gravity-forms @@ -30,7 +30,7 @@ * @package Pods\Gravity Forms */ -define( 'PODS_GF_VERSION', '1.0' ); +define( 'PODS_GF_VERSION', '1.1' ); define( 'PODS_GF_FILE', __FILE__ ); define( 'PODS_GF_DIR', plugin_dir_path( PODS_GF_FILE ) ); define( 'PODS_GF_URL', plugin_dir_url( PODS_GF_FILE ) ); diff --git a/readme.txt b/readme.txt index 75e6aee..122c07a 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Donate link: https://pods.io/friends-of-pods/ Tags: pods, gravity forms, form mapping Requires at least: 4.0 Tested up to: 4.5 -Stable tag: 1.0 +Stable tag: 1.1 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -34,6 +34,20 @@ Special thanks to Naomi C. Bush for her help == Changelog == += 1.1 - June 13th, 2016 = + +* Added: Support for edit mode when using the Pods GF add-on mapping in the GF UI -- Use the new filter `pods_gf_addon_edit_id`, just return the ID to edit and the options will automatically be set for you +* Added: When filtering the Pods data in `Pods_GF::gf_to_pods()` (via the `pods_gf_to_pods_data` and related filters), if you set the proper ID field in that array it will now be used to *save* over the existing item; Helpful for dynamic editing configurations based upon different processes and workflows in the code +* Added: `Pods_GF::confirmation()` now supports `{@gf_to_pods_id}` replacement in confirmation URLs, replacing the variable properly to the resulting saved ID +* Fixed: `Pods_GF::_gf_to_pods_handler()` would sometimes get the action improperly set to `edit`, but only `add`, `save`, or `bypass` are valid +* Fixed: When an invalid pod is called in `Pods_GF::_gf_to_pods_handler()`, there's now a proper fallback to avoid PHP errors/warnings/notices +* Fixed: When an invalid pod is called in `Pods_GF::_gf_field_validation()`, there's now a proper fallback to avoid PHP errors/warnings/notices +* Fixed: `Pods_GF::confirmation()` would add the `gform_confirmation_{$form_id}` filter incorrectly and would cause PHP warnings about the callback, causing the confirmation functionality to not work properly +* Fixed: `Pods_GF::confirmation()` confirmation URL replacement now handles a few more cases where previously PHP notices would result +* Changed: `Pods_GF` is now storing multiple instances statically, cannot be called with `new Pods_GF()`, must be called with `Pods_GF::get_instance()` but more importantly should be called through the standard `pods_gf()` helper function to remain backwards compatible with previous versions +* Changed: `Pods_GF::$gf_to_pods_id` is no longer an integer, but an array of integers keyed by the GF Form ID +* Changed: `Pods_GF::$keep_files` is no longer an boolean, but an array of booleans keyed by the GF Form ID + = 1.0 - March 4th, 2016 = * Initial release