Remove all plugins / install base theme
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
class GFAddonLocking extends GFLocking {
|
||||
protected $_strings;
|
||||
/* @var GFAddOn $_addon */
|
||||
protected $_addon;
|
||||
|
||||
/**
|
||||
* e.g.
|
||||
*
|
||||
* array(
|
||||
* "object_type" => 'contact',
|
||||
* "capabilities" => array("gravityforms_contacts_edit_contacts"),
|
||||
* "redirect_url" => admin_url("admin.php?page=gf_contacts"),
|
||||
* "edit_url" => admin_url(sprintf("admin.php?page=gf_contacts&id=%d", $contact_id)),
|
||||
* "strings" => $strings
|
||||
* );
|
||||
*
|
||||
* @param array $config
|
||||
* @param GFAddOn $addon
|
||||
*/
|
||||
public function __construct( $config, $addon ) {
|
||||
$this->_addon = $addon;
|
||||
$capabilities = isset( $config['capabilities'] ) ? $config['capabilities'] : array();
|
||||
$redirect_url = isset( $config['redirect_url'] ) ? $config['redirect_url'] : '';
|
||||
$edit_url = isset( $config['edit_url'] ) ? $config['edit_url'] : '';
|
||||
$object_type = isset( $config['object_type'] ) ? $config['object_type'] : '';
|
||||
$this->_strings = isset( $config['strings'] ) ? $config['strings'] : array();
|
||||
parent::__construct( $object_type, $redirect_url, $edit_url, $capabilities );
|
||||
}
|
||||
|
||||
public function get_strings() {
|
||||
return array_merge( parent::get_strings(), $this->_strings );
|
||||
}
|
||||
|
||||
protected function is_edit_page() {
|
||||
return $this->_addon->is_locking_edit_page();
|
||||
}
|
||||
|
||||
protected function is_list_page() {
|
||||
return $this->_addon->is_locking_list_page();
|
||||
}
|
||||
|
||||
protected function is_view_page() {
|
||||
return $this->_addon->is_locking_view_page();
|
||||
}
|
||||
|
||||
protected function get_object_id() {
|
||||
return $this->_addon->get_locking_object_id();
|
||||
}
|
||||
|
||||
protected function is_object_locked( $object_id ) {
|
||||
return $this->is_object_locked( $object_id );
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,334 +0,0 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
class GFAutoUpgrade {
|
||||
protected $_version;
|
||||
protected $_min_gravityforms_version;
|
||||
protected $_slug;
|
||||
protected $_title;
|
||||
protected $_full_path;
|
||||
protected $_path;
|
||||
protected $_url;
|
||||
protected $_is_gravityforms_supported;
|
||||
|
||||
|
||||
public function __construct( $slug, $version, $min_gravityforms_version, $title, $full_path, $path, $url, $is_gravityforms_supported ) {
|
||||
$this->_slug = $slug;
|
||||
$this->_version = $version;
|
||||
$this->_min_gravityforms_version = $min_gravityforms_version;
|
||||
$this->_title = $title;
|
||||
$this->_full_path = $full_path;
|
||||
$this->_path = $path;
|
||||
$this->_url = $url;
|
||||
$this->_is_gravityforms_supported = $is_gravityforms_supported;
|
||||
add_action( 'init', array( $this, 'init' ) );
|
||||
}
|
||||
|
||||
public function init() {
|
||||
if ( is_admin() ) {
|
||||
GFCommon::load_gf_text_domain();
|
||||
add_action( 'install_plugins_pre_plugin-information', array( $this, 'display_changelog' ), 9 );
|
||||
add_action( 'gform_after_check_update', array( $this, 'flush_version_info' ) );
|
||||
add_action( 'gform_updates', array( $this, 'display_updates' ) );
|
||||
|
||||
add_filter( 'gform_updates_list', array( $this, 'get_update_info' ) );
|
||||
|
||||
if ( RG_CURRENT_PAGE == 'plugins.php' ) {
|
||||
add_action( 'after_plugin_row_' . $this->_path, array( $this, 'rg_plugin_row' ) );
|
||||
} elseif ( in_array( RG_CURRENT_PAGE, array( 'admin-ajax.php' ) ) ) {
|
||||
add_action( 'wp_ajax_gf_get_changelog', array( $this, 'ajax_display_changelog' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Check for updates. The check might not run the admin context. E.g. from WP-CLI.
|
||||
add_filter( 'transient_update_plugins', array( $this, 'check_update' ) );
|
||||
add_filter( 'site_transient_update_plugins', array( $this, 'check_update' ) );
|
||||
|
||||
// ManageWP premium update filters
|
||||
add_filter( 'mwp_premium_update_notification', array( $this, 'premium_update_push' ) );
|
||||
add_filter( 'mwp_premium_perform_update', array( $this, 'premium_update' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays messages for the Gravity Forms listing on the Plugins page.
|
||||
*
|
||||
* Displays if Gravity Forms isn't supported.
|
||||
*
|
||||
* @since Unknown
|
||||
* @since 2.4.15 Update to improve multisite updates.
|
||||
*/
|
||||
public function rg_plugin_row() {
|
||||
|
||||
if ( ! $this->_is_gravityforms_supported ) {
|
||||
$message = sprintf( esc_html__( 'Gravity Forms %s is required. Activate it now or %spurchase it today!%s', 'gravityforms' ), $this->_min_gravityforms_version, "<a href='https://www.gravityforms.com'>", '</a>' );
|
||||
GFAddOn::display_plugin_message( $message, true );
|
||||
}
|
||||
}
|
||||
|
||||
//Integration with ManageWP
|
||||
public function premium_update_push( $premium_update ) {
|
||||
|
||||
if ( ! function_exists( 'get_plugin_data' ) ) {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
||||
}
|
||||
|
||||
$update = $this->get_version_info( $this->_slug );
|
||||
if ( rgar( $update, 'is_valid_key' ) == true && version_compare( $this->_version, $update['version'], '<' ) ) {
|
||||
$plugin_data = get_plugin_data( $this->_full_path );
|
||||
$plugin_data['type'] = 'plugin';
|
||||
$plugin_data['slug'] = $this->_path;
|
||||
$plugin_data['new_version'] = isset( $update['version'] ) ? $update['version'] : false;
|
||||
$premium_update[] = $plugin_data;
|
||||
}
|
||||
|
||||
return $premium_update;
|
||||
}
|
||||
|
||||
//Integration with ManageWP
|
||||
public function premium_update( $premium_update ) {
|
||||
|
||||
if ( ! function_exists( 'get_plugin_data' ) ) {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
||||
}
|
||||
|
||||
$update = $this->get_version_info( $this->_slug );
|
||||
if ( rgar( $update, 'is_valid_key' ) == true && version_compare( $this->_version, $update['version'], '<' ) ) {
|
||||
$plugin_data = get_plugin_data( $this->_full_path );
|
||||
$plugin_data['slug'] = $this->_path;
|
||||
$plugin_data['type'] = 'plugin';
|
||||
$plugin_data['url'] = isset( $update['url'] ) ? $update['url'] : false; // OR provide your own callback function for managing the update
|
||||
|
||||
array_push( $premium_update, $plugin_data );
|
||||
}
|
||||
|
||||
return $premium_update;
|
||||
}
|
||||
|
||||
public function flush_version_info() {
|
||||
$this->set_version_info( $this->_slug, false );
|
||||
}
|
||||
|
||||
private function set_version_info( $plugin_slug, $version_info ) {
|
||||
if ( function_exists( 'set_site_transient' ) ) {
|
||||
set_site_transient( $plugin_slug . '_version', $version_info, 60 * 60 * 12 );
|
||||
} else {
|
||||
set_transient( $plugin_slug . '_version', $version_info, 60 * 60 * 12 );
|
||||
}
|
||||
}
|
||||
|
||||
public function check_update( $option ) {
|
||||
|
||||
if ( empty( $option ) ) {
|
||||
return $option;
|
||||
}
|
||||
|
||||
$key = $this->get_key();
|
||||
|
||||
$version_info = $this->get_version_info( $this->_slug );
|
||||
|
||||
if ( rgar( $version_info, 'is_error' ) == '1' ) {
|
||||
return $option;
|
||||
}
|
||||
|
||||
if ( empty( $option->response[ $this->_path ] ) ) {
|
||||
$option->response[ $this->_path ] = new stdClass();
|
||||
}
|
||||
|
||||
$plugin = array(
|
||||
'plugin' => $this->_path,
|
||||
'url' => $this->_url,
|
||||
'slug' => $this->_slug,
|
||||
'package' => $version_info['url'] ? str_replace( '{KEY}', $key, $version_info['url'] ) : '',
|
||||
'new_version' => $version_info['version'],
|
||||
'id' => '0',
|
||||
);
|
||||
|
||||
//Empty response means that the key is invalid. Do not queue for upgrade
|
||||
if ( ! rgar( $version_info, 'is_valid_key' ) || version_compare( $this->_version, $version_info['version'], '>=' ) ) {
|
||||
unset( $option->response[ $this->_path ] );
|
||||
$option->no_update[ $this->_path ] = (object) $plugin;
|
||||
} else {
|
||||
$option->response[ $this->_path ] = (object) $plugin;
|
||||
}
|
||||
|
||||
return $option;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Displays current version details on plugins page and updates page
|
||||
public function display_changelog() {
|
||||
if ( $_REQUEST['plugin'] != $this->_slug ) {
|
||||
return;
|
||||
}
|
||||
$change_log = $this->get_changelog();
|
||||
echo $change_log;
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get changelog with admin-ajax.php in GFForms::maybe_display_update_notification().
|
||||
*
|
||||
* @since 2.4.15
|
||||
*/
|
||||
public function ajax_display_changelog() {
|
||||
check_admin_referer();
|
||||
|
||||
$this->display_changelog();
|
||||
}
|
||||
|
||||
private function get_changelog() {
|
||||
$key = $this->get_key();
|
||||
$body = "key={$key}";
|
||||
$options = array( 'method' => 'POST', 'timeout' => 3, 'body' => $body );
|
||||
$options['headers'] = array(
|
||||
'Content-Type' => 'application/x-www-form-urlencoded; charset=' . get_option( 'blog_charset' ),
|
||||
'Content-Length' => strlen( $body ),
|
||||
'User-Agent' => 'WordPress/' . get_bloginfo( 'version' ),
|
||||
);
|
||||
|
||||
$raw_response = GFCommon::post_to_manager( 'changelog.php', $this->get_remote_request_params( $this->_slug, $key, $this->_version ), $options );
|
||||
|
||||
if ( is_wp_error( $raw_response ) || 200 != $raw_response['response']['code'] ) {
|
||||
$text = sprintf( esc_html__( 'Oops!! Something went wrong.%sPlease try again or %scontact us%s.', 'gravityforms' ), '<br/>', "<a href='" . esc_attr( GFCommon::get_support_url() ). "'>", '</a>' );
|
||||
} else {
|
||||
$text = $raw_response['body'];
|
||||
if ( substr( $text, 0, 10 ) != '<!--GFM-->' ) {
|
||||
$text = '';
|
||||
}
|
||||
}
|
||||
|
||||
return stripslashes( $text );
|
||||
}
|
||||
|
||||
private function get_version_info( $offering, $use_cache = true ) {
|
||||
|
||||
$version_info = GFCommon::get_version_info( $use_cache );
|
||||
$is_valid_key = rgar( $version_info, 'is_valid_key' ) && rgars( $version_info, "offerings/{$offering}/is_available" );
|
||||
|
||||
$info = array( 'is_valid_key' => $is_valid_key, 'version' => rgars( $version_info, "offerings/{$offering}/version" ), 'url' => rgars( $version_info, "offerings/{$offering}/url" ) );
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
private function get_remote_request_params( $offering, $key, $version ) {
|
||||
global $wpdb;
|
||||
|
||||
return sprintf( 'of=%s&key=%s&v=%s&wp=%s&php=%s&mysql=%s', urlencode( $offering ), urlencode( $key ), urlencode( $version ), urlencode( get_bloginfo( 'version' ) ), urlencode( phpversion() ), urlencode( GFCommon::get_db_version() ) );
|
||||
}
|
||||
|
||||
private function get_key() {
|
||||
if ( $this->_is_gravityforms_supported ) {
|
||||
return GFCommon::get_key();
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function get_update_info( $updates ) {
|
||||
|
||||
$force_check = rgget( 'force-check' ) == 1;
|
||||
$version_info = $this->get_version_info( $this->_slug, ! $force_check );
|
||||
|
||||
$plugin_file = $this->_path;
|
||||
$upgrade_url = wp_nonce_url( 'update.php?action=upgrade-plugin&plugin=' . urlencode( $plugin_file ), 'upgrade-plugin_' . $plugin_file );
|
||||
|
||||
if ( ! rgar( $version_info, 'is_valid_key' ) ) {
|
||||
|
||||
$version_icon = 'dashicons-no';
|
||||
$version_message = sprintf(
|
||||
'<p>%s</p>',
|
||||
sprintf(
|
||||
esc_html( '%sRegister%s your copy of Gravity Forms to receive access to automatic updates and support. Need a license key? %sPurchase one now%s.', 'gravityforms' ),
|
||||
'<a href="admin.php?page=gf_settings">',
|
||||
'</a>',
|
||||
'<a href="https://www.gravityforms.com">',
|
||||
'</a>'
|
||||
)
|
||||
);
|
||||
|
||||
} elseif ( version_compare( $this->_version, $version_info['version'], '<' ) ) {
|
||||
|
||||
$details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . urlencode( $this->_slug ) . '§ion=changelog&TB_iframe=true&width=600&height=800' );
|
||||
$message_link_text = sprintf( esc_html__( 'View version %s details', 'gravityforms' ), $version_info['version'] );
|
||||
$message_link = sprintf( '<a href="%s" class="thickbox" title="%s">%s</a>', esc_url( $details_url ), esc_attr( $this->_title ), $message_link_text );
|
||||
$message = sprintf( esc_html__( 'There is a new version of %1$s available. %s.', 'gravityforms' ), $this->_title, $message_link );
|
||||
|
||||
$version_icon = 'dashicons-no';
|
||||
$version_message = $message;
|
||||
|
||||
} else {
|
||||
|
||||
$version_icon = 'dashicons-yes';
|
||||
$version_message = sprintf( esc_html__( 'Your version of %s is up to date.', 'gravityforms' ), $this->_title );
|
||||
}
|
||||
|
||||
$updates[] = array(
|
||||
'name' => esc_html( $this->_title ),
|
||||
'is_valid_key' => rgar( $version_info, 'is_valid_key' ),
|
||||
'path' => $this->_path,
|
||||
'slug' => $this->_slug,
|
||||
'latest_version' => $version_info['version'],
|
||||
'installed_version' => $this->_version,
|
||||
'upgrade_url' => $upgrade_url,
|
||||
'download_url' => $version_info['url'],
|
||||
'version_icon' => $version_icon,
|
||||
'version_message' => $version_message,
|
||||
);
|
||||
|
||||
return $updates;
|
||||
|
||||
}
|
||||
|
||||
public function display_updates() {
|
||||
|
||||
?>
|
||||
<div class="wrap <?php echo GFCommon::get_browser_class() ?>">
|
||||
<h2><?php esc_html_e( $this->_title ); ?></h2>
|
||||
<?php
|
||||
$force_check = rgget( 'force-check' ) == 1;
|
||||
$version_info = $this->get_version_info( $this->_slug, ! $force_check );
|
||||
|
||||
if ( ! rgar( $version_info, 'is_valid_key' ) ) {
|
||||
?>
|
||||
<div class="gf_update_expired alert_red">
|
||||
<?php printf( esc_html__( '%sRegister%s your copy of Gravity Forms to receive access to automatic updates and support. Need a license key? %sPurchase one now%s.', 'gravityforms' ), '<a href="admin.php?page=gf_settings">','</a>','<a href="https://www.gravityforms.com">', '</a>' ); ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
} elseif ( version_compare( $this->_version, $version_info['version'], '<' ) ) {
|
||||
|
||||
if ( rgar( $version_info, 'is_valid_key' ) ) {
|
||||
$plugin_file = $this->_path;
|
||||
$upgrade_url = wp_nonce_url( 'update.php?action=upgrade-plugin&plugin=' . urlencode( $plugin_file ), 'upgrade-plugin_' . $plugin_file );
|
||||
$details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . urlencode( $this->_slug ) . '§ion=changelog&TB_iframe=true&width=600&height=800' );
|
||||
$message_link_text = sprintf( esc_html__( 'View version %s details', 'gravityforms' ), $version_info['version'] );
|
||||
$message_link = sprintf( '<a href="%s" class="thickbox" title="%s">%s</a>', esc_url( $details_url ), esc_attr( $this->_title ), $message_link_text );
|
||||
$message = sprintf( esc_html__( 'There is a new version of %1$s available. %s.', 'gravityforms' ), $this->_title, $message_link );
|
||||
|
||||
?>
|
||||
<div class="gf_update_outdated alert_yellow">
|
||||
<?php echo $message . ' <p>' . sprintf( esc_html__( 'You can update to the latest version automatically or download the update and install it manually. %sUpdate Automatically%s %sDownload Update%s', 'gravityforms' ), "</p><a class='button-primary' href='{$upgrade_url}'>", '</a>', " <a class='button' href='{$version_info['url']}'>", '</a>' ); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
} else {
|
||||
|
||||
?>
|
||||
<div class="gf_update_current alert_green">
|
||||
<?php printf( esc_html__( 'Your version of %s is up to date.', 'gravityforms' ), $this->_title ); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,310 +0,0 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'GF_Background_Process' ) ) {
|
||||
require_once GF_PLUGIN_DIR_PATH . 'includes/libraries/gf-background-process.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* GF_Feed_Processor Class.
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
class GF_Feed_Processor extends GF_Background_Process {
|
||||
|
||||
/**
|
||||
* Contains an instance of this class, if available.
|
||||
*
|
||||
* @since 2.2
|
||||
* @access private
|
||||
* @var object $_instance If available, contains an instance of this class.
|
||||
*/
|
||||
private static $_instance = null;
|
||||
|
||||
/**
|
||||
* The action name.
|
||||
*
|
||||
* @since 2.2
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $action = 'gf_feed_processor';
|
||||
|
||||
/**
|
||||
* Get instance of this class.
|
||||
*
|
||||
* @since 2.2
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return GF_Feed_Processor
|
||||
*/
|
||||
public static function get_instance() {
|
||||
|
||||
if ( null === self::$_instance ) {
|
||||
self::$_instance = new self;
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Task
|
||||
*
|
||||
* @since 2.2
|
||||
* @access protected
|
||||
*
|
||||
* Override this method to perform any actions required on each
|
||||
* queue item. Return the modified item for further processing
|
||||
* in the next pass through. Or, return false to remove the
|
||||
* item from the queue.
|
||||
*
|
||||
* @param array $item The task arguments: addon, feed, entry_id, and form_id.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function task( $item ) {
|
||||
|
||||
$addon = $item['addon'];
|
||||
$feed = $item['feed'];
|
||||
$feed_name = rgars( $feed, 'meta/feed_name' ) ? $feed['meta']['feed_name'] : rgars( $feed, 'meta/feedName' );
|
||||
|
||||
$callable = array( is_string( $addon ) ? $addon : get_class( $addon ), 'get_instance' );
|
||||
if ( is_callable( $callable ) ) {
|
||||
$addon = call_user_func( $callable );
|
||||
}
|
||||
|
||||
if ( ! $addon instanceof GFFeedAddOn ) {
|
||||
GFCommon::log_error( __METHOD__ . "(): attempted feed (#{$feed['id']} - {$feed_name}) for entry #{$item['entry_id']} for {$feed['addon_slug']} but add-on could not be found. Bailing." );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$entry = GFAPI::get_entry( $item['entry_id'] );
|
||||
$addon_slug = $addon->get_slug();
|
||||
|
||||
// Remove task if entry cannot be found.
|
||||
if ( is_wp_error( $entry ) ) {
|
||||
|
||||
call_user_func( array(
|
||||
$addon,
|
||||
'log_debug',
|
||||
), __METHOD__ . "(): attempted feed (#{$feed['id']} - {$feed_name}) for entry #{$item['entry_id']} for {$addon_slug} but entry could not be found. Bailing." );
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
$processed_feeds = $addon->get_feeds_by_entry( $entry['id'] );
|
||||
|
||||
if ( is_array( $processed_feeds ) && in_array( $feed['id'], $processed_feeds ) ) {
|
||||
call_user_func( array(
|
||||
$addon,
|
||||
'log_debug',
|
||||
), __METHOD__ . "(): already processed feed (#{$feed['id']} - {$feed_name}) for entry #{$entry['id']} for {$addon_slug}. Bailing." );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$item = $this->increment_attempts( $item );
|
||||
|
||||
$max_attempts = 1;
|
||||
$form = $this->filter_form( GFAPI::get_form( $item['form_id'] ), $entry );
|
||||
|
||||
/**
|
||||
* Allow the number of retries to be modified before the feed is abandoned.
|
||||
*
|
||||
* if $max_attempts > 1 and if GFFeedAddOn::process_feed() throws an error or returns a WP_Error then the feed
|
||||
* will be attempted again. Once the maximum number of attempts has been reached then the feed will be abandoned.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param int $max_attempts The maximum number of retries allowed. Default: 1.
|
||||
* @param array $form The form array
|
||||
* @param array $entry The entry array
|
||||
* @param string $addon_slug The add-on slug
|
||||
* @param array $feed The feed array
|
||||
*/
|
||||
$max_attempts = apply_filters( 'gform_max_async_feed_attempts', $max_attempts, $form, $entry, $addon_slug, $feed );
|
||||
|
||||
// Remove task if it was attempted too many times but failed to complete.
|
||||
if ( $item['attempts'] > $max_attempts ) {
|
||||
|
||||
call_user_func( array(
|
||||
$addon,
|
||||
'log_debug',
|
||||
), __METHOD__ . "(): attempted feed (#{$feed['id']} - {$feed_name}) for entry #{$entry['id']} for {$addon->get_slug()} too many times. Bailing." );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use the add-on to log the start of feed processing.
|
||||
call_user_func( array(
|
||||
$addon,
|
||||
'log_debug',
|
||||
), __METHOD__ . "(): Starting to process feed (#{$feed['id']} - {$feed_name}) for entry #{$entry['id']} for {$addon->get_slug()}. Attempt number: " . $item['attempts'] );
|
||||
|
||||
try {
|
||||
|
||||
// Maybe convert PHP errors to exceptions so that they get caught.
|
||||
// This will catch some fatal errors, but not all.
|
||||
// Errors that are not caught will halt execution of subsequent feeds, but those will be
|
||||
// executed during the next cron cycles, which happens every 5 minutes
|
||||
set_error_handler( array( $this, 'custom_error_handler' ) );
|
||||
|
||||
// Process feed.
|
||||
$returned_entry = call_user_func( array( $addon, 'process_feed' ), $feed, $entry, $form );
|
||||
|
||||
// Back to built-in error handler.
|
||||
restore_error_handler();
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
|
||||
// Back to built-in error handler.
|
||||
restore_error_handler();
|
||||
|
||||
// Log the exception.
|
||||
call_user_func( array(
|
||||
$addon,
|
||||
'log_error',
|
||||
), __METHOD__ . "(): Unable to process feed due to error: {$e->getMessage()}" );
|
||||
|
||||
// Return the item for another attempt
|
||||
return $item;
|
||||
}
|
||||
|
||||
if ( is_wp_error( $returned_entry ) ) {
|
||||
/** @var WP_Error $returned_entry */
|
||||
// Log the error.
|
||||
call_user_func( array(
|
||||
$addon,
|
||||
'log_error',
|
||||
), __METHOD__ . "(): Unable to process feed due to error: {$returned_entry->get_error_message()}" );
|
||||
|
||||
// Return the item for another attempt
|
||||
return $item;
|
||||
}
|
||||
|
||||
|
||||
// If returned value from the process feed call is an array containing an ID, update entry and set the entry to its value.
|
||||
if ( is_array( $returned_entry ) && rgar( $returned_entry, 'id' ) ) {
|
||||
|
||||
// Set entry to returned entry.
|
||||
$entry = $returned_entry;
|
||||
|
||||
// Save updated entry.
|
||||
if ( $entry !== $returned_entry ) {
|
||||
GFAPI::update_entry( $entry );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a custom action when a feed has been processed.
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @param array $feed The feed which was processed.
|
||||
* @param array $entry The current entry object, which may have been modified by the processed feed.
|
||||
* @param array $form The current form object.
|
||||
* @param GFAddOn $addon The current instance of the GFAddOn object which extends GFFeedAddOn or GFPaymentAddOn (i.e. GFCoupons, GF_User_Registration, GFStripe).
|
||||
*/
|
||||
do_action( 'gform_post_process_feed', $feed, $entry, $form, $addon );
|
||||
do_action( "gform_{$feed['addon_slug']}_post_process_feed", $feed, $entry, $form, $addon );
|
||||
|
||||
// Log that Add-On has been fulfilled.
|
||||
call_user_func( array(
|
||||
$addon,
|
||||
'log_debug',
|
||||
), __METHOD__ . '(): Marking entry #' . $entry['id'] . ' as fulfilled for ' . $feed['addon_slug'] );
|
||||
gform_update_meta( $entry['id'], "{$feed['addon_slug']}_is_fulfilled", true );
|
||||
|
||||
// Get current processed feeds.
|
||||
$meta = gform_get_meta( $entry['id'], 'processed_feeds' );
|
||||
|
||||
// If no feeds have been processed for this entry, initialize the meta array.
|
||||
if ( empty( $meta ) ) {
|
||||
$meta = array();
|
||||
}
|
||||
|
||||
// Add this feed to this Add-On's processed feeds.
|
||||
$meta[ $feed['addon_slug'] ][] = $feed['id'];
|
||||
|
||||
// Update the entry meta.
|
||||
gform_update_meta( $entry['id'], 'processed_feeds', $meta );
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom error handler to convert any errors to an exception.
|
||||
*
|
||||
* @since 2.2
|
||||
* @since 2.6.5 Removed the $context param.
|
||||
* @access public
|
||||
*
|
||||
* @param int $number The level of error raised.
|
||||
* @param string $string The error message, as a string.
|
||||
* @param string $file The filename the error was raised in.
|
||||
* @param int $line The line number the error was raised at.
|
||||
* @param array $context An array that points to the active symbol table at the point the error occurred.
|
||||
*
|
||||
* @throws ErrorException
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public function custom_error_handler( $number, $string, $file, $line ) {
|
||||
|
||||
// Determine if this error is one of the enabled ones in php config (php.ini, .htaccess, etc).
|
||||
$error_is_enabled = (bool) ( $number & ini_get( 'error_reporting' ) );
|
||||
|
||||
// Throw an Error Exception, to be handled by whatever Exception handling logic is available in this context.
|
||||
if ( in_array( $number, array( E_USER_ERROR, E_RECOVERABLE_ERROR ) ) && $error_is_enabled ) {
|
||||
|
||||
throw new ErrorException( $string, 0, $number, $file, $line );
|
||||
|
||||
} elseif ( $error_is_enabled ) {
|
||||
|
||||
// Log the error if it's enabled. Otherwise, just ignore it.
|
||||
error_log( $string, 0 );
|
||||
|
||||
// Make sure this ends up in $php_errormsg, if appropriate.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function increment_attempts( $item ) {
|
||||
$batch = $this->get_batch();
|
||||
|
||||
$item_feed = rgar( $item, 'feed' );
|
||||
$item_entry_id = rgar( $item, 'entry_id' );
|
||||
|
||||
foreach ( $batch->data as $key => $task ) {
|
||||
$task_feed = rgar( $task, 'feed' );
|
||||
$task_entry_id = rgar( $task, 'entry_id' );
|
||||
if ( $item_feed['id'] === $task_feed['id'] && $item_entry_id === $task_entry_id ) {
|
||||
$batch->data[ $key ]['attempts'] = isset( $batch->data[ $key ]['attempts'] ) ? $batch->data[ $key ]['attempts'] + 1 : 1;
|
||||
$item['attempts'] = $batch->data[ $key ]['attempts'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->update( $batch->key, $batch->data );
|
||||
return $item;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the GF_Feed_Processor class
|
||||
*
|
||||
* @see GF_Feed_Processor::get_instance()
|
||||
* @return GF_Feed_Processor
|
||||
*/
|
||||
function gf_feed_processor() {
|
||||
return GF_Feed_Processor::get_instance();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,927 +0,0 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'GFResults' ) ) {
|
||||
|
||||
class GFResults {
|
||||
protected $_slug;
|
||||
protected $_title;
|
||||
protected $_icon;
|
||||
protected $_callbacks;
|
||||
protected $_capabilities;
|
||||
protected $_search_title;
|
||||
|
||||
public function __construct( $slug, $config ) {
|
||||
$this->_slug = $slug;
|
||||
$this->_title = rgar( $config, 'title' );
|
||||
$this->_icon = rgar( $config, 'icon' );
|
||||
$this->_search_title = rgempty( 'search_title', $config ) ? esc_html__( 'Results Filters', 'gravityforms' ) : rgar( $config, 'search_title' );
|
||||
$this->_callbacks = isset( $config['callbacks'] ) ? $config['callbacks'] : array();
|
||||
$this->_capabilities = isset( $config['capabilities'] ) ? $config['capabilities'] : array();
|
||||
}
|
||||
|
||||
public function init() {
|
||||
|
||||
if ( ! GFCommon::current_user_can_any( $this->_capabilities ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// is any GF page
|
||||
if ( GFForms::is_gravity_page() ) {
|
||||
|
||||
// add top toolbar menu item
|
||||
add_filter( 'gform_toolbar_menu', array( $this, 'add_toolbar_menu_item' ), 10, 2 );
|
||||
|
||||
// add custom form action
|
||||
add_filter( 'gform_form_actions', array( $this, 'add_form_action' ), 10, 2 );
|
||||
|
||||
}
|
||||
|
||||
// is results page
|
||||
if ( rgget( 'view' ) == "gf_results_{$this->_slug}" ) {
|
||||
|
||||
// add the results view
|
||||
add_action( 'gform_entries_view', array( $this, 'add_view' ), 10, 2 );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
|
||||
|
||||
// tooltips
|
||||
require_once( GFCommon::get_base_path() . '/tooltips.php' );
|
||||
add_filter( 'gform_tooltips', array( $this, 'add_tooltips' ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function enqueue_admin_scripts() {
|
||||
wp_enqueue_script( 'jquery-ui-resizable' );
|
||||
wp_enqueue_script( 'jquery-ui-datepicker' );
|
||||
|
||||
wp_enqueue_script( 'google_charts' );
|
||||
wp_enqueue_style( 'gaddon_results_css' );
|
||||
wp_enqueue_script( 'gaddon_results_js' );
|
||||
$this->localize_results_scripts();
|
||||
}
|
||||
|
||||
public static function localize_results_scripts() {
|
||||
|
||||
// Get current page protocol
|
||||
$protocol = isset( $_SERVER['HTTPS'] ) ? 'https://' : 'http://';
|
||||
// Output admin-ajax.php URL with same protocol as current page
|
||||
|
||||
$vars = array(
|
||||
'ajaxurl' => admin_url( 'admin-ajax.php', $protocol ),
|
||||
'imagesUrl' => GFCommon::get_base_url() . '/images'
|
||||
);
|
||||
|
||||
wp_localize_script( 'gaddon_results_js', 'gresultsVars', $vars );
|
||||
|
||||
$strings = array(
|
||||
'ajaxError' => wp_strip_all_tags( __( 'Error retrieving results. If the problem persists, please contact support.', 'gravityforms' ) )
|
||||
);
|
||||
|
||||
wp_localize_script( 'gaddon_results_js', 'gresultsStrings', $strings );
|
||||
|
||||
}
|
||||
|
||||
private function get_fields( $form ) {
|
||||
return isset( $this->_callbacks['fields'] ) ? call_user_func( $this->_callbacks['fields'], $form ) : $form['fields'];
|
||||
}
|
||||
|
||||
public function add_form_action( $actions, $form_id ) {
|
||||
return $this->filter_menu_items( $actions, $form_id, true );
|
||||
}
|
||||
|
||||
public function add_toolbar_menu_item( $menu_items, $form_id ) {
|
||||
return $this->filter_menu_items( $menu_items, $form_id, false );
|
||||
}
|
||||
|
||||
public function filter_menu_items( $menu_items, $form_id, $compact ) {
|
||||
$form_meta = GFFormsModel::get_form_meta( $form_id );
|
||||
$results_fields = $this->get_fields( $form_meta );
|
||||
if ( false === empty( $results_fields ) ) {
|
||||
$form_id = $form_meta['id'];
|
||||
$link_class = '';
|
||||
if ( rgget( 'page' ) == 'gf_new_form' ) {
|
||||
$link_class = 'gf_toolbar_disabled';
|
||||
} elseif ( rgget( 'page' ) == 'gf_entries' && rgget( 'view' ) == 'gf_results_' . $this->_slug ) {
|
||||
$link_class = 'gf_toolbar_active';
|
||||
}
|
||||
|
||||
$id = rgget( 'id' );
|
||||
if ( empty( $id ) ) {
|
||||
//on the form list page, do not use icons.
|
||||
$icon = '';
|
||||
} else {
|
||||
$icon = $this->_icon;
|
||||
if ( empty( $icon ) ) {
|
||||
$icon = '<i class="fa fa-bar-chart-o fa-lg"></i>';
|
||||
}
|
||||
}
|
||||
|
||||
$sub_menu_items = array();
|
||||
$sub_menu_items[] = array(
|
||||
'label' => $this->_title,
|
||||
'icon' => $icon,
|
||||
'title' => esc_html__( 'View results generated by this form', 'gravityforms' ),
|
||||
'link_class' => $link_class,
|
||||
'url' => admin_url( "admin.php?page=gf_entries&view=gf_results_{$this->_slug}&id={$form_id}" ),
|
||||
'capabilities' => $this->_capabilities,
|
||||
);
|
||||
|
||||
$duplicate_submenus = wp_filter_object_list( rgars( $menu_items, 'results/sub_menu_items' ), array( 'label' => $sub_menu_items[0]['label'] ) );
|
||||
if ( count( $duplicate_submenus ) > 0 ) {
|
||||
return $menu_items;
|
||||
}
|
||||
|
||||
// If there's already a menu item with the key "results" then merge the two.
|
||||
if ( isset( $menu_items['results'] ) ) {
|
||||
$existing_link_class = $menu_items['results']['link_class'];
|
||||
$link_class == empty( $existing_link_class ) ? $link_class : $existing_link_class;
|
||||
$existing_capabilities = $menu_items['results']['capabilities'];
|
||||
$merged_capabilities = array_merge( $existing_capabilities, $this->_capabilities );
|
||||
$existing_sub_menu_items = isset( $menu_items['results']['sub_menu_items'] ) ? $menu_items['results']['sub_menu_items'] : $menu_items['results']['single_menu_item'];
|
||||
$merged_sub_menu_items = array_merge( $existing_sub_menu_items, $sub_menu_items );
|
||||
$menu_items['results']['link_class'] = $link_class;
|
||||
$menu_items['results']['capabilities'] = $merged_capabilities;
|
||||
$menu_items['results']['sub_menu_items'] = $merged_sub_menu_items;
|
||||
$menu_items['results']['label'] = esc_html__( 'Results', 'gravityforms' );
|
||||
$menu_items['results']['icon'] = '<i class="fa fa-bar-chart-o fa-lg"></i>';
|
||||
|
||||
} else {
|
||||
// so far during the page cycle this is the only menu item for this key.
|
||||
$menu_items['results'] = array(
|
||||
'label' => $compact ? esc_html__( 'Results', 'gravityforms' ) : $this->_title,
|
||||
'icon' => $icon,
|
||||
'title' => esc_attr__( 'View results generated by this form', 'gravityforms' ),
|
||||
'url' => admin_url( "admin.php?page=gf_entries&view=gf_results_{$this->_slug}&id={$form_id}" ),
|
||||
'menu_class' => 'gf_form_toolbar_results',
|
||||
'link_class' => $link_class,
|
||||
'capabilities' => $this->_capabilities,
|
||||
'single_menu_item' => $sub_menu_items,
|
||||
'priority' => 750,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $menu_items;
|
||||
}
|
||||
|
||||
|
||||
public function add_view( $view, $form_id ) {
|
||||
if ( $view == 'gf_results_' . $this->_slug ) {
|
||||
$form_id = absint( $form_id );
|
||||
GFResults::results_page( $form_id, $this->_title, 'gf_entries', $view );
|
||||
}
|
||||
}
|
||||
|
||||
public function results_page( $form_id, $page_title, $gf_page, $gf_view ) {
|
||||
$form_id = absint( $form_id );
|
||||
if ( empty( $form_id ) ) {
|
||||
$forms = RGFormsModel::get_forms();
|
||||
if ( ! empty( $forms ) ) {
|
||||
$form_id = $forms[0]->id;
|
||||
}
|
||||
}
|
||||
$form = GFFormsModel::get_form_meta( $form_id );
|
||||
$form = gf_apply_filters( array( 'gform_form_pre_results', $form_id ), $form );
|
||||
|
||||
// Set up filter vars
|
||||
$start_date = preg_replace( '/[^0-9-]/', '', rgget( 'start' ) );
|
||||
$end_date = preg_replace( '/[^0-9-]/', '', rgget( 'end' ) );
|
||||
|
||||
$all_fields = $form['fields'];
|
||||
|
||||
$filter_settings = GFCommon::get_field_filter_settings( $form );
|
||||
$filter_settings = apply_filters( 'gform_filters_pre_results', $filter_settings, $form );
|
||||
$filter_settings = array_values( $filter_settings ); // reset the numeric keys in case some filters have been unset
|
||||
|
||||
$filter_fields = rgget( 'f' );
|
||||
$filter_operators = rgget( 'o' );
|
||||
$filter_values = rgget( 'v' );
|
||||
$filters = array();
|
||||
|
||||
$init_vars = array();
|
||||
if ( ! empty( $filter_fields ) ) {
|
||||
$init_vars['mode'] = rgget( 'mode' );
|
||||
foreach ( $filter_fields as $i => $filter_field ) {
|
||||
$filters[ $i ]['field'] = $filter_field;
|
||||
$filters[ $i ]['operator'] = $filter_operators[ $i ];
|
||||
$filters[ $i ]['value'] = $filter_values[ $i ];
|
||||
}
|
||||
$init_vars['filters'] = $filters;
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var gresultsFields = <?php echo json_encode( $all_fields ); ?>;
|
||||
var gresultsFilterSettings = <?php echo json_encode( $filter_settings ); ?>;
|
||||
var gresultsInitVars = <?php echo json_encode( $init_vars ); ?>;
|
||||
|
||||
<?php GFCommon::gf_global() ?>
|
||||
<?php GFCommon::gf_vars() ?>
|
||||
</script>
|
||||
|
||||
<div class="wrap gforms_edit_form <?php echo GFCommon::get_browser_class() ?>">
|
||||
|
||||
<?php //GFCommon::form_page_title( $form ); ?>
|
||||
<?php //GFCommon::display_dismissible_message(); ?>
|
||||
<?php //GFForms::top_toolbar(); ?>
|
||||
<?php GFForms::admin_header(array(), true ) ;?>
|
||||
<?php if ( false === empty( $all_fields ) ) : ?>
|
||||
|
||||
<div id="poststuff" class="metabox-holder has-right-sidebar">
|
||||
<div id="side-info-column" class="inner-sidebar">
|
||||
<div id="gresults-results-filter" class="gform-settings-panel__content postbox">
|
||||
<h2><?php echo $this->_search_title ?></h2>
|
||||
|
||||
<div id="gresults-results-filter-content">
|
||||
<form id="gresults-results-filter-form" action="" method="GET">
|
||||
<?php wp_nonce_field( 'gf_results', '_gf_results_nonce' ); ?>
|
||||
<input type="hidden" id="gresults-page-slug" name="page"
|
||||
value="<?php echo esc_attr( $gf_page ); ?>">
|
||||
<input type="hidden" id="gresults-view-slug" name="view"
|
||||
value="<?php echo esc_attr( $gf_view ); ?>">
|
||||
<input type="hidden" id="gresults-form-id" name="id"
|
||||
value="<?php echo esc_attr( $form_id ); ?>">
|
||||
|
||||
<?php
|
||||
$filter_ui = array(
|
||||
'fields' => array(
|
||||
'label' => esc_attr__( 'Include results if', 'gravityforms' ),
|
||||
'tooltip' => 'gresults_filters',
|
||||
'markup' => '<div class="gform-settings-field__conditional-logic"><div id="gresults-results-field-filters-container">
|
||||
<!-- placeholder populated by js -->
|
||||
</div></div>',
|
||||
),
|
||||
'start_date' => array(
|
||||
'label' => esc_attr__( 'Start date', 'gravityforms' ),
|
||||
'markup' => '<div class="gform-settings-field gform-settings-field__date_time">
|
||||
<span class="gform-settings-input__container"><input type="text" id="gresults-results-filter-date-start" name="start" value="' . esc_attr( $start_date ) . '"/><button type="button" class="ui-datepicker-trigger"><span class="screen-reader-text">'.esc_html__( 'Open Date Picker', 'gravityforms' ).'</span><svg width="18" height="18" role="presentation" focusable="false" fill="#9092B2" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.0909 1.6364V1.231C13.0909.5513 13.6357 0 14.3182 0c.6778 0 1.2273.5468 1.2273 1.2311v.4053h.8254c.8997 0 1.6291.7349 1.6291 1.6288v13.106C18 17.2707 17.2721 18 16.3709 18H1.6291C.7294 18 0 17.2651 0 16.3712V3.2652c0-.8996.728-1.6288 1.6291-1.6288h.8254V1.231C2.4545.5513 2.9993 0 3.6818 0c.6778 0 1.2273.5468 1.2273 1.2311v.4053h2.4545V1.231C7.3636.5513 7.9084 0 8.591 0c.6778 0 1.2273.5468 1.2273 1.2311v.4053h3.2727zM1.6364 7.3636v9h14.7272v-9H1.6364z"></path></svg></button></span>
|
||||
</div>',
|
||||
),
|
||||
'end_date' => array(
|
||||
'label' => esc_attr__( 'End date', 'gravityforms' ),
|
||||
'markup' => '<div class="gform-settings-field gform-settings-field__date_time" >
|
||||
<span class="gform-settings-input__container"><input type="text" id="gresults-results-filter-date-end" name="end" value="' . esc_attr( $end_date ) . '"/><button type="button" class="ui-datepicker-trigger"><span class="screen-reader-text">'.esc_html__( 'Open Date Picker', 'gravityforms' ).'</span><svg width="18" height="18" role="presentation" focusable="false" fill="#9092B2" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M13.0909 1.6364V1.231C13.0909.5513 13.6357 0 14.3182 0c.6778 0 1.2273.5468 1.2273 1.2311v.4053h.8254c.8997 0 1.6291.7349 1.6291 1.6288v13.106C18 17.2707 17.2721 18 16.3709 18H1.6291C.7294 18 0 17.2651 0 16.3712V3.2652c0-.8996.728-1.6288 1.6291-1.6288h.8254V1.231C2.4545.5513 2.9993 0 3.6818 0c.6778 0 1.2273.5468 1.2273 1.2311v.4053h2.4545V1.231C7.3636.5513 7.9084 0 8.591 0c.6778 0 1.2273.5468 1.2273 1.2311v.4053h3.2727zM1.6364 7.3636v9h14.7272v-9H1.6364z"></path></svg></button></span>
|
||||
</div>',
|
||||
),
|
||||
);
|
||||
$filter_ui = apply_filters( 'gform_filter_ui', $filter_ui, $form_id, $page_title, $gf_page, $gf_view );
|
||||
|
||||
foreach ( $filter_ui as $name => $filter ) {
|
||||
?>
|
||||
<div class="gform-settings-field__header"><label class='gform-settings-label'><?php echo $filter['label'] ?><?php gform_tooltip( rgar( $filter, 'tooltip' ), 'tooltip_bottomleft' ) ?></label></div>
|
||||
<?php
|
||||
echo $filter['markup'];
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
|
||||
<div id="gresults-results-filter-buttons">
|
||||
<input type="submit" id="gresults-results-filter-submit-button"
|
||||
class="button primary large"
|
||||
value="<?php esc_attr_e( 'Apply filters', 'gravityforms' ); ?>">
|
||||
<input type="button" id="gresults-results-filter-clear-button"
|
||||
class="button large"
|
||||
value="<?php esc_attr_e( 'Clear', 'gravityforms' ); ?>"
|
||||
onclick="gresults.clearFilterForm();"
|
||||
onkeypress="gresults.clearFilterForm();">
|
||||
|
||||
<div class="gresults-filter-loading"
|
||||
style="display:none; float:right; margin-top:5px;">
|
||||
<i class='gform-spinner'></i>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gresults-filter-loading" style="display:none;margin:0 5px 10px 0;">
|
||||
<i class='gform-spinner'></i>
|
||||
<a href="javascript:void(0);" onclick="javascript:gresultsAjaxRequest.abort()" onkeypress="javascript:gresultsAjaxRequest.abort()"><?php esc_html_e( 'Cancel', 'gravityforms' ); ?></a>
|
||||
</div>
|
||||
|
||||
<div id="gresults-results-wrapper">
|
||||
<div id="gresults-results">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
else :
|
||||
_e( 'This form does not have any fields that can be used for results', 'gravityforms' );
|
||||
endif ?>
|
||||
</div>
|
||||
|
||||
<?php GFForms::admin_footer() ?>
|
||||
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
public static function add_tooltips( $tooltips ) {
|
||||
$tooltips['gresults_total_score'] = '<h6>' . esc_html__( 'Total Score', 'gravityforms' ) . '</h6>' . esc_html__( 'Scores are weighted calculations. Items ranked higher are given a greater score than items that are ranked lower. The total score for each item is the sum of the weighted scores.', 'gravityforms' );
|
||||
$tooltips['gresults_agg_rank'] = '<h6>' . esc_html__( 'Aggregate Rank', 'gravityforms' ) . '</h6>' . esc_html__( 'The aggregate rank is the overall rank for all entries based on the weighted scores for each item.', 'gravityforms' );
|
||||
$tooltips['gresults_date_range'] = '<h6>' . esc_html__( 'Date Range', 'gravityforms' ) . '</h6>' . esc_html__( 'Date Range is optional, if no date range is specified it will be ignored.', 'gravityforms' );
|
||||
$tooltips['gresults_filters'] = '<h6>' . esc_html__( 'Filters', 'gravityforms' ) . '</h6>' . esc_html__( 'Narrow the results by adding filters. Note that some field types support more options than others.', 'gravityforms' );
|
||||
$tooltips['gresults_average_row_score'] = '<h6>' . esc_html__( 'Average Row Score', 'gravityforms' ) . '</h6>' . esc_html__( 'The average (mean) score for each row: the sum of all the scores for each row divided by the total number of entries.', 'gravityforms' );
|
||||
$tooltips['gresults_average_global_score'] = '<h6>' . esc_html__( 'Average Global Score', 'gravityforms' ) . '</h6>' . esc_html__( 'The average (mean) score for the whole field. The sum of the total scores divided by the number of entries.', 'gravityforms' );
|
||||
$tooltips['gresults_average_score'] = '<h6>' . esc_html__( 'Average Score', 'gravityforms' ) . '</h6>' . esc_html__( 'The average (mean) score: The sum of the scores divided by the number of entries.', 'gravityforms' );
|
||||
|
||||
return $tooltips;
|
||||
}
|
||||
|
||||
|
||||
public function ajax_get_results() {
|
||||
|
||||
check_ajax_referer( 'gf_results', '_gf_results_nonce' );
|
||||
|
||||
if ( ! GFAPI::current_user_can_any( $this->_capabilities ) ) {
|
||||
wp_die( 'Not allowed' );
|
||||
}
|
||||
|
||||
// tooltips
|
||||
require_once( GFCommon::get_base_path() . '/tooltips.php' );
|
||||
add_filter( 'gform_tooltips', array( $this, 'add_tooltips' ) );
|
||||
|
||||
$output = array();
|
||||
$html = '';
|
||||
$form_id = rgpost( 'id' );
|
||||
$form_id = absint( $form_id );
|
||||
$form = GFFormsModel::get_form_meta( $form_id );
|
||||
$form = gf_apply_filters( array( 'gform_form_pre_results', $form_id ), $form );
|
||||
$search_criteria['status'] = 'active';
|
||||
$fields = $this->get_fields( $form );
|
||||
$total_entries = GFAPI::count_entries( $form_id, $search_criteria );
|
||||
if ( $total_entries == 0 ) {
|
||||
$html = esc_html__( 'No results.', 'gravityforms' );
|
||||
} else {
|
||||
$search_criteria = array();
|
||||
$search_criteria['field_filters'] = GFCommon::get_field_filters_from_post( $form );
|
||||
|
||||
$start_date = preg_replace( '/[^0-9-]/', '', rgpost( 'start' ) );
|
||||
$end_date = preg_replace( '/[^0-9-]/', '', rgpost( 'end' ) );
|
||||
|
||||
if ( $start_date ) {
|
||||
$search_criteria['start_date'] = $start_date;
|
||||
}
|
||||
if ( $end_date ) {
|
||||
$search_criteria['end_date'] = $end_date;
|
||||
}
|
||||
|
||||
$search_criteria['status'] = 'active';
|
||||
$output['s'] = http_build_query( $search_criteria );
|
||||
$state_array = null;
|
||||
if ( isset( $_POST['state'] ) ) {
|
||||
$state = $_POST['state'];
|
||||
$posted_check_sum = rgpost( 'checkSum' );
|
||||
$generated_check_sum = self::generate_checksum( $state );
|
||||
$state_array = json_decode( base64_decode( $state ), true );
|
||||
if ( $generated_check_sum !== $posted_check_sum ) {
|
||||
$output['status'] = 'complete';
|
||||
$output['html'] = esc_html__( 'There was an error while processing the entries. Please contact support.', 'gravityforms' );
|
||||
echo json_encode( $output );
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
$data = isset( $this->_callbacks['data'] ) ? call_user_func( $this->_callbacks['data'], $form, $fields, $search_criteria, $state_array ) : $this->get_results_data( $form, $fields, $search_criteria, $state_array );
|
||||
$entry_count = $data['entry_count'];
|
||||
|
||||
if ( 'incomplete' === rgar( $data, 'status' ) ) {
|
||||
$state = base64_encode( json_encode( $data ) );
|
||||
$output['status'] = 'incomplete';
|
||||
$output['stateObject'] = $state;
|
||||
$output['checkSum'] = self::generate_checksum( $state );
|
||||
$output['html'] = sprintf( esc_html__( 'Entries processed: %1$d of %2$d', 'gravityforms' ), rgar( $data, 'offset' ), $entry_count );
|
||||
echo json_encode( $output );
|
||||
die();
|
||||
}
|
||||
|
||||
if ( $total_entries > 0 ) {
|
||||
$html = isset( $this->_callbacks['markup'] ) ? call_user_func( $this->_callbacks['markup'], $html, $data, $form, $fields ) : '';
|
||||
if ( empty( $html ) ) {
|
||||
foreach ( $fields as $field ) {
|
||||
$field_id = $field->id;
|
||||
$html .= "<div class='gresults-results-field gform-settings-panel' id='gresults-results-field-{$field_id}'>";
|
||||
$html .= "<header class='gform-settings-panel__header'><legend class='gform-settings-panel__title'>" . esc_html( GFCommon::get_label( $field ) ) . '</legend></header>';
|
||||
$html .= '<div class="gform-settings-panel__content">' . self::get_field_results( $form_id, $data, $field, $search_criteria ) . '</div>';
|
||||
$html .= '</div>';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$html .= esc_html__( 'No results', 'gravityforms' );
|
||||
}
|
||||
}
|
||||
|
||||
$output['html'] = $html;
|
||||
$output['status'] = 'complete';
|
||||
$output['searchCriteria'] = $search_criteria;
|
||||
echo json_encode( $output );
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
public function ajax_get_more_results() {
|
||||
|
||||
check_ajax_referer( 'gf_results', '_gf_results_nonce' );
|
||||
|
||||
if ( ! GFAPI::current_user_can_any( $this->_capabilities ) ) {
|
||||
wp_die( 'Not allowed' );
|
||||
}
|
||||
|
||||
$form_id = rgpost( 'form_id' );
|
||||
$field_id = rgpost( 'field_id' );
|
||||
$offset = rgpost( 'offset' );
|
||||
$search_criteria = rgpost( 'search_criteria' );
|
||||
|
||||
if ( empty( $search_criteria ) ) {
|
||||
$search_criteria = array();
|
||||
}
|
||||
$page_size = 10;
|
||||
|
||||
$form = RGFormsModel::get_form_meta( $form_id );
|
||||
$form_id = $form['id'];
|
||||
$field = RGFormsModel::get_field( $form, $field_id );
|
||||
$more_remaining = false;
|
||||
$html = self::get_default_field_results( $form_id, $field, $search_criteria, $offset, $page_size, $more_remaining );
|
||||
|
||||
$response = array();
|
||||
$response['more_remaining'] = $more_remaining;
|
||||
$response['html'] = $html;
|
||||
$response['offset'] = $offset;
|
||||
|
||||
echo json_encode( $response );
|
||||
die();
|
||||
}
|
||||
|
||||
private static function generate_checksum( $data ) {
|
||||
return wp_hash( crc32( ( $data ) ) );
|
||||
}
|
||||
|
||||
|
||||
public static function get_total_entries( $form ) {
|
||||
$totals = RGFormsModel::get_form_counts( $form['id'] );
|
||||
|
||||
return $totals['total'];
|
||||
}
|
||||
|
||||
public static function get_field_results( $form_id, $data, $field, $search_criteria ) {
|
||||
|
||||
if ( empty( $data['entry_count'] ) || empty ( $data['field_data'] ) ) {
|
||||
return esc_html__( 'No entries for this field', 'gravityforms' );
|
||||
}
|
||||
|
||||
$field_data = $data['field_data'];
|
||||
$entry_count = $data['entry_count'];
|
||||
|
||||
if ( empty( $field_data[ $field->id ] ) ) {
|
||||
return esc_html__( 'No entries for this field', 'gravityforms' );
|
||||
}
|
||||
|
||||
$field_results = '';
|
||||
|
||||
$field_type = GFFormsModel::get_input_type( $field );
|
||||
switch ( $field_type ) {
|
||||
case 'radio' :
|
||||
case 'checkbox' :
|
||||
case 'select' :
|
||||
case 'rating' :
|
||||
case 'multiselect' :
|
||||
$results = $field_data[ $field->id ];
|
||||
$non_zero_results = is_array( $results ) ? array_filter( $results ) : $results;
|
||||
if ( empty( $non_zero_results ) ) {
|
||||
$field_results .= esc_html__( 'No entries for this field', 'gravityforms' );
|
||||
|
||||
return $field_results;
|
||||
}
|
||||
$choices = $field->choices;
|
||||
|
||||
$data_table = array();
|
||||
$data_table [] = array( esc_html__( 'Choice', 'gravityforms' ), esc_html__( 'Frequency', 'gravityforms' ) );
|
||||
|
||||
foreach ( $choices as $choice ) {
|
||||
$text = $choice['text'];
|
||||
$val = $results[ $choice['value'] ];
|
||||
$data_table [] = array( $text, $val );
|
||||
}
|
||||
|
||||
$bar_height = 40;
|
||||
$chart_area_height = ( count( $choices ) * ( $bar_height + 20 ) );
|
||||
|
||||
$chart_options = array(
|
||||
'isStacked' => true,
|
||||
'height' => ( $chart_area_height + $bar_height ),
|
||||
'fontSize' => 14,
|
||||
'chartArea' => array(
|
||||
'top' => 0,
|
||||
'left' => 200,
|
||||
'height' => $chart_area_height,
|
||||
'width' => '100%',
|
||||
),
|
||||
'series' => array(
|
||||
'0' => array(
|
||||
'color' => 'silver',
|
||||
'visibleInLegend' => 'false',
|
||||
),
|
||||
),
|
||||
'hAxis' => array(
|
||||
'viewWindowMode' => 'explicit',
|
||||
'viewWindow' => array( 'min' => 0 ),
|
||||
'title' => esc_html__( 'Frequency', 'gravityforms' ),
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
$data_table_json = htmlentities( json_encode( $data_table ), ENT_QUOTES, 'UTF-8', true );
|
||||
$options_json = htmlentities( json_encode( $chart_options ), ENT_QUOTES, 'UTF-8', true );
|
||||
$div_id = 'gresults-results-chart-field-' . $field->id;
|
||||
$height = ''; // = sprintf("height:%dpx", (count($choices) * $bar_height));
|
||||
|
||||
$field_results .= sprintf( '<div class="gresults-chart-wrapper" style="width: 100%%;%s" id=%s data-datatable=\'%s\' data-options=\'%s\' data-charttype="bar" ></div>', $height, $div_id, $data_table_json, $options_json );
|
||||
|
||||
|
||||
break;
|
||||
case 'likert' :
|
||||
$results = $field_data[ $field->id ];
|
||||
$multiple_rows = $field->gsurveyLikertEnableMultipleRows ? true : false;
|
||||
$scoring_enabled = $field->gsurveyLikertEnableScoring && class_exists( 'GFSurvey' ) ? true : false;
|
||||
|
||||
$n = 100;
|
||||
|
||||
$xr = 255;
|
||||
$xg = 255;
|
||||
$xb = 255;
|
||||
|
||||
$yr = 100;
|
||||
$yg = 250;
|
||||
$yb = 100;
|
||||
|
||||
$field_results .= "<div class='gsurvey-likert-field-results'>";
|
||||
$field_results .= "<table class='gsurvey-likert'>";
|
||||
$field_results .= '<tr>';
|
||||
if ( $multiple_rows ) {
|
||||
$field_results .= '<td></td>';
|
||||
}
|
||||
|
||||
foreach ( $field->choices as $choice ) {
|
||||
$field_results .= "<td class='gsurvey-likert-choice-label'>" . $choice['text'] . '</td>';
|
||||
}
|
||||
|
||||
if ( $multiple_rows && $scoring_enabled ) {
|
||||
$field_results .= sprintf( '<td>%s %s</td>', esc_html__( 'Average Score', 'gravityforms' ), gform_tooltip( 'gresults_average_row_score', null, true ) );
|
||||
}
|
||||
|
||||
$field_results .= '</tr>';
|
||||
|
||||
foreach ( $field->gsurveyLikertRows as $row ) {
|
||||
$row_text = $row['text'];
|
||||
$row_value = $row['value'];
|
||||
$max = 0;
|
||||
foreach ( $field->choices as $choice ) {
|
||||
if ( $multiple_rows ) {
|
||||
$choice_value = rgar( $choice, 'value' );
|
||||
$results_row = rgar( $results, $row_value );
|
||||
$results_for_choice = rgar( $results_row, $choice_value );
|
||||
$max = max( array( $max, $results_for_choice ) );
|
||||
} else {
|
||||
$max = max( array( $max, $results[ $choice['value'] ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
$field_results .= '<tr>';
|
||||
|
||||
if ( $multiple_rows ) {
|
||||
$field_results .= "<td class='gsurvey-likert-row-label'>" . $row_text . '</td>';
|
||||
}
|
||||
|
||||
foreach ( $field->choices as $choice ) {
|
||||
$val = $multiple_rows ? $results[ $row_value ][ $choice['value'] ] : $results[ $choice['value'] ];
|
||||
$percent = $max > 0 ? round( $val / $max * 100, 0 ) : 0;
|
||||
$red = (int) ( ( $xr + ( ( $percent * ( $yr - $xr ) ) / ( $n - 1 ) ) ) );
|
||||
$green = (int) ( ( $xg + ( ( $percent * ( $yg - $xg ) ) / ( $n - 1 ) ) ) );
|
||||
$blue = (int) ( ( $xb + ( ( $percent * ( $yb - $xb ) ) / ( $n - 1 ) ) ) );
|
||||
$clr = 'rgb(' . $red . ',' . $green . ',' . $blue . ')';
|
||||
$field_results .= "<td class='gsurvey-likert-results' style='background-color:{$clr}'>" . $val . '</td>';
|
||||
}
|
||||
|
||||
if ( $multiple_rows && $scoring_enabled ) {
|
||||
$row_sum = $results[ $row_value ]['row_score_sum'];
|
||||
$average_row_score = $row_sum == 0 ? 0 : round( $row_sum / $entry_count, 3 );
|
||||
$field_results .= "<td class='gsurvey-likert-results'>" . $average_row_score . '</td>';
|
||||
}
|
||||
|
||||
$field_results .= '</tr>';
|
||||
|
||||
if ( false === $multiple_rows ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$field_results .= '</table>';
|
||||
$field_results .= '</div>';
|
||||
|
||||
if ( $scoring_enabled ) {
|
||||
$sum = $results['sum_of_scores'];
|
||||
$average_score = $sum == 0 ? 0 : round( $sum / $entry_count, 3 );
|
||||
if ( $multiple_rows ) {
|
||||
$average_global_score_tooltip = gform_tooltip( 'gresults_average_global_score', null, true );
|
||||
$field_results .= sprintf( "<div class='gsurvey-likert-score'>%s %s: %s</div>", esc_html__( 'Average global score', 'gravityforms' ), $average_global_score_tooltip, $average_score );
|
||||
} else {
|
||||
$field_results .= sprintf( "<div class='gsurvey-likert-score'>%s %s: %s</div>", esc_html__( 'Average score', 'gravityforms' ), gform_tooltip( 'gresults_average_score', null, true ), $average_score );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'rank' :
|
||||
$results = $field_data[ $field->id ];
|
||||
arsort( $results );
|
||||
$field_results .= "<div class='gsurvey-rank-field-results'>";
|
||||
$field_results .= ' <table>';
|
||||
$field_results .= " <tr class='gresults-results-field-table-header'>";
|
||||
$field_results .= " <td class='gresults-rank-field-label'>";
|
||||
$field_results .= esc_html__( 'Item', 'gravityforms' );
|
||||
$field_results .= ' </td>';
|
||||
$field_results .= " <td class='gresults-rank-field-score'>";
|
||||
$field_results .= esc_html__( 'Total Score', 'gravityforms' ) . ' ' . gform_tooltip( 'gresults_total_score', null, true );
|
||||
$field_results .= ' </td>';
|
||||
$field_results .= " <td class='gresults-rank-field-rank'>";
|
||||
$field_results .= esc_html__( 'Aggregate Rank', 'gravityforms' ) . ' ' . gform_tooltip( 'gresults_agg_rank', null, true );
|
||||
$field_results .= ' </td>';
|
||||
$field_results .= ' </tr>';
|
||||
|
||||
$agg_rank = 1;
|
||||
foreach ( $results as $choice_val => $score ) {
|
||||
$field_results .= '<tr>';
|
||||
$field_results .= " <td class='gresults-rank-field-label' style='text-align:left;'>";
|
||||
$field_results .= RGFormsModel::get_choice_text( $field, $choice_val );
|
||||
$field_results .= ' </td>';
|
||||
$field_results .= " <td class='gresults-rank-field-score'>";
|
||||
$field_results .= $score;
|
||||
$field_results .= ' </td>';
|
||||
$field_results .= " <td class='gresults-rank-field-rank'>";
|
||||
$field_results .= $agg_rank;
|
||||
$field_results .= ' </td>';
|
||||
$field_results .= '</tr>';
|
||||
$agg_rank ++;
|
||||
}
|
||||
$field_results .= '</table>';
|
||||
$field_results .= '</div>';
|
||||
|
||||
break;
|
||||
default :
|
||||
$page_size = 5;
|
||||
$offset = 0;
|
||||
$field_id = $field->id;
|
||||
$more_remaining = false;
|
||||
$default_field_results = self::get_default_field_results( $form_id, $field, $search_criteria, $offset, $page_size, $more_remaining );
|
||||
|
||||
$field_results .= "<div class='gresults-results-field-sub-label'>" . esc_html__( 'Latest values:', 'gravityforms' ) . '</div>';
|
||||
|
||||
$field_results .= "<ul id='gresults-results-field-content-{$field_id}' class='gresults-results-field-content' data-offset='{$offset}'>";
|
||||
|
||||
$field_results .= $default_field_results;
|
||||
$field_results .= '</ul>';
|
||||
|
||||
if ( $more_remaining ) {
|
||||
$field_results .= "<a id='gresults-results-field-more-link-{$field_id}' class='gresults-results-field-more-link' href='javascript:void(0)' onclick='gresults.getMoreResults({$form_id},{$field_id})' onkeypress='gresults.getMoreResults({$form_id},{$field_id})'>" . esc_html__( 'Show more', 'gravityforms' ) . '</a>';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $field_results;
|
||||
|
||||
}
|
||||
|
||||
public function get_results_data( $form, $fields, $search_criteria = array(), $state_array = array(), $max_execution_time = 15 /* seconds */ ) {
|
||||
// todo: add hooks to modify $max_execution_time and $page_size?
|
||||
|
||||
$page_size = 150;
|
||||
|
||||
$time_start = microtime( true );
|
||||
|
||||
$form_id = $form['id'];
|
||||
$data = array();
|
||||
$offset = 0;
|
||||
$entry_count = 0;
|
||||
$field_data = array();
|
||||
|
||||
|
||||
if ( $state_array ) {
|
||||
//get counts from state
|
||||
$data = $state_array;
|
||||
$offset = (int) rgar( $data, 'offset' );
|
||||
|
||||
unset( $data['offset'] );
|
||||
$entry_count = $offset;
|
||||
$field_data = rgar( $data, 'field_data' );
|
||||
} else {
|
||||
//initialize counts
|
||||
foreach ( $fields as $field ) {
|
||||
$field_type = GFFormsModel::get_input_type( $field );
|
||||
if ( false === isset( $field->choices ) ) {
|
||||
$field_data[ $field->id ] = 0;
|
||||
continue;
|
||||
}
|
||||
$choices = $field->choices;
|
||||
|
||||
if ( $field_type == 'likert' && rgar( $field, 'gsurveyLikertEnableMultipleRows' ) ) {
|
||||
foreach ( $field->gsurveyLikertRows as $row ) {
|
||||
foreach ( $choices as $choice ) {
|
||||
$field_data[ $field->id ][ $row['value'] ][ $choice['value'] ] = 0;
|
||||
}
|
||||
if ( rgar( $field, 'gsurveyLikertEnableScoring' ) ) {
|
||||
$field_data[ $field->id ][ $row['value'] ]['row_score_sum'] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( ! empty( $choices ) && is_array( $choices ) ) {
|
||||
foreach ( $choices as $choice ) {
|
||||
$field_data[ $field->id ][ $choice['value'] ] = 0;
|
||||
}
|
||||
} else {
|
||||
$field_data[ $field->id ] = 0;
|
||||
}
|
||||
}
|
||||
if ( $field_type == 'likert' && rgar( $field, 'gsurveyLikertEnableScoring' ) ) {
|
||||
$field_data[ $field->id ]['sum_of_scores'] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$count_search_leads = GFAPI::count_entries( $form_id, $search_criteria );
|
||||
$data['entry_count'] = $count_search_leads;
|
||||
|
||||
$entries_left = $count_search_leads - $offset;
|
||||
|
||||
while ( $entries_left > 0 ) {
|
||||
|
||||
$paging = array(
|
||||
'offset' => $offset,
|
||||
'page_size' => $page_size,
|
||||
);
|
||||
|
||||
$search_leads_time_start = microtime( true );
|
||||
$leads = GFFormsModel::search_leads( $form_id, $search_criteria, null, $paging );
|
||||
$search_leads_time_end = microtime( true );
|
||||
$search_leads_time = $search_leads_time_end - $search_leads_time_start;
|
||||
|
||||
$leads_in_search = count( $leads );
|
||||
|
||||
$entry_count += $leads_in_search;
|
||||
$leads_processed = 0;
|
||||
foreach ( $leads as $lead ) {
|
||||
|
||||
$lead_time_start = microtime( true );
|
||||
foreach ( $fields as $field ) {
|
||||
$field_type = GFFormsModel::get_input_type( $field );
|
||||
$field_id = $field->id;
|
||||
$value = RGFormsModel::get_lead_field_value( $lead, $field );
|
||||
|
||||
if ( $field_type == 'likert' && rgar( $field, 'gsurveyLikertEnableMultipleRows' ) ) {
|
||||
|
||||
if ( empty( $value ) ) {
|
||||
continue;
|
||||
}
|
||||
foreach ( $value as $value_vector ) {
|
||||
if ( empty( $value_vector ) ) {
|
||||
continue;
|
||||
}
|
||||
list( $row_val, $col_val ) = explode( ':', $value_vector, 2 );
|
||||
if ( isset( $field_data[ $field->id ][ $row_val ] ) && isset( $field_data[ $field->id ][ $row_val ][ $col_val ] ) ) {
|
||||
$field_data[ $field->id ][ $row_val ][ $col_val ] ++;
|
||||
if ( $field->gsurveyLikertEnableScoring ) {
|
||||
$field_data[ $field->id ][ $row_val ]['row_score_sum'] += $this->get_likert_row_score( $row_val, $field, $lead );
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ( $field_type == 'rank' ) {
|
||||
$score = count( rgar( $field, 'choices' ) );
|
||||
$values = explode( ',', $value );
|
||||
foreach ( $values as $ranked_value ) {
|
||||
$field_data[ $field->id ][ $ranked_value ] += $score;
|
||||
$score --;
|
||||
}
|
||||
} else {
|
||||
|
||||
if ( empty( $field->choices ) ) {
|
||||
if ( false === empty( $value ) ) {
|
||||
$field_data[ $field_id ] ++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$choices = $field->choices;
|
||||
|
||||
foreach ( $choices as $choice ) {
|
||||
$choice_is_selected = false;
|
||||
if ( is_array( $value ) ) {
|
||||
$choice_value = rgar( $choice, 'value' );
|
||||
if ( in_array( $choice_value, $value ) ) {
|
||||
$choice_is_selected = true;
|
||||
}
|
||||
} else {
|
||||
if ( RGFormsModel::choice_value_match( $field, $choice, $value ) ) {
|
||||
$choice_is_selected = true;
|
||||
}
|
||||
}
|
||||
if ( $choice_is_selected ) {
|
||||
$field_data[ $field_id ][ $choice['value'] ] ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $field_type == 'likert' && rgar( $field, 'gsurveyLikertEnableScoring' ) ) {
|
||||
$field_data[ $field->id ]['sum_of_scores'] += $this->get_likert_score( $field, $lead );
|
||||
}
|
||||
}
|
||||
$leads_processed ++;
|
||||
$lead_time_end = microtime( true );
|
||||
$total_execution_time = $lead_time_end - $search_leads_time_start;
|
||||
$lead_execution_time = $lead_time_end - $lead_time_start;
|
||||
if ( $total_execution_time + $lead_execution_time > $max_execution_time ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$data['field_data'] = $field_data;
|
||||
if ( isset( $this->_callbacks['calculation'] ) ) {
|
||||
$data = call_user_func( $this->_callbacks['calculation'], $data, $form, $fields, $leads );
|
||||
$field_data = $data['field_data'];
|
||||
}
|
||||
$offset += $leads_processed;
|
||||
$entries_left -= $leads_processed;
|
||||
|
||||
$time_end = microtime( true );
|
||||
$execution_time = ( $time_end - $time_start );
|
||||
|
||||
if ( $entries_left > 0 && $execution_time + $search_leads_time > $max_execution_time ) {
|
||||
$data['status'] = 'incomplete';
|
||||
$data['offset'] = $offset;
|
||||
$progress = $data['entry_count'] > 0 ? round( $data['offset'] / $data['entry_count'] * 100 ) : 0;
|
||||
$data['progress'] = $progress;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $entries_left <= 0 ) {
|
||||
$data['status'] = 'complete';
|
||||
}
|
||||
}
|
||||
|
||||
$data['timestamp'] = time();
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function get_likert_row_score( $row_val, $field, $entry ) {
|
||||
return is_callable( array(
|
||||
'GFSurvey',
|
||||
'get_likert_row_score',
|
||||
) ) ? GFSurvey::get_likert_row_score( $row_val, $field, $entry ) : 0;
|
||||
}
|
||||
|
||||
public function get_likert_score( $field, $entry ) {
|
||||
return is_callable( array(
|
||||
'GFSurvey',
|
||||
'get_field_score',
|
||||
) ) ? GFSurvey::get_field_score( $field, $entry ) : 0;
|
||||
}
|
||||
|
||||
|
||||
public static function get_default_field_results( $form_id, $field, $search_criteria, &$offset, $page_size, &$more_remaining = false ) {
|
||||
$field_results = '';
|
||||
|
||||
$sorting = array( 'key' => 'date_created', 'direction' => 'DESC' );
|
||||
|
||||
$c = 0;
|
||||
|
||||
do {
|
||||
$paging = array( 'offset' => $offset, 'page_size' => $page_size );
|
||||
$leads = GFFormsModel::search_leads( $form_id, $search_criteria, $sorting, $paging );
|
||||
foreach ( $leads as $lead ) {
|
||||
|
||||
$value = RGFormsModel::get_lead_field_value( $lead, $field );
|
||||
|
||||
$content = apply_filters( 'gform_entries_field_value', $value, $form_id, $field->id, $lead );
|
||||
|
||||
if ( is_array( $content ) ) {
|
||||
$content = join( ' ', $content );
|
||||
}
|
||||
|
||||
if ( ! empty( $content ) ) {
|
||||
$field_results .= "<li>" . wp_kses_post( $content ) . "</li>";
|
||||
$c ++;
|
||||
}
|
||||
}
|
||||
$offset += $page_size;
|
||||
|
||||
} while ( $c < $page_size && ! empty( $leads ) );
|
||||
|
||||
if ( ! empty( $leads ) ) {
|
||||
$more_remaining = true;
|
||||
}
|
||||
|
||||
return $field_results;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
.settings-field-map-table { }
|
||||
.settings-field-map-table thead th { font-weight: bold; border-bottom: 1px solid #ccc; }
|
||||
.settings-field-map-table tbody td { border-bottom: 1px dotted #eee; }
|
||||
.settings-field-map-table select { max-width: 90%; }
|
||||
|
||||
.settings-field-map-table .custom-key-reset,
|
||||
.settings-field-map-table .custom-value-reset,
|
||||
.gaddon-setting-select-custom-container .select-custom-reset {
|
||||
background: url( ../../../images/xit.gif ) no-repeat scroll 0 0 transparent;
|
||||
cursor:pointer;
|
||||
display:none;
|
||||
position:absolute;
|
||||
text-indent:-9999px;
|
||||
width:10px;
|
||||
height: 10px;
|
||||
-moz-transition: none;
|
||||
-webkit-transition: none;
|
||||
-o-transition: color 0 ease-in;
|
||||
transition: none;
|
||||
}
|
||||
.settings-field-map-table .custom-key-reset {
|
||||
margin-top: 10px;
|
||||
margin-left: 165px;
|
||||
}
|
||||
.settings-field-map-table .repeater th { padding-left: 0px; }
|
||||
|
||||
.settings-field-map-table .custom-key-reset:hover,
|
||||
.settings-field-map-table .custom-value-reset:hover,
|
||||
.gaddon-setting-select-custom-container .select-custom-reset:hover {
|
||||
background-position-x: -10px;
|
||||
}
|
||||
|
||||
.settings-field-map-table .custom-key-container:hover .custom-key-reset,
|
||||
.settings-field-map-table .custom-key-container:hover .custom-value-reset,
|
||||
.gaddon-setting-select-custom-container:hover .select-custom-reset {
|
||||
display:block;
|
||||
}
|
||||
|
||||
.gaddon-setting-select-custom-container { display:inline-block;position:relative; }
|
||||
.gaddon-setting-select-custom-container .select-custom-reset {
|
||||
left: 171px;
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
.gaddon-section .required { color: #f00; }
|
||||
.gaddon-setting-inline{
|
||||
display:inline;
|
||||
margin-right:6px;
|
||||
}
|
||||
|
||||
.mt-gaddon-editor {
|
||||
float: right;
|
||||
position: relative;
|
||||
right: 21px;
|
||||
top: 70px;
|
||||
}
|
||||
|
||||
.mt-gaddon-editor ~ .wp-editor-wrap {
|
||||
margin-right: 23px;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
.settings-field-map-table thead th{font-weight:700;border-bottom:1px solid #ccc}.settings-field-map-table tbody td{border-bottom:1px dotted #eee}.settings-field-map-table select{max-width:90%}.gaddon-setting-select-custom-container .select-custom-reset,.settings-field-map-table .custom-key-reset,.settings-field-map-table .custom-value-reset{background:url(../../../images/xit.gif) no-repeat scroll 0 0 transparent;cursor:pointer;display:none;position:absolute;text-indent:-9999px;width:10px;height:10px;-moz-transition:none;-webkit-transition:none;-o-transition:color 0 ease-in;transition:none}.settings-field-map-table .custom-key-reset{margin-top:10px;margin-left:165px}.settings-field-map-table .repeater th{padding-left:0}.gaddon-setting-select-custom-container .select-custom-reset:hover,.settings-field-map-table .custom-key-reset:hover,.settings-field-map-table .custom-value-reset:hover{background-position-x:-10px}.gaddon-setting-select-custom-container:hover .select-custom-reset,.settings-field-map-table .custom-key-container:hover .custom-key-reset,.settings-field-map-table .custom-key-container:hover .custom-value-reset{display:block}.gaddon-setting-select-custom-container{display:inline-block;position:relative}.gaddon-setting-select-custom-container .select-custom-reset{left:171px;top:10px}.gaddon-section .required{color:red}.gaddon-setting-inline{display:inline;margin-right:6px}.mt-gaddon-editor{float:right;position:relative;right:21px;top:70px}.mt-gaddon-editor~.wp-editor-wrap{margin-right:23px}
|
||||
@@ -1,292 +0,0 @@
|
||||
/* --------- TODO: remove quiz specific styles ------------------*/
|
||||
|
||||
table#gquiz-results-summary {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
table#gquiz-results-summary td {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
table#gquiz-results-summary td.gquiz-results-summary-label {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
table#gquiz-results-summary td.gquiz-results-summary-data {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.gquiz-results-summary-data-box {
|
||||
width: 75%;
|
||||
padding: 15px 0;
|
||||
min-width: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.gaddon-results-summary-secondary{
|
||||
padding-top: 4px;
|
||||
font-weight: normal;
|
||||
font-size:13px;
|
||||
}
|
||||
|
||||
.gaddon-results-summary-primary{
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
.gquiz-field-precentages-correct {
|
||||
float: left;
|
||||
margin: 8px 0 0 64px;
|
||||
}
|
||||
|
||||
/* -------------------------------------*/
|
||||
|
||||
table#gaddon-results-summary {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
table#gaddon-results-summary td {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
table#gaddon-results-summary td.gaddon-results-summary-label {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
table#gaddon-results-summary td.gaddon-results-summary-data {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.gaddon-results-summary-data-box {
|
||||
border: 1px solid silver;
|
||||
padding: 10px;
|
||||
width: 75%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.gaddon-field-precentages-correct {
|
||||
float: left;
|
||||
margin: 15px 0 0 50px;
|
||||
}
|
||||
|
||||
|
||||
/*-------------*/
|
||||
#gresults-results {
|
||||
margin-right: 300px;
|
||||
}
|
||||
|
||||
.gform-admin .gresults-filter-loading .gform-spinner {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.gf-results .gf-result-box {
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #e3e6ef;
|
||||
box-shadow: 0 1px 4px rgb(18 25 97 / 8%);
|
||||
padding: 1.562rem 1rem;
|
||||
}
|
||||
|
||||
.gf-results .gf-result-box {
|
||||
margin-right: 0;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.gf-results .gf-result-box__primary {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@media screen and ( min-width: 782px ) {
|
||||
.gf-results {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.gf-results .gf-result-box {
|
||||
flex: 1 1 0px;
|
||||
margin-right: 1.25rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.gf-results .gf-result-box:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.gresults-results-field {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
.gresults-results-field table{
|
||||
border-bottom: 1px solid silver;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.gresults-results-field table td{
|
||||
padding:5px;
|
||||
border-right: 1px solid silver;
|
||||
border-top: 1px solid silver;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.gresults-results-field-table-header{
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.gresults-results-field table td:first-child {
|
||||
border-left: 1px solid silver;
|
||||
}
|
||||
|
||||
|
||||
ul.gresults-results-field-content,
|
||||
ul.gresults-results-field-content li{
|
||||
list-style:disc outside none;
|
||||
}
|
||||
ul.gresults-results-field-content{
|
||||
margin:10px;
|
||||
}
|
||||
|
||||
td.gresults-rank-field-score,
|
||||
td.gresults-rank-field-rank{
|
||||
width:110px;
|
||||
}
|
||||
|
||||
.gsurvey-rank-field-results table{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
|
||||
/* filter box */
|
||||
|
||||
#gresults-results-filter-content {
|
||||
padding:12px;
|
||||
border-top: 1px solid #EBEBF2
|
||||
}
|
||||
|
||||
|
||||
.gresults-results-filter-section-label {
|
||||
font-size:1.2em;
|
||||
font-weight:bold;
|
||||
margin-top:10px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
|
||||
#gresults-results-filter label {
|
||||
margin-top:10px;
|
||||
display:block;
|
||||
}
|
||||
|
||||
#gresults-results-filter-content #gform-no-filters {
|
||||
color: #242748;
|
||||
}
|
||||
|
||||
.gresults-remove,
|
||||
.gresults-add {
|
||||
margin-top:2px;
|
||||
vertical-align:middle;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.gresults-add {
|
||||
margin-left:5px;
|
||||
}
|
||||
|
||||
#gresults-no-filters{
|
||||
color:silver;
|
||||
}
|
||||
|
||||
.gresults-datepicker,
|
||||
.gresults-filter-value,
|
||||
.gresults-filter-field {
|
||||
width:150px;
|
||||
box-sizing:border-box;
|
||||
-ms-box-sizing:border-box;
|
||||
-moz-box-sizing:border-box;
|
||||
-webkit-box-sizing:border-box;
|
||||
height: 2em;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.gresults-filter-operator {
|
||||
width:70px;
|
||||
}
|
||||
|
||||
#gresults-results-filter-buttons {
|
||||
clear:both;
|
||||
margin-top:20px;
|
||||
width:180px;
|
||||
}
|
||||
|
||||
.gresults-results-filter-field-label {
|
||||
font-size:1.1em;
|
||||
font-weight:bold;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
|
||||
.gresults-results-filter-field {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
.gresults-results-filter-field ul li label {
|
||||
margin-left:5px;
|
||||
}
|
||||
|
||||
.gresults-results-filter-title {
|
||||
font-size:1.5em;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
/*
|
||||
#gresults-results-filter {
|
||||
visibility: hidden;
|
||||
}
|
||||
*/
|
||||
|
||||
#gresults-results-field-filters-container.resizable {
|
||||
border-bottom:5px double #ddd;
|
||||
min-height:120px;
|
||||
}
|
||||
|
||||
#gresults-results-field-filters {
|
||||
height:100%;
|
||||
overflow-y:auto;
|
||||
}
|
||||
|
||||
.ui-resizable {
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.ui-resizable-handle {
|
||||
position:absolute;
|
||||
font-size:0.1px;
|
||||
z-index:99999;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.ui-resizable-s {
|
||||
cursor:s-resize;
|
||||
height:7px;
|
||||
width:100%;
|
||||
bottom:-5px;
|
||||
left:0px;
|
||||
}
|
||||
|
||||
.gsurvey-likert-score{
|
||||
margin-top:5px;
|
||||
}
|
||||
|
||||
/* NEW */
|
||||
|
||||
#gquiz-results-summary { margin: 60px 0; }
|
||||
|
||||
.gresults-chart-wrapper { border-top: 1px solid #dfdfdf; margin: 0 0 28px; }
|
||||
.gquiz-field-precentages-correct + .gresults-chart-wrapper { margin: 0 0 14px; }
|
||||
|
||||
.gresults-label-group { display: block; clear: right; }
|
||||
.gresults-label-group .gresults-label { display: inline-block; width: 65px; }
|
||||
.gresults-group-correct .gresults-value { color: green; }
|
||||
.gresults-group-incorrect .gresults-value { color: red; }
|
||||
@@ -1 +0,0 @@
|
||||
table#gquiz-results-summary{table-layout:fixed}table#gquiz-results-summary td{font-weight:700;text-align:center;padding:10px}table#gquiz-results-summary td.gquiz-results-summary-label{font-size:1.2em}table#gquiz-results-summary td.gquiz-results-summary-data{font-size:2em}.gquiz-results-summary-data-box{width:75%;padding:15px 0;min-width:0;margin:auto}.gaddon-results-summary-secondary{padding-top:4px;font-weight:400;font-size:13px}.gaddon-results-summary-primary{padding:5px}.gquiz-field-precentages-correct{float:left;margin:8px 0 0 64px}table#gaddon-results-summary{table-layout:fixed}table#gaddon-results-summary td{font-weight:700;text-align:center;padding:10px}table#gaddon-results-summary td.gaddon-results-summary-label{font-size:1.2em}table#gaddon-results-summary td.gaddon-results-summary-data{font-size:2em}.gaddon-results-summary-data-box{border:1px solid silver;padding:10px;width:75%;margin:auto}.gaddon-field-precentages-correct{float:left;margin:15px 0 0 50px}#gresults-results{margin-right:300px}.gform-admin .gresults-filter-loading .gform-spinner{display:inline-block}.gf-results .gf-result-box{background:#fff;border-radius:3px;border:1px solid #e3e6ef;box-shadow:0 1px 4px rgb(18 25 97 / 8%);padding:1.562rem 1rem}.gf-results .gf-result-box{margin-right:0;margin-bottom:1.25rem}.gf-results .gf-result-box__primary{display:flex}@media screen and (min-width:782px){.gf-results{display:flex;justify-content:space-between;margin-bottom:1.25rem}.gf-results .gf-result-box{flex:1 1 0px;margin-right:1.25rem;margin-bottom:0}.gf-results .gf-result-box:last-child{margin-right:0}}.gresults-results-field{margin-bottom:20px}.gresults-results-field table{border-bottom:1px solid silver;border-spacing:0}.gresults-results-field table td{padding:5px;border-right:1px solid silver;border-top:1px solid silver;text-align:center}.gresults-results-field-table-header{background-color:#eee}.gresults-results-field table td:first-child{border-left:1px solid silver}ul.gresults-results-field-content,ul.gresults-results-field-content li{list-style:disc outside none}ul.gresults-results-field-content{margin:10px}td.gresults-rank-field-rank,td.gresults-rank-field-score{width:110px}.gsurvey-rank-field-results table{width:100%}#gresults-results-filter-content{padding:12px;border-top:1px solid #ebebf2}.gresults-results-filter-section-label{font-size:1.2em;font-weight:700;margin-top:10px;margin-bottom:10px}#gresults-results-filter label{margin-top:10px;display:block}#gresults-results-filter-content #gform-no-filters{color:#242748}.gresults-add,.gresults-remove{margin-top:2px;vertical-align:middle;cursor:pointer}.gresults-add{margin-left:5px}#gresults-no-filters{color:silver}.gresults-datepicker,.gresults-filter-field,.gresults-filter-value{width:150px;box-sizing:border-box;-ms-box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;height:2em;padding:2px}.gresults-filter-operator{width:70px}#gresults-results-filter-buttons{clear:both;margin-top:20px;width:180px}.gresults-results-filter-field-label{font-size:1.1em;font-weight:700;margin-bottom:10px}.gresults-results-filter-field{margin-bottom:20px}.gresults-results-filter-field ul li label{margin-left:5px}.gresults-results-filter-title{font-size:1.5em;font-weight:700}#gresults-results-field-filters-container.resizable{border-bottom:5px double #ddd;min-height:120px}#gresults-results-field-filters{height:100%;overflow-y:auto}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.gsurvey-likert-score{margin-top:5px}#gquiz-results-summary{margin:60px 0}.gresults-chart-wrapper{border-top:1px solid #dfdfdf;margin:0 0 28px}.gquiz-field-precentages-correct+.gresults-chart-wrapper{margin:0 0 14px}.gresults-label-group{display:block;clear:right}.gresults-label-group .gresults-label{display:inline-block;width:65px}.gresults-group-correct .gresults-value{color:green}.gresults-group-incorrect .gresults-value{color:red}
|
||||
@@ -1,308 +0,0 @@
|
||||
/* ------------------ Field Map ------------------ */
|
||||
|
||||
.gforms_form_settings.form-table .settings-field-map-table thead th {
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
padding-left:0px;
|
||||
}
|
||||
|
||||
table.settings-field-map-table tbody td {
|
||||
padding: 0px 0px 8px 0px;
|
||||
}
|
||||
|
||||
.settings-field-map-table td:first-child {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.settings-field-map-table td:last-child {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.settings-field-map-table .repeater th, .settings-field-map-table .repeater td:nth-child(2) {
|
||||
padding-left: 0px;
|
||||
padding-top: 0px;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.settings-field-map-table select {
|
||||
font-family: inherit;
|
||||
height: 25px;
|
||||
width: 210px;
|
||||
}
|
||||
|
||||
.settings-field-map-table .chosen-container,
|
||||
.settings-field-map-table .select2-container {
|
||||
width: 210px !important;
|
||||
}
|
||||
|
||||
.settings-field-map-table .custom-key-container,
|
||||
.settings-field-map-table .custom-value-container {
|
||||
position: relative;
|
||||
width: 210px;
|
||||
}
|
||||
|
||||
.settings-field-map-table .custom-key-container input,
|
||||
.settings-field-map-table .custom-value-container input {
|
||||
width: 210px;
|
||||
}
|
||||
|
||||
.settings-field-map-table .custom-key-container input:not(:only-child),
|
||||
.settings-field-map-table .custom-value-container input:not(:only-child) {
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
.settings-field-map-table .custom-key-container.supports-merge-tags input:not(:only-child),
|
||||
.settings-field-map-table .custom-value-container.supports-merge-tags input:not(:only-child) {
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
||||
.settings-field-map-table .custom-value-container.supports-merge-tags .all-merge-tags {
|
||||
height: 25px;
|
||||
position: absolute;
|
||||
right: 36px;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.settings-field-map-table .custom-value-container.supports-merge-tags .all-merge-tags .tooltip-merge-tag {
|
||||
background-position: center;
|
||||
height: 25px;
|
||||
margin: 0;
|
||||
width: 25px;
|
||||
}
|
||||
|
||||
.settings-field-map-table .custom-key-reset,
|
||||
.settings-field-map-table .custom-value-reset {
|
||||
background: url( '../images/field-map-reset.png' ) no-repeat center #ddd;
|
||||
background-size: 10px 10px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 25px;
|
||||
opacity: .3;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
right: 11px;
|
||||
text-indent: -9999px;
|
||||
top: 0;
|
||||
transition: opacity .25s ease-in-out;
|
||||
width: 25px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.settings-field-map-table .custom-key-reset:hover,
|
||||
.settings-field-map-table .custom-value-reset:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.settings-field-map-table .add-item span,
|
||||
.settings-field-map-table .remove-item span {
|
||||
background: url( '../images/field-map-buttons.png' ) no-repeat center top transparent;
|
||||
background-size: 20px 100px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 25px;
|
||||
overflow: hidden;
|
||||
text-indent: -9999px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.settings-field-map-table .add-item span:hover {
|
||||
background-position: 0 -25px;
|
||||
}
|
||||
|
||||
.settings-field-map-table .remove-item span {
|
||||
background-position: 0 -50px;
|
||||
}
|
||||
|
||||
.settings-field-map-table .remove-item span:hover {
|
||||
background-position: 0 -75px;
|
||||
}
|
||||
|
||||
@media screen and ( max-width: 782px ) {
|
||||
|
||||
.settings-field-map-table .custom-key-container input:not(:only-child),
|
||||
.settings-field-map-table .custom-value-container input:not(:only-child) {
|
||||
padding-right: 45px;
|
||||
}
|
||||
|
||||
.settings-field-map-table .custom-key-reset,
|
||||
.settings-field-map-table .custom-value-reset {
|
||||
height: 40px;
|
||||
right: 0;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ---------------- Select Custom ---------------- */
|
||||
|
||||
.gaddon-setting-select-custom-container .select-custom-reset {
|
||||
background: url( ../../../images/xit.gif ) no-repeat scroll 0 0 transparent;
|
||||
cursor:pointer;
|
||||
display:none;
|
||||
position:absolute;
|
||||
text-indent:-9999px;
|
||||
width:10px;
|
||||
height: 10px;
|
||||
-moz-transition: none;
|
||||
-webkit-transition: none;
|
||||
-o-transition: color 0 ease-in;
|
||||
transition: none;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.gaddon-setting-select-custom-container .select-custom-reset:hover { background-position-x: -10px; }
|
||||
|
||||
.gaddon-setting-select-custom-container:hover .select-custom-reset {
|
||||
display:block;
|
||||
}
|
||||
|
||||
.gaddon-setting-select-custom-container {
|
||||
display:inline-block;
|
||||
position:relative;
|
||||
width: 210px;
|
||||
}
|
||||
.gaddon-setting-select-custom-container .select-custom-reset {
|
||||
left: 171px;
|
||||
top: 10px;
|
||||
}
|
||||
.gaddon-section .required { color: #f00; }
|
||||
.gaddon-setting-inline{
|
||||
display:inline;
|
||||
margin-right:6px;
|
||||
}
|
||||
|
||||
.gaddon-section-description ol { }
|
||||
.gaddon-section-description ol li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.repeater-buttons .add-item {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.add-item, .remove-item {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.mt-gaddon-editor {
|
||||
float: right;
|
||||
position: relative;
|
||||
right: 0.625rem;
|
||||
top: 2.8125rem;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
div#tab_notification .mt-gaddon-editor {
|
||||
top: 3.3125rem;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .mt-gaddon-editor {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mt-gaddon-editor ~ .wp-editor-wrap {
|
||||
margin-right: 23px;
|
||||
}
|
||||
|
||||
/* Visual Radio Buttons */
|
||||
.gaddon-setting-choice-visual {
|
||||
display: inline-block;
|
||||
margin-bottom: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.gaddon-setting-choice-visual label {
|
||||
background: #F9F9F9;
|
||||
border: 1px solid #eee;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.gaddon-setting-choice-visual label > span {
|
||||
display: inline-block;
|
||||
-webkit-filter: brightness( 1.8 ) grayscale( 1 ) opacity( .5 );
|
||||
-moz-filter: brightness( 1.8 ) grayscale( 1 ) opacity( .5 );
|
||||
filter: brightness( 1.8 ) grayscale( 1 ) opacity( .5 );
|
||||
height: 65px;
|
||||
min-width: 110px;
|
||||
padding: 5px 10px 0;
|
||||
-webkit-transition: all 100ms ease-in;
|
||||
-moz-transition: all 100ms ease-in;
|
||||
transition: all 100ms ease-in;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.gaddon-setting-choice-visual label > span > i {
|
||||
color: #0074a2;
|
||||
display: inline-block;
|
||||
font-size: 2.5em;
|
||||
height: 32px;
|
||||
margin: 5px;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.gaddon-setting-choice-visual label > span > img{
|
||||
height: 32px;
|
||||
margin: 5px;
|
||||
vertical-align: middle;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.gaddon-setting-choice-visual input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.gaddon-setting-choice-visual input:checked + label {
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.gaddon-setting-choice-visual input:checked + label > span {
|
||||
-webkit-filter: none;
|
||||
-moz-filter: none;
|
||||
filter: none;
|
||||
}
|
||||
|
||||
.gaddon-setting-choice-visual input:not([disabled]):not([checked]) + label > span:hover{
|
||||
-webkit-filter: brightness(1.2) grayscale(.5) opacity(.9);
|
||||
-moz-filter: brightness(1.2) grayscale(.5) opacity(.9);
|
||||
filter: brightness(1.2) grayscale(.5) opacity(.9);
|
||||
}
|
||||
|
||||
/* Feed Ordering */
|
||||
.ui-sortable-helper {
|
||||
background-color: #fff !important;
|
||||
-webkit-box-shadow: 6px 6px 28px -9px rgba(0,0,0,0.75);
|
||||
-moz-box-shadow: 6px 6px 28px -9px rgba(0,0,0,0.75);
|
||||
box-shadow: 6px 6px 28px -9px rgba(0,0,0,0.75);
|
||||
transform: rotate(1deg);
|
||||
-moz-transform: rotate(1deg);
|
||||
-webkit-transform: rotate(1deg);
|
||||
}
|
||||
|
||||
.wp-list-table.feed-list-sortable .sort-column {
|
||||
vertical-align: top;
|
||||
width: 2.2em;
|
||||
}
|
||||
|
||||
.wp-list-table.feed-list-sortable .feed-sort-handle {
|
||||
cursor: move;
|
||||
font-size: 1.25rem;
|
||||
width: 2.2em;
|
||||
}
|
||||
|
||||
/* ------------------ Feed List ------------------ */
|
||||
@media screen and ( max-width: 782px ) {
|
||||
.wp-list-table tbody tr:not(.inline-edit-row):not(.no-items) td:not(.column-primary)::before {
|
||||
content: attr(data-colname) ":";
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.wp-list-table.feeds .manage-column {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.wp-list-table.feeds .manage-column img {
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
|
||||
<?php
|
||||
//Nothing to see here
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
@@ -1,2 +0,0 @@
|
||||
<?php
|
||||
//Nothing to see here
|
||||
@@ -1,111 +0,0 @@
|
||||
var GFFeedOrder = function( args ) {
|
||||
|
||||
var self = this,
|
||||
$ = jQuery;
|
||||
|
||||
/**
|
||||
* Initialize Feed Ordering
|
||||
*/
|
||||
self.init = function() {
|
||||
|
||||
// Assign options to instance.
|
||||
self.options = args;
|
||||
|
||||
// Prepare sorting handle.
|
||||
var sortHandleMarkup = '<td class="sort-column"><i class="gform-icon gform-icon--drag-indicator feed-sort-handle"></i></td>';
|
||||
|
||||
// Add sorting handle to table.
|
||||
$( '.wp-list-table thead tr, .wp-list-table tfoot tr' ).append( '<th class="sort-column"></th>' );
|
||||
$( '.wp-list-table tbody tr' ).append( sortHandleMarkup );
|
||||
|
||||
// Initialize sorting.
|
||||
self.initSorting();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize jQuery UI Sortable.
|
||||
*/
|
||||
self.initSorting = function() {
|
||||
|
||||
$( '.wp-list-table tbody' ).sortable(
|
||||
{
|
||||
cursor: 'move',
|
||||
handle: '.feed-sort-handle',
|
||||
placeholder: 'feed-placeholder',
|
||||
tolerance: 'pointer',
|
||||
create: function() { $( '.wp-list-table' ).addClass( 'feed-list-sortable' ); },
|
||||
helper: self.fixSortableColumnWidths,
|
||||
start: self.setPlaceholderHeight,
|
||||
update: self.updateFeedOrder,
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix table column widths.
|
||||
*/
|
||||
self.fixSortableColumnWidths = function( event, tr ) {
|
||||
|
||||
var $originals = tr.children(),
|
||||
$helper = tr.clone();
|
||||
|
||||
$helper.children().each( function( index ) {
|
||||
$( this ).width( $originals.eq( index ).width() );
|
||||
} );
|
||||
|
||||
return $helper;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order of feeds.
|
||||
*/
|
||||
self.getFeedOrder = function() {
|
||||
|
||||
// Get all the checkboxes from the feed list table.
|
||||
var feed_checkboxes = $( '.wp-list-table tbody .check-column input[type="checkbox"]' );
|
||||
|
||||
// Map a function to the feed checkboxes array that returns the checkbox value.
|
||||
return feed_checkboxes.map( function() {
|
||||
return $( this ).val();
|
||||
} ).get();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set height of the placeholder draggable feed.
|
||||
*/
|
||||
self.setPlaceholderHeight = function( event, ui ) {
|
||||
|
||||
// Set the height of the placeholder to the height of the feed being moved.
|
||||
$( '.wp-list-table .feed-placeholder' ).height( ui.item.height() );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the feed ordering to the database.
|
||||
*/
|
||||
self.updateFeedOrder = function( event, ui ) {
|
||||
|
||||
$.ajax(
|
||||
ajaxurl,
|
||||
{
|
||||
method: 'POST',
|
||||
dataType: 'JSON',
|
||||
data: {
|
||||
action: 'gf_save_feed_order',
|
||||
addon: self.options.addon,
|
||||
form_id: self.options.formId,
|
||||
feed_order: self.getFeedOrder(),
|
||||
nonce: self.options.nonce,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
this.init();
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
var GFFeedOrder=function(e){var o=this,i=jQuery;o.init=function(){o.options=e;i(".wp-list-table thead tr, .wp-list-table tfoot tr").append('<th class="sort-column"></th>'),i(".wp-list-table tbody tr").append('<td class="sort-column"><i class="gform-icon gform-icon--drag-indicator feed-sort-handle"></i></td>'),o.initSorting()},o.initSorting=function(){i(".wp-list-table tbody").sortable({cursor:"move",handle:".feed-sort-handle",placeholder:"feed-placeholder",tolerance:"pointer",create:function(){i(".wp-list-table").addClass("feed-list-sortable")},helper:o.fixSortableColumnWidths,start:o.setPlaceholderHeight,update:o.updateFeedOrder})},o.fixSortableColumnWidths=function(e,t){var o=t.children(),t=t.clone();return t.children().each(function(e){i(this).width(o.eq(e).width())}),t},o.getFeedOrder=function(){return i('.wp-list-table tbody .check-column input[type="checkbox"]').map(function(){return i(this).val()}).get()},o.setPlaceholderHeight=function(e,t){i(".wp-list-table .feed-placeholder").height(t.item.height())},o.updateFeedOrder=function(e,t){i.ajax(ajaxurl,{method:"POST",dataType:"JSON",data:{action:"gf_save_feed_order",addon:o.options.addon,form_id:o.options.formId,feed_order:o.getFeedOrder(),nonce:o.options.nonce}})},this.init()};
|
||||
@@ -1,136 +0,0 @@
|
||||
var gfieldmap = function( options ) {
|
||||
|
||||
var self = this;
|
||||
|
||||
self.options = options;
|
||||
self.UI = jQuery( '#gaddon-setting-row-'+ self.options.fieldName );
|
||||
|
||||
self.init = function() {
|
||||
|
||||
self.bindEvents();
|
||||
|
||||
self.setupData();
|
||||
|
||||
self.setupRepeater();
|
||||
|
||||
};
|
||||
|
||||
self.bindEvents = function() {
|
||||
|
||||
self.UI.on( 'change', 'select[name="_gaddon_setting_'+ self.options.keyFieldName +'"]', function() {
|
||||
|
||||
var $select = jQuery( this ),
|
||||
$selectElm = $select.data( 'chosen' ) ? $select.siblings( '.chosen-container' ) : ( $select.data( 'select2' ) ? $select.siblings( '.select2-container' ) : $select ),
|
||||
$input = $select.siblings( '.custom-key-container' );
|
||||
|
||||
if( $select.val() != 'gf_custom' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$selectElm.fadeOut( function() {
|
||||
$input.fadeIn().focus();
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
self.UI.on( 'click', 'a.custom-key-reset', function( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
var $reset = jQuery( this ),
|
||||
$input = $reset.parents( '.custom-key-container' ),
|
||||
$select = $input.siblings( 'select.key' ),
|
||||
$selectElm = $select.data( 'chosen' ) ? $select.siblings( '.chosen-container' ) : ( $select.data( 'select2' ) ? $select.siblings( '.select2-container' ) : $select );
|
||||
|
||||
$input.fadeOut( function() {
|
||||
$input.find( 'input' ).val( '' ).change();
|
||||
$select.val( '' ).trigger( 'change' );
|
||||
$selectElm.fadeIn().focus();
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
self.UI.closest( 'form' ).on( 'submit', function( event ) {
|
||||
|
||||
jQuery( '[name^="_gaddon_setting_'+ self.options.fieldName +'_"]' ).each( function( i ) {
|
||||
|
||||
jQuery( this ).removeAttr( 'name' );
|
||||
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
};
|
||||
|
||||
self.setupData = function() {
|
||||
|
||||
var data = jQuery( '#' + self.options.fieldId ).val();
|
||||
self.data = data ? jQuery.parseJSON( data ) : null;
|
||||
|
||||
if ( ! self.data ) {
|
||||
self.data = [ {
|
||||
key: '',
|
||||
value: '',
|
||||
custom_key: ''
|
||||
} ];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
self.setupRepeater = function() {
|
||||
|
||||
var limit;
|
||||
if (self.options.limit > 0){
|
||||
limit = self.options.limit;
|
||||
}
|
||||
else{
|
||||
limit = 0;
|
||||
}
|
||||
|
||||
self.UI.find( 'tbody.repeater' ).repeater( {
|
||||
|
||||
limit: limit,
|
||||
items: self.data,
|
||||
addButtonMarkup: '<i class="gficon-add"></i>',
|
||||
removeButtonMarkup: '<i class="gficon-subtract"></i>',
|
||||
callbacks: {
|
||||
add: function( obj, $elem, item ) {
|
||||
|
||||
var key_select = $elem.find( 'select[name="_gaddon_setting_'+ self.options.keyFieldName +'"]' );
|
||||
|
||||
if ( ! item.custom_key && key_select.length > 0 ) {
|
||||
$elem.find( '.custom-key-container' ).hide();
|
||||
} else {
|
||||
$elem.find( '.key' ).hide();
|
||||
}
|
||||
|
||||
gform.doAction( 'gform_fieldmap_add_row', obj, $elem, item );
|
||||
|
||||
},
|
||||
save: function( obj, data ) {
|
||||
|
||||
data = jQuery.extend( {}, data );
|
||||
|
||||
for ( var i = 0; i < data.length; i++ ) {
|
||||
|
||||
if ( data[i].custom_key != '' ) {
|
||||
data[i].custom = 1;
|
||||
data[i].key = data[i].custom_key;
|
||||
}
|
||||
|
||||
delete data[i].custom_key;
|
||||
|
||||
}
|
||||
|
||||
jQuery( '#'+ self.options.fieldId ).val( jQuery.toJSON( data ) );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
return self.init();
|
||||
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
var gfieldmap=function(e){var a=this;return a.options=e,a.UI=jQuery("#gaddon-setting-row-"+a.options.fieldName),a.init=function(){a.bindEvents(),a.setupData(),a.setupRepeater()},a.bindEvents=function(){a.UI.on("change",'select[name="_gaddon_setting_'+a.options.keyFieldName+'"]',function(){var e=jQuery(this),t=e.data("chosen")?e.siblings(".chosen-container"):e.data("select2")?e.siblings(".select2-container"):e,n=e.siblings(".custom-key-container");"gf_custom"==e.val()&&t.fadeOut(function(){n.fadeIn().focus()})}),a.UI.on("click","a.custom-key-reset",function(e){e.preventDefault();var t=jQuery(this).parents(".custom-key-container"),n=t.siblings("select.key"),i=n.data("chosen")?n.siblings(".chosen-container"):n.data("select2")?n.siblings(".select2-container"):n;t.fadeOut(function(){t.find("input").val("").change(),n.val("").trigger("change"),i.fadeIn().focus()})}),a.UI.closest("form").on("submit",function(e){jQuery('[name^="_gaddon_setting_'+a.options.fieldName+'_"]').each(function(e){jQuery(this).removeAttr("name")})})},a.setupData=function(){var e=jQuery("#"+a.options.fieldId).val();a.data=e?jQuery.parseJSON(e):null,a.data||(a.data=[{key:"",value:"",custom_key:""}])},a.setupRepeater=function(){var e=0<a.options.limit?a.options.limit:0;a.UI.find("tbody.repeater").repeater({limit:e,items:a.data,addButtonMarkup:'<i class="gficon-add"></i>',removeButtonMarkup:'<i class="gficon-subtract"></i>',callbacks:{add:function(e,t,n){var i=t.find('select[name="_gaddon_setting_'+a.options.keyFieldName+'"]');(!n.custom_key&&0<i.length?t.find(".custom-key-container"):t.find(".key")).hide(),gform.doAction("gform_fieldmap_add_row",e,t,n)},save:function(e,t){t=jQuery.extend({},t);for(var n=0;n<t.length;n++)""!=t[n].custom_key&&(t[n].custom=1,t[n].key=t[n].custom_key),delete t[n].custom_key;jQuery("#"+a.options.fieldId).val(jQuery.toJSON(t))}}})},a.init()};
|
||||
@@ -1,234 +0,0 @@
|
||||
|
||||
var GFFrontendFeeds = function( args ) {
|
||||
|
||||
var self = this,
|
||||
$ = jQuery;
|
||||
|
||||
/**
|
||||
* Initialize Feed Ordering
|
||||
*/
|
||||
self.init = function() {
|
||||
|
||||
// Assign options to instance.
|
||||
self.options = args;
|
||||
|
||||
self.triggerInputIds = self.getTriggerInputIds( self.options.feeds );
|
||||
|
||||
self.activeFeeds = [];
|
||||
|
||||
self.evaluateFeeds();
|
||||
|
||||
self.bindEvents();
|
||||
|
||||
};
|
||||
|
||||
self.bindEvents = function() {
|
||||
|
||||
gform.addAction( 'gform_input_change', function( elem, formId, inputId ) {
|
||||
|
||||
var fieldId = parseInt( inputId ) + '';
|
||||
var isTriggeredInput = $.inArray( inputId, self.triggerInputIds ) !== -1 || $.inArray( fieldId , self.triggerInputIds ) !== -1 ;
|
||||
|
||||
if( self.options.formId == formId && isTriggeredInput ) {
|
||||
self.evaluateFeeds();
|
||||
}
|
||||
} );
|
||||
|
||||
};
|
||||
|
||||
self.evaluateFeeds = function() {
|
||||
|
||||
var feed, isMatch, isActivated;
|
||||
|
||||
for( i = 0; i < self.options.feeds.length; i++ ) {
|
||||
|
||||
feed = self.options.feeds[ i ];
|
||||
isMatch = self.evaluateFeed( feed, self.options.formId );
|
||||
isActivated = self.isFeedActivated( feed );
|
||||
|
||||
if( ! isMatch && isActivated !== null ) {
|
||||
self.deactivateFeed( feed );
|
||||
} else if( isMatch && ! isActivated && ( ! feed.isSingleFeed || ( feed.isSingleFeed && self.hasPriority( feed.feedId, feed.addonSlug ) ) ) ) {
|
||||
self.activateFeed( feed );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after the conditional logic on the form has been evaluated.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $feeds A collection of feed objects.
|
||||
* @param int $formId The form id.
|
||||
*/
|
||||
gform.doAction( 'gform_frontend_feeds_evaluated', self.options.feeds, self.options.formId, self );
|
||||
gform.doAction( 'gform_frontend_feeds_evaluated_{0}'.gformFormat( self.options.formId ), self.options.feeds, self.options.formId, self );
|
||||
gform.doAction( 'gform_{0}_frontend_feeds_evaluated'.gformFormat( feed.addonSlug ), self.options.feeds, self.options.formId, self );
|
||||
gform.doAction( 'gform_{0}_frontend_feeds_evaluated_{0}'.gformFormat( feed.addonSlug, self.options.formId ), self.options.feeds, self.options.formId, self );
|
||||
|
||||
};
|
||||
|
||||
self.evaluateFeed = function( feed, formId ) {
|
||||
|
||||
// Feeds with no configured conditional logic always a match.
|
||||
if( ! feed.conditionalLogic ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return gf_get_field_action( formId, feed.conditionalLogic ) == 'show';
|
||||
};
|
||||
|
||||
self.getTriggerInputIds = function() {
|
||||
var inputIds = [];
|
||||
for( var i = 0; i < self.options.feeds.length; i++ ) {
|
||||
|
||||
var feed = self.options.feeds[ i ];
|
||||
|
||||
if( ! feed.conditionalLogic ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for( var j = 0; j < feed.conditionalLogic.rules.length; j++ ) {
|
||||
var rule = self.options.feeds[i].conditionalLogic.rules[j];
|
||||
if( $.inArray( rule.fieldId, inputIds ) == -1 ) {
|
||||
inputIds.push( rule.fieldId );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return inputIds;
|
||||
};
|
||||
|
||||
self.isFeedActivated = function( feed ) {
|
||||
|
||||
if( typeof feed != 'object' ) {
|
||||
feed = self.getFeed( feed );
|
||||
if( ! feed ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return typeof feed.isActivated != 'undefined' ? feed.isActivated : null;
|
||||
};
|
||||
|
||||
self.getFeed = function( feedId ) {
|
||||
for( var i = 0; i < self.options.feeds.length; i++ ) {
|
||||
var feed = self.options.feeds[ i ];
|
||||
if( feed.feedId == feedId ) {
|
||||
return feed;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
self.getFeedsByAddon = function( addonSlug, currentFeed, onlyActive ) {
|
||||
var feeds = [];
|
||||
for( var i = 0; i < self.options.feeds.length; i++ ) {
|
||||
var feed = self.options.feeds[ i ];
|
||||
if( feed.addonSlug == addonSlug
|
||||
&& ! ( currentFeed && feed.feedId == currentFeed.feedId )
|
||||
) {
|
||||
if( onlyActive ) {
|
||||
if( self.isFeedActivated( feed ) ) {
|
||||
feeds.push( feed );
|
||||
}
|
||||
} else {
|
||||
feeds.push( feed );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return feeds;
|
||||
};
|
||||
|
||||
self.activateFeed = function( feeds ) {
|
||||
|
||||
if( feeds.feedId ) {
|
||||
feeds = [ feeds ];
|
||||
}
|
||||
|
||||
for( var i = 0; i < feeds.length; i++ ) {
|
||||
|
||||
var feed = feeds[ i ];
|
||||
|
||||
feed.isActivated = true;
|
||||
|
||||
/**
|
||||
* Fires after the conditional logic on the form has been evaluated and the feed has been found to be active.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $feeds A collection of feed objects.
|
||||
* @param int $formId The form id.
|
||||
*/
|
||||
|
||||
gform.doAction( 'gform_frontend_feed_activated', feed, self.options.formId );
|
||||
gform.doAction( 'gform_frontend_feed_activated_{0}'.gformFormat( self.options.formId ), feed, self.options.formId );
|
||||
gform.doAction( 'gform_{0}_frontend_feed_activated'.gformFormat( feed.addonSlug ), feed, self.options.formId );
|
||||
gform.doAction( 'gform_{0}_frontend_feed_activated_{0}'.gformFormat( feed.addonSlug, self.options.formId ), feed, self.options.formId );
|
||||
|
||||
if( feed.isSingleFeed ) {
|
||||
self.deactivateFeed( self.getFeedsByAddon( feed.addonSlug, feed ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
self.deactivateFeed = function( feeds ) {
|
||||
|
||||
if( feeds.feedId ) {
|
||||
feeds = [ feeds ];
|
||||
}
|
||||
|
||||
for( var i = 0; i < feeds.length; i++ ) {
|
||||
|
||||
var feed = feeds[ i ],
|
||||
isActivated = self.isFeedActivated( feed );
|
||||
|
||||
if( isActivated === null || isActivated === false ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
feed.isActivated = false;
|
||||
|
||||
/**
|
||||
* Fires after the conditional logic on the form has been evaluated and the feed has become inactive.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $feeds A collection of feed objects.
|
||||
* @param int $formId The form id.
|
||||
*/
|
||||
gform.doAction( 'gform_frontend_feed_deactivated', feed, self.options.formId );
|
||||
gform.doAction( 'gform_frontend_feed_deactivated_{0}'.gformFormat( self.options.formId ), feed, self.options.formId );
|
||||
gform.doAction( 'gform_{0}_frontend_feed_deactivated'.gformFormat( feed.addonSlug ), feed, self.options.formId );
|
||||
gform.doAction( 'gform_{0}_frontend_feed_deactivated_{0}'.gformFormat( feed.addonSlug, self.options.formId ), feed, self.options.formId );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
self.hasPriority = function( feedId, addonSlug ) {
|
||||
|
||||
var addonFeeds = self.getFeedsByAddon( addonSlug );
|
||||
|
||||
for( var i = 0; i <= addonFeeds.length; i++ ) {
|
||||
|
||||
var feed = addonFeeds[i];
|
||||
|
||||
if( feed.feedId != feedId && feed.isActivated ) {
|
||||
return false;
|
||||
} else if ( feed.feedId == feedId ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
this.init();
|
||||
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
var GFFrontendFeeds=function(o){var r=this,f=jQuery;r.init=function(){r.options=o,r.triggerInputIds=r.getTriggerInputIds(r.options.feeds),r.activeFeeds=[],r.evaluateFeeds(),r.bindEvents()},r.bindEvents=function(){gform.addAction("gform_input_change",function(o,e,t){var d=parseInt(t)+"",t=-1!==f.inArray(t,r.triggerInputIds)||-1!==f.inArray(d,r.triggerInputIds);r.options.formId==e&&t&&r.evaluateFeeds()})},r.evaluateFeeds=function(){var o,e,t;for(i=0;i<r.options.feeds.length;i++)o=r.options.feeds[i],e=r.evaluateFeed(o,r.options.formId),t=r.isFeedActivated(o),e||null===t?e&&!t&&(!o.isSingleFeed||o.isSingleFeed&&r.hasPriority(o.feedId,o.addonSlug))&&r.activateFeed(o):r.deactivateFeed(o);gform.doAction("gform_frontend_feeds_evaluated",r.options.feeds,r.options.formId,r),gform.doAction("gform_frontend_feeds_evaluated_{0}".gformFormat(r.options.formId),r.options.feeds,r.options.formId,r),gform.doAction("gform_{0}_frontend_feeds_evaluated".gformFormat(o.addonSlug),r.options.feeds,r.options.formId,r),gform.doAction("gform_{0}_frontend_feeds_evaluated_{0}".gformFormat(o.addonSlug,r.options.formId),r.options.feeds,r.options.formId,r)},r.evaluateFeed=function(o,e){return!o.conditionalLogic||"show"==gf_get_field_action(e,o.conditionalLogic)},r.getTriggerInputIds=function(){for(var o=[],e=0;e<r.options.feeds.length;e++){var t=r.options.feeds[e];if(t.conditionalLogic)for(var d=0;d<t.conditionalLogic.rules.length;d++){var n=r.options.feeds[e].conditionalLogic.rules[d];-1==f.inArray(n.fieldId,o)&&o.push(n.fieldId)}}return o},r.isFeedActivated=function(o){return!("object"!=typeof o&&!(o=r.getFeed(o)))&&(void 0!==o.isActivated?o.isActivated:null)},r.getFeed=function(o){for(var e=0;e<r.options.feeds.length;e++){var t=r.options.feeds[e];if(t.feedId==o)return t}return!1},r.getFeedsByAddon=function(o,e,t){for(var d=[],n=0;n<r.options.feeds.length;n++){var i=r.options.feeds[n];i.addonSlug!=o||e&&i.feedId==e.feedId||t&&!r.isFeedActivated(i)||d.push(i)}return d},r.activateFeed=function(o){o.feedId&&(o=[o]);for(var e=0;e<o.length;e++){var t=o[e];t.isActivated=!0,gform.doAction("gform_frontend_feed_activated",t,r.options.formId),gform.doAction("gform_frontend_feed_activated_{0}".gformFormat(r.options.formId),t,r.options.formId),gform.doAction("gform_{0}_frontend_feed_activated".gformFormat(t.addonSlug),t,r.options.formId),gform.doAction("gform_{0}_frontend_feed_activated_{0}".gformFormat(t.addonSlug,r.options.formId),t,r.options.formId),t.isSingleFeed&&r.deactivateFeed(r.getFeedsByAddon(t.addonSlug,t))}},r.deactivateFeed=function(o){o.feedId&&(o=[o]);for(var e=0;e<o.length;e++){var t=o[e],d=r.isFeedActivated(t);null!==d&&!1!==d&&(t.isActivated=!1,gform.doAction("gform_frontend_feed_deactivated",t,r.options.formId),gform.doAction("gform_frontend_feed_deactivated_{0}".gformFormat(r.options.formId),t,r.options.formId),gform.doAction("gform_{0}_frontend_feed_deactivated".gformFormat(t.addonSlug),t,r.options.formId),gform.doAction("gform_{0}_frontend_feed_deactivated_{0}".gformFormat(t.addonSlug,r.options.formId),t,r.options.formId))}},r.hasPriority=function(o,e){for(var t=r.getFeedsByAddon(e),d=0;d<=t.length;d++){var n=t[d];if(n.feedId!=o&&n.isActivated)return!1;if(n.feedId==o)return!0}return!1},this.init()};
|
||||
@@ -1,166 +0,0 @@
|
||||
var GFGenericMap = function( options ) {
|
||||
|
||||
var self = this;
|
||||
|
||||
self.options = options;
|
||||
self.UI = jQuery( '#gaddon-setting-row-'+ self.options.fieldName );
|
||||
|
||||
self.init = function() {
|
||||
|
||||
self.bindEvents();
|
||||
|
||||
self.setupData();
|
||||
|
||||
self.setupRepeater();
|
||||
|
||||
};
|
||||
|
||||
self.bindEvents = function() {
|
||||
|
||||
self.UI.on( 'change', 'select[name="_gaddon_setting_'+ self.options.keyFieldName +'"]', function() {
|
||||
|
||||
var $select = jQuery( this ),
|
||||
$selectElm = $select.data( 'chosen' ) ? $select.siblings( '.chosen-container' ) : ( $select.data( 'select2' ) ? $select.siblings( '.select2-container' ) : $select ),
|
||||
$input = $select.siblings( '.custom-key-container' );
|
||||
|
||||
if( $select.val() != 'gf_custom' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$selectElm.fadeOut( function() {
|
||||
$input.fadeIn().focus();
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
self.UI.on( 'change', 'select[name="_gaddon_setting_'+ self.options.valueFieldName +'"]', function() {
|
||||
|
||||
var $select = jQuery( this ),
|
||||
$selectElm = $select.data( 'chosen' ) ? $select.siblings( '.chosen-container' ) : ( $select.data( 'select2' ) ? $select.siblings( '.select2-container' ) : $select ),
|
||||
$input = $select.siblings( '.custom-value-container' );
|
||||
|
||||
if ( $select.val() != 'gf_custom' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$selectElm.fadeOut( function() {
|
||||
$input.fadeIn().focus();
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
self.UI.on( 'click', 'a.custom-key-reset', function( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
var $reset = jQuery( this ),
|
||||
$input = $reset.parents( '.custom-key-container' ),
|
||||
$select = $input.siblings( 'select.key' ),
|
||||
$selectElm = $select.data( 'chosen' ) ? $select.siblings( '.chosen-container' ) : ( $select.data( 'select2' ) ? $select.siblings( '.select2-container' ) : $select );
|
||||
|
||||
$input.fadeOut( function() {
|
||||
$input.find( 'input' ).val( '' ).change();
|
||||
$select.val( '' ).trigger( 'change' );
|
||||
$selectElm.fadeIn().focus();
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
self.UI.on( 'click', 'a.custom-value-reset', function( event ) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
var $reset = jQuery( this ),
|
||||
$input = $reset.parents( '.custom-value-container' ),
|
||||
$select = $input.siblings( 'select.value' ),
|
||||
$selectElm = $select.data( 'chosen' ) ? $select.siblings( '.chosen-container' ) : ( $select.data( 'select2' ) ? $select.siblings( '.select2-container' ) : $select );
|
||||
|
||||
$input.fadeOut( function() {
|
||||
$input.find( 'input' ).val( '' ).change();
|
||||
$select.val( '' ).trigger( 'change' );
|
||||
$selectElm.fadeIn().focus();
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
self.UI.closest( 'form' ).on( 'submit', function( event ) {
|
||||
|
||||
jQuery( '[name^="_gaddon_setting_'+ self.options.fieldName +'_"]' ).each( function( i ) {
|
||||
|
||||
jQuery( this ).removeAttr( 'name' );
|
||||
|
||||
} );
|
||||
|
||||
} );
|
||||
|
||||
};
|
||||
|
||||
self.setupData = function() {
|
||||
|
||||
var data = jQuery( '#' + self.options.fieldId ).val();
|
||||
self.data = data ? jQuery.parseJSON( data ) : null;
|
||||
|
||||
if ( ! self.data ) {
|
||||
self.data = [ {
|
||||
key: '',
|
||||
value: '',
|
||||
custom_key: '',
|
||||
custom_value: ''
|
||||
} ];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
self.setupRepeater = function() {
|
||||
|
||||
var limit = self.options.limit > 0 ? self.options.limit : 0;
|
||||
|
||||
self.UI.find( 'tbody.repeater' ).repeater( {
|
||||
|
||||
limit: limit,
|
||||
items: self.data,
|
||||
addButtonMarkup: '<i class="gficon-add"></i>',
|
||||
removeButtonMarkup: '<i class="gficon-subtract"></i>',
|
||||
callbacks: {
|
||||
add: function( obj, $elem, item ) {
|
||||
|
||||
var key_select = $elem.find( 'select[name="_gaddon_setting_'+ self.options.keyFieldName +'"]' );
|
||||
|
||||
if ( ! item.custom_key && ( key_select.length > 0 && key_select.val() !== 'gf_custom' ) ) {
|
||||
$elem.find( '.custom-key-container' ).hide();
|
||||
} else {
|
||||
$elem.find( '.key' ).hide();
|
||||
}
|
||||
|
||||
var value_select = $elem.find( 'select[name="_gaddon_setting_'+ self.options.valueFieldName +'"]' );
|
||||
|
||||
if ( ! item.custom_value && ( value_select.length > 0 && value_select.val() !== 'gf_custom' ) ) {
|
||||
$elem.find( '.custom-value-container' ).hide();
|
||||
} else {
|
||||
$elem.find( '.value' ).hide();
|
||||
}
|
||||
|
||||
if ( self.options.mergeTags ) {
|
||||
new gfMergeTagsObj( form, $elem.find( '.custom-value-container input' ) );
|
||||
$elem.find( '.custom-value-container' ).addClass( 'supports-merge-tags' );
|
||||
}
|
||||
|
||||
if ( window.hasOwnProperty( 'gform' ) ) {
|
||||
gform.doAction( 'gform_fieldmap_add_row', obj, $elem, item );
|
||||
}
|
||||
|
||||
},
|
||||
save: function( obj, data ) {
|
||||
|
||||
jQuery( '#'+ self.options.fieldId ).val( JSON.stringify( data ) );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
return self.init();
|
||||
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
var GFGenericMap=function(e){var i=this;return i.options=e,i.UI=jQuery("#gaddon-setting-row-"+i.options.fieldName),i.init=function(){i.bindEvents(),i.setupData(),i.setupRepeater()},i.bindEvents=function(){i.UI.on("change",'select[name="_gaddon_setting_'+i.options.keyFieldName+'"]',function(){var e=jQuery(this),n=e.data("chosen")?e.siblings(".chosen-container"):e.data("select2")?e.siblings(".select2-container"):e,t=e.siblings(".custom-key-container");"gf_custom"==e.val()&&n.fadeOut(function(){t.fadeIn().focus()})}),i.UI.on("change",'select[name="_gaddon_setting_'+i.options.valueFieldName+'"]',function(){var e=jQuery(this),n=e.data("chosen")?e.siblings(".chosen-container"):e.data("select2")?e.siblings(".select2-container"):e,t=e.siblings(".custom-value-container");"gf_custom"==e.val()&&n.fadeOut(function(){t.fadeIn().focus()})}),i.UI.on("click","a.custom-key-reset",function(e){e.preventDefault();var n=jQuery(this).parents(".custom-key-container"),t=n.siblings("select.key"),a=t.data("chosen")?t.siblings(".chosen-container"):t.data("select2")?t.siblings(".select2-container"):t;n.fadeOut(function(){n.find("input").val("").change(),t.val("").trigger("change"),a.fadeIn().focus()})}),i.UI.on("click","a.custom-value-reset",function(e){e.preventDefault();var n=jQuery(this).parents(".custom-value-container"),t=n.siblings("select.value"),a=t.data("chosen")?t.siblings(".chosen-container"):t.data("select2")?t.siblings(".select2-container"):t;n.fadeOut(function(){n.find("input").val("").change(),t.val("").trigger("change"),a.fadeIn().focus()})}),i.UI.closest("form").on("submit",function(e){jQuery('[name^="_gaddon_setting_'+i.options.fieldName+'_"]').each(function(e){jQuery(this).removeAttr("name")})})},i.setupData=function(){var e=jQuery("#"+i.options.fieldId).val();i.data=e?jQuery.parseJSON(e):null,i.data||(i.data=[{key:"",value:"",custom_key:"",custom_value:""}])},i.setupRepeater=function(){var e=0<i.options.limit?i.options.limit:0;i.UI.find("tbody.repeater").repeater({limit:e,items:i.data,addButtonMarkup:'<i class="gficon-add"></i>',removeButtonMarkup:'<i class="gficon-subtract"></i>',callbacks:{add:function(e,n,t){var a=n.find('select[name="_gaddon_setting_'+i.options.keyFieldName+'"]'),a=((!t.custom_key&&0<a.length&&"gf_custom"!==a.val()?n.find(".custom-key-container"):n.find(".key")).hide(),n.find('select[name="_gaddon_setting_'+i.options.valueFieldName+'"]'));(!t.custom_value&&0<a.length&&"gf_custom"!==a.val()?n.find(".custom-value-container"):n.find(".value")).hide(),i.options.mergeTags&&(new gfMergeTagsObj(form,n.find(".custom-value-container input")),n.find(".custom-value-container").addClass("supports-merge-tags")),window.hasOwnProperty("gform")&&gform.doAction("gform_fieldmap_add_row",e,n,t)},save:function(e,n){jQuery("#"+i.options.fieldId).val(JSON.stringify(n))}}})},i.init()};
|
||||
@@ -1,46 +0,0 @@
|
||||
function loadBillingLength(setting_name){
|
||||
var intervals = window[setting_name + "_intervals"]
|
||||
if(!intervals)
|
||||
return;
|
||||
|
||||
var unit = jQuery("#" + setting_name + "_unit").val();
|
||||
var min = gform.utils.escapeHtml( intervals[unit]["min"] );
|
||||
var max = gform.utils.escapeHtml( intervals[unit]["max"] );
|
||||
var lengthField = jQuery("#" + setting_name + "_length");
|
||||
var length = lengthField.val();
|
||||
var str = "";
|
||||
for(var i=min; i<=max; i++){
|
||||
var selected = length == i ? "selected='selected'" : "";
|
||||
str += "<option value='" + i + "' " + selected + ">" + i + "</option>";
|
||||
}
|
||||
lengthField.html( str );
|
||||
}
|
||||
|
||||
function cancel_subscription( entryId ) {
|
||||
|
||||
if ( !confirm( gaddon_payment_strings.subscriptionCancelWarning ) )
|
||||
return;
|
||||
|
||||
jQuery( "#subscription_cancel_spinner" ).show();
|
||||
jQuery( "#cancelsub" ).prop( "disabled", true );
|
||||
jQuery.post(
|
||||
ajaxurl,
|
||||
{
|
||||
action: "gaddon_cancel_subscription",
|
||||
entry_id: entryId,
|
||||
gaddon_cancel_subscription: gaddon_payment_strings.subscriptionCancelNonce
|
||||
},
|
||||
function ( response ) {
|
||||
jQuery( "#subscription_cancel_spinner" ).hide();
|
||||
if ( response.success === true ) {
|
||||
jQuery( "#gform_payment_status" ).html( gform.utils.escapeHtml( gaddon_payment_strings.subscriptionCanceled ) );
|
||||
jQuery( "#cancelsub" ).hide();
|
||||
} else {
|
||||
jQuery( "#cancelsub" ).prop( "disabled", false );
|
||||
if ( response.success === false ) {
|
||||
alert( gaddon_payment_strings.subscriptionError );
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
function loadBillingLength(n){var e=window[n+"_intervals"];if(e){for(var s=jQuery("#"+n+"_unit").val(),i=gform.utils.escapeHtml(e[s].min),c=gform.utils.escapeHtml(e[s].max),e=jQuery("#"+n+"_length"),t=e.val(),r="",a=i;a<=c;a++)r+="<option value='"+a+"' "+(t==a?"selected='selected'":"")+">"+a+"</option>";e.html(r)}}function cancel_subscription(n){confirm(gaddon_payment_strings.subscriptionCancelWarning)&&(jQuery("#subscription_cancel_spinner").show(),jQuery("#cancelsub").prop("disabled",!0),jQuery.post(ajaxurl,{action:"gaddon_cancel_subscription",entry_id:n,gaddon_cancel_subscription:gaddon_payment_strings.subscriptionCancelNonce},function(n){jQuery("#subscription_cancel_spinner").hide(),!0===n.success?(jQuery("#gform_payment_status").html(gform.utils.escapeHtml(gaddon_payment_strings.subscriptionCanceled)),jQuery("#cancelsub").hide()):(jQuery("#cancelsub").prop("disabled",!1),!1===n.success&&alert(gaddon_payment_strings.subscriptionError))}))}
|
||||
@@ -1,251 +0,0 @@
|
||||
var gresultsAjaxRequest;
|
||||
|
||||
var gresults = {
|
||||
|
||||
drawCharts: function () {
|
||||
var containers = jQuery('.gresults-chart-wrapper');
|
||||
containers.each(function (index, elem) {
|
||||
var id = jQuery(elem).attr('id');
|
||||
var options = jQuery(elem).data('options');
|
||||
var datatable = jQuery(elem).data('datatable');
|
||||
var chartType = jQuery(elem).data('charttype');
|
||||
var data_array = datatable;
|
||||
var data = google.visualization.arrayToDataTable(data_array);
|
||||
var cont = document.getElementById(id);
|
||||
var chart;
|
||||
if (chartType == "bar") {
|
||||
chart = new google.visualization.BarChart(cont);
|
||||
} else if (chartType == "pie") {
|
||||
chart = new google.visualization.PieChart(cont);
|
||||
} else if (chartType == "column") {
|
||||
chart = new google.visualization.ColumnChart(cont);
|
||||
}
|
||||
chart.draw(data, options);
|
||||
});
|
||||
},
|
||||
|
||||
renderStateData: function (state) {
|
||||
var results = jQuery("#gresults-results");
|
||||
results.data('searchcriteria', state.searchCriteria);
|
||||
jQuery("#gresults-results-filter").html(state.filterUI);
|
||||
results.css('opacity', 0);
|
||||
results.html(state.html);
|
||||
gresults.drawCharts();
|
||||
results.fadeTo("slow", 1);
|
||||
|
||||
var filterContainer = jQuery("#gresults-results-field-filters-container");
|
||||
filterContainer.resizable();
|
||||
filterContainer.resizable('destroy');
|
||||
filterContainer.resizable({
|
||||
handles: 's'
|
||||
});
|
||||
},
|
||||
|
||||
getResults: function () {
|
||||
gresults.recordFormState();
|
||||
var gresultsData = jQuery('#gresults-results-filter-form').serialize();
|
||||
gresults.sendRequest(gresultsData)
|
||||
},
|
||||
|
||||
sendRequest: function (gresultsData, serverStateObject, checkSum) {
|
||||
var results = jQuery("#gresults-results");
|
||||
var filterButtons = jQuery("#gresults-results-filter-buttons input");
|
||||
var viewSlug = jQuery("#gresults-view-slug").val();
|
||||
var nonce = jQuery("#_gf_results_nonce").val()
|
||||
var data_str = "action=gresults_get_results_" + viewSlug + "&" + gresultsData + '&_gf_results_nonce' + nonce ;
|
||||
if (serverStateObject)
|
||||
data_str += "&state=" + serverStateObject + "&checkSum=" + checkSum;
|
||||
|
||||
gresultsAjaxRequest = jQuery.ajax({
|
||||
url : ajaxurl,
|
||||
type : 'POST',
|
||||
dataType : 'json',
|
||||
data : data_str,
|
||||
beforeSend: function (xhr, opts) {
|
||||
results.fadeTo("slow", 0.33);
|
||||
results.html('');
|
||||
gform.utils.trigger( { event: 'gform/page_loader/show' } );
|
||||
filterButtons.attr('disabled', 'disabled');
|
||||
}
|
||||
})
|
||||
.done(function (response) {
|
||||
if (!response || response === -1) {
|
||||
gform.utils.trigger( { event: 'gform/page_loader/hide' } );
|
||||
results.html(gresultsStrings.ajaxError);
|
||||
} else {
|
||||
if (response.status === "complete") {
|
||||
filterButtons.removeAttr('disabled');
|
||||
gform.utils.trigger( { event: 'gform/page_loader/hide' } );
|
||||
results.html(response.html);
|
||||
jQuery("#gresults-results").data('searchcriteria', response.searchCriteria); //used in 'more' links
|
||||
|
||||
var filterUI = jQuery("#gresults-results-filter").html();
|
||||
|
||||
gresults.drawCharts();
|
||||
results.fadeTo("slow", 1);
|
||||
if (window.history.replaceState) {
|
||||
if (!history.state) {
|
||||
history.replaceState({"html": response.html, "filterUI": filterUI, "searchCriteria": response.searchCriteria}, "", "?" + gresultsData);
|
||||
} else {
|
||||
history.pushState({"html": response.html, "filterUI": filterUI, "searchCriteria": response.searchCriteria}, "", "?" + gresultsData);
|
||||
}
|
||||
}
|
||||
gresults.drawCharts();
|
||||
if (window["gform_initialize_tooltips"])
|
||||
gform_initialize_tooltips();
|
||||
} else if (response.status === "incomplete") {
|
||||
serverStateObject = response.stateObject;
|
||||
gresults.sendRequest(gresultsData, serverStateObject, response.checkSum);
|
||||
results.html(response.html);
|
||||
} else {
|
||||
gform.utils.trigger( { event: 'gform/page_loader/hide' } );
|
||||
results.html(gresultsStrings.ajaxError);
|
||||
}
|
||||
}
|
||||
})
|
||||
.fail(function (error) {
|
||||
filterButtons.removeAttr('disabled');
|
||||
results.fadeTo("fast", 1);
|
||||
var msg = error.statusText;
|
||||
gform.utils.trigger( { event: 'gform/page_loader/hide' } );
|
||||
if (msg == "abort") {
|
||||
msg = "Request cancelled";
|
||||
} else {
|
||||
msg = gresultsStrings.ajaxError;
|
||||
}
|
||||
results.html(msg);
|
||||
})
|
||||
},
|
||||
|
||||
getMoreResults: function (formId, fieldId) {
|
||||
var container = jQuery('#gresults-results-field-content-' + fieldId),
|
||||
results = jQuery("#gresults-results"),
|
||||
offset = jQuery(container).data('offset'),
|
||||
viewSlug = jQuery("#gresults-view-slug").val(),
|
||||
searchCriteria = results.data('searchcriteria'),
|
||||
nonce = jQuery("#_gf_results_nonce").val();
|
||||
|
||||
jQuery.ajax({
|
||||
url : ajaxurl,
|
||||
type : 'POST',
|
||||
dataType: 'json',
|
||||
data : {
|
||||
action: 'gresults_get_more_results_' + viewSlug,
|
||||
view: viewSlug,
|
||||
form_id: formId,
|
||||
field_id: fieldId,
|
||||
offset: offset,
|
||||
search_criteria: searchCriteria,
|
||||
_gf_results_nonce: nonce
|
||||
},
|
||||
success : function (response) {
|
||||
if (response === -1) {
|
||||
//permission denied
|
||||
}
|
||||
else {
|
||||
if (response.html)
|
||||
jQuery(container).append(response.html);
|
||||
if (!response.more_remaining)
|
||||
jQuery('#gresults-results-field-more-link-' + fieldId).hide();
|
||||
|
||||
jQuery(container).data('offset', response.offset);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
|
||||
},
|
||||
|
||||
clearFilterForm: function () {
|
||||
jQuery("#gresults-results-field-filters-container").off('click', '.gform-add').gfFilterUI(gresultsFilterSettings, [], true);
|
||||
jQuery('#gresults-results-filter-form').find('input, select').each(function () {
|
||||
switch (this.type) {
|
||||
case 'text':
|
||||
case 'select-one':
|
||||
jQuery(this).val('').change();
|
||||
break;
|
||||
case 'checkbox':
|
||||
case 'radio':
|
||||
this.checked = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
recordFormState: function () {
|
||||
jQuery("#gresults-results-filter-form input[type='radio']").each(function () {
|
||||
if (this.checked) {
|
||||
jQuery(this).prop("defaultChecked", true);
|
||||
} else {
|
||||
jQuery(this).prop("defaultChecked", false);
|
||||
}
|
||||
});
|
||||
jQuery("#gresults-results-filter-form input[type='checkbox']").each(function () {
|
||||
if (this.checked) {
|
||||
jQuery(this).prop("defaultChecked", true);
|
||||
} else {
|
||||
jQuery(this).prop("defaultChecked", false);
|
||||
}
|
||||
});
|
||||
jQuery("#gresults-results-filter-form input[type='text']").each(function () {
|
||||
jQuery(this).prop("defaultValue", jQuery(this).val());
|
||||
});
|
||||
jQuery("#gresults-results-filter-form select option").each(function () {
|
||||
jQuery(this).prop("defaultSelected", jQuery(this).prop('selected'));
|
||||
});
|
||||
},
|
||||
|
||||
setCustomFilter: function(key, value){
|
||||
elementId = "gresults-custom-" + key;
|
||||
if(jQuery('#' + elementId).length == 0)
|
||||
jQuery('#gresults-results-filter-form').append("<input type='hidden' id='" + elementId + "' name='" + key + "' value='" + value + "'>");
|
||||
else
|
||||
jQuery('#' + elementId).val(value);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
google.load('visualization', '1', {packages: ['corechart']});
|
||||
google.setOnLoadCallback(gresults.drawCharts);
|
||||
|
||||
|
||||
jQuery( window ).on( 'load', function () {
|
||||
|
||||
if (jQuery("#gresults-results").length > 0) {
|
||||
|
||||
jQuery("#gresults-results-field-filters-container").gfFilterUI(gresultsFilterSettings, gresultsInitVars, true);
|
||||
var $window = jQuery(window);
|
||||
|
||||
$window.resize(function (e) {
|
||||
if (e.target === window) {
|
||||
gresults.drawCharts();
|
||||
}
|
||||
});
|
||||
|
||||
window.onpopstate = function (e) {
|
||||
if (e.state)
|
||||
gresults.renderStateData(e.state)
|
||||
};
|
||||
|
||||
|
||||
jQuery("#gresults-results-filter-date-start, #gresults-results-filter-date-end").datepicker({dateFormat: 'yy-mm-dd', changeMonth: true, changeYear: true});
|
||||
|
||||
jQuery('.ui-datepicker-trigger').on('click', function() {
|
||||
jQuery(this).parent().find('input').datepicker( 'show' );
|
||||
});
|
||||
|
||||
jQuery("#gresults-results-filter-form").submit(function (e) {
|
||||
gresults.getResults();
|
||||
return false;
|
||||
});
|
||||
|
||||
if (history.state) {
|
||||
gresults.renderStateData(history.state)
|
||||
} else {
|
||||
gresults.getResults();
|
||||
}
|
||||
if (window["gform_initialize_tooltips"])
|
||||
gform_initialize_tooltips();
|
||||
|
||||
}
|
||||
});
|
||||
File diff suppressed because one or more lines are too long
@@ -1,131 +0,0 @@
|
||||
window.GFToken = null;
|
||||
|
||||
( function( $ ) {
|
||||
|
||||
GFToken = function( args ) {
|
||||
|
||||
for ( var prop in args ) {
|
||||
if ( args.hasOwnProperty( prop ) )
|
||||
this[prop] = args[prop];
|
||||
}
|
||||
|
||||
this.form = $( '#gform_' + this.formId );
|
||||
|
||||
this.init = function() {
|
||||
|
||||
var GFTokenObj = this;
|
||||
|
||||
this.tokens = {};
|
||||
|
||||
/* Initialize spinner. */
|
||||
if ( ! this.isAjax )
|
||||
gformInitSpinner( this.formId );
|
||||
|
||||
/* If multipage form, run on gform_page_loaded. */
|
||||
if ( this.hasPages ) {
|
||||
|
||||
$( document ).bind( 'gform_page_loaded', function( event, form_id, current_page ) {
|
||||
|
||||
if ( form_id != GFTokenObj.formId)
|
||||
return;
|
||||
|
||||
if ( current_page != GFTokenObj.pageCount)
|
||||
GFTokenObj.saveEntryData();
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
this.form.submit( function() {
|
||||
GFTokenObj.onSubmit();
|
||||
} );
|
||||
|
||||
};
|
||||
|
||||
this.onSubmit = function() {
|
||||
|
||||
if ( this.form.data('gftokensubmitting') ) {
|
||||
return;
|
||||
} else {
|
||||
event.preventDefault();
|
||||
this.form.data( 'gftokensubmitting', true );
|
||||
}
|
||||
|
||||
this.saveEntryData();
|
||||
this.processTokens();
|
||||
|
||||
}
|
||||
|
||||
this.processTokens = function() {
|
||||
|
||||
/* Process feeds. */
|
||||
for ( var feed_id in this.feeds ) {
|
||||
|
||||
this.active_feed = this.feeds[feed_id];
|
||||
|
||||
/* Create new feed object so we can store the billing information. */
|
||||
var feed = {
|
||||
'billing_fields': {},
|
||||
'id': this.active_feed.id,
|
||||
'name': this.active_feed.name
|
||||
};
|
||||
|
||||
/* Add billing information to feed object. */
|
||||
for ( var billing_field in this.active_feed.billing_fields ) {
|
||||
|
||||
field_id = this.active_feed.billing_fields[ billing_field ];
|
||||
feed.billing_fields[ billing_field ] = this.entry_data[ field_id ];
|
||||
|
||||
}
|
||||
|
||||
/* Get credit card token response. */
|
||||
window[ this.callback ].createToken( feed, this );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.saveEntryData = function() {
|
||||
|
||||
var GFPaymentObj = this,
|
||||
input_prefix = 'input_' + this.formId + '_';
|
||||
|
||||
if ( ! this.entry_data )
|
||||
this.entry_data = {};
|
||||
|
||||
this.form.find( 'input[id^="' + input_prefix + '"], select[id^="' + input_prefix + '"], textarea[id^="' + input_prefix + '"]' ).each( function() {
|
||||
|
||||
var input_id = $( this ).attr( 'id' ).replace( input_prefix, '' ).replace( '_', '.' );
|
||||
|
||||
if ( $.inArray( input_id, GFPaymentObj.fields ) >= 0 )
|
||||
GFPaymentObj.entry_data[ input_id ] = $( this ).val();
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
this.saveToken = function( token ) {
|
||||
|
||||
/* Add token response to tokens array. */
|
||||
this.tokens[ this.active_feed.id ] = {
|
||||
'feed_id': this.active_feed.id,
|
||||
'response': token
|
||||
};
|
||||
|
||||
if ( this.tokens.length == this.feeds.length ) {
|
||||
|
||||
/* Add tokens to form. */
|
||||
this.form.find( this.responseField ).val( $.toJSON( this.tokens ) );
|
||||
|
||||
/* Submit the form. */
|
||||
this.form.submit();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.init();
|
||||
|
||||
}
|
||||
|
||||
} )( jQuery );
|
||||
@@ -1 +0,0 @@
|
||||
window.GFToken=null,function(n){GFToken=function(i){for(var t in i)i.hasOwnProperty(t)&&(this[t]=i[t]);this.form=n("#gform_"+this.formId),this.init=function(){var s=this;this.tokens={},this.isAjax||gformInitSpinner(this.formId),this.hasPages&&n(document).bind("gform_page_loaded",function(i,t,e){t==s.formId&&e!=s.pageCount&&s.saveEntryData()}),this.form.submit(function(){s.onSubmit()})},this.onSubmit=function(){this.form.data("gftokensubmitting")||(event.preventDefault(),this.form.data("gftokensubmitting",!0),this.saveEntryData(),this.processTokens())},this.processTokens=function(){for(var i in this.feeds){this.active_feed=this.feeds[i];var t,e={billing_fields:{},id:this.active_feed.id,name:this.active_feed.name};for(t in this.active_feed.billing_fields)field_id=this.active_feed.billing_fields[t],e.billing_fields[t]=this.entry_data[field_id];window[this.callback].createToken(e,this)}},this.saveEntryData=function(){var t=this,e="input_"+this.formId+"_";this.entry_data||(this.entry_data={}),this.form.find('input[id^="'+e+'"], select[id^="'+e+'"], textarea[id^="'+e+'"]').each(function(){var i=n(this).attr("id").replace(e,"").replace("_",".");0<=n.inArray(i,t.fields)&&(t.entry_data[i]=n(this).val())})},this.saveToken=function(i){this.tokens[this.active_feed.id]={feed_id:this.active_feed.id,response:i},this.tokens.length==this.feeds.length&&(this.form.find(this.responseField).val(n.toJSON(this.tokens)),this.form.submit())},this.init()}}(jQuery);
|
||||
@@ -1,2 +0,0 @@
|
||||
<?php
|
||||
//Nothing to see here
|
||||
@@ -1,329 +0,0 @@
|
||||
/**
|
||||
* jQuery Repeater
|
||||
*
|
||||
* Easily create a section of repeatable items.
|
||||
*
|
||||
* 1. Include repeater.js
|
||||
* 2. Define a template to be used by the repeater.
|
||||
* a. Input elements should have a class "property_{i}" (do not replace {i} with an index, the script will handle this.
|
||||
* b. The template should include a container for the "row" of elements.
|
||||
* c. Use the {buttons} merge tag to indicate the location of the repeater buttons.
|
||||
*
|
||||
* Example:
|
||||
* <div class="repeater">
|
||||
* <!-- Template Start -->
|
||||
* <div class="row">
|
||||
* <input class="name_{i}" />
|
||||
* <input class="age_{i}" />
|
||||
* {buttons}
|
||||
* </div>
|
||||
* <!-- / Template Ends -->
|
||||
* </div>
|
||||
*
|
||||
* 3. Define a "save" callback to handle how your data is saved. It will give you an array of objects representing your data.
|
||||
*
|
||||
*/
|
||||
|
||||
jQuery.fn.repeater = function( options ) {
|
||||
|
||||
var self = this,
|
||||
defaults = {
|
||||
template: '',
|
||||
limit: 5,
|
||||
items: [{}],
|
||||
saveEvents: 'blur change',
|
||||
saveElements: 'input, select',
|
||||
addButtonMarkup: '+',
|
||||
removeButtonMarkup: '-',
|
||||
minItemCount: 1,
|
||||
callbacks: {
|
||||
save: function() { },
|
||||
beforeAdd: function() { },
|
||||
add: function() { },
|
||||
beforeAddNew: function() { },
|
||||
addNew: function() { },
|
||||
beforeRemove: function() { },
|
||||
remove: function() { },
|
||||
repeaterButtons: function() { return false; }
|
||||
}
|
||||
};
|
||||
|
||||
self.options = jQuery.extend( true, {}, defaults, options );
|
||||
self.elem = jQuery( this );
|
||||
self.items = self.options.items;
|
||||
self.callbacks = self.options.callbacks;
|
||||
self._template = self.options.template;
|
||||
self._baseObj = self.items[0];
|
||||
|
||||
self.init = function() {
|
||||
|
||||
self.stashTemplate();
|
||||
|
||||
self.elem.addClass( 'repeater' );
|
||||
self.refresh();
|
||||
|
||||
self.bindEvents();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
self.bindEvents = function() {
|
||||
|
||||
self.options.saveEvents = self.getNamespacedEvents( self.options.saveEvents );
|
||||
|
||||
self.elem.off( 'click.repeater', 'a.add-item' );
|
||||
self.elem.on( 'click.repeater', 'a.add-item:not(.inactive)', function() {
|
||||
self.addNewItem( this );
|
||||
});
|
||||
|
||||
self.elem.off( 'click.repeater', 'a.remove-item' );
|
||||
self.elem.on( 'click.repeater', 'a.remove-item', function( event ){
|
||||
self.removeItem( this );
|
||||
});
|
||||
|
||||
self.elem.off( self.options.saveEvents, self.options.saveElements );
|
||||
self.elem.on( self.options.saveEvents, self.options.saveElements, function() {
|
||||
self.save();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
self.stashTemplate = function() {
|
||||
|
||||
// if no template provided or in "storage", use current HTML
|
||||
if( ! self._template )
|
||||
self._template = self.elem.html();
|
||||
|
||||
self._template = jQuery.trim( self._template );
|
||||
|
||||
}
|
||||
|
||||
self.addItem = function( item, index ) {
|
||||
|
||||
var itemMarkup = self.getItemMarkup( item, index),
|
||||
itemElem = jQuery( itemMarkup ).addClass( 'item-' + index );
|
||||
|
||||
self.callbacks.beforeAdd( self, itemElem, item, index );
|
||||
|
||||
self.append( itemElem );
|
||||
self.populateSelects( item, index );
|
||||
|
||||
self.callbacks.add( self, itemElem, item, index );
|
||||
|
||||
}
|
||||
|
||||
self.getItemMarkup = function( item, index ) {
|
||||
|
||||
var itemMarkup = self._template;
|
||||
|
||||
for( var property in item ) {
|
||||
|
||||
if( ! item.hasOwnProperty( property ) )
|
||||
continue;
|
||||
|
||||
itemMarkup = itemMarkup.replace( /{i}/g, index );
|
||||
itemMarkup = itemMarkup.replace( '{buttons}', self.getRepeaterButtonsMarkup( index ) );
|
||||
itemMarkup = itemMarkup.replace( new RegExp( '{' + property + '}', 'g' ), escapeAttr( item[property] ) );
|
||||
|
||||
}
|
||||
|
||||
return itemMarkup;
|
||||
}
|
||||
|
||||
self.getRepeaterButtonsMarkup = function( index ) {
|
||||
|
||||
var buttonsMarkup = self.callbacks.repeaterButtons( self, index );
|
||||
|
||||
if( ! buttonsMarkup )
|
||||
buttonsMarkup = self.getDefaultButtonsMarkup( index );
|
||||
|
||||
return buttonsMarkup;
|
||||
}
|
||||
|
||||
self.getDefaultButtonsMarkup = function( index ) {
|
||||
|
||||
var cssClass = self.items.length >= self.options.limit && self.options.limit !== 0 ? 'inactive' : '',
|
||||
buttons = '<a class="add-item ' + cssClass + '" data-index="' + index + '">' + self.options.addButtonMarkup + '</a>';
|
||||
|
||||
if( self.items.length > self.options.minItemCount )
|
||||
buttons += '<a class="remove-item" data-index="' + index + '">' + self.options.removeButtonMarkup + '</a>';
|
||||
|
||||
return '<div class="repeater-buttons">' + buttons + '</div>';
|
||||
}
|
||||
|
||||
self.populateSelects = function( item, index ) {
|
||||
|
||||
// after appending the row, check each property to see if it is a select and then populate
|
||||
for ( var property in item ) {
|
||||
|
||||
if ( ! item.hasOwnProperty( property ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var input = self.elem.find( '.' + property + '_' + index );
|
||||
|
||||
if ( ! input.is( 'select' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( jQuery.isArray( item[ property ] ) ) {
|
||||
input.val( item[ property ] );
|
||||
} else {
|
||||
input.find( 'option[value="' + item[ property ] + '"]' ).prop( 'selected', true );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
self.addNewItem = function( elemOrItem, index ) {
|
||||
|
||||
var isElem = self.isElement( elemOrItem ),
|
||||
index = parseInt( typeof index !== 'undefined' ? index : ( isElem ? parseInt( jQuery( elemOrItem ).attr( 'data-index' ), 10 ) + 1 : self.items.length ), 10 ),
|
||||
item = isElem ? self.getBaseObject() : elemOrItem;
|
||||
|
||||
self.callbacks.beforeAddNew( self, index );
|
||||
self.items.splice( index, 0, item );
|
||||
self.callbacks.addNew( self, index );
|
||||
|
||||
self.refresh().save();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
self.removeItem = function( elemOrIndex ) {
|
||||
|
||||
var index = self.isElement( elemOrIndex ) ? jQuery( elemOrIndex ).attr( 'data-index' ) : elemOrIndex;
|
||||
|
||||
self.callbacks.beforeRemove( self, index );
|
||||
|
||||
// using delete (over splice) to maintain the correct indexes for
|
||||
// the items array when saving the data from the UI
|
||||
delete self.items[index];
|
||||
|
||||
self.callbacks.remove( self, index );
|
||||
|
||||
self.save().refresh();
|
||||
|
||||
}
|
||||
|
||||
self.refresh = function() {
|
||||
|
||||
self.elem.empty();
|
||||
|
||||
for( var i = 0; i < self.items.length; i++ ) {
|
||||
self.addItem( self.items[i], i );
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
self.save = function() {
|
||||
|
||||
var keys = self.getBaseObjectKeys(),
|
||||
data = [];
|
||||
|
||||
for( var i = 0; i < self.items.length; i++ ) {
|
||||
|
||||
if( typeof self.items[i] == 'undefined' )
|
||||
continue;
|
||||
|
||||
var item = {};
|
||||
|
||||
for( var j = 0; j < keys.length; j++ ) {
|
||||
|
||||
var key = keys[j],
|
||||
id = '.' + key + '_' + i,
|
||||
value = self.elem.find( id ).val();
|
||||
|
||||
item[key] = typeof value == 'undefined' ? false : value;
|
||||
|
||||
}
|
||||
|
||||
data.push( item );
|
||||
|
||||
}
|
||||
|
||||
// save data to items
|
||||
self.items = data;
|
||||
|
||||
// save data externally via callback
|
||||
self.callbacks.save( self, data );
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops through the current items array and retrieves the object properties of the
|
||||
* first valid item object. Originally this would simply pull the object keys from
|
||||
* the first index of the items array; however, when the first item has been
|
||||
* 'deleted' (see the save() method), it will be undefined.
|
||||
*/
|
||||
self.getBaseObjectKeys = function() {
|
||||
|
||||
var keys = [],
|
||||
items = self.items.length > 0 ? self.items : [ self._baseObj ];
|
||||
|
||||
for( var i = 0; i < items.length; i++ ) {
|
||||
|
||||
if( typeof items[i] == 'undefined' )
|
||||
continue;
|
||||
|
||||
for( var key in items[i] ) {
|
||||
if( ! items[i].hasOwnProperty( key ) )
|
||||
continue;
|
||||
keys.push( key );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
self.getBaseObject = function() {
|
||||
|
||||
var item = {},
|
||||
keys = self.getBaseObjectKeys();
|
||||
|
||||
for( var i = 0; i < keys.length; i++ ) {
|
||||
item[keys[i]] = '';
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
self.getNamespacedEvents = function( events ) {
|
||||
|
||||
var events = events.split( ' ' ),
|
||||
namespacedEvents = [];
|
||||
|
||||
for( var i = 0; i < events.length; i++ ) {
|
||||
namespacedEvents.push( events[i] + '.repeater' );
|
||||
}
|
||||
|
||||
return namespacedEvents.join( ' ' );
|
||||
}
|
||||
|
||||
/**
|
||||
* http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object
|
||||
* @param obj
|
||||
* @returns {boolean}
|
||||
*/
|
||||
self.isElement = function( obj ) {
|
||||
try {
|
||||
//Using W3 DOM2 (works for FF, Opera and Chrom)
|
||||
return obj instanceof HTMLElement;
|
||||
}
|
||||
catch(e){
|
||||
//Browsers not supporting W3 DOM2 don't have HTMLElement and
|
||||
//an exception is thrown and we end up here. Testing some
|
||||
//properties that all elements have. (works on IE7)
|
||||
return (typeof obj==="object") &&
|
||||
(obj.nodeType===1) && (typeof obj.style === "object") &&
|
||||
(typeof obj.ownerDocument ==="object");
|
||||
}
|
||||
}
|
||||
|
||||
return self.init();
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
jQuery.fn.repeater=function(e){var i=this;return i.options=jQuery.extend(!0,{},{template:"",limit:5,items:[{}],saveEvents:"blur change",saveElements:"input, select",addButtonMarkup:"+",removeButtonMarkup:"-",minItemCount:1,callbacks:{save:function(){},beforeAdd:function(){},add:function(){},beforeAddNew:function(){},addNew:function(){},beforeRemove:function(){},remove:function(){},repeaterButtons:function(){return!1}}},e),i.elem=jQuery(this),i.items=i.options.items,i.callbacks=i.options.callbacks,i._template=i.options.template,i._baseObj=i.items[0],i.init=function(){return i.stashTemplate(),i.elem.addClass("repeater"),i.refresh(),i.bindEvents(),i},i.bindEvents=function(){i.options.saveEvents=i.getNamespacedEvents(i.options.saveEvents),i.elem.off("click.repeater","a.add-item"),i.elem.on("click.repeater","a.add-item:not(.inactive)",function(){i.addNewItem(this)}),i.elem.off("click.repeater","a.remove-item"),i.elem.on("click.repeater","a.remove-item",function(e){i.removeItem(this)}),i.elem.off(i.options.saveEvents,i.options.saveElements),i.elem.on(i.options.saveEvents,i.options.saveElements,function(){i.save()})},i.stashTemplate=function(){i._template||(i._template=i.elem.html()),i._template=jQuery.trim(i._template)},i.addItem=function(e,t){var n=i.getItemMarkup(e,t),n=jQuery(n).addClass("item-"+t);i.callbacks.beforeAdd(i,n,e,t),i.append(n),i.populateSelects(e,t),i.callbacks.add(i,n,e,t)},i.getItemMarkup=function(e,t){var n,a=i._template;for(n in e)e.hasOwnProperty(n)&&(a=(a=(a=a.replace(/{i}/g,t)).replace("{buttons}",i.getRepeaterButtonsMarkup(t))).replace(new RegExp("{"+n+"}","g"),escapeAttr(e[n])));return a},i.getRepeaterButtonsMarkup=function(e){return i.callbacks.repeaterButtons(i,e)||i.getDefaultButtonsMarkup(e)},i.getDefaultButtonsMarkup=function(e){var t='<a class="add-item '+(i.items.length>=i.options.limit&&0!==i.options.limit?"inactive":"")+'" data-index="'+e+'">'+i.options.addButtonMarkup+"</a>";return i.items.length>i.options.minItemCount&&(t+='<a class="remove-item" data-index="'+e+'">'+i.options.removeButtonMarkup+"</a>"),'<div class="repeater-buttons">'+t+"</div>"},i.populateSelects=function(e,t){for(var n in e){var a;e.hasOwnProperty(n)&&(a=i.elem.find("."+n+"_"+t)).is("select")&&(jQuery.isArray(e[n])?a.val(e[n]):a.find('option[value="'+e[n]+'"]').prop("selected",!0))}},i.addNewItem=function(e,t){var n=i.isElement(e),t=parseInt(void 0!==t?t:n?parseInt(jQuery(e).attr("data-index"),10)+1:i.items.length,10),n=n?i.getBaseObject():e;return i.callbacks.beforeAddNew(i,t),i.items.splice(t,0,n),i.callbacks.addNew(i,t),i.refresh().save(),i},i.removeItem=function(e){e=i.isElement(e)?jQuery(e).attr("data-index"):e;i.callbacks.beforeRemove(i,e),delete i.items[e],i.callbacks.remove(i,e),i.save().refresh()},i.refresh=function(){i.elem.empty();for(var e=0;e<i.items.length;e++)i.addItem(i.items[e],e);return i},i.save=function(){for(var e=i.getBaseObjectKeys(),t=[],n=0;n<i.items.length;n++)if(void 0!==i.items[n]){for(var a={},r=0;r<e.length;r++){var s=e[r],o=i.elem.find("."+s+"_"+n).val();a[s]=void 0!==o&&o}t.push(a)}return i.items=t,i.callbacks.save(i,t),i},i.getBaseObjectKeys=function(){for(var e=[],t=0<i.items.length?i.items:[i._baseObj],n=0;n<t.length;n++)if(void 0!==t[n]){for(var a in t[n])t[n].hasOwnProperty(a)&&e.push(a);break}return e},i.getBaseObject=function(){for(var e={},t=i.getBaseObjectKeys(),n=0;n<t.length;n++)e[t[n]]="";return e},i.getNamespacedEvents=function(e){for(var e=e.split(" "),t=[],n=0;n<e.length;n++)t.push(e[n]+".repeater");return t.join(" ")},i.isElement=function(t){try{return t instanceof HTMLElement}catch(e){return"object"==typeof t&&1===t.nodeType&&"object"==typeof t.style&&"object"==typeof t.ownerDocument}},i.init()};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,67 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Assets\Admin_Dependencies;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Assets\GF_Dependencies;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
|
||||
|
||||
/**
|
||||
* Class GF_Admin_Script_Dependencies
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Assets\Admin_Dependencies;
|
||||
*/
|
||||
class GF_Admin_Script_Dependencies extends GF_Dependencies {
|
||||
|
||||
/**
|
||||
* Items to enqueue globally in admin.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $items = array(
|
||||
'gform_gravityforms_admin',
|
||||
);
|
||||
|
||||
/**
|
||||
* Enqueue the item by handle.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param $handle
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function do_enqueue( $handle ) {
|
||||
wp_enqueue_script( $handle );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the global scripts should enqueue.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function should_enqueue() {
|
||||
/***
|
||||
* The newer JavaScript added in 2.5 is now enqueued globally in the admin.
|
||||
* We implemented this as we are now using code splitting to only inject JavaScript
|
||||
* dynamically as it is needed, and to also allow our addons easy access to the core libraries
|
||||
* we use.
|
||||
*
|
||||
* This filter allows users to make our admin scripts only load on Gravity Forms admin screens.
|
||||
* Setting it to false may cause unexpected behavior/feature loss in some addons or core.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*
|
||||
* @param bool true Load admin scripts globally?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
return apply_filters( 'gform_load_admin_scripts_globally', true );
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Assets\Admin_Dependencies;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Assets\GF_Dependencies;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
|
||||
|
||||
/**
|
||||
* Class GF_Admin_Style_Dependencies
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Assets\Admin_Dependencies;
|
||||
*/
|
||||
class GF_Admin_Style_Dependencies extends GF_Dependencies {
|
||||
|
||||
/**
|
||||
* Items to enqueue globally in admin.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $items = array(
|
||||
'gform_common_css_utilities',
|
||||
'gform_common_icons',
|
||||
'gform_admin_icons',
|
||||
'gform_admin_components',
|
||||
'gform_admin_css_utilities',
|
||||
);
|
||||
|
||||
/**
|
||||
* Enqueue the item by handle.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param $handle
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function do_enqueue( $handle ) {
|
||||
wp_enqueue_style( $handle );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Assets;
|
||||
|
||||
class GF_Asset_Processor {
|
||||
|
||||
/**
|
||||
* @var array $map - The Hash Map generated by our node scripts.
|
||||
*/
|
||||
private $map;
|
||||
|
||||
/**
|
||||
* @var string $asset_path - The path to the js dist directory.
|
||||
*/
|
||||
private $asset_path;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $map
|
||||
* @param string $asset_path
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $map, $asset_path ) {
|
||||
$this->map = $map;
|
||||
$this->asset_path = $asset_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform processing actions on assets.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process_assets() {
|
||||
$this->process_versions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the ver values for all of the registered scripts in order to append a
|
||||
* file hash (if it exists) or the filemtime (if required).
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function process_versions() {
|
||||
global $wp_scripts;
|
||||
|
||||
$registered = $wp_scripts->registered;
|
||||
|
||||
foreach( $registered as &$asset ) {
|
||||
|
||||
// Bail if not one of our assets.
|
||||
if ( $asset->src && strpos( $asset->src, 'gravityforms/assets/js/dist' ) === false ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$basename = basename( $asset->src );
|
||||
$path = sprintf( '%s/%s', $this->asset_path, $basename );
|
||||
|
||||
// Asset doesn't exist in hash_map, skip.
|
||||
if ( ! array_key_exists( $basename, $this->map ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// The hash is either the value from our map, or the filemtime for dev.
|
||||
$hash = defined( 'GF_DEV_TIME_AS_VER' ) && GF_DEV_TIME_AS_VER ?
|
||||
filemtime( $path ) :
|
||||
$this->map[ $basename ]['version'];
|
||||
|
||||
$asset->ver = $hash;
|
||||
}
|
||||
|
||||
$wp_scripts->registered = $registered;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Assets;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Assets\Theme_Dependencies\GF_Theme_Script_Dependencies;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Assets\Admin_Dependencies\GF_Admin_Script_Dependencies;
|
||||
use Gravity_Forms\Gravity_Forms\Assets\Admin_Dependencies\GF_Admin_Style_Dependencies;
|
||||
|
||||
/**
|
||||
* Class GF_Asset_Service_Provider
|
||||
*
|
||||
* Service provider for assets.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Merge_Tags;
|
||||
*/
|
||||
class GF_Asset_Service_Provider extends GF_Service_Provider {
|
||||
|
||||
const HASH_MAP = 'hash_map';
|
||||
const ASSET_PROCESSOR = 'asset_processor';
|
||||
const STYLE_DEPS = 'gf_global_style_deps';
|
||||
const SCRIPT_DEPS = 'gf_global_script_deps';
|
||||
const SCRIPT_DEPS_THEME = 'gf_global_script_deps_theme';
|
||||
const SVG_OPTIONS = 'gf_svg_options';
|
||||
|
||||
private $plugin_dir;
|
||||
|
||||
public function __construct( $plugin_dir ) {
|
||||
$this->plugin_dir = $plugin_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register services to the container.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*/
|
||||
public function register( GF_Service_Container $container ) {
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/class-gf-asset-processor.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/class-gf-dependencies.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/admin-dependencies/class-gf-admin-script-dependencies.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/admin-dependencies/class-gf-admin-style-dependencies.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/theme-dependencies/class-gf-theme-script-dependencies.php' );
|
||||
|
||||
$container->add( self::HASH_MAP, function () {
|
||||
if ( ! file_exists( \GFCommon::get_base_path() . '/assets/js/dist/assets.php' ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$map = require( \GFCommon::get_base_path() . '/assets/js/dist/assets.php' );
|
||||
|
||||
return rgar( $map, 'hash_map', array() );
|
||||
} );
|
||||
|
||||
$container->add( self::ASSET_PROCESSOR, function () use ( $container ) {
|
||||
$basepath = \GFCommon::get_base_path();
|
||||
$asset_path = sprintf( '%s/assets/js/dist/', $basepath );
|
||||
|
||||
return new GF_Asset_Processor( $container->get( self::HASH_MAP ), $asset_path );
|
||||
} );
|
||||
|
||||
$container->add( self::STYLE_DEPS, function () {
|
||||
return new GF_Admin_Style_Dependencies();
|
||||
} );
|
||||
|
||||
$container->add( self::SCRIPT_DEPS, function () {
|
||||
return new GF_Admin_Script_Dependencies();
|
||||
} );
|
||||
|
||||
$container->add( self::SCRIPT_DEPS_THEME, function () {
|
||||
return new GF_Theme_Script_Dependencies();
|
||||
} );
|
||||
|
||||
$this->svg_delivery( $container );
|
||||
}
|
||||
|
||||
public function init( GF_Service_Container $container ) {
|
||||
add_action( 'init', function () use ( $container ) {
|
||||
$container->get( self::ASSET_PROCESSOR )->process_assets();
|
||||
}, 9999 );
|
||||
|
||||
add_action( 'admin_enqueue_scripts', function () use ( $container ) {
|
||||
$container->get( self::STYLE_DEPS )->enqueue();
|
||||
$container->get( self::SCRIPT_DEPS )->enqueue();
|
||||
|
||||
// Styles and scripts required for the tooltips.
|
||||
wp_enqueue_style( 'gform_font_awesome' );
|
||||
wp_enqueue_script( 'gform_tooltip_init' );
|
||||
} );
|
||||
|
||||
add_action( 'gform_enqueue_scripts', function () use ( $container ) {
|
||||
$container->get( self::SCRIPT_DEPS_THEME )->enqueue();
|
||||
} );
|
||||
|
||||
add_filter( 'gform_noconflict_styles', function ( $styles ) use ( $container ) {
|
||||
return array_merge( $styles, $container->get( self::STYLE_DEPS )->get_items() );
|
||||
}, 1 );
|
||||
}
|
||||
|
||||
private function svg_delivery( GF_Service_Container $container ) {
|
||||
$default_path = sprintf( '%s/assets/img/base', untrailingslashit( $this->plugin_dir ) );
|
||||
|
||||
/**
|
||||
* Allows users to filter the path used to glob the available SVGs to use for display in themes.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param string $path The default orbital theme svg path within our plugin.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
$svg_path = apply_filters( 'gform_svg_theme_path', $default_path );
|
||||
|
||||
$svgs = array();
|
||||
|
||||
foreach ( \GFCommon::glob( '*.svg', trailingslashit( $svg_path ) ) as $filename ) {
|
||||
$key = pathinfo( $filename, PATHINFO_FILENAME );
|
||||
$svgs[ $key ] = file_get_contents( $filename );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows users to filter the SVG options available to output in themes.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param array $svgs The current SVG options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
$svgs = apply_filters( 'gform_svg_theme_options', $svgs );
|
||||
|
||||
$container->add( self::SVG_OPTIONS, $svgs );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Gravity Forms Abstract Asset
|
||||
*
|
||||
* Provides base functionality for enqueueable/printable assets.
|
||||
*
|
||||
* @since 2.5
|
||||
* @package gravityforms
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class GF_Asset
|
||||
*/
|
||||
abstract class GF_Asset {
|
||||
|
||||
/**
|
||||
* @var string $handle
|
||||
*/
|
||||
protected $handle;
|
||||
|
||||
/**
|
||||
* @var string $url
|
||||
*/
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* GF_Asset constructor.
|
||||
*
|
||||
* @param string $handle
|
||||
* @param string $url
|
||||
*/
|
||||
public function __construct( $handle, $url = '' ) {
|
||||
$this->handle = $handle;
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle enqueueing the asset this class represents (e.g., using wp_enqueue_script() or wp_enqueue_style())
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function enqueue_asset();
|
||||
|
||||
/**
|
||||
* Handle printing the asset this class represents (e.g., using wp_print_scripts() or wp_print_styles())
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function print_asset();
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Assets;
|
||||
|
||||
abstract class GF_Dependencies {
|
||||
|
||||
/**
|
||||
* Items to enqueue
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $items = array();
|
||||
|
||||
/**
|
||||
* The method for actually enqueueing the items.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param $handle
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function do_enqueue( $handle );
|
||||
|
||||
/**
|
||||
* Get the dependency items.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_items() {
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the items.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param $items
|
||||
*/
|
||||
public function enqueue() {
|
||||
if ( ! $this->should_enqueue() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $this->items as $handle ) {
|
||||
$this->do_enqueue( $handle );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to determine whether the assets outlined should be enqueued.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function should_enqueue() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Gravity Forms Script Asset
|
||||
*
|
||||
* @since 2.5
|
||||
* @package gravityforms
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class GF_Script_Asset
|
||||
*/
|
||||
class GF_Script_Asset extends GF_Asset {
|
||||
|
||||
/**
|
||||
* The data for any localized information.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @var array $localize_data
|
||||
*/
|
||||
private $localize_data = array();
|
||||
|
||||
/**
|
||||
* Localize data to this script.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param string $object_name
|
||||
* @param array $data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_localize_data( $object_name, $data ) {
|
||||
$this->localize_data[ $object_name ] = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the asset.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue_asset() {
|
||||
wp_enqueue_script( $this->handle, $this->url );
|
||||
|
||||
if ( empty( $this->localize_data ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $this->localize_data as $object_name => $data ) {
|
||||
wp_localize_script( $this->handle, $object_name, $data );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the asset.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function print_asset() {
|
||||
$this->enqueue_asset();
|
||||
|
||||
wp_print_scripts( $this->handle );
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Gravity Forms Style Asset
|
||||
*
|
||||
* @since 2.5
|
||||
* @package gravityforms
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class GF_Style_Asset
|
||||
*/
|
||||
class GF_Style_Asset extends GF_Asset {
|
||||
|
||||
/**
|
||||
* Enqueue the asset.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue_asset() {
|
||||
wp_enqueue_style( $this->handle, $this->url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the asset.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function print_asset() {
|
||||
$this->enqueue_asset();
|
||||
wp_print_styles( $this->handle );
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
<?php
|
||||
//Nothing to see here
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Assets\Theme_Dependencies;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Assets\GF_Dependencies;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
|
||||
|
||||
/**
|
||||
* Class GF_Theme_Script_Dependencies
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Assets\Theme_Dependencies;
|
||||
*/
|
||||
class GF_Theme_Script_Dependencies extends GF_Dependencies {
|
||||
|
||||
/**
|
||||
* Items to enqueue globally in admin.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $items = array(
|
||||
'gform_gravityforms_theme',
|
||||
);
|
||||
|
||||
/**
|
||||
* Enqueue the item by handle.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param $handle
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function do_enqueue( $handle ) {
|
||||
wp_enqueue_script( $handle );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Service provider for async (background) processors.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms
|
||||
*/
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Async;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
|
||||
use Gravity_Forms\Gravity_Forms\Telemetry\GF_Telemetry_Processor;
|
||||
use GFForms;
|
||||
use GF_Background_Process;
|
||||
use GF_Background_Upgrader;
|
||||
use GF_Feed_Processor;
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class GF_Background_Processing_Service_Provider
|
||||
*
|
||||
* @since 2.6.9
|
||||
*/
|
||||
class GF_Background_Process_Service_Provider extends GF_Service_Provider {
|
||||
|
||||
const UPGRADER = 'upgrade_processor';
|
||||
const FEEDS = 'feeds_processor';
|
||||
const NOTIFICATIONS = 'notifications_processor';
|
||||
const TELEMETRY = 'telemetry_processor';
|
||||
|
||||
/**
|
||||
* The names and classes of the async (background) processors.
|
||||
*
|
||||
* @since 2.6.9
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $processors = array(
|
||||
self::UPGRADER => GF_Background_Upgrader::class,
|
||||
self::FEEDS => GF_Feed_Processor::class,
|
||||
self::NOTIFICATIONS => GF_Notifications_Processor::class,
|
||||
self::TELEMETRY => GF_Telemetry_Processor::class,
|
||||
);
|
||||
|
||||
/**
|
||||
* Initializing the processors and adding them to the container as services.
|
||||
*
|
||||
* @since 2.6.9
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*/
|
||||
public function register( GF_Service_Container $container ) {
|
||||
GFForms::init_background_upgrader();
|
||||
require_once GF_PLUGIN_DIR_PATH . 'includes/addon/class-gf-feed-processor.php';
|
||||
require_once GF_PLUGIN_DIR_PATH . 'includes/async/class-gf-notifications-processor.php';
|
||||
require_once GF_PLUGIN_DIR_PATH . 'includes/telemetry/class-gf-telemetry-processor.php';
|
||||
|
||||
foreach ( $this->processors as $name => $class ) {
|
||||
$container->add( $name, function () use ( $name, $class ) {
|
||||
if ( $name === self::UPGRADER ) {
|
||||
return GFForms::$background_upgrader;
|
||||
}
|
||||
|
||||
$callback = array( $class, 'get_instance' );
|
||||
if ( is_callable( $callback ) ) {
|
||||
return call_user_func( $callback );
|
||||
}
|
||||
|
||||
return new $class();
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializing hooks.
|
||||
*
|
||||
* @since 2.6.9
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*/
|
||||
public function init( GF_Service_Container $container ) {
|
||||
$processors = array_keys( $this->processors );
|
||||
|
||||
add_action( 'gform_uninstalling', function () use ( $processors, $container ) {
|
||||
foreach ( $processors as $name ) {
|
||||
/**
|
||||
* @var GF_Background_Process $processor
|
||||
*/
|
||||
$processor = $container->get( $name );
|
||||
$processor->clear_scheduled_events();
|
||||
$processor->clear_queue( true );
|
||||
$processor->unlock_process();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Async;
|
||||
|
||||
use GF_Background_Process;
|
||||
use GFCommon;
|
||||
use GFAPI;
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'GF_Background_Process' ) ) {
|
||||
require_once GF_PLUGIN_DIR_PATH . 'includes/libraries/gf-background-process.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* GF_Notifications_Processor Class.
|
||||
*
|
||||
* @since 2.6.9
|
||||
*/
|
||||
class GF_Notifications_Processor extends GF_Background_Process {
|
||||
|
||||
/**
|
||||
* The action name.
|
||||
*
|
||||
* @since 2.6.9
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $action = 'gf_notifications_processor';
|
||||
|
||||
/**
|
||||
* Processes the task.
|
||||
*
|
||||
* @since 2.6.9
|
||||
*
|
||||
* @param array $item The task arguments.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function task( $item ) {
|
||||
$notifications = rgar( $item, 'notifications' );
|
||||
if ( empty( $notifications ) || ! is_array( $notifications ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$entry = GFAPI::get_entry( rgar( $item, 'entry_id' ) );
|
||||
if ( is_wp_error( $entry ) ) {
|
||||
GFCommon::log_debug( __METHOD__ . sprintf( '(): Aborting; Entry #%d not found.', rgar( $item, 'entry_id' ) ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$form = GFAPI::get_form( rgar( $item, 'form_id' ) );
|
||||
if ( empty( $form ) ) {
|
||||
GFCommon::log_debug( __METHOD__ . sprintf( '(): Aborting; Form #%d not found.', rgar( $item, 'form_id' ) ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$form = $this->filter_form( $form, $entry );
|
||||
$event = rgar( $item, 'event', 'form_submission' );
|
||||
$data = rgar( $item, 'data' );
|
||||
if ( ! is_array( $data ) ) {
|
||||
$data = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows custom actions to be performed before notifications are sent asynchronously.
|
||||
*
|
||||
* @since 2.7.1
|
||||
*
|
||||
* @param string $event The event being processed.
|
||||
* @param array $notifications An array containing the IDs of the notifications being processed.
|
||||
* @param array $form The form being processed.
|
||||
* @param array $entry The entry being processed.
|
||||
* @param array $data An array of data which can be used in the notifications via the generic {object:property} merge tag. Defaults to empty array.
|
||||
*/
|
||||
do_action( 'gform_pre_process_async_notifications', $event, $notifications, $form, $entry, $data );
|
||||
|
||||
GFCommon::send_notifications( $notifications, $form, $entry, true, $event, $data );
|
||||
|
||||
/**
|
||||
* Allows custom actions to be performed after notifications are sent asynchronously.
|
||||
*
|
||||
* @since 2.7.1
|
||||
*
|
||||
* @param string $event The event being processed.
|
||||
* @param array $notifications An array containing the IDs of the notifications being processed.
|
||||
* @param array $form The form being processed.
|
||||
* @param array $entry The entry being processed.
|
||||
* @param array $data An array of data which can be used in the notifications via the generic {object:property} merge tag. Defaults to empty array.
|
||||
*/
|
||||
do_action( 'gform_post_process_async_notifications', $event, $notifications, $form, $entry, $data );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if async (background) processing of notifications is enabled.
|
||||
*
|
||||
* @since 2.7.1
|
||||
*
|
||||
* @param array $notifications An array containing the IDs of the notifications to be sent.
|
||||
* @param array $form The form being processed.
|
||||
* @param array $entry The entry being processed.
|
||||
* @param string $event The event being processed.
|
||||
* @param array $data An array of data which can be used in the notifications via the generic {object:property} merge tag. Defaults to empty array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled( $notifications, $form, $entry, $event = 'form_submission', $data = array() ) {
|
||||
$form_id = absint( rgar( $form, 'id' ) );
|
||||
$is_enabled = false;
|
||||
|
||||
/**
|
||||
* Allows async (background) processing of notifications to be enabled or disabled.
|
||||
*
|
||||
* @since 2.6.9
|
||||
*
|
||||
* @param bool $is_enabled Is async (background) processing of notifications enabled? Default is false.
|
||||
* @param string $event The event the notifications are to be sent for.
|
||||
* @param array $notifications An array containing the IDs of the notifications to be sent.
|
||||
* @param array $form The form currently being processed.
|
||||
* @param array $entry The entry currently being processed.
|
||||
* @param array $data An array of data which can be used in the notifications via the generic {object:property} merge tag. Defaults to empty array.
|
||||
*/
|
||||
return gf_apply_filters( array(
|
||||
'gform_is_asynchronous_notifications_enabled',
|
||||
$form_id,
|
||||
), $is_enabled, $event, $notifications, $form, $entry, $data );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Blocks;
|
||||
|
||||
/**
|
||||
* Gravity Forms Block Attributes class.
|
||||
*
|
||||
* @since 2.7.4
|
||||
*
|
||||
* Class GF_Block_Attributes
|
||||
*/
|
||||
class GF_Block_Attributes {
|
||||
|
||||
public function store( $attributes ) {
|
||||
add_filter( 'gform_form_block_attribute_values', function( $attr ) use ( $attributes ) {
|
||||
$form_id = rgar( $attributes, 'formId', 0 );
|
||||
|
||||
if ( ! array_key_exists( $form_id, $attr ) ) {
|
||||
$attr[ $form_id ] = array();
|
||||
}
|
||||
|
||||
$attr[ $form_id ][] = $attributes;
|
||||
return $attr;
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,251 +0,0 @@
|
||||
<?php
|
||||
|
||||
// If Gravity Forms Block Manager is not available, do not run.
|
||||
if ( ! class_exists( 'GF_Blocks' ) || ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class GF_Block_Form extends GF_Block {
|
||||
|
||||
/**
|
||||
* Contains an instance of this block, if available.
|
||||
*
|
||||
* @since 2.4.10
|
||||
* @var GF_Block $_instance If available, contains an instance of this block.
|
||||
*/
|
||||
private static $_instance = null;
|
||||
|
||||
/**
|
||||
* Block type.
|
||||
*
|
||||
* @since 2.4.10
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'gravityforms/form';
|
||||
|
||||
/**
|
||||
* Handle of primary block script.
|
||||
*
|
||||
* @since 2.4.10
|
||||
* @var string
|
||||
*/
|
||||
public $script_handle = 'gform_editor_block_form';
|
||||
|
||||
/**
|
||||
* Handle of primary block style.
|
||||
*
|
||||
* @since 2.5.6
|
||||
* @var string
|
||||
*/
|
||||
public $style_handle = 'gform_editor_block_form';
|
||||
|
||||
public function __construct() {
|
||||
$this->assign_attributes();
|
||||
}
|
||||
|
||||
private function assign_attributes() {
|
||||
$default_attributes = GFForms::get_service_container()->get( \Gravity_Forms\Gravity_Forms\Blocks\GF_Blocks_Service_Provider::FORM_BLOCK_ATTRIBUTES );
|
||||
$attributes = apply_filters( 'gform_form_block_attributes', $default_attributes );
|
||||
|
||||
array_walk( $attributes, function ( &$value ) {
|
||||
$value = array( 'type' => $value['type'] );
|
||||
} );
|
||||
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get instance of this class.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @return GF_Block_Form
|
||||
*/
|
||||
public static function get_instance() {
|
||||
|
||||
if ( null === self::$_instance ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// # SCRIPT / STYLES -----------------------------------------------------------------------------------------------
|
||||
public function register_block_assets() {
|
||||
parent::register_block_assets();
|
||||
if ( function_exists( 'wp_enqueue_block_style' ) && is_admin() ) {
|
||||
wp_enqueue_block_style( $this->type, array( 'handle' => 'gravity_forms_theme_reset' ) );
|
||||
wp_enqueue_block_style( $this->type, array( 'handle' => 'gravity_forms_theme_foundation' ) );
|
||||
wp_enqueue_block_style( $this->type, array( 'handle' => 'gravity_forms_theme_framework' ) );
|
||||
wp_enqueue_block_style( $this->type, array( 'handle' => 'gravity_forms_orbital_theme' ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register scripts for block.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function scripts() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Localize Form block script.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @param array $script Script arguments.
|
||||
*/
|
||||
public function localize_script( $script = array() ) {
|
||||
|
||||
wp_localize_script(
|
||||
$script['handle'],
|
||||
'gform_block_form',
|
||||
array(
|
||||
'adminURL' => admin_url( 'admin.php' ),
|
||||
'forms' => $this->get_forms(),
|
||||
'preview' => GFCommon::get_base_url() . '/images/gf_block_preview.svg',
|
||||
)
|
||||
);
|
||||
|
||||
if ( function_exists( 'wp_set_script_translations' ) ) {
|
||||
wp_set_script_translations( $script['handle'], 'gravityforms', GFCommon::get_base_path() . '/languages' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register styles for block.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function styles() {
|
||||
|
||||
// Prepare styling dependencies.
|
||||
$deps = array( 'wp-edit-blocks' );
|
||||
|
||||
/**
|
||||
* Allows users to disable all CSS files from being loaded on the Front End.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @param boolean Whether to disable css.
|
||||
*/
|
||||
$disable_css = apply_filters( 'gform_disable_css', get_option( 'rg_gforms_disable_css' ) );
|
||||
|
||||
// Add Gravity Forms styling if CSS is enabled.
|
||||
if ( ! $disable_css ) {
|
||||
$deps = array_merge( $deps, array( 'gform_basic', 'gforms_formsmain_css', 'gforms_ready_class_css', 'gforms_browsers_css', 'gform_theme' ) );
|
||||
|
||||
/**
|
||||
* Allows users to disable the main theme.css file from being loaded on the Front End.
|
||||
*
|
||||
* @since 2.5-beta-3
|
||||
*
|
||||
* @param boolean Whether to disable the theme css.
|
||||
*/
|
||||
$disable_theme_css = apply_filters( 'gform_disable_form_theme_css', false );
|
||||
|
||||
if ( ! $disable_theme_css ) {
|
||||
$deps[] = 'gform_theme';
|
||||
}
|
||||
}
|
||||
|
||||
$dev_min = defined( 'GF_SCRIPT_DEBUG' ) && GF_SCRIPT_DEBUG ? '' : '.min';
|
||||
|
||||
return array(
|
||||
array(
|
||||
'handle' => $this->style_handle,
|
||||
'src' => GFCommon::get_base_url() . "/assets/css/dist/blocks{$dev_min}.css",
|
||||
'deps' => $deps,
|
||||
'version' => defined( 'GF_SCRIPT_DEBUG' ) && GF_SCRIPT_DEBUG ? filemtime( GFCommon::get_base_path() . "/assets/css/dist/blocks{$dev_min}.css" ) : GFForms::$version,
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// # BLOCK RENDER -------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Display block contents on frontend.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @param array $attributes Block attributes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render_block( $attributes = array() ) {
|
||||
GFForms::get_service_container()->get( 'block_attributes' )->store( $attributes );
|
||||
|
||||
// Prepare variables.
|
||||
$form_id = rgar( $attributes, 'formId' ) ? $attributes['formId'] : false;
|
||||
$title = isset( $attributes['title'] ) ? $attributes['title'] : true;
|
||||
$description = isset( $attributes['description'] ) ? $attributes['description'] : true;
|
||||
$ajax = isset( $attributes['ajax'] ) ? $attributes['ajax'] : false;
|
||||
$tabindex = isset( $attributes['tabindex'] ) ? intval( $attributes['tabindex'] ) : 0;
|
||||
$field_values = isset( $attributes['fieldValues'] ) ? $attributes['fieldValues'] : '';
|
||||
|
||||
// If form ID was not provided or form does not exist, return.
|
||||
if ( ! $form_id || ( $form_id && ! GFAPI::get_form( $form_id ) ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Use Gravity Forms function for REST API requests.
|
||||
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
|
||||
|
||||
// Start output buffering.
|
||||
ob_start();
|
||||
|
||||
// Prepare field values.
|
||||
if ( ! empty( $field_values ) ) {
|
||||
$field_values = str_replace( '&', '&', $field_values );
|
||||
parse_str( $field_values, $field_value_array );
|
||||
$field_values = stripslashes_deep( $field_value_array );
|
||||
}
|
||||
|
||||
// Get form output string.
|
||||
$form_string = gravity_form( $form_id, $title, $description, false, $field_values, $ajax, $tabindex, false );
|
||||
|
||||
// Get output buffer contents.
|
||||
$buffer_contents = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
// Return buffer contents with form string.
|
||||
return $buffer_contents . $form_string;
|
||||
|
||||
}
|
||||
|
||||
// Encode field values.
|
||||
$field_values = htmlspecialchars_decode( $field_values );
|
||||
$field_values = str_replace( array( '&', '[', ']' ), array( '&', '[', ']' ), $field_values );
|
||||
parse_str( $field_values, $field_value_array ); //parsing query string like string for field values and placing them into an associative array
|
||||
$field_values = stripslashes_deep( $field_value_array );
|
||||
|
||||
// If no field values are set, set field values to an empty string
|
||||
if ( empty( $field_values ) ) {
|
||||
$field_values = '';
|
||||
}
|
||||
|
||||
return gravity_form( $form_id, $title, $description, false, $field_values, $ajax, $tabindex, false );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Register block.
|
||||
if ( true !== ( $registered = GF_Blocks::register( GF_Block_Form::get_instance() ) ) && is_wp_error( $registered ) ) {
|
||||
|
||||
// Log that block could not be registered.
|
||||
GFCommon::log_error( 'Unable to register block; ' . $registered->get_error_message() );
|
||||
|
||||
}
|
||||
@@ -1,369 +0,0 @@
|
||||
<?php
|
||||
|
||||
// If Gravity Forms Block Manager is not available, do not run.
|
||||
if ( ! class_exists( 'GF_Blocks' ) || ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base Gravity Forms Block class.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* Class GF_Block
|
||||
*/
|
||||
class GF_Block {
|
||||
|
||||
/**
|
||||
* Contains an instance of this block, if available.
|
||||
*
|
||||
* @since 2.4.10
|
||||
* @var GF_Block $_instance If available, contains an instance of this block.
|
||||
*/
|
||||
private static $_instance = null;
|
||||
|
||||
/**
|
||||
* Block type.
|
||||
*
|
||||
* @since 2.4.10
|
||||
* @var string
|
||||
*/
|
||||
public $type = '';
|
||||
|
||||
/**
|
||||
* Handle of primary block editor script.
|
||||
*
|
||||
* @since 2.4.10
|
||||
* @var string
|
||||
*/
|
||||
public $script_handle = '';
|
||||
|
||||
/**
|
||||
* Handle of primary block editor style.
|
||||
*
|
||||
* @since 2.5.6
|
||||
* @var string
|
||||
*/
|
||||
public $style_handle = '';
|
||||
|
||||
/**
|
||||
* Handle of primary block FE script.
|
||||
*
|
||||
* @since 2.4.10
|
||||
* @var string
|
||||
*/
|
||||
public $fe_script_handle = '';
|
||||
|
||||
/**
|
||||
* Handle of primary block FE style.
|
||||
*
|
||||
* @since 2.5.6
|
||||
* @var string
|
||||
*/
|
||||
public $fe_style_handle = '';
|
||||
|
||||
/**
|
||||
* Block attributes.
|
||||
*
|
||||
* @since 2.4.10
|
||||
* @var array
|
||||
*/
|
||||
public $attributes = array();
|
||||
|
||||
/**
|
||||
* Register block type.
|
||||
* Enqueue editor assets.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @uses GF_Block::register_block_type()
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
$this->register_block_type();
|
||||
|
||||
$this->register_block_assets();
|
||||
|
||||
add_action( 'gform_post_enqueue_scripts', array( $this, 'post_enqueue_scripts' ), 10, 3 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// # BLOCK REGISTRATION --------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get block type.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type() {
|
||||
|
||||
return $this->type;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register block with WordPress.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*/
|
||||
public function register_block_type() {
|
||||
register_block_type( $this->get_type(), $this->get_block_properties() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array representing the properties for this block. Can be overriden by inheriting
|
||||
* classes in order to provide more/fewer/different properties.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_block_properties() {
|
||||
return array(
|
||||
'render_callback' => array( $this, 'render_block' ),
|
||||
'editor_script' => $this->script_handle,
|
||||
'editor_style' => $this->style_handle,
|
||||
'attributes' => $this->attributes,
|
||||
'script' => $this->fe_script_handle,
|
||||
'style' => $this->fe_style_handle,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue/register the block's assets upon init
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_block_assets() {
|
||||
add_action( 'enqueue_block_editor_assets', array( $this, 'register_scripts' ) );
|
||||
add_action( 'enqueue_block_editor_assets', array( $this, 'register_styles' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks allowed blocks for Gravity forms blocks to only enqueue block editor assets when necessary.
|
||||
*
|
||||
* @since 2.4.18
|
||||
*
|
||||
* @deprecated since 2.5.6. See GF_Block::register_block_assets()
|
||||
*
|
||||
* @param bool|array $allowed_block_types Array of block type slugs, or boolean to enable/disable all.
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
public function check_allowed_blocks( $allowed_block_types ) {
|
||||
|
||||
// Only enqueue block editor assets if all blocks are allowed or if the current block type is an allowed block.
|
||||
if ( $allowed_block_types === true || ( is_array( $allowed_block_types ) && in_array( $this->get_type(), $allowed_block_types ) ) ) {
|
||||
add_action( 'enqueue_block_editor_assets', array( $this, 'register_scripts' ) );
|
||||
add_action( 'enqueue_block_editor_assets', array( $this, 'register_styles' ) );
|
||||
}
|
||||
|
||||
return $allowed_block_types;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// # SCRIPT ENQUEUEING ---------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Enqueue block scripts.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @uses GF_Block::scripts()
|
||||
*/
|
||||
public function register_scripts() {
|
||||
|
||||
// Get registered scripts.
|
||||
$scripts = $this->scripts();
|
||||
|
||||
// If no scripts are registered, return.
|
||||
if ( empty( $scripts ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through scripts.
|
||||
foreach ( $scripts as $script ) {
|
||||
|
||||
// Prepare parameters.
|
||||
$src = isset( $script['src'] ) ? $script['src'] : false;
|
||||
$deps = isset( $script['deps'] ) ? $script['deps'] : array();
|
||||
$version = isset( $script['version'] ) ? $script['version'] : false;
|
||||
$in_footer = isset( $script['in_footer'] ) ? $script['in_footer'] : false;
|
||||
|
||||
// Enqueue script.
|
||||
if ( $this->script_handle === $script['handle'] ) {
|
||||
// Support for the editor_style property, if a style_handle is defined. No need to enqueue.
|
||||
wp_register_script( $script['handle'], $src, $deps, $version, $in_footer );
|
||||
} else {
|
||||
// style_handle isn't defined, or this is an additional style. Enqueue it manually.
|
||||
wp_enqueue_script( $script['handle'], $src, $deps, $version, $in_footer );
|
||||
}
|
||||
|
||||
// Localize script.
|
||||
if ( rgar( $script, 'strings' ) ) {
|
||||
wp_localize_script( $script['handle'], $script['handle'] . '_strings', $script['strings'] );
|
||||
}
|
||||
|
||||
// Run script callback.
|
||||
if ( rgar( $script, 'callback' ) && is_callable( $script['callback'] ) ) {
|
||||
call_user_func( $script['callback'], $script );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue scripts
|
||||
*
|
||||
* @depecated since 2.5.6. Use ::register_scripts() instead.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue_scripts() {
|
||||
$this->register_scripts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this function to provide a list of scripts to be enqueued.
|
||||
* Following is an example of the array that is expected to be returned by this function:
|
||||
* <pre>
|
||||
* <code>
|
||||
*
|
||||
* array(
|
||||
* array(
|
||||
* 'handle' => 'super_signature_script',
|
||||
* 'src' => $this->get_base_url() . '/super_signature/ss.js',
|
||||
* 'version' => $this->_version,
|
||||
* 'deps' => array( 'jquery'),
|
||||
* 'callback' => array( $this, 'localize_scripts' ),
|
||||
* 'strings' => array(
|
||||
* // Accessible in JavaScript using the global variable "[script handle]_strings"
|
||||
* 'stringKey1' => __( 'The string', 'gravityforms' ),
|
||||
* 'stringKey2' => __( 'Another string.', 'gravityforms' )
|
||||
* )
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function scripts() {
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// # STYLE ENQUEUEING ----------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Enqueue block styles.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*/
|
||||
public function register_styles() {
|
||||
|
||||
// Get registered styles.
|
||||
$styles = $this->styles();
|
||||
|
||||
// If no styles are registered, return.
|
||||
if ( empty( $styles ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through styles.
|
||||
foreach ( $styles as $style ) {
|
||||
|
||||
// Prepare parameters.
|
||||
$src = isset( $style['src'] ) ? $style['src'] : false;
|
||||
$deps = isset( $style['deps'] ) ? $style['deps'] : array();
|
||||
$version = isset( $style['version'] ) ? $style['version'] : false;
|
||||
$media = isset( $style['media'] ) ? $style['media'] : 'all';
|
||||
|
||||
if ( $this->style_handle === $style['handle'] ) {
|
||||
// Support for the editor_style property, if a style_handle is defined. No need to enqueue.
|
||||
wp_register_style( $style['handle'], $src, $deps, $version, $media );
|
||||
} else {
|
||||
// style_handle isn't defined, or this is an additional style. Enqueue it manually.
|
||||
wp_enqueue_style( $style['handle'], $src, $deps, $version, $media );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue styles
|
||||
*
|
||||
* @depecated since 2.5.6. Use ::register_styles() instead.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue_styles() {
|
||||
$this->register_styles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this function to provide a list of styles to be enqueued.
|
||||
* See scripts() for an example of the format expected to be returned.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function styles() {
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// # BLOCK RENDER -------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Display block contents on frontend.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @param array $attributes Block attributes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render_block( $attributes = array() ) {
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to perform additional actions when scripts/styles are enqueued on the wp_enqueue_scripts hook.
|
||||
*
|
||||
* @since 2.4.18
|
||||
*
|
||||
* @param array $found_forms An array of found forms using the form ID as the key to the ajax status.
|
||||
* @param array $found_blocks An array of found GF blocks.
|
||||
* @param WP_Post $post The post which was processed.
|
||||
*/
|
||||
public function post_enqueue_scripts( $found_forms, $found_blocks, $post ) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Blocks;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Service_Provider;
|
||||
use Gravity_Forms\Gravity_Forms\Blocks\Config\GF_Blocks_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Blocks\GF_Block_Attributes;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
|
||||
|
||||
use GFFormDisplay;
|
||||
use GFCommon;
|
||||
|
||||
/**
|
||||
* Class GF_Blocks_Service_Provider
|
||||
*
|
||||
* Service provider for the Blocks Service.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Blocks;
|
||||
*/
|
||||
class GF_Blocks_Service_Provider extends GF_Service_Provider {
|
||||
|
||||
// Configs
|
||||
const BLOCKS_CONFIG = 'blocks_config';
|
||||
|
||||
// Attributes
|
||||
const FORM_BLOCK_ATTRIBUTES = 'form_block_attributes';
|
||||
|
||||
const BLOCK_ATTRIBUTES = 'block_attributes';
|
||||
|
||||
/**
|
||||
* Array mapping config class names to their container ID.
|
||||
*
|
||||
* @since
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $configs = array(
|
||||
self::BLOCKS_CONFIG => GF_Blocks_Config::class,
|
||||
);
|
||||
|
||||
/**
|
||||
* Register services to the container.
|
||||
*
|
||||
* @since
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*/
|
||||
public function register( GF_Service_Container $container ) {
|
||||
|
||||
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-block-attributes.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/config/class-gf-blocks-config.php' );
|
||||
|
||||
$container->add( self::FORM_BLOCK_ATTRIBUTES, function () {
|
||||
require_once( GFCommon::get_base_path() . '/form_display.php' );
|
||||
$global_styles = GFFormDisplay::validate_form_styles( apply_filters( 'gform_default_styles', false ) );
|
||||
|
||||
return array(
|
||||
'formId' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
),
|
||||
'title' =>
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'default' => true,
|
||||
),
|
||||
'description' =>
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'default' => true,
|
||||
),
|
||||
'ajax' =>
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'default' => false,
|
||||
),
|
||||
'tabindex' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
),
|
||||
'fieldValues' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
),
|
||||
'formPreview' =>
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'default' => true,
|
||||
),
|
||||
'imgPreview' =>
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'default' => false,
|
||||
),
|
||||
'theme' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => '',
|
||||
),
|
||||
'inputSize' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => rgar( $global_styles, 'inputSize' ) ? $global_styles['inputSize'] : 'md',
|
||||
),
|
||||
'inputBorderRadius' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => rgar( $global_styles, 'inputBorderRadius' ) ? $global_styles['inputBorderRadius'] : 3,
|
||||
),
|
||||
'inputBorderColor' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => rgar( $global_styles, 'inputBorderColor' ) ? $global_styles['inputBorderColor'] : '#686e77',
|
||||
),
|
||||
'inputBackgroundColor' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => rgar( $global_styles, 'inputBackgroundColor' ) ? $global_styles['inputBackgroundColor'] : '#fff',
|
||||
),
|
||||
'inputColor' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => rgar( $global_styles, 'inputColor' ) ? $global_styles['inputColor'] : '#112337',
|
||||
),
|
||||
'inputPrimaryColor' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
// Setting this to empty allows us to set this to what the appropriate default
|
||||
// should be from within the block. When empty, it defaults to:
|
||||
// buttonPrimaryBackgroundColor
|
||||
'default' => rgar( $global_styles, 'inputPrimaryColor' ) ? $global_styles['inputPrimaryColor'] : '', // #204ce5
|
||||
),
|
||||
'labelFontSize' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => rgar( $global_styles, 'labelFontSize' ) ? $global_styles['labelFontSize'] : 14,
|
||||
),
|
||||
'labelColor' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => rgar( $global_styles, 'labelColor' ) ? $global_styles['labelColor'] : '#112337',
|
||||
),
|
||||
'descriptionFontSize' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => rgar( $global_styles, 'descriptionFontSize' ) ? $global_styles['descriptionFontSize'] : 13,
|
||||
),
|
||||
'descriptionColor' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => rgar( $global_styles, 'descriptionColor' ) ? $global_styles['descriptionColor'] : '#585e6a',
|
||||
),
|
||||
'buttonPrimaryBackgroundColor' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => rgar( $global_styles, 'buttonPrimaryBackgroundColor' ) ? $global_styles['buttonPrimaryBackgroundColor'] : '#204ce5',
|
||||
),
|
||||
'buttonPrimaryColor' =>
|
||||
array(
|
||||
'type' => 'string',
|
||||
'default' => rgar( $global_styles, 'buttonPrimaryColor' ) ? $global_styles['buttonPrimaryColor'] : '#fff',
|
||||
),
|
||||
);
|
||||
} );
|
||||
|
||||
$this->add_configs( $container );
|
||||
$this->block_attributes( $container );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize any actions or hooks.
|
||||
*
|
||||
* @since
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init( GF_Service_Container $container ) {
|
||||
|
||||
add_action( 'gform_post_enqueue_scripts', function( $found_forms, $found_blocks, $post ) use ( $container ) {
|
||||
foreach( $found_blocks as $block ) {
|
||||
$attributes = $block['attrs'];
|
||||
$container->get( self::BLOCK_ATTRIBUTES )->store( $attributes );
|
||||
}
|
||||
}, -10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* For each config defined in $configs, instantiate and add to container.
|
||||
*
|
||||
* @since
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function add_configs( GF_Service_Container $container ) {
|
||||
foreach ( $this->configs as $name => $class ) {
|
||||
$container->add( $name, function () use ( $container, $class ) {
|
||||
if ( $class == GF_Blocks_Config::class ) {
|
||||
return new $class( $container->get( GF_Config_Service_Provider::DATA_PARSER ), $container->get( self::FORM_BLOCK_ATTRIBUTES ) );
|
||||
}
|
||||
|
||||
return new $class( $container->get( GF_Config_Service_Provider::DATA_PARSER ) );
|
||||
} );
|
||||
|
||||
$container->get( GF_Config_Service_Provider::CONFIG_COLLECTION )->add_config( $container->get( $name ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Block services.
|
||||
*
|
||||
* @since 2.7.4
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function block_attributes( GF_Service_Container $container ) {
|
||||
$container->add( self::BLOCK_ATTRIBUTES, function () use ( $container ) {
|
||||
return new GF_Block_Attributes();
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
<?php
|
||||
|
||||
defined( 'ABSPATH' ) or die();
|
||||
|
||||
// Load core Block class.
|
||||
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-block.php' );
|
||||
|
||||
/**
|
||||
* Handles management of Gravity Forms editor blocks.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* Class GF_Blocks
|
||||
*/
|
||||
class GF_Blocks {
|
||||
|
||||
/**
|
||||
* Registered Gravity Forms editor blocks.
|
||||
*
|
||||
* @since 2.4.10
|
||||
* @var GF_Block[]
|
||||
*/
|
||||
private static $_blocks = array();
|
||||
|
||||
/**
|
||||
* Register a block type.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @param GF_Block $block Block class.
|
||||
*
|
||||
* @return bool|WP_Error
|
||||
*/
|
||||
public static function register( $block ) {
|
||||
|
||||
if ( ! is_subclass_of( $block, 'GF_Block' ) ) {
|
||||
return new WP_Error( 'block_not_subclass', 'Must be a subclass of GF_Block' );
|
||||
}
|
||||
|
||||
// Get block type.
|
||||
$block_type = $block->get_type();
|
||||
|
||||
if ( empty( $block_type ) ) {
|
||||
return new WP_Error( 'block_type_undefined', 'The type must be set' );
|
||||
}
|
||||
|
||||
if ( isset( self::$_blocks[ $block_type ] ) ) {
|
||||
return new WP_Error( 'block_already_registered', 'Block type already registered: ' . $block_type );
|
||||
}
|
||||
|
||||
// Register block.
|
||||
self::$_blocks[ $block_type ] = $block;
|
||||
|
||||
// Initialize block.
|
||||
call_user_func( array( $block, 'init' ) );
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get instance of block.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @param string $block_type Block type.
|
||||
*
|
||||
* @return GF_Block|bool
|
||||
*/
|
||||
public static function get( $block_type ) {
|
||||
|
||||
return isset( self::$_blocks[ $block_type ] ) ? self::$_blocks[ $block_type ] : false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of registered block types.
|
||||
*
|
||||
* @since 2.4.18
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_all_types() {
|
||||
return array_keys( self::$_blocks );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
new GF_Blocks();
|
||||
@@ -1,98 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Blocks\Config;
|
||||
|
||||
use GFSettings;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Data_Parser;
|
||||
use \GFCommon;
|
||||
use \GFAPI;
|
||||
use \GFFormDisplay;
|
||||
|
||||
/**
|
||||
* Config items for Blocks.
|
||||
*
|
||||
* @since
|
||||
*/
|
||||
class GF_Blocks_Config extends GF_Config {
|
||||
|
||||
protected $name = 'gform_admin_config';
|
||||
protected $script_to_localize = 'gform_gravityforms_admin_vendors';
|
||||
protected $attributes = array();
|
||||
|
||||
public function __construct( GF_Config_Data_Parser $parser, array $attributes ) {
|
||||
parent::__construct( $parser );
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
public function should_enqueue() {
|
||||
return GFCommon::is_block_editor_page();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of forms for Block control.
|
||||
*
|
||||
* @since 2.4.10
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_forms() {
|
||||
|
||||
// Initialize forms array.
|
||||
$forms = array();
|
||||
|
||||
// Load GFFormDisplay class.
|
||||
if ( ! class_exists( 'GFFormDisplay' ) ) {
|
||||
require_once GFCommon::get_base_path() . '/form_display.php';
|
||||
}
|
||||
|
||||
// Get form objects.
|
||||
$form_objects = GFAPI::get_forms( true, false, 'title', 'ASC' );
|
||||
|
||||
// Loop through forms, add conditional logic check.
|
||||
foreach ( $form_objects as $form ) {
|
||||
$forms[] = array(
|
||||
'id' => $form['id'],
|
||||
'title' => $form['title'],
|
||||
'hasConditionalLogic' => GFFormDisplay::has_conditional_logic( $form ),
|
||||
'isLegacyMarkup' => GFCommon::is_legacy_markup_enabled( $form ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the list of available forms displayed in the Form block.
|
||||
*
|
||||
* @since 2.4.23
|
||||
*
|
||||
* @param array $forms A collection of active forms on site.
|
||||
*/
|
||||
return apply_filters( 'gform_block_form_forms', $forms );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
$attributes = apply_filters( 'gform_form_block_attributes', $this->attributes );
|
||||
|
||||
$orbital_default = GFSettings::is_orbital_default();
|
||||
|
||||
return array(
|
||||
'gravityforms/form' => array(
|
||||
'data' => array(
|
||||
'attributes' => $attributes,
|
||||
'adminURL' => admin_url( 'admin.php' ),
|
||||
'forms' => $this->get_forms(),
|
||||
'preview' => GFCommon::get_base_url() . '/images/gf_block_preview.svg',
|
||||
'orbitalDefault' => $orbital_default,
|
||||
'styles' => array(
|
||||
'defaults' => \GFForms::get_service_container()->get( \Gravity_Forms\Gravity_Forms\Form_Display\GF_Form_Display_Service_Provider::BLOCK_STYLES_DEFAULTS ),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,104 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Background Upgrader
|
||||
*
|
||||
* Uses https://github.com/A5hleyRich/wp-background-processing to handle DB
|
||||
* updates in the background.
|
||||
*
|
||||
* @class GF_Background_Upgrader
|
||||
* @version 2.3
|
||||
* @category Class
|
||||
* @author Rocketgenius
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'GF_Background_Process' ) ) {
|
||||
require_once GF_PLUGIN_DIR_PATH . 'includes/libraries/gf-background-process.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* GF_Background_Upgrader Class.
|
||||
*/
|
||||
class GF_Background_Upgrader extends GF_Background_Process {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $action = 'gf_upgrader';
|
||||
|
||||
/**
|
||||
* Returns the data for the background upgrader.
|
||||
*
|
||||
* @since 2.3
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_data() {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the queue empty for all blogs?
|
||||
*
|
||||
* @since 2.3
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_queue_empty() {
|
||||
return parent::is_queue_empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the updater running?
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_updating() {
|
||||
return false === $this->is_queue_empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Task
|
||||
*
|
||||
* Override this method to perform any actions required on each
|
||||
* queue item. Return the modified item for further processing
|
||||
* in the next pass through. Or, return false to remove the
|
||||
* item from the queue.
|
||||
*
|
||||
* @param string $callback Update callback function
|
||||
* @return mixed
|
||||
*/
|
||||
protected function task( $callback ) {
|
||||
if ( ! defined( 'GF_UPGRADING' ) ) {
|
||||
define( 'GF_UPGRADING', true );
|
||||
}
|
||||
|
||||
if ( is_callable( $callback ) ) {
|
||||
GFCommon::log_debug( sprintf( '%s(): Running callback: %s', __METHOD__, print_r( $callback, 1 ) ) );
|
||||
$needs_more_time = call_user_func( $callback );
|
||||
if ( $needs_more_time ) {
|
||||
GFCommon::log_debug( sprintf( '%s(): Callback needs another run: %s', __METHOD__, print_r( $callback, 1 ) ) );
|
||||
return $callback;
|
||||
} else {
|
||||
GFCommon::log_debug( sprintf( '%s(): Finished callback: %s', __METHOD__, print_r( $callback, 1 ) ) );
|
||||
}
|
||||
} else {
|
||||
GFCommon::log_debug( sprintf( '%s(): Could not find callback: %s', __METHOD__, print_r( $callback, 1 ) ) );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete
|
||||
*
|
||||
* Override if applicable, but ensure that the below actions are
|
||||
* performed, or, call parent::complete().
|
||||
*/
|
||||
protected function complete() {
|
||||
parent::complete();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,209 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Handles download requests for files stored by File Upload fields.
|
||||
*
|
||||
* Class GF_Download
|
||||
*/
|
||||
class GF_Download {
|
||||
|
||||
/**
|
||||
* If the request is for a Gravity Forms file download then validate and deliver.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function maybe_process() {
|
||||
if ( isset( $_GET['gf-download'] ) ) {
|
||||
|
||||
$file = $_GET['gf-download'];
|
||||
$form_id = rgget( 'form-id' );
|
||||
$field_id = rgget( 'field-id' );
|
||||
|
||||
if ( empty( $file ) || empty( $form_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$hash = rgget( 'hash' );
|
||||
GFCommon::log_debug( __METHOD__ . "(): Starting file download process. file: {$file}, hash: {$hash}." );
|
||||
|
||||
$permission_granted = self::validate_download( $form_id, $field_id, $file, $hash );
|
||||
|
||||
if ( has_filter( 'gform_permission_granted_pre_download' ) ) {
|
||||
GFCommon::log_debug( __METHOD__ . '(): Executing functions hooked to gform_permission_granted_pre_download.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow custom logic to be used to determine if the file can be accessed.
|
||||
*
|
||||
* @since 2.4.3.2
|
||||
*
|
||||
* @param bool $permission_granted Indicates if access to the file has been granted. Default is the result of the hash validation.
|
||||
* @param int $form_id The ID of the form used to upload the requested file.
|
||||
* @param int $field_id The ID of the field used to upload the requested file.
|
||||
*/
|
||||
$permission_granted = apply_filters( 'gform_permission_granted_pre_download', $permission_granted, $form_id, $field_id );
|
||||
|
||||
if ( $permission_granted ) {
|
||||
GFCommon::log_debug( __METHOD__ . '(): Download validated. Proceeding.' );
|
||||
self::deliver( $form_id, $file );
|
||||
} else {
|
||||
GFCommon::log_debug( __METHOD__ . '(): Download validation failed. Aborting with 401.' );
|
||||
self::die_401();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the hash for the download.
|
||||
*
|
||||
* @param int $form_id
|
||||
* @param int $field_id
|
||||
* @param string $file
|
||||
* @param string $hash
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function validate_download( $form_id, $field_id, $file, $hash ) {
|
||||
if ( empty( $hash ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( has_filter( 'gform_require_login_pre_download' ) ) {
|
||||
GFCommon::log_debug( __METHOD__ . '(): Executing functions hooked to gform_require_login_pre_download.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows login to be required to access the file.
|
||||
*
|
||||
* @since 2.2.3.16
|
||||
*
|
||||
* @param bool $require_login Does the user need to be logged in to access the file? Default false.
|
||||
* @param int $form_id The ID of the form used to upload the requested file.
|
||||
* @param int $field_id The ID of the field used to upload the requested file.
|
||||
*/
|
||||
$require_login = apply_filters( 'gform_require_login_pre_download', false, $form_id, $field_id );
|
||||
|
||||
if ( $require_login && ! is_user_logged_in() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$hash_check = GFCommon::generate_download_hash( $form_id, $field_id, $file );
|
||||
$valid = hash_equals( $hash, $hash_check );
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the file.
|
||||
*
|
||||
* @param $form_id
|
||||
* @param $file
|
||||
*/
|
||||
private static function deliver( $form_id, $file ) {
|
||||
$path = GFFormsModel::get_upload_path( $form_id );
|
||||
$file_path = trailingslashit( $path ) . $file;
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . "(): Checking if file exists: {$file_path}." );
|
||||
|
||||
if ( file_exists( $file_path ) ) {
|
||||
GFCommon::log_debug( __METHOD__ . '(): File exists. Starting delivery.' );
|
||||
|
||||
$content_type = self::get_content_type( $file_path );
|
||||
$content_disposition = rgget( 'dl' ) ? 'attachment' : 'inline';
|
||||
|
||||
nocache_headers();
|
||||
header( 'X-Robots-Tag: noindex', true );
|
||||
header( 'Content-Type: ' . $content_type );
|
||||
header( 'Content-Description: File Transfer' );
|
||||
header( 'Content-Disposition: ' . $content_disposition . '; filename="' . wp_basename( $file ) . '"' );
|
||||
header( 'Content-Transfer-Encoding: binary' );
|
||||
// Clear buffer AND turn off output buffering before starting delivery of files requested for download to prevent third-parties to corrupt the file content.
|
||||
if ( ob_get_contents() ) {
|
||||
ob_end_clean();
|
||||
}
|
||||
self::readfile_chunked( $file_path );
|
||||
die();
|
||||
} else {
|
||||
GFCommon::log_debug( __METHOD__ . '(): File does not exist. Aborting with 404.' );
|
||||
self::die_404();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate mime type for the file extension.
|
||||
*
|
||||
* @param $file_path
|
||||
*
|
||||
* @return mixed|null|string
|
||||
*/
|
||||
private static function get_content_type( $file_path ) {
|
||||
$info = wp_check_filetype( $file_path );
|
||||
$type = rgar( $info, 'type' );
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads file in chunks so big downloads are possible without changing PHP.INI
|
||||
* See https://github.com/bcit-ci/CodeIgniter/wiki/Download-helper-for-large-files
|
||||
*
|
||||
* @access public
|
||||
* @param string $file The file
|
||||
* @param boolean $retbytes Return the bytes of file
|
||||
* @return bool|string If string, $status || $cnt
|
||||
*/
|
||||
private static function readfile_chunked( $file, $retbytes = true ) {
|
||||
|
||||
$chunksize = 1024 * 1024;
|
||||
$buffer = '';
|
||||
$cnt = 0;
|
||||
$handle = @fopen( $file, 'r' );
|
||||
|
||||
if ( $size = @filesize( $file ) ) {
|
||||
header( 'Content-Length: ' . $size );
|
||||
}
|
||||
|
||||
if ( false === $handle ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while ( ! @feof( $handle ) ) {
|
||||
$buffer = @fread( $handle, $chunksize );
|
||||
echo $buffer;
|
||||
|
||||
if ( $retbytes ) {
|
||||
$cnt += strlen( $buffer );
|
||||
}
|
||||
}
|
||||
|
||||
$status = @fclose( $handle );
|
||||
|
||||
if ( $retbytes && $status ) {
|
||||
return $cnt;
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the request with a 404 (Not Found) HTTP status code. Loads the 404 template if it exists.
|
||||
*/
|
||||
private static function die_404() {
|
||||
global $wp_query;
|
||||
status_header( 404 );
|
||||
$wp_query->set_404();
|
||||
$template_path = get_404_template();
|
||||
if ( file_exists( $template_path ) ) {
|
||||
require_once( $template_path );
|
||||
}
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the request with a 401 (Unauthorized) HTTP status code.
|
||||
*/
|
||||
private static function die_401() {
|
||||
status_header( 401 );
|
||||
die();
|
||||
}
|
||||
}
|
||||
@@ -1,351 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Adds integration with osDXP.
|
||||
*
|
||||
* @since 2.4.15
|
||||
*/
|
||||
class GF_OSDXP {
|
||||
|
||||
/**
|
||||
* @var GF_OSDXP
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* @var array The array of page slugs.
|
||||
*/
|
||||
private $slugs = array();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @since 2.4.15
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->slugs = [
|
||||
'gf_settings' => esc_html__( 'Settings', 'gravityforms' ),
|
||||
'gf_export' => esc_html__( 'Import/Export', 'gravityforms' ),
|
||||
'gf_addons' => esc_html__( 'Add-Ons', 'gravityforms' ),
|
||||
'gf_help' => esc_html__( 'Help', 'gravityforms' ),
|
||||
'gf_system_status' => esc_html__( 'System Status', 'gravityforms' ),
|
||||
];
|
||||
add_filter( 'osdxp_license_key_gravityforms', array( $this, 'license_key' ) );
|
||||
add_filter( 'osdxp_dashboard_license_submit_response', array( $this, 'process_license_key_submit' ), 10, 3 );
|
||||
add_filter( 'osdxp_dashboard_license_deletion_response', array(
|
||||
$this,
|
||||
'process_license_key_deletion',
|
||||
), 10, 2 );
|
||||
add_filter( 'osdxp_add_module_settings_page', array( $this, 'settings_page' ) );
|
||||
add_filter( 'parent_file', array( $this, 'settings_page_highlight' ) );
|
||||
add_action( 'in_admin_header', array( $this, 'nav_tabs' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a class instance.
|
||||
*
|
||||
* @since 2.4.15
|
||||
*
|
||||
* @return GF_OSDXP instance of GF_OSDXP.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the license key display.
|
||||
*
|
||||
* @since 2.4.15
|
||||
*
|
||||
* @param $license_key
|
||||
*
|
||||
* @return string|null Return a string or null to display the text box.
|
||||
*/
|
||||
public static function license_key( $license_key ) {
|
||||
$version_info = GFCommon::get_version_info( false );
|
||||
$key = GFCommon::get_key();
|
||||
|
||||
if ( ! rgempty( 'is_error', $version_info ) ) {
|
||||
return esc_attr__( 'There was an error while validating your license key. Gravity Forms will continue to work, but automatic upgrades will not be available. Please contact support to resolve this issue.', 'gravityforms' );
|
||||
} elseif ( rgar( $version_info, 'is_valid_key' ) ) {
|
||||
return esc_html__( 'Valid', 'gravityforms' );
|
||||
|
||||
} elseif ( ! empty( $key ) ) {
|
||||
return esc_html__( 'Invalid or Expired.', 'gravityforms' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Process license key submit.
|
||||
*
|
||||
* Callback for the 'osdxp_dashboard_license_submit_response' filter.
|
||||
*
|
||||
* @since 2.4.15
|
||||
*
|
||||
* @param array $response Response.
|
||||
* @param string $plugin_slug Plugin slug.
|
||||
* @param string $license_key License key.
|
||||
*
|
||||
* @return array Response array.
|
||||
*/
|
||||
public static function process_license_key_submit( $response, $plugin_slug, $license_key ) {
|
||||
|
||||
if ( 'gravityforms' !== $plugin_slug ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
if ( ! is_array( $response ) ) {
|
||||
$response = array();
|
||||
}
|
||||
|
||||
// Sanitize license key.
|
||||
$license_key = sanitize_text_field( $license_key );
|
||||
|
||||
GFFormsModel::save_key( $license_key );
|
||||
|
||||
// Updating message because key could have been changed.
|
||||
GFCommon::cache_remote_message();
|
||||
|
||||
// Re-caching version info.
|
||||
$version_info = GFCommon::get_version_info( false );
|
||||
|
||||
$error_message = '';
|
||||
|
||||
$key = GFCommon::get_key();
|
||||
|
||||
if ( ! rgempty( 'is_error', $version_info ) ) {
|
||||
$error_message = esc_attr__( 'There was an error while validating your license key. Gravity Forms will continue to work, but automatic upgrades will not be available. Please contact support to resolve this issue.', 'gravityforms' );
|
||||
} elseif ( rgar( $version_info, 'is_valid_key' ) ) {
|
||||
|
||||
update_option( 'gform_pending_installation', 0 );
|
||||
if ( ! get_option( 'rg_gforms_currency' ) ) {
|
||||
update_option( 'rg_gforms_currency', 'USD' );
|
||||
}
|
||||
|
||||
$success_message = esc_html__( 'Valid Key : Your license key has been successfully validated.', 'gravityforms' );
|
||||
|
||||
if ( empty( $response['success_messages'] ) || ! is_array( $response['success_messages'] ) ) {
|
||||
$response['success_messages'] = array();
|
||||
}
|
||||
|
||||
$response['success_messages'][] = $success_message;
|
||||
} elseif ( rgar( $version_info, 'reason' ) == 'requires_enterprise_license' ) {
|
||||
$error_message = esc_html__( 'Invalid Key - an Enterprise license is required.', 'gravityforms' );
|
||||
} elseif ( ! empty( $key ) ) {
|
||||
$error_message = esc_html__( 'Invalid or Expired Key - Please make sure you have entered the correct value and that your key is not expired.', 'gravityforms' );
|
||||
}
|
||||
|
||||
if ( ! empty( $error_message ) ) {
|
||||
|
||||
if ( empty( $response['error_messages'] ) || ! is_array( $response['error_messages'] ) ) {
|
||||
$response['error_messages'] = array();
|
||||
}
|
||||
|
||||
$response['error_messages'][] = $error_message;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the license key deletion.
|
||||
*
|
||||
* @since 2.4.15
|
||||
*
|
||||
* @param $response
|
||||
* @param $plugin_slug
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function process_license_key_deletion( $response, $plugin_slug ) {
|
||||
|
||||
if ( $plugin_slug != 'gravityforms' ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
if ( ! is_array( $response ) ) {
|
||||
$response = array();
|
||||
}
|
||||
|
||||
GFFormsModel::save_key( '' );
|
||||
|
||||
$response['success'] = 1;
|
||||
|
||||
if ( empty( $response['success_messages'] ) || ! is_array( $response['success_messages'] ) ) {
|
||||
$response['success_messages'] = array();
|
||||
}
|
||||
|
||||
$response['success_messages'][] = esc_html__( 'License successfully removed.', 'gravityforms' );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers plugin pages with osDXP.
|
||||
*
|
||||
* @since 2.4.15
|
||||
*
|
||||
* @param $pages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function settings_page( $pages ) {
|
||||
|
||||
/**
|
||||
* Setup.
|
||||
*/
|
||||
$has_full_access = current_user_can( 'gform_full_access' );
|
||||
$min_cap = GFCommon::current_user_can_which( GFCommon::all_caps() );
|
||||
if ( empty( $min_cap ) ) {
|
||||
$min_cap = 'gform_full_access';
|
||||
}
|
||||
|
||||
$parent_menu = array(
|
||||
'name' => 'gf_edit_forms',
|
||||
'callback' => array('GFForms', 'forms')
|
||||
);
|
||||
|
||||
/**
|
||||
* Remove Classic WP-Admin menu items.
|
||||
*/
|
||||
global $admin_page_hooks;
|
||||
static $removed = false;
|
||||
if ( ! $removed && is_array( $admin_page_hooks ) ) {
|
||||
$removed = true;
|
||||
remove_menu_page( $parent_menu['name'] );
|
||||
remove_submenu_page( $parent_menu['name'], 'gf_settings' );
|
||||
remove_submenu_page( $parent_menu['name'], 'gf_export' );
|
||||
remove_submenu_page( $parent_menu['name'], 'gf_addons' );
|
||||
remove_submenu_page( $parent_menu['name'], 'gf_system_status' );
|
||||
remove_submenu_page( $parent_menu['name'], 'gf_help' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add osDXP specific pages.
|
||||
*/
|
||||
// Top-level action page.
|
||||
$pages[] = array(
|
||||
'function' => $parent_menu['callback'],
|
||||
'type' => 'menu',
|
||||
'menu_slug' => $parent_menu['name'],
|
||||
'page_title' => esc_html__( 'Forms', 'gravityforms' ),
|
||||
'menu_title' => esc_html__( 'Forms', 'gravityforms' ),
|
||||
'capability' => $has_full_access ? 'gform_full_access' : $min_cap,
|
||||
'icon_url' => GFForms::get_admin_icon_b64( '#FFF' ),
|
||||
);
|
||||
// Settings page.
|
||||
$pages[] = array(
|
||||
'function' => array( 'GFForms', 'settings_page' ),
|
||||
'menu_slug' => 'gf_settings',
|
||||
'page_title' => esc_html__( 'Form Settings', 'gravityforms' ),
|
||||
'menu_title' => esc_html__( 'Form Settings', 'gravityforms' ),
|
||||
'capability' => $has_full_access ? 'gform_full_access' : 'gravityforms_view_settings',
|
||||
);
|
||||
// Export page.
|
||||
$pages[] = array(
|
||||
'function' => array( 'GFForms', 'export_page' ),
|
||||
'menu_slug' => 'gf_export',
|
||||
'type' => 'endpoint',
|
||||
'page_title' => esc_html__( 'Import/Export', 'gravityforms' ),
|
||||
'menu_title' => esc_html__( 'Import/Export', 'gravityforms' ),
|
||||
'capability' => $has_full_access ? 'gform_full_access' : ( current_user_can( 'gravityforms_export_entries' ) ? 'gravityforms_export_entries' : 'gravityforms_edit_forms' ),
|
||||
);
|
||||
if ( current_user_can( 'install_plugins' ) ) {
|
||||
// Add-ons page.
|
||||
$pages[] = array(
|
||||
'function' => array( 'GFForms', 'addons_page' ),
|
||||
'menu_slug' => 'gf_addons',
|
||||
'type' => 'endpoint',
|
||||
'page_title' => esc_html__( 'Add-Ons', 'gravityforms' ),
|
||||
'menu_title' => esc_html__( 'Add-Ons', 'gravityforms' ),
|
||||
'capability' => $has_full_access ? 'gform_full_access' : 'gravityforms_view_addons',
|
||||
);
|
||||
}
|
||||
// System status page.
|
||||
$pages[] = array(
|
||||
'function' => array( 'GFForms', 'system_status' ),
|
||||
'menu_slug' => 'gf_system_status',
|
||||
'type' => 'endpoint',
|
||||
'page_title' => esc_html__( 'System Status', 'gravityforms' ),
|
||||
'menu_title' => esc_html__( 'System Status', 'gravityforms' ),
|
||||
'capability' => $has_full_access ? 'gform_full_access' : 'gravityforms_system_status',
|
||||
);
|
||||
// Help page.
|
||||
$pages[] = array(
|
||||
'function' => array( 'GFForms', 'help_page' ),
|
||||
'menu_slug' => 'gf_help',
|
||||
'type' => 'endpoint',
|
||||
'page_title' => esc_html__( 'Help', 'gravityforms' ),
|
||||
'menu_title' => esc_html__( 'Help', 'gravityforms' ),
|
||||
'capability' => $has_full_access ? 'gform_full_access' : $min_cap,
|
||||
);
|
||||
|
||||
return $pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to check if a page slug is a setting/misc page.
|
||||
*
|
||||
* @since 2.4.15
|
||||
*
|
||||
* @param $plugin_page
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_setting_page( $plugin_page ) {
|
||||
return array_key_exists( $plugin_page, $this->slugs );
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights appropriate menu item for misc pages.
|
||||
*
|
||||
* @since 2.4.15
|
||||
*
|
||||
* @param $file
|
||||
*
|
||||
* @return $file
|
||||
*/
|
||||
public function settings_page_highlight( $file ) {
|
||||
global $plugin_page, $submenu_file;
|
||||
|
||||
if ( $this->is_setting_page( $plugin_page ) ) {
|
||||
$file = 'dxp-module-settings';
|
||||
$submenu_file = 'gf_settings';
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs Nav Tabs for settings&misc pages.
|
||||
*
|
||||
* @since 2.4.15
|
||||
*/
|
||||
public function nav_tabs() {
|
||||
global $plugin_page;
|
||||
|
||||
if ( $this->is_setting_page( $plugin_page ) ) {
|
||||
?>
|
||||
<ul class="osdxp-nav-tabs">
|
||||
<?php
|
||||
foreach ( $this->slugs as $path => $name ) {
|
||||
?>
|
||||
<li <?php echo ( $path === $plugin_page ) ? 'class="active"' : '' ?>>
|
||||
<a href="<?php echo admin_url( 'admin.php?page=' . $path ); ?>">
|
||||
<?php echo $name; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php
|
||||
} ?>
|
||||
</ul>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GF_OSDXP::get_instance();
|
||||
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms;
|
||||
|
||||
/**
|
||||
* Class GF_Service_Container
|
||||
*
|
||||
* A simple Service Container used to collect and organize Services used by the application and its modules.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms
|
||||
*/
|
||||
class GF_Service_Container {
|
||||
|
||||
private $services = array();
|
||||
private $providers = array();
|
||||
|
||||
/**
|
||||
* Add a service to the container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param string $name The service Name
|
||||
* @param mixed $service The service to add
|
||||
*/
|
||||
public function add( $name, $service, $defer = false ) {
|
||||
if ( empty( $name ) ) {
|
||||
$name = get_class( $service );
|
||||
}
|
||||
|
||||
if ( ! $defer && is_callable( $service ) ) {
|
||||
$service = $service();
|
||||
}
|
||||
|
||||
$this->services[ $name ] = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a service from the container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param string $name The service name.
|
||||
*/
|
||||
public function remove( $name ) {
|
||||
unset( $this->services[ $name ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a service from the container by name.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param string $name The service name.
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function get( $name ) {
|
||||
if ( ! isset( $this->services[ $name ] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( is_callable( $this->services[ $name ] ) ) {
|
||||
$called = $this->services[ $name ]();
|
||||
$this->services[ $name ] = $called;
|
||||
}
|
||||
|
||||
return $this->services[ $name ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a service provider to the container and register each of its services.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param GF_Service_Provider $provider
|
||||
*/
|
||||
public function add_provider( GF_Service_Provider $provider ) {
|
||||
$provider_name = get_class( $provider );
|
||||
|
||||
// Only add providers a single time.
|
||||
if ( isset( $this->providers[ $provider_name ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->providers[ $provider_name ] = $provider;
|
||||
|
||||
$provider->set_container( $this );
|
||||
$provider->register( $this );
|
||||
$provider->init( $this );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_App_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Service_Provider;
|
||||
|
||||
/**
|
||||
* Class GF_Service_Provider
|
||||
*
|
||||
* An abstraction which provides a contract for defining Service Providers. Service Providers facilitate
|
||||
* organizing Services into discreet modules, as opposed to having to register each service in a single location.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms
|
||||
*/
|
||||
abstract class GF_Service_Provider {
|
||||
|
||||
/**
|
||||
* @var GF_Service_Container $container
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
public function set_container( GF_Service_Container $container ) {
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new services to the Service Container.
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function register( GF_Service_Container $container );
|
||||
|
||||
/**
|
||||
* Noop by default - used to initialize hooks and filters for the given module.
|
||||
*/
|
||||
public function init( GF_Service_Container $container ) {}
|
||||
|
||||
//----------------------------------------
|
||||
//---------- App Registration ------------
|
||||
//----------------------------------------
|
||||
|
||||
/**
|
||||
* Register a JS app with the given arguments.
|
||||
*
|
||||
* @since 2.7.1
|
||||
*
|
||||
* @param array $args
|
||||
*/
|
||||
public function register_app( $args ) {
|
||||
$config = new GF_App_Config( $this->container->get( GF_Config_Service_Provider::DATA_PARSER ) );
|
||||
$config->set_data( $args );
|
||||
|
||||
$this->container->get( GF_Config_Service_Provider::CONFIG_COLLECTION )->add_config( $config );
|
||||
|
||||
$should_display = is_callable( $args['enqueue'] ) ? call_user_func( $args['enqueue'] ) : $args['enqueue'];
|
||||
|
||||
if ( ! $should_display ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $args['css'] ) ) {
|
||||
$this->enqueue_app_css( $args );
|
||||
}
|
||||
|
||||
if ( ! empty( $args['root_element'] ) ) {
|
||||
$this->add_root_element( $args['root_element'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the CSS assets for the app.
|
||||
*
|
||||
* @since 2.7.1
|
||||
*
|
||||
* @param $args
|
||||
*/
|
||||
protected function enqueue_app_css( $args ) {
|
||||
$css_asset = $args['css'];
|
||||
|
||||
add_action( 'wp_enqueue_scripts', function () use ( $css_asset ) {
|
||||
call_user_func_array( 'wp_enqueue_style', $css_asset );
|
||||
} );
|
||||
|
||||
add_action( 'admin_enqueue_scripts', function () use ( $css_asset ) {
|
||||
call_user_func_array( 'wp_enqueue_style', $css_asset );
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the root element to the footer output for bootstrapping.
|
||||
*
|
||||
* @since 2.7.1
|
||||
*
|
||||
* @param string $root
|
||||
*/
|
||||
protected function add_root_element( $root ) {
|
||||
add_action( 'admin_footer', function() use ( $root ) {
|
||||
echo '<div data-js="' . $root . '"></div>';
|
||||
}, 10, 0 );
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,551 +0,0 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
if ( ! defined( 'GRAVITY_API_URL' ) ) {
|
||||
define( 'GRAVITY_API_URL', 'https://gravityapi.com/wp-json/gravityapi/v1' );
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Gravity_Api' ) ) {
|
||||
|
||||
/**
|
||||
* Client-side API wrapper for interacting with the Gravity APIs.
|
||||
*
|
||||
* @package Gravity Forms
|
||||
* @subpackage Gravity_Api
|
||||
* @since 1.9
|
||||
* @access public
|
||||
*/
|
||||
class Gravity_Api {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance() {
|
||||
if ( null == self::$instance ) {
|
||||
self::$instance = new self;
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves site key and site secret key from remote API and stores them as WP options. Returns false if license key is invalid; otherwise, returns true.
|
||||
*
|
||||
* @since 2.3
|
||||
*
|
||||
* @param string $license_key License key to be registered.
|
||||
* @param boolean $is_md5 Specifies if $license_key provided is an MD5 or unhashed license key.
|
||||
*
|
||||
* @return bool|WP_Error
|
||||
*/
|
||||
public function register_current_site( $license_key, $is_md5 = false ) {
|
||||
|
||||
$body = array();
|
||||
$body['site_name'] = get_bloginfo( 'name' );
|
||||
$body['site_url'] = get_bloginfo( 'url' );
|
||||
|
||||
if ( $is_md5 ) {
|
||||
$body['license_key_md5'] = $license_key;
|
||||
} else {
|
||||
$body['license_key'] = $license_key;
|
||||
}
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . '(): registering site' );
|
||||
|
||||
$result = $this->request( 'sites', $body, 'POST', array( 'headers' => $this->get_license_auth_header( $license_key ) ) );
|
||||
$result = $this->prepare_response_body( $result, true );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
GFCommon::log_error( __METHOD__ . '(): error registering site. ' . $result->get_error_message() );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
update_option( 'gf_site_key', $result['key'] );
|
||||
update_option( 'gf_site_secret', $result['secret'] );
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . '(): site registration successful. Site Key: ' . $result['key'] );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates license key for a site that has already been registered.
|
||||
*
|
||||
* @since 2.3
|
||||
* @since 2.5 Returns License Response on success.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $new_license_key_md5 Hash license key to be updated
|
||||
*
|
||||
* @return \Gravity_Forms\Gravity_Forms\License\GF_License_API_Response|WP_Error
|
||||
*/
|
||||
public function update_current_site( $new_license_key_md5 ) {
|
||||
|
||||
$site_key = $this->get_site_key();
|
||||
$site_secret = $this->get_site_secret();
|
||||
if ( empty( $site_key ) || empty( $site_secret ) ) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$body = GFCommon::get_remote_post_params();
|
||||
$body['site_name'] = get_bloginfo( 'name' );
|
||||
$body['site_url'] = get_bloginfo( 'url' );
|
||||
$body['site_key'] = $site_key;
|
||||
$body['site_secret'] = $site_secret;
|
||||
$body['license_key_md5'] = $new_license_key_md5;
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . '(): refreshing license info' );
|
||||
|
||||
$result = $this->request( 'sites/' . $site_key, $body, 'PUT', array( 'headers' => $this->get_site_auth_header( $site_key, $site_secret ) ) );
|
||||
$result = $this->prepare_response_body( $result, true );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . '(): error updating site registration. ' . print_r( $result, true ) );
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/***
|
||||
* Removes a license key from a registered site. NOTE: It doesn't actually deregister the site.
|
||||
*
|
||||
* @deprecated Use gapi()->update_current_site('') instead.
|
||||
*
|
||||
* @return bool|WP_Error
|
||||
*/
|
||||
public function deregister_current_site() {
|
||||
|
||||
$site_key = $this->get_site_key();
|
||||
$site_secret = $this->get_site_secret();
|
||||
|
||||
if ( empty( $site_key ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . '(): deregistering' );
|
||||
|
||||
$body = array(
|
||||
'license_key_md5' => '',
|
||||
);
|
||||
|
||||
$result = $this->request( 'sites/' . $site_key, $body, 'PUT', array( 'headers' => $this->get_site_auth_header( $site_key, $site_secret ) ) );
|
||||
$result = $this->prepare_response_body( $result, true );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . '(): error updating site registration. ' . print_r( $result, true ) );
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the given license key to get its information from the API.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param string $key The license key.
|
||||
*
|
||||
* @return array|false|WP_Error
|
||||
*/
|
||||
public function check_license( $key ) {
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . '(): getting site and license info' );
|
||||
|
||||
$params = array(
|
||||
'site_url' => get_option( 'home' ),
|
||||
'is_multisite' => is_multisite(),
|
||||
);
|
||||
|
||||
$resource = 'licenses/' . $key . '/check?' . build_query( $params );
|
||||
$result = $this->request( $resource, null );
|
||||
$result = $this->prepare_response_body( $result, true );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . '(): error getting site and license information. ' . $result->get_error_message() );
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
$response = $result;
|
||||
|
||||
if ( rgar( $result, 'license' ) ) {
|
||||
$response = rgar( $result, 'license' );
|
||||
}
|
||||
|
||||
// Set the license object to the transient.
|
||||
set_transient( 'rg_gforms_license', $response, DAY_IN_SECONDS );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get GF core and add-on family information.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return false|array
|
||||
*/
|
||||
public function get_plugins_info() {
|
||||
$version_info = $this->get_version_info();
|
||||
|
||||
if ( empty( $version_info['offerings'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $version_info['offerings'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get version information from the Gravity Manager API.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param false $cache
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_version_info( $cache = false ) {
|
||||
|
||||
$version_info = null;
|
||||
|
||||
if ( $cache ) {
|
||||
$cached_info = get_option( 'gform_version_info' );
|
||||
|
||||
// Checking cache expiration
|
||||
$cache_duration = DAY_IN_SECONDS; // 24 hours.
|
||||
$cache_timestamp = $cached_info && isset( $cached_info['timestamp'] ) ? $cached_info['timestamp'] : 0;
|
||||
|
||||
// Is cache expired? If not, set $version_info to the cached data.
|
||||
if ( $cache_timestamp + $cache_duration >= time() ) {
|
||||
$version_info = $cached_info;
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_wp_error( $version_info ) || isset( $version_info['headers'] ) ) {
|
||||
// Legacy ( < 2.1.1.14 ) version info contained the whole raw response.
|
||||
$version_info = null;
|
||||
}
|
||||
|
||||
// If we reach this point with a $version_info array, it's from cache, and we can return it.
|
||||
if ( $version_info ) {
|
||||
return $version_info;
|
||||
}
|
||||
|
||||
//Getting version number
|
||||
$options = array(
|
||||
'method' => 'POST',
|
||||
'timeout' => 20,
|
||||
);
|
||||
|
||||
$options['headers'] = array(
|
||||
'Content-Type' => 'application/x-www-form-urlencoded; charset=' . get_option( 'blog_charset' ),
|
||||
'User-Agent' => 'WordPress/' . get_bloginfo( 'version' ),
|
||||
);
|
||||
|
||||
$options['body'] = GFCommon::get_remote_post_params();
|
||||
$options['timeout'] = 15;
|
||||
|
||||
$nocache = $cache ? '' : 'nocache=1'; //disabling server side caching
|
||||
|
||||
$raw_response = GFCommon::post_to_manager( 'version.php', $nocache, $options );
|
||||
$version_info = array(
|
||||
'is_valid_key' => '1',
|
||||
'version' => '',
|
||||
'url' => '',
|
||||
'is_error' => '1',
|
||||
);
|
||||
|
||||
if ( is_wp_error( $raw_response ) || rgars( $raw_response, 'response/code' ) != 200 ) {
|
||||
$version_info['timestamp'] = time();
|
||||
|
||||
return $version_info;
|
||||
}
|
||||
|
||||
$decoded = json_decode( $raw_response['body'], true );
|
||||
|
||||
if ( empty( $decoded ) ) {
|
||||
$version_info['timestamp'] = time();
|
||||
|
||||
return $version_info;
|
||||
}
|
||||
|
||||
$decoded['timestamp'] = time();
|
||||
|
||||
// Caching response.
|
||||
update_option( 'gform_version_info', $decoded, false ); //caching version info
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the usage data (call version.php in Gravity Manager). We will replace it once we have statistics API endpoints.
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
public function update_site_data() {
|
||||
|
||||
// Whenever we update the plugins info, we call the versions.php to update usage data.
|
||||
$options = array( 'method' => 'POST' );
|
||||
$options['headers'] = array(
|
||||
'Content-Type' => 'application/x-www-form-urlencoded; charset=' . get_option( 'blog_charset' ),
|
||||
'User-Agent' => 'WordPress/' . get_bloginfo( 'version' ),
|
||||
'Referer' => get_bloginfo( 'url' ),
|
||||
);
|
||||
$options['body'] = GFCommon::get_remote_post_params();
|
||||
// Set the version to 3 which lightens the burden of version.php, it won't return anything to us anymore.
|
||||
$options['body']['version'] = '3';
|
||||
$options['timeout'] = 15;
|
||||
|
||||
$nocache = 'nocache=1'; //disabling server side caching
|
||||
|
||||
GFCommon::post_to_manager( 'version.php', $nocache, $options );
|
||||
}
|
||||
|
||||
public function send_email_to_hubspot( $email ) {
|
||||
GFCommon::log_debug( __METHOD__ . '(): Sending installation wizard to hubspot.' );
|
||||
|
||||
$body = array(
|
||||
'email' => $email,
|
||||
);
|
||||
|
||||
$result = $this->request( 'emails/installation/add-to-list', $body, 'POST', array( 'headers' => $this->get_license_info_header( $site_secret ) ) );
|
||||
$result = $this->prepare_response_body( $result, true );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
GFCommon::log_debug( __METHOD__ . '(): error sending installation wizard to hubspot. ' . print_r( $result, true ) );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// # HELPERS
|
||||
|
||||
/**
|
||||
* @return false|mixed|void
|
||||
*/
|
||||
public function get_key() {
|
||||
return GFCommon::get_key();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $site_key
|
||||
* @param $site_secret
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function get_site_auth_header( $site_key, $site_secret ) {
|
||||
|
||||
$auth = base64_encode( "{$site_key}:{$site_secret}" );
|
||||
|
||||
return array( 'Authorization' => 'GravityAPI ' . $auth );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $site_secret
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function get_license_info_header( $site_secret ) {
|
||||
$auth = base64_encode( "gravityforms.com:{$site_secret}" );
|
||||
|
||||
return array( 'Authorization' => 'GravityAPI ' . $auth );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $license_key_md5
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function get_license_auth_header( $license_key_md5 ) {
|
||||
|
||||
$auth = base64_encode( "license:{$license_key_md5}" );
|
||||
|
||||
return array( 'Authorization' => 'GravityAPI ' . $auth );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare response body.
|
||||
*
|
||||
* @since unknown
|
||||
* @since 2.5 Support a WP_Error being returned.
|
||||
* @since 2.5 Allow results to be returned as array with second param.
|
||||
*
|
||||
* @param WP_Error|WP_REST_Response $raw_response The API response.
|
||||
* @param bool $as_array Whether to return the response as an array or object.
|
||||
*
|
||||
* @return array|object|WP_Error
|
||||
*/
|
||||
public function prepare_response_body( $raw_response, $as_array = false ) {
|
||||
|
||||
if ( is_wp_error( $raw_response ) ) {
|
||||
return $raw_response;
|
||||
}
|
||||
|
||||
$response_body = json_decode( wp_remote_retrieve_body( $raw_response ), $as_array );
|
||||
$response_code = wp_remote_retrieve_response_code( $raw_response );
|
||||
$response_message = wp_remote_retrieve_response_message( $raw_response );
|
||||
|
||||
if ( $response_code > 200 ) {
|
||||
|
||||
// If a WP_Error was returned in the body.
|
||||
if ( rgar( $response_body, 'code' ) ) {
|
||||
|
||||
// Restore the WP_Error.
|
||||
$error = new WP_Error( $response_body['code'], $response_body['message'], $response_body['data'] );
|
||||
} else {
|
||||
$error = new WP_Error( 'server_error', 'Error from server: ' . $response_message );
|
||||
}
|
||||
|
||||
return $error;
|
||||
|
||||
}
|
||||
|
||||
return $response_body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge the site credentials.
|
||||
*
|
||||
* @since unknown
|
||||
* @since 2.5 Added the deletion of the gf_site_registered option.
|
||||
*/
|
||||
public function purge_site_credentials() {
|
||||
|
||||
delete_option( 'gf_site_key' );
|
||||
delete_option( 'gf_site_secret' );
|
||||
delete_option( 'gf_site_registered' );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Making API requests.
|
||||
*
|
||||
* @since unknown
|
||||
* @since 2.5 Purge the registration data on site if certain errors matched.
|
||||
*
|
||||
* @param string $resource The API route.
|
||||
* @param array $body The request body.
|
||||
* @param string $method The method.
|
||||
* @param array $options The options.
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function request( $resource, $body, $method = 'POST', $options = array() ) {
|
||||
$body['timestamp'] = time();
|
||||
|
||||
// set default options
|
||||
$options = wp_parse_args( $options, array(
|
||||
'method' => $method,
|
||||
'timeout' => 10,
|
||||
'body' => in_array( $method, array( 'GET', 'DELETE' ) ) ? null : json_encode( $body ),
|
||||
'headers' => array(),
|
||||
'sslverify' => false,
|
||||
) );
|
||||
|
||||
// set default header options
|
||||
$options['headers'] = wp_parse_args( $options['headers'], array(
|
||||
'Content-Type' => 'application/json; charset=' . get_option( 'blog_charset' ),
|
||||
'User-Agent' => 'WordPress/' . get_bloginfo( 'version' ),
|
||||
'Referer' => get_bloginfo( 'url' ),
|
||||
) );
|
||||
|
||||
// WP docs say method should be uppercase
|
||||
$options['method'] = strtoupper( $options['method'] );
|
||||
|
||||
$request_url = $this->get_gravity_api_url() . $resource;
|
||||
|
||||
return wp_remote_request( $request_url, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|mixed|void
|
||||
*/
|
||||
public function get_site_key() {
|
||||
|
||||
if ( defined( 'GRAVITY_API_SITE_KEY' ) ) {
|
||||
return GRAVITY_API_SITE_KEY;
|
||||
}
|
||||
|
||||
$site_key = get_option( 'gf_site_key' );
|
||||
if ( empty( $site_key ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $site_key;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|mixed|void
|
||||
*/
|
||||
public function get_site_secret() {
|
||||
if ( defined( 'GRAVITY_API_SITE_SECRET' ) ) {
|
||||
return GRAVITY_API_SITE_SECRET;
|
||||
}
|
||||
$site_secret = get_option( 'gf_site_secret' );
|
||||
if ( empty( $site_secret ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $site_secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_gravity_api_url() {
|
||||
return trailingslashit( GRAVITY_API_URL );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the site has the gf_site_key and gf_site_secret options.
|
||||
*
|
||||
* @since unknown
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_site_registered() {
|
||||
return $this->get_site_key() && $this->get_site_secret();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the site has the gf_site_key, gf_site_secret and also the gf_site_registered options.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_legacy_registration() {
|
||||
|
||||
return $this->is_site_registered() && ! get_option( 'gf_site_registered' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function gapi() {
|
||||
return Gravity_Api::get_instance();
|
||||
}
|
||||
|
||||
gapi();
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,483 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms;
|
||||
|
||||
use GFCommon;
|
||||
|
||||
/**
|
||||
* Allows to download translations from TranslationsPress
|
||||
* This is a modified version of the library available at https://github.com/WP-Translations/t15s-registry
|
||||
* This version aims to be compatible with PHP 5.2, and supports only plugins.
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
class TranslationsPress_Updater {
|
||||
|
||||
const T15S_TRANSIENT_KEY = 't15s-registry-gforms';
|
||||
const T15S_API_URL = 'https://packages.translationspress.com/rocketgenius/packages.json';
|
||||
|
||||
/**
|
||||
* The plugin slug.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $slug = '';
|
||||
|
||||
/**
|
||||
* The locales installed during the current request.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $installed = array();
|
||||
|
||||
/**
|
||||
* Cached TranslationsPress data for all Rocketgenius plugins.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @var null|object
|
||||
*/
|
||||
private static $all_translations;
|
||||
|
||||
/**
|
||||
* The current instances of this class with the slugs as the keys.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @var TranslationsPress_Updater[]
|
||||
*/
|
||||
private static $_instances = array();
|
||||
|
||||
/**
|
||||
* Returns an instance of this class for the given slug.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @param string $slug The plugin slug.
|
||||
*
|
||||
* @return TranslationsPress_Updater
|
||||
*/
|
||||
public static function get_instance( $slug ) {
|
||||
if ( empty( self::$_instances[ $slug ] ) ) {
|
||||
self::$_instances[ $slug ] = new self( $slug );
|
||||
}
|
||||
|
||||
return self::$_instances[ $slug ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new project to load translations for.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param string $slug The plugin slug.
|
||||
* @param string $deprecated Not used. Previously, the locale to be installed.
|
||||
*/
|
||||
public function __construct( $slug, $deprecated = '' ) {
|
||||
$this->slug = $slug;
|
||||
|
||||
if ( 'gravityforms' === $slug ) {
|
||||
// Translations data for all Rocketgenius plugins is stored together so we only need to add this hook once.
|
||||
add_action( 'delete_site_transient_update_plugins', array( __CLASS__, 'refresh_all_translations' ) );
|
||||
}
|
||||
|
||||
add_action( 'gform_post_install', array( $this, 'install' ), 10, 0 );
|
||||
add_action( 'gform_post_upgrade', array( $this, 'install' ), 10, 0 );
|
||||
add_action( 'upgrader_process_complete', array( $this, 'upgrader_process_complete' ), 10, 2 );
|
||||
|
||||
add_filter( 'translations_api', array( $this, 'translations_api' ), 10, 3 );
|
||||
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'site_transient_update_plugins' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Short-circuits translations API requests for private projects.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param bool|array $result The result object. Default false.
|
||||
* @param string $requested_type The type of translations being requested.
|
||||
* @param object $args Translation API arguments.
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
public function translations_api( $result, $requested_type, $args ) {
|
||||
if ( 'plugins' !== $requested_type || $this->slug !== $args['slug'] ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $this->get_plugin_translations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the translations transients to include the current plugin.
|
||||
*
|
||||
* @see wp_get_translation_updates()
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param mixed $value The transient value.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function site_transient_update_plugins( $value ) {
|
||||
if ( ! $value ) {
|
||||
$value = new \stdClass();
|
||||
}
|
||||
|
||||
if ( ! isset( $value->translations ) ) {
|
||||
$value->translations = array();
|
||||
}
|
||||
|
||||
$translations = $this->get_plugin_translations();
|
||||
|
||||
if ( empty( $translations['translations'] ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
foreach ( $translations['translations'] as $translation ) {
|
||||
if ( ! $this->should_install( $translation ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$translation['type'] = 'plugin';
|
||||
$translation['slug'] = $this->slug;
|
||||
|
||||
$value->translations[] = $translation;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the TranslationsPress data for the current plugin.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_plugin_translations() {
|
||||
self::set_all_translations();
|
||||
|
||||
return (array) rgar( self::$all_translations->projects, $this->slug );
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the cached TranslationsPress data, if expired.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*/
|
||||
public static function refresh_all_translations() {
|
||||
static $done;
|
||||
|
||||
if ( $done ) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$all_translations = null;
|
||||
self::set_all_translations();
|
||||
$done = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the cached TranslationsPress data needs refreshing.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function is_transient_expired() {
|
||||
$cache_lifespan = 12 * HOUR_IN_SECONDS;
|
||||
|
||||
return ! isset( self::$all_translations->_last_checked ) || ( time() - self::$all_translations->_last_checked ) > $cache_lifespan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the translations data from the TranslationsPress API.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function get_remote_translations_data() {
|
||||
$result = json_decode( wp_remote_retrieve_body( wp_remote_get( self::T15S_API_URL, array( 'timeout' => 3 ) ) ), true );
|
||||
|
||||
return is_array( $result ) ? $result : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches the TranslationsPress data, if not already cached.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*/
|
||||
private static function set_all_translations() {
|
||||
if ( is_object( self::$all_translations ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$all_translations = get_site_transient( self::T15S_TRANSIENT_KEY );
|
||||
if ( is_object( self::$all_translations ) && ! self::is_transient_expired() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$all_translations = new \stdClass();
|
||||
self::$all_translations->projects = self::get_remote_translations_data();
|
||||
self::$all_translations->_last_checked = time();
|
||||
set_site_transient( self::T15S_TRANSIENT_KEY, self::$all_translations );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the translations for a given project.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @deprecated 2.5.6
|
||||
*
|
||||
* @param string $url Full GlotPress API URL for the project.
|
||||
*
|
||||
* @return array Translation data.
|
||||
*/
|
||||
public static function get_translations( $url ) {
|
||||
_deprecated_function( __METHOD__, '2.5.6', '\Gravity_Forms\Gravity_Forms\TranslationsPress_Updater::get_plugin_translations' );
|
||||
self::set_all_translations();
|
||||
|
||||
return self::$all_translations->projects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads and installs the translations for the specified plugin.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param string $slug The plugin slug.
|
||||
* @param string $locale The locale when the site locale is changed or an empty string to install all the user available locales.
|
||||
*/
|
||||
public static function download_package( $slug, $locale = '' ) {
|
||||
self::get_instance( $slug )->install( $locale );
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers translation installation, if required.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @param string $locale The locale when the site locale is changed or an empty string to install all the user available locales.
|
||||
*/
|
||||
public function install( $locale = '' ) {
|
||||
if ( $locale && in_array( $locale, $this->installed ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$translations = $this->get_plugin_translations();
|
||||
|
||||
if ( empty( $translations['translations'] ) ) {
|
||||
GFCommon::log_error( __METHOD__ . sprintf( '(): Aborting; No translations list for %s.', $this->slug ) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $translations['translations'] as $translation ) {
|
||||
if ( ! $this->should_install( $translation, $locale ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->install_translation( $translation );
|
||||
|
||||
if ( $locale ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads and installs the given translation.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @param array $translation The translation data.
|
||||
*/
|
||||
private function install_translation( $translation ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
if ( ! $wp_filesystem ) {
|
||||
require_once ABSPATH . '/wp-admin/includes/admin.php';
|
||||
|
||||
// Same approach as in WP Core: https://github.com/WordPress/wordpress-develop/blob/6.2/src/wp-includes/rest-api/endpoints/class-wp-rest-plugins-controller.php#L853-L869.
|
||||
ob_start();
|
||||
$filesystem_credentials_available = request_filesystem_credentials( self_admin_url() );
|
||||
ob_end_clean();
|
||||
|
||||
if ( ! $filesystem_credentials_available ) {
|
||||
GFCommon::log_error( __METHOD__ . '(): Aborting; filesystem credentials required.' );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! \WP_Filesystem() ) {
|
||||
GFCommon::log_error( __METHOD__ . '(): Aborting; unable to init WP_Filesystem.' );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$lang_dir = $this->get_path();
|
||||
if ( ! $wp_filesystem->is_dir( $lang_dir ) ) {
|
||||
$wp_filesystem->mkdir( $lang_dir, FS_CHMOD_DIR );
|
||||
}
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . '(): Downloading: ' . $translation['package'] );
|
||||
$temp_file = download_url( $translation['package'] );
|
||||
|
||||
if ( is_wp_error( $temp_file ) ) {
|
||||
GFCommon::log_error( __METHOD__ . '(): Error downloading package. Code: ' . $temp_file->get_error_code() . '; Message: ' . $temp_file->get_error_message() );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$zip_path = $lang_dir . $this->slug . '-' . $translation['language'] . '.zip';
|
||||
$copy_result = $wp_filesystem->copy( $temp_file, $zip_path, true, FS_CHMOD_FILE );
|
||||
$wp_filesystem->delete( $temp_file );
|
||||
|
||||
if ( ! $copy_result ) {
|
||||
GFCommon::log_error( __METHOD__ . '(): Unable to move package to: ' . $lang_dir );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$result = unzip_file( $zip_path, $lang_dir );
|
||||
@unlink( $zip_path );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
GFCommon::log_error( __METHOD__ . '(): Error extracting package. Code: ' . $result->get_error_code() . '; Message: ' . $result->get_error_message() );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GFCommon::log_debug( __METHOD__ . sprintf( '(): Installed %s translation for %s.', $translation['language'], $this->slug ) );
|
||||
$this->installed[] = $translation['language'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs which locales WordPress installs translations for.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @param object $upgrader_object WP_Upgrader Instance.
|
||||
* @param array $hook_extra Item update data.
|
||||
*/
|
||||
public function upgrader_process_complete( $upgrader_object, $hook_extra ) {
|
||||
if ( rgar( $hook_extra, 'type' ) !== 'translation' || empty( $hook_extra['translations'] ) || empty( $upgrader_object->result ) || is_wp_error( $upgrader_object->result ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$locales = array();
|
||||
|
||||
foreach ( $hook_extra['translations'] as $translation ) {
|
||||
if ( rgar( $translation, 'type' ) !== 'plugin' || rgar( $translation, 'slug' ) !== $this->slug ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$locales[] = $translation['language'];
|
||||
}
|
||||
|
||||
if ( empty( $locales ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->installed = $locales;
|
||||
GFCommon::log_debug( __METHOD__ . sprintf( '(): WordPress installed %s translation(s) for %s.', implode( ', ', $locales ), $this->slug ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of locales the site has installed.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_available_languages() {
|
||||
static $languages = array();
|
||||
|
||||
if ( empty( $languages ) ) {
|
||||
$languages = get_available_languages();
|
||||
}
|
||||
|
||||
return $languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header data from the installed translations for the current plugin.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_installed_translations_data() {
|
||||
static $data = array();
|
||||
|
||||
if ( isset( $data[ $this->slug ] ) ) {
|
||||
return $data[ $this->slug ];
|
||||
}
|
||||
|
||||
$data[ $this->slug ] = array();
|
||||
$translations = GFCommon::get_installed_translations( $this->slug, true );
|
||||
|
||||
foreach ( $translations as $locale => $mo_file ) {
|
||||
$po_file = str_replace( '.mo', '.po', $mo_file );
|
||||
if ( ! file_exists( $po_file ) ) {
|
||||
continue;
|
||||
}
|
||||
$data[ $this->slug ][ $locale ] = wp_get_pomo_file_data( $po_file );
|
||||
}
|
||||
|
||||
return $data[ $this->slug ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to where plugin translations are stored.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_path() {
|
||||
return WP_LANG_DIR . '/plugins/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a translation should be installed.
|
||||
*
|
||||
* @since 2.5.6
|
||||
*
|
||||
* @param array $translation The translation data.
|
||||
* @param string $locale The locale when the site locale is changed or an empty string to check all the user available locales.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function should_install( $translation, $locale = '' ) {
|
||||
if ( ( $locale && $locale !== $translation['language'] ) || ! in_array( $translation['language'], $this->get_available_languages() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $translation['updated'] ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$installed = $this->get_installed_translations_data();
|
||||
|
||||
if ( ! isset( $installed[ $translation['language'] ] ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$local = date_create( $installed[ $translation['language'] ]['PO-Revision-Date'] );
|
||||
$remote = date_create( $translation['updated'] );
|
||||
|
||||
return $remote > $local;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TranslationsPress_Updater::get_instance( 'gravityforms' );
|
||||
@@ -1,95 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Collection;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Configurator;
|
||||
|
||||
/**
|
||||
* Config items for app registration, including helper methods.
|
||||
*
|
||||
* @since 2.7.1
|
||||
*/
|
||||
class GF_App_Config extends GF_Config {
|
||||
|
||||
/**
|
||||
* The name of the app, in slug form.
|
||||
*
|
||||
* @var string $app_name
|
||||
*/
|
||||
private $app_name;
|
||||
|
||||
/**
|
||||
* The condition for enqueuing the app data.
|
||||
*
|
||||
* @var bool|callable $display_condition
|
||||
*/
|
||||
private $display_condition;
|
||||
|
||||
/**
|
||||
* The CSS assets to enqueue.
|
||||
*
|
||||
* @var array $css_asset
|
||||
*/
|
||||
private $css_asset;
|
||||
|
||||
/**
|
||||
* The relative path to the chunk in JS.
|
||||
*
|
||||
* @var string $chunk
|
||||
*/
|
||||
private $chunk;
|
||||
|
||||
/**
|
||||
* The root element to use to load the app.
|
||||
*
|
||||
* @var string $root_element
|
||||
*/
|
||||
private $root_element;
|
||||
|
||||
/**
|
||||
* Set the data for this app config.
|
||||
*
|
||||
* @since 2.7.1
|
||||
*
|
||||
* @param $data
|
||||
*/
|
||||
public function set_data( $data ) {
|
||||
$this->name = $data['object_name'];
|
||||
$this->script_to_localize = $data['script_name'];
|
||||
$this->app_name = $data['app_name'];
|
||||
|
||||
$this->display_condition = $data['enqueue'];
|
||||
$this->chunk = $data['chunk'];
|
||||
$this->root_element = $data['root_element'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we should enqueue this data.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function should_enqueue() {
|
||||
return is_admin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
return array(
|
||||
'apps' => array(
|
||||
$this->app_name => array(
|
||||
'should_display' => is_callable( $this->display_condition ) ? call_user_func( $this->display_condition ) : $this->display_condition,
|
||||
'chunk_path' => $this->chunk,
|
||||
'root_element' => $this->root_element,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
|
||||
/**
|
||||
* Collection to hold GF_Config items and provide their structured data when needed.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Config
|
||||
*/
|
||||
class GF_Config_Collection {
|
||||
|
||||
/**
|
||||
* @var GF_Config[] $configs
|
||||
*/
|
||||
private $configs = array();
|
||||
|
||||
/**
|
||||
* Add a config to the collection.
|
||||
*
|
||||
* @param GF_Config $config
|
||||
*/
|
||||
public function add_config( GF_Config $config ) {
|
||||
$this->configs[] = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle outputting the config data.
|
||||
*
|
||||
* If $localize is true, data is actually localized via `wp_localize_script`, otherwise
|
||||
* data is simply returned as an array.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param bool $localize Whether to localize the data, or simply return it.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function handle( $localize = true ) {
|
||||
$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 );
|
||||
$data_to_localize = array_merge( $data_to_localize, $item_data );
|
||||
}
|
||||
|
||||
return $data_to_localize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Localize the data for the given script.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param string $script
|
||||
* @param GF_Config[] $items
|
||||
*/
|
||||
private function localize_data_for_script( $script, $items, $localize = true ) {
|
||||
$data = array();
|
||||
|
||||
foreach ( $items as $name => $configs ) {
|
||||
$localized_data = $this->get_merged_data_for_object( $configs );
|
||||
|
||||
/**
|
||||
* Allows users to filter the data localized for a given script/resource.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $localized_data The current localize data
|
||||
* @param string $script The script being localized
|
||||
* @param array $configs An array of $configs being applied to this script
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
$localized_data = apply_filters( 'gform_localized_script_data_' . $name, $localized_data, $script, $configs );
|
||||
|
||||
$data[ $name ] = $localized_data;
|
||||
|
||||
if ( $localize ) {
|
||||
wp_localize_script( $script, $name, $localized_data );
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the merged data object for the applicable configs. Will process each config by its
|
||||
* $priority property, overriding or merging values as needed.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Config[] $configs
|
||||
*/
|
||||
private function get_merged_data_for_object( $configs ) {
|
||||
// Squash warnings for PHP < 7.0 when running tests.
|
||||
@usort( $configs, array( $this, 'sort_by_priority' ) );
|
||||
|
||||
$data = array();
|
||||
|
||||
foreach ( $configs as $config ) {
|
||||
|
||||
// Config is set to overwrite data - simply return its value without attempting to merge.
|
||||
if ( $config->should_overwrite() ) {
|
||||
$data = $config->get_data();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Config should be merged - loop through each key and attempt to recursively merge the values.
|
||||
foreach ( $config->get_data() as $key => $value ) {
|
||||
$existing = isset( $data[ $key ] ) ? $data[ $key ] : null;
|
||||
|
||||
if ( is_null( $existing ) || ! is_array( $existing ) || ! is_array( $value ) ) {
|
||||
$data[ $key ] = $value;
|
||||
continue;
|
||||
}
|
||||
|
||||
$data[ $key ] = array_merge_recursive( $existing, $value );
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate configs, organized by the script they belong to.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_configs_by_script() {
|
||||
$data_to_localize = array();
|
||||
|
||||
foreach ( $this->configs as $config ) {
|
||||
if ( ( ! defined( 'GFORMS_DOING_MOCK' ) || ! GFORMS_DOING_MOCK ) && ! $config->should_enqueue() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data_to_localize[ $config->script_to_localize() ][ $config->name() ][] = $config;
|
||||
}
|
||||
|
||||
return $data_to_localize;
|
||||
}
|
||||
|
||||
/**
|
||||
* usort() callback to sort the configs by their $priority.
|
||||
*
|
||||
* @param GF_Config $a
|
||||
* @param GF_Config $b
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_by_priority( GF_Config $a, GF_Config $b ) {
|
||||
if ( $a->priority() === $b->priority() ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $a->priority() < $b->priority() ? - 1 : 1;
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config;
|
||||
|
||||
/**
|
||||
* Parses a given data array to return either Live or Mock values, depending on the
|
||||
* environment and context.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Config
|
||||
*/
|
||||
class GF_Config_Data_Parser {
|
||||
|
||||
/**
|
||||
* Parse the given $data array and get the correct values for the context.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function parse( $data ) {
|
||||
$return = array();
|
||||
|
||||
foreach( $data as $key => $value ) {
|
||||
$return[ $key ] = $this->get_correct_value( $value );
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop through each array key and get the correct value. Is called recursively for
|
||||
* nested arrays.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
private function get_correct_value( $value ) {
|
||||
|
||||
// Value isn't array - we've reached the final level for this branch.
|
||||
if ( ! is_array( $value ) ) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
// Value is an array with our defined value and default keys. Return either live or mock data.
|
||||
if ( array_key_exists( 'default', $value ) && array_key_exists( 'value', $value ) ) {
|
||||
return $this->is_mock() ? $value['default'] : $value['value'];
|
||||
}
|
||||
|
||||
$data = array();
|
||||
|
||||
// Value is an array - recursively call this method to dig into each level and return the correct value.
|
||||
foreach( $value as $key => $value ) {
|
||||
$data[ $key ] = $this->get_correct_value( $value );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the current environmental context is a Mock context.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_mock() {
|
||||
return defined( 'GFORMS_DOING_MOCK' ) && GFORMS_DOING_MOCK;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,209 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\Items\GF_Config_Admin_I18n;
|
||||
use Gravity_Forms\Gravity_Forms\Config\Items\GF_Config_Block_Editor;
|
||||
use Gravity_Forms\Gravity_Forms\Config\Items\GF_Config_Global;
|
||||
use Gravity_Forms\Gravity_Forms\Config\Items\GF_Config_I18n;
|
||||
use Gravity_Forms\Gravity_Forms\Config\Items\GF_Config_Legacy_Check;
|
||||
use Gravity_Forms\Gravity_Forms\Config\Items\GF_Config_Legacy_Check_Multi;
|
||||
use Gravity_Forms\Gravity_Forms\Config\Items\GF_Config_Multifile;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
|
||||
|
||||
/**
|
||||
* Class GF_Config_Service_Provider
|
||||
*
|
||||
* Service provider for the Config Service.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Config
|
||||
*/
|
||||
class GF_Config_Service_Provider extends GF_Service_Provider {
|
||||
|
||||
// Organizational services
|
||||
const CONFIG_COLLECTION = 'config_collection';
|
||||
const DATA_PARSER = 'data_parser';
|
||||
|
||||
// Config services
|
||||
const I18N_CONFIG = 'i18n_config';
|
||||
const I18N_ADMIN_CONFIG = 'i18n_admin_config';
|
||||
const LEGACY_CONFIG = 'legacy_config';
|
||||
const LEGACY_MULTI_CONFIG = 'legacy_multi_config';
|
||||
const MULTIFILE_CONFIG = 'multifile_config';
|
||||
const BLOCK_EDITOR_CONFIG = 'block_editor_config';
|
||||
const GLOBAL_CONFIG = 'global_config';
|
||||
|
||||
/**
|
||||
* Array mapping config class names to their container ID.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $configs = array(
|
||||
self::I18N_CONFIG => GF_Config_I18n::class,
|
||||
self::I18N_ADMIN_CONFIG => GF_Config_Admin_I18n::class,
|
||||
self::LEGACY_CONFIG => GF_Config_Legacy_Check::class,
|
||||
self::LEGACY_MULTI_CONFIG => GF_Config_Legacy_Check_Multi::class,
|
||||
self::MULTIFILE_CONFIG => GF_Config_Multifile::class,
|
||||
self::BLOCK_EDITOR_CONFIG => GF_Config_Block_Editor::class,
|
||||
);
|
||||
|
||||
/**
|
||||
* Register services to the container.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*/
|
||||
public function register( GF_Service_Container $container ) {
|
||||
|
||||
// Include required files.
|
||||
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-config-collection.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-config.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-config-data-parser.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . 'class-gf-app-config.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . 'items/class-gf-config-global.php' );
|
||||
|
||||
// Add to container
|
||||
$container->add( self::CONFIG_COLLECTION, function () {
|
||||
return new GF_Config_Collection();
|
||||
} );
|
||||
|
||||
$container->add( self::DATA_PARSER, function () {
|
||||
return new GF_Config_Data_Parser();
|
||||
} );
|
||||
|
||||
$container->add( self::GLOBAL_CONFIG, function () {
|
||||
return new GF_Config_Global();
|
||||
} );
|
||||
|
||||
// Add configs to container.
|
||||
$this->register_config_items( $container );
|
||||
$this->register_configs_to_collection( $container );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiailize any actions or hooks.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init( GF_Service_Container $container ) {
|
||||
|
||||
// Need to pass $this to callbacks; save as variable.
|
||||
$self = $this;
|
||||
|
||||
add_action( 'wp_enqueue_scripts', function () use ( $container ) {
|
||||
$container->get( self::CONFIG_COLLECTION )->handle();
|
||||
}, 9999 );
|
||||
|
||||
add_action( 'admin_enqueue_scripts', function () use ( $container ) {
|
||||
$container->get( self::CONFIG_COLLECTION )->handle();
|
||||
}, 9999 );
|
||||
|
||||
add_action( 'gform_preview_init', function () use ( $container ) {
|
||||
$container->get( self::CONFIG_COLLECTION )->handle();
|
||||
}, 0 );
|
||||
|
||||
add_action( 'rest_api_init', function () use ( $container, $self ) {
|
||||
register_rest_route( 'gravityforms/v2', '/tests/mock-data', array(
|
||||
'methods' => 'GET',
|
||||
'callback' => array( $self, 'config_mocks_endpoint' ),
|
||||
'permission_callback' => function () {
|
||||
return true;
|
||||
},
|
||||
) );
|
||||
} );
|
||||
|
||||
// Add global config data to admin and theme.
|
||||
add_filter( 'gform_localized_script_data_gform_admin_config', function ( $data ) use ( $self ) {
|
||||
return $self->add_global_config_data( $data );
|
||||
} );
|
||||
|
||||
add_filter( 'gform_localized_script_data_gform_theme_config', function ( $data ) use ( $self ) {
|
||||
return $self->add_global_config_data( $data );
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* For each config defined in $configs, instantiate and add to container.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function register_config_items( GF_Service_Container $container ) {
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/items/class-gf-config-i18n.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/items/class-gf-config-admin-i18n.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/items/class-gf-config-legacy-check.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/items/class-gf-config-legacy-check-multi.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/items/class-gf-config-multifile.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/items/class-gf-config-block-editor.php' );
|
||||
|
||||
$parser = $container->get( self::DATA_PARSER );
|
||||
|
||||
foreach ( $this->configs as $name => $class ) {
|
||||
$container->add( $name, function () use ( $class, $parser ) {
|
||||
return new $class( $parser );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register each config defined in $configs to the GF_Config_Collection.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_configs_to_collection( GF_Service_Container $container ) {
|
||||
$collection = $container->get( self::CONFIG_COLLECTION );
|
||||
|
||||
foreach ( $this->configs as $name => $config ) {
|
||||
$config_class = $container->get( $name );
|
||||
$collection->add_config( $config_class );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the Config Mocks REST endpoint.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function config_mocks_endpoint() {
|
||||
define( 'GFORMS_DOING_MOCK', true );
|
||||
$container = \GFForms::get_service_container();
|
||||
$data = $container->get( self::CONFIG_COLLECTION )->handle( false );
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add global data to both admin and theme configs so that it is available everywhere
|
||||
* within the system.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_global_config_data( $data ) {
|
||||
$container = \GFForms::get_service_container();
|
||||
$global = $container->get( self::GLOBAL_CONFIG )->data();
|
||||
|
||||
return array_merge( $data, $global );
|
||||
}
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config;
|
||||
|
||||
/**
|
||||
* Base class for providing advanced functionality when localizing Config Data
|
||||
* for usage in Javascript.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Config
|
||||
*/
|
||||
abstract class GF_Config {
|
||||
|
||||
/**
|
||||
* The Data Parser
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var GF_Config_Data_Parser
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
* The data for this config object.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* The object name for this config.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* The ID of the script to localize the data to.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $script_to_localize;
|
||||
|
||||
/**
|
||||
* The priority of this config - can be used to control the order in
|
||||
* which configs are processed in the Collection.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $priority = 0;
|
||||
|
||||
/**
|
||||
* Whether the config should enqueue it's data. Can also be handled by overriding the
|
||||
* ::should_enqueue() method.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $should_enqueue = true;
|
||||
|
||||
/**
|
||||
* Whether this config should overwrite previous values in the object.
|
||||
*
|
||||
* If set to "true", the object will be overwritten by the values provided here.
|
||||
* If set to "false", the object will have its values merged with those defined here, recursively.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $overwrite = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param GF_Config_Data_Parser $parser
|
||||
*/
|
||||
public function __construct( GF_Config_Data_Parser $parser ) {
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to handle defining the data array for this config.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function data();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_enqueue() {
|
||||
if ( is_callable( $this->should_enqueue ) ) {
|
||||
return call_user_func( $this->should_enqueue );
|
||||
}
|
||||
|
||||
return $this->should_enqueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for the config, passing it through a filter.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_data() {
|
||||
if ( ( ! defined( 'GFORMS_DOING_MOCK' ) || ! GFORMS_DOING_MOCK ) && ! $this->should_enqueue() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows developers to modify the raw config data being sent to the Config Parser. Useful for
|
||||
* adding in custom default/mock values for a given entry in the data, as well as modifying
|
||||
* things like callbacks for dynamic data before it's parsed and localized.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $data
|
||||
* @param string $script_to_localize
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
$data = apply_filters( 'gform_config_data_' . $this->name(), $this->data(), $this->script_to_localize() );
|
||||
|
||||
return $this->parser->parse( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the config's object.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the $priority for the config.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function priority() {
|
||||
return $this->priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the script to localize.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function script_to_localize() {
|
||||
return $this->script_to_localize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the config should override previous values.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_overwrite() {
|
||||
return $this->overwrite;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config\Items;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Collection;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Configurator;
|
||||
|
||||
/**
|
||||
* Config items for Admin I18N
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
class GF_Config_Admin_I18n extends GF_Config {
|
||||
|
||||
protected $name = 'gform_admin_i18n';
|
||||
protected $script_to_localize = 'gform_gravityforms_admin_vendors';
|
||||
|
||||
/**
|
||||
* Whether we should enqueue this data.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return bool|mixed
|
||||
*/
|
||||
public function should_enqueue() {
|
||||
return is_admin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
return array(
|
||||
// named sub objects that match the admin js file name (camelCased) they are localizing
|
||||
'formAdmin' => array(
|
||||
'toggleFeedInactive' => esc_html__( 'Inactive', 'gravityforms' ),
|
||||
'toggleFeedActive' => esc_html__( 'Active', 'gravityforms' ),
|
||||
),
|
||||
'shortcodeUi' => array(
|
||||
'editForm' => esc_html__( 'Edit Form', 'gravityforms' ),
|
||||
'insertForm' => esc_html__( 'Insert Form', 'gravityforms' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config\Items;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Collection;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Configurator;
|
||||
|
||||
/**
|
||||
* Config items for the Block Editor.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
class GF_Config_Block_Editor extends GF_Config {
|
||||
|
||||
protected $name = 'gform_admin_config';
|
||||
protected $script_to_localize = 'gform_gravityforms_admin_vendors';
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
return array(
|
||||
'block_editor' => array(
|
||||
'data' => array(
|
||||
'is_block_editor' => \GFCommon::is_block_editor_page(),
|
||||
),
|
||||
'i18n' => array(
|
||||
'insert_gform_block_title' => __( 'Add Block To Page', 'gravityforms' ),
|
||||
'insert_gform_block_content' => __( 'Click or drag the Gravity Forms Block into the page to insert the form you selected. %1$sLearn More.%2$s', 'gravityforms' ),
|
||||
),
|
||||
'urls' => array(
|
||||
'block_docs' => 'https://docs.gravityforms.com/gravity-forms-gutenberg-block/',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config\Items;
|
||||
|
||||
/**
|
||||
* Acts as a container for any Global Config data we need to send to both
|
||||
* the admin and theme side of the ecosystem.
|
||||
*
|
||||
* @since 2.7
|
||||
*/
|
||||
class GF_Config_Global {
|
||||
|
||||
/**
|
||||
* The data to send to both configs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function data() {
|
||||
return array(
|
||||
'hmr_dev' => defined( 'GF_ENABLE_HMR' ) && GF_ENABLE_HMR,
|
||||
'public_path' => trailingslashit( \GFCommon::get_base_url() ) . 'assets/js/dist/',
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config\Items;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Collection;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Configurator;
|
||||
|
||||
/**
|
||||
* Config items for Theme I18N
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
class GF_Config_I18n extends GF_Config {
|
||||
|
||||
protected $name = 'gform_i18n';
|
||||
protected $script_to_localize = 'gform_gravityforms';
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
return array(
|
||||
'datepicker' => array(
|
||||
'days' => array(
|
||||
'monday' => esc_html__( 'Mo', 'gravityforms' ),
|
||||
'tuesday' => esc_html__( 'Tu', 'gravityforms' ),
|
||||
'wednesday' => esc_html__( 'We', 'gravityforms' ),
|
||||
'thursday' => esc_html__( 'Th', 'gravityforms' ),
|
||||
'friday' => esc_html__( 'Fr', 'gravityforms' ),
|
||||
'saturday' => esc_html__( 'Sa', 'gravityforms' ),
|
||||
'sunday' => esc_html__( 'Su', 'gravityforms' ),
|
||||
),
|
||||
'months' => array(
|
||||
'january' => esc_html__( 'January', 'gravityforms' ),
|
||||
'february' => esc_html__( 'February', 'gravityforms' ),
|
||||
'march' => esc_html__( 'March', 'gravityforms' ),
|
||||
'april' => esc_html__( 'April', 'gravityforms' ),
|
||||
'may' => esc_html__( 'May', 'gravityforms' ),
|
||||
'june' => esc_html__( 'June', 'gravityforms' ),
|
||||
'july' => esc_html__( 'July', 'gravityforms' ),
|
||||
'august' => esc_html__( 'August', 'gravityforms' ),
|
||||
'september' => esc_html__( 'September', 'gravityforms' ),
|
||||
'october' => esc_html__( 'October', 'gravityforms' ),
|
||||
'november' => esc_html__( 'November', 'gravityforms' ),
|
||||
'december' => esc_html__( 'December', 'gravityforms' ),
|
||||
),
|
||||
'firstDay' => array(
|
||||
'value' => absint( get_option( 'start_of_week' ) ),
|
||||
'default' => 1,
|
||||
),
|
||||
'iconText' => esc_html__( 'Select date', 'gravityforms' ),
|
||||
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config\Items;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Collection;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Configurator;
|
||||
|
||||
/**
|
||||
* Config items for Multi Legacy Check (mostly just data from a filter).
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
class GF_Config_Legacy_Check_Multi extends GF_Config {
|
||||
|
||||
protected $name = 'gf_legacy_multi';
|
||||
protected $script_to_localize = 'gform_gravityforms';
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
/**
|
||||
* Allows users to filter the legacy checks for any form on the page.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array
|
||||
*/
|
||||
return apply_filters( 'gform_gf_legacy_multi', array() );
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config\Items;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Collection;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Configurator;
|
||||
|
||||
/**
|
||||
* Config items for Theme Legacy Checks.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
class GF_Config_Legacy_Check extends GF_Config {
|
||||
|
||||
protected $name = 'gf_legacy';
|
||||
protected $script_to_localize = 'gform_layout_editor';
|
||||
|
||||
/**
|
||||
* Determine if the config should enqueue its data.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_enqueue() {
|
||||
return \GFCommon::is_form_editor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
$form = \RGFormsModel::get_form_meta( rgget( 'id' ) );
|
||||
|
||||
return array(
|
||||
'is_legacy' => array(
|
||||
'value' => \GFCommon::is_legacy_markup_enabled( $form ),
|
||||
'default' => 0,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Config\Items;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Configurator;
|
||||
|
||||
/**
|
||||
* Config items for Multifile Strings
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
class GF_Config_Multifile extends GF_Config {
|
||||
|
||||
protected $script_to_localize = 'gform_gravityforms';
|
||||
protected $name = 'gform_gravityforms';
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
return array(
|
||||
'strings' => array(
|
||||
'invalid_file_extension' => wp_strip_all_tags( __( 'This type of file is not allowed. Must be one of the following: ', 'gravityforms' ) ),
|
||||
'delete_file' => wp_strip_all_tags( __( 'Delete this file', 'gravityforms' ) ),
|
||||
'in_progress' => wp_strip_all_tags( __( 'in progress', 'gravityforms' ) ),
|
||||
'file_exceeds_limit' => wp_strip_all_tags( __( 'File exceeds size limit', 'gravityforms' ) ),
|
||||
'illegal_extension' => wp_strip_all_tags( __( 'This type of file is not allowed.', 'gravityforms' ) ),
|
||||
'max_reached' => wp_strip_all_tags( __( 'Maximum number of files reached', 'gravityforms' ) ),
|
||||
'unknown_error' => wp_strip_all_tags( __( 'There was a problem while saving the file on the server', 'gravityforms' ) ),
|
||||
'currently_uploading' => wp_strip_all_tags( __( 'Please wait for the uploading to complete', 'gravityforms' ) ),
|
||||
'cancel' => wp_strip_all_tags( __( 'Cancel', 'gravityforms' ) ),
|
||||
'cancel_upload' => wp_strip_all_tags( __( 'Cancel this upload', 'gravityforms' ) ),
|
||||
'cancelled' => wp_strip_all_tags( __( 'Cancelled', 'gravityforms' ) )
|
||||
),
|
||||
'vars' => array(
|
||||
'images_url' => \GFCommon::get_base_url() . '/images'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Handles logic for duplicate submission prevention services.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Duplicate_Submissions
|
||||
*/
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Duplicate_Submissions;
|
||||
|
||||
/**
|
||||
* Class GF_Duplicate_Submissions_Handler
|
||||
*
|
||||
* @since 2.9.1
|
||||
*
|
||||
* Provides functionality for handling duplicate submissions while avoiding multiple
|
||||
* entries being submitted.
|
||||
*/
|
||||
class GF_Duplicate_Submissions_Handler {
|
||||
|
||||
/**
|
||||
* The URL parameter used for redirect protection in Safari.
|
||||
*/
|
||||
const SAFARI_REDIRECT_PARAM = 'gf_protect_submission';
|
||||
|
||||
/**
|
||||
* The base URL for this plugin
|
||||
*
|
||||
* @var string $base_url.
|
||||
*/
|
||||
private $base_url;
|
||||
|
||||
/**
|
||||
* GF_Duplicate_Submissions_Handler constructor.
|
||||
*
|
||||
* @param string $base_url The Base URL for this Plugin.
|
||||
*/
|
||||
public function __construct( $base_url ) {
|
||||
$this->base_url = $base_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if duplicate submission protection is enabled. false otherwise.
|
||||
*
|
||||
* @returns bool $is_enabled true if duplicate protection is active/enabled. false otherwise
|
||||
*/
|
||||
public function is_enabled() {
|
||||
|
||||
$form_id = filter_input( INPUT_POST, 'gform_submit', FILTER_SANITIZE_NUMBER_INT );
|
||||
|
||||
if ( empty( $form_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows users to disable duplicate submissions protection, either globally
|
||||
* or on a form-by-form basis.
|
||||
*
|
||||
* @since 2.5.15
|
||||
*
|
||||
* @param bool Passes a false value by default.
|
||||
* @param int|string Passes the current form ID.
|
||||
*/
|
||||
$is_disabled = gf_apply_filters( array( 'gform_is_disabled_duplicate_submissions_protection', $form_id ), false, $form_id );
|
||||
|
||||
return ! $is_disabled;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the JS file if this is a form submission configured for duplicate protection.
|
||||
*/
|
||||
public function maybe_enqueue_scripts() {
|
||||
|
||||
if ( $this->is_enabled() ) {
|
||||
$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG || isset( $_GET['gform_debug'] ) ? '' : '.min';
|
||||
wp_enqueue_script( 'gform_duplicate_submissions', $this->base_url . "/js/duplicate-submissions{$min}.js", array(), true );
|
||||
wp_localize_script( 'gform_duplicate_submissions', 'gf_duplicate_submissions', $this->get_localized_script_data() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correct data to localize to the JS file.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_localized_script_data() {
|
||||
return array(
|
||||
'is_gf_submission' => (int) $this->is_valid_submission(),
|
||||
'safari_redirect_param' => self::SAFARI_REDIRECT_PARAM,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current submission exists, and is valid.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_valid_submission() {
|
||||
$form_id = filter_input( INPUT_POST, 'gform_submit', FILTER_SANITIZE_NUMBER_INT );
|
||||
|
||||
if ( empty( $form_id ) || ! class_exists( '\GFFormDisplay' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$entry_id = rgars( \GFFormDisplay::$submission, $form_id . '/lead/id' );
|
||||
|
||||
if ( empty( $entry_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
\GFCommon::log_debug( __METHOD__ . sprintf( '(): form #%d. entry #%d.', $form_id, $entry_id ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to a $_GET request if we detect a dupe submission from Safari.
|
||||
*/
|
||||
public function maybe_handle_safari_redirect() {
|
||||
if ( rgget( self::SAFARI_REDIRECT_PARAM ) != '1' || ! $this->is_enabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the submission URL from the $_SERVER, and strip out our redirect param.
|
||||
$submission_url = filter_input( INPUT_SERVER, 'HTTP_REFERER', FILTER_SANITIZE_URL );
|
||||
$base_url = esc_url( remove_query_arg( self::SAFARI_REDIRECT_PARAM, $submission_url ) );
|
||||
|
||||
// Redirect to the form's page URL as a GET request.
|
||||
wp_safe_redirect( $base_url, 303 );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Service Provider for Duplicate Submission Service
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Duplicate_Submissions
|
||||
*/
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Duplicate_Submissions;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Class GF_License_Service_Provider
|
||||
*
|
||||
* Service provider for the Duplicate Submission Service.
|
||||
*/
|
||||
class GF_Duplicate_Submissions_Service_Provider extends GF_Service_Provider {
|
||||
|
||||
const GF_DUPLICATE_SUBMISSION_HANDLER = 'gf_duplicate_submission_handler';
|
||||
|
||||
/**
|
||||
* Includes all related files and adds all containers.
|
||||
*
|
||||
* @param GF_Service_Container $container Container singleton object.
|
||||
*/
|
||||
public function register( GF_Service_Container $container ) {
|
||||
\GFForms::include_gravity_api();
|
||||
|
||||
require_once plugin_dir_path( __FILE__ ) . 'class-gf-duplicate-submissions-handler.php';
|
||||
|
||||
$container->add(
|
||||
self::GF_DUPLICATE_SUBMISSION_HANDLER,
|
||||
function () {
|
||||
return new GF_Duplicate_Submissions_Handler( \GFCommon::get_base_url() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes service.
|
||||
*
|
||||
* @param GF_Service_Container $container Service Container.
|
||||
*/
|
||||
public function init( GF_Service_Container $container ) {
|
||||
parent::init( $container );
|
||||
|
||||
$duplicate_submission_handler = $container->get( self::GF_DUPLICATE_SUBMISSION_HANDLER );
|
||||
|
||||
add_action( 'gform_enqueue_scripts', array( $duplicate_submission_handler, 'maybe_enqueue_scripts' ) );
|
||||
add_action( 'wp_loaded', array( $duplicate_submission_handler, 'maybe_handle_safari_redirect' ), 8, 0 );
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Editor_Button;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Service_Provider;
|
||||
use Gravity_Forms\Gravity_Forms\Editor_Button\Config\GF_Editor_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Editor_Button\Dom\GF_Editor_Button;
|
||||
use Gravity_Forms\Gravity_Forms\Editor_Button\Endpoints\GF_Editor_Save_Editor_Settings;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
|
||||
|
||||
/**
|
||||
* Class GF_Editor_Service_Provider
|
||||
*
|
||||
* Service provider for the Embed Form Service.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Editor_Button;
|
||||
*/
|
||||
class GF_Editor_Service_Provider extends GF_Service_Provider {
|
||||
|
||||
// Configs
|
||||
const EDITOR_CONFIG = 'editor_config';
|
||||
const ENDPOINTS_CONFIG = 'editor_endpoints_config';
|
||||
|
||||
// DOM
|
||||
const DOM_EDITOR_BUTTON = 'dom_editor_button';
|
||||
|
||||
/**
|
||||
* Array mapping config class names to their container ID.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $configs = array(
|
||||
self::EDITOR_CONFIG => GF_Editor_Config::class,
|
||||
);
|
||||
|
||||
/**
|
||||
* Register services to the container.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*/
|
||||
public function register( GF_Service_Container $container ) {
|
||||
// Configs
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/config/class-gf-editor-config.php' );
|
||||
|
||||
// Dom
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/dom/class-gf-editor-button.php' );
|
||||
|
||||
// Endpoints
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/endpoints/class-gf-editor-save-editor-settings.php' );
|
||||
|
||||
$container->add( self::ENDPOINTS_CONFIG, function () {
|
||||
return new GF_Editor_Save_Editor_Settings();
|
||||
} );
|
||||
|
||||
$this->add_configs( $container );
|
||||
$this->dom( $container );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize any actions or hooks.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init( GF_Service_Container $container ) {
|
||||
add_action( 'gform_after_toolbar_buttons', function () use ( $container ) {
|
||||
$container->get( self::DOM_EDITOR_BUTTON )->output_button();
|
||||
} );
|
||||
|
||||
add_action( 'wp_ajax_' . GF_Editor_Save_Editor_Settings::ACTION_NAME, function () use ( $container ) {
|
||||
$container->get( self::ENDPOINTS_CONFIG )->handle();
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* For each config defined in $configs, instantiate and add to container.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private 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 ) );
|
||||
} );
|
||||
|
||||
$container->get( GF_Config_Service_Provider::CONFIG_COLLECTION )->add_config( $container->get( $name ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register DOM-related services.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function dom( GF_Service_Container $container ) {
|
||||
$container->add( self::DOM_EDITOR_BUTTON, function() {
|
||||
return new GF_Editor_Button();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the compact view is enabled for the given form and user.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @param int $user_id The user ID.
|
||||
* @param int $form_id The form ID.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_compact_view_enabled( $user_id, $form_id ) {
|
||||
$compact_view = get_user_meta( $user_id, 'gform_compact_view_' . $form_id, true );
|
||||
return $compact_view === 'enable';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the field ID view in compact view is enabled for the given form and user.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @param int $user_id The user ID.
|
||||
* @param int $form_id The form ID.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_field_id_enabled( $user_id, $form_id ) {
|
||||
$field_id = get_user_meta( $user_id, 'gform_compact_view_show_id_' . $form_id, true );
|
||||
return $field_id === 'enable';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Editor_Button\Config;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Editor_Button\GF_Editor_Service_Provider;
|
||||
use Gravity_Forms\Gravity_Forms\Editor_Button\Endpoints\GF_Editor_Save_Editor_Settings;
|
||||
|
||||
/**
|
||||
* Config items for the Editor Settings Button
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
class GF_Editor_Config extends GF_Config {
|
||||
|
||||
protected $name = 'gform_admin_config';
|
||||
protected $script_to_localize = 'gform_gravityforms_admin_vendors';
|
||||
|
||||
/**
|
||||
* Determine if the config should enqueue its data.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_enqueue() {
|
||||
return \GFCommon::is_form_editor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
return array(
|
||||
'components' => array(
|
||||
'editor_button' => array(
|
||||
'i18n' => array(
|
||||
'title' => esc_html__( 'Editor Preferences', 'gravityforms' ),
|
||||
'closeButtonAriaLabel' => esc_html__( 'Close button', 'gravityforms' ),
|
||||
'description' => esc_html__( 'Change options related to the form editor.', 'gravityforms' ),
|
||||
'compactToggleLabel' => esc_html__( 'Compact View', 'gravityforms' ),
|
||||
'compactToggleText' => esc_html__( 'Simplify the preview of form fields for a more streamlined editing experience.', 'gravityforms' ),
|
||||
'idToggleLabel' => esc_html__( 'Show Field IDs', 'gravityforms' ),
|
||||
'idToggleText' => esc_html__( 'Show the ID of each field in Compact View.', 'gravityforms' ),
|
||||
),
|
||||
'endpoints' => $this->get_endpoints(),
|
||||
'compactViewEnabled' => GF_Editor_Service_Provider::is_compact_view_enabled( get_current_user_id(), rgget( 'id' ) ),
|
||||
'fieldIdEnabled' => GF_Editor_Service_Provider::is_field_id_enabled( get_current_user_id(), rgget( 'id' ) ),
|
||||
'form' => rgget( 'id' ),
|
||||
),
|
||||
'dropdown_menu' => array(
|
||||
'i18n' => array(
|
||||
'duplicateButtonLabel' => esc_html__( 'Duplicate', 'gravityforms' ),
|
||||
'deleteButtonLabel' => esc_html__( 'Delete', 'gravityforms' ),
|
||||
'dropdownButtonLabel' => esc_html__( 'Dropdown menu button', 'gravityforms' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the endpoints for saving the compact view settings.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @return \array[][]
|
||||
*/
|
||||
private function get_endpoints() {
|
||||
return array(
|
||||
'save_editor_settings' => array(
|
||||
'action' => array(
|
||||
'value' => GF_Editor_Save_Editor_Settings::ACTION_NAME,
|
||||
'default' => 'mock_endpoint',
|
||||
),
|
||||
'nonce' => array(
|
||||
'value' => wp_create_nonce( GF_Editor_Save_Editor_Settings::ACTION_NAME ),
|
||||
'default' => 'nonce',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Editor_Button\Dom;
|
||||
|
||||
/**
|
||||
* Handle outputting the Embed Button in the UI.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Embed_Form\Dom
|
||||
*/
|
||||
class GF_Editor_Button {
|
||||
|
||||
/**
|
||||
* Output the HTML for the Embed Button.
|
||||
*/
|
||||
public function output_button() {
|
||||
?>
|
||||
<button
|
||||
data-js="editor-flyout-trigger"
|
||||
class="gform-button gform-button--icon-white gform-button--icon-editor"
|
||||
aria-label="<?php esc_attr_e( 'Open editor preferences', 'gravityforms' ); ?>"
|
||||
title="<?php esc_attr_e( 'Open editor preferences', 'gravityforms' ); ?>"
|
||||
>
|
||||
<i class="gform-icon gform-icon--cog gform-button__icon" aria-hidden="true"></i>
|
||||
</button>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Editor_Button\Endpoints;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
|
||||
/**
|
||||
* AJAX Endpoint for saving the compact view settings.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Editor_Button\Endpoints
|
||||
*/
|
||||
class GF_Editor_Save_Editor_Settings {
|
||||
|
||||
// Strings
|
||||
const ACTION_NAME = 'gf_save_editor_settings';
|
||||
|
||||
/**
|
||||
* Handle the AJAX request.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle() {
|
||||
check_ajax_referer( self::ACTION_NAME );
|
||||
|
||||
$form = intval( rgpost( 'form' ) );
|
||||
$user = get_current_user_id();
|
||||
$name = rgpost( 'name' );
|
||||
$value = rgpost( 'value' );
|
||||
$value = ( $value == 'enable' ) ? 'enable' : 'disable';
|
||||
|
||||
update_user_meta( $user, 'gform_' . $name . '_' . $form, $value );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Embed_Form;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config_Service_Provider;
|
||||
use Gravity_Forms\Gravity_Forms\Embed_Form\Config\GF_Embed_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Embed_Form\Config\GF_Embed_Config_I18N;
|
||||
use Gravity_Forms\Gravity_Forms\Embed_Form\Config\GF_Embed_Endpoints_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Embed_Form\Dom\GF_Embed_Button;
|
||||
use Gravity_Forms\Gravity_Forms\Embed_Form\Endpoints\GF_Embed_Endpoint_Create_With_Block;
|
||||
use Gravity_Forms\Gravity_Forms\Embed_Form\Endpoints\GF_Embed_Endpoint_Get_Posts;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
|
||||
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
|
||||
|
||||
/**
|
||||
* Class GF_Embed_Service_Provider
|
||||
*
|
||||
* Service provider for the Embed Form Service.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Embed_Form;
|
||||
*/
|
||||
class GF_Embed_Service_Provider extends GF_Service_Provider {
|
||||
|
||||
// Configs
|
||||
const EMBED_CONFIG = 'embed_config';
|
||||
const EMBED_CONFIG_I18N = 'embed_config_i18n';
|
||||
const EMBED_CONFIG_ENDPOINTS = 'embed_config_endpoints';
|
||||
|
||||
// Endpoints
|
||||
const ENDPOINT_GET_POSTS = 'endpoint_get_posts';
|
||||
const ENDPOINT_CREATE_WITH_BLOCK = 'endpoint_create_with_block';
|
||||
|
||||
// DOM
|
||||
const DOM_EMBED_BUTTON = 'dom_embed_button';
|
||||
|
||||
// Strings
|
||||
const ADD_BLOCK_PARAM = 'gfAddBlock';
|
||||
|
||||
/**
|
||||
* Array mapping config class names to their container ID.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $configs = array(
|
||||
self::EMBED_CONFIG => GF_Embed_Config::class,
|
||||
self::EMBED_CONFIG_I18N => GF_Embed_Config_I18N::class,
|
||||
self::EMBED_CONFIG_ENDPOINTS => GF_Embed_Endpoints_Config::class,
|
||||
);
|
||||
|
||||
/**
|
||||
* Register services to the container.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*/
|
||||
public function register( GF_Service_Container $container ) {
|
||||
// Configs
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/config/class-gf-embed-config.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/config/class-gf-embed-config-i18n.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/config/class-gf-embed-endpoints-config.php' );
|
||||
|
||||
// Endpoints
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/endpoints/class-gf-embed-endpoint-get-posts.php' );
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/endpoints/class-gf-embed-endpoint-create-with-block.php' );
|
||||
|
||||
// Dom
|
||||
require_once( plugin_dir_path( __FILE__ ) . '/dom/class-gf-embed-button.php' );
|
||||
|
||||
$this->add_configs( $container );
|
||||
$this->add_endpoints( $container );
|
||||
$this->dom( $container );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiailize any actions or hooks.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init( GF_Service_Container $container ) {
|
||||
add_action( 'wp_ajax_' . GF_Embed_Endpoint_Get_Posts::ACTION_NAME, function () use ( $container ) {
|
||||
$container->get( self::ENDPOINT_GET_POSTS )->handle();
|
||||
} );
|
||||
|
||||
add_action( 'wp_ajax_' . GF_Embed_Endpoint_Create_With_Block::ACTION_NAME, function () use ( $container ) {
|
||||
$container->get( self::ENDPOINT_CREATE_WITH_BLOCK )->handle();
|
||||
} );
|
||||
|
||||
add_action( 'gform_before_toolbar_buttons', function () use ( $container ) {
|
||||
$container->get( self::DOM_EMBED_BUTTON )->output_button();
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* For each config defined in $configs, instantiate and add to container.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private 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 ) );
|
||||
} );
|
||||
|
||||
$container->get( GF_Config_Service_Provider::CONFIG_COLLECTION )->add_config( $container->get( $name ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register AJAX endpoints for the Embed UI.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function add_endpoints( GF_Service_Container $container ) {
|
||||
$container->add( self::ENDPOINT_GET_POSTS, function () use ( $container ) {
|
||||
return new GF_Embed_Endpoint_Get_Posts();
|
||||
} );
|
||||
|
||||
$container->add( self::ENDPOINT_CREATE_WITH_BLOCK, function () use ( $container ) {
|
||||
return new GF_Embed_Endpoint_Create_With_Block();
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register DOM-related services.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param GF_Service_Container $container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function dom( GF_Service_Container $container ) {
|
||||
$container->add( self::DOM_EMBED_BUTTON, function() {
|
||||
return new GF_Embed_Button();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Embed_Form\Config;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
|
||||
/**
|
||||
* Config items for the Embed Form I18N
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
class GF_Embed_Config_I18N extends GF_Config {
|
||||
|
||||
protected $name = 'gform_admin_config';
|
||||
protected $script_to_localize = 'gform_gravityforms_admin_vendors';
|
||||
|
||||
/**
|
||||
* Determine if the config should enqueue its data.
|
||||
*
|
||||
* @since 2.6.2
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_enqueue() {
|
||||
return \GFCommon::is_form_editor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
return array(
|
||||
'components' => array(
|
||||
'embed_form' => array(
|
||||
'i18n' => array(
|
||||
'title' => esc_html__( 'Embed Form', 'gravityforms' ),
|
||||
'id' => esc_html__( 'Form ID: %s', 'gravityforms' ),
|
||||
'add_title' => esc_html__( 'Add to Existing Content', 'gravityforms' ),
|
||||
'add_post_type_choice_label' => esc_html__( '%1$sAdd to Existing Content:%2$s %3$s', 'gravityforms' ),
|
||||
'add_dropdown_placeholder' => esc_html__( 'Select a %s', 'gravityforms' ),
|
||||
'add_trigger_aria_text' => esc_html__( 'Select a post', 'gravityforms' ),
|
||||
'add_search_aria_text' => esc_html__( 'Search all %ss', 'gravityforms' ),
|
||||
'add_button_label' => esc_html__( 'Insert Form', 'gravityforms' ),
|
||||
'create_title' => esc_html__( 'Create New', 'gravityforms' ),
|
||||
'create_post_type_choice_label' => esc_html__( '%1$sCreate New:%2$s %3$s', 'gravityforms' ),
|
||||
'create_placeholder' => esc_html__( 'Enter %s Name', 'gravityforms' ),
|
||||
'create_button_label' => esc_html__( 'Create', 'gravityforms' ),
|
||||
'dialog_title' => esc_html__( 'Unsaved Changes', 'gravityforms' ),
|
||||
'dialog_content' => esc_html__( 'Oops! You have unsaved changes in the form, before you can continue with embedding it please save your changes.', 'gravityforms' ),
|
||||
'dialog_confirm_text' => esc_html__( 'Save Changes', 'gravityforms' ),
|
||||
'dialog_confirm_saving' => esc_html__( 'Saving', 'gravityforms' ),
|
||||
'dialog_cancel_text' => esc_html__( 'Cancel', 'gravityforms' ),
|
||||
'dialog_close_title' => esc_html__( 'Close this dialog and return to form editor.', 'gravityforms' ),
|
||||
'shortcode_title' => esc_html__( 'Not Using the Block Editor?', 'gravityforms' ),
|
||||
'shortcode_description' => esc_html__( 'Copy and paste the shortcode within your page builder.', 'gravityforms' ),
|
||||
'shortcode_button_label' => esc_html__( 'Copy Shortcode', 'gravityforms' ),
|
||||
'shortcode_button_copied' => esc_html__( 'Copied', 'gravityforms' ),
|
||||
'shortcode_helper' => esc_html__( '%1$sLearn more%2$s about the shortcode.', 'gravityforms' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Embed_Form\Config;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
|
||||
/**
|
||||
* Config items for the Embed Form UI.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
class GF_Embed_Config extends GF_Config {
|
||||
|
||||
protected $name = 'gform_admin_config';
|
||||
protected $script_to_localize = 'gform_gravityforms_admin_vendors';
|
||||
|
||||
/**
|
||||
* Determine if the config should enqueue its data.
|
||||
*
|
||||
* @since 2.6.2
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_enqueue() {
|
||||
return \GFCommon::is_form_editor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
return array(
|
||||
'components' => array(
|
||||
'embed_form' => array(
|
||||
'urls' => $this->get_urls(),
|
||||
'data' => array(
|
||||
'form_id' => array(
|
||||
'value' => rgget( 'id' ),
|
||||
'default' => 1,
|
||||
),
|
||||
'post_types' => array(
|
||||
'value' => $this->get_available_post_types(),
|
||||
'default' => $this->placeholder_post_types(),
|
||||
),
|
||||
'items' => array(
|
||||
'value' => $this->get_items_by_type(),
|
||||
'default' => $this->placeholder_items(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the various URLs for the Embed UI.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_urls() {
|
||||
$edit_link = '';
|
||||
|
||||
$post_type_object = get_post_type_object( 'page' );
|
||||
if ( ! empty( $post_type_object->_edit_link ) ) {
|
||||
$edit_link = admin_url( str_replace( '%d', '%1$s', $post_type_object->_edit_link ) . '&action=edit' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the edit post link to be customized.
|
||||
*
|
||||
* @since 2.6.2
|
||||
*
|
||||
* @param string $link The edit link. Use %1$s as the placeholder for the ID.
|
||||
*/
|
||||
$edit_link = apply_filters( 'gform_embed_edit_post_link', $edit_link );
|
||||
|
||||
return [
|
||||
'edit_post' => [
|
||||
'value' => $edit_link,
|
||||
'default' => 'https://gravity.loc/wp-admin/post.php?post=%1$s&action=edit',
|
||||
],
|
||||
'shortcode_docs' => 'https://docs.gravityforms.com/shortcodes/',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Post Types data for the Embed UI.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_available_post_types() {
|
||||
$types = array(
|
||||
array(
|
||||
'slug' => 'page',
|
||||
'label' => get_post_type_object( 'page' )->labels->singular_name,
|
||||
),
|
||||
array(
|
||||
'slug' => 'post',
|
||||
'label' => get_post_type_object( 'post' )->labels->singular_name,
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Allows users to modify the post types sent as selectable options in the Embed UI.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param array $types
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
return apply_filters( 'gform_embed_post_types', $types );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the items to localize for each post type.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_items_by_type() {
|
||||
$types = $this->get_available_post_types();
|
||||
$data = array();
|
||||
foreach ( $types as $type ) {
|
||||
$slug = $type['slug'];
|
||||
$label = $type['label'];
|
||||
|
||||
$items = get_posts( array( 'post_type' => $slug, 'posts_per_page' => 5 ) );
|
||||
array_walk( $items, function ( &$item ) {
|
||||
$item = array(
|
||||
'value' => $item->ID,
|
||||
'label' => $item->post_title,
|
||||
);
|
||||
} );
|
||||
|
||||
$data[ $slug ]['entries'] = $items;
|
||||
$data[ $slug ]['count'] = $this->get_total_posts_by_type( $slug );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the totals for the given post type.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param string $type - The Post Type to query for.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_total_posts_by_type( $type ) {
|
||||
$args = array(
|
||||
'post_type' => $type,
|
||||
'post_status' => 'publish',
|
||||
);
|
||||
|
||||
$query = new \WP_Query( $args );
|
||||
|
||||
return $query->found_posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the placeholder post type values for use in Mocks.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function placeholder_post_types() {
|
||||
return array(
|
||||
array( 'slug' => 'page', 'label' => __( 'Page', 'gravityforms' ) ),
|
||||
array( 'slug' => 'post', 'label' => __( 'Post', 'gravityforms' ) ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the placeholder post items for use in Mocks.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function placeholder_items() {
|
||||
return array(
|
||||
'post' => array(
|
||||
'count' => 2,
|
||||
'entries' => array(
|
||||
array(
|
||||
'value' => 1,
|
||||
'label' => 'Post One',
|
||||
),
|
||||
array(
|
||||
'value' => 2,
|
||||
'label' => 'Post Two',
|
||||
),
|
||||
),
|
||||
),
|
||||
'page' => array(
|
||||
'count' => 25,
|
||||
'entries' => array(
|
||||
array(
|
||||
'value' => 3,
|
||||
'label' => 'Page Three',
|
||||
),
|
||||
array(
|
||||
'value' => 4,
|
||||
'label' => 'Page Four',
|
||||
),
|
||||
array(
|
||||
'value' => 5,
|
||||
'label' => 'Page Five',
|
||||
),
|
||||
array(
|
||||
'value' => 6,
|
||||
'label' => 'Page Six',
|
||||
),
|
||||
array(
|
||||
'value' => 7,
|
||||
'label' => 'Page Seven',
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Embed_Form\Config;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\Config\GF_Config;
|
||||
use Gravity_Forms\Gravity_Forms\Embed_Form\Endpoints\GF_Embed_Endpoint_Create_With_Block;
|
||||
use Gravity_Forms\Gravity_Forms\Embed_Form\Endpoints\GF_Embed_Endpoint_Get_Posts;
|
||||
|
||||
/**
|
||||
* Config items for the Embed Forms REST Endpoints.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
class GF_Embed_Endpoints_Config extends GF_Config {
|
||||
|
||||
protected $script_to_localize = 'gform_gravityforms_admin_vendors';
|
||||
protected $name = 'gform_admin_config';
|
||||
protected $overwrite = false;
|
||||
|
||||
/**
|
||||
* Determine if the config should enqueue its data.
|
||||
*
|
||||
* @since 2.6.2
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_enqueue() {
|
||||
return \GFCommon::is_form_editor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Config data.
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data() {
|
||||
return array(
|
||||
'components' => array(
|
||||
'embed_form' => array(
|
||||
'endpoints' => $this->get_endpoints(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the various endpoints for the Embed UI.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_endpoints() {
|
||||
return array(
|
||||
|
||||
// Endpoint to get posts for typeahead
|
||||
'get_posts' => array(
|
||||
'action' => array(
|
||||
'value' => 'gf_embed_query_posts',
|
||||
'default' => 'mock_endpoint',
|
||||
),
|
||||
'nonce' => array(
|
||||
'value' => wp_create_nonce( GF_Embed_Endpoint_Get_Posts::ACTION_NAME ),
|
||||
'default' => 'nonce',
|
||||
)
|
||||
),
|
||||
|
||||
// Endpoint to create a new page with our block inserted.
|
||||
'create_post_with_block' => array(
|
||||
'action' => array(
|
||||
'value' => GF_Embed_Endpoint_Create_With_Block::ACTION_NAME,
|
||||
'default' => 'mock_endpoint',
|
||||
),
|
||||
'nonce' => array(
|
||||
'value' => wp_create_nonce( GF_Embed_Endpoint_Create_With_Block::ACTION_NAME ),
|
||||
'default' => 'nonce',
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Embed_Form\Dom;
|
||||
|
||||
/**
|
||||
* Handle outputting the Embed Button in the UI.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Embed_Form\Dom
|
||||
*/
|
||||
class GF_Embed_Button {
|
||||
|
||||
/**
|
||||
* Output the HTML for the Embed Button.
|
||||
*/
|
||||
public function output_button() {
|
||||
?>
|
||||
<button data-js="embed-flyout-trigger" class="gform-button gform-button--white gform-button--icon-leading">
|
||||
<i class="gform-button__icon gform-icon gform-icon--embed-alt"></i>
|
||||
<?php _e( 'Embed', 'gravityforms' ); ?>
|
||||
</button>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Embed_Form\Endpoints;
|
||||
|
||||
/**
|
||||
* AJAX Endpoint for creating a new post with a specific block already added.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Embed_Form\Endpoints
|
||||
*/
|
||||
class GF_Embed_Endpoint_Create_With_Block {
|
||||
|
||||
// Strings
|
||||
const ACTION_NAME = 'gf_embed_create_post_with_block';
|
||||
|
||||
// Request Params
|
||||
const PARAM_FORM_ID = 'form_id';
|
||||
const PARAM_POST_TYPE = 'post_type';
|
||||
const PARAM_POST_TITLE = 'post_title';
|
||||
|
||||
/**
|
||||
* Handle the AJAX request.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle() {
|
||||
check_ajax_referer( self::ACTION_NAME );
|
||||
|
||||
$post_type = rgpost( self::PARAM_POST_TYPE );
|
||||
$form_id = rgpost( self::PARAM_FORM_ID );
|
||||
$post_title = rgpost( self::PARAM_POST_TITLE );
|
||||
|
||||
if ( empty( $post_type ) || empty( $form_id ) ) {
|
||||
wp_send_json_error( 'Request must include a post_type and form_id.', 400 );
|
||||
}
|
||||
|
||||
$post_data = array(
|
||||
'post_title' => $post_title,
|
||||
'post_type' => $post_type,
|
||||
'post_content' => $this->get_content_for_form( $form_id ),
|
||||
);
|
||||
|
||||
$new_id = wp_insert_post( $post_data );
|
||||
|
||||
wp_send_json_success( array( 'ID' => $new_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the properly-formatted comment string for the block we're inserting.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @param $form_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_content_for_form( $form_id ) {
|
||||
$attrs = array(
|
||||
'formId' => $form_id
|
||||
);
|
||||
|
||||
return get_comment_delimited_block_content( 'gravityforms/form', $attrs, '' );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Embed_Form\Endpoints;
|
||||
|
||||
/**
|
||||
* AJAX Endpoint for getting posts based on search params.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Embed_Form\Endpoints
|
||||
*/
|
||||
class GF_Embed_Endpoint_Get_Posts {
|
||||
|
||||
// Strings
|
||||
const ACTION_NAME = 'gf_embed_query_posts';
|
||||
|
||||
// Parameters
|
||||
const PARAM_OFFSET = 'offset';
|
||||
const PARAM_COUNT = 'count';
|
||||
const PARAM_STATUS = 'status';
|
||||
const PARAM_SEARCH = 'search';
|
||||
const PARAM_POST_TYPE = 'post_type';
|
||||
|
||||
// Defaults
|
||||
const DEFAULT_OFFSET = 0;
|
||||
const DEFAULT_COUNT = 10;
|
||||
const DEFAULT_STATUS = 'publish';
|
||||
const DEFAULT_SEARCH = '';
|
||||
const DEFAULT_POST_TYPE = 'post';
|
||||
|
||||
/**
|
||||
* Handle the AJAX request.
|
||||
*
|
||||
* @since 2.6
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle() {
|
||||
check_ajax_referer( self::ACTION_NAME );
|
||||
|
||||
$offset = rgpost( self::PARAM_OFFSET ) ? rgpost( self::PARAM_OFFSET ) : self::DEFAULT_OFFSET;
|
||||
$count = rgpost( self::PARAM_COUNT ) ? rgpost( self::PARAM_COUNT ) : self::DEFAULT_COUNT;
|
||||
$status = rgpost( self::PARAM_STATUS ) ? rgpost( self::PARAM_STATUS ) : self::DEFAULT_STATUS;
|
||||
$search = rgpost( self::PARAM_SEARCH ) ? rgpost( self::PARAM_SEARCH ) : self::DEFAULT_SEARCH;
|
||||
$post_type = rgpost( self::PARAM_POST_TYPE ) ? rgpost( self::PARAM_POST_TYPE ) : self::DEFAULT_POST_TYPE;
|
||||
|
||||
$args = array(
|
||||
'post_type' => $post_type,
|
||||
'post_status' => $status,
|
||||
'posts_per_page' => $count,
|
||||
'offset' => $offset,
|
||||
's' => $search,
|
||||
);
|
||||
|
||||
$query = new \WP_Query( $args );
|
||||
|
||||
$posts = $query->get_posts();
|
||||
|
||||
array_walk( $posts, function ( &$post ) {
|
||||
$post = array(
|
||||
'value' => $post->ID,
|
||||
'label' => $post->post_title,
|
||||
);
|
||||
} );
|
||||
|
||||
wp_send_json_success( $posts );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,224 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Handles logic for adjusting Gravity Forms to different environment configurations.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Environment_Config
|
||||
*/
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Environment_Config;
|
||||
|
||||
/**
|
||||
* Class GF_Environment_Config_Handler
|
||||
*
|
||||
* @since 2.6.7
|
||||
*
|
||||
* Provides functionality for handling environment configuration options.
|
||||
*/
|
||||
class GF_Environment_Config_Handler {
|
||||
|
||||
/**
|
||||
* Provides caching service.
|
||||
*
|
||||
* @var \GFCache $cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* GF_Environment_Config_Handler constructor.
|
||||
*
|
||||
* @since 2.6.7
|
||||
*
|
||||
* @param \GFCache $cache Provides caching service.
|
||||
*/
|
||||
public function __construct( $cache ) {
|
||||
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an environment setting from wp_options.
|
||||
*
|
||||
* @since 2.6.7
|
||||
*
|
||||
* @param string $name The environment setting name. Don't include the "gf_env_" prefix.
|
||||
* @param mixed $default Default value to be returned if option is not set.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_environment_setting( $name, $default = false ) {
|
||||
$option_name = "gf_env_{$name}";
|
||||
$setting = $this->cache->get( $option_name, $found );
|
||||
if ( ! $found ) {
|
||||
$setting = get_option( $option_name, $default );
|
||||
$this->cache->set( $option_name, $setting );
|
||||
}
|
||||
return $setting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the license_key config value.
|
||||
*
|
||||
* @since 2.6.7
|
||||
*
|
||||
* @return string The license key config.
|
||||
*/
|
||||
public function get_license_key() {
|
||||
return $this->get_environment_setting( 'license_key', false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hide_license config value.
|
||||
*
|
||||
* @since 2.6.7
|
||||
*
|
||||
* @return bool Returns true if license is supposed to be hidden from the UI, false otherwise.
|
||||
*/
|
||||
public function get_hide_license() {
|
||||
return (bool) $this->get_environment_setting( 'hide_license', false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hide_background_updates config value.
|
||||
*
|
||||
* @since 2.6.9
|
||||
*
|
||||
* @return bool Returns true if the background updates setting is supposed to be hidden from the UI. Returns false otherwise.
|
||||
*/
|
||||
public function get_hide_background_updates() {
|
||||
return (bool) $this->get_environment_setting( 'hide_background_updates', false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hide_install_wizard config value.
|
||||
*
|
||||
* @since 2.6.7
|
||||
*
|
||||
* @return bool Returns true if install wizard is supposed to be hidden. Returns false otherwise.
|
||||
*/
|
||||
public function get_hide_install_wizard() {
|
||||
return (bool) $this->get_environment_setting( 'hide_setup_wizard', false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hide_update_message config value.
|
||||
*
|
||||
* @since 2.6.7
|
||||
*
|
||||
* @return bool Returns true if install wizard is supposed to be hidden. Returns false otherwise.
|
||||
*/
|
||||
public function get_hide_update_message() {
|
||||
return (bool) $this->get_environment_setting( 'hide_update_message', false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the support_url config value.
|
||||
*
|
||||
* @since 2.6.7
|
||||
*
|
||||
* @return string The support link config value.
|
||||
*/
|
||||
public function get_support_url() {
|
||||
return $this->get_environment_setting( 'support_url', 'https://www.gravityforms.com/open-support-ticket/' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unregistered_license_message config value.
|
||||
*
|
||||
* @since 2.6.7
|
||||
*
|
||||
* @return string The message to be displayed when the license is unregistered.
|
||||
*/
|
||||
public function get_unregistered_license_message() {
|
||||
return $this->get_environment_setting( 'unregistered_license_message' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Target of the pre_option_gform_pending_installation filter. Bypasses the installation wizard by returning 0 for the gform_pending_installation option.
|
||||
*
|
||||
* @hook pre_option_gform_pending_installation 10, 1
|
||||
*
|
||||
* @return int Returns 0 if the install wizard is set to be hidden by environment settings. Otherwise return false so that option is not overridden.
|
||||
*/
|
||||
public function maybe_override_gform_pending_installation() {
|
||||
|
||||
// If environment config is set to hide install wizard, override gform_pending_intallation option with 0. Otherwise, use existing option.
|
||||
$hide_install_wizard = $this->get_hide_install_wizard();
|
||||
return $hide_install_wizard ? 0 : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe hides the automatic update message on the plugin's page.
|
||||
*
|
||||
* @since 2.6.8
|
||||
*/
|
||||
public function maybe_hide_plugin_page_message() {
|
||||
|
||||
if ( $this->get_hide_update_message() ) {
|
||||
remove_filter( 'transient_update_plugins', array( 'GFForms', 'check_update' ) );
|
||||
remove_filter( 'site_transient_update_plugins', array( 'GFForms', 'check_update' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe hides the automatic update message on the Update page.
|
||||
*
|
||||
* @since 2.6.8
|
||||
*
|
||||
* @hook gform_updates_list, 20
|
||||
*
|
||||
* @param array $updates Updates array being filtered.
|
||||
*/
|
||||
public function maybe_hide_update_page_message( $updates ) {
|
||||
|
||||
if ( ! $this->get_hide_update_message() ) {
|
||||
return $updates;
|
||||
}
|
||||
|
||||
foreach ( $updates as & $update ) {
|
||||
if ( $update['slug'] == 'gravityforms' ) {
|
||||
$update['latest_version'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
return $updates;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Target of the pre_option_rg_gforms_key filter. Uses the license key configured by the environment settings if one is set.
|
||||
*
|
||||
* @hook pre_option_rg_gforms_key 10, 1
|
||||
*
|
||||
* @since 2.6.7
|
||||
*
|
||||
* @return string Returns the environment license key if one is set. If not set, return false so that value is not overridden.
|
||||
*/
|
||||
public function maybe_override_rg_gforms_key() {
|
||||
|
||||
// Use environment license key if one is set. Otherwise, use rg_gforms_key option.
|
||||
$env_license_key = $this->get_license_key();
|
||||
return $env_license_key !== false ? $env_license_key : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Target of the gform_plugin_settings_fields filter. Removes sections from the settings page that are configured to be hidden.
|
||||
*
|
||||
* @since 2.6.9
|
||||
*
|
||||
* @param array $fields The settings fields to be filtered.
|
||||
*
|
||||
* @return array Returns the filtered $fields array.
|
||||
*/
|
||||
public function maybe_hide_setting( $fields ) {
|
||||
|
||||
if ( $this->get_hide_license() ) {
|
||||
unset( $fields['license_key'] );
|
||||
unset( $fields['license_key_details'] );
|
||||
}
|
||||
if ( $this->get_hide_background_updates() ) {
|
||||
unset( $fields['background_updates'] );
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\Environment_Config;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Class GF_Environment_Config_Service_Provider
|
||||
*
|
||||
* Service provider for the Environment_Config Service.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\Environment_Config;
|
||||
*/
|
||||
class GF_Environment_Config_Service_Provider extends GF_Service_Provider {
|
||||
|
||||
const GF_ENVIRONMENT_CONFIG_HANDLER = 'gf_environment_config_handler';
|
||||
|
||||
/**
|
||||
* Register services to the container.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param GF_Service_Container $container Service Container.
|
||||
*/
|
||||
public function register( GF_Service_Container $container ) {
|
||||
require_once plugin_dir_path( __FILE__ ) . 'class-gf-environment-config-handler.php';
|
||||
|
||||
$container->add(
|
||||
self::GF_ENVIRONMENT_CONFIG_HANDLER,
|
||||
function () use ( $container ) {
|
||||
return new GF_Environment_Config_Handler( $container->get( GF_Util_Service_Provider::GF_CACHE ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiailize any actions or hooks.
|
||||
*
|
||||
* @since 2.7
|
||||
*
|
||||
* @param GF_Service_Container $container Service Container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init( GF_Service_Container $container ) {
|
||||
|
||||
$handler = $container->get( self::GF_ENVIRONMENT_CONFIG_HANDLER );
|
||||
|
||||
// Gets environment license key.
|
||||
add_filter( 'pre_option_rg_gforms_key', array( $handler, 'maybe_override_rg_gforms_key' ) );
|
||||
|
||||
// Maybe bypass installation wizard.
|
||||
add_filter( 'pre_option_gform_pending_installation', array( $handler, 'maybe_override_gform_pending_installation' ) );
|
||||
|
||||
// Maybe hides license key setting and license key details.
|
||||
add_filter( 'gform_plugin_settings_fields', array( $handler, 'maybe_hide_setting' ) );
|
||||
|
||||
// Maybe hide plugin auto update messages.
|
||||
add_filter( 'init', array( $handler, 'maybe_hide_plugin_page_message' ), 20 );
|
||||
add_filter( 'gform_updates_list', array( $handler, 'maybe_hide_update_page_message' ), 20 );
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\External_API;
|
||||
|
||||
/**
|
||||
* Class GF_API_Connector
|
||||
*
|
||||
* An abstraction allowing us to create codified API Connector classes with a distinct
|
||||
* strategy for each one, and a standardized Cache mechanism. This separates the actually
|
||||
* communication logic from the class which calls it, allowing better testability.
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\External_API
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
abstract class GF_API_Connector {
|
||||
|
||||
protected $strategy;
|
||||
|
||||
/**
|
||||
* @var \GFCache $cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* GF_API_Connector constructor.
|
||||
*
|
||||
* @param $strategy The strategy class used to actually communicate with the API.
|
||||
* @param $cache The cache class used for caching results and other operations.
|
||||
*/
|
||||
public function __construct( $strategy, $cache ) {
|
||||
$this->strategy = $strategy;
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,218 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\External_API;
|
||||
|
||||
/**
|
||||
* Class GF_API_Response
|
||||
*
|
||||
* An abstracted Response class used to standardize the responses we send back from an API Connector. Includes
|
||||
* standardized serialization and JSON methods to support saving the class to the Database.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\External_API
|
||||
*/
|
||||
abstract class GF_API_Response implements \JsonSerializable, \Serializable {
|
||||
|
||||
/**
|
||||
* The data for this response.
|
||||
*
|
||||
* @var array $data
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* The status for this response.
|
||||
*
|
||||
* @var array $status
|
||||
*/
|
||||
protected $status = array();
|
||||
|
||||
/**
|
||||
* The errors (if any) for this response.
|
||||
*
|
||||
* @var array $errors
|
||||
*/
|
||||
protected $errors = array();
|
||||
|
||||
/**
|
||||
* The meta data (if any) for this response.
|
||||
*
|
||||
* @var array $meta
|
||||
*/
|
||||
protected $meta = array();
|
||||
|
||||
/**
|
||||
* Set the status for the response.
|
||||
*
|
||||
* @param $status
|
||||
*/
|
||||
protected function set_status( $status ) {
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add data item.
|
||||
*
|
||||
* @param $item
|
||||
*/
|
||||
protected function add_data_item( $item ) {
|
||||
$this->data[] = $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an error message.
|
||||
*
|
||||
* @param $error_message
|
||||
*/
|
||||
protected function add_error( $error_message ) {
|
||||
$this->errors[] = $error_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a meta item to the response.
|
||||
*
|
||||
* @param $key
|
||||
* @param $value
|
||||
*/
|
||||
protected function add_meta_item( $key, $value ) {
|
||||
$this->meta[ $key ] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for this response
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_data() {
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any errors on this response.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_errors() {
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response status.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_status() {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response meta.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_meta() {
|
||||
return $this->meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the response has any errors.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_errors() {
|
||||
return ! empty( $this->errors );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific piece of the data.
|
||||
*
|
||||
* @param $name
|
||||
* @param int $index
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function get_data_value( $name, $index = 0 ) {
|
||||
if ( ! isset( $this->data[ $index ][ $name ] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->data[ $index ][ $name ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Standardization of the class when serialized and unserialized. Useful for standardizing how it
|
||||
* is stored in the Database.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize() {
|
||||
return serialize( $this->__serialize() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the object for serializing.
|
||||
*
|
||||
* @since 2.6.2
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __serialize() {
|
||||
return array(
|
||||
'data' => $this->data,
|
||||
'errors' => $this->errors,
|
||||
'status' => $this->status,
|
||||
'meta' => $this->meta,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrate the Response data when unserializing.
|
||||
*
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize( $serialized ) {
|
||||
$this->__unserialize( unserialize( $serialized ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrates the object when unserializing.
|
||||
*
|
||||
* @since 2.6.2
|
||||
*
|
||||
* @param array $data The unserialized data.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __unserialize( $data ) {
|
||||
$this->data = $data['data'];
|
||||
$this->errors = $data['errors'];
|
||||
$this->status = $data['status'];
|
||||
$this->meta = $data['meta'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Process data for JSON Encoding.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize() {
|
||||
|
||||
$response = array();
|
||||
|
||||
$response['status'] = $this->status;
|
||||
$response['meta'] = $this->meta;
|
||||
|
||||
if ( empty( $this->errors ) ) {
|
||||
$response['data'] = $this->data;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->errors ) ) {
|
||||
$response['errors'] = $this->errors;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Gravity_Forms\Gravity_Forms\External_API;
|
||||
|
||||
use Gravity_Forms\Gravity_Forms\External_API\GF_API_Response;
|
||||
|
||||
/**
|
||||
* Interface GF_API_Response_Factory
|
||||
*
|
||||
* Contract to define how Response Factories should behave.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @package Gravity_Forms\Gravity_Forms\External_API
|
||||
*/
|
||||
interface GF_API_Response_Factory {
|
||||
|
||||
/**
|
||||
* @param mixed ...$args
|
||||
*
|
||||
* @return GF_API_Response
|
||||
*/
|
||||
public function create( ...$args );
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,177 +0,0 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_Calculation extends GF_Field {
|
||||
|
||||
public $type = 'calculation';
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'disable_quantity_setting',
|
||||
'rules_setting',
|
||||
'duplicate_setting',
|
||||
'calculation_setting',
|
||||
'conditional_logic_field_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_button() {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
$quantity_id = $this->id . '.3';
|
||||
$quantity = rgget( $quantity_id, $value );
|
||||
|
||||
if ( $this->isRequired && rgblank( $quantity ) && ! $this->disableQuantity ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty($this->errorMessage) ? esc_html__( 'This field is required.', 'gravityforms' ) : $this->errorMessage;
|
||||
} elseif ( ! empty( $quantity ) && ( ! is_numeric( $quantity ) || intval( $quantity ) != floatval( $quantity ) || intval( $quantity ) < 0 ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = esc_html__( 'Please enter a valid quantity', 'gravityforms' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the field inputs.
|
||||
*
|
||||
* @since unknown
|
||||
* @since 2.5 Add accessibility enhancements.
|
||||
*
|
||||
* @param array $form The form object.
|
||||
* @param string $value The field value.
|
||||
* @param array $entry The entry object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = $form['id'];
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
$is_legacy_markup = GFCommon::is_legacy_markup_enabled( $form );
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
$product_name = ! is_array( $value ) || empty( $value[ $this->id . '.1' ] ) ? esc_attr( $this->label ) : esc_attr( $value[ $this->id . '.1' ] );
|
||||
$price = ! is_array( $value ) || empty( $value[ $this->id . '.2' ] ) ? $this->basePrice : esc_attr( $value[ $this->id . '.2' ] );
|
||||
$quantity = is_array( $value ) ? esc_attr( $value[ $this->id . '.3' ] ) : '';
|
||||
|
||||
if ( empty( $price ) ) {
|
||||
$price = 0;
|
||||
}
|
||||
|
||||
$has_quantity = sizeof( GFCommon::get_product_fields_by_type( $form, array( 'quantity' ), $this->id ) ) > 0;
|
||||
if ( $has_quantity ) {
|
||||
$this->disableQuantity = true;
|
||||
}
|
||||
|
||||
$currency = $is_entry_detail && ! empty( $entry ) ? $entry['currency'] : '';
|
||||
|
||||
$quantity_field = '';
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
|
||||
$product_quantity_sub_label = $this->get_product_quantity_label( $form_id );
|
||||
|
||||
if ( $is_entry_detail || $is_form_editor ) {
|
||||
$style = $this->disableQuantity ? "style='display:none;'" : '';
|
||||
$quantity_field = " <span class='ginput_quantity_label gform-field-label gform-field-label--type-sub-large' {$style}>{$product_quantity_sub_label}</span> <input type='number' name='input_{$id}.3' value='{$quantity}' id='ginput_quantity_{$form_id}_{$this->id}' class='ginput_quantity' size='10' min='0' {$disabled_text} />";
|
||||
} elseif ( ! $this->disableQuantity ) {
|
||||
$tabindex = $this->get_tabindex();
|
||||
$describedby_extra_id = array();
|
||||
if ( ! $is_legacy_markup ) {
|
||||
$describedby_extra_id = array( "ginput_product_price_{$this->formId}_{$this->id}" );
|
||||
}
|
||||
$quantity_aria_describedby = $this->get_aria_describedby( $describedby_extra_id );
|
||||
$quantity_field .= " <span class='ginput_quantity_label gform-field-label' aria-hidden='true'>" . $product_quantity_sub_label . "</span> <input type='number' name='input_{$id}.3' value='{$quantity}' id='input_{$form_id}_{$this->id}_1' class='ginput_quantity' size='10' min='0' {$tabindex} {$disabled_text} {$quantity_aria_describedby} />";
|
||||
} else {
|
||||
if ( ! is_numeric( $quantity ) ) {
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
if ( ! $has_quantity ) {
|
||||
$quantity_field .= "<input type='hidden' name='input_{$id}.3' value='{$quantity}' class='ginput_quantity_{$form_id}_{$this->id} gform_hidden' />";
|
||||
}
|
||||
}
|
||||
|
||||
$wrapper_open = $is_legacy_markup ? '' : "<div id='ginput_product_price_{$form_id}_{$this->id}' class='ginput_product_price_wrapper'>";
|
||||
$wrapper_close = $is_legacy_markup ? '' : '</div>';
|
||||
|
||||
return "<div class='ginput_container ginput_container_product_calculation'>
|
||||
<input type='hidden' name='input_{$id}.1' value='{$product_name}' class='gform_hidden' />
|
||||
$wrapper_open
|
||||
<span class='gform-field-label gform-field-label--type-sub-large ginput_product_price_label'>" . gf_apply_filters( array( 'gform_product_price', $form_id, $this->id ), esc_html__( 'Price', 'gravityforms' ), $form_id ) . ":</span>
|
||||
<span class='gform-field-label gform-field-label--type-sub-large ginput_product_price' id='{$field_id}'>" . esc_html( GFCommon::to_money( $price, $currency ) ) . "</span>
|
||||
$wrapper_close
|
||||
<input type='hidden' name='input_{$id}.2' id='ginput_base_price_{$form_id}_{$this->id}' class='gform_hidden' value='" . esc_attr( $price ) . "'/>
|
||||
{$quantity_field}
|
||||
</div>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the field label.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param bool $force_frontend_label Should the frontend label be displayed in the admin even if an admin label is configured.
|
||||
* @param string $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_label( $force_frontend_label, $value ) {
|
||||
$field_label = parent::get_field_label( $force_frontend_label, $value );
|
||||
|
||||
// Checking the defined product name.
|
||||
if ( ! rgempty( $this->id . '.1', $value ) ) {
|
||||
$field_label = rgar( $value, $this->id . '.1' );
|
||||
}
|
||||
|
||||
if ( $this->disableQuantity || ! $this->get_context_property( 'rendering_form' ) ) {
|
||||
$label = esc_html( $field_label );
|
||||
} else {
|
||||
$product_quantity_sub_label = $this->get_product_quantity_label( $this->formId );
|
||||
$label = '<span class="gfield_label_product gform-field-label">' . esc_html( $field_label ) . '</span>' . ' <span class="screen-reader-text">' . $product_quantity_sub_label . '</span>';
|
||||
}
|
||||
|
||||
return $label;
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
if ( is_array( $value ) && ! empty( $value ) ) {
|
||||
$product_name = trim( $value[ $this->id . '.1' ] );
|
||||
$price = trim( $value[ $this->id . '.2' ] );
|
||||
$quantity = trim( $value[ $this->id . '.3' ] );
|
||||
|
||||
$product = $product_name . ', ' . esc_html__( 'Qty: ', 'gravityforms' ) . $quantity . ', ' . esc_html__( 'Price: ', 'gravityforms' ) . $price;
|
||||
|
||||
return $product;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
// ignore submitted value and recalculate price in backend
|
||||
list( $prefix, $field_id, $input_id ) = rgexplode( '_', $input_name, 3 );
|
||||
if ( $input_id == 2 ) {
|
||||
$currency = new RGCurrency( GFCommon::get_currency() );
|
||||
$lead = empty( $lead ) ? RGFormsModel::get_lead( $lead_id ) : $lead;
|
||||
$value = $currency->to_money( GFCommon::calculate( $this, $form, $lead ) );
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
$this->enableCalculation = (bool) $this->enableCalculation;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Calculation() );
|
||||
@@ -1,682 +0,0 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_CAPTCHA extends GF_Field {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'captcha';
|
||||
|
||||
|
||||
/**
|
||||
* The reCAPTCHA API response.
|
||||
*
|
||||
* @var \stdClass
|
||||
*/
|
||||
private $response;
|
||||
|
||||
/**
|
||||
* The reCAPTCHA site key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $site_key;
|
||||
|
||||
/**
|
||||
* The reCAPTCHA secret key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $secret_key;
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'CAPTCHA', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Adds a captcha field to your form to help protect your website from spam and bot abuse.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--recaptcha';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'captcha_type_setting',
|
||||
'captcha_badge_setting',
|
||||
'captcha_size_setting',
|
||||
'captcha_fg_setting',
|
||||
'captcha_bg_setting',
|
||||
'captcha_language_setting',
|
||||
'captcha_theme_setting',
|
||||
'conditional_logic_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the warning message to be displayed in the form editor sidebar.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_sidebar_messages() {
|
||||
if ( $this->captchaType === 'math' || $this->captchaType === 'simple_captcha' || ( ! empty( $this->get_site_key() ) && ! empty( $this->get_secret_key() ) ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Translators: 1. Opening <a> tag with link to the Forms > Settings > reCAPTCHA page. 2. closing <a> tag.
|
||||
return sprintf( __( 'To use reCAPTCHA v2 you must configure the site and secret keys on the %1$sreCAPTCHA Settings%2$s page.', 'gravityforms' ), "<a href='?page=gf_settings&subview=recaptcha' target='_blank'>", '</a>' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the reCAPTCHA field.
|
||||
*
|
||||
* This method always gets called on the last page of a form, as well as on the page where the field is assigned.
|
||||
*
|
||||
* @since Unknown
|
||||
*
|
||||
* @param array|string $value The field value.
|
||||
* @param array $form The form data.
|
||||
*/
|
||||
public function validate( $value, $form ) {
|
||||
switch ( $this->captchaType ) {
|
||||
case 'simple_captcha' :
|
||||
if ( class_exists( 'ReallySimpleCaptcha' ) ) {
|
||||
$prefix = $_POST[ "input_captcha_prefix_{$this->id}" ];
|
||||
$captcha_obj = $this->get_simple_captcha();
|
||||
|
||||
if ( ! $captcha_obj->check( $prefix, str_replace( ' ', '', $value ) ) ) {
|
||||
$this->set_failed_validation( esc_html__( "The CAPTCHA wasn't entered correctly. Go back and try it again.", 'gravityforms' ) );
|
||||
}
|
||||
|
||||
//removes old files in captcha folder (older than 1 hour);
|
||||
$captcha_obj->cleanup();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'math' :
|
||||
$prefixes = explode( ',', $_POST[ "input_captcha_prefix_{$this->id}" ] );
|
||||
$captcha_obj = $this->get_simple_captcha();
|
||||
|
||||
//finding first number
|
||||
for ( $first = 0; $first < 10; $first ++ ) {
|
||||
if ( $captcha_obj->check( $prefixes[0], $first ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//finding second number
|
||||
for ( $second = 0; $second < 10; $second ++ ) {
|
||||
if ( $captcha_obj->check( $prefixes[2], $second ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//if it is a +, perform the sum
|
||||
if ( $captcha_obj->check( $prefixes[1], '+' ) ) {
|
||||
$result = $first + $second;
|
||||
} else {
|
||||
$result = $first - $second;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ( intval( $result ) != intval( $value ) ) {
|
||||
$this->set_failed_validation( esc_html__( "The CAPTCHA wasn't entered correctly. Go back and try it again.", 'gravityforms' ) );
|
||||
}
|
||||
|
||||
//removes old files in captcha folder (older than 1 hour);
|
||||
$captcha_obj->cleanup();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->validate_recaptcha( $form );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the reCAPTCHA response.
|
||||
*
|
||||
* In our application flow, we create a decoded string out of the reCAPTCHA service response if the reCAPTCHA field
|
||||
* is added to the form on a page other than the last page. We therefore first attempt to validate the decoded response,
|
||||
* falling back to validating the reCAPTCHA with a request to Google.
|
||||
*
|
||||
* @see GF_Field_CAPTCHA::verify_decoded_response()
|
||||
*
|
||||
* @since unknown
|
||||
*
|
||||
* @param array $form The form data.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validate_recaptcha( $form ) {
|
||||
$response = $this->get_posted_recaptcha_response();
|
||||
|
||||
if ( ! ( $this->verify_decoded_response( $form, $response ) || $this->verify_recaptcha_response( $response ) ) ) {
|
||||
$this->set_failed_validation( __( 'The reCAPTCHA was invalid. Go back and try it again.', 'gravityforms' ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the decoded response meets the requirements for submitting the form.
|
||||
*
|
||||
* Returns false if the decoded response doesn't exist or the reCAPTCHA field is on the last page, as we'll want
|
||||
* regular validation at that point instead.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param array $form The form data.
|
||||
* @param string $response The encoded response to verify.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function verify_decoded_response( $form, $response ) {
|
||||
$decoded_response = $this->get_decoded_recaptcha_response( $response );
|
||||
|
||||
// No decoded object.
|
||||
if ( ! is_object( $decoded_response ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Not a time that we need to verify the decoded object.
|
||||
if ( ! GFFormDisplay::is_last_page( $form ) || $this->is_on_last_page( $form ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
$decoded_response->success === true
|
||||
&& ! empty( $decoded_response->token )
|
||||
&& gmdate( time() ) <= strtotime( '+1 day', strtotime( $decoded_response->challenge_ts ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set validation failed on reCAPTCHA field.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param string $message The message to set if one does not already exist.
|
||||
*/
|
||||
private function set_failed_validation( $message ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? $message : $this->errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the saved site key.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_site_key() {
|
||||
if ( ! $this->site_key ) {
|
||||
$this->site_key = get_option( 'rg_gforms_captcha_public_key', '' );
|
||||
}
|
||||
|
||||
return $this->site_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the saved secret key.
|
||||
*
|
||||
* @since 2.4.25
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_secret_key() {
|
||||
if ( ! $this->secret_key ) {
|
||||
$this->secret_key = get_option( 'rg_gforms_captcha_private_key', '' );
|
||||
}
|
||||
|
||||
return $this->secret_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the reCAPTCHA response input.
|
||||
*
|
||||
* When user clicks on the "I'm not a robot" box, the response token is populated into a hidden field by Google.
|
||||
* If the current form is a multi-page form and the reCAPTCHA field is on a page other than the last page, this
|
||||
* value will return an openssl encoded string with the Google reCAPTCHA validation data and some supplemental
|
||||
* validation data instead.
|
||||
*
|
||||
* @see GF_Field_CAPTCHA::get_encoded_recaptcha_response()
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_posted_recaptcha_response() {
|
||||
return sanitize_text_field( rgpost( 'g-recaptcha-response' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the reCAPTCHA token provided by Google.
|
||||
*
|
||||
* @since unknown
|
||||
*
|
||||
* @param string $response The token to verify.
|
||||
* @param null $secret_key The secret key for reCAPTCHA verification.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function verify_recaptcha_response( $response, $secret_key = null ) {
|
||||
|
||||
$verify_url = 'https://www.google.com/recaptcha/api/siteverify';
|
||||
|
||||
if ( $secret_key == null ) {
|
||||
$secret_key = $this->get_secret_key();
|
||||
}
|
||||
|
||||
// pass secret key and token for verification of whether the response was valid
|
||||
$response = wp_remote_post( $verify_url, array(
|
||||
'method' => 'POST',
|
||||
'body' => array(
|
||||
'secret' => $secret_key,
|
||||
'response' => $response
|
||||
),
|
||||
) );
|
||||
|
||||
if ( ! is_wp_error( $response ) ) {
|
||||
$this->response = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
return $this->response->success == true;
|
||||
} else {
|
||||
GFCommon::log_debug( __METHOD__ . '(): Validating the reCAPTCHA response has failed due to the following: ' . $response->get_error_message() );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$form_id = $form['id'];
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$id = (int) $this->id;
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
|
||||
switch ( $this->captchaType ) {
|
||||
case 'simple_captcha' :
|
||||
$size = empty($this->simpleCaptchaSize) ? 'medium' : esc_attr( $this->simpleCaptchaSize );
|
||||
$captcha = $this->get_captcha();
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
$dimensions = $is_entry_detail || $is_form_editor ? '' : "width='" . esc_attr( rgar( $captcha, 'width' ) ) . "' height='" . esc_attr( rgar( $captcha, 'height' ) ) . "'";
|
||||
|
||||
return "<div class='gfield_captcha_container'><img class='gfield_captcha' src='" . esc_url( rgar( $captcha, 'url' ) ) . "' alt='' {$dimensions} /><div class='gfield_captcha_input_container simple_captcha_{$size}'><input type='text' autocomplete='off' name='input_{$id}' id='{$field_id}' {$tabindex}/><input type='hidden' name='input_captcha_prefix_{$id}' value='" . esc_attr( rgar( $captcha, 'prefix' ) ) . "' /></div></div>";
|
||||
break;
|
||||
|
||||
case 'math' :
|
||||
$size = empty( $this->simpleCaptchaSize ) ? 'medium' : esc_attr( $this->simpleCaptchaSize );
|
||||
$captcha_1 = $this->get_math_captcha( 1 );
|
||||
$captcha_2 = $this->get_math_captcha( 2 );
|
||||
$captcha_3 = $this->get_math_captcha( 3 );
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
|
||||
$dimensions = $is_entry_detail || $is_form_editor ? '' : "width='" . esc_attr( rgar( $captcha_1, 'width' ) ) . "' height='" . esc_attr( rgar( $captcha_1, 'height' ) ) . "'";
|
||||
$prefix_value = rgar( $captcha_1, 'prefix' ) . ',' . rgar( $captcha_2, 'prefix' ) . ',' . rgar( $captcha_3, 'prefix' );
|
||||
|
||||
return "<div class='gfield_captcha_container'><img class='gfield_captcha' src='" . esc_url( rgar( $captcha_1, 'url' ) ) . "' alt='' {$dimensions} /><img class='gfield_captcha' src='" . esc_url( rgar( $captcha_2, 'url' ) ) . "' alt='' {$dimensions} /><img class='gfield_captcha' src='" . esc_url( rgar( $captcha_3, 'url' ) ) . "' alt='' {$dimensions} /><div class='gfield_captcha_input_container math_{$size}'><input type='text' autocomplete='off' name='input_{$id}' id='{$field_id}' {$tabindex}/><input type='hidden' name='input_captcha_prefix_{$id}' value='" . esc_attr( $prefix_value ) . "' /></div></div>";
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
$this->site_key = $this->get_site_key();
|
||||
$this->secret_key = $this->get_secret_key();
|
||||
$theme = in_array( $this->captchaTheme, array( 'blackglass', 'dark' ) ) ? 'dark' : 'light';
|
||||
$type = get_option( 'rg_gforms_captcha_type' );
|
||||
if ( $is_entry_detail || $is_form_editor ){
|
||||
|
||||
//for admin, show a thumbnail depending on chosen theme
|
||||
if ( empty( $this->site_key ) || empty( $this->secret_key ) ) {
|
||||
|
||||
return "<div class='ginput_container'><div class='captcha_message'>" . __( 'To use the reCAPTCHA field you must do the following:', 'gravityforms' ) . "</div><div class='captcha_message'>1 - <a href='https://www.google.com/recaptcha/admin' target='_blank'>" . sprintf( __( 'Sign up%s for an API key pair for your site.', 'gravityforms' ), '</a>' ) . "</div><div class='captcha_message'>2 - " . sprintf( __( 'Enter your reCAPTCHA site and secret keys in the %sreCAPTCHA Settings%s.', 'gravityforms' ), "<a href='?page=gf_settings&subview=recaptcha' target='_blank'>", '</a>' ) . '</div></div>';
|
||||
}
|
||||
|
||||
$type_suffix = $type == 'invisible' ? 'invisible_' : '';
|
||||
$alt = esc_attr__( 'An example of reCAPTCHA', 'gravityforms' );
|
||||
|
||||
return "<div class='ginput_container'><img class='gfield_captcha' src='" . GFCommon::get_base_url() . "/images/captcha_{$type_suffix}{$theme}.jpg' alt='{$alt}' /></div>";
|
||||
}
|
||||
|
||||
if ( empty( $this->site_key ) || empty( $this->secret_key ) ) {
|
||||
GFCommon::log_error( __METHOD__ . sprintf( '(): reCAPTCHA secret keys not saved in the reCAPTCHA Settings (%s). The reCAPTCHA field will always fail validation during form submission.', admin_url( 'admin.php' ) . '?page=gf_settings&subview=recaptcha' ) );
|
||||
}
|
||||
|
||||
$stoken = '';
|
||||
|
||||
if ( ! empty( $this->secret_key ) && ! empty( $secure_token ) && $this->use_stoken() ) {
|
||||
// The secure token is a deprecated feature of the reCAPTCHA API.
|
||||
// https://developers.google.com/recaptcha/docs/secure_token
|
||||
$secure_token = self::create_recaptcha_secure_token( $this->secret_key );
|
||||
$stoken = sprintf( 'data-stoken=\'%s\'', esc_attr( $secure_token ) );
|
||||
}
|
||||
|
||||
$size = '';
|
||||
$badge = '';
|
||||
|
||||
if ( $type == 'invisible' ) {
|
||||
$size = "data-size='invisible'";
|
||||
$badge = $this->captchaBadge ? $this->captchaBadge : 'bottomright';
|
||||
$tabindex = -1;
|
||||
} else {
|
||||
$tabindex = GFCommon::$tab_index > 0 ? GFCommon::$tab_index++ : 0;
|
||||
}
|
||||
|
||||
$output = "<div id='" . esc_attr( $field_id ) ."' class='ginput_container ginput_recaptcha' data-sitekey='" . esc_attr( $this->site_key ) . "' {$stoken} data-theme='" . esc_attr( $theme ) . "' data-tabindex='{$tabindex}' {$size} data-badge='{$badge}'></div>";
|
||||
|
||||
$recaptcha_response = $this->get_posted_recaptcha_response();
|
||||
|
||||
if ( ! $this->requires_encoding( $form, $recaptcha_response ) ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<input
|
||||
type="hidden"
|
||||
name="g-recaptcha-response"
|
||||
value="<?php esc_attr_e( $this->get_encoded_recaptcha_response( $form, $recaptcha_response) ); ?>"
|
||||
/>
|
||||
<?php
|
||||
return $output .= ob_get_clean();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the reCAPTCHA response with details from Google.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param array $form The form data.
|
||||
* @param string $response The posted response data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_encoded_recaptcha_response( $form, $response ) {
|
||||
if ( ! $this->response ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$this->response->token = $response;
|
||||
|
||||
return GFCommon::openssl_encrypt( base64_encode( json_encode( $this->response ) ), $this->secret_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode and return the value of g-recaptcha-response field.
|
||||
*
|
||||
* The first time this method is called, the $response parameter will be the result of the reCAPTCHA callback,
|
||||
* and decryption will fail. On subsequent requests, it should contain an encoded string of the reCAPTCHA response
|
||||
* and the original token used to make the request.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param string $response An openssl encoded string, or the reCAPTCHA token on the very first call.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_decoded_recaptcha_response( $response ) {
|
||||
$decoded_response = GFCommon::openssl_decrypt( $response, $this->get_secret_key() );
|
||||
|
||||
if ( ! $decoded_response ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return json_decode( base64_decode( $decoded_response ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the reCAPTCHA response should be saved and encoded for validation on the final form page.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param array $form The form data.
|
||||
* @param string $recaptcha_response The reCAPTCHA response.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function requires_encoding( $form, $recaptcha_response ) {
|
||||
return $recaptcha_response && ! $this->failed_validation && GFFormDisplay::get_current_page( rgar( $form, 'id' ) ) != $this->pageNumber && ! $this->is_on_last_page( $form );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this CAPTCHA field is on the last page of the given form.
|
||||
*
|
||||
* @since 2.4.24
|
||||
*
|
||||
* @param array $form The form data.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_on_last_page( $form ) {
|
||||
$pages = GFAPI::get_fields_by_type( $form, array( 'page' ) );
|
||||
|
||||
return count( $pages ) + 1 === (int) $this->pageNumber;
|
||||
}
|
||||
|
||||
public function get_captcha() {
|
||||
if ( ! class_exists( 'ReallySimpleCaptcha' ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$captcha = $this->get_simple_captcha();
|
||||
|
||||
//If captcha folder does not exist and can't be created, return an empty captcha
|
||||
if ( ! wp_mkdir_p( $captcha->tmp_dir ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$captcha->char_length = 5;
|
||||
switch ( $this->simpleCaptchaSize ) {
|
||||
case 'small' :
|
||||
$captcha->img_size = array( 100, 28 );
|
||||
$captcha->font_size = 18;
|
||||
$captcha->base = array( 8, 20 );
|
||||
$captcha->font_char_width = 17;
|
||||
|
||||
break;
|
||||
|
||||
case 'large' :
|
||||
$captcha->img_size = array( 200, 56 );
|
||||
$captcha->font_size = 32;
|
||||
$captcha->base = array( 18, 42 );
|
||||
$captcha->font_char_width = 35;
|
||||
break;
|
||||
|
||||
default :
|
||||
$captcha->img_size = array( 150, 42 );
|
||||
$captcha->font_size = 26;
|
||||
$captcha->base = array( 15, 32 );
|
||||
$captcha->font_char_width = 25;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->simpleCaptchaFontColor ) ) {
|
||||
$captcha->fg = $this->hex2rgb( $this->simpleCaptchaFontColor );
|
||||
}
|
||||
if ( ! empty( $this->simpleCaptchaBackgroundColor ) ) {
|
||||
$captcha->bg = $this->hex2rgb( $this->simpleCaptchaBackgroundColor );
|
||||
}
|
||||
|
||||
$word = $captcha->generate_random_word();
|
||||
$prefix = mt_rand();
|
||||
$filename = $captcha->generate_image( $prefix, $word );
|
||||
$url = RGFormsModel::get_upload_url( 'captcha' ) . '/' . $filename;
|
||||
$path = $captcha->tmp_dir . $filename;
|
||||
|
||||
if ( GFCommon::is_ssl() && strpos( $url, 'http:' ) !== false ) {
|
||||
$url = str_replace( 'http:', 'https:', $url );
|
||||
}
|
||||
|
||||
return array( 'path' => $path, 'url' => $url, 'height' => $captcha->img_size[1], 'width' => $captcha->img_size[0], 'prefix' => $prefix );
|
||||
}
|
||||
|
||||
public function get_simple_captcha() {
|
||||
$captcha = new ReallySimpleCaptcha();
|
||||
$captcha->tmp_dir = RGFormsModel::get_upload_path( 'captcha' ) . '/';
|
||||
|
||||
return $captcha;
|
||||
}
|
||||
|
||||
public function get_math_captcha( $pos ) {
|
||||
if ( ! class_exists( 'ReallySimpleCaptcha' ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$captcha = $this->get_simple_captcha();
|
||||
|
||||
//If captcha folder does not exist and can't be created, return an empty captcha
|
||||
if ( ! wp_mkdir_p( $captcha->tmp_dir ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$captcha->char_length = 1;
|
||||
if ( $pos == 1 || $pos == 3 ) {
|
||||
$captcha->chars = '0123456789';
|
||||
} else {
|
||||
$captcha->chars = '+';
|
||||
}
|
||||
|
||||
switch ( $this->simpleCaptchaSize ) {
|
||||
case 'small' :
|
||||
$captcha->img_size = array( 23, 28 );
|
||||
$captcha->font_size = 18;
|
||||
$captcha->base = array( 6, 20 );
|
||||
$captcha->font_char_width = 17;
|
||||
|
||||
break;
|
||||
|
||||
case 'large' :
|
||||
$captcha->img_size = array( 36, 56 );
|
||||
$captcha->font_size = 32;
|
||||
$captcha->base = array( 10, 42 );
|
||||
$captcha->font_char_width = 35;
|
||||
break;
|
||||
|
||||
default :
|
||||
$captcha->img_size = array( 30, 42 );
|
||||
$captcha->font_size = 26;
|
||||
$captcha->base = array( 9, 32 );
|
||||
$captcha->font_char_width = 25;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->simpleCaptchaFontColor ) ) {
|
||||
$captcha->fg = $this->hex2rgb( $this->simpleCaptchaFontColor );
|
||||
}
|
||||
if ( ! empty( $this->simpleCaptchaBackgroundColor ) ) {
|
||||
$captcha->bg = $this->hex2rgb( $this->simpleCaptchaBackgroundColor );
|
||||
}
|
||||
|
||||
$word = $captcha->generate_random_word();
|
||||
$prefix = mt_rand();
|
||||
$filename = $captcha->generate_image( $prefix, $word );
|
||||
$url = RGFormsModel::get_upload_url( 'captcha' ) . '/' . $filename;
|
||||
$path = $captcha->tmp_dir . $filename;
|
||||
|
||||
if ( GFCommon::is_ssl() && strpos( $url, 'http:' ) !== false ) {
|
||||
$url = str_replace( 'http:', 'https:', $url );
|
||||
}
|
||||
|
||||
return array( 'path' => $path, 'url' => $url, 'height' => $captcha->img_size[1], 'width' => $captcha->img_size[0], 'prefix' => $prefix );
|
||||
}
|
||||
|
||||
private function hex2rgb( $color ) {
|
||||
if ( $color[0] == '#' ) {
|
||||
$color = substr( $color, 1 );
|
||||
}
|
||||
|
||||
if ( strlen( $color ) == 6 ) {
|
||||
list( $r, $g, $b ) = array(
|
||||
$color[0] . $color[1],
|
||||
$color[2] . $color[3],
|
||||
$color[4] . $color[5],
|
||||
);
|
||||
} elseif ( strlen( $color ) == 3 ) {
|
||||
list( $r, $g, $b ) = array( $color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2] );
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
$r = hexdec( $r );
|
||||
$g = hexdec( $g );
|
||||
$b = hexdec( $b );
|
||||
|
||||
return array( $r, $g, $b );
|
||||
}
|
||||
|
||||
public function create_recaptcha_secure_token( $secret_key ) {
|
||||
|
||||
// If required cypher is not available, skip
|
||||
if ( ! defined( 'MCRYPT_RIJNDAEL_128' ) ) {
|
||||
GFCommon::log_error( __METHOD__ . sprintf( '(): Legacy MCRYPT_RIJNDAEL_128 cypher not available on system. Generate new reCAPTCHA v2 keys (https://www.google.com/recaptcha/admin/create) and update your Gravity Forms reCAPTCHA Settings (%s) to resolve.', admin_url( 'admin.php' ) . '?page=gf_settings&subview=recaptcha' ) );
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$secret_key = substr( hash( 'sha1', $secret_key, true ), 0, 16 );
|
||||
$session_id = uniqid( 'recaptcha' );
|
||||
$ts_ms = round( ( microtime( true ) - 1 ) * 1000 );
|
||||
|
||||
//create json string
|
||||
$params = array( 'session_id' => $session_id, 'ts_ms' => $ts_ms );
|
||||
$plaintext = json_encode( $params );
|
||||
GFCommon::log_debug( 'recaptcha token parameters: ' . $plaintext );
|
||||
|
||||
//pad json string
|
||||
$pad = 16 - ( strlen( $plaintext ) % 16 );
|
||||
$padded = $plaintext . str_repeat( chr( $pad ), $pad );
|
||||
|
||||
//encrypt as 128
|
||||
$encrypted = GFCommon::openssl_encrypt( $padded, $secret_key, MCRYPT_RIJNDAEL_128 );
|
||||
|
||||
$token = str_replace( array( '+', '/', '=' ), array( '-', '_', '' ), $encrypted );
|
||||
GFCommon::log_debug( ' token being used is: ' . $token );
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
public function use_stoken() {
|
||||
// 'gform_recaptcha_keys_status' will be set to true if new keys have been entered
|
||||
return ! get_option( 'gform_recaptcha_keys_status', false );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_CAPTCHA() );
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,596 +0,0 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* The Consent Field keeps track of exactly what the user consented to. The consent value ("1"), checkbox label and the Form revision ID
|
||||
* are all stored in the entry meta table in separate input values when consent is given.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* Class GF_Field_Consent
|
||||
*/
|
||||
class GF_Field_Consent extends GF_Field {
|
||||
|
||||
/**
|
||||
* Declare the field type.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'consent';
|
||||
|
||||
/**
|
||||
* Checked indicator URL.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $checked_indicator_url = '';
|
||||
|
||||
/**
|
||||
* Checked indicator image markup.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $checked_indicator_markup = '';
|
||||
|
||||
/**
|
||||
* Indicates if this field supports state validation.
|
||||
*
|
||||
* @since 2.5.11
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_supports_state_validation = true;
|
||||
|
||||
/**
|
||||
* GF_Field_Consent constructor.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $data Data needed when initiate the class.
|
||||
*/
|
||||
public function __construct( $data = array() ) {
|
||||
parent::__construct( $data );
|
||||
|
||||
/**
|
||||
* Filters the consent checked indicator (image) URL.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string $url Image URL.
|
||||
*/
|
||||
$this->checked_indicator_url = apply_filters( 'gform_consent_checked_indicator', GFCommon::get_base_url() . '/images/tick.png' );
|
||||
|
||||
/**
|
||||
* Filters the consent checked indicator (image) element.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string $tag Image tag.
|
||||
*/
|
||||
$this->checked_indicator_markup = apply_filters( 'gform_consent_checked_indicator_markup', '<img src="' . esc_url( $this->checked_indicator_url ) . '" />' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field title.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Consent', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Offers a “yes/no” consent checkbox and a detailed description of what is being consented to.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--consent';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field button properties for the form editor. The array contains two elements:
|
||||
* 'group' => 'standard_fields' // or 'advanced_fields', 'post_fields', 'pricing_fields'
|
||||
* 'text' => 'Button text'
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_form_editor_button() {
|
||||
return array(
|
||||
'group' => 'advanced_fields',
|
||||
'text' => $this->get_form_editor_field_title(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class names of the settings which should be available on the field in the form editor.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'checkbox_label_setting',
|
||||
'rules_setting',
|
||||
'visibility_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if this field type can be used when configuring conditional logic rules.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_conditional_logic_supported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML tag for the field container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container_tag( $form ) {
|
||||
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form ) ) {
|
||||
return parent::get_field_container_tag( $form );
|
||||
}
|
||||
|
||||
return 'fieldset';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field inner markup.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param array $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
* @param null|array $entry Null or the Entry Object currently being edited.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_input( $form, $value = array(), $entry = null ) {
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
$is_admin = $is_form_editor || $is_entry_detail;
|
||||
|
||||
$html_input_type = 'checkbox';
|
||||
|
||||
$id = (int) $this->id;
|
||||
$tabindex = $this->get_tabindex();
|
||||
$disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
|
||||
$required_attribute = $this->isRequired ? 'aria-required="true"' : '';
|
||||
$invalid_attribute = $this->failed_validation ? 'aria-invalid="true"' : 'aria-invalid="false"';
|
||||
|
||||
$target_input_id = parent::get_first_input_id( $form );
|
||||
$for_attribute = empty( $target_input_id ) ? '' : "for='{$target_input_id}'";
|
||||
$label_class_attribute = 'class="gform-field-label gform-field-label--type-inline gfield_consent_label"';
|
||||
$required_div = ( $this->labelPlacement === 'hidden_label' && $this->isRequired ) ? $this->get_required_indicator() : '';
|
||||
|
||||
if ( $is_admin && ! GFCommon::is_entry_detail_edit() ) {
|
||||
$checkbox_label = ! is_array( $value ) || empty( $value[ $id . '.2' ] ) ? $this->checkboxLabel : $value[ $id . '.2' ];
|
||||
$revision_id = ! is_array( $value ) || empty( $value[ $id . '.3' ] ) ? GFFormsModel::get_latest_form_revisions_id( $form['id'] ) : $value[ $id . '.3' ];
|
||||
$value = ! is_array( $value ) || empty( $value[ $id . '.1' ] ) ? '0' : esc_attr( $value[ $id . '.1' ] );
|
||||
} else {
|
||||
$checkbox_label = trim( $this->checkboxLabel );
|
||||
$revision_id = GFFormsModel::get_latest_form_revisions_id( $form['id'] );
|
||||
// We compare if the description text from different revisions has been changed.
|
||||
$current_description = $this->get_field_description_from_revision( $revision_id );
|
||||
$submitted_description = $this->get_field_description_from_revision( $value[ $id . '.3' ] );
|
||||
|
||||
$value = ! is_array( $value ) || empty( $value[ $id . '.1' ] ) || ( $checkbox_label !== $value[ $id . '.2' ] ) || ( $current_description !== $submitted_description ) ? '0' : esc_attr( $value[ $id . '.1' ] );
|
||||
}
|
||||
$checked = $is_form_editor ? '' : checked( '1', $value, false );
|
||||
|
||||
$description = $is_entry_detail ? $this->get_field_description_from_revision( $revision_id ) : $this->description;
|
||||
$extra_describedby_ids = empty( $description ) ? array() : array( "gfield_consent_description_{$form['id']}_{$this->id}" );
|
||||
$aria_describedby = $this->get_aria_describedby( $extra_describedby_ids );
|
||||
|
||||
$input = "<input name='input_{$id}.1' id='{$target_input_id}' type='{$html_input_type}' value='1' {$tabindex} {$aria_describedby} {$required_attribute} {$invalid_attribute} {$disabled_text} {$checked} /> <label {$label_class_attribute} {$for_attribute} >{$checkbox_label}{$required_div}</label>";
|
||||
$input .= "<input type='hidden' name='input_{$id}.2' value='" . esc_attr( $checkbox_label ) . "' class='gform_hidden' />";
|
||||
$input .= "<input type='hidden' name='input_{$id}.3' value='" . esc_attr( $revision_id ) . "' class='gform_hidden' />";
|
||||
|
||||
if ( $is_entry_detail ) {
|
||||
$input .= $this->get_description( $this->get_field_description_from_revision( $revision_id ), '' );
|
||||
}
|
||||
|
||||
return sprintf( "<div class='ginput_container ginput_container_consent'>%s</div>", $input );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the input ID to be assigned to the field label for attribute.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_first_input_id( $form ) {
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the markup for the field description.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string $description The field description.
|
||||
* @param string $css_class The css class to be assigned to the description container.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description( $description, $css_class ) {
|
||||
if ( ! empty( $description ) ) {
|
||||
$id = "gfield_consent_description_{$this->formId}_{$this->id}";
|
||||
|
||||
$css_class .= ' gfield_consent_description';
|
||||
|
||||
return "<div class='$css_class' id='$id'>" . nl2br( $description ) . '</div>';
|
||||
}
|
||||
|
||||
return parent::get_description( $description, $css_class );
|
||||
}
|
||||
|
||||
/**
|
||||
* If a field has a description, the aria-describedby attribute for the input field is returned.
|
||||
* This method is specific to the consent field since the consent description has a different ID pattern.
|
||||
*
|
||||
* @since 2.6.8
|
||||
*
|
||||
* @param array|string $extra_ids Any extra ids that should be added to the describedby attribute.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_aria_describedby( $extra_ids = array() ) {
|
||||
|
||||
$describedby_ids = is_array( $extra_ids ) ? $extra_ids : explode( ' ', $extra_ids );
|
||||
|
||||
if ( $this->failed_validation ) {
|
||||
$describedby_ids[] = "validation_message_{$this->formId}_{$this->id}";
|
||||
}
|
||||
|
||||
if ( empty( $describedby_ids ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return 'aria-describedby="' . implode( ' ', $describedby_ids ) . '"';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when determining if the field has failed required validation.
|
||||
*
|
||||
* The consent field has three inputs; only the checkbox is required.
|
||||
*
|
||||
* @since 2.7.5
|
||||
*
|
||||
* @param int $form_id The ID of the form currently being processed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_value_submission_empty( $form_id ) {
|
||||
return rgblank( rgpost( 'input_' . $this->id . '_1' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize and format the value before it is saved to the Entry Object.
|
||||
* We also add the value of inputs .2 and .3 here since they are not displayed in the form.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string $value The value to be saved.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param string $input_name The input name used when accessing the $_POST.
|
||||
* @param int $lead_id The ID of the Entry currently being processed.
|
||||
* @param array $lead The Entry Object currently being processed.
|
||||
*
|
||||
* @return array|string The safe value.
|
||||
*/
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
list( $input, $field_id, $input_id ) = rgexplode( '_', $input_name, 3 );
|
||||
|
||||
switch ( $input_id ) {
|
||||
case '1':
|
||||
$value = ( ! empty( $value ) ) ? '1' : '';
|
||||
break;
|
||||
case '2':
|
||||
$value = ( $lead[ $field_id . '.1' ] === '1' ) ? $value : '';
|
||||
break;
|
||||
case '3':
|
||||
$value = ( $lead[ $field_id . '.1' ] === '1' ) ? $value : '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the values of consent field inputs in merge tags.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string|array $value The field value. Depending on the location the merge tag is being used the following functions may have already been applied to the value: esc_html, nl2br, and urlencode.
|
||||
* @param string $input_id The field or input ID from the merge tag currently being processed.
|
||||
* @param array $entry The Entry Object currently being processed.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
* @param string $modifier The merge tag modifier. e.g. value.
|
||||
* @param string|array $raw_value The raw field value from before any formatting was applied to $value.
|
||||
* @param bool $url_encode Indicates if the urlencode function may have been applied to the $value.
|
||||
* @param bool $esc_html Indicates if the esc_html function may have been applied to the $value.
|
||||
* @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
|
||||
* @param bool $nl2br Indicates if the nl2br function may have been applied to the $value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
|
||||
list( $field_id, $input_id ) = explode( '.', $input_id );
|
||||
|
||||
switch ( $input_id ) {
|
||||
case '1':
|
||||
$value = ! rgblank( $value ) ? $this->checked_indicator_markup : '';
|
||||
break;
|
||||
case '3':
|
||||
$value = ! rgblank( $value ) ? $this->get_field_description_from_revision( $value ) : '';
|
||||
if ( $value !== '' && $nl2br ) {
|
||||
$value = nl2br( $value );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value for display on the entries list page.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string|array $value The field value.
|
||||
* @param array $entry The Entry Object currently being processed.
|
||||
* @param string $field_id The field or input ID currently being processed.
|
||||
* @param array $columns The properties for the columns being displayed on the entry list page.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
|
||||
list( $field_id, $input_id ) = explode( '.', $field_id );
|
||||
|
||||
switch ( $input_id ) {
|
||||
case '1':
|
||||
$value = ! rgblank( $value ) ? $this->checked_indicator_markup : '';
|
||||
$value .= ! rgblank( $value ) ? ' ' . trim( $entry[ $this->id . '.2' ] ) : '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value for display on the entry detail page and for the {all_fields} merge tag.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param string|array $value The field value.
|
||||
* @param string $currency The entry currency code.
|
||||
* @param bool|false $use_text When processing choice based fields should the choice text be returned instead of the value.
|
||||
* @param string $format The format requested for the location the merge is being used. Possible values: html, text or url.
|
||||
* @param string $media The location where the value will be displayed. Possible values: screen or email.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
$return = '';
|
||||
|
||||
if ( is_array( $value ) && ! empty( $value ) ) {
|
||||
$consent = trim( $value[ $this->id . '.1' ] );
|
||||
$text = trim( $value[ $this->id . '.2' ] );
|
||||
$revision_id = absint( trim( $value[ $this->id . '.3' ] ) );
|
||||
|
||||
if ( ! rgblank( $consent ) ) {
|
||||
$return = $this->checked_indicator_markup;
|
||||
$return .= ' ' . wp_kses_post( $text );
|
||||
|
||||
if ( $media === 'screen' ) {
|
||||
// checking revisions.
|
||||
$description = $this->get_field_description_from_revision( $revision_id );
|
||||
|
||||
if ( ! empty( $description ) ) {
|
||||
$return .= '<br /><div class="gfield_consent_description">' . nl2br( $description ) . '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entry value before it is used in entry exports and by framework add-ons using GFAddOn::get_field_value().
|
||||
*
|
||||
* For CSV export return a string or array.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param array $entry The entry currently being processed.
|
||||
* @param string $input_id The field or input ID.
|
||||
* @param bool|false $use_text When processing choice based fields should the choice text be returned instead of the value.
|
||||
* @param bool|false $is_csv Is the value going to be used in the .csv entries export.
|
||||
*
|
||||
* @return string|array
|
||||
*/
|
||||
public function get_value_export( $entry, $input_id = '', $use_text = false, $is_csv = false ) {
|
||||
if ( empty( $input_id ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$value = parent::get_value_export( $entry, $input_id, $use_text, $is_csv );
|
||||
|
||||
list( $field_id, $input_id ) = rgexplode( '.', $input_id, 2 );
|
||||
|
||||
switch ( $input_id ) {
|
||||
case '1':
|
||||
$value = ! rgblank( $value ) ? esc_html__( 'Checked', 'gravityforms' ) : esc_html__( 'Not Checked', 'gravityforms' );
|
||||
break;
|
||||
case '3':
|
||||
$value = ! rgblank( $value ) ? $this->get_field_description_from_revision( $value ) : '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces settings into expected values while saving the form object.
|
||||
*
|
||||
* No escaping should be done at this stage to prevent double escaping on output.
|
||||
*
|
||||
* @since 2.4
|
||||
*/
|
||||
public function sanitize_settings() {
|
||||
parent::sanitize_settings();
|
||||
$this->checkboxLabel = $this->maybe_wp_kses( $this->checkboxLabel );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filter settings for the current field.
|
||||
*
|
||||
* If overriding to add custom settings call the parent method first to get the default settings.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_settings() {
|
||||
$filter_settings = array(
|
||||
'key' => $this->id . '.1',
|
||||
'text' => GFFormsModel::get_label( $this ),
|
||||
'preventMultiple' => false,
|
||||
'operators' => $this->get_filter_operators(),
|
||||
);
|
||||
|
||||
$values = $this->get_filter_values();
|
||||
if ( ! empty( $values ) ) {
|
||||
$filter_settings['values'] = $values;
|
||||
}
|
||||
|
||||
return $filter_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filter operators for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_operators() {
|
||||
$operators = array( 'is', 'isnot' );
|
||||
|
||||
return $operators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filters values setting for the current field.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_filter_values() {
|
||||
$choices = array(
|
||||
array(
|
||||
'value' => '1',
|
||||
'text' => esc_html__( 'Checked', 'gravityforms' ),
|
||||
),
|
||||
);
|
||||
|
||||
return $choices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get consent description from the form revision.
|
||||
*
|
||||
* @since 2.4
|
||||
*
|
||||
* @param int $revision_id Revision ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_description_from_revision( $revision_id ) {
|
||||
global $wpdb;
|
||||
$revisions_table_name = GFFormsModel::get_form_revisions_table_name();
|
||||
$display_meta = $wpdb->get_var( $wpdb->prepare( "SELECT display_meta FROM $revisions_table_name WHERE form_id=%d AND id=%d", $this->formId, $revision_id ) );
|
||||
$value = '';
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
|
||||
if ( ! empty( $display_meta ) ) {
|
||||
$display_meta_array = json_decode( $display_meta, true );
|
||||
foreach ( $display_meta_array['fields'] as $field ) {
|
||||
if ( $field['id'] === $this->id ) {
|
||||
$value = $field['description'];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$value = ( ! empty( $this->description ) ) ? $this->description : '';
|
||||
}
|
||||
|
||||
if ( $is_entry_detail ) {
|
||||
$value = $this->maybe_wp_kses( $value );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_Consent() );
|
||||
@@ -1,626 +0,0 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'GFForms' ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
class GF_Field_CreditCard extends GF_Field {
|
||||
|
||||
public $type = 'creditcard';
|
||||
|
||||
public function get_form_editor_field_title() {
|
||||
return esc_attr__( 'Credit Card', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor description.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_description() {
|
||||
return esc_attr__( 'Allows users to enter credit card information.', 'gravityforms' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field's form editor icon.
|
||||
*
|
||||
* This could be an icon url or a gform-icon class.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_editor_field_icon() {
|
||||
return 'gform-icon--credit-card';
|
||||
}
|
||||
|
||||
function get_form_editor_field_settings() {
|
||||
return array(
|
||||
'conditional_logic_field_setting',
|
||||
'force_ssl_field_setting',
|
||||
'credit_card_style_setting',
|
||||
'error_message_setting',
|
||||
'label_setting',
|
||||
'label_placement_setting',
|
||||
'sub_labels_setting',
|
||||
'sub_label_placement_setting',
|
||||
'label_placement_setting',
|
||||
'admin_label_setting',
|
||||
'rules_setting',
|
||||
'description_setting',
|
||||
'css_class_setting',
|
||||
'credit_card_setting',
|
||||
'input_placeholders_setting',
|
||||
);
|
||||
}
|
||||
|
||||
public function get_form_editor_button() {
|
||||
return array(); // this button is conditionally added in the form detail page
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the IDs of required inputs.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_required_inputs_ids() {
|
||||
return array( '1', '2_month', '2_year', '3' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array that contains aria-describedby attribute for each input.
|
||||
*
|
||||
* Depending on each input's validation state, aria-describedby takes the value of the validation message container ID, the description only or nothing.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $required_inputs_ids IDs of required field inputs.
|
||||
* @param array|string $values Inputs values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_inputs_describedby_attributes( $required_inputs_ids, $values ) {
|
||||
|
||||
$describedby_attributes = array();
|
||||
$warning_container_id = ! GFCommon::is_ssl() && ! ( $this->is_form_editor() || $this->is_entry_detail() ) ? "field_{$this->formId}_{$this->id}_creditcard_warning_message" : '';
|
||||
|
||||
foreach ( $this->inputs as $input ) {
|
||||
$input_id = str_replace( $this->id . '.', '', $input['id'] );
|
||||
$input_value = GFForms::get( $input['id'], $values );
|
||||
if ( ! empty( $_POST[ 'is_submit_' . $this->formId ] ) && $this->isRequired && in_array( $input_id, $required_inputs_ids ) && empty( $input_value ) ) {
|
||||
$describedby_attributes[ $input_id ] = "aria-describedby='validation_message_{$this->formId}_{$this->id} {$warning_container_id}'";
|
||||
} else {
|
||||
$describedby_attributes[ $input_id ] = empty( $warning_container_id ) ? '' : "aria-describedby='{$warning_container_id}'";
|
||||
}
|
||||
}
|
||||
|
||||
return $describedby_attributes;
|
||||
}
|
||||
|
||||
public function validate( $value, $form ) {
|
||||
$card_number = rgpost( 'input_' . $this->id . '_1' );
|
||||
$expiration_date = rgpost( 'input_' . $this->id . '_2' );
|
||||
$security_code = rgpost( 'input_' . $this->id . '_3' );
|
||||
|
||||
if ( $this->isRequired && ( empty( $card_number ) || empty( $security_code ) || empty( $expiration_date[0] ) || empty( $expiration_date[1] ) ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = empty( $this->errorMessage ) ? esc_html__( 'Please enter your credit card information.', 'gravityforms' ) : $this->errorMessage;
|
||||
} elseif ( ! empty( $card_number ) ) {
|
||||
$card_type = GFCommon::get_card_type( $card_number );
|
||||
|
||||
if ( empty( $security_code ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = esc_html__( "Please enter your card's security code.", 'gravityforms' );
|
||||
} elseif ( ! $card_type ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = esc_html__( 'Invalid credit card number.', 'gravityforms' );
|
||||
} elseif ( ! $this->is_card_supported( $card_type['slug'] ) ) {
|
||||
$this->failed_validation = true;
|
||||
$this->validation_message = $card_type['name'] . ' ' . esc_html__( 'is not supported. Please enter one of the supported credit cards.', 'gravityforms' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function is_card_supported( $card_slug ) {
|
||||
$supported_cards = $this->creditCards;
|
||||
$default_cards = array( 'amex', 'discover', 'mastercard', 'visa' );
|
||||
|
||||
if ( ! empty( $supported_cards ) && in_array( $card_slug, $supported_cards ) ) {
|
||||
return true;
|
||||
} elseif ( empty( $supported_cards ) && in_array( $card_slug, $default_cards ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public function get_value_submission( $field_values, $get_from_post_global_var = true ) {
|
||||
|
||||
if ( $get_from_post_global_var ) {
|
||||
$value[ $this->id . '.1' ] = $this->get_input_value_submission( 'input_' . $this->id . '_1', rgar( $this->inputs[0], 'name' ), $field_values, true );
|
||||
$value[ $this->id . '.2' ] = $this->get_input_value_submission( 'input_' . $this->id . '_2', rgar( $this->inputs[1], 'name' ), $field_values, true );
|
||||
$value[ $this->id . '.3' ] = $this->get_input_value_submission( 'input_' . $this->id . '_3', rgar( $this->inputs[3], 'name' ), $field_values, true );
|
||||
$value[ $this->id . '.4' ] = $this->get_input_value_submission( 'input_' . $this->id . '_4', rgar( $this->inputs[4], 'name' ), $field_values, true );
|
||||
$value[ $this->id . '.5' ] = $this->get_input_value_submission( 'input_' . $this->id . '_5', rgar( $this->inputs[5], 'name' ), $field_values, true );
|
||||
} else {
|
||||
$value = $this->get_input_value_submission( 'input_' . $this->id, $this->inputName, $field_values, $get_from_post_global_var );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML tag for the field container.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param array $form The current Form object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_container_tag( $form ) {
|
||||
|
||||
if ( GFCommon::is_legacy_markup_enabled( $form ) ) {
|
||||
return parent::get_field_container_tag( $form );
|
||||
}
|
||||
|
||||
return 'fieldset';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an insecure page warning below the field content.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @param string|array $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
|
||||
* @param bool $force_frontend_label Should the frontend label be displayed in the admin even if an admin label is configured.
|
||||
* @param array $form The Form Object currently being processed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_field_content( $value, $force_frontend_label, $form ) {
|
||||
|
||||
$is_form_editor = GFCommon::is_form_editor();
|
||||
$is_entry_detail = GFCommon::is_entry_detail();
|
||||
$is_admin = $is_form_editor || $is_entry_detail;
|
||||
|
||||
// Get existing field content.
|
||||
$field_content = parent::get_field_content( $value, $force_frontend_label, $form );
|
||||
|
||||
// If SSL is not used, display warning message.
|
||||
if ( ! GFCommon::is_ssl() && ! $is_admin ) {
|
||||
$field_content = "<div class='gfield_description gfield_validation_message gfield_creditcard_warning_message' id='field_{$form['id']}_{$this->id}_creditcard_warning_message'><span>" . esc_html__( 'This page is unsecured. Do not enter a real credit card number! Use this field only for testing purposes. ', 'gravityforms' ) . '</span></div>' . $field_content;
|
||||
}
|
||||
|
||||
return $field_content;
|
||||
|
||||
}
|
||||
|
||||
public function get_field_input( $form, $value = '', $entry = null ) {
|
||||
$is_entry_detail = $this->is_entry_detail();
|
||||
$is_form_editor = $this->is_form_editor();
|
||||
|
||||
$form_id = $form['id'];
|
||||
$id = intval( $this->id );
|
||||
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
|
||||
$form_id = ( $is_entry_detail || $is_form_editor ) && empty( $form_id ) ? rgget( 'id' ) : $form_id;
|
||||
|
||||
$disabled_text = $is_form_editor ? "disabled='disabled'" : '';
|
||||
$class_suffix = $is_entry_detail ? '_admin' : '';
|
||||
|
||||
|
||||
$form_sub_label_placement = rgar( $form, 'subLabelPlacement' );
|
||||
$field_sub_label_placement = $this->subLabelPlacement;
|
||||
$is_sub_label_above = $field_sub_label_placement == 'above' || ( empty( $field_sub_label_placement ) && $form_sub_label_placement == 'above' );
|
||||
$sub_label_class = $field_sub_label_placement == 'hidden_label' ? "hidden_sub_label screen-reader-text" : '';
|
||||
|
||||
$card_number = '';
|
||||
$card_name = '';
|
||||
$expiration_month = '';
|
||||
$expiration_year = '';
|
||||
$security_code = '';
|
||||
$autocomplete = "autocomplete='off'";
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$card_number = esc_attr( rgget( $this->id . '.1', $value ) );
|
||||
$card_name = esc_attr( rgget( $this->id . '.5', $value ) );
|
||||
$expiration_date = rgget( $this->id . '.2', $value );
|
||||
if ( ! is_array( $expiration_date ) && ! empty( $expiration_date ) ) {
|
||||
$expiration_date = explode( '/', $expiration_date );
|
||||
}
|
||||
|
||||
if ( is_array( $expiration_date ) && count( $expiration_date ) == 2 ) {
|
||||
$expiration_month = $expiration_date[0];
|
||||
$expiration_year = $expiration_date[1];
|
||||
}
|
||||
|
||||
$security_code = esc_attr( rgget( $this->id . '.3', $value ) );
|
||||
}
|
||||
|
||||
$action = ! ( $is_entry_detail || $is_form_editor ) ? "gformMatchCard(\"{$field_id}_1\");" : '';
|
||||
|
||||
$onchange = "onchange='{$action}'";
|
||||
$onkeyup = "onkeyup='{$action}'";
|
||||
|
||||
$card_icons = '';
|
||||
$cards = GFCommon::get_card_types();
|
||||
$enabled_card_names = array();
|
||||
|
||||
foreach ( $cards as $card ) {
|
||||
|
||||
$style = '';
|
||||
if ( $this->is_card_supported( $card['slug'] ) ) {
|
||||
$print_card = true;
|
||||
$enabled_card_names[] = rgar( $card, 'name' );
|
||||
} elseif ( $is_form_editor || $is_entry_detail ) {
|
||||
$print_card = true;
|
||||
$style = "style='display:none;'";
|
||||
} else {
|
||||
$print_card = false;
|
||||
}
|
||||
|
||||
if ( $print_card ) {
|
||||
$card_icons .= "<div class='gform_card_icon gform_card_icon_{$card['slug']}' {$style}>{$card['name']}</div>";
|
||||
}
|
||||
}
|
||||
|
||||
$payment_methods = apply_filters( 'gform_payment_methods', array(), $this, $form_id );
|
||||
$payment_options = '';
|
||||
if ( is_array( $payment_methods ) ) {
|
||||
foreach ( $payment_methods as $payment_method ) {
|
||||
$checked = rgpost( 'gform_payment_method' ) == $payment_method['key'] ? "checked='checked'" : '';
|
||||
$payment_options .= "<div class='gform_payment_option gform_payment_{$payment_method['key']}'><input type='radio' name='gform_payment_method' value='{$payment_method['key']}' id='gform_payment_method_{$payment_method['key']}' onclick='gformToggleCreditCard();' onkeypress='gformToggleCreditCard();' {$checked}/> {$payment_method['label']}</div>";
|
||||
}
|
||||
}
|
||||
$checked = rgpost( 'gform_payment_method' ) == 'creditcard' || rgempty( 'gform_payment_method' ) ? "checked='checked'" : '';
|
||||
$card_radio_button = empty( $payment_options ) ? '' : "<input type='radio' name='gform_payment_method' id='gform_payment_method_creditcard' value='creditcard' onclick='gformToggleCreditCard();' onkeypress='gformToggleCreditCard();' {$checked}/>";
|
||||
$card_describer = sprintf(
|
||||
"<span class='screen-reader-text' id='field_%d_%d_supported_creditcards'>%s %s</span>",
|
||||
$form_id,
|
||||
$this->id,
|
||||
esc_html__( 'Supported Credit Cards:', 'gravityforms' ),
|
||||
implode( ', ', $enabled_card_names )
|
||||
);
|
||||
$card_icons = "{$payment_options}<div class='gform_card_icon_container'>{$card_radio_button}{$card_icons}{$card_describer}</div>";
|
||||
|
||||
// Aria attributes.
|
||||
$number_aria_attributes = $this->get_aria_attributes( $value, '1' );
|
||||
$expiration_month_aria_attributes = $this->get_aria_attributes( $value, '2_month' );
|
||||
$expiration_year_aria_attributes = $this->get_aria_attributes( $value, '2_year' );
|
||||
$security_aria_attributes = $this->get_aria_attributes( $value, '3' );
|
||||
$name_aria_attributes = $this->get_aria_attributes( $value, '5' );
|
||||
|
||||
//card number fields
|
||||
$tabindex = $this->get_tabindex();
|
||||
$card_number_field_input = GFFormsModel::get_input( $this, $this->id . '.1' );
|
||||
$validation_helper = ! is_admin() ? "pattern='[0-9]*' title='" . esc_attr__( 'Only digits are allowed', 'gravityforms' ) . "'" : '';
|
||||
$card_number_label = rgar( $card_number_field_input, 'customLabel' ) != '' ? $card_number_field_input['customLabel'] : esc_html__( 'Card Number', 'gravityforms' );
|
||||
$card_number_label = gf_apply_filters( array( 'gform_card_number', $form_id ), $card_number_label, $form_id );
|
||||
|
||||
$card_number_placeholder = $this->get_input_placeholder_attribute( $card_number_field_input );
|
||||
if ( $is_sub_label_above ) {
|
||||
$card_field = "<span class='ginput_full{$class_suffix} gform-grid-col' id='{$field_id}_1_container' >
|
||||
{$card_icons}
|
||||
<label for='{$field_id}_1' id='{$field_id}_1_label' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$card_number_label}</label>
|
||||
<input type='text' name='input_{$id}.1' id='{$field_id}_1' value='{$card_number}' {$tabindex} {$disabled_text} {$onchange} {$onkeyup} {$autocomplete} {$validation_helper} {$card_number_placeholder} {$number_aria_attributes}/>
|
||||
</span>";
|
||||
} else {
|
||||
$card_field = "<span class='ginput_full{$class_suffix} gform-grid-col' id='{$field_id}_1_container' >
|
||||
{$card_icons}
|
||||
<input type='text' name='input_{$id}.1' id='{$field_id}_1' value='{$card_number}' {$tabindex} {$disabled_text} {$onchange} {$onkeyup} {$autocomplete} {$validation_helper} {$card_number_placeholder} {$number_aria_attributes}/>
|
||||
<label for='{$field_id}_1' id='{$field_id}_1_label' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$card_number_label}</label>
|
||||
</span>";
|
||||
}
|
||||
|
||||
// Expiration Date Inputs
|
||||
$expiration_wrapper_tag = $this->get_field_container_tag( $form ) === 'fieldset' ? 'fieldset' : 'span';
|
||||
$expiration_label_tag = $expiration_wrapper_tag === 'fieldset' ? 'legend' : 'label';
|
||||
$expiration_label_for = $expiration_label_tag === 'label' ? " for='{$field_id}_2_month'" : '';
|
||||
$expiration_month_input = GFFormsModel::get_input( $this, $this->id . '.2_month' );
|
||||
|
||||
$expiration_label = rgar( $expiration_month_input, 'customLabel' ) != '' ? esc_html( $expiration_month_input['customLabel'] ) : esc_html__( 'Expiration Date', 'gravityforms' );
|
||||
$expiration_label = gf_apply_filters( array( 'gform_card_expiration', $form_id ), $expiration_label, $form_id );
|
||||
|
||||
// Expiration Date: Month
|
||||
$expiration_month_label = $expiration_wrapper_tag === 'fieldset' ? "<label for='{$field_id}_2_month' class='gform-field-label gform-field-label--type-sub screen-reader-text'>" . esc_html__( 'Month', 'gravityforms' ) . "</label>" : '';
|
||||
$expiration_month_tab_index = $this->get_tabindex();
|
||||
$expiration_month_placeholder = $this->get_input_placeholder_value( $expiration_month_input );
|
||||
$expiration_months = $this->get_expiration_months( $expiration_month, $expiration_month_placeholder );
|
||||
|
||||
// Expiration Date: Year
|
||||
$expiration_year_input = GFFormsModel::get_input( $this, $this->id . '.2_year' );
|
||||
$expiration_year_tab_index = $this->get_tabindex();
|
||||
$expiration_year_placeholder = $this->get_input_placeholder_value( $expiration_year_input );
|
||||
$expiration_years = $this->get_expiration_years( $expiration_year, $expiration_year_placeholder );
|
||||
|
||||
if ( $expiration_wrapper_tag === 'fieldset' ) {
|
||||
$expiration_year_label_for = $is_form_editor ? '' : $field_id . '_2_year';
|
||||
$expiration_year_label = "<label for='{$expiration_year_label_for}' class='gform-field-label gform-field-label--type-sub screen-reader-text'>" . esc_html__( 'Year', 'gravityforms' ) . "</label>";
|
||||
} else {
|
||||
$expiration_year_label = '';
|
||||
}
|
||||
|
||||
// legend tag should be the first child of fieldset, so we are putting out this markup for fieldset
|
||||
// even if the sub-label is below or hidden.
|
||||
if ( $expiration_wrapper_tag === 'fieldset' || $is_sub_label_above ) {
|
||||
$expiration_field = "<span class='ginput_full{$class_suffix} ginput_cardextras gform-grid-col gform-grid-row' id='{$field_id}_2_container'>
|
||||
<{$expiration_wrapper_tag} class='ginput_cardinfo_left{$class_suffix} gform-grid-col' id='{$field_id}_2_cardinfo_left'>
|
||||
<{$expiration_label_tag}{$expiration_label_for} class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$expiration_label}</{$expiration_label_tag}>
|
||||
<span class='ginput_card_expiration_container ginput_card_field gform-grid-row'>
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "<span class='ginput_card_expiration_month_container gform-grid-col'>" : "" ) . "
|
||||
{$expiration_month_label}
|
||||
<select name='input_{$id}.2[]' id='{$field_id}_2_month' {$expiration_month_tab_index} {$disabled_text} class='ginput_card_expiration ginput_card_expiration_month' {$expiration_month_aria_attributes}>
|
||||
{$expiration_months}
|
||||
</select>
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "</span>" : "" ) . "
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "<span class='ginput_card_expiration_year_container gform-grid-col'>" : "" ) . "
|
||||
{$expiration_year_label}
|
||||
<select name='input_{$id}.2[]' id='{$field_id}_2_year' {$expiration_year_tab_index} {$disabled_text} class='ginput_card_expiration ginput_card_expiration_year' {$expiration_year_aria_attributes}>
|
||||
{$expiration_years}
|
||||
</select>
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "</span>" : "" ) . "
|
||||
</span>
|
||||
</{$expiration_wrapper_tag}>";
|
||||
|
||||
} else {
|
||||
$expiration_field = "<span class='ginput_full{$class_suffix} ginput_cardextras gform-grid-col gform-grid-row' id='{$field_id}_2_container'>
|
||||
<{$expiration_wrapper_tag} class='ginput_cardinfo_left{$class_suffix}' id='{$field_id}_2_cardinfo_left'>
|
||||
<span class='ginput_card_expiration_container ginput_card_field'>
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "<span class='ginput_card_expiration_month_container'>" : "" ) . "
|
||||
<select name='input_{$id}.2[]' id='{$field_id}_2_month' {$expiration_month_tab_index} {$disabled_text} class='ginput_card_expiration ginput_card_expiration_month' {$expiration_month_aria_attributes}>
|
||||
{$expiration_months}
|
||||
</select>
|
||||
{$expiration_month_label}
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "</span>" : "" ) . "
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "<span class='ginput_card_expiration_year_container'>" : "" ) . "
|
||||
<select name='input_{$id}.2[]' id='{$field_id}_2_year' {$expiration_year_tab_index} {$disabled_text} class='ginput_card_expiration ginput_card_expiration_year' {$expiration_year_aria_attributes}>
|
||||
{$expiration_years}
|
||||
</select>
|
||||
{$expiration_year_label}
|
||||
" . ( $expiration_wrapper_tag === 'fieldset' ? "</span>" : "" ) . "
|
||||
</span>
|
||||
<{$expiration_label_tag}{$expiration_label_for} class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$expiration_label}</{$expiration_label_tag}>
|
||||
</{$expiration_wrapper_tag}>";
|
||||
}
|
||||
//security code field
|
||||
$tabindex = $this->get_tabindex();
|
||||
$security_code_field_input = GFFormsModel::get_input( $this, $this->id . '.3' );
|
||||
$security_code_label = rgar( $security_code_field_input, 'customLabel' ) != '' ? $security_code_field_input['customLabel'] : esc_html__( 'Security Code', 'gravityforms' );
|
||||
$security_code_label = gf_apply_filters( array( 'gform_card_security_code', $form_id ), $security_code_label, $form_id );
|
||||
$validation_helper = "pattern='[0-9]*' title='" . esc_attr__( 'Only digits are allowed', 'gravityforms' ) . "'";
|
||||
$security_code_placeholder = $this->get_input_placeholder_attribute( $security_code_field_input );
|
||||
if ( $is_sub_label_above ) {
|
||||
$security_field = "<span class='ginput_cardinfo_right{$class_suffix} gform-grid-col' id='{$field_id}_2_cardinfo_right'>
|
||||
<label for='{$field_id}_3' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>$security_code_label</label>
|
||||
<input type='text' name='input_{$id}.3' id='{$field_id}_3' {$tabindex} {$disabled_text} class='ginput_card_security_code' value='{$security_code}' {$autocomplete} {$validation_helper} {$security_code_placeholder} {$security_aria_attributes}/>
|
||||
<span class='ginput_card_security_code_icon'> </span>
|
||||
</span>
|
||||
</span>";
|
||||
} else {
|
||||
$security_field = "<span class='ginput_cardinfo_right{$class_suffix} gform-grid-col' id='{$field_id}_2_cardinfo_right'>
|
||||
<input type='text' name='input_{$id}.3' id='{$field_id}_3' {$tabindex} {$disabled_text} class='ginput_card_security_code' value='{$security_code}' {$autocomplete} {$validation_helper} {$security_code_placeholder} {$security_aria_attributes}/>
|
||||
<span class='ginput_card_security_code_icon'> </span>
|
||||
<label for='{$field_id}_3' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>$security_code_label</label>
|
||||
</span>
|
||||
</span>";
|
||||
}
|
||||
|
||||
$tabindex = $this->get_tabindex();
|
||||
$card_name_field_input = GFFormsModel::get_input( $this, $this->id . '.5' );
|
||||
$card_name_label = rgar( $card_name_field_input, 'customLabel' ) != '' ? $card_name_field_input['customLabel'] : esc_html__( 'Cardholder Name', 'gravityforms' );
|
||||
$card_name_label = gf_apply_filters( array( 'gform_card_name', $form_id ), $card_name_label, $form_id );
|
||||
|
||||
$card_name_placeholder = $this->get_input_placeholder_attribute( $card_name_field_input );
|
||||
if ( $is_sub_label_above ) {
|
||||
$card_name_field = "<span class='ginput_full{$class_suffix} gform-grid-col' id='{$field_id}_5_container'>
|
||||
<label for='{$field_id}_5' id='{$field_id}_5_label' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$card_name_label}</label>
|
||||
<input type='text' name='input_{$id}.5' id='{$field_id}_5' value='{$card_name}' {$tabindex} {$disabled_text} {$card_name_placeholder} {$name_aria_attributes}/>
|
||||
</span>";
|
||||
} else {
|
||||
$card_name_field = "<span class='ginput_full{$class_suffix} gform-grid-col' id='{$field_id}_5_container'>
|
||||
<input type='text' name='input_{$id}.5' id='{$field_id}_5' value='{$card_name}' {$tabindex} {$disabled_text} {$card_name_placeholder} {$name_aria_attributes}/>
|
||||
<label for='{$field_id}_5' id='{$field_id}_5_label' class='gform-field-label gform-field-label--type-sub {$sub_label_class}'>{$card_name_label}</label>
|
||||
</span>";
|
||||
}
|
||||
|
||||
return "<div class='ginput_complex{$class_suffix} ginput_container ginput_container_creditcard gform-grid-row' id='{$field_id}'>" . $card_field . $expiration_field . $security_field . $card_name_field . ' </div>';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the options for the Expiration Date Month drop down.
|
||||
*
|
||||
* @since Unknown
|
||||
* @since 2.5 Added $included_placeholder parameter.
|
||||
*
|
||||
* @param string $selected_month The currently selected month.
|
||||
* @param string $placeholder Placeholder text.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_expiration_months( $selected_month, $placeholder ) {
|
||||
|
||||
$str = '';
|
||||
|
||||
if ( empty( $placeholder ) ) {
|
||||
$placeholder = esc_html__( 'Month', 'gravityforms' );
|
||||
}
|
||||
|
||||
$str .= "<option value=''>{$placeholder}</option>";
|
||||
|
||||
for ( $i = 1; $i < 13; $i ++ ) {
|
||||
$selected = intval( $selected_month ) == $i ? "selected='selected'" : '';
|
||||
$month = str_pad( $i, 2, '0', STR_PAD_LEFT );
|
||||
$str .= "<option value='{$i}' {$selected}>{$month}</option>";
|
||||
}
|
||||
|
||||
return $str;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the options for the Expiration Date Year drop down.
|
||||
*
|
||||
* @since Unknown
|
||||
* @since 2.5 Added $included_placeholder parameter.
|
||||
*
|
||||
* @param string $selected_year The currently selected year.
|
||||
* @param string $placeholder Placeholder text.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_expiration_years( $selected_year, $placeholder ) {
|
||||
|
||||
$str = '';
|
||||
|
||||
if ( empty( $placeholder ) ) {
|
||||
$placeholder = esc_html__( 'Year', 'gravityforms' );
|
||||
}
|
||||
|
||||
$str .= "<option value=''>{$placeholder}</option>";
|
||||
|
||||
$year = intval( date( 'Y' ) );
|
||||
|
||||
for ( $i = $year; $i < ( $year + 20 ); $i ++ ) {
|
||||
$selected = intval( $selected_year ) == $i ? "selected='selected'" : '';
|
||||
$str .= "<option value='{$i}' {$selected}>{$i}</option>";
|
||||
}
|
||||
|
||||
return $str;
|
||||
|
||||
}
|
||||
|
||||
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
|
||||
|
||||
if ( is_array( $value ) ) {
|
||||
$card_number = trim( rgget( $this->id . '.1', $value ) );
|
||||
$card_type = trim( rgget( $this->id . '.4', $value ) );
|
||||
$separator = $format == 'html' ? '<br/>' : "\n";
|
||||
|
||||
return empty( $card_number ) ? '' : $card_type . $separator . $card_number;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function get_form_inline_script_on_page_render( $form ) {
|
||||
|
||||
$field_id = "input_{$form['id']}_{$this->id}";
|
||||
|
||||
if ( $this->forceSSL && ! GFCommon::is_ssl() && ! GFCommon::is_preview() ) {
|
||||
$script = "document.location.href='" . esc_js( RGFormsModel::get_current_page_url( true ) ) . "';";
|
||||
} else {
|
||||
$script = "jQuery(document).ready(function(){ { gformMatchCard(\"{$field_id}_1\"); } } );";
|
||||
}
|
||||
|
||||
$card_rules = $this->get_credit_card_rules();
|
||||
$script = "if(!window['gf_cc_rules']){window['gf_cc_rules'] = new Array(); } window['gf_cc_rules'] = " . GFCommon::json_encode( $card_rules ) . "; $script";
|
||||
|
||||
return $script;
|
||||
}
|
||||
|
||||
public function get_credit_card_rules() {
|
||||
|
||||
$cards = GFCommon::get_card_types();
|
||||
//$supported_cards = //TODO: Only include enabled cards
|
||||
$rules = array();
|
||||
|
||||
foreach ( $cards as $card ) {
|
||||
$prefixes = explode( ',', $card['prefixes'] );
|
||||
foreach ( $prefixes as $prefix ) {
|
||||
$rules[ $card['slug'] ][] = $prefix;
|
||||
}
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function get_entry_inputs() {
|
||||
$inputs = array();
|
||||
// only store month and card number input values
|
||||
foreach ( $this->inputs as $input ) {
|
||||
if ( in_array( $input['id'], array( $this->id . '.1', $this->id . '.4' ) ) ) {
|
||||
$inputs[] = $input;
|
||||
}
|
||||
}
|
||||
|
||||
return $inputs;
|
||||
}
|
||||
|
||||
public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
|
||||
|
||||
//saving last 4 digits of credit card
|
||||
list( $input_token, $field_id_token, $input_id ) = rgexplode( '_', $input_name, 3 );
|
||||
if ( $input_id == '1' ) {
|
||||
$value = str_replace( ' ', '', $value );
|
||||
$card_number_length = strlen( $value );
|
||||
$value = substr( $value, - 4, 4 );
|
||||
$value = str_pad( $value, $card_number_length, 'X', STR_PAD_LEFT );
|
||||
} elseif ( $input_id == '4' ) {
|
||||
|
||||
$value = rgpost( "input_{$field_id_token}_4" );
|
||||
|
||||
if ( ! $value ) {
|
||||
$card_number = rgpost( "input_{$field_id_token}_1" );
|
||||
$card_type = GFCommon::get_card_type( $card_number );
|
||||
$value = $card_type ? $card_type['name'] : '';
|
||||
}
|
||||
} else {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
return $this->sanitize_entry_value( $value, $form['id'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades inputs, if needed.
|
||||
*
|
||||
* @since 2.1.2.7
|
||||
* @access public
|
||||
* @see GF_Field::post_convert_field()
|
||||
*
|
||||
* @uses GF_Field::post_convert_field()
|
||||
* @uses GF_Field_CreditCard::maybe_upgrade_inputs()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function post_convert_field() {
|
||||
parent::post_convert_field();
|
||||
$this->maybe_upgrade_inputs();
|
||||
}
|
||||
|
||||
/**
|
||||
* GF1.8 and earlier used 5 inputs (1 input for the expiration date); GF1.9 changed to 6 inputs (the expiration month and year now separate); upgrade those fields still using the older configuration.
|
||||
*/
|
||||
public function maybe_upgrade_inputs() {
|
||||
$inputs = $this->inputs;
|
||||
$exp_input = $inputs[1];
|
||||
$exp_id = $this->id . '.2';
|
||||
|
||||
if ( count( $inputs ) == 5 && $exp_input['id'] == $exp_id ) {
|
||||
$new_inputs = array(
|
||||
array(
|
||||
'id' => $exp_id . '_month',
|
||||
'label' => esc_html__( 'Expiration Month', 'gravityforms' ),
|
||||
'defaultLabel' => $exp_input['label']
|
||||
),
|
||||
array(
|
||||
'id' => $exp_id . '_year',
|
||||
'label' => esc_html__( 'Expiration Year', 'gravityforms' ),
|
||||
)
|
||||
);
|
||||
|
||||
array_splice( $inputs, 1, 1, $new_inputs );
|
||||
$this->inputs = $inputs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GF_Fields::register( new GF_Field_CreditCard() );
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user