initial
This commit is contained in:
@@ -0,0 +1,440 @@
|
||||
<?php
|
||||
/**
|
||||
* Form CRUD handler.
|
||||
*
|
||||
* Handles creating and updating forms.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Save_Form
|
||||
*/
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Save_Form;
|
||||
|
||||
use GFFormsModel;
|
||||
use RGFormsModel;
|
||||
use GFAPI;
|
||||
use GFForms;
|
||||
use GFCommon;
|
||||
|
||||
class GF_Form_CRUD_Handler {
|
||||
|
||||
// Statuses expected after attempting to save a form.
|
||||
const STATUS_SUCCESS = 'success';
|
||||
const STATUS_FAILURE = 'failure';
|
||||
const STATUS_INVALID_META = 'invalid_meta';
|
||||
const STATUS_INVALID_JSON = 'invalid_json';
|
||||
const STATUS_DUPLICATE_TITLE = 'duplicate_title';
|
||||
const STATUS_MISSING_TITLE = 'missing_title';
|
||||
|
||||
/**
|
||||
* Holds an instance of the GFFormsModel class.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var \GFFormsModel
|
||||
*/
|
||||
private $gf_forms_model;
|
||||
|
||||
/**
|
||||
* Holds an instance of the GFCommon class.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var \GFCommon
|
||||
*/
|
||||
private $gf_common;
|
||||
|
||||
/**
|
||||
* Holds an instance of the RGFormsModel class.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var \RGFormsModel
|
||||
*/
|
||||
private $rg_forms_model;
|
||||
|
||||
/**
|
||||
* Holds an instance of the GFAPI class.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var \GFAPI
|
||||
*/
|
||||
private $gf_api;
|
||||
|
||||
/**
|
||||
* Holds an instance of the GFForms class.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var \GFForms
|
||||
*/
|
||||
private $gf_forms;
|
||||
|
||||
/**
|
||||
* The ID of the form we are working with.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $form_id;
|
||||
|
||||
/**
|
||||
* The JSON representation of the form.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $form_json;
|
||||
|
||||
/**
|
||||
* The meta data of the form as an associative array.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $form_meta;
|
||||
|
||||
/**
|
||||
* Contains the delete form fields.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var integer[]
|
||||
*/
|
||||
private $deleted_fields;
|
||||
|
||||
/**
|
||||
* The form object.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $form;
|
||||
|
||||
/**
|
||||
* GF_Form_CRUD_Handler constructor.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $dependencies Array of dependency objects.
|
||||
*/
|
||||
public function __construct( $dependencies ) {
|
||||
|
||||
$this->gf_forms_model = $dependencies['gf_forms_model'];
|
||||
$this->rg_forms_model = $dependencies['rg_forms_model'];
|
||||
$this->gf_common = $dependencies['gf_common'];
|
||||
$this->gf_api = $dependencies['gf_api'];
|
||||
$this->gf_forms = $dependencies['gf_forms'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing form or creates a new one if necessary.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param int $form_id The ID of the form to update.
|
||||
* @param string $form_json The JSON representation of the form.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function save( $form_id, $form_json ) {
|
||||
|
||||
$this->form_id = $form_id;
|
||||
$this->form_json = $form_json;
|
||||
$this->deleted_fields = array();
|
||||
$this->form_meta = array();
|
||||
|
||||
if ( ! $this->cleanup() ) {
|
||||
return array(
|
||||
'status' => self::STATUS_INVALID_JSON,
|
||||
'meta' => null,
|
||||
);
|
||||
}
|
||||
|
||||
$validation_result = $this->validate();
|
||||
if ( rgar( $validation_result, 'status' ) !== self::STATUS_SUCCESS ) {
|
||||
return $validation_result;
|
||||
}
|
||||
// $this->form_meta is populated during insert or update.
|
||||
if ( $this->form_id <= 0 ) {
|
||||
$save_result = $this->insert();
|
||||
} else {
|
||||
$save_result = $this->update();
|
||||
}
|
||||
|
||||
ob_start();
|
||||
|
||||
/**
|
||||
* Fires after a form is saved
|
||||
*
|
||||
* Used to run additional actions after the form is saved
|
||||
*
|
||||
* @since 2.4.6.1 Added the $deleted_fields param.
|
||||
* @since unknown
|
||||
*
|
||||
* @param array $form_meta The form meta
|
||||
* @param bool $is_new Returns true if this is a new form.
|
||||
* @param array $deleted_fields The IDs of any fields which have been deleted.
|
||||
*/
|
||||
do_action( 'gform_after_save_form', $this->form_meta, rgar( $save_result, 'is_new' ), $this->deleted_fields );
|
||||
|
||||
$after_save_markup = ob_get_clean();
|
||||
|
||||
$save_result['actions_markup'] = array(
|
||||
'gform_after_save_form' => $after_save_markup,
|
||||
);
|
||||
|
||||
return $save_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the form data before updating or creating it.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array An array containing the status of the validation and the form meta.
|
||||
*/
|
||||
private function validate() {
|
||||
|
||||
$gf_forms_model = $this->gf_forms_model;
|
||||
|
||||
// If form meta is not found, exit.
|
||||
if ( ! is_array( $this->form_meta ) ) {
|
||||
return array(
|
||||
'status' => self::STATUS_INVALID_META,
|
||||
'meta' => null,
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! rgar( $this->form_meta, 'title' ) ) {
|
||||
return array(
|
||||
'status' => self::STATUS_MISSING_TITLE,
|
||||
'meta' => null,
|
||||
);
|
||||
}
|
||||
|
||||
// If form has a duplicate title, exit.
|
||||
$forms = $gf_forms_model::get_forms();
|
||||
foreach ( $forms as $form ) {
|
||||
if ( strtolower( $form->title ) == strtolower( $this->form_meta['title'] ) && rgar( $this->form_meta, 'id' ) != $form->id ) {
|
||||
return array(
|
||||
'status' => self::STATUS_DUPLICATE_TITLE,
|
||||
'meta' => $this->form_meta,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'status' => self::STATUS_SUCCESS,
|
||||
'meta' => $this->form_meta,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs any sanitization/formatting necessary before processing the form.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function cleanup() {
|
||||
|
||||
$gf_forms_model = $this->gf_forms_model;
|
||||
$gf_common = $this->gf_common;
|
||||
$gf_forms = $this->gf_forms;
|
||||
$action = rgpost( 'action' );
|
||||
|
||||
if ( $action !== 'create_from_template' ) {
|
||||
// Clean up form meta JSON.
|
||||
$gf_common::log_debug( 'GF_Form_CRUD_Handler::cleanup(): Form meta json before stripslashes: ' . $this->form_json );
|
||||
|
||||
$this->form_json = stripslashes( $this->form_json );
|
||||
}
|
||||
|
||||
$gf_common::log_debug( 'GF_Form_CRUD_Handler::cleanup(): Form meta json before nl2br: ' . $this->form_json );
|
||||
$this->form_json = nl2br( $this->form_json );
|
||||
$gf_common::log_debug( 'GF_Form_CRUD_Handler::cleanup(): Final form meta json: ' . $this->form_json );
|
||||
|
||||
// Convert form meta JSON to array.
|
||||
$this->form_meta = json_decode( $this->form_json, true );
|
||||
|
||||
if ( ! is_array( $this->form_meta ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->form_meta = $gf_forms_model::convert_field_objects( $this->form_meta );
|
||||
|
||||
// Set version of Gravity Forms form was created with.
|
||||
if ( $this->form_id === 0 ) {
|
||||
$this->form_meta['version'] = $gf_forms::$version;
|
||||
}
|
||||
|
||||
// Sanitize form settings.
|
||||
$this->form_meta = $gf_forms_model::maybe_sanitize_form_settings( $this->form_meta );
|
||||
|
||||
$deleted_fields = $this->get_deleted_fields();
|
||||
$gf_common::log_debug( 'GF_Form_CRUD_Handler::cleanup(): Deleted fields ' . print_r( $deleted_fields, true ) );
|
||||
unset( $this->form_meta['deletedFields'] );
|
||||
$gf_common::log_debug( 'GF_Form_CRUD_Handler::cleanup(): Form meta => ' . print_r( $this->form_meta, true ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing form.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array The result of the update and the resulting form meta.
|
||||
*/
|
||||
private function update() {
|
||||
|
||||
$gf_forms_model = $this->gf_forms_model;
|
||||
$gf_common = $this->gf_common;
|
||||
$gf_forms = $this->gf_forms;
|
||||
$gf_api = $this->gf_api;
|
||||
$rg_forms_model = $this->rg_forms_model;
|
||||
|
||||
// Trim form meta values.
|
||||
$this->form_meta = $gf_forms_model::trim_form_meta_values( $this->form_meta );
|
||||
$deleted_fields = $this->get_deleted_fields();
|
||||
// Delete fields.
|
||||
if ( ! empty( $deleted_fields ) ) {
|
||||
foreach ( $deleted_fields as $deleted_field_id ) {
|
||||
$this->form_meta = $gf_forms_model::delete_field( $this->form_meta, $deleted_field_id, false );
|
||||
}
|
||||
}
|
||||
|
||||
// Save form meta.
|
||||
$gf_forms_model::update_form_meta( $this->form_id, $this->form_meta );
|
||||
|
||||
// Update form title.
|
||||
$gf_api::update_form_property( $this->form_id, 'title', $this->form_meta['title'] );
|
||||
|
||||
// Get form meta.
|
||||
$this->form_meta = $rg_forms_model::get_form_meta( $this->form_id );
|
||||
|
||||
if ( ! empty( $deleted_fields ) ) {
|
||||
// Remove logic/routing rules based on deleted fields from confirmations and notifications.
|
||||
foreach ( $deleted_fields as $deleted_field ) {
|
||||
$this->form_meta = $gf_forms_model::delete_field_from_confirmations( $this->form_meta, $deleted_field );
|
||||
$this->form_meta = $gf_forms_model::delete_field_from_notifications( $this->form_meta, $deleted_field );
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'status' => self::STATUS_SUCCESS,
|
||||
'meta' => $this->form_meta,
|
||||
'is_new' => false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new form.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array The status of the insert and the form meta data.
|
||||
*/
|
||||
private function insert() {
|
||||
$rg_forms_model = $this->rg_forms_model;
|
||||
$gf_forms_model = $this->gf_forms_model;
|
||||
|
||||
// Inserting form.
|
||||
$this->form_id = $rg_forms_model::insert_form( $this->form_meta['title'] );
|
||||
|
||||
// Updating object's id property.
|
||||
$this->form_meta['id'] = $this->form_id;
|
||||
|
||||
// Use the notifications in form_meta if one is set. If not set, and default notification is not disabled by the hook, use default.
|
||||
$notifications = rgempty( 'notifications', $this->form_meta ) ? $this->get_default_notification() : rgar( $this->form_meta, 'notifications' );
|
||||
if ( ! empty( $notifications ) ) {
|
||||
// updating notifications form meta.
|
||||
$rg_forms_model::save_form_notifications( $this->form_id, $notifications );
|
||||
}
|
||||
|
||||
// Use default confirmation if not set in form_meta.
|
||||
$confirmations = rgempty( 'confirmations', $this->form_meta ) ? $this->get_default_confirmation() : rgar( $this->form_meta, 'confirmations' );
|
||||
$gf_forms_model::save_form_confirmations( $this->form_id, $confirmations );
|
||||
|
||||
// Adding markup version. Increment this when we make breaking changes to form markup.
|
||||
$this->form_meta['markupVersion'] = 2;
|
||||
|
||||
// Removing notifications and confirmations from form meta.
|
||||
unset( $this->form_meta['confirmations'] );
|
||||
unset( $this->form_meta['notifications'] );
|
||||
|
||||
// Updating form meta.
|
||||
$gf_forms_model::update_form_meta( $this->form_id, $this->form_meta );
|
||||
|
||||
// Get form meta.
|
||||
$this->form_meta = $gf_forms_model::get_form_meta( $this->form_id );
|
||||
|
||||
return array(
|
||||
'status' => self::STATUS_SUCCESS,
|
||||
'meta' => $this->form_meta,
|
||||
'is_new' => true,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default notifications.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @return array Returns the array containing the default notifications.
|
||||
*/
|
||||
private function get_default_notification() {
|
||||
if ( ! apply_filters( 'gform_default_notification', true ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$default_notification = array(
|
||||
'id' => uniqid(),
|
||||
'isActive' => true,
|
||||
'to' => '{admin_email}',
|
||||
'name' => __( 'Admin Notification', 'gravityforms' ),
|
||||
'event' => 'form_submission',
|
||||
'toType' => 'email',
|
||||
'subject' => __( 'New submission from', 'gravityforms' ) . ' {form_title}',
|
||||
'message' => '{all_fields}',
|
||||
);
|
||||
|
||||
return array( $default_notification['id'] => $default_notification );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default confirmations.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @return array Returns the confirmation array.
|
||||
*/
|
||||
private function get_default_confirmation() {
|
||||
$gf_forms_model = $this->gf_forms_model;
|
||||
|
||||
$confirmation = $gf_forms_model::get_default_confirmation();
|
||||
return array( $confirmation['id'] => $confirmation );
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the deleted field IDs from the form meta or returns them if they were already extracted before.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
private function get_deleted_fields() {
|
||||
if ( empty( $this->deleted_fields ) ) {
|
||||
// Extract deleted field IDs.
|
||||
$this->deleted_fields = rgar( $this->form_meta, 'deletedFields' );
|
||||
}
|
||||
|
||||
return $this->deleted_fields;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user