Add gravity flow demo

This commit is contained in:
Almira Krdzic
2018-06-28 10:02:07 +02:00
parent 1b5076bf2f
commit 12a5066018
1106 changed files with 317603 additions and 4720 deletions

View File

@@ -0,0 +1,59 @@
<?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 );
}
}

View File

@@ -0,0 +1,318 @@
<?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' ) );
}
}
// 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' ) );
}
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 );
} else {
$version_info = $this->get_version_info( $this->_slug );
if ( ! rgar( $version_info, 'is_valid_key' ) ) {
$title = $this->_title;
if ( version_compare( $this->_version, $version_info['version'], '<' ) ) {
$new_version = sprintf( esc_html__( 'There is a new version of %s available.', 'gravityforms' ), $title ) . sprintf( ' <a class="thickbox" title="%s" href="plugin-install.php?tab=plugin-information&plugin=%s&TB_iframe=true&width=640&height=808">', $title, $this->_slug ) . sprintf( esc_html__( 'View version %s Details', 'gravityforms' ), $version_info['version'] ) . '</a>. ';
} else {
$new_version = '';
}
$message = $new_version . sprintf( esc_html__( '%sRegister%s your copy of Gravity Forms to receive access to automatic upgrades 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></td>';
GFAddOn::display_plugin_message( $message );
}
}
}
//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 ) {
$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();
}
//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 ] );
} else {
$option->response[ $this->_path ]->plugin = $this->_path;
$option->response[ $this->_path ]->url = $this->_url;
$option->response[ $this->_path ]->slug = $this->_slug;
$option->response[ $this->_path ]->package = str_replace( '{KEY}', $key, $version_info['url'] );
$option->response[ $this->_path ]->new_version = $version_info['version'];
$option->response[ $this->_path ]->id = '0';
}
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;
}
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' ),
'Referer' => get_bloginfo( 'url' ),
);
$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='https://www.gravityforms.com/support/'>", '</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( $wpdb->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&amp;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 ) . '&section=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&amp;plugin=' . urlencode( $plugin_file ), 'upgrade-plugin_' . $plugin_file );
$details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . urlencode( $this->_slug ) . '&section=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>', "&nbsp;<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
}
}

View File

@@ -0,0 +1,271 @@
<?php
if ( ! class_exists( 'GFForms' ) ) {
die();
}
if ( ! class_exists( 'WP_Async_Request' ) ) {
require_once( GFCommon::get_base_path() . '/includes/libraries/wp-async-request.php' );
}
if ( ! class_exists( 'GF_Background_Process' ) ) {
require_once( GFCommon::get_base_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 ) {
// Extract items.
$addon = $item['addon'];
$feed = $item['feed'];
$entry = GFAPI::get_entry( $item['entry_id'] );
$form = GFAPI::get_form( $item['form_id'] );
// 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->get_slug()} but entry could not be found. Bailing." );
return false;
}
// Get feed name.
$feed_name = rgars( $feed, 'meta/feed_name' ) ? $feed['meta']['feed_name'] : rgars( $feed, 'meta/feedName' );
$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->get_slug()}. Bailing." );
return false;
}
$item = $this->increment_attempts( $item );
// Remove task if it was attempted before but failed to complete.
if ( $item['attempts'] > 1 ) {
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 false;
}
// 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
* @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, $context ) {
// 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( $errstr, 0, $errno, $errfile, $errline );
} 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 object GF_Feed_Processor
*/
function gf_feed_processor() {
return GF_Feed_Processor::get_instance();
}

View File

@@ -0,0 +1,944 @@
<?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' => esc_html__( '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 = $menu_items['results']['sub_menu_items'];
$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' => '',
'onclick' => 'return false;',
'onkeypress' => 'return false;',
'menu_class' => 'gf_form_toolbar_results',
'link_class' => $link_class,
'capabilities' => $this->_capabilities,
'sub_menu_items' => $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;
}
$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG || isset( $_GET['gform_debug'] ) ? '' : '.min';
$admin_css_url = GFCommon::get_base_url() . "/css/admin{$min}.css?ver=" . GFForms::$version;
?>
<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>
<link rel="stylesheet"
href="<?php echo esc_url( $admin_css_url ); ?>"
type="text/css"/>
<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 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="postbox">
<h3 style="cursor: default;"><?php echo $this->_search_title ?></h3>
<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__( 'Filters', 'gravityforms' ),
'tooltip' => 'gresults_filters',
'markup' => '<div id="gresults-results-field-filters-container">
<!-- placeholder populated by js -->
</div>'
),
'date_range' => array(
'label' => esc_attr__( 'Date Range', 'gravityforms' ),
'tooltip' => 'gresults_date_range',
'markup' => '<div style="width:90px; float:left; ">
<label
for="gresults-results-filter-date-start">' . esc_html__( 'Start', 'gravityforms' ) . '</label>
<input type="text" id="gresults-results-filter-date-start" name="start"
style="width:80px"
class="gresults-datepicker"
value="' . esc_attr( $start_date ) . '"/>
</div>
<div style="width:90px; float:left; ">
<label
for="gresults-results-filter-date-end">' . esc_html__( 'End', 'gravityforms' ) . '</label>
<input type="text" id="gresults-results-filter-date-end" name="end"
style="width:80px"
class="gresults-datepicker"
value="' . esc_attr( $end_date ) . '"/>
</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='gresults-results-filter-section-label'>
<?php echo $filter['label'] ?>
&nbsp;<?php gform_tooltip( rgar( $filter, 'tooltip' ), 'tooltip_bottomleft' ) ?>
</div>
<?php
echo $filter['markup'];
}
?>
<br style="clear:both"/>
<div id="gresults-results-filter-buttons">
<input type="submit" id="gresults-results-filter-submit-button"
class="button button-primary button-large"
value="<?php esc_attr_e( 'Apply filters', 'gravityforms' ); ?>">
<input type="button" id="gresults-results-filter-clear-button"
class="button button-secondary 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='gficon-gravityforms-spinner-icon gficon-spin'></i>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="gresults-filter-loading" style="display:none;margin:0 5px 10px 0;">
<i class='gficon-gravityforms-spinner-icon gficon-spin'></i>&nbsp;
<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">&nbsp;
</div>
</div>
<?php
else :
_e( 'This form does not have any fields that can be used for results', 'gravityforms' );
endif ?>
</div>
<?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' id='gresults-results-field-{$field_id}'>";
$html .= "<div class='gresults-results-field-label'>" . esc_html( GFCommon::get_label( $field ) ) . '</div>';
$html .= '<div>' . 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 );
$chart_options = array(
'isStacked' => true,
'height' => ( $chart_area_height + $bar_height ),
'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' ) . '&nbsp;' . 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' ) . '&nbsp;' . 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>{$content}</li>";
$c ++;
}
}
$offset += $page_size;
} while ( $c < $page_size && ! empty( $leads ) );
if ( ! empty( $leads ) ) {
$more_remaining = true;
}
return $field_results;
}
}
}

View File

@@ -0,0 +1,60 @@
.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;
}

View File

@@ -0,0 +1 @@
.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;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}

View File

@@ -0,0 +1,265 @@
/* --------- 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;
min-height:460px;;
}
.gresults-results-field {
margin-bottom:20px;
}
.gresults-results-field-label {
font-size: 1.2em;
padding: 0 0 14px;
}
.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 {
/*position:absolute;
width:270px;*/
}
#gresults-results-filter-content {
padding:10px;
}
/*
#gresults-results-filter.sticky {
position:fixed;
top:30px;
}
*/
.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-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; }

View File

@@ -0,0 +1 @@
table#gaddon-results-summary,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 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;min-height:460px}.gresults-results-field{margin-bottom:20px}.gresults-results-field-label{font-size:1.2em;padding:0 0 14px}.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}ul.gresults-results-field-content{margin:10px}.gresults-add,.gresults-results-filter-field ul li label{margin-left:5px}td.gresults-rank-field-rank,td.gresults-rank-field-score{width:110px}.gsurvey-rank-field-results table{width:100%}#gresults-results-filter-content{padding:10px}.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-add,.gresults-remove{margin-top:2px;vertical-align:middle;cursor:pointer}#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-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}

View File

@@ -0,0 +1,281 @@
/* ------------------ Field Map ------------------ */
.settings-field-map-table thead th {
font-weight: bold;
}
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 .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: 220px;
}
.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-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 a {
background: url( '../images/field-map-merge.svg' ) no-repeat center;
background-size: 16px 16px;
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;
}
.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; }
.mt-gaddon-editor {
float: right;
position: relative;
right: 21px;
top: 70px;
}
.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;
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

View File

@@ -0,0 +1,2 @@
<?php
//Nothing to see here

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,2 @@
<?php
//Nothing to see here

View File

@@ -0,0 +1,111 @@
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="fa fa-bars 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();
}

View File

@@ -0,0 +1 @@
var GFFeedOrder=function(a){var b=this,c=jQuery;b.init=function(){b.options=a,c(".wp-list-table thead tr, .wp-list-table tfoot tr").append('<th class="sort-column"></th>'),c(".wp-list-table tbody tr").append('<td class="sort-column"><i class="fa fa-bars feed-sort-handle"></i></td>'),b.initSorting()},b.initSorting=function(){c(".wp-list-table tbody").sortable({cursor:"move",handle:".feed-sort-handle",placeholder:"feed-placeholder",tolerance:"pointer",create:function(){c(".wp-list-table").addClass("feed-list-sortable")},helper:b.fixSortableColumnWidths,start:b.setPlaceholderHeight,update:b.updateFeedOrder})},b.fixSortableColumnWidths=function(a,b){var d=b.children(),e=b.clone();return e.children().each(function(a){c(this).width(d.eq(a).width())}),e},b.getFeedOrder=function(){return c('.wp-list-table tbody .check-column input[type="checkbox"]').map(function(){return c(this).val()}).get()},b.setPlaceholderHeight=function(a,b){c(".wp-list-table .feed-placeholder").height(b.item.height())},b.updateFeedOrder=function(a,d){c.ajax(ajaxurl,{method:"POST",dataType:"JSON",data:{action:"gf_save_feed_order",addon:b.options.addon,form_id:b.options.formId,feed_order:b.getFeedOrder(),nonce:b.options.nonce}})},this.init()};

View File

@@ -0,0 +1,135 @@
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() {
self.data = jQuery.parseJSON( jQuery( '#' + self.options.fieldId ).val() );
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: '<span>+</span>',
removeButtonMarkup: '<span>-</span>',
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();
};

View File

@@ -0,0 +1 @@
var gfieldmap=function(a){var b=this;return b.options=a,b.UI=jQuery("#gaddon-setting-row-"+b.options.fieldName),b.init=function(){b.bindEvents(),b.setupData(),b.setupRepeater()},b.bindEvents=function(){b.UI.on("change",'select[name="_gaddon_setting_'+b.options.keyFieldName+'"]',function(){var a=jQuery(this),b=a.data("chosen")?a.siblings(".chosen-container"):a.data("select2")?a.siblings(".select2-container"):a,c=a.siblings(".custom-key-container");"gf_custom"==a.val()&&b.fadeOut(function(){c.fadeIn().focus()})}),b.UI.on("click","a.custom-key-reset",function(a){a.preventDefault();var b=jQuery(this),c=b.parents(".custom-key-container"),d=c.siblings("select.key"),e=d.data("chosen")?d.siblings(".chosen-container"):d.data("select2")?d.siblings(".select2-container"):d;c.fadeOut(function(){c.find("input").val("").change(),d.val("").trigger("change"),e.fadeIn().focus()})}),b.UI.closest("form").on("submit",function(a){jQuery('[name^="_gaddon_setting_'+b.options.fieldName+'_"]').each(function(a){jQuery(this).removeAttr("name")})})},b.setupData=function(){b.data=jQuery.parseJSON(jQuery("#"+b.options.fieldId).val()),b.data||(b.data=[{key:"",value:"",custom_key:""}])},b.setupRepeater=function(){var a;a=b.options.limit>0?b.options.limit:0,b.UI.find("tbody.repeater").repeater({limit:a,items:b.data,addButtonMarkup:"<span>+</span>",removeButtonMarkup:"<span>-</span>",callbacks:{add:function(a,c,d){var e=c.find('select[name="_gaddon_setting_'+b.options.keyFieldName+'"]');!d.custom_key&&e.length>0?c.find(".custom-key-container").hide():c.find(".key").hide(),gform.doAction("gform_fieldmap_add_row",a,c,d)},save:function(a,c){c=jQuery.extend({},c);for(var d=0;d<c.length;d++)""!=c[d].custom_key&&(c[d].custom=1,c[d].key=c[d].custom_key),delete c[d].custom_key;jQuery("#"+b.options.fieldId).val(jQuery.toJSON(c))}}})},b.init()};

View File

@@ -0,0 +1,164 @@
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() {
self.data = jQuery.parseJSON( jQuery( '#' + self.options.fieldId ).val() );
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: '<span>+</span>',
removeButtonMarkup: '<span>-</span>',
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();
}
var value_select = $elem.find( 'select[name="_gaddon_setting_'+ self.options.valueFieldName +'"]' );
if ( ! item.custom_value && value_select.length > 0 ) {
$elem.find( '.custom-value-container' ).hide();
} else {
$elem.find( '.value' ).hide();
}
if ( self.options.mergeTags ) {
new gfMergeTagsObj( form, $elem.find( '.custom-value-container input' ) );
}
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();
};

View File

@@ -0,0 +1 @@
var GFGenericMap=function(a){var b=this;return b.options=a,b.UI=jQuery("#gaddon-setting-row-"+b.options.fieldName),b.init=function(){b.bindEvents(),b.setupData(),b.setupRepeater()},b.bindEvents=function(){b.UI.on("change",'select[name="_gaddon_setting_'+b.options.keyFieldName+'"]',function(){var a=jQuery(this),b=a.data("chosen")?a.siblings(".chosen-container"):a.data("select2")?a.siblings(".select2-container"):a,c=a.siblings(".custom-key-container");"gf_custom"==a.val()&&b.fadeOut(function(){c.fadeIn().focus()})}),b.UI.on("change",'select[name="_gaddon_setting_'+b.options.valueFieldName+'"]',function(){var a=jQuery(this),b=a.data("chosen")?a.siblings(".chosen-container"):a.data("select2")?a.siblings(".select2-container"):a,c=a.siblings(".custom-value-container");"gf_custom"==a.val()&&b.fadeOut(function(){c.fadeIn().focus()})}),b.UI.on("click","a.custom-key-reset",function(a){a.preventDefault();var b=jQuery(this),c=b.parents(".custom-key-container"),d=c.siblings("select.key"),e=d.data("chosen")?d.siblings(".chosen-container"):d.data("select2")?d.siblings(".select2-container"):d;c.fadeOut(function(){c.find("input").val("").change(),d.val("").trigger("change"),e.fadeIn().focus()})}),b.UI.on("click","a.custom-value-reset",function(a){a.preventDefault();var b=jQuery(this),c=b.parents(".custom-value-container"),d=c.siblings("select.value"),e=d.data("chosen")?d.siblings(".chosen-container"):d.data("select2")?d.siblings(".select2-container"):d;c.fadeOut(function(){c.find("input").val("").change(),d.val("").trigger("change"),e.fadeIn().focus()})}),b.UI.closest("form").on("submit",function(a){jQuery('[name^="_gaddon_setting_'+b.options.fieldName+'_"]').each(function(a){jQuery(this).removeAttr("name")})})},b.setupData=function(){b.data=jQuery.parseJSON(jQuery("#"+b.options.fieldId).val()),b.data||(b.data=[{key:"",value:"",custom_key:"",custom_value:""}])},b.setupRepeater=function(){var a=b.options.limit>0?b.options.limit:0;b.UI.find("tbody.repeater").repeater({limit:a,items:b.data,addButtonMarkup:"<span>+</span>",removeButtonMarkup:"<span>-</span>",callbacks:{add:function(a,c,d){var e=c.find('select[name="_gaddon_setting_'+b.options.keyFieldName+'"]');!d.custom_key&&e.length>0?c.find(".custom-key-container").hide():c.find(".key").hide();var f=c.find('select[name="_gaddon_setting_'+b.options.valueFieldName+'"]');!d.custom_value&&f.length>0?c.find(".custom-value-container").hide():c.find(".value").hide(),b.options.mergeTags&&new gfMergeTagsObj(form,c.find(".custom-value-container input")),window.hasOwnProperty("gform")&&gform.doAction("gform_fieldmap_add_row",a,c,d)},save:function(a,c){jQuery("#"+b.options.fieldId).val(JSON.stringify(c))}}})},b.init()};

View File

@@ -0,0 +1,46 @@
function loadBillingLength(setting_name){
var intervals = window[setting_name + "_intervals"]
if(!intervals)
return;
var unit = jQuery("#" + setting_name + "_unit").val();
var min = intervals[unit]["min"];
var max = 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 == 1)
{
jQuery("#gform_payment_status").html(gaddon_payment_strings.subscriptionCanceled);
jQuery("#cancelsub").hide();
}
else
{
jQuery("#cancelsub").prop("disabled", false);
alert(gaddon_payment_strings.subscriptionError);
}
}
);
}

View File

@@ -0,0 +1 @@
function loadBillingLength(a){var b=window[a+"_intervals"];if(b){for(var c=jQuery("#"+a+"_unit").val(),d=b[c].min,e=b[c].max,f=jQuery("#"+a+"_length"),g=f.val(),h="",i=d;i<=e;i++){h+="<option value='"+i+"' "+(g==i?"selected='selected'":"")+">"+i+"</option>"}f.html(h)}}function cancel_subscription(a){confirm(gaddon_payment_strings.subscriptionCancelWarning)&&(jQuery("#subscription_cancel_spinner").show(),jQuery("#cancelsub").prop("disabled",!0),jQuery.post(ajaxurl,{action:"gaddon_cancel_subscription",entry_id:a,gaddon_cancel_subscription:gaddon_payment_strings.subscriptionCancelNonce},function(a){jQuery("#subscription_cancel_spinner").hide(),1==a?(jQuery("#gform_payment_status").html(gaddon_payment_strings.subscriptionCanceled),jQuery("#cancelsub").hide()):(jQuery("#cancelsub").prop("disabled",!1),alert(gaddon_payment_strings.subscriptionError))}))}

View File

@@ -0,0 +1,245 @@
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 loading = jQuery(".gresults-filter-loading");
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('');
loading.show();
filterButtons.attr('disabled', 'disabled');
}
})
.done(function (response) {
if (!response || response === -1) {
loading.hide();
results.html(gresultsStrings.ajaxError);
} else {
if (response.status === "complete") {
filterButtons.removeAttr('disabled');
loading.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 {
loading.hide();
results.html(gresultsStrings.ajaxError);
}
}
})
.fail(function (error) {
filterButtons.removeAttr('disabled');
results.fadeTo("fast", 1);
var msg = error.statusText;
loading.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);
var results = jQuery("#gresults-results");
var offset = jQuery(container).data('offset');
var viewSlug = jQuery("#gresults-view-slug").val();
var searchCriteria = results.data('searchcriteria');
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
},
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").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(document).ready(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("#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();
}
});

View File

@@ -0,0 +1 @@
var gresultsAjaxRequest,gresults={drawCharts:function(){jQuery(".gresults-chart-wrapper").each(function(a,b){var c,d=jQuery(b).attr("id"),e=jQuery(b).data("options"),f=jQuery(b).data("datatable"),g=jQuery(b).data("charttype"),h=f,i=google.visualization.arrayToDataTable(h),j=document.getElementById(d);"bar"==g?c=new google.visualization.BarChart(j):"pie"==g?c=new google.visualization.PieChart(j):"column"==g&&(c=new google.visualization.ColumnChart(j)),c.draw(i,e)})},renderStateData:function(a){var b=jQuery("#gresults-results");b.data("searchcriteria",a.searchCriteria),jQuery("#gresults-results-filter").html(a.filterUI),b.css("opacity",0),b.html(a.html),gresults.drawCharts(),b.fadeTo("slow",1);var c=jQuery("#gresults-results-field-filters-container");c.resizable(),c.resizable("destroy"),c.resizable({handles:"s"})},getResults:function(){gresults.recordFormState();var a=jQuery("#gresults-results-filter-form").serialize();gresults.sendRequest(a)},sendRequest:function(a,b,c){var d=jQuery("#gresults-results"),e=jQuery("#gresults-results-filter-buttons input"),f=jQuery(".gresults-filter-loading"),g=jQuery("#gresults-view-slug").val(),h=jQuery("#_gf_results_nonce").val(),i="action=gresults_get_results_"+g+"&"+a+"&_gf_results_nonce"+h;b&&(i+="&state="+b+"&checkSum="+c),gresultsAjaxRequest=jQuery.ajax({url:ajaxurl,type:"POST",dataType:"json",data:i,beforeSend:function(a,b){d.fadeTo("slow",.33),d.html(""),f.show(),e.attr("disabled","disabled")}}).done(function(c){if(c&&-1!==c)if("complete"===c.status){e.removeAttr("disabled"),f.hide(),d.html(c.html),jQuery("#gresults-results").data("searchcriteria",c.searchCriteria);var g=jQuery("#gresults-results-filter").html();gresults.drawCharts(),d.fadeTo("slow",1),window.history.replaceState&&(history.state?history.pushState({html:c.html,filterUI:g,searchCriteria:c.searchCriteria},"","?"+a):history.replaceState({html:c.html,filterUI:g,searchCriteria:c.searchCriteria},"","?"+a)),gresults.drawCharts(),window.gform_initialize_tooltips&&gform_initialize_tooltips()}else"incomplete"===c.status?(b=c.stateObject,gresults.sendRequest(a,b,c.checkSum),d.html(c.html)):(f.hide(),d.html(gresultsStrings.ajaxError));else f.hide(),d.html(gresultsStrings.ajaxError)}).fail(function(a){e.removeAttr("disabled"),d.fadeTo("fast",1);var b=a.statusText;f.hide(),b="abort"==b?"Request cancelled":gresultsStrings.ajaxError,d.html(b)})},getMoreResults:function(a,b){var c=jQuery("#gresults-results-field-content-"+b),d=jQuery("#gresults-results"),e=jQuery(c).data("offset"),f=jQuery("#gresults-view-slug").val(),g=d.data("searchcriteria");return jQuery.ajax({url:ajaxurl,type:"POST",dataType:"json",data:{action:"gresults_get_more_results_"+f,view:f,form_id:a,field_id:b,offset:e,search_criteria:g},success:function(a){-1===a||(a.html&&jQuery(c).append(a.html),a.more_remaining||jQuery("#gresults-results-field-more-link-"+b).hide(),jQuery(c).data("offset",a.offset))}}),!1},clearFilterForm:function(){jQuery("#gresults-results-field-filters-container").gfFilterUI(gresultsFilterSettings,[],!0),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=!1}})},recordFormState:function(){jQuery("#gresults-results-filter-form input[type='radio']").each(function(){this.checked?jQuery(this).prop("defaultChecked",!0):jQuery(this).prop("defaultChecked",!1)}),jQuery("#gresults-results-filter-form input[type='checkbox']").each(function(){this.checked?jQuery(this).prop("defaultChecked",!0):jQuery(this).prop("defaultChecked",!1)}),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(a,b){elementId="gresults-custom-"+a,0==jQuery("#"+elementId).length?jQuery("#gresults-results-filter-form").append("<input type='hidden' id='"+elementId+"' name='"+a+"' value='"+b+"'>"):jQuery("#"+elementId).val(b)}};google.load("visualization","1",{packages:["corechart"]}),google.setOnLoadCallback(gresults.drawCharts),jQuery(document).ready(function(){if(jQuery("#gresults-results").length>0){jQuery("#gresults-results-field-filters-container").gfFilterUI(gresultsFilterSettings,gresultsInitVars,!0);jQuery(window).resize(function(a){a.target===window&&gresults.drawCharts()}),window.onpopstate=function(a){a.state&&gresults.renderStateData(a.state)},jQuery("#gresults-results-filter-date-start, #gresults-results-filter-date-end").datepicker({dateFormat:"yy-mm-dd",changeMonth:!0,changeYear:!0}),jQuery("#gresults-results-filter-form").submit(function(a){return gresults.getResults(),!1}),history.state?gresults.renderStateData(history.state):gresults.getResults(),window.gform_initialize_tooltips&&gform_initialize_tooltips()}});

View File

@@ -0,0 +1,22 @@
jQuery(document).ready(function ($) {
$('.gaddon-setting-select-custom').on('change', function () {
if ($(this).val() == 'gf_custom')
$(this).hide().siblings('.gaddon-setting-select-custom-container').show();
});
$('.gaddon-setting-select-custom-container .select-custom-reset').on('click', function (event) {
event.preventDefault();
var $input = $(this).closest('.gaddon-setting-select-custom-container'),
$select = $input.prev('select.gaddon-setting-select-custom');
$input.fadeOut(function () {
$input.find('input').val('').change();
$select.fadeIn().focus().val('');
});
});
});

View File

@@ -0,0 +1 @@
jQuery(document).ready(function(a){a(".gaddon-setting-select-custom").on("change",function(){"gf_custom"==a(this).val()&&a(this).hide().siblings(".gaddon-setting-select-custom-container").show()}),a(".gaddon-setting-select-custom-container .select-custom-reset").on("click",function(b){b.preventDefault();var c=a(this).closest(".gaddon-setting-select-custom-container"),d=c.prev("select.gaddon-setting-select-custom");c.fadeOut(function(){c.find("input").val("").change(),d.fadeIn().focus().val("")})})});

View File

@@ -0,0 +1,131 @@
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 );

View File

@@ -0,0 +1 @@
window.GFToken=null,function(a){GFToken=function(b){for(var c in b)b.hasOwnProperty(c)&&(this[c]=b[c]);this.form=a("#gform_"+this.formId),this.init=function(){var b=this;this.tokens={},this.isAjax||gformInitSpinner(this.formId),this.hasPages&&a(document).bind("gform_page_loaded",function(a,c,d){c==b.formId&&d!=b.pageCount&&b.saveEntryData()}),this.form.submit(function(){b.onSubmit()})},this.onSubmit=function(){this.form.data("gftokensubmitting")||(event.preventDefault(),this.form.data("gftokensubmitting",!0),this.saveEntryData(),this.processTokens())},this.processTokens=function(){for(var a in this.feeds){this.active_feed=this.feeds[a];var b={billing_fields:{},id:this.active_feed.id,name:this.active_feed.name};for(var c in this.active_feed.billing_fields)field_id=this.active_feed.billing_fields[c],b.billing_fields[c]=this.entry_data[field_id];window[this.callback].createToken(b,this)}},this.saveEntryData=function(){var b=this,c="input_"+this.formId+"_";this.entry_data||(this.entry_data={}),this.form.find('input[id^="'+c+'"], select[id^="'+c+'"], textarea[id^="'+c+'"]').each(function(){var d=a(this).attr("id").replace(c,"").replace("_",".");a.inArray(d,b.fields)>=0&&(b.entry_data[d]=a(this).val())})},this.saveToken=function(b){this.tokens[this.active_feed.id]={feed_id:this.active_feed.id,response:b},this.tokens.length==this.feeds.length&&(this.form.find(this.responseField).val(a.toJSON(this.tokens)),this.form.submit())},this.init()}}(jQuery);

View File

@@ -0,0 +1,2 @@
<?php
//Nothing to see here

View File

@@ -0,0 +1,329 @@
/**
* 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' ), 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();
};

View File

@@ -0,0 +1 @@
jQuery.fn.repeater=function(a){var b=this,c={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}}};return b.options=jQuery.extend(!0,{},c,a),b.elem=jQuery(this),b.items=b.options.items,b.callbacks=b.options.callbacks,b._template=b.options.template,b._baseObj=b.items[0],b.init=function(){return b.stashTemplate(),b.elem.addClass("repeater"),b.refresh(),b.bindEvents(),b},b.bindEvents=function(){b.options.saveEvents=b.getNamespacedEvents(b.options.saveEvents),b.elem.off("click.repeater","a.add-item"),b.elem.on("click.repeater","a.add-item:not(.inactive)",function(){b.addNewItem(this)}),b.elem.off("click.repeater","a.remove-item"),b.elem.on("click.repeater","a.remove-item",function(a){b.removeItem(this)}),b.elem.off(b.options.saveEvents,b.options.saveElements),b.elem.on(b.options.saveEvents,b.options.saveElements,function(){b.save()})},b.stashTemplate=function(){b._template||(b._template=b.elem.html()),b._template=jQuery.trim(b._template)},b.addItem=function(a,c){var d=b.getItemMarkup(a,c),e=jQuery(d).addClass("item-"+c);b.callbacks.beforeAdd(b,e,a,c),b.append(e),b.populateSelects(a,c),b.callbacks.add(b,e,a,c)},b.getItemMarkup=function(a,c){var d=b._template;for(var e in a)a.hasOwnProperty(e)&&(d=d.replace(/{i}/g,c),d=d.replace("{buttons}",b.getRepeaterButtonsMarkup(c)),d=d.replace(new RegExp("{"+e+"}","g"),a[e]));return d},b.getRepeaterButtonsMarkup=function(a){var c=b.callbacks.repeaterButtons(b,a);return c||(c=b.getDefaultButtonsMarkup(a)),c},b.getDefaultButtonsMarkup=function(a){var c=b.items.length>=b.options.limit&&0!==b.options.limit?"inactive":"",d='<a class="add-item '+c+'" data-index="'+a+'">'+b.options.addButtonMarkup+"</a>";return b.items.length>b.options.minItemCount&&(d+='<a class="remove-item" data-index="'+a+'">'+b.options.removeButtonMarkup+"</a>"),'<div class="repeater-buttons">'+d+"</div>"},b.populateSelects=function(a,c){for(var d in a)if(a.hasOwnProperty(d)){var e=b.elem.find("."+d+"_"+c);e.is("select")&&(jQuery.isArray(a[d])?e.val(a[d]):e.find('option[value="'+a[d]+'"]').prop("selected",!0))}},b.addNewItem=function(a,c){var d=b.isElement(a),c=parseInt(void 0!==c?c:d?parseInt(jQuery(a).attr("data-index"),10)+1:b.items.length,10),e=d?b.getBaseObject():a;return b.callbacks.beforeAddNew(b,c),b.items.splice(c,0,e),b.callbacks.addNew(b,c),b.refresh().save(),b},b.removeItem=function(a){var c=b.isElement(a)?jQuery(a).attr("data-index"):a;b.callbacks.beforeRemove(b,c),delete b.items[c],b.callbacks.remove(b,c),b.save().refresh()},b.refresh=function(){b.elem.empty();for(var a=0;a<b.items.length;a++)b.addItem(b.items[a],a);return b},b.save=function(){for(var a=b.getBaseObjectKeys(),c=[],d=0;d<b.items.length;d++)if(void 0!==b.items[d]){for(var e={},f=0;f<a.length;f++){var g=a[f],h="."+g+"_"+d,i=b.elem.find(h).val();e[g]=void 0!==i&&i}c.push(e)}return b.items=c,b.callbacks.save(b,c),b},b.getBaseObjectKeys=function(){for(var a=[],c=b.items.length>0?b.items:[b._baseObj],d=0;d<c.length;d++)if(void 0!==c[d]){for(var e in c[d])c[d].hasOwnProperty(e)&&a.push(e);break}return a},b.getBaseObject=function(){for(var a={},c=b.getBaseObjectKeys(),d=0;d<c.length;d++)a[c[d]]="";return a},b.getNamespacedEvents=function(a){for(var a=a.split(" "),b=[],c=0;c<a.length;c++)b.push(a[c]+".repeater");return b.join(" ")},b.isElement=function(a){try{return a instanceof HTMLElement}catch(b){return"object"==typeof a&&1===a.nodeType&&"object"==typeof a.style&&"object"==typeof a.ownerDocument}},b.init()};