plugin install
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/**
|
||||
* Class GF_Save_Form_Helper
|
||||
*
|
||||
* Provides some helper functions to the form saving functionality.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Save_Form
|
||||
*/
|
||||
namespace Gravity_Forms\Gravity_Forms\Save_Form;
|
||||
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
|
||||
|
||||
class GF_Save_Form_Helper {
|
||||
/**
|
||||
* Stores an instance of GFForms to call common static functions.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var \GFForms
|
||||
*/
|
||||
protected $gf_forms;
|
||||
|
||||
/**
|
||||
* GF_Save_Form_Helper constructor.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $dependencies Array of dependency objects.
|
||||
*/
|
||||
public function __construct( $dependencies ) {
|
||||
$this->gf_forms = $dependencies['gf_forms'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the AJAX action being executed is one of the endpoints of saving the form.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_ajax_save_action() {
|
||||
$action = rgpost( 'action' );
|
||||
$gf_forms = $this->gf_forms;
|
||||
$endpoint = $gf_forms::get_service_container()->get( $action );
|
||||
return $endpoint && is_a( $endpoint, 'Gravity_Forms\Gravity_Forms\Save_Form\Endpoints\GF_Save_Form_Endpoint_Admin' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the ajax save is disabled using the provided filter
|
||||
*
|
||||
* @param integer $form_id If provided the filter will be used for this specific form.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function is_ajax_save_disabled( $form_id = null ) {
|
||||
$is_ajax_save_disabled = false;
|
||||
/**
|
||||
* This filter should be used to disabled ajax save.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param boolean $is_ajax_save_disabled Defaults to false.
|
||||
*/
|
||||
return gf_apply_filters( array( 'gform_disable_ajax_save', $form_id ), $is_ajax_save_disabled );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* Service Provider for Form saving
|
||||
*
|
||||
* Handles all CRUD operations related to editing forms via different kinds of editors.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Save_Form
|
||||
*/
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Save_Form;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Service_Provider;
|
||||
use Gravity_Forms\Gravity_Forms\Save_Form\Config\GF_Form_Editor_Form_Save_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Save_Form\Config\GF_Admin_Form_Save_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Save_Form\Endpoints\GF_Save_Form_Endpoint_Admin;
|
||||
use Gravity_Forms\Gravity_Forms\Save_Form\Endpoints\GF_Save_Form_Endpoint_Form_Editor;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
|
||||
use Gravity_Forms\Gravity_Forms\Util\GF_Util_Service_Provider;
|
||||
|
||||
/**
|
||||
* Service Provider for Form saving
|
||||
*
|
||||
* Handles all CRUD operations related to editing forms via different kinds of editors.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* Service provider for the Duplicate Submission Service.
|
||||
*/
|
||||
class GF_Save_Form_Service_Provider extends GF_Service_Provider {
|
||||
|
||||
// Configs names, used as keys for the configuration classes in the service container.
|
||||
const ADMIN_SAVE_CONFIG = 'admin_save_config';
|
||||
|
||||
/**
|
||||
* The configuration class names and their corresponding string keys in the service container.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $configs = array(
|
||||
self::ADMIN_SAVE_CONFIG => GF_Admin_Form_Save_Config::class,
|
||||
);
|
||||
|
||||
// Endpoint names, used as keys for the endpoint classes in the service container.
|
||||
// keys are the same names for the ajax actions.
|
||||
const ENDPOINT_ADMIN_SAVE = 'admin_save_form';
|
||||
|
||||
/**
|
||||
* The endpoint class names and their corresponding string keys in the service container.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $endpoints = array(
|
||||
self::ENDPOINT_ADMIN_SAVE => GF_Save_Form_Endpoint_Admin::class,
|
||||
);
|
||||
|
||||
// The CRUD handler key in the service container.
|
||||
const GF_FORM_CRUD_HANDLER = 'gf_form_crud_handler';
|
||||
const GF_SAVE_FROM_HELPER = 'gf_save_form_helper';
|
||||
|
||||
/**
|
||||
* Includes all related files and adds all containers.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container Container singleton object.
|
||||
*/
|
||||
public function register( GF_Service_Container $container ) {
|
||||
require_once plugin_dir_path( __FILE__ ) . 'config/class-gf-admin-form-save-config.php';
|
||||
require_once plugin_dir_path( __FILE__ ) . 'endpoints/class-gf-save-form-endpoint-admin.php';
|
||||
require_once plugin_dir_path( __FILE__ ) . 'class-gf-form-crud-handler.php';
|
||||
require_once plugin_dir_path( __FILE__ ) . 'class-gf-save-form-helper.php';
|
||||
|
||||
$container->add(
|
||||
self::GF_FORM_CRUD_HANDLER,
|
||||
function () use ( $container ) {
|
||||
return new GF_Form_CRUD_handler(
|
||||
array(
|
||||
GF_Util_Service_Provider::GF_FORMS_MODEL => $container->get( GF_Util_Service_Provider::GF_FORMS_MODEL ),
|
||||
GF_Util_Service_Provider::RG_FORMS_MODEL => $container->get( GF_Util_Service_Provider::RG_FORMS_MODEL ),
|
||||
GF_Util_Service_Provider::GF_COMMON => $container->get( GF_Util_Service_Provider::GF_COMMON ),
|
||||
GF_Util_Service_Provider::GF_API => $container->get( GF_Util_Service_Provider::GF_API ),
|
||||
GF_Util_Service_Provider::GF_FORMS => $container->get( GF_Util_Service_Provider::GF_FORMS ),
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$container->add(
|
||||
self::GF_SAVE_FROM_HELPER,
|
||||
function () use ( $container ) {
|
||||
return new GF_Save_Form_Helper(
|
||||
array(
|
||||
GF_Util_Service_Provider::GF_FORMS => $container->get( GF_Util_Service_Provider::GF_FORMS ),
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$this->add_configs( $container );
|
||||
$this->add_endpoints( $container );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register configuration classes.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*/
|
||||
public function add_configs( GF_Service_Container $container ) {
|
||||
foreach ( $this->configs as $name => $class ) {
|
||||
$container->add(
|
||||
$name,
|
||||
function () use ( $container, $class ) {
|
||||
return new $class(
|
||||
$container->get( GF_Config_Service_Provider::DATA_PARSER ),
|
||||
array(
|
||||
GF_Util_Service_Provider::GF_FORMS => $container->get( GF_Util_Service_Provider::GF_FORMS ),
|
||||
GF_Util_Service_Provider::GF_API => $container->get( GF_Util_Service_Provider::GF_API ),
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$container->get( GF_Config_Service_Provider::CONFIG_COLLECTION )->add_config( $container->get( $name ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Form Saving Endpoints.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function add_endpoints( GF_Service_Container $container ) {
|
||||
foreach ( $this->endpoints as $name => $class ) {
|
||||
$container->add(
|
||||
$name,
|
||||
function () use ( $container, $class ) {
|
||||
return new $class(
|
||||
array(
|
||||
GF_Save_Form_Service_Provider::GF_FORM_CRUD_HANDLER => $container->get( GF_Save_Form_Service_Provider::GF_FORM_CRUD_HANDLER ),
|
||||
GF_Util_Service_Provider::GF_FORMS_MODEL => $container->get( GF_Util_Service_Provider::GF_FORMS_MODEL ),
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize any actions or hooks required for handling form saving..
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*/
|
||||
public function init( GF_Service_Container $container ) {
|
||||
|
||||
add_filter(
|
||||
'gform_ajax_actions',
|
||||
function( $ajax_actions ) {
|
||||
$ajax_actions[] = GF_Save_Form_Endpoint_Admin::ACTION_NAME;
|
||||
|
||||
return $ajax_actions;
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'wp_ajax_' . GF_Save_Form_Endpoint_Admin::ACTION_NAME,
|
||||
function () use ( $container ) {
|
||||
$container->get( self::ENDPOINT_ADMIN_SAVE )->handle();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Save_Form\Config;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config;
|
||||
use Gravity_Forms\Gravity_Forms\Save_Form\Endpoints\GF_Save_Form_Endpoint_Admin;
|
||||
|
||||
class GF_Admin_Form_Save_Config extends Config\GF_Config {
|
||||
|
||||
const JSON_START_STRING = 'GFORMS_SAVE_REQUEST_JSON_START';
|
||||
const JSON_END_STRING = 'GFORMS_SAVE_REQUEST_JSON_END';
|
||||
|
||||
/**
|
||||
* The object name for this config.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'gform_admin_config';
|
||||
|
||||
/**
|
||||
* The ID of the script to localize the data to.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $script_to_localize = 'gform_gravityforms_admin_vendors';
|
||||
|
||||
/**
|
||||
* An instance of the GFForms class to use for calling common static functions.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var \GFForms
|
||||
*/
|
||||
protected $gf_forms;
|
||||
|
||||
/**
|
||||
* An instance of the GFAPI class to use for calling static GForms API functions.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var \GFAPI
|
||||
*/
|
||||
protected $gf_api;
|
||||
|
||||
/**
|
||||
* GF_Admin_Form_Save_Config constructor.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param Config\GF_Config_Data_Parser $parser Parses a given data array to return either Live or Mock values.
|
||||
* @param array $dependencies Array of dependency objects.
|
||||
*/
|
||||
public function __construct( Config\GF_Config_Data_Parser $parser, $dependencies ) {
|
||||
$this->gf_forms = $dependencies['gf_forms'];
|
||||
$this->gf_api = $dependencies['gf_api'];
|
||||
parent::__construct( $parser );
|
||||
}
|
||||
|
||||
public function should_enqueue() {
|
||||
return \GFForms::is_gravity_page();
|
||||
}
|
||||
|
||||
public function data() {
|
||||
$gf_forms = $this->gf_forms;
|
||||
return array(
|
||||
'admin_save_form' => array(
|
||||
'data' => array(
|
||||
'is_form_editor' => $gf_forms::get_page() === 'form_editor',
|
||||
'is_quick_editor' => false,
|
||||
'form' => $this->get_form(),
|
||||
'json_containers' => array(
|
||||
GF_Admin_Form_Save_Config::JSON_START_STRING,
|
||||
GF_Admin_Form_Save_Config::JSON_END_STRING,
|
||||
),
|
||||
),
|
||||
'endpoints' => $this->get_endpoints(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the form if an ID found in the the query parameters.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return false|array
|
||||
*/
|
||||
private function get_form() {
|
||||
$gf_forms = $this->gf_forms;
|
||||
$gf_api = $this->gf_api;
|
||||
$form_id = $gf_forms::get_page() === 'form_editor' ? rgget( 'id' ) : rgget( 'form_id' );
|
||||
if ( $form_id ) {
|
||||
return $gf_api::get_form( $form_id );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the endpoints for saving the form in the admin area.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return \array[][]
|
||||
*/
|
||||
private function get_endpoints() {
|
||||
return array(
|
||||
'admin_save_form' => array(
|
||||
'action' => array(
|
||||
'value' => GF_Save_Form_Endpoint_Admin::ACTION_NAME,
|
||||
'default' => 'mock_endpoint',
|
||||
),
|
||||
'nonce' => array(
|
||||
'value' => wp_create_nonce( GF_Save_Form_Endpoint_Admin::ACTION_NAME ),
|
||||
'default' => 'nonce',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Save_Form\Endpoints;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Save_Form\Config\GF_Admin_Form_Save_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Form_Editor\Save_Form\Config\GF_Form_Editor_Form_Save_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Save_Form\GF_Form_CRUD_Handler;
|
||||
use Gravity_Forms\Gravity_Forms\Save_Form\GF_Save_Form_Service_Provider;
|
||||
|
||||
/**
|
||||
* AJAX Endpoint for Saving the form in the admin area.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Save_Form\Endpoints
|
||||
*/
|
||||
class GF_Save_Form_Endpoint_Admin {
|
||||
|
||||
// AJAX action name.
|
||||
const ACTION_NAME = 'admin_save_form';
|
||||
// The required parameters keys in the request.
|
||||
const PARAM_FORM_ID = 'form_id';
|
||||
const PARAM_FORM_JSON = 'data';
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An instance of the CRUD service.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var GF_Form_CRUD_Handler
|
||||
*/
|
||||
protected $form_crud_handler;
|
||||
|
||||
/**
|
||||
* An instance of GFFormsModel to call common static functions.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var \GFFormsModel
|
||||
*/
|
||||
protected $gf_forms_model;
|
||||
|
||||
/**
|
||||
* An instance of GFForms to call common static functions.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var \GFForms
|
||||
*/
|
||||
protected $gf_forms;
|
||||
|
||||
|
||||
/**
|
||||
* The required parameters to execute the endpoint.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $required_params = array(
|
||||
self::PARAM_FORM_JSON,
|
||||
self::PARAM_FORM_ID,
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* GF_Save_Form_Endpoint_Admin constructor.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $dependencies Array of dependency objects.
|
||||
*/
|
||||
public function __construct( $dependencies ) {
|
||||
$this->form_crud_handler = rgar( $dependencies, 'gf_form_crud_handler' );
|
||||
$this->gf_forms_model = rgar( $dependencies, 'gf_forms_model' );
|
||||
$this->gf_forms = rgar( $dependencies, 'gf_forms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the AJAX save request.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle() {
|
||||
|
||||
if ( ! $this->validate() ) {
|
||||
wp_send_json_error( 'Missing required parameter', 400 );
|
||||
}
|
||||
|
||||
$this->gather_required_params();
|
||||
|
||||
$result = $this->save();
|
||||
|
||||
if ( rgar( $result, 'status' ) === GF_Form_CRUD_Handler::STATUS_SUCCESS ) {
|
||||
wp_send_json_success( $this->get_success_status_response( $result ) );
|
||||
} else {
|
||||
wp_send_json_error( $this->get_error_status_response( $result ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the request and makes sure it has the required parameters.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate() {
|
||||
check_ajax_referer( static::ACTION_NAME );
|
||||
|
||||
foreach ( $this->required_params as $key ) {
|
||||
if ( empty( rgpost( $key ) ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign the required parameters to their corresponding properties.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
protected function gather_required_params() {
|
||||
$this->form_id = rgpost( self::PARAM_FORM_ID );
|
||||
$this->form_json = rgpost( self::PARAM_FORM_JSON );
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the form.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array The status of the operation and the form data.
|
||||
*/
|
||||
protected function save() {
|
||||
|
||||
return $this->form_crud_handler->save( $this->form_id, $this->form_json );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a successful operation and returns the desired response.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $result The result of the operation.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function get_success_status_response( $result ) {
|
||||
return $this->wrap_json_response( $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a failed operation and returns the desired response.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $result The result of the operation.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function get_error_status_response( $result ) {
|
||||
$status = rgar( $result, 'status', GF_Form_CRUD_Handler::STATUS_FAILURE );
|
||||
|
||||
if ( $status === GF_Form_CRUD_Handler::STATUS_DUPLICATE_TITLE ) {
|
||||
$result['error'] = esc_html_e( 'Please enter a unique form title, this title is used for an existing form.', 'gravityforms' );
|
||||
} elseif ( $status === 0 || ! is_numeric( $status ) ) {
|
||||
$result['error'] = esc_html__( 'There was an error while saving your form.', 'gravityforms' ) . sprintf( esc_html__( 'Please %1$scontact our support team%2$s.', 'gravityforms' ), '<a target="_blank" href="' . esc_attr( GFCommon::get_support_url() ) . '">', '</a>' );
|
||||
}
|
||||
|
||||
return $this->wrap_json_response( $result );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the response inside two known strings, so we can extract the response object in case of content output during to notices for example.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $response The Response array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function wrap_json_response( $response ) {
|
||||
$json_start = array( GF_Admin_Form_Save_Config::JSON_START_STRING => 0 );
|
||||
$json_end = array( GF_Admin_Form_Save_Config::JSON_END_STRING => 1 );
|
||||
|
||||
$response = array_merge( $json_start, $response );
|
||||
$response = array_merge( $response, $json_end );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user