plugin updates
This commit is contained in:
@@ -39,31 +39,57 @@ class GF_Config_Collection {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function handle( $localize = true ) {
|
||||
public function handle( $localize = true, $args = null ) {
|
||||
|
||||
$scripts = $this->get_configs_by_script();
|
||||
$data_to_localize = array();
|
||||
|
||||
foreach ( $scripts as $script => $items ) {
|
||||
$item_data = $this->localize_data_for_script( $script, $items, $localize );
|
||||
$item_data = $this->localize_data_for_script( $script, $items, $localize, $args );
|
||||
$data_to_localize = array_merge( $data_to_localize, $item_data );
|
||||
}
|
||||
|
||||
return $data_to_localize;
|
||||
}
|
||||
|
||||
public function handle_ajax() {
|
||||
|
||||
// Check nonce.
|
||||
$nonce_result = check_ajax_referer( 'gform_config_ajax', 'gform_ajax_nonce', false );
|
||||
|
||||
if ( ! $nonce_result ) {
|
||||
wp_send_json_error( esc_html__( 'Unable to verify nonce. Please refresh the page and try again.', 'gravityforms' ) );
|
||||
}
|
||||
|
||||
$args = json_decode( rgpost( 'args' ), true );
|
||||
$config_path = rgpost( 'config_path' );
|
||||
$configs = $this->get_configs_by_path( $config_path, $args );
|
||||
|
||||
if ( ! $configs ) {
|
||||
wp_send_json_error( sprintf( esc_html__( 'Unable to find config: %s', 'gravityforms' ), $config_path ) );
|
||||
}
|
||||
|
||||
$data = $this->get_merged_data_for_object( $configs, $args );
|
||||
wp_send_json_success( $data );
|
||||
}
|
||||
/**
|
||||
* Localize the data for the given script.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param string $script
|
||||
* @param GF_Config[] $items
|
||||
* @param string $script The script to localize.
|
||||
* @param array $items The associative array of configs to process for this script.
|
||||
* @param bool $localize Whether to actually localize the data, or simply return it.
|
||||
* @param array $args The arguments to pass to the config objects.
|
||||
*
|
||||
* @return array Returns the localized data.
|
||||
*/
|
||||
private function localize_data_for_script( $script, $items, $localize = true ) {
|
||||
private function localize_data_for_script( $script, $items, $localize = true, $args = null ) {
|
||||
$data = array();
|
||||
|
||||
foreach ( $items as $name => $configs ) {
|
||||
$localized_data = $this->get_merged_data_for_object( $configs );
|
||||
|
||||
$localized_data = $this->get_merged_data_for_object( $configs, $args );
|
||||
|
||||
/**
|
||||
* Allows users to filter the data localized for a given script/resource.
|
||||
@@ -96,7 +122,7 @@ class GF_Config_Collection {
|
||||
*
|
||||
* @param GF_Config[] $configs
|
||||
*/
|
||||
private function get_merged_data_for_object( $configs ) {
|
||||
private function get_merged_data_for_object( $configs, $args ) {
|
||||
// Squash warnings for PHP < 7.0 when running tests.
|
||||
@usort( $configs, array( $this, 'sort_by_priority' ) );
|
||||
|
||||
@@ -104,6 +130,8 @@ class GF_Config_Collection {
|
||||
|
||||
foreach ( $configs as $config ) {
|
||||
|
||||
$config->set_args( $args );
|
||||
|
||||
// Config is set to overwrite data - simply return its value without attempting to merge.
|
||||
if ( $config->should_overwrite() ) {
|
||||
$data = $config->get_data();
|
||||
@@ -147,6 +175,27 @@ class GF_Config_Collection {
|
||||
return $data_to_localize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of configs that match the specified config path.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param string $config_path The path of the config to be returned.
|
||||
* @param array $args The arguments to pass to the config objects.
|
||||
*
|
||||
* @return array Returns an array of configs that are associated with the specified config path.
|
||||
*/
|
||||
private function get_configs_by_path( $config_path, $args )
|
||||
{
|
||||
$configs = array();
|
||||
foreach ( $this->configs as $config ) {
|
||||
if ( $config->enable_ajax( $config_path, $args ) ) {
|
||||
$configs[] = $config;
|
||||
}
|
||||
}
|
||||
return $configs;
|
||||
}
|
||||
|
||||
/**
|
||||
* usort() callback to sort the configs by their $priority.
|
||||
*
|
||||
@@ -162,4 +211,4 @@ class GF_Config_Collection {
|
||||
|
||||
return $a->priority() < $b->priority() ? - 1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,15 @@ class GF_Config_Service_Provider extends GF_Service_Provider {
|
||||
$this->register_configs_to_collection( $container );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the config has been localized.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private static $is_localized = false;
|
||||
|
||||
/**
|
||||
* Initiailize any actions or hooks.
|
||||
*
|
||||
@@ -100,16 +109,43 @@ class GF_Config_Service_Provider extends GF_Service_Provider {
|
||||
$self = $this;
|
||||
|
||||
add_action( 'wp_enqueue_scripts', function () use ( $container ) {
|
||||
$container->get( self::CONFIG_COLLECTION )->handle();
|
||||
// Only localize during wp_enqueue_scripts if none of the other more specific events have been fired.
|
||||
if ( ! self::$is_localized ) {
|
||||
$container->get( self::CONFIG_COLLECTION )->handle();
|
||||
}
|
||||
}, 9999 );
|
||||
|
||||
add_action( 'admin_enqueue_scripts', function () use ( $container ) {
|
||||
$container->get( self::CONFIG_COLLECTION )->handle();
|
||||
// Only localize during admin_enqueue_scripts if none of the other more specific events have been fired.
|
||||
if ( ! self::$is_localized ) {
|
||||
$container->get( self::CONFIG_COLLECTION )->handle();
|
||||
}
|
||||
}, 9999 );
|
||||
|
||||
add_action( 'gform_preview_init', function () use ( $container ) {
|
||||
$container->get( self::CONFIG_COLLECTION )->handle();
|
||||
}, 0 );
|
||||
add_action( 'gform_output_config', function ( $form_ids = null ) use ( $container ) {
|
||||
$container->get( self::CONFIG_COLLECTION )->handle( true, $form_ids );
|
||||
self::$is_localized = true;
|
||||
} );
|
||||
|
||||
add_action( 'gform_post_enqueue_scripts', function ( $found_forms, $found_blocks, $post ) use ( $container ) {
|
||||
$form_ids = array_column( $found_forms, 'formId' );
|
||||
$container->get( self::CONFIG_COLLECTION )->handle( true, array( 'form_ids' => $form_ids ) );
|
||||
self::$is_localized = true;
|
||||
}, 10, 3);
|
||||
|
||||
add_action( 'gform_preview_init', function ( $form_id ) use ( $container ) {
|
||||
$form_ids = array( $form_id );
|
||||
$container->get( self::CONFIG_COLLECTION )->handle( true, array( 'form_ids' => $form_ids ) );
|
||||
self::$is_localized = true;
|
||||
}, 10, 2);
|
||||
|
||||
add_action('wp_ajax_gform_get_config', function () use ( $container ) {
|
||||
$container->get( self::CONFIG_COLLECTION )->handle_ajax();
|
||||
});
|
||||
|
||||
add_action('wp_ajax_nopriv_gform_get_config', function () use ( $container ) {
|
||||
$container->get( self::CONFIG_COLLECTION )->handle_ajax();
|
||||
});
|
||||
|
||||
add_action( 'rest_api_init', function () use ( $container, $self ) {
|
||||
register_rest_route( 'gravityforms/v2', '/tests/mock-data', array(
|
||||
@@ -206,4 +242,4 @@ class GF_Config_Service_Provider extends GF_Service_Provider {
|
||||
|
||||
return array_merge( $data, $global );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,13 @@ abstract class GF_Config {
|
||||
*/
|
||||
protected $overwrite = false;
|
||||
|
||||
/**
|
||||
* An args array. Use in the data() method to retrieve data specific to the specified args. For example, form specific configs will have an array of form ids specified in args.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $args = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -98,6 +105,26 @@ abstract class GF_Config {
|
||||
*/
|
||||
abstract protected function data();
|
||||
|
||||
/**
|
||||
* Override this method to add enable ajax loading for a specific config path.
|
||||
* To enable loading data() via ajax, check if $config_path is one of the paths that are provided by the config. If so, return true.
|
||||
*
|
||||
* Example:
|
||||
* public function enable_ajax( $config_path, $args ) {
|
||||
* return str_starts_with( $config_path, 'gform_theme_config/common/form/product_meta' );
|
||||
* }
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param string $config_path The full path to the config item when stored in the browser's window object, for example: "gform_theme_config/common/form/product_meta"
|
||||
* @param array $args The args used to load the config data. This will be empty for generic config items. For form specific items will be in the format: array( 'form_ids' => array(123,222) ).
|
||||
*
|
||||
* @return bool Return true to load the config data associated with the provided $config_path. Return false otherwise.
|
||||
*/
|
||||
public function enable_ajax( $config_path, $args ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the config should enqueue its data. If should_enqueue() is a method,
|
||||
* call it and return the result. If not, simply return the (boolean) value of the property.
|
||||
@@ -187,4 +214,68 @@ abstract class GF_Config {
|
||||
return $this->overwrite;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Sets the $form_ids arrays.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param array $args Args array to be set
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_args( $args ) {
|
||||
$this->args = $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the config data against a hash to ensure it has not been tampered with.
|
||||
* This method is called via AJAX, initiated by the gform.config.isValid() JS method.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function validate_ajax() {
|
||||
|
||||
// Check nonce
|
||||
$nonce_result = check_ajax_referer( 'gform_config_ajax', 'gform_ajax_nonce', false );
|
||||
|
||||
if ( ! $nonce_result ) {
|
||||
wp_send_json_error( esc_html__( 'Unable to verify nonce. Please refresh the page and try again.', 'gravityforms' ) );
|
||||
}
|
||||
|
||||
$config = json_decode( rgpost( 'config' ), true );
|
||||
$hash = rgar( $config, 'hash' );
|
||||
if ( ! $hash ) {
|
||||
wp_send_json_error( esc_html__( 'Invalid config.', 'gravityforms' ) );
|
||||
}
|
||||
|
||||
// Remove hash from config before validating.
|
||||
unset( $config['hash'] );
|
||||
|
||||
// Compare hash to config.
|
||||
if ( $hash !== self::hash( $config ) ) {
|
||||
wp_send_json_error( esc_html__( 'Config validation failed. Hash does not match', 'gravityforms' ) );
|
||||
}
|
||||
|
||||
// Send success response.
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashes the config data.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return string Returns the hash of the config data.
|
||||
*/
|
||||
public static function hash( $config ) {
|
||||
return wp_hash( json_encode( $config ) );
|
||||
}
|
||||
}
|
||||
|
||||
// AJAX hash validation for config data.
|
||||
add_action('wp_ajax_gform_validate_config', array( 'Gravity_Forms\Gravity_Forms\Config\GF_Config', 'validate_ajax' ) );
|
||||
add_action('wp_ajax_nopriv_gform_validate_config', array( 'Gravity_Forms\Gravity_Forms\Config\GF_Config', 'validate_ajax' ) );
|
||||
|
||||
@@ -19,6 +19,7 @@ class GF_Config_Global {
|
||||
return array(
|
||||
'hmr_dev' => defined( 'GF_ENABLE_HMR' ) && GF_ENABLE_HMR,
|
||||
'public_path' => trailingslashit( \GFCommon::get_base_url() ) . 'assets/js/dist/',
|
||||
'config_nonce' => wp_create_nonce( 'gform_config_ajax' ),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user