Skip to content

Instantly share code, notes, and snippets.

@geekontheroad
Last active November 26, 2023 14:31
Show Gist options
  • Save geekontheroad/5d7825d45401e1edaec16e797565a616 to your computer and use it in GitHub Desktop.
Save geekontheroad/5d7825d45401e1edaec16e797565a616 to your computer and use it in GitHub Desktop.
<?php
/**
* Geek on the Road // GP Nested Forms
*
* Description: Populate child entries from one parent form into another parent form with a different child form
* Version: 0.1
* Author: Johan d'Hollander
* Author URI: https://geekontheroad.com
*
*
* This snippet is for Gravity Perks Nested Forms and allows you to duplicate and populate child entries from Form A into Form B.
* You can have different child forms in both Form A and B, just use the field mapping in the configuration below to map field values from Form A child entries to Form B child entries.
*
* INSTRUCTIONS
* Copy this code to your functions.php or save as custom plugin
* Complete the configuration Array at the bottom of this file
*/
class GOTR_GPNF_Populate_Other_Child_Entries
{
// holds the entry id of the entry in the first form (step1)
private $_original_entry = 0;
// holds the ids of the newly created child entries for the second form
private $_child_entries = array();
// flag to ensure the child entries are only created once
private $_entries_created = false;
// holds the configuration
private $_args = array();
public function __construct($args = array())
{
// store provided argunments in the class
$this->_args = wp_parse_args($args, array(
'first_step_form_id' => 0,
'first_step_nested_field_id' => 0,
'second_step_form_id' => 0,
'second_step_nested_field_id' => 0,
'second_step_child_form_id' => 0,
'field_map' => array(),
));
// init the class
add_action('init', array($this, 'init'));
}
public function init()
{
// create the entries on form load
add_filter('gform_pre_render', array($this, 'create_new_child_entries'), 10, 3);
// populate the nested field with the child entries ids
add_filter('gform_field_value_nestedform', array($this, 'populate_child_entries'), 10, 3);
// retrieve the original entry and save in the class
$this->maybe_get_original_entry();
}
public function create_new_child_entries($form, $ajax, $field_values)
{
// abort if the user is not logged in or there is no entry from the first form or this is not for the correct form
if (!is_user_logged_in() || !$this->_original_entry || !$this->is_applicable_form($form)) {
return $form;
}
// get the current page in a multi page
$current_page = GFFormDisplay::get_current_page($form['id']);
// only proceed if the entries are not already created and we are on the first page of the form
if (!$this->_entries_created && $current_page <= 1) {
// we have to get the Nested form cookie for this form
$session = new GPNF_Session($form['id']);
$cookie = $session->get_cookie();
// only proceed if there is a cookie
if ($cookie) {
// get the temporary id from the cookie which we will use as our parent entry ID for the new child entries
$temporary_id = rgar($cookie, 'hash', '');
// get the child entries from the first step form in an array
$original_child_entries = rgar($this->_original_entry, $this->_args['first_step_nested_field_id']); // this returns a comma separated list of child entry ids
$original_child_entries_array = explode(",", $original_child_entries);
// loop through child entries and create new ones for the second form
foreach ($original_child_entries_array as $entry_id) {
// retrieve the entry
$entry = GFAPI::get_entry($entry_id);
if (!is_wp_error($entry) && $entry) {
// start new entry and define the nested form required parameters
$new_child_entry = array(
'form_id' => $this->_args['second_step_child_form_id'],
GPNF_Entry::ENTRY_PARENT_KEY => $temporary_id,
GPNF_Entry::ENTRY_PARENT_FORM_KEY => $this->_args['second_step_form_id'],
GPNF_Entry::ENTRY_NESTED_FORM_FIELD_KEY => $this->_args['second_step_nested_field_id']
);
// map the original child entry values to this new entry
$mapping = $this->_args['field_map'];
foreach ($mapping as $first_key => $second_key) {
$new_child_entry[$second_key] = $entry[$first_key];
}
// save the new entry and get the new entry id
$new_child_entry_id = GFAPI::add_entry($new_child_entry);
// save the new entry id to the class so we can populate it later to the nested form field
if ($new_child_entry_id) {
$this->_child_entries[] = $new_child_entry_id;
}
}
}
// set flag to avoid double entries
$this->_entries_created = true;
}
}
return $form;
}
// populate the new child entries into the nested field
public function populate_child_entries($value, $field, $name)
{
if (!empty($this->_child_entries)) {
return implode(",", $this->_child_entries);
}
return $value;
}
// Maybe retrieve the original entry from the first step for this user
public function maybe_get_original_entry()
{
if (!is_user_logged_in()) {
return false;
}
$search_criteria = array();
$search_criteria['status'] = 'active';
$search_criteria['field_filters'][] = array('key' => 'created_by', 'value' => get_current_user_id());
$entries = GFAPI::get_entries($this->_args['first_step_form_id'], $search_criteria);
if ($entries && !empty($entries)) {
// we should have one entry here and otherwise we take the first one and store it in the class
$this->_original_entry = $entries[0];
}
}
// this only needs to run for the second form configured in the configuration
public function is_applicable_form($form)
{
$form_id = isset($form['id']) ? $form['id'] : 0;
return $form_id == $this->_args['second_step_form_id'];
}
}
/**
* Configuration
**/
new GOTR_GPNF_Populate_Other_Child_Entries(array(
'first_step_form_id' => 1, // the first form ID
'first_step_nested_field_id' => 54, // the nested form field ID in the second form
'second_step_form_id' => 18, // the second form ID
'second_step_nested_field_id' => 12, // the nested form field ID in the second form
'second_step_child_form_id' => 19, // the child form ID used in the second form
// map the fields of the first child form to the fields of the second child form
'field_map' => array(
// field ID in first child form => field ID in second child form
'8' => '8',
'5' => '5',
'7' => '7',
'9' => '9',
),
));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment