diff --git a/change_log.txt b/change_log.txt index 2ff0fef..5ff17a9 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,3 +1,119 @@ +------------------------------------------------------------------------------------------------------------------- +Version 1.8.13 + - Added additional check plus user feedback for failed multi-file uploads. + - Fixed a potential security vulnerability for some server configurations which could allow code to be executed via the file upload field. + - Fixed issue with form export/import setting inactive notifications to active. + - Fixed issue with resend notification not accepting a list of emails. + - Fixed another issue with field label for Name and Address fields. + - Fixed issue with field label for Name and Address fields. + - Fixed issue causing checkboxes checked by default to be rendered unchecked in certain situations. + + - AF: Fixed another issue with simple_condition() function/feature creating javascript errors. + - AF: Fixed get_field_map_fields function to no longer include the text "field_map" in the mapped fields prefix. + - AF: Fixed issue with payments less than $1.00 not being processed. + +------------------------------------------------------------------------------------------------------------------- +Version 1.8.12 + - Added PHP version of the "gform_calculation_result" filter. + add_filter( 'gform_calculation_result', 'my_calc_result', 10, 5 ); + function my_calc_result( $result, $formula, $field, $form, $entry ) { + // modify result as needed + return $result; + } + - Updated chosen js, styles and images to latest version. + - Fixed issue with multiple file upload merge tag not including a line break when in html format. + - Fixed issue with List field markup; more than . + - Fixed markup validation issue with List Field where label for attribute did not match a valid input. + - AF: Fixed issue with simple_condition() function/feature creating javascript errors. + - AF: Added a check in the maybe_process_callback function to see if the callback has been aborted to prevent processing for the Payment Add-On. + - API: Added GFAPI::get_forms() method. + +------------------------------------------------------------------------------------------------------------------- +Version 1.8.11 + + - Fixed issue where tags were closed incorrectly generating invalid HTML markup. + - Fixed issue with notifications not being sent when configured with multiple email addresses. + - Fixed issue with legacy notifications getting marked as inactive after being edited. + +------------------------------------------------------------------------------------------------------------------- +Version 1.8.10 + + - Added gform_enable_shortcode_notification_message hook to allow for disabling shortcode processing of notification messages. + - Added $field_values as a third paramater for the gform_pre_render filter. + - Added new hook: 'gform_send_email_failed'; allows interception when a call to GFCommon::send_email() fails. + add_action( 'gform_send_email_failed', 'my_send_email_failed_func', 10, 2 ); + function my_send_email_failed_func( $error, $email ) { + // do what you want with the $error and $email data. + } + - Added new JS filter: 'gform_calculation_formula' to allow modifying formula before it is processed by GF on frontend. + gform.addFilter( 'gform_calculation_formula', function( formula, formulaField, formId, calcObj ) { + // custom code here + return formula; + } ); + - Added $rule and $form parameters to the gform_is_value_match filter. + - Added GFCommon::esc_like() method to fix deprecation notice in WP 4.0 while maintining backwards compatibility with previous WP versions. + - Added condition to not include "gform_chosen" if "chosen" is already enqueued. + + - Updated gf_reset_to_default() to not select disabled options in drop downs when reseting default value. + - Updated GCommon::is_valid_url() to use filter_var( $url, FILTER_VALIDATE_URL ). + - Updated GCommon::is_valid_email() to use filter_var( $email, FILTER_VALIDATE_EMAIL ). + - Updated entry details payment information markup. + - Updated complete_payment function to update the entry's payment_amount, transaction_id, and payment_date for the Payment Add-On. + - Updated process for enqueuing chosen script to check if "chosen" is a registered handle and if so to include it instead of "gform_chosen". + - Updated french translation. + - Updated product calculation field to allow the label to be changed dynamically like the single product field. + - Updated delete_leads_by_form function to include deleting data from the lead meta table. + + - API: Updated GFAPI::get_entries() to include field choice texts in addition to values when performing a global search. + + - Fixed fatal error triggered on some servers. + - Fixed Notice message. + - Fixed an issue with multi-page, ajax-enabled forms with images as buttons where multiple spinners were displayed during form submission. + - Fixed issue with multi file upload merge tag. + - Fixed issue with confirmation type "Page" when permalink contains a query string. + - Fixed bug with default values for conditional logic where any choice with a 'price' attr set (even if it wasn't a pricing field) was incorrectly treated as a pricing value. + - Fixed a issue with GFCommon::esc_like() causing a fatal error on WordPress < 4.0. + - Fixed an issue with checkbox, radio button and drop-down fields which caused data to be saved incorrectly if a pipe ("|") was used in a choice value. + - Fixed the validation of the website field to accept commas in the path. + - Fixed notices thrown in WP 4.0 on pages using/extending WP_List_Table. + - Fixed an issue affecting the search function on the entry list and the conditional logic on the entry export page where field choice values would be taken into account but not their corresponding texts/labels while performing a global search based on any form field. This affects all radio, checkbox and drop-down fields plus derivative fields in add-ons i.e. Poll, Survey and Quiz fields. + - Fixed a bug with conditional logic animation in Firefox. + - Fixed "Index too large" error for payment addons. + - Fixed issue with inactive notifications getting changed back to active when notification is edited. + - Fixed issue where admin label was not used for fields in the inactive column on the "Select Columns" ui. + - Fixed issue where is_section_empty() returned true even if section contained a product field and 'gform_display_product_summary' filter returned false. + - Fixed issue where
tags were being displayed on notifications even when the message type was set to "text". + - Fixed notice thrown in update_confirmation function when isDefault not set. + - Fixed warnings thrown in get_version_info when the response is not an array. + + - AF: Fixed issue with sales page where payment method drop down displayed blank values. + - AF: Fixed issue when creating subscriptions upon first subscription payment. + - AF: Fixed issue with payment going to gateway when the amount was negative. + - AF: Updated payment Add-On so that redirect_url() is called earlier in the page life-cycle. + - AF: Fixed issue with results page displaying an error message for the Stripe Add-On. + - AF: Added support for checkbox item callback to allow an individual checkbox item to be customized. + - AF: Fixed issue that caused a $0.00 total when selecting the same product field for the subscription payment and trial payment. + - AF: Fixed issue with plugin settings page displaying slug instead of Title. + - AF: Fixed issue with payment add-on sending requests to payment gateways even when payment was $0.00. + - AF: Updated process_capture function to set is_fulfilled to true so complete_payment function uses the entry value for Payment Add-On. + - AF: Updated maybe_process_feed function to handle delayed payments for the Payment Add-On. + - AF: Added support for formatting inputs as currency. + - AF: Fixed notice thrown in the process_callback_action function when logging for the Payment Add-On. + - AF: Updated maybe_process_feeds function to not process feeds set as inactive. + - AF: Added register and init_addons() function to allow for aid in initializing addons and support overriding them. + - AF: Updated process_capture function in the Payment Add-on to call complete_payment. + - AF: Updated Payment AF validation to only validate if the validation result is valid. + - AF: Fixed misspelling on database key in create table for ...gf_addon_payment_transaction for the Payment Add-On. + - AF: Updated confirmation function to set the transaction type on the entry for payment gateways that redirect to a url for the Payment Add-On. + - AF: Added code to update the payment_gateway meta for the entry when the gateway is a URL redirect for the Payment Add-On. + - AF: Fixed notices thrown in the complete_payment function in the Payment Add-On. + - AF: Updated priority of Payment AF validation from 10 to 20 to ensure all validation has passed before payment validation occurs (resolves issue where validation could sometimes fail AFTER a subscription was created). + - AF: Fixed issue where "name" attribute was output twice. + - AF: Updated 'name' property of plugin settings tabs to use slug rather than short title. + - AF: Fixed issue where feed status was not saved. + - AF: Added a post_callback function to the Payment Add-On. + - AF: Added tooltips to the Payment Add-On. + ------------------------------------------------------------------------------------------------------------------- Version 1.8.9 - Added "password" to the list of fields which allow HTML input. diff --git a/common.php b/common.php index ce5aea1..70a630a 100644 --- a/common.php +++ b/common.php @@ -220,13 +220,31 @@ public static function is_invalid_or_empty_email($email){ return empty($email) || !self::is_valid_email($email); } - public static function is_valid_url($url){ - return preg_match('!^(http|https)://([\w-]+\.?)+[\w-]+(:\d+)?(/[\w- ./?~%&=+\']*)?$!', $url); - } + public static function is_valid_url( $url ) { + $url = trim( $url ); - public static function is_valid_email($email){ - return preg_match('/^(([a-zA-Z0-9_.\-+!#$&\'*+=?^`{|}~])+\@((([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+|localhost) *,? *)+$/', $email); - } + return ( ( strpos( $url, 'http://' ) === 0 || strpos( $url, 'https://' ) === 0 ) && + filter_var( $url, FILTER_VALIDATE_URL ) !== false ); + } + + public static function is_valid_email( $email ) { + return filter_var( $email, FILTER_VALIDATE_EMAIL ); + } + + public static function is_valid_email_list( $email_list ) { + $emails = explode( ',', $email_list ); + if ( ! is_array( $emails ) ){ + return false; + } + + foreach( $emails as $email ){ + if ( ! filter_var( $email, FILTER_VALIDATE_EMAIL ) ) { + return false; + } + } + + return true; + } public static function get_label($field, $input_id = 0, $input_only = false){ return RGFormsModel::get_label($field, $input_id, $input_only); @@ -694,17 +712,25 @@ public static function replace_variables($text, $form, $lead, $url_encode = fals case "fileupload" : if(rgar($field, "multipleFiles")){ - $files = empty($value) ? array() : json_decode($value, true); - foreach($files as &$file){ - $file = str_replace(" ", "%20", $file); - } - $value = join("\r\n", $files); - if($format == "html"){ - $value = nl2br($value); - } - } else { - $value = str_replace(" ", "%20", $value); - } + + $files = empty( $raw_value ) ? array() : json_decode( $raw_value, true ); + foreach ( $files as &$file ) { + + $file = str_replace( ' ', '%20', $file ); + + if ( $esc_html ){ + $value = esc_html( $value ); + } + } + $value = $format == 'html' ? join( "
", $files ) : join( ", ", $files ); + + } else { + $value = str_replace( ' ', '%20', $value ); + } + + if ( $url_encode ){ + $value = urlencode( $value ); + } break; @@ -872,14 +898,14 @@ public static function replace_variables($text, $form, $lead, $url_encode = fals $text = str_replace("{entry_url}", $url_encode ? urlencode($entry_url) : $entry_url, $text); //post id - $text = str_replace("{post_id}", $url_encode ? urlencode($lead["post_id"]) : $lead["post_id"], $text); + $text = str_replace("{post_id}", $url_encode ? urlencode(rgar($lead, "post_id")) : rgar($lead, "post_id"), $text); //admin email $wp_email = get_bloginfo("admin_email"); $text = str_replace("{admin_email}", $url_encode ? urlencode($wp_email) : $wp_email, $text); //post edit url - $post_url = get_bloginfo("wpurl") . "/wp-admin/post.php?action=edit&post=" . $lead["post_id"]; + $post_url = get_bloginfo("wpurl") . "/wp-admin/post.php?action=edit&post=" . rgar($lead, "post_id"); $text = str_replace("{post_edit_url}", $url_encode ? urlencode($post_url) : $post_url, $text); $text = self::replace_variables_prepopulate($text, $url_encode); @@ -1282,7 +1308,10 @@ private static function prepare_user_notification($form, $lead, $override_option $message_format = apply_filters("gform_notification_format_{$form["id"]}", apply_filters("gform_notification_format", "html", "user", $form, $lead), "user", $form, $lead); $message = GFCommon::replace_variables(rgget("message", $form["autoResponder"]), $form, $lead, false, false, !rgget("disableAutoformat", $form["autoResponder"]), $message_format); - $message = do_shortcode($message); + + if(apply_filters("gform_enable_shortcode_notification_message", true, $form, $lead)){ + $message = do_shortcode($message); + } //Running trough variable replacement $to = GFCommon::replace_variables($to, $form, $lead, false, false); @@ -1314,7 +1343,10 @@ private static function prepare_admin_notification($form, $lead, $override_optio $message_format = apply_filters("gform_notification_format_{$form["id"]}", apply_filters("gform_notification_format", "html", "admin", $form, $lead), "admin", $form, $lead); $message = GFCommon::replace_variables(rgget("message", $form["notification"]), $form, $lead, false, false, !rgget("disableAutoformat", $form["notification"]), $message_format); - $message = do_shortcode($message); + + if(apply_filters("gform_enable_shortcode_notification_message", true, $form, $lead)){ + $message = do_shortcode($message); + } $version_info = self::get_version_info(); $is_expired = !rgempty("expiration_time", $version_info) && $version_info["expiration_time"] < time(); @@ -1344,7 +1376,7 @@ private static function prepare_admin_notification($form, $lead, $override_optio $source_field = RGFormsModel::get_field($form, $routing["fieldId"]); $field_value = RGFormsModel::get_lead_field_value($lead, $source_field); - $is_value_match = RGFormsModel::is_value_match($field_value, $routing["value"], $routing["operator"], $source_field) && !RGFormsModel::is_field_hidden($form, $source_field, array(), $lead); + $is_value_match = RGFormsModel::is_value_match( $field_value, $routing["value"], $routing["operator"], $source_field, $routing, $form ) && !RGFormsModel::is_field_hidden($form, $source_field, array(), $lead); if ($is_value_match) $email_to[] = $routing["email"]; @@ -1399,7 +1431,7 @@ public static function send_notification($notification, $form, $lead){ $source_field = RGFormsModel::get_field($form, $routing["fieldId"]); $field_value = RGFormsModel::get_lead_field_value($lead, $source_field); - $is_value_match = RGFormsModel::is_value_match($field_value, $routing["value"], $routing["operator"], $source_field) && !RGFormsModel::is_field_hidden($form, $source_field, array(), $lead); + $is_value_match = RGFormsModel::is_value_match($field_value, $routing["value"], $routing["operator"], $source_field, $routing, $form ) && !RGFormsModel::is_field_hidden($form, $source_field, array(), $lead); if ($is_value_match) $email_to[] = $routing["email"]; @@ -1422,7 +1454,10 @@ public static function send_notification($notification, $form, $lead){ $message_format = rgempty("message_format", $notification) ? "html" : rgar($notification, "message_format"); $message = GFCommon::replace_variables(rgar($notification, "message"), $form, $lead, false, false, !rgar($notification, "disableAutoformat"), $message_format); - $message = do_shortcode($message); + + if(apply_filters("gform_enable_shortcode_notification_message", true, $form, $lead)){ + $message = do_shortcode($message); + } // allow attachments to be passed as a single path (string) or an array of paths, if string provided, add to array $attachments = rgar( $notification, "attachments" ); @@ -1559,28 +1594,30 @@ public static function has_user_notification($form){ private static function send_email($from, $to, $bcc, $reply_to, $subject, $message, $from_name="", $message_format="html", $attachments=""){ - $to = str_replace(" ", "", $to); - $bcc = str_replace(" ", "", $bcc); + $to = str_replace( " ", "", $to ); + $bcc = str_replace( " ", "", $bcc ); + $error = false; - //invalid to email address or no content. can't send email - if(!GFCommon::is_valid_email($to) || (empty($subject) && empty($message))){ - GFCommon::log_debug("Cannot send email because either the TO address is invalid or there is no SUBJECT or MESSAGE."); - GFCommon::log_debug(print_r(compact("to", "subject", "message"), true)); - return; - } + if( ! GFCommon::is_valid_email( $from ) ) { + $from = get_bloginfo( 'admin_email' ); + } - if(!GFCommon::is_valid_email($from)) - $from = get_bloginfo("admin_email"); + if( ! GFCommon::is_valid_email_list( $to ) ) { + $error = new WP_Error( 'invalid_to', 'Cannot send email because the TO address is invalid.' ); + } else if( empty( $subject ) && empty( $message ) ) { + $error = new WP_Error( 'missing_subject_and_message', 'Cannot send email because there is no SUBJECT and no MESSAGE.' ); + } else if( ! GFCommon::is_valid_email( $from ) ) { + $error = new WP_Error( 'invalid_from', 'Cannot send email because the FROM address is invalid.' ); + } - //invalid from address. can't send email - if(!GFCommon::is_valid_email($from)){ - GFCommon::log_debug("Cannot send email because the FROM address is invalid."); - GFCommon::log_debug(print_r(compact("to", "from", "subject"), true)); + if( is_wp_error( $error ) ) { + GFCommon::log_debug( $error->get_error_message() ); + GFCommon::log_debug( print_r( compact( 'to', 'subject', 'message' ), true ) ); + do_action( 'gform_send_email_failed', $error, compact( 'from', 'to', 'bcc', 'reply_to', 'subject', 'message', 'from_name', 'message_format', 'attachments' ) ); return; - } + } $content_type = $message_format == "html" ? "text/html" : "text/plain"; - $name = empty($from_name) ? $from : $from_name; $headers = array(); @@ -1589,7 +1626,7 @@ private static function send_email($from, $to, $bcc, $reply_to, $subject, $messa if(GFCommon::is_valid_email($reply_to)) $headers["Reply-To"] = "Reply-To: {$reply_to}"; - if(GFCommon::is_valid_email($bcc)) + if(GFCommon::is_valid_email_list($bcc)) $headers["Bcc"] = "Bcc: $bcc"; $headers["Content-type"] = "Content-type: {$content_type}; charset=" . get_option('blog_charset'); @@ -1801,15 +1838,16 @@ public static function get_version_info($cache=true){ $options['timeout'] = 15; $nocache = $cache ? "" : "nocache=1"; //disabling server side caching - + $raw_response = self::post_to_manager("version.php", $nocache, $options); //caching responses. set_transient("gform_update_info", $raw_response, 86400); //caching for 24 hours } - if ( is_wp_error( $raw_response ) || $raw_response['response']['code'] != 200 ) + if ( is_wp_error( $raw_response ) || rgars($raw_response, 'response/code') != 200 ) { return array("is_valid_key" => "1", "version" => "", "url" => "", "is_error" => "1"); + } $version_info = json_decode($raw_response['body'], true); @@ -1994,9 +2032,14 @@ public static function selection_display($value, $field, $currency="", $use_text return ""; } - $ary = explode("|", $value); - $val = $ary[0]; - $price = count($ary) > 1 ? $ary[1] : ""; + if ( isset( $field['enablePrice'] ) && $field['enablePrice'] ) { + $ary = explode( '|', $value ); + $val = $ary[0]; + $price = count( $ary ) > 1 ? $ary[1] : ''; + } else { + $val = $value; + $price = ''; + } if($use_text) $val = RGFormsModel::get_choice_text($field, $val); @@ -2350,31 +2393,48 @@ public static function get_select_choices($field, $value=""){ return $choices; } - public static function is_section_empty($section_field, $form, $lead){ - $cache_key = "GFCommon::is_section_empty_" . $form["id"] . "_" . $section_field["id"]; + public static function is_section_empty( $section_field, $form, $entry ) { - $value = GFCache::get($cache_key); + $cache_key = "GFCommon::is_section_empty_{$form['id']}_{$section_field['id']}"; + $value = GFCache::get( $cache_key ); - if($value !== false) + if( $value !== false ) { return $value == true; + } - $fields = self::get_section_fields($form, $section_field["id"]); - if(!is_array($fields)){ - GFCache::set($cache_key, 1); + $fields = self::get_section_fields( $form, $section_field['id'] ); + if( ! is_array( $fields ) ) { + GFCache::set( $cache_key, 1 ); return true; } - foreach($fields as $field){ - $val = RGFormsModel::get_lead_field_value($lead, $field); - $val = GFCommon::get_lead_field_display($field, $val, rgar($lead, 'currency')); + foreach( $fields as $field ) { + + $value = GFFormsModel::get_lead_field_value( $entry, $field ); + $value = GFCommon::get_lead_field_display( $field, $value, rgar( $entry, 'currency' ) ); + + if( rgblank( $value ) ) { + continue; + } + + // most fields are displayed in the section by default, exceptions are handled below + $is_field_displayed_in_section = true; - if(!self::is_product_field($field["type"]) && !rgblank($val)){ - GFCache::set($cache_key, 0); + // by default, product fields are not displayed in their containing section (displayed in a product summary table) + // if the filter is used to disable this, product fields are displayed in the section like other fields + if( self::is_product_field( $field['type'] ) ) { + $display_product_summary = apply_filters( 'gform_display_product_summary', true, $field, $form, $entry ); + $is_field_displayed_in_section = ! $display_product_summary; + } + + if( $is_field_displayed_in_section ) { + GFCache::set( $cache_key, 0 ); return false; } + } - GFCache::set($cache_key, 1); + GFCache::set( $cache_key, 1 ); return true; } @@ -3861,21 +3921,21 @@ public static function get_field_input($field, $value="", $lead_id=0, $form_id=0 $has_columns = is_array(rgar($field, "choices")); $columns = $has_columns ? rgar($field, "choices") : array(array()); + $label_target_shim = sprintf( '', $form_id, $field['id'] ); $list = "
" . + $label_target_shim . ""; $class_attr = ""; if($has_columns){ - $list .= ""; - $colnum = 1; - foreach($columns as $column){ - $odd_even = ($colnum % 2) == 0 ? "even" : "odd"; - $list .= ""; - $colnum++; + $list .= ''; + for( $colnum = 1; $colnum <= count( $columns ) + 1; $colnum++ ) { + $odd_even = ( $colnum % 2 ) == 0 ? 'even' : 'odd'; + $list .= sprintf( "", $field['id'], $colnum, $odd_even ); } - $list .= ""; + $list .= ''; $list .= ""; foreach($columns as $column){ @@ -3884,7 +3944,11 @@ public static function get_field_input($field, $value="", $lead_id=0, $form_id=0 $list .= ""; } else{ - $list .= ""; + $list .= + '' . + "" . + "" . + ''; } $delete_display = count($value) == 1 ? "visibility:hidden;" : ""; @@ -4044,9 +4108,9 @@ private static function get_list_input($field, $has_columns, $column, $value, $f foreach($input_info["choices"] as $choice){ if(is_array($choice)){ - $choice_value = $choice["value"]; - $choice_text = $choice["text"]; - $choice_selected = $choice["isSelected"]; + $choice_value = rgar($choice,"value"); + $choice_text = rgar($choice,"text"); + $choice_selected = rgar($choice,"isSelected"); } else{ $choice_value = $choice; @@ -4081,7 +4145,7 @@ public static function clean_extensions($extensions){ } public static function get_disallowed_file_extensions(){ - return array("php", "asp", "exe", "com", "htaccess"); + return array("php", "asp", "exe", "com", "htaccess", "phtml", "php3", "php4", "php5", "php6"); } public static function to_money($number, $currency_code=""){ @@ -4665,9 +4729,8 @@ public static function get_lead_field_display($field, $value, $currency="", $use break; default : - if (!is_array($value)) - { - return nl2br($value); + if (!is_array($value)){ + return $format == "html" ? nl2br($value) : $value; } break; } @@ -4991,11 +5054,11 @@ public static function evaluate_conditional_logic($logic, $form, $lead) { foreach($logic["rules"] as $rule) { if (in_array($rule["fieldId"], $entry_meta_keys)){ - $is_value_match = GFFormsModel::is_value_match(rgar($lead,$rule["fieldId"]), $rule["value"], $rule["operator"]);; + $is_value_match = GFFormsModel::is_value_match(rgar($lead,$rule["fieldId"]), $rule["value"], $rule["operator"], null, $rule, $form ); } else { $source_field = GFFormsModel::get_field($form, $rule["fieldId"]); $field_value = empty($lead) ? GFFormsModel::get_field_value($source_field, array()) : GFFormsModel::get_lead_field_value($lead, $source_field); - $is_value_match = GFFormsModel::is_value_match($field_value, $rule["value"], $rule["operator"], $source_field); + $is_value_match = GFFormsModel::is_value_match( $field_value, $rule["value"], $rule["operator"], $source_field, $rule, $form ); } if($is_value_match) @@ -5269,6 +5332,7 @@ public static function calculate($field, $form, $lead) { } $result = preg_match( '/^[0-9 -\/*\(\)]+$/', $formula ) ? eval( "return {$formula};" ) : false; + $result = apply_filters( 'gform_calculation_result', $result, $formula, $field, $form, $lead ); return $result; } @@ -5869,6 +5933,18 @@ public static function decrypt( $text ) { return trim( mcrypt_decrypt( MCRYPT_RIJNDAEL_256, $key, base64_decode( $text ), MCRYPT_MODE_ECB, mcrypt_create_iv( $iv_size, MCRYPT_RAND ) ) ); } + public static function esc_like( $value ) { + global $wpdb; + + if( is_callable( array( $wpdb, 'esc_like' ) ) ) { + $value = $wpdb->esc_like( $value ); + } else { + $value = like_escape( $value ); + } + + return $value; + } + } class GFCategoryWalker extends Walker { diff --git a/css/admin.css b/css/admin.css index 0f2fe3c..efa6d75 100644 --- a/css/admin.css +++ b/css/admin.css @@ -1305,6 +1305,9 @@ table td.gfield_category_cell { } /* view form styles ------------------------------------------------------*/ +div.gf_payment_detail{ + margin-bottom: 15px; +} table.entry-detail-view { margin-bottom: 16px diff --git a/css/formsmain.css b/css/formsmain.css index abd14b5..841111d 100644 --- a/css/formsmain.css +++ b/css/formsmain.css @@ -1288,408 +1288,400 @@ body .gform_wrapper div.gform_body ul.gform_fields li.gfield.gfield_html dl dd { min-width: 45px !important; } -/* enhanced UI/select styles added in v.1.6 -----------------------------------------------------------------*/ - - -.gform_wrapper select.chzn-select { - visibility: hidden; - height: 28px !important; - min-height: 28px !important; -} - -.gform_wrapper .chzn-container { - font-size: 13px; - position: relative; - margin-bottom: 4px; - display: inline-block; - zoom: 1; -} - -.gform_wrapper .chzn-container .chzn-drop { - background-color: #FFF; - border: 1px solid #AAA; - border-top: 0; - position: absolute; - top: 29px; - left: 0; - -webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15); - -moz-box-shadow: 0 4px 5px rgba(0,0,0,.15); - -o-box-shadow: 0 4px 5px rgba(0,0,0,.15); - box-shadow: 0 4px 5px rgba(0,0,0,.15); - z-index: 999; -} - -.gform_wrapper .chzn-container-single .chzn-single { - background-color: #FFF; - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #EEE), color-stop(0.5, white)); - background-image: -webkit-linear-gradient(center bottom, #EEE 0%, white 50%); - background-image: -moz-linear-gradient(center bottom, #EEE 0%, white 50%); - background-image: -o-linear-gradient(top, #EEE 0%,#FFF 50%); - background-image: -ms-linear-gradient(top, #EEE 0%,#FFF 50%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#EEE', endColorstr='#FFF',GradientType=0 ); - background-image: linear-gradient(top, #EEE 0%,#FFF 50%); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -moz-background-clip: padding; - -webkit-background-clip: padding-box; - background-clip: padding-box; - border: 1px solid #AAA; - display: block; overflow: hidden; - white-space: nowrap; - position: relative; - height: 26px; - line-height: 26px; - padding: 0 0 0 8px; - color: #444; - text-decoration: none; +/* enhanced UI/select styles updated in v.1.8.12 -----------------------------------------------------------------*/ + + +.gform_wrapper .chosen-container { + position: relative; + display: inline-block; + vertical-align: middle; + font-size: 13px; + zoom: 1; + *display: inline; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} +.gform_wrapper .chosen-container .chosen-drop { + position: absolute; + top: 100%; + left: -9999px; + z-index: 1010; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 100%; + border: 1px solid #aaa; + border-top: 0; + background: #fff; + box-shadow: 0 4px 5px rgba(0, 0, 0, .15); +} +.gform_wrapper .chosen-container.chosen-with-drop .chosen-drop { + left: 0; +} +.gform_wrapper .chosen-container a { + cursor: pointer; +} +.gform_wrapper .chosen-container-single .chosen-single { + position: relative; + display: block; + overflow: hidden; + padding: 0 0 0 8px; + height: 23px; + border: 1px solid #aaa; + border-radius: 5px; + background-color: #fff; + background: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(20%, #fff), color-stop(50%, #f6f6f6), color-stop(52%, #eee), color-stop(100%, #f4f4f4)); + background: -webkit-linear-gradient(top, #fff 20%, #f6f6f6 50%, #eee 52%, #f4f4f4 100%); + background: -moz-linear-gradient(top, #fff 20%, #f6f6f6 50%, #eee 52%, #f4f4f4 100%); + background: -o-linear-gradient(top, #fff 20%, #f6f6f6 50%, #eee 52%, #f4f4f4 100%); + background: linear-gradient(top, #fff 20%, #f6f6f6 50%, #eee 52%, #f4f4f4 100%); + background-clip: padding-box; + box-shadow: 0 0 3px #fff inset, 0 1px 1px rgba(0, 0, 0, .1); + color: #444; + text-decoration: none; + white-space: nowrap; + line-height: 24px; +} +.gform_wrapper .chosen-container-single .chosen-default { + color: #999; +} +.gform_wrapper .chosen-container-single .chosen-single span { + display: block; + overflow: hidden; + margin-right: 26px; + text-overflow: ellipsis; + white-space: nowrap; +} +.gform_wrapper .chosen-container-single .chosen-single-with-deselect span { + margin-right: 38px; +} +.gform_wrapper .chosen-container-single .chosen-single abbr { + position: absolute; + top: 6px; + right: 26px; + display: block; + width: 12px; + height: 12px; + background: url(../images/chosen-sprite.png) -42px 1px no-repeat; + font-size: 1px; +} +.gform_wrapper .chosen-container-single .chosen-single abbr:hover { + background-position: -42px -10px; +} +.gform_wrapper .chosen-container-single.chosen-disabled .chosen-single abbr:hover { + background-position: -42px -10px; +} +.gform_wrapper .chosen-container-single .chosen-single div { + position: absolute; + top: 0; + right: 0; + display: block; + width: 18px; + height: 100%} +.gform_wrapper .chosen-container-single .chosen-single div b { + display: block; + width: 100%; + height: 100%; + background: url(../images/chosen-sprite.png) no-repeat 0 2px; +} +.gform_wrapper .chosen-container-single .chosen-search { + position: relative; + z-index: 1010; + margin: 0; + padding: 3px 4px; + white-space: nowrap; +} +.gform_wrapper .chosen-container-single .chosen-search input[type=text] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + margin: 1px 0; + padding: 4px 20px 4px 5px; + width: 100%; + height: auto; + outline: 0; + border: 1px solid #aaa; + background: #fff url(../images/chosen-sprite.png) no-repeat 100% -20px; + background: url(../images/chosen-sprite.png) no-repeat 100% -20px; + font-size: 1em; + font-family: sans-serif; + line-height: normal; + border-radius: 0; +} +.gform_wrapper .chosen-container-single .chosen-drop { + margin-top: -1px; + border-radius: 0 0 4px 4px; + background-clip: padding-box; +} +.gform_wrapper .chosen-container-single.chosen-container-single-nosearch .chosen-search { + position: absolute; + left: -9999px; +} +.gform_wrapper .chosen-container .chosen-results { + position: relative; + overflow-x: hidden; + overflow-y: auto; + margin: 0 4px 4px 0; + padding: 0 0 0 4px; + max-height: 240px; + -webkit-overflow-scrolling: touch; +} +.gform_wrapper .chosen-container .chosen-results li { + display: none; + margin: 0; + padding: 5px 6px; + list-style: none; + line-height: 15px; + -webkit-touch-callout: none; +} +.gform_wrapper .chosen-container .chosen-results li.active-result { + display: list-item; + cursor: pointer; +} +.gform_wrapper .chosen-container .chosen-results li.disabled-result { + display: list-item; + color: #ccc; + cursor: default; +} +.gform_wrapper .chosen-container .chosen-results li.highlighted { + background-color: #3875d7; + background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc)); + background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%); + background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%); + background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%); + background-image: linear-gradient(#3875d7 20%, #2a62bc 90%); + color: #fff; +} +.gform_wrapper .chosen-container .chosen-results li.no-results { + display: list-item; + background: #f4f4f4; +} +.gform_wrapper .chosen-container .chosen-results li.group-result { + display: list-item; + font-weight: 700; + cursor: default; +} +.gform_wrapper .chosen-container .chosen-results li.group-option { + padding-left: 15px; +} +.gform_wrapper .chosen-container .chosen-results li em { + font-style: normal; + text-decoration: underline; +} +.gform_wrapper .chosen-container-multi .chosen-choices { + position: relative; + overflow: hidden; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + margin: 0; + padding: 0; + width: 100%; + height: auto!important; + height: 1%; + border: 1px solid #aaa; + background-color: #fff; + background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(1%, #eee), color-stop(15%, #fff)); + background-image: -webkit-linear-gradient(#eee 1%, #fff 15%); + background-image: -moz-linear-gradient(#eee 1%, #fff 15%); + background-image: -o-linear-gradient(#eee 1%, #fff 15%); + background-image: linear-gradient(#eee 1%, #fff 15%); + cursor: text; +} +.gform_wrapper .chosen-container-multi .chosen-choices li { + float: left; + list-style: none; +} +.gform_wrapper .chosen-container-multi .chosen-choices li.search-field { + margin: 0; + padding: 0; + white-space: nowrap; +} +.gform_wrapper .chosen-container-multi .chosen-choices li.search-field input[type=text] { + margin: 1px 0; + padding: 5px; + height: 15px; + outline: 0; + border: 0!important; + background: transparent!important; + box-shadow: none; + color: #666; + font-size: 100%; + font-family: sans-serif; + line-height: normal; + border-radius: 0; +} +.gform_wrapper .chosen-container-multi .chosen-choices li.search-field .default { + color: #999; +} +.gform_wrapper .chosen-container-multi .chosen-choices li.search-choice { + position: relative; + margin: 3px 0 3px 5px !important; + padding: 3px 20px 3px 5px; + border: 1px solid #aaa; + border-radius: 3px; + background-color: #e4e4e4; + background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee)); + background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%); + background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%); + background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%); + background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%); + background-clip: padding-box; + box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, .05); + color: #333; + line-height: 13px; + cursor: default; +} +.gform_wrapper .chosen-container-multi .chosen-choices li.search-choice .search-choice-close { + position: absolute; + top: 4px; + right: 3px; + display: block; + width: 12px; + height: 12px; + background: url(../images/chosen-sprite.png) -42px 1px no-repeat; + font-size: 1px; +} +.gform_wrapper .chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover { + background-position: -42px -10px; +} +.gform_wrapper .chosen-container-multi .chosen-choices li.search-choice-disabled { + padding-right: 5px; + border: 1px solid #ccc; + background-color: #e4e4e4; + background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee)); + background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%); + background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%); + background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%); + background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%); + color: #666; +} +.gform_wrapper .chosen-container-multi .chosen-choices li.search-choice-focus { + background: #d4d4d4; +} +.gform_wrapper .chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close { + background-position: -42px -10px; +} +.gform_wrapper .chosen-container-multi .chosen-results { + margin: 0; + padding: 0; +} +.gform_wrapper .chosen-container-multi .chosen-drop .result-selected { + display: list-item; + color: #ccc; + cursor: default; +} +.gform_wrapper .chosen-container-active .chosen-single { + border: 1px solid #5897fb; + box-shadow: 0 0 5px rgba(0, 0, 0, .3); +} +.gform_wrapper .chosen-container-active.chosen-with-drop .chosen-single { + border: 1px solid #aaa; + -moz-border-radius-bottomright: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomleft: 0; + border-bottom-left-radius: 0; + background-image: -webkit-gradient(linear, 50% 0, 50% 100%, color-stop(20%, #eee), color-stop(80%, #fff)); + background-image: -webkit-linear-gradient(#eee 20%, #fff 80%); + background-image: -moz-linear-gradient(#eee 20%, #fff 80%); + background-image: -o-linear-gradient(#eee 20%, #fff 80%); + background-image: linear-gradient(#eee 20%, #fff 80%); + box-shadow: 0 1px 0 #fff inset; +} +.gform_wrapper .chosen-container-active.chosen-with-drop .chosen-single div { + border-left: 0; + background: transparent; +} +.gform_wrapper .chosen-container-active.chosen-with-drop .chosen-single div b { + background-position: -18px 2px; +} +.gform_wrapper .chosen-container-active .chosen-choices { + border: 1px solid #5897fb; + box-shadow: 0 0 5px rgba(0, 0, 0, .3); +} +.gform_wrapper .chosen-container-active .chosen-choices li.search-field input[type=text] { + color: #111!important; +} +.gform_wrapper .chosen-disabled { + opacity: .5!important; + cursor: default; +} +.gform_wrapper .chosen-disabled .chosen-single { + cursor: default; +} +.gform_wrapper .chosen-disabled .chosen-choices .search-choice .search-choice-close { + cursor: default; +} +.gform_wrapper .chosen-rtl { + text-align: right; +} +.gform_wrapper .chosen-rtl .chosen-single { + overflow: visible; + padding: 0 8px 0 0; +} +.gform_wrapper .chosen-rtl .chosen-single span { + margin-right: 0; + margin-left: 26px; + direction: rtl; +} +.gform_wrapper .chosen-rtl .chosen-single-with-deselect span { + margin-left: 38px; +} +.gform_wrapper .chosen-rtl .chosen-single div { + right: auto; + left: 3px; +} +.gform_wrapper .chosen-rtl .chosen-single abbr { + right: auto; + left: 26px; +} +.gform_wrapper .chosen-rtl .chosen-choices li { + float: right; +} +.gform_wrapper .chosen-rtl .chosen-choices li.search-field input[type=text] { + direction: rtl; +} +.gform_wrapper .chosen-rtl .chosen-choices li.search-choice { + margin: 3px 5px 3px 0; + padding: 3px 5px 3px 19px; +} +.gform_wrapper .chosen-rtl .chosen-choices li.search-choice .search-choice-close { + right: auto; + left: 4px; +} +.gform_wrapper .chosen-rtl.chosen-container-single-nosearch .chosen-search.gform_wrapper .chosen-rtl .chosen-drop { + left: 9999px; } - -.gform_wrapper .chzn-container-single .chzn-single span { - margin-right: 26px; - display: block; - overflow: hidden; - white-space: nowrap; - -o-text-overflow: ellipsis; - -ms-text-overflow: ellipsis; - text-overflow: ellipsis; -} - -.gform_wrapper .chzn-container-single .chzn-single div { - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; - -moz-background-clip: padding; - -webkit-background-clip: padding-box; - background-clip: padding-box; - background-color: #CCC; - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #CCC), color-stop(0.6, #EEE)); - background-image: -webkit-linear-gradient(center bottom, #CCC 0%, #EEE 60%); - background-image: -moz-linear-gradient(center bottom, #CCC 0%, #EEE 60%); - background-image: -o-linear-gradient(bottom, #CCC 0%, #EEE 60%); - background-image: -ms-linear-gradient(top, #CCC 0%,#EEE 60%); - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#CCC', endColorstr='#EEE',GradientType=0 ); - background-image: linear-gradient(top, #CCC 0%,#EEE 60%); - border-left: 1px solid #AAA; - position: absolute; - right: 0; - top: 0; - display: block; - height: 100%; - width: 18px; -} - -.gform_wrapper .chzn-container-single .chzn-single div b { - background-image: url(../images/chosen-sprite.png); - background-position: 0 1px; - background-repeat: no-repeat; - display: block; - width: 100%; - height: 100%; -} - -.gform_wrapper .chzn-container-single .chzn-search { - padding: 3px 4px; - margin: 0; - white-space: nowrap; -} - -.gform_wrapper .chzn-container-single .chzn-search input { - background: #FFF url(../images/chosen-sprite.png) 100% -20px no-repeat; - background: url(../images/chosen-sprite.png) 100% -20px no-repeat, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #EEE)); - background: url(../images/chosen-sprite.png) 100% -20px no-repeat, -webkit-linear-gradient(center bottom, white 85%, #EEE 99%); - background: url(../images/chosen-sprite.png) 100% -20px no-repeat, -moz-linear-gradient(center bottom, white 85%, #EEE 99%); - background: url(../images/chosen-sprite.png) 100% -20px no-repeat, -o-linear-gradient(bottom, white 85%, #EEE 99%); - background: url(../images/chosen-sprite.png) 100% -20px no-repeat, -ms-linear-gradient(top, #FFF 85%,#EEE 99%); - background: url(../images/chosen-sprite.png) 100% -20px no-repeat, -ms-linear-gradient(top, #FFF 85%,#EEE 99%); - background: url(../images/chosen-sprite.png) 100% -20px no-repeat, linear-gradient(top, #FFF 85%,#EEE 99%); - margin: 1px 0; - padding: 4px 20px 4px 5px; - outline: 0; - border: 1px solid #AAA; - font-family: sans-serif; - font-size: 1em; +.gform_wrapper .chosen-rtl.chosen-container-single .chosen-results { + margin: 0 0 4px 4px; + padding: 0 4px 0 0; } - -.gform_wrapper .chzn-container-single .chzn-drop { - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; - -moz-background-clip: padding; - -webkit-background-clip: padding-box; - background-clip: padding-box; -} - -.gform_wrapper .chzn-container-multi .chzn-choices { - background-color: #FFF; - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #EEE)); - background-image: -webkit-linear-gradient(center bottom, white 85%, #EEE 99%); - background-image: -moz-linear-gradient(center bottom, white 85%, #EEE 99%); - background-image: -o-linear-gradient(bottom, white 85%, #EEE 99%); - background-image: -ms-linear-gradient(top, #FFF 85%,#EEE 99%); - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFF', endColorstr='#EEE',GradientType=0 ); - background-image: linear-gradient(top, #FFF 85%,#EEE 99%); - border: 1px solid #AAA; - margin: 0; - padding: 0; - cursor: text; - overflow: hidden; - height: auto !important; - height: 1%; position: relative; -} - -.gform_wrapper .chzn-container-multi .chzn-choices li { - float: left; - list-style: none; -} - -.gform_wrapper .chzn-container-multi .chzn-choices .search-field { - white-space: nowrap; - margin: 0; - padding: 0; -} - -.gform_wrapper .chzn-container-multi .chzn-choices .search-field input { - color: #666; - background: transparent !important; - border: 0 !important; - padding: 5px; - margin: 1px 0; - outline: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - -o-box-shadow: none; - box-shadow: none; -} - -.gform_wrapper .chzn-container-multi .chzn-choices .search-field .default { - color: #999; -} - -.gform_wrapper .chzn-container-multi .chzn-choices .search-choice { - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -moz-background-clip: padding; - -webkit-background-clip: padding-box; - background-clip: padding-box; - background-color: #E4E4E4; - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #E4E4E4), color-stop(0.7, #EEE)); - background-image: -webkit-linear-gradient(center bottom, #E4E4E4 0%, #EEE 70%); - background-image: -moz-linear-gradient(center bottom, #E4E4E4 0%, #EEE 70%); - background-image: -o-linear-gradient(bottom, #E4E4E4 0%, #EEE 70%); - background-image: -ms-linear-gradient(top, #E4E4E4 0%,#EEE 70%); - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#E4E4E4', endColorstr='#EEE',GradientType=0 ); - background-image: linear-gradient(top, #E4E4E4 0%,#EEE 70%); - color: #333; - border: 1px solid #B4B4B4; - line-height: 13px; - padding: 3px 19px 3px 6px; - margin: 3px 0 3px 5px; - position: relative; -} - -.gform_wrapper .chzn-container-multi .chzn-choices .search-choice span { - cursor: default; -} - -.gform_wrapper .chzn-container-multi .chzn-choices .search-choice-focus { - background-color: #D4D4D4; -} - -.gform_wrapper .chzn-container-multi .chzn-choices .search-choice .search-choice-close { - display: block; - position: absolute; - right: 5px; - top: 6px; - width: 8px; - height: 9px; - font-size: 1px; - background-image: url(../images/chosen-sprite.png); - background-position: right top; - background-repeat: no-repeat; -} - -.gform_wrapper .chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover { - background-position: right -9px; -} - -.gform_wrapper .chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close { - background-position: right -9px; -} - -.gform_wrapper .chzn-container .chzn-results { - margin: 0 4px 4px 0; - max-height: 190px; - padding: 0 0 0 4px; - position: relative; - overflow-x: hidden; - overflow-y: auto; -} - -.gform_wrapper .chzn-container-multi .chzn-results { - margin: -1px 0 0; - padding: 0; -} - -.gform_wrapper .chzn-container .chzn-results li { - display:none; - line-height: 80%; - padding: 7px 7px 8px; - margin: 0; - list-style: none; -} - -.gform_wrapper .chzn-container .chzn-results .active-result { - cursor: pointer; - display: list-item; -} - -.gform_wrapper .chzn-container .chzn-results .highlighted { - background-color: #F0F0F0; -} - -.gform_wrapper .chzn-container .chzn-results li em { - background-color: #FEFFDE; - font-style: normal; -} - -.gform_wrapper .chzn-container .chzn-results .highlighted em { - background: transparent; -} - -.gform_wrapper .chzn-container .chzn-results .no-results { - background-color: #F4F4F4; -} - -.gform_wrapper .chzn-container .chzn-results .group-result { - cursor: default; - color: #999; - font-weight: bold; -} - -.gform_wrapper .chzn-container .chzn-results .group-option { - padding-left: 20px; -} - -.gform_wrapper .chzn-container-multi .chzn-drop .result-selected { - display: none; -} - -.gform_wrapper .chzn-container-active .chzn-single { - -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); - -moz-box-shadow: 0 0 5px rgba(0,0,0,.3); - -o-box-shadow: 0 0 5px rgba(0,0,0,.3); - box-shadow: 0 0 5px rgba(0,0,0,.3); -} - -.gform_wrapper .chzn-container-active .chzn-single-with-drop { - border: 1px solid #AAA; - -webkit-box-shadow: 0 1px 0 #FFF inset; - -moz-box-shadow: 0 1px 0 #FFF inset; - -o-box-shadow: 0 1px 0 #FFF inset; - box-shadow: 0 1px 0 #FFF inset; - background-color: #EEE; - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #EEE)); - background-image: -webkit-linear-gradient(center bottom, white 0%, #EEE 50%); - background-image: -moz-linear-gradient(center bottom, white 0%, #EEE 50%); - background-image: -o-linear-gradient(bottom, white 0%, #EEE 50%); - background-image: -ms-linear-gradient(top, #FFF 0%,#EEE 50%); - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFF', endColorstr='#EEE',GradientType=0 ); - background-image: linear-gradient(top, #FFF 0%,#EEE 50%); - -webkit-border-bottom-left-radius : 0; - -webkit-border-bottom-right-radius: 0; - -moz-border-radius-bottomleft : 0; - -moz-border-radius-bottomright: 0; - border-bottom-left-radius : 0; - border-bottom-right-radius: 0; -} - -.gform_wrapper .chzn-container-active .chzn-single-with-drop div { - background: transparent; - border-left: none; -} - -.gform_wrapper .chzn-container-active .chzn-single-with-drop div b { - background-position: -18px 1px; -} - -.gform_wrapper .chzn-container-active .chzn-choices { - -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3); - -moz-box-shadow: 0 0 5px rgba(0,0,0,.3); - -o-box-shadow: 0 0 5px rgba(0,0,0,.3); - box-shadow: 0 0 5px rgba(0,0,0,.3); -} - -.gform_wrapper .chzn-container-active .chzn-choices .search-field input { - color: #111 !important; -} - -.gform_wrapper .chzn-rtl { - direction: rtl; - text-align: right; -} - -.gform_wrapper .chzn-rtl .chzn-single { - padding-left: 0; - padding-right: 8px; -} - -.gform_wrapper .chzn-rtl .chzn-single span { - margin-left: 26px; - margin-right: 0; -} - -.gform_wrapper .chzn-rtl .chzn-single div { - left: 0; - right: auto; - border-left: none; - border-right: 1px solid #AAA; - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; +.gform_wrapper .chosen-rtl .chosen-results li.group-option { + padding-right: 15px; + padding-left: 0; } - -.gform_wrapper .chzn-rtl .chzn-choices li { - float: right; +.gform_wrapper .chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div { + border-right: 0; } - -.gform_wrapper .chzn-rtl .chzn-choices .search-choice { - padding: 3px 6px 3px 19px; - margin: 3px 5px 3px 0; +.gform_wrapper .chosen-rtl .chosen-search input[type=text] { + padding: 4px 5px 4px 20px; + background: #fff url(../images/chosen-sprite.png) no-repeat -30px -20px; + background: url(../images/chosen-sprite.png) no-repeat -30px -20px; + direction: rtl; } - -.gform_wrapper .chzn-rtl .chzn-choices .search-choice .search-choice-close { - left: 5px; - right: auto; - background-position: right top; +.gform_wrapper .chosen-rtl.chosen-container-single .chosen-single div b { + background-position: 6px 2px; } - -.gform_wrapper .chzn-rtl.chzn-container-single .chzn-results { - margin-left: 4px; - margin-right: 0; - padding-left: 0; - padding-right: 4px; -} - -.gform_wrapper .chzn-rtl .chzn-results .group-option { - padding-left: 0; - padding-right: 20px; +.gform_wrapper .chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b { + background-position: -12px 2px; } - -.gform_wrapper .chzn-rtl.chzn-container-active .chzn-single-with-drop div { - border-right: none; -} - -.gform_wrapper .chzn-rtl .chzn-search input { - background: url(../images/chosen-sprite.png) -38px -20px no-repeat, #FFF; - background: url(../images/chosen-sprite.png) -38px -20px no-repeat, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #EEE)); - background: url(../images/chosen-sprite.png) -38px -20px no-repeat, -webkit-linear-gradient(center bottom, white 85%, #EEE 99%); - background: url(../images/chosen-sprite.png) -38px -20px no-repeat, -moz-linear-gradient(center bottom, white 85%, #EEE 99%); - background: url(../images/chosen-sprite.png) -38px -20px no-repeat, -o-linear-gradient(bottom, white 85%, #EEE 99%); - background: url(../images/chosen-sprite.png) -38px -20px no-repeat, -ms-linear-gradient(top, #FFF 85%,#EEE 99%); - background: url(../images/chosen-sprite.png) -38px -20px no-repeat, -ms-linear-gradient(top, #FFF 85%,#EEE 99%); - background: url(../images/chosen-sprite.png) -38px -20px no-repeat, linear-gradient(top, #FFF 85%,#EEE 99%); - padding: 4px 5px 4px 20px; +@media only screen and (-webkit-min-device-pixel-ratio:2), only screen and (min-resolution:144dpi) { + .gform_wrapper .chosen-rtl .chosen-search input[type=text].gform_wrapper .chosen-container-single .chosen-single abbr.gform_wrapper .chosen-container-single .chosen-single div b.gform_wrapper .chosen-container-single .chosen-search input[type=text].gform_wrapper .chosen-container-multi .chosen-choices .search-choice .search-choice-close.gform_wrapper .chosen-container .chosen-results-scroll-down span.gform_wrapper .chosen-container .chosen-results-scroll-up span { + background-image: url(../images/chosen-sprite@2x.png)!important; + background-size: 52px 37px!important; + background-repeat: no-repeat!important; + } } /* credit card icons ------------------------------------------------------*/ diff --git a/entry_detail.php b/entry_detail.php index 47927d5..bffa0b3 100644 --- a/entry_detail.php +++ b/entry_detail.php @@ -1,1005 +1,1018 @@ - "is_starred", "value" => (bool) $star); - if(!is_null($read)) - $search_criteria["field_filters"][] = array("key" => "is_read", "value" => (bool) $read); - - $search_field_id = rgget("field_id"); - - if(isset($_GET["field_id"]) && $_GET["field_id"] !== ''){ - $key = $search_field_id; - $val = rgget("s"); - $strpos_row_key = strpos($search_field_id, "|"); - if ($strpos_row_key !== false) { //multi-row likert - $key_array = explode("|", $search_field_id); - $key = $key_array[0]; - $val = $key_array[1] . ":" . $val; - } - $type = rgget("type"); - if(empty($type)){ - $type = rgget("field_id") == "0" ? "global" : "field"; - } - - $search_criteria["field_filters"][] = array( - "key" => $key, - "type" => $type, - "operator" => rgempty("operator", $_GET) ? "is" : rgget("operator"), - "value" => $val - ); - } - - $paging = array('offset' => $position, 'page_size' => 1); - - if(!empty($sort_field)) - $sorting = array('key' => $_GET["sort"], 'direction' => $sort_direction, 'is_numeric' => $is_numeric); - else - $sorting = array(); - $total_count = 0; - $leads = GFAPI::get_entries($form['id'], $search_criteria, $sorting, $paging, $total_count); - - $prev_pos = !rgblank($position) && $position > 0 ? $position - 1 : false; - $next_pos = !rgblank($position) && $position < $total_count - 1 ? $position + 1 : false; - - // unread filter requires special handling for pagination since entries are filter out of the query as they are read - if($filter == 'unread') { - $next_pos = $position; - - if($next_pos + 1 == $total_count) - $next_pos = false; - - } - - if(!$lead_id){ - $lead = !empty($leads) ? $leads[0] : false; - } else { - $lead = GFAPI::get_entry($lead_id); - } - - - if(!$lead) { - _e("Oops! We couldn't find your entry. Please try again", "gravityforms"); - return; - } - - RGFormsModel::update_lead_property($lead["id"], "is_read", 1); - - switch(RGForms::post("action")){ - case "update" : - check_admin_referer('gforms_save_entry', 'gforms_save_entry'); - //Loading files that have been uploaded to temp folder - $files = GFCommon::json_decode(stripslashes(RGForms::post("gform_uploaded_files"))); - if(!is_array($files)) - $files = array(); - - GFFormsModel::$uploaded_files[$form_id] = $files; - GFFormsModel::save_lead($form, $lead); - - do_action("gform_after_update_entry", $form, $lead["id"]); - do_action("gform_after_update_entry_{$form["id"]}", $form, $lead["id"]); - - $lead = RGFormsModel::get_lead($lead["id"]); - $lead = GFFormsModel::set_entry_meta($lead, $form); - break; - - case "add_note" : - check_admin_referer('gforms_update_note', 'gforms_update_note'); - $user_data = get_userdata($current_user->ID); - RGFormsModel::add_note($lead["id"], $current_user->ID, $user_data->display_name, stripslashes($_POST["new_note"])); - - //emailing notes if configured - if(rgpost("gentry_email_notes_to")) - { - $email_to = $_POST["gentry_email_notes_to"]; - $email_from = $current_user->user_email; - $email_subject = stripslashes($_POST["gentry_email_subject"]); - - $headers = "From: \"$email_from\" <$email_from> \r\n"; - $result = wp_mail($email_to, $email_subject, stripslashes($_POST["new_note"]), $headers); - } - break; - - case "add_quick_note" : - check_admin_referer('gforms_save_entry', 'gforms_save_entry'); - $user_data = get_userdata($current_user->ID); - RGFormsModel::add_note($lead["id"], $current_user->ID, $user_data->display_name, stripslashes($_POST["quick_note"])); - break; - - case "bulk" : - check_admin_referer('gforms_update_note', 'gforms_update_note'); - if($_POST["bulk_action"] == "delete") - RGFormsModel::delete_notes($_POST["note"]); - break; - - case "trash" : - check_admin_referer('gforms_save_entry', 'gforms_save_entry'); - RGFormsModel::update_lead_property($lead["id"], "status", "trash"); - $lead = RGFormsModel::get_lead($lead["id"]); - break; - - case "restore" : - case "unspam" : - check_admin_referer('gforms_save_entry', 'gforms_save_entry'); - RGFormsModel::update_lead_property($lead["id"], "status", "active"); - $lead = RGFormsModel::get_lead($lead["id"]); - break; - - case "spam" : - check_admin_referer('gforms_save_entry', 'gforms_save_entry'); - RGFormsModel::update_lead_property($lead["id"], "status", "spam"); - $lead = RGFormsModel::get_lead($lead["id"]); - break; - - case "delete" : - check_admin_referer('gforms_save_entry', 'gforms_save_entry'); - if(!GFCommon::current_user_can_any("gravityforms_delete_entries")) - die(__("You don't have adequate permissions to delete entries.", "gravityforms")); - RGFormsModel::delete_lead($lead["id"]); - ?> - - - - - - - - - " /> - -
-

ID: lock_info($lead_id);?>

- - -
-
    -
  • entry of
  • -
  • -
  • -
-
- - - - -
-
- - - -
-

- -

-
-
-
-
- :

- : -

- : -

- - : " alt="" title="">user_login) ?> -

- - - : " target="_blank" alt="" title="">.../ -

- - : " title="">post_title) ?> -

- : -

- : -

- : -

- : -

- -
-
- -
- '; - echo apply_filters("gform_entrydetail_update_button", $update_button); - if($mode == "edit") - echo '  '; - } - ?> -
-
-
-
-
-
- - - - - - - -
-

-
- -
- -

- - " class="button"> - - " id="notification_" onclick="toggleNotificationOverride();" /> -

- - - - - " class="button" style="" onclick="ResendNotifications();"/> - - - -
-
-
- - - - -
- - - - - -
- - -
- -
-
- -
-

- -

- - - -
- -
- -
- -
-
-
-
- - -
- -
- -
-

- -

-
-
 
- - - - - - "; - - $content = apply_filters("gform_field_content", $content, $field, $value, $lead["id"], $form["id"]); - - echo $content; - break; - } - } - ?> - -
-

-
" . - GFCommon::get_field_input($field, $value, $lead["id"]) . "
-
- -
- - 0 && $is_editable && GFCommon::current_user_can_any("gravityforms_edit_entry_notes")){ - ?> -
- - - '; - echo apply_filters("gform_notes_apply_button", $apply_button); - ?> -
- - - - - - - - - - - = $notes_count ? true : false; - ?> - - - - - - - - - - - - -
Notes
- - - - "> - note_type ? " gforms_note_{$note->note_type}" : ""; - ?> -
-
user_id, 48), $note);?>
-
user_name)?>
-

user_email) ?>
- date_created, false)) ?>

-
-
value) ?>
-
- - '; - echo apply_filters("gform_addnote_button", $note_button); - - if(!empty($emails)){ ?> -    - - -    - - - - -
- - - - - - - - - - = $field_count ? true : false; - ?> - - - - = $field_count && !$has_product_fields ? true : false; - $last_row = $is_last ? " lastrow" : ""; - - $display_value = empty($display_value) && $display_value !== "0" ? " " : $display_value; - - $content = ' - - - - - - '; - - $content = apply_filters("gform_field_content", $content, $field, $value, $lead["id"], $form["id"]); - - echo $content; - - } - break; - } - } - - $products = array(); - if($has_product_fields){ - $products = GFCommon::get_product_fields($form, $lead); - if(!empty($products["products"])){ - ?> - - - - - - - - - -
- : - - - onclick="ToggleShowEmptyFields();"/>   - -
">
' . esc_html(GFCommon::get_label($field)) . '
' . $display_value . '
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
    - - > - -
-
  
 
-
- $pos), remove_query_arg(array('pos', 'lid'))) . '"': ''; - $class .= ' gf_entry_pagination_link'; - $class .= $pos !== false ? ' gf_entry_pagination_link_active' : ' gf_entry_pagination_link_inactive'; - - return ''; - } - - /** - * @param $lead - * @param $form - * @return mixed - */ - public static function payment_details_box($lead, $form) - { - ?> - -
-

- -

- -
-
-
-
- : -

- : -

- : -

- : -

- -
-
-
-
- "is_starred", "value" => (bool) $star); + if(!is_null($read)) + $search_criteria["field_filters"][] = array("key" => "is_read", "value" => (bool) $read); + + $search_field_id = rgget("field_id"); + + if(isset($_GET["field_id"]) && $_GET["field_id"] !== ''){ + $key = $search_field_id; + $val = rgget("s"); + $strpos_row_key = strpos($search_field_id, "|"); + if ($strpos_row_key !== false) { //multi-row likert + $key_array = explode("|", $search_field_id); + $key = $key_array[0]; + $val = $key_array[1] . ":" . $val; + } + $type = rgget("type"); + if(empty($type)){ + $type = rgget("field_id") == "0" ? "global" : "field"; + } + + $search_criteria["field_filters"][] = array( + "key" => $key, + "type" => $type, + "operator" => rgempty("operator", $_GET) ? "is" : rgget("operator"), + "value" => $val + ); + } + + $paging = array('offset' => $position, 'page_size' => 1); + + if(!empty($sort_field)) + $sorting = array('key' => $_GET["sort"], 'direction' => $sort_direction, 'is_numeric' => $is_numeric); + else + $sorting = array(); + $total_count = 0; + $leads = GFAPI::get_entries($form['id'], $search_criteria, $sorting, $paging, $total_count); + + $prev_pos = !rgblank($position) && $position > 0 ? $position - 1 : false; + $next_pos = !rgblank($position) && $position < $total_count - 1 ? $position + 1 : false; + + // unread filter requires special handling for pagination since entries are filter out of the query as they are read + if($filter == 'unread') { + $next_pos = $position; + + if($next_pos + 1 == $total_count) + $next_pos = false; + + } + + if(!$lead_id){ + $lead = !empty($leads) ? $leads[0] : false; + } else { + $lead = GFAPI::get_entry($lead_id); + } + + + if(!$lead) { + _e("Oops! We couldn't find your entry. Please try again", "gravityforms"); + return; + } + + RGFormsModel::update_lead_property($lead["id"], "is_read", 1); + + switch(RGForms::post("action")){ + case "update" : + check_admin_referer('gforms_save_entry', 'gforms_save_entry'); + //Loading files that have been uploaded to temp folder + $files = GFCommon::json_decode(stripslashes(RGForms::post("gform_uploaded_files"))); + if(!is_array($files)) + $files = array(); + + GFFormsModel::$uploaded_files[$form_id] = $files; + GFFormsModel::save_lead($form, $lead); + + do_action("gform_after_update_entry", $form, $lead["id"]); + do_action("gform_after_update_entry_{$form["id"]}", $form, $lead["id"]); + + $lead = RGFormsModel::get_lead($lead["id"]); + $lead = GFFormsModel::set_entry_meta($lead, $form); + break; + + case "add_note" : + check_admin_referer('gforms_update_note', 'gforms_update_note'); + $user_data = get_userdata($current_user->ID); + RGFormsModel::add_note($lead["id"], $current_user->ID, $user_data->display_name, stripslashes($_POST["new_note"])); + + //emailing notes if configured + if(rgpost("gentry_email_notes_to")){ + GFCommon::log_debug( 'Preparing to email entry notes.' ); + $email_to = $_POST["gentry_email_notes_to"]; + $email_from = $current_user->user_email; + $email_subject = stripslashes($_POST["gentry_email_subject"]); + $headers = "From: \"$email_from\" <$email_from> \r\n"; + $body = stripslashes( $_POST["new_note"] ); + GFCommon::log_debug( "Emailing notes - TO: $email_to SUBJECT: $email_subject BODY: $body HEADERS: $headers" ); + $result = wp_mail( $email_to, $email_subject, $body, $headers ); + } + break; + + case "add_quick_note" : + check_admin_referer('gforms_save_entry', 'gforms_save_entry'); + $user_data = get_userdata($current_user->ID); + RGFormsModel::add_note($lead["id"], $current_user->ID, $user_data->display_name, stripslashes($_POST["quick_note"])); + break; + + case "bulk" : + check_admin_referer('gforms_update_note', 'gforms_update_note'); + if($_POST["bulk_action"] == "delete") + RGFormsModel::delete_notes($_POST["note"]); + break; + + case "trash" : + check_admin_referer('gforms_save_entry', 'gforms_save_entry'); + RGFormsModel::update_lead_property($lead["id"], "status", "trash"); + $lead = RGFormsModel::get_lead($lead["id"]); + break; + + case "restore" : + case "unspam" : + check_admin_referer('gforms_save_entry', 'gforms_save_entry'); + RGFormsModel::update_lead_property($lead["id"], "status", "active"); + $lead = RGFormsModel::get_lead($lead["id"]); + break; + + case "spam" : + check_admin_referer('gforms_save_entry', 'gforms_save_entry'); + RGFormsModel::update_lead_property($lead["id"], "status", "spam"); + $lead = RGFormsModel::get_lead($lead["id"]); + break; + + case "delete" : + check_admin_referer('gforms_save_entry', 'gforms_save_entry'); + if(!GFCommon::current_user_can_any("gravityforms_delete_entries")) + die(__("You don't have adequate permissions to delete entries.", "gravityforms")); + RGFormsModel::delete_lead($lead["id"]); + ?> + + + + + +
+ + + " /> + +
+

ID: lock_info($lead_id);?>

+ + +
+
    +
  • entry of
  • +
  • +
  • +
+
+ + + + +
+
+ + + +
+

+ +

+
+
+
+ :

+ : +

+ : +

+ + : " alt="" title="">user_login) ?> +

+ + + : " target="_blank" alt="" title="">.../ +

+ + : " title="">post_title) ?> +

+ : +

+ : +

+ : +

+ : +

+ +
+
+ +
+ '; + echo apply_filters("gform_entrydetail_update_button", $update_button); + if($mode == "edit") + echo '  '; + } + ?> +
+
+
+
+
+
+ + + + + + + +
+

+
+ +
+ +

+ + " class="button"> + + " id="notification_" onclick="toggleNotificationOverride();" /> +

+ + + + + " class="button" style="" onclick="ResendNotifications();"/> + + + +
+
+
+ + + + +
+ + + + + +
+ + +
+ +
+
+ +
+

+ +

+ + + +
+ +
+ +
+ +
+
+
+
+ + +
+ +
+ +
+

+ +

+
+ + + + + + + "; + + $content = apply_filters("gform_field_content", $content, $field, $value, $lead["id"], $form["id"]); + + echo $content; + break; + } + } + ?> + +
+

+
" . + GFCommon::get_field_input($field, $value, $lead["id"]) . "
+
+ +
+
+ 0 && $is_editable && GFCommon::current_user_can_any("gravityforms_edit_entry_notes")){ + ?> +
+ + + '; + echo apply_filters("gform_notes_apply_button", $apply_button); + ?> +
+ + + + + + + + + + + = $notes_count ? true : false; + ?> + + + + + + + + + + + + +
Notes
+ + + + "> + note_type ? " gforms_note_{$note->note_type}" : ""; + ?> +
+
user_id, 48), $note);?>
+
user_name)?>
+

user_email) ?>
+ date_created, false)) ?>

+
+
value) ?>
+
+ + '; + echo apply_filters("gform_addnote_button", $note_button); + + if(!empty($emails)){ ?> +    + + +    + + + + +
+ + + + + + + + + + = $field_count ? true : false; + ?> + + + + = $field_count && !$has_product_fields ? true : false; + $last_row = $is_last ? " lastrow" : ""; + + $display_value = empty($display_value) && $display_value !== "0" ? " " : $display_value; + + $content = ' + + + + + + '; + + $content = apply_filters("gform_field_content", $content, $field, $value, $lead["id"], $form["id"]); + + echo $content; + + } + break; + } + } + + $products = array(); + if($has_product_fields){ + $products = GFCommon::get_product_fields($form, $lead); + if(!empty($products["products"])){ + ?> + + + + + + + + + +
+ : + + + onclick="ToggleShowEmptyFields();"/>   + +
">
' . esc_html(GFCommon::get_label($field)) . '
' . $display_value . '
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
    + + > + +
+
  
 
+
+ $pos), remove_query_arg(array('pos', 'lid'))) . '"': ''; + $class .= ' gf_entry_pagination_link'; + $class .= $pos !== false ? ' gf_entry_pagination_link_active' : ' gf_entry_pagination_link_inactive'; + + return ''; + } + + /** + * @param $lead + * @param $form + * @return mixed + */ + public static function payment_details_box($lead, $form) + { + ?> + +
+

+ +

+ +
+
+
+ +
+ : +
+ + +
+ : +
+ +
+ : +
+ +
+ : +
+ +
+
+
+
+ \ No newline at end of file diff --git a/export.php b/export.php index dba5857..6a5e287 100644 --- a/export.php +++ b/export.php @@ -72,15 +72,19 @@ public static function maybe_export(){ foreach($field["choices"] as &$choice) unset($choice["value"]); } + } - // convert associative array to indexed - if(isset($form['confirmations'])) - $form['confirmations'] = array_values($form['confirmations']); + // convert associative array to indexed + if(isset($form['confirmations'])) + $form['confirmations'] = array_values($form['confirmations']); - if(isset($form['notifications'])) - $form['notifications'] = array_values($form['notifications']); + if(isset($form['notifications'])){ + $form['notifications'] = array_values($form['notifications']); - } + foreach( $form["notifications"] as &$notification ){ + $notification["isActive"] = rgar( $notification, "isActive" ) ? "1" : "0"; + } + } $form = apply_filters( 'gform_export_form', $form ); $form = apply_filters( "gform_export_form_{$form['id']}", $form ); diff --git a/form_display.php b/form_display.php index 8931d8a..3083802 100644 --- a/form_display.php +++ b/form_display.php @@ -164,6 +164,7 @@ private static function upload_files($form, $files){ GFCommon::log_debug("upload_files() - temp file info: " . print_r($file_info, true)); if($file_info && move_uploaded_file($_FILES[$input_name]['tmp_name'], $target_path . $file_info["temp_filename"])){ + GFFormsModel::set_permissions( $target_path . $file_info['temp_filename'] ); $files[$input_name] = $file_info["uploaded_filename"]; GFCommon::log_debug("upload_files() - file uploaded successfully: {$file_info["uploaded_filename"]}"); } @@ -437,7 +438,7 @@ public static function get_form($form_id, $display_title=true, $display_descript $form["fields"][] = self::get_honeypot_field($form); //Fired right before the form rendering process. Allow users to manipulate the form object before it gets displayed in the front end - $form = apply_filters("gform_pre_render_$form_id", apply_filters("gform_pre_render", $form, $ajax), $ajax); + $form = apply_filters( "gform_pre_render_{$form_id}", apply_filters( 'gform_pre_render', $form, $ajax, $field_values ), $ajax, $field_values ); if($form == null) return "

" . __("Oops! We could not locate your form.", "gravityforms") . "

"; @@ -594,7 +595,7 @@ public static function get_form($form_id, $display_title=true, $display_descript "; if($has_pages){ - $previous_button = self::get_form_button($form["id"], "gform_previous_button_{$form["id"]}", $form["lastPageButton"], __("Previous", "gravityforms"), "button gform_previous_button", __("Previous Page", "gravityforms"), self::get_current_page($form_id) -1); + $previous_button = self::get_form_button($form["id"], "gform_previous_button_{$form["id"]}", $form["lastPageButton"], __("Previous", "gravityforms"), "gform_previous_button", __("Previous Page", "gravityforms"), self::get_current_page($form_id) -1); $previous_button = apply_filters("gform_previous_button", $previous_button, $form); $previous_button = apply_filters("gform_previous_button_{$form["id"]}", $previous_button, $form); $form_string .= "" . self::gform_footer($form, "gform_page_footer " . $form['labelPlacement'], $ajax, $field_values, $previous_button, $display_title, $display_description, $is_postback) . " @@ -774,12 +775,14 @@ private static function get_form_button($form_id, $button_input_id, $button, $de } if($button["type"] == "text" || empty($button["imageUrl"])){ + $class .= ' button'; $button_text = !empty($button["text"]) ? $button["text"] : $default_text; $button_input = ""; } else{ $imageUrl = $button["imageUrl"]; - $button_input= ""; + $class .= ' gform_image_button'; + $button_input= ""; } return $button_input; } @@ -788,7 +791,7 @@ private static function gform_footer($form, $class, $ajax, $field_values, $previ $form_id = $form["id"]; $footer = "
"; - $button_input = self::get_form_button($form["id"], "gform_submit_button_{$form["id"]}", $form["button"], __("Submit", "gravityforms"), "button gform_button", __("Submit", "gravityforms"), 0); + $button_input = self::get_form_button($form["id"], "gform_submit_button_{$form["id"]}", $form["button"], __("Submit", "gravityforms"), "gform_button", __("Submit", "gravityforms"), 0); $button_input = apply_filters("gform_submit_button", $button_input, $form); $button_input = apply_filters("gform_submit_button_{$form_id}", $button_input, $form); $footer .= $previous_button . " " . $button_input; @@ -1031,40 +1034,40 @@ public static function handle_confirmation($form, $lead, $ajax=false){ $confirmation = empty($form["confirmation"]["message"]) ? "{$anchor} " : "{$anchor}
" . GFCommon::replace_variables($form["confirmation"]["message"], $form, $lead, false, true, $nl2br) . "
"; } else{ - if(!empty($form["confirmation"]["pageId"])){ - $url = get_permalink($form["confirmation"]["pageId"]); - $dynamic_query = GFCommon::replace_variables(trim($form["confirmation"]["queryString"]), $form, $lead, true); - if(!empty($dynamic_query)) - $url .= "?" . $dynamic_query; - } - else{ - $url = GFCommon::replace_variables(trim($form["confirmation"]["url"]), $form, $lead, false, true); - $url_info = parse_url($url); - $query_string = rgar($url_info, "query"); - $dynamic_query = GFCommon::replace_variables(trim($form["confirmation"]["queryString"]), $form, $lead, true); - $query_string .= rgempty("query", $url_info) || empty($dynamic_query) ? $dynamic_query : "&" . $dynamic_query; - - if(!empty($url_info["fragment"])) - $query_string .= "#" . rgar($url_info,"fragment"); - - $url = $url_info["scheme"] . "://" . rgar($url_info,"host"); - if(!empty($url_info["port"])) - $url .= ":" . rgar($url_info,"port"); - - $url .= rgar($url_info,"path"); - if(!empty($query_string)){ - $url .= "?{$query_string}"; - } + if ( ! empty( $form['confirmation']['pageId'] ) ) { + $url = get_permalink( $form['confirmation']['pageId'] ); - } + } else { + $url = GFCommon::replace_variables( trim( $form['confirmation']['url'] ), $form, $lead, false, true, true, 'text' ); + } - if(headers_sent() || $ajax){ - //Perform client side redirect for AJAX forms, of if headers have already been sent - $confirmation = self::get_js_redirect_confirmation($url, $ajax); - } - else{ - $confirmation = array("redirect" => $url); - } + $url_info = parse_url( $url ); + $query_string = rgar( $url_info, 'query' ); + $dynamic_query = GFCommon::replace_variables( trim( $form['confirmation']['queryString'] ), $form, $lead, true, false, false, 'text' ); + $query_string .= rgempty( 'query', $url_info ) || empty( $dynamic_query ) ? $dynamic_query : '&' . $dynamic_query; + + + if ( ! empty( $url_info['fragment'] ) ) { + $query_string .= '#' . rgar( $url_info, 'fragment' ); + } + + $url = $url_info['scheme'] . '://' . rgar( $url_info, 'host' ); + if ( ! empty( $url_info['port'] ) ) { + $url .= ':' . rgar( $url_info, 'port' ); + } + + $url .= rgar( $url_info, 'path' ); + if ( ! empty( $query_string ) ) { + $url .= "?{$query_string}"; + } + + + if ( headers_sent() || $ajax ) { + //Perform client side redirect for AJAX forms, of if headers have already been sent + $confirmation = self::get_js_redirect_confirmation( $url, $ajax ); + } else { + $confirmation = array( 'redirect' => $url ); + } } $confirmation = apply_filters("gform_confirmation_{$form["id"]}", apply_filters("gform_confirmation", $confirmation, $form, $lead, $ajax), $form, $lead, $ajax); @@ -1703,7 +1706,11 @@ public static function enqueue_form_scripts( $form, $ajax = false ){ } if( self::has_enhanced_dropdown( $form ) ) { - wp_enqueue_script( 'gform_chosen' ); + if( wp_script_is( 'chosen', 'registered' ) ) { + wp_enqueue_script( 'chosen' ); + } else { + wp_enqueue_script( 'gform_chosen' ); + } } do_action( 'gform_enqueue_scripts', $form, $ajax ); @@ -1773,8 +1780,12 @@ public static function print_form_scripts( $form, $ajax ) { $scripts[] = 'gform_masked_input'; } - if( self::has_enhanced_dropdown( $form ) && ! wp_script_is( 'gform_chosen' ) ) { - $scripts[] = 'gform_chosen'; + if( self::has_enhanced_dropdown( $form ) && ! wp_script_is( 'gform_chosen' ) && ! wp_script_is( 'chosen' ) ) { + if( wp_script_is( 'chosen', 'registered' ) ) { + $scripts[] = 'chosen'; + } else { + $scripts[] = 'gform_chosen'; + } } if( ! wp_script_is( 'jquery' ) ) { @@ -1890,11 +1901,16 @@ private static function get_conditional_logic($form, $field_values = array()){ //radio buttons start at 0 and checkboxes start at 1 $choice_index = $input_type == "radio" ? 0 : 1; + $is_pricing_field = GFCommon::is_pricing_field( $field['type'] ); foreach($field["choices"] as $choice){ + if( $input_type == "checkbox" && ($choice_index % 10) == 0){ + $choice_index++; + } + if(rgar($choice,"isSelected") && $input_type == "select"){ - $val = isset($choice["price"]) ? $choice["value"] . "|" . GFCommon::to_number($choice["price"]) : $choice["value"]; + $val = $is_pricing_field ? $choice["value"] . "|" . GFCommon::to_number($choice["price"]) : $choice["value"]; $default_values[$field["id"]] = $val; } else if(rgar($choice,"isSelected")){ @@ -2397,10 +2413,10 @@ public static function get_field($field, $value="", $force_frontend_label = fals return; //ignore page breaks in the entry detail page } else if(!IS_ADMIN){ - $next_button = self::get_form_button($form["id"], "gform_next_button_{$form["id"]}_{$field["id"]}", $field["nextButton"], __("Next", "gravityforms"), "button gform_next_button", __("Next Page", "gravityforms"), $field["pageNumber"]); + $next_button = self::get_form_button($form["id"], "gform_next_button_{$form["id"]}_{$field["id"]}", $field["nextButton"], __("Next", "gravityforms"), "gform_next_button", __("Next Page", "gravityforms"), $field["pageNumber"]); $next_button = apply_filters("gform_next_button", $next_button, $form); $next_button = apply_filters("gform_next_button_{$form["id"]}", $next_button, $form); - $previous_button = $field["pageNumber"] == 2 ? "" : self::get_form_button($form["id"], "gform_previous_button_{$form["id"]}_{$field["id"]}", $field["previousButton"], __("Previous", "gravityforms"), "button gform_previous_button", __("Previous Page", "gravityforms"), $field["pageNumber"]-2); + $previous_button = $field["pageNumber"] == 2 ? "" : self::get_form_button($form["id"], "gform_previous_button_{$form["id"]}_{$field["id"]}", $field["previousButton"], __("Previous", "gravityforms"), "gform_previous_button", __("Previous Page", "gravityforms"), $field["pageNumber"]-2); if(!empty($previous_button)){ $previous_button = apply_filters("gform_previous_button", $previous_button, $form); $previous_button = apply_filters("gform_previous_button_{$form["id"]}", $previous_button, $form); @@ -2512,8 +2528,9 @@ public static function get_field_content($field, $value="", $force_frontend_labe $admin_buttons = IS_ADMIN ? "
{$field_type_title} : " . __("Field ID", "gravityforms") . " {$field["id"]}
" . $delete_field_link . $duplicate_field_link . "
" : ""; $field_label = $force_frontend_label ? $field["label"] : GFCommon::get_label($field); - if(rgar($field, "inputType") == "singleproduct" && !rgempty($field["id"] . ".1", $value)) + if( (rgar($field, "inputType") == "singleproduct" || rgar($field, "inputType") == "calculation" ) && !rgempty($field["id"] . ".1", $value)){ $field_label = rgar($value, $field["id"] . ".1"); + } $field_id = IS_ADMIN || $form_id == 0 ? "input_$id" : "input_" . $form_id . "_$id"; @@ -2564,9 +2581,14 @@ public static function get_field_content($field, $value="", $force_frontend_labe $target_input_id = $field_id . "_3"; } - case "address" : - if(empty($target_input_id)) + case "address" : + if(empty($target_input_id)){ $target_input_id = $field_id . "_1"; + } + + case 'list': + if(empty($target_input_id)) + $target_input_id = sprintf( 'input_%s_%s_shim', $form_id, $field['id'] ); default : if(empty($target_input_id)) @@ -2734,8 +2756,9 @@ public static function update_confirmation($form, $lead=null) { foreach($form['confirmations'] as $confirmation) { - if($confirmation['isDefault']) + if( rgar($confirmation, 'isDefault') ){ continue; + } if(isset($confirmation['isActive']) && ! $confirmation['isActive']) continue; diff --git a/form_settings.php b/form_settings.php index 31a3fc2..68669d6 100644 --- a/form_settings.php +++ b/form_settings.php @@ -1431,7 +1431,10 @@ function prepare_items() { } function display() { - extract( $this->_args ); + //extract( $this->_args ); + + $singular = $this->_args['singular']; + ?> diff --git a/forms_model.php b/forms_model.php index 8f560f2..636f8c7 100644 --- a/forms_model.php +++ b/forms_model.php @@ -657,6 +657,7 @@ public static function delete_leads_by_form($form_id, $status=""){ $lead_notes_table = self::get_lead_notes_table_name(); $lead_detail_table = self::get_lead_details_table_name(); $lead_detail_long_table = self::get_lead_details_long_table_name(); + $lead_meta_table = self::get_lead_meta_table_name(); do_action("gform_delete_entries", $form_id, $status); @@ -688,6 +689,13 @@ public static function delete_leads_by_form($form_id, $status=""){ )", $form_id); $wpdb->query($sql); + //Delete from lead meta + $sql = $wpdb->prepare(" DELETE FROM $lead_meta_table + WHERE lead_id IN ( + SELECT id FROM $lead_table WHERE form_id=%d {$status_filter} + )", $form_id); + $wpdb->query($sql); + //Delete from lead $sql = $wpdb->prepare("DELETE FROM $lead_table WHERE form_id=%d {$status_filter}", $form_id); $wpdb->query($sql); @@ -1472,7 +1480,7 @@ public static function get_section($form, $field_id){ return null; } - public static function is_value_match( $field_value, $target_value, $operation="is", $source_field = null, $rule = null ){ + public static function is_value_match( $field_value, $target_value, $operation="is", $source_field = null, $rule = null, $form = null ) { $is_match = false; @@ -1500,7 +1508,7 @@ public static function is_value_match( $field_value, $target_value, $operation=" $is_match = true; } - return apply_filters( 'gform_is_value_match', $is_match, $field_value, $target_value, $operation, $source_field, $rule ); + return apply_filters( 'gform_is_value_match', $is_match, $field_value, $target_value, $operation, $source_field, $rule, $form ); } private static function try_convert_float($text){ @@ -1582,7 +1590,7 @@ private static function get_field_display($form, $field, $field_values, $lead=nu $source_field = RGFormsModel::get_field($form, $rule["fieldId"]); $field_value = empty($lead) ? self::get_field_value($source_field, $field_values) : self::get_lead_field_value($lead, $source_field); - $is_value_match = self::is_value_match($field_value, $rule["value"], $rule["operator"], $source_field); + $is_value_match = self::is_value_match( $field_value, $rule['value'], $rule['operator'], $source_field, $rule, $form ); if($is_value_match) $match_count++; @@ -2004,7 +2012,7 @@ public static function prepare_value($form, $field, $value, $input_name, $lead_i break; case "date" : - $value = self::prepare_date($field["dateFormat"], $value); + $value = self::prepare_date( rgar( $field, 'dateFormat' ), $value); break; @@ -2792,7 +2800,7 @@ private static function move_temp_file($form_id, $tempfile_info){ } } - private static function set_permissions($path){ + public static function set_permissions($path){ $permission = apply_filters("gform_file_permission", 0644, $path); if($permission){ @@ -4094,7 +4102,60 @@ private static function get_field_filters_where($form_id, $search_criteria) { break; case "global": - $sql_array[] = $wpdb->prepare("value $operator %s", $search_term); + // include choice text + $forms = array(); + if ( $form_id == 0 ) { + $forms = GFAPI::get_forms(); + } elseif ( is_array( $form_id ) ) { + foreach ( $form_id as $id ){ + $forms[] = GFAPI::get_form( $id ); + } + } else { + $forms[] = GFAPI::get_form( $form_id ); + } + + $choice_texts_clauses = array(); + foreach ( $forms as $form ) { + if ( isset( $form['fields'] ) ) { + $choice_texts_clauses_for_form = array(); + foreach ( $form['fields'] as $field ) { + $choice_texts_clauses_for_field = array(); + if ( isset( $field['choices'] ) && is_array( $field['choices'] ) ) { + foreach ( $field['choices'] as $choice ) { + if ( ( $operator == '=' && strtolower( $choice['text'] ) == strtolower( $val ) ) || ( $operator == 'like' && strpos( strtolower( $choice['text'] ), strtolower( $val ) ) !== false ) ) { + if ( rgar( $field, 'gsurveyLikertEnableMultipleRows' ) ){ + $choice_value = '%' . $choice['value'] . '%' ; + $choice_search_operator = 'like'; + } else { + $choice_value = $choice['value']; + $choice_search_operator = '='; + } + $choice_texts_clauses_for_field[] = $wpdb->prepare( "field_number BETWEEN %s AND %s AND value {$choice_search_operator} %s", (float) $field['id'] - 0.0001, (float) $field['id'] + 0.9999, $choice_value ); + } + } + } + if ( ! empty( $choice_texts_clauses_for_field ) ) { + $choice_texts_clauses_for_form[] = join( ' OR ', $choice_texts_clauses_for_field ); + } + } + } + if ( ! empty( $choice_texts_clauses_for_form ) ) { + $choice_texts_clauses[] = '(l.form_id = ' . $form['id'] . ' AND (' . join( ' OR ', $choice_texts_clauses_for_form ) . ' ))'; + } + } + $choice_texts_clause = ''; + if ( ! empty( $choice_texts_clauses) ){ + $choice_texts_clause = join( ' OR ', $choice_texts_clauses ); + $choice_texts_clause = " + l.id IN ( + SELECT + lead_id + FROM {$lead_details_table_name} + WHERE {$choice_texts_clause} ) OR "; + } + + $choice_value_clause = $wpdb->prepare( "value {$operator} %s", $search_term ); + $sql_array[] = '(' . $choice_texts_clause . $choice_value_clause . ')'; break; case "meta": /* doesn't support "<>" for multiple values of the same key */ diff --git a/gravityforms.php b/gravityforms.php index 421849f..e016f5f 100644 --- a/gravityforms.php +++ b/gravityforms.php @@ -3,14 +3,14 @@ Plugin Name: Gravity Forms Plugin URI: http://www.gravityforms.com Description: Easily create web forms and manage form entries within the WordPress admin. -Version: 1.8.9 +Version: 1.8.13 Author: rocketgenius Author URI: http://www.rocketgenius.com Text Domain: gravityforms Domain Path: /languages ------------------------------------------------------------------------ -Copyright 2009-2013 Rocketgenius Inc. +Copyright 2009-2014 Rocketgenius Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -76,11 +76,11 @@ if(!defined("GRAVITY_MANAGER_PROXY_URL")) define('GRAVITY_MANAGER_PROXY_URL', 'http://proxy.gravityplugins.com'); -require_once( plugin_dir_path( __FILE__ ). '/common.php'); -require_once( plugin_dir_path( __FILE__ ). '/forms_model.php'); -require_once( plugin_dir_path( __FILE__ ). '/widget.php'); -require_once( plugin_dir_path( __FILE__ ) . '/includes/api.php'); -require_once( plugin_dir_path( __FILE__ ) . '/includes/webapi/webapi.php'); +require_once( plugin_dir_path( __FILE__ ) . 'common.php' ); +require_once( plugin_dir_path( __FILE__ ) . 'forms_model.php' ); +require_once( plugin_dir_path( __FILE__ ) . 'widget.php' ); +require_once( plugin_dir_path( __FILE__ ) . 'includes/api.php' ); +require_once( plugin_dir_path( __FILE__ ) . 'includes/webapi/webapi.php' ); // GFCommon::$version is deprecated, set it to current version for backwards compat GFCommon::$version = GFForms::$version; @@ -103,9 +103,20 @@ add_action("admin_footer", array("RGForms", "no_conflict_mode_style"), 1); } +add_action( 'plugins_loaded', array( 'GFForms', 'loaded' ) ); + class GFForms { - public static $version = '1.8.9'; + public static $version = '1.8.13'; + + public static function loaded(){ + do_action( 'gform_loaded' ); + + //initializing Add-Ons if necessary + if ( class_exists( 'GFAddOn' ) ) { + GFAddOn::init_addons(); + } + } public static function has_members_plugin(){ return function_exists( 'members_get_capabilities' ); @@ -237,7 +248,7 @@ public static function init(){ } else{ - add_action('wp_enqueue_scripts', array('RGForms', 'enqueue_scripts')); + add_action('wp_enqueue_scripts', array('RGForms', 'enqueue_scripts'), 11 ); add_action('wp', array('RGForms', 'ajax_parse_request'), 10); } @@ -794,7 +805,7 @@ public static function premium_update( $premium_update ){ return $premium_update; } - private static function drop_index($table, $index){ + public static function drop_index($table, $index){ global $wpdb; $has_index = $wpdb->get_var("SHOW INDEX FROM {$table} WHERE Key_name='{$index}'"); if($has_index){ @@ -1888,7 +1899,7 @@ public static function resend_notifications(){ if(!is_array($notifications)) die(__("No notifications have been selected. Please select a notification to be sent.", "gravityforms")); - if(rgpost('sendTo') && GFCommon::is_invalid_or_empty_email(rgpost('sendTo'))) + if( ! rgempty( 'sendTo', $_POST ) && ! GFCommon::is_valid_email_list(rgpost('sendTo'))) die(__("The Send To email address provided is not valid.", "gravityforms")); foreach($leads as $lead_id){ diff --git a/images/chosen-sprite.png b/images/chosen-sprite.png index f20db44..3611ae4 100644 Binary files a/images/chosen-sprite.png and b/images/chosen-sprite.png differ diff --git a/images/chosen-sprite@2x.png b/images/chosen-sprite@2x.png new file mode 100644 index 0000000..ffe4d7d Binary files /dev/null and b/images/chosen-sprite@2x.png differ diff --git a/includes/addon/class-gf-addon.php b/includes/addon/class-gf-addon.php index 404d4b9..89ecba5 100644 --- a/includes/addon/class-gf-addon.php +++ b/includes/addon/class-gf-addon.php @@ -4,6 +4,7 @@ die(); } + /** * Handles all tasks mostly common to any Gravity Forms Add-On, including third party ones * @@ -102,6 +103,7 @@ abstract class GFAddOn { private $_no_conflict_styles = array(); private $_preview_styles = array(); private $_print_styles = array(); + private static $_registered_addons = array( 'active' => array(), 'inactive' => array() ); /** * Class constructor which hooks the instance into the WordPress init action @@ -118,7 +120,51 @@ function __construct() { $this->pre_init(); } - /** + /** + * Registers an addon so that it gets initialized appropriately + * + * @param string $class - The class name + * @param string $overrides - Specify the class to replace/override + */ + public static function register( $class, $overrides = null ){ + + //Ignore classes that have been marked as inactive + if ( in_array( $class, self::$_registered_addons['inactive'] ) ) { + return; + } + + //Mark classes as active. Override existing active classes if they are supposed to be overridden + $index = array_search( $overrides, self::$_registered_addons['active'] ); + if ( $index !== false ){ + self::$_registered_addons['active'][ $index ] = $class; + } else { + self::$_registered_addons['active'][] = $class; + } + + //Mark overridden classes as inactive. + if ( ! empty( $overrides ) ){ + self::$_registered_addons['inactive'][] = $overrides; + } + + + } + + /** + * Target of gform_init Gravity Forms hook. Initializes all addons. + */ + public static function init_addons(){ + + //Removing duplicate add-ons + $active_addons = array_unique(self::$_registered_addons['active']); + + foreach ( $active_addons as $addon ){ + + call_user_func( array( $addon, 'get_instance' ) ); + + } + } + + /** * Gets executed before all init functions. Override this function to perform initialization tasks that must be done prior to init */ public function pre_init(){ @@ -1038,21 +1084,24 @@ protected function get_setting( $setting_name, $default_value = "" , $settings = if( ! $settings ) $settings = $this->get_current_settings(); - if (false === $settings) + if (false === $settings) { return $default_value; + } if (strpos($setting_name, "[") !== false) { $path_parts = explode("[", $setting_name); foreach ($path_parts as $part) { $part = trim($part, "]"); - if (false === isset($settings[$part])) + if (false === isset($settings[$part])) { return $default_value; + } $settings = rgar($settings, $part); } $setting = $settings; } else { - if (false === isset($settings[$setting_name])) + if (false === isset($settings[$setting_name])) { return $default_value; + } $setting = $settings[$setting_name]; } @@ -1320,54 +1369,96 @@ protected function settings_hidden($field, $echo = true) { return $html; } - /*** - * Renders and initializes a checkbox field or a collection of checkbox fields based on the $field array - * - * @param array $field - Field array containing the configuration options of this field - * @param bool $echo = true - true to echo the output to the screen, false to simply return the contents as a string - * @return string The HTML for the field - */ - protected function settings_checkbox( $field, $echo = true ) { - - $field["type"] = "checkbox"; //making sure type is set to checkbox - - $default_attributes = array("onclick" => 'jQuery(this).siblings("input[type=hidden]").val(jQuery(this).prop("checked") ? 1 : 0);'); - $field_attributes = $this->get_field_attributes($field, $default_attributes); - $horizontal = rgar($field, "horizontal") ? " gaddon-setting-inline" : ""; - - $html = ""; - - if(is_array($field["choices"])){ - foreach( $field["choices"] as $choice ) { - $choice['id'] = $choice['name']; - $choice_attributes = $this->get_choice_attributes($choice, $field_attributes); - $value = $this->get_setting($choice['name'], rgar($choice, "default_value")); - $tooltip = isset( $choice['tooltip'] ) ? gform_tooltip( $choice['tooltip'], rgar( $choice, 'tooltip_class'), true ) : ""; - $hidden_field_value = $value == '1' ? '1' : '0'; - $html .= ' -
- - - -
- '; - } - } - - if( $this->field_failed_validation( $field ) ) - $html .= $this->get_error_icon( $field ); - - if ($echo) - echo $html; - - return $html; - } - - /*** + /*** + * Renders and initializes a checkbox field or a collection of checkbox fields based on the $field array + * + * @param array $field - Field array containing the configuration options of this field + * @param bool $echo = true - true to echo the output to the screen, false to simply return the contents as a string + * + * @return string The HTML for the field + */ + protected function settings_checkbox( $field, $echo = true ) { + + $field['type'] = 'checkbox'; //making sure type is set to checkbox + + $default_attributes = array( 'onclick' => 'jQuery(this).siblings("input[type=hidden]").val(jQuery(this).prop("checked") ? 1 : 0);' ); + $field_attributes = $this->get_field_attributes( $field, $default_attributes ); + $horizontal = rgar( $field, 'horizontal' ) ? ' gaddon-setting-inline' : ''; + + $html = ''; + + if ( is_array( $field['choices'] ) ) { + foreach ( $field['choices'] as $choice ) { + $choice['id'] = sanitize_title($choice['name']); + $choice_attributes = $this->get_choice_attributes( $choice, $field_attributes ); + $value = $this->get_setting( $choice['name'], rgar( $choice, 'default_value' ) ); + $tooltip = isset( $choice['tooltip'] ) ? gform_tooltip( $choice['tooltip'], rgar( $choice, 'tooltip_class' ), true ) : ''; + + $html .= $this->checkbox_item( $choice, $horizontal, $choice_attributes, $value, $tooltip ); + + } + } + + if ( $this->field_failed_validation( $field ) ) + $html .= $this->get_error_icon( $field ); + + if ( $echo ) + echo $html; + + return $html; + } + + + /** + * Returns the markup for an individual checkbox item give the parameters + * + * @param $choice - Choice array with all configured properties + * @param $horizontal_class - CSS class to style checkbox items horizontally + * @param $attributes - String containing all the attributes for the input tag. + * @param $value - Currently selection (1 if field has been checked. 0 or null otherwise) + * @param $tooltip - String containing a tooltip for this checkbox item. + * + * @return string - The markup of an individual checkbox item + */ + protected function checkbox_item( $choice, $horizontal_class, $attributes, $value, $tooltip ) { + $hidden_field_value = $value == '1' ? '1' : '0'; + $checkbox_item = ' +
+ '; + + if ( is_callable( array( $this, "checkbox_input_{$choice['name']}" ) ) ) { + $markup = call_user_func( array( $this, "checkbox_input_{$choice['name']}" ), $choice, $attributes, $value, $tooltip ); + } else { + $markup = $this->checkbox_input( $choice, $attributes, $value, $tooltip ); + } + + $checkbox_item .= $markup . '
'; + + return $checkbox_item; + } + + /** + * Returns the markup for an individual checkbox input and its associated label + * + * @param $choice - Choice array with all configured properties + * @param $attributes - String containing all the attributes for the input tag. + * @param $value - Currently selection (1 if field has been checked. 0 or null otherwise) + * @param $tooltip - String containing a tooltip for this checkbox item. + * + * @return string - The markup of an individual checkbox input and its associated label + */ + protected function checkbox_input( $choice, $attributes, $value, $tooltip ) { + $markup = ' + '; + + return $markup; + } + + + /*** * Renders and initializes a radio field or a collection of radio fields based on the $field array * * @param array $field - Field array containing the configuration options of this field @@ -1483,8 +1574,9 @@ public function settings_field_map( $field, $echo = true ) { $html = ''; $field_map = rgar( $field, 'field_map' ); - if( empty( $field_map ) ) + if( empty( $field_map ) ) { return $html; + } $form_id = rgget( 'id' ); @@ -1591,7 +1683,7 @@ public function get_mapped_field_name( $parent_field, $field_name ) { public static function get_field_map_fields( $feed, $field_name ) { $fields = array(); - $prefix = "field_map_{$field_name}_"; + $prefix = "{$field_name}_"; foreach( $feed['meta'] as $name => $value ) { if( strpos( $name, $prefix ) === 0 ) { @@ -1782,14 +1874,13 @@ protected function settings_save( $field, $echo = true ) { protected function simple_condition($setting_name_root){ $conditional_fields = $this->get_conditional_logic_fields(); - $create_condition_value_script = ""; $str = $this->settings_select(array( "name" => "{$setting_name_root}_field_id", "type" => "select", "choices" => $conditional_fields, "class" => "optin_select", - "onchange" => "jQuery('#" . esc_attr($setting_name_root) . "_container').html(GetRuleValues('gf_setting', 0, jQuery(this).val(), '', '_gaddon_setting_" . esc_attr($setting_name_root) . "_value'));" + "onchange" => "jQuery('#" . esc_attr($setting_name_root) . "_container').html(GetRuleValues('simple_condition_{$setting_name_root}', 0, jQuery(this).val(), '', '_gaddon_setting_" . esc_attr($setting_name_root) . "_value'));" ), false); $str .= $this->settings_select(array( @@ -1831,10 +1922,25 @@ protected function simple_condition($setting_name_root){ $field_id = $this->get_setting("{$setting_name_root}_field_id"); - if(!empty($field_id)){ - $current_condition_value = $this->get_setting("{$setting_name_root}_value"); - $str .= ""; - } + $value = $this->get_setting("{$setting_name_root}_value"); + $operator = $this->get_setting("{$setting_name_root}_operator"); + + $str .= ""; return $str; } @@ -1849,7 +1955,7 @@ protected function get_field_attributes($field, $default = array()){ // each nonstandard property will be extracted from the $props array so it is not auto-output in the field HTML $no_output_props = apply_filters( 'gaddon_no_output_field_properties', array( 'default_value', 'label', 'choices', 'feedback_callback', 'checked', 'checkbox_label', 'value', 'type', - 'validation_callback', 'required', 'hidden', 'tooltip', 'dependency', "messages" ), $field ); + 'validation_callback', 'required', 'hidden', 'tooltip', 'dependency', 'messages', 'name' ), $field ); $default_props = array( 'class' => '', // will default to gaddon-setting @@ -2667,11 +2773,11 @@ protected function form_settings_fields($form){ protected function plugin_settings_init() { $subview = rgget("subview"); RGForms::add_settings_page( array( - 'name' => $this->get_short_title(), + 'name' => $this->_slug, 'tab_label' => $this->get_short_title(), 'handler' => array($this, 'plugin_settings_page') ) ); - if (rgget("page") == "gf_settings" && $subview == $this->get_short_title() && $this->current_user_can_any($this->_capabilities_settings_page)) { + if (rgget("page") == "gf_settings" && $subview == $this->_slug && $this->current_user_can_any($this->_capabilities_settings_page)) { require_once(GFCommon::get_base_path() . "/tooltips.php"); } diff --git a/includes/addon/class-gf-feed-addon.php b/includes/addon/class-gf-feed-addon.php index c1ebbf9..ea7c506 100644 --- a/includes/addon/class-gf-feed-addon.php +++ b/includes/addon/class-gf-feed-addon.php @@ -30,6 +30,14 @@ public function init_frontend() { } + public function init_ajax() { + + parent::init_ajax(); + + add_action( "wp_ajax_gf_feed_is_active_{$this->_slug}", array( $this, 'ajax_toggle_is_active' ) ); + + } + protected function setup(){ parent::setup(); @@ -112,35 +120,41 @@ protected function uninstall(){ public function maybe_process_feed( $entry, $form, $is_delayed = false ) { - $paypal_feed = $this->get_paypal_feed( $form['id'], $entry ); - $has_payment = self::get_paypal_payment_amount($form, $entry, $paypal_feed) > 0; + //Getting all active feeds for current addon + $feeds = $this->get_feeds( $form['id'] ); + + //Aborting if delayed payment is configured + if ( ! empty( $feeds ) ) { + $is_delayed_payment_configured = $this->is_delayed_payment( $entry, $form, $is_delayed ); - if( $paypal_feed && rgar( $paypal_feed['meta'], "delay_{$this->_slug}" ) && $has_payment && !$is_delayed ) { - self::log_debug( "Feed processing delayed pending PayPal payment received for entry {$entry['id']}" ); - return $entry; - } + if ( $is_delayed_payment_configured ) { + $this->log_debug( "Feed processing delayed pending PayPal payment received for entry {$entry['id']}" ); - // getting all active feeds - $feeds = $this->get_feeds( $form['id'] ); + return $entry; + } + } + //Processing feeds $processed_feeds = array(); foreach ( $feeds as $feed ) { - if ( $this->is_feed_condition_met( $feed, $form, $entry ) ) { + if ( $feed['is_active'] && $this->is_feed_condition_met( $feed, $form, $entry ) ) { $this->process_feed( $feed, $entry, $form ); - $processed_feeds[] = $feed["id"]; + $processed_feeds[] = $feed['id']; } else { - $this->log_debug( "Opt-in condition not met; not fulfilling entry {$entry["id"]} to list" ); + $this->log_debug( 'Opt-in condition not met or feed is inactive, not processing feed for entry #' . $entry['id'] . ". Feed Status: " . $feed['is_active'] ); } } - if(!empty($processed_feeds)){ - $meta = gform_get_meta($entry["id"], "processed_feeds"); - if(empty($meta)) + //Saving processed feeds + if( ! empty( $processed_feeds ) ){ + $meta = gform_get_meta( $entry['id'], 'processed_feeds' ); + if( empty($meta) ) { $meta = array(); + } $meta[$this->_slug] = $processed_feeds; - gform_update_meta( $entry["id"], "processed_feeds", $meta ); + gform_update_meta( $entry['id'], 'processed_feeds', $meta ); } return $entry; @@ -282,10 +296,6 @@ public function delete_feeds($form_id = null){ public function form_settings_init(){ parent::form_settings_init(); - - if (RG_CURRENT_PAGE == "admin-ajax.php") { - add_action("wp_ajax_gf_feed_is_active_{$this->_slug}", array($this, 'ajax_toggle_is_active')); - } } public function ajax_toggle_is_active(){ @@ -814,6 +824,21 @@ protected function has_feed( $form_id, $meets_conditional_logic = null ) { //does not require that feed meets conditional logic. return true since there are feeds return true; } + + protected function is_delayed_payment( $entry, $form, $is_delayed ) { + if ( $this->_slug == 'gravityformspaypal' ) { + return false; + } + + $paypal_feed = $this->get_paypal_feed( $form['id'], $entry ); + if ( ! $paypal_feed ) { + return false; + } + + $has_payment = self::get_paypal_payment_amount( $form, $entry, $paypal_feed ) > 0; + + return rgar( $paypal_feed['meta'], "delay_{$this->_slug}" ) && $has_payment && ! $is_delayed; + } } diff --git a/includes/addon/class-gf-payment-addon.php b/includes/addon/class-gf-payment-addon.php index ab4bd90..d009923 100644 --- a/includes/addon/class-gf-payment-addon.php +++ b/includes/addon/class-gf-payment-addon.php @@ -15,7 +15,7 @@ require_once('class-gf-feed-addon.php' ); abstract class GFPaymentAddOn extends GFFeedAddOn { - private $_payment_version = "1.1"; + private $_payment_version = "1.2"; /** @@ -31,9 +31,14 @@ abstract class GFPaymentAddOn extends GFFeedAddOn { protected $_supports_callbacks = false; protected $authorization = array(); + protected $redirect_url = ''; + protected $current_feed = false; + protected $current_submission_data = false; + protected $is_payment_gateway = false; - //--------- Initialization ---------- + + //--------- Initialization ---------- public function pre_init(){ parent::pre_init(); @@ -61,16 +66,18 @@ public function init_admin() { } } - public function init_frontend(){ + public function init_frontend() { parent::init_frontend(); - add_filter("gform_confirmation", array($this, "confirmation"), 20, 4); + add_filter( "gform_confirmation", array( $this, "confirmation" ), 20, 4 ); + + add_filter( "gform_validation", array( $this, "validation" ), 20 ); + add_filter( "gform_entry_post_save", array( $this, "entry_post_save" ), 10, 2 ); - add_filter("gform_validation", array($this, "validation")); - add_filter("gform_entry_post_save", array($this, "entry_post_save"), 10, 2); } + public function init_ajax(){ parent::init_ajax(); @@ -119,7 +126,7 @@ private function upgrade_payment($previous_versions) { date_created datetime, PRIMARY KEY (id), KEY lead_id (lead_id), - KEY trasanction_type (transaction_type), + KEY transaction_type (transaction_type), KEY type_lead (lead_id,transaction_type) ) $charset_collate;"; @@ -134,10 +141,14 @@ private function upgrade_payment($previous_versions) { callback_id varchar(250), date_created datetime, PRIMARY KEY (id), - KEY slug_callback_id (addon_slug,callback_id) + KEY addon_slug_callback_id (addon_slug(50),callback_id(100)) ) $charset_collate;"; GFFormsModel::dbDelta($sql); + + //droping legacy index + GFForms::drop_index( "{$wpdb->prefix}gf_addon_payment_callback", 'slug_callback_id' ); + } @@ -146,25 +157,15 @@ private function upgrade_payment($previous_versions) { //--------- Submission Process ------ public function confirmation($confirmation, $form, $entry, $ajax){ - if(!$this->payment_method_is_overridden('redirect_url')) - return $confirmation; - - $feed = $this->get_payment_feed($entry, $form); - - if(!$feed){ - $this->log_debug("No payment feed was located for form_id = " . $form["id"] . " - NOT sending to " . $this->_slug); - return $confirmation; + if ( empty( $this->redirect_url ) ) { + return $confirmation; } - $submission_data = $this->get_submission_data($feed, $form, $entry); + $confirmation = array( 'redirect' => $this->redirect_url ); - $url = $this->redirect_url($feed, $submission_data, $form, $entry); + return $confirmation; - if($url) - $confirmation = array("redirect" => $url); - - return $confirmation; - } + } /** * Override this function to specify a URL to the third party payment processor. Useful when developing a payment gateway that processes the payment outsite of the website (i.e. PayPal Standard). @@ -180,57 +181,63 @@ protected function redirect_url($feed, $submission_data, $form, $entry){ public function validation( $validation_result ) { - if( ! GFFormDisplay::is_last_page( $validation_result['form'] ) ) - return $validation_result; + if ( ! $validation_result['is_valid'] || ! GFFormDisplay::is_last_page( $validation_result['form'] ) ) { + return $validation_result; + } - $has_authorize = $this->payment_method_is_overridden('authorize'); - $has_subscribe = $this->payment_method_is_overridden('subscribe'); - if(!$has_authorize && !$has_subscribe) - return $validation_result; + $form = $validation_result['form']; + $entry = GFFormsModel::create_lead( $form ); + $feed = $this->get_payment_feed( $entry, $form ); - //Getting submission data - $form = $validation_result["form"]; - $entry = GFFormsModel::create_lead($form); - $feed = $this->get_payment_feed($entry, $form); + if ( ! $feed ) { + return $validation_result; + } - if(!$feed) - return $validation_result; + $submission_data = $this->get_submission_data( $feed, $form, $entry ); - $do_authorization = $has_authorize && $feed["meta"]["transactionType"] == "product"; - $do_subscription = $has_subscribe && $feed["meta"]["transactionType"] == "subscription"; + //Do not process payment if payment amount is 0 or less + if ( floatval( $submission_data['payment_amount'] ) <= 0 ) { - if(!$do_authorization && !$do_subscription) - return $validation_result; + $this->log_debug( 'Payment amount is $0.00 or less. Not sending to payment gateway.' ); - $submission_data = $this->get_submission_data($feed, $form, $entry); + return $validation_result; + } - //Running an authorization only transaction if function is implemented and this is a single payment - if($do_authorization){ - $this->authorization = $this->authorize($feed, $submission_data, $form, $entry); - } - else if($do_subscription){ + $this->is_payment_gateway = true; + $this->current_feed = $feed; + $this->current_submission_data = $submission_data; - $subscription = $this->subscribe( $feed, $submission_data, $form, $entry ); + $performed_authorization = false; + $is_subscription = $feed["meta"]["transactionType"] == "subscription"; - $this->authorization["is_authorized"] = $subscription["is_success"]; - $this->authorization["error_message"] = rgar($subscription, "error_message"); - $this->authorization["subscription"] = $subscription; + if ( $this->payment_method_is_overridden( 'authorize' ) && ! $is_subscription ) { - } + //Running an authorization only transaction if function is implemented and this is a single payment + $this->authorization = $this->authorize( $feed, $submission_data, $form, $entry ); + $performed_authorization = true; - $this->authorization["feed"] = $feed; - $this->authorization["submission_data"] = $submission_data; + } else if ( $this->payment_method_is_overridden( 'subscribe' ) && $is_subscription ) { - if(!$this->authorization["is_authorized"]){ - $validation_result = $this->get_validation_result($validation_result, $this->authorization); + $subscription = $this->subscribe( $feed, $submission_data, $form, $entry ); - //Setting up current page to point to the credit card page since that will be the highlighted field - GFFormDisplay::set_current_page($validation_result["form"]["id"], $validation_result["credit_card_page"]); - } + $this->authorization['is_authorized'] = $subscription['is_success']; + $this->authorization['error_message'] = rgar( $subscription, 'error_message' ); + $this->authorization['subscription'] = $subscription; - return $validation_result; - } + $performed_authorization = true; + } + + if ( $performed_authorization && ! $this->authorization['is_authorized'] ) { + $validation_result = $this->get_validation_result( $validation_result, $this->authorization ); + + //Setting up current page to point to the credit card page since that will be the highlighted field + GFFormDisplay::set_current_page( $validation_result['form']['id'], $validation_result['credit_card_page'] ); + } + + return $validation_result; + + } /** * Override this method to add integration code to the payment processor in order to authorize a credit card with or without capturing payment. This method is executed during the form validation process and allows @@ -332,62 +339,68 @@ protected function get_validation_result($validation_result, $authorization_resu public function entry_post_save($entry, $form){ - //Abort if authorization wasn't done. - if(empty($this->authorization)) - return $entry; + if ( ! $this->is_payment_gateway ){ + return $entry; + } - $feed = $this->authorization["feed"]; + $feed = $this->current_feed; - if($feed["meta"]["transactionType"] == "product"){ + if ( ! empty( $this->authorization ) ) { + //If an authorization was done, capture it - if($this->payment_method_is_overridden('capture') && rgempty("captured_payment", $this->authorization)){ - $capture_response = $this->capture($this->authorization, $feed, $this->authorization["submission_data"], $form, $entry); - $this->authorization["captured_payment"] = $capture_response; - } + if ( $feed['meta']['transactionType'] == 'subscription' ) { - $entry = $this->process_capture($this->authorization, $feed, $this->authorization["submission_data"], $form, $entry); + $entry = $this->process_subscription( $this->authorization, $feed, $this->current_submission_data, $form, $entry ); - } - else if($feed["meta"]["transactionType"] == "subscription"){ + } else { - $entry = $this->process_subscription($this->authorization, $feed, $this->authorization["submission_data"], $form, $entry); + if ( $this->payment_method_is_overridden( 'capture' ) && rgempty( 'captured_payment', $this->authorization ) ) { - } + $this->authorization['captured_payment'] = $this->capture( $this->authorization, $feed, $this->current_submission_data, $form, $entry ); - gform_update_meta($entry["id"], "payment_gateway", $this->_slug); + } - return $entry; - } + $entry = $this->process_capture( $this->authorization, $feed, $this->current_submission_data, $form, $entry ); + } + } + else if ( $this->payment_method_is_overridden( 'redirect_url' ) ){ - protected function process_capture($authorization, $feed, $submission_data, $form, $entry){ + //If the url_redirect() function is overridden, call it. - $payment = rgar($authorization,"captured_payment"); - if(empty($payment)) - return $entry; + //Getting URL to redirect to ( saved to be used by the confirmation() function ) + $this->redirect_url = $this->redirect_url( $feed, $this->current_submission_data, $form, $entry ); + + //Setting transaction_type to subscription or one time payment + $entry['transaction_type'] = rgars( $feed, 'meta/transactionType' ) == 'subscription' ? 2 : 1; - if($payment["is_success"]){ + } + + //Saving which gateway was used to process this entry + gform_update_meta( $entry['id'], 'payment_gateway', $this->_slug ); - $entry["transaction_id"] = $payment["transaction_id"]; - $entry["transaction_type"] = "1"; - $entry["is_fulfilled"] = true; - $entry["currency"] = GFCommon::get_currency(); - $entry["payment_amount"] = $payment["amount"]; - $entry["payment_status"] = "Paid"; - $entry["payment_date"] = gmdate("Y-m-d H:i:s"); - $entry["payment_method"] = $payment["payment_method"]; + return $entry; - $this->insert_transaction($entry["id"], "payment", $entry["transaction_id"], $entry["payment_amount"]); + } + + protected function process_capture($authorization, $feed, $submission_data, $form, $entry){ + $payment = rgar( $authorization, 'captured_payment' ); + if( empty( $payment ) ) { + return $entry; + } - $this->add_note($entry["id"], sprintf(__("Payment has been captured successfully. Amount: %s. Transaction Id: %s", "gravityforms"), GFCommon::to_money($payment["amount"], $entry["currency"]),$payment["transaction_id"]), "success"); + if( $payment['is_success'] ){ + $entry['is_fulfilled'] = '1'; + $payment["payment_status"] = "Paid"; + $payment["payment_date"] = gmdate("Y-m-d H:i:s"); + $this->complete_payment( $entry, $payment ); } - else{ + else { $entry["payment_status"] = "Failed"; $this->add_note($entry["id"], sprintf( __("Payment failed to be captured. Reason: %s", "gravityforms") , $payment["error_message"] ), "error"); + GFAPI::update_entry($entry); } - GFAPI::update_entry($entry); - return $entry; } @@ -467,7 +480,7 @@ public function get_payment_feed( $entry, $form = false ) { $feeds = $this->get_feeds( $form['id'] ); foreach ( $feeds as $feed ) { - if ( $this->is_feed_condition_met( $feed, $form, $entry ) ){ + if ( $feed['is_active'] && $this->is_feed_condition_met( $feed, $form, $entry ) ){ $submission_feed = $feed; break; } @@ -477,9 +490,25 @@ public function get_payment_feed( $entry, $form = false ) { return $submission_feed; } - protected function is_payment_gateway($entry_id){ - $feeds = $this->get_feeds_by_entry($entry_id); - return is_array($feeds) && count($feeds) > 0; + /** + * Returns true if the current Add-On was the one used as the payment gateway for the specified entry. + * + * NOTE: For plugins overriding the redirect_url() function, there could be inconsistencies when using this function during the submission process + * + * @param $entry_id + * + * @return bool Returns true if the current Add-On was the one used as the payment gateway for the specified entry. + * + */ + protected function is_payment_gateway($entry_id){ + + if ( $this->is_payment_gateway ){ + return true; + } + + $gateway = gform_get_meta($entry_id, 'payment_gateway'); + + return $gateway == $this->_slug; } protected function get_submission_data($feed, $form, $entry){ @@ -544,35 +573,49 @@ protected function get_order_data($feed, $form, $entry){ $options = array(); if(is_array(rgar($product, "options"))){ foreach($product["options"] as $option){ - $options[] = $option["option_name"]; - $product_price += $option["price"]; + if ( isset( $option['option_name'] ) ){ + $options[] = $option["option_name"]; + $product_price += $option["price"]; + } } } - if(!empty($trial_field) && $trial_field == $field_id){ - $trial_amount = $product_price * $quantity; - } - else if(!empty($setup_fee_field) && $setup_fee_field == $field_id){ - $fee_amount = $product_price * $quantity; - } - else - { - if(is_numeric($payment_field) && $payment_field != $field_id) - continue; + $is_trial_or_setup_fee = false; - $amount += $product_price * $quantity; + if ( ! empty( $trial_field ) && $trial_field == $field_id ) { - $description = ""; - if(!empty($options)) - $description = __("options: ", "gravityforms") . " " . implode(", ", $options); + $trial_amount = $product_price * $quantity; + $is_trial_or_setup_fee = true; + + } else if ( ! empty( $setup_fee_field ) && $setup_fee_field == $field_id ) { + + $fee_amount = $product_price * $quantity; + $is_trial_or_setup_fee = true; + } + + //Do not add to line items if the payment field selected in the feed is not the current field. + if ( is_numeric( $payment_field ) && $payment_field != $field_id ) { + continue; + } + + //Do not add to line items if the payment field is set to "Form Total" and the current field was used for trial or setup fee. + if ( $is_trial_or_setup_fee && ! is_numeric( $payment_field ) ){ + continue; + } + + $amount += $product_price * $quantity; + + $description = ""; + if(!empty($options)) + $description = __("options: ", "gravityforms") . " " . implode(", ", $options); + + if($product_price >= 0){ + $line_items[] = array("id" => $field_id, "name"=>$product["name"], "description" =>$description, "quantity" =>$quantity, "unit_price"=>GFCommon::to_number($product_price), "options" => rgar($product, "options")); + } + else{ + $discounts[] = array("id" => $field_id, "name"=>$product["name"], "description" =>$description, "quantity" =>$quantity, "unit_price"=>GFCommon::to_number($product_price), "options" => rgar($product, "options")); + } - if($product_price >= 0){ - $line_items[] = array("id" => $field_id, "name"=>$product["name"], "description" =>$description, "quantity" =>$quantity, "unit_price"=>GFCommon::to_number($product_price), "options" => rgar($product, "options")); - } - else{ - $discounts[] = array("id" => $field_id, "name"=>$product["name"], "description" =>$description, "quantity" =>$quantity, "unit_price"=>GFCommon::to_number($product_price), "options" => rgar($product, "options")); - } - } } if ($trial_field == "enter_amount"){ @@ -608,34 +651,50 @@ public function maybe_process_callback() { // to generically process the callback data $this->log_debug("Initializing callback processing for: " . $this->_slug); - $result = $this->callback(); + $callback_action = $this->callback(); - $this->log_debug("Result from gateway callback: " . print_r($result, true)); + $this->log_debug("Result from gateway callback: " . print_r($callback_action, true)); - if( is_array( $result ) && rgar( $result, 'type' ) ) { - $result = $this->process_callback_action( $result ); + $result = false; + if(is_wp_error( $callback_action )) { + $this->display_callback_error($callback_action); } + else if($callback_action && is_array( $callback_action ) && rgar( $callback_action, 'type' ) && ! rgar($callback_action, 'abort_callback') ) { - if(is_wp_error( $result )) { - $data = $result->get_error_data(); - $status = !rgempty("status_header", $data) ? $data["status_header"] : 200; + $result = $this->process_callback_action( $callback_action ); - status_header( $status ); - echo $result->get_error_message(); + if(is_wp_error( $result )) { + $this->display_callback_error($result); } else if( !$result ){ status_header( 200 ); - echo "Callback bypassed"; + echo "Callback could not be processed."; } else { status_header( 200 ); echo 'Callback processed successfully.'; } + } + else{ + status_header( 200 ); + echo "Callback bypassed"; + } + + $this->post_callback($callback_action, $result); die(); } + private function display_callback_error($error){ + + $data = $error->get_error_data(); + $status = !rgempty("status_header", $data) ? $data["status_header"] : 200; + + status_header( $status ); + echo $error->get_error_message(); + } + /** * Processes callback based on provided data. * @@ -686,25 +745,25 @@ private function process_callback_action( $action ) { case 'refund_payment': $result = $this->refund_payment( $entry, $action ); break; - case 'fail_payment': - $result = $this->fail_payment( $entry, $action ); - break; - case 'add_pending_payment': - $result = $this->add_pending_payment( $entry, $action ); - break; - case 'void_authorization': - $result = $this->void_authorization( $entry, $action ); - break; - case 'create_subscription': - $result = $this->start_subscription($entry, $action); - break; + case 'fail_payment': + $result = $this->fail_payment( $entry, $action ); + break; + case 'add_pending_payment': + $result = $this->add_pending_payment( $entry, $action ); + break; + case 'void_authorization': + $result = $this->void_authorization( $entry, $action ); + break; + case 'create_subscription': + $result = $this->start_subscription($entry, $action); + break; case 'cancel_subscription': $feed = $this->get_payment_feed( $entry ); $result = $this->cancel_subscription( $entry, $feed, $action["note"] ); break; - case 'expire_subscription': - $result = $this->expire_subscription( $entry, $action ); - break; + case 'expire_subscription': + $result = $this->expire_subscription( $entry, $action ); + break; case 'add_subscription_payment': $result = $this->add_subscription_payment( $entry, $action ); break; @@ -719,7 +778,7 @@ private function process_callback_action( $action ) { break; } - $this->log_debug("Callback action successful? {$result}"); + $this->log_debug( 'Callback action successful? ' . print_r( $result, true ) ); if(rgar($action, "id") && $result){ $this->register_callback($action["id"], $action['entry_id']); @@ -748,6 +807,8 @@ protected function is_duplicate_callback($callback_id){ protected function callback() { } + protected function post_callback($callback_action, $result) {} + // # PAYMENT INTERACTION FUNCTIONS @@ -769,20 +830,40 @@ public function add_pending_payment( $entry, $action ){ public function complete_payment( $entry, $action ) { - if( ! $action['payment_status'] ) + if ( ! rgar($action, 'payment_status') ) { $action['payment_status'] = 'Paid'; + } - if( ! $action['transaction_type'] ) + if ( ! rgar($action, 'transaction_type') ) { $action['transaction_type'] = 'payment'; + } - if( ! $action['note'] ) { + if ( ! rgar( $action, 'payment_date' ) ) { + $action['payment_date'] = gmdate( 'y-m-d H:i:s' ); + } + + //set is_fulfilled in process_capture by gateways that are not url redirects + //url redirects should not have this set yet, happens in post_callback for them + $entry['is_fulfilled'] = "1"; + $entry['transaction_id'] = rgar ( $action, 'transaction_id' ); + $entry['transaction_type'] = "1"; + $entry['payment_status'] = $action['payment_status']; + $entry['payment_amount'] = rgar( $action, 'amount' ); + $entry['payment_date'] = $action['payment_date']; + $entry['payment_method'] = rgar( $action, 'payment_method' ); + $entry['currency'] = GFCommon::get_currency(); + + if ( ! rgar($action, 'note') ) { $amount_formatted = GFCommon::to_money( $action['amount'], $entry['currency'] ); $action['note'] = sprintf( __( 'Payment has been completed. Amount: %s. Transaction Id: %s.', 'gravityforms' ), $amount_formatted, $action['transaction_id'] ); } + - GFAPI::update_entry_property( $entry['id'], 'payment_status', $action['payment_status'] ); - $this->insert_transaction( $entry['id'], $action['transaction_type'], $action['transaction_id'], $action['amount'] ); - $this->add_note( $entry['id'], $action['note'], "success" ); + GFAPI::update_entry( $entry ); + + $this->insert_transaction( $entry['id'], $action['transaction_type'], $action['transaction_id'], $action['amount'] ); + + $this->add_note( $entry['id'], $action['note'], "success" ); do_action("gform_post_payment_completed", $entry, $action); @@ -854,18 +935,18 @@ public function void_authorization( $entry, $action ){ public function start_subscription( $entry, $subscription ) { if (!$this->has_subscription($entry)){ - $entry['payment_status'] = 'Active'; - $entry['payment_amount'] = $subscription['amount']; - $entry['payment_date'] = gmdate( 'y-m-d H:i:s' ); - $entry['transaction_id'] = $subscription['subscription_id']; - $entry['transaction_type'] = '2'; // subscription - $entry['is_fulfilled'] = true; - - $result = GFAPI::update_entry( $entry ); - - $this->add_note( $entry['id'], sprintf( __( 'Subscription has been created. Subscription Id: %s.', 'gravityforms' ), $subscription['subscription_id'] ), "success" ); - - do_action("gform_post_subscription_started", $entry, $subscription); + $entry['payment_status'] = 'Active'; + $entry['payment_amount'] = $subscription['amount']; + $entry['payment_date'] = gmdate( 'y-m-d H:i:s' ); + $entry['transaction_id'] = $subscription['subscription_id']; + $entry['transaction_type'] = '2'; // subscription + $entry['is_fulfilled'] = '1'; + + $result = GFAPI::update_entry( $entry ); + + $this->add_note( $entry['id'], sprintf( __( 'Subscription has been created. Subscription Id: %s.', 'gravityforms' ), $subscription['subscription_id'] ), "success" ); + + do_action("gform_post_subscription_started", $entry, $subscription); } return $entry; @@ -879,13 +960,7 @@ public function start_subscription( $entry, $subscription ) { * @return [null] */ public function add_subscription_payment( $entry, $action ) { - //see if a subscription has been created first, if not, create it - if (!$this->has_subscription($entry)){ - $this->start_subscription($entry, $action); - } - else{ - GFAPI::update_entry_property( $entry['id'], 'payment_amount', $action['amount'] ); - } + if( ! $action['transaction_type'] ) $action['transaction_type'] = 'payment'; @@ -932,7 +1007,6 @@ public function cancel_subscription( $entry, $feed, $note = null ) { } GFAPI::update_entry_property( $entry['id'], 'payment_status', "Cancelled" ); - $this->modify_post( rgar( $entry, 'post_id' ), rgars( $feed, 'meta/update_post_action' ) ); $this->add_note( $entry['id'], $note ); // include $subscriber_id as 3rd parameter for backwards compatibility @@ -1063,7 +1137,8 @@ public function feed_settings_fields() { "label" => __("Name", "gravityforms"), "type" => "text", "class" => "medium", - "required" => true + "required" => true, + "tooltip" => "
" . __("Name", "gravityforms") . "
" . __("Enter a feed name to uniquely identify this setup.", "gravityforms") ), array( "name"=> "transactionType", @@ -1074,7 +1149,8 @@ public function feed_settings_fields() { array("label" => __("Select a transaction type", "gravityforms"), "value" => ""), array("label" => __("Products and Services", "gravityforms"), "value" => "product"), array("label" => __("Subscription", "gravityforms"), "value" => "subscription") - ) + ), + "tooltip" => "
" . __("Transaction Type", "gravityforms") . "
" . __("Select a transaction type") ) ) ), @@ -1091,18 +1167,21 @@ public function feed_settings_fields() { "label" => __("Recurring Amount", "gravityforms"), "type" => "select", "choices" => $this->recurring_amount_choices(), - "required" => true + "required" => true, + "tooltip" => "
" . __("Recurring Amount", "gravityforms") . "
" . __("Select which field determines the recurring payment amount, or select 'Form Total' to use the total of all pricing fields as the recurring amount.", "gravityforms") ), array( "name" => "billingCycle", "label" => __("Billing Cycle", "gravityforms"), "type" => "billing_cycle", + "tooltip" => "
" . __("Billing Cycle", "gravityforms") . "
" . __("Select your billing cycle. This determines how often the recurring payment should occur.", "gravityforms") ), array( "name" => "recurringTimes", "label" => __("Recurring Times", "gravityforms"), "type" => "select", - "choices" => array(array("label" => "infinite", "value" => "0")) + $this->get_numeric_choices(1,100) + "choices" => array(array("label" => "infinite", "value" => "0")) + $this->get_numeric_choices(1,100), + "tooltip" => "
" . __("Recurring Times", "gravityforms") . "
" . __("Select how many times the recurring payment should be made. The default is to bill the customer until the subscription is canceled.", "gravityforms") ), array( "name" => "setupFee", @@ -1113,7 +1192,8 @@ public function feed_settings_fields() { "name" => "trial", "label" => __("Trial", "gravityforms"), "type" => "trial", - "hidden" => $this->get_setting("setupFee_enabled") + "hidden" => $this->get_setting("setupFee_enabled"), + "tooltip" => "
" . __("Trial Period", "gravityformspaypal") . "
" . __("Enable a trial period. The users recurring payment will not begin until after this trial period.", "gravityforms") ) ) ), @@ -1131,7 +1211,8 @@ public function feed_settings_fields() { "type" => "select", "choices" => $this->product_amount_choices(), "required" => true, - "default_value" => "form_total" + "default_value" => "form_total", + "tooltip" => "
" . __("Payment Amount", "gravityforms") . "
" . __("Select which field determines the payment amount, or select 'Form Total' to use the total of all pricing fields as the payment amount.", "gravityforms") ) ) ), @@ -1154,7 +1235,8 @@ public function other_settings_fields(){ "name" => "billingInformation", "label" => __("Billing Information", "gravityforms"), "type" => "field_map", - "field_map" => $this->billing_info_fields() + "field_map" => $this->billing_info_fields(), + "tooltip" => "
" . __("Billing Information", "gravityforms") . "
" . __("Map your Form Fields to the available listed fields.", "gravityforms") ) ); @@ -1171,7 +1253,8 @@ public function other_settings_fields(){ $other_settings[] = array( "name" => "conditionalLogic", "label" => __("Conditional Logic", "gravityforms"), - "type" => "feed_condition" + "type" => "feed_condition", + "tooltip" => "
" . __("Conditional Logic", "gravityforms") . "
" . __("When conditions are enabled, form submissions will only be sent to the payment gateway when the conditions are met. When disabled, all form submissions will be sent to the payment gateway.", "gravityforms") ); return $other_settings; @@ -1253,7 +1336,7 @@ public function settings_setup_fee( $field, $echo = true ) { public function set_trial_onchange($field){ - return "alert('firing onchange');if(jQuery(this).prop('checked')){jQuery('#{$field["name"]}_product').show('slow');if (jQuery('#{$field["name"]}_product').val() == 'enter_amount'){jQuery('#{$field["name"]}_amount').show('slow');}} else {jQuery('#{$field["name"]}_product').hide('slow');jQuery('#{$field["name"]}_amount').hide('slow');}"; + return "if(jQuery(this).prop('checked')){jQuery('#{$field["name"]}_product').show('slow');if (jQuery('#{$field["name"]}_product').val() == 'enter_amount'){jQuery('#{$field["name"]}_amount').show();}} else {jQuery('#{$field["name"]}_product').hide('slow');jQuery('#{$field["name"]}_amount').hide();}"; } @@ -1282,7 +1365,7 @@ public function settings_trial( $field, $echo = true ) { "name" => $field["name"] . "_product", "type" => "select", "class" => $this->get_setting("{$field["name"]}_enabled") ? "" : "hidden", - "onchange" => "if(jQuery(this).val() == 'enter_amount'){jQuery('#{$field["name"]}_amount').show('slow');} else {jQuery('#{$field["name"]}_amount').hide('slow');}", + "onchange" => "if(jQuery(this).val() == 'enter_amount'){jQuery('#{$field["name"]}_amount').show();} else {jQuery('#{$field["name"]}_amount').hide();}", "choices" => $payment_choices ); @@ -1292,7 +1375,7 @@ public function settings_trial( $field, $echo = true ) { $amount_field = array( "type" => "text", "name" => "{$field["name"]}_amount", - "class" => $this->get_setting("{$field["name"]}_enabled") && $this->get_setting("{$field["name"]}_product") == "enter_amount" ? "" : "hidden", + "class" => $this->get_setting("{$field["name"]}_enabled") && $this->get_setting("{$field["name"]}_product") == 'enter_amount' ? 'gform_currency' : 'hidden gform_currency', ); $html .= " " . $this->settings_text($amount_field, false); @@ -1381,16 +1464,13 @@ protected function get_payment_choices($form){ //--------- Stats Page ------------------- public function get_results_page_config() { - $current_form = $this->get_current_form(); - - if(!$this->has_feed($current_form["id"])) - return false; return array( "title" => "Sales", "search_title" => "Filter", "capabilities" => array("gravityforms_view_entries"), "callbacks" => array( + "fields" => array($this, "results_fields"), "data" => array($this, "results_data"), "markup" => array($this, "results_markup"), "filter_ui" => array($this, "results_filter_ui") @@ -1399,6 +1479,17 @@ public function get_results_page_config() { } + public function results_fields($form) { + + if( $this->has_feed( $form['id'] ) ){ + return $form['fields']; + } + else { + return false; + } + + } + public function results_markup($html, $data, $form, $fields){ $html = "
@@ -1685,8 +1776,7 @@ protected function get_sales_summary($form_id){ $tz_offset = $this->get_mysql_tz_offset(); - $summary = $wpdb->get_results( - $wpdb->prepare(" + $sql = $wpdb->prepare(" SELECT lead.date, lead.orders, lead.subscriptions, transaction.revenue FROM ( SELECT date( CONVERT_TZ(date_created, '+00:00', '" . $tz_offset . "') ) as date, @@ -1705,7 +1795,9 @@ protected function get_sales_summary($form_id){ WHERE l.form_id=%d GROUP BY date ) AS transaction on lead.date = transaction.date - ORDER BY date desc", $form_id, $form_id), ARRAY_A); + ORDER BY date desc", $form_id, $form_id); + + $summary = $wpdb->get_results($sql, ARRAY_A); $total_summary = $wpdb->get_results( $wpdb->prepare(" @@ -1743,7 +1835,7 @@ protected function get_sales_summary($form_id){ $result["yesterday"]["subscriptions"] = $day["subscriptions"]; } - $is_within_30_days = strtotime($day["date"]) >= strtotime($local_time . " -30 days") ; + $is_within_30_days = strtotime( $day["date"] ) >= strtotime( "-30 days", $local_time ) ; if($is_within_30_days){ $result["last30"]["revenue"] += floatval($day["revenue"]); $result["last30"]["orders"] += floatval($day["orders"]); @@ -1798,8 +1890,16 @@ protected function get_payment_methods($form_id){ $payment_methods = $wpdb->get_col($wpdb->prepare("SELECT DISTINCT payment_method FROM {$wpdb->prefix}rg_lead WHERE form_id=%d", $form_id)); - return $payment_methods; + return array_filter( $payment_methods, array( $this, 'array_filter_non_blank' ) ); } + + protected function array_filter_non_blank ( $value ){ + if( empty( $value ) || $value == 'null' ){ + return false; + } + return true; + } + //-------- Uninstall --------------------- protected function uninstall(){ global $wpdb; @@ -1808,8 +1908,12 @@ protected function uninstall(){ $sql = $wpdb->prepare( "DELETE FROM {$wpdb->prefix}gf_addon_payment_transaction WHERE lead_id IN (SELECT lead_id FROM {$wpdb->prefix}rg_lead_meta WHERE meta_key='payment_gateway' AND meta_value=%s)", $this->_slug); + $wpdb->query($sql); - $wpdb->query($sql); + $sql = $wpdb->prepare( "DELETE FROM {$wpdb->prefix}gf_addon_payment_callback WHERE addon_slug=%s", $this->_slug); + $wpdb->query($sql); + + delete_option( 'gravityformsaddon_payment_version' ); //clear cron wp_clear_scheduled_hook($this->_slug . "_cron"); @@ -1835,7 +1939,13 @@ public function scripts() { array( "admin_page" => array( "form_settings" ), "tab" => $this->_slug ), array( "admin_page" => array( "entry_view" ) ) ) - ) + ), + array( + 'handle' => 'gform_form_admin', + 'enqueue' => array( + array( 'admin_page' => array( 'entry_edit' ) ), + ), + ), ); return array_merge( parent::scripts(), $scripts ); diff --git a/includes/api.php b/includes/api.php index 7b30465..0dbc96d 100644 --- a/includes/api.php +++ b/includes/api.php @@ -47,6 +47,33 @@ public static function get_form($form_id) { } + /** + * Returns all the form objects + * + * @since 1.8.11.5 + * @access public + * @static + * + * @param bool $active + * @param bool $trash + * + * @return mixed The array of Forms + */ + public static function get_forms( $active = true, $trash = false ) { + + $form_ids = GFFormsModel::get_form_ids( $active, $trash ); + if ( empty( $form_ids ) ) { + return array(); + } + + $forms = array(); + foreach ( $form_ids as $form_id ) { + $forms[] = GFAPI::get_form( $form_id ); + } + + return $forms; + } + /** * Deletes the forms with the given Form IDs * diff --git a/includes/upload.php b/includes/upload.php index 8a41edd..e4ef18d 100644 --- a/includes/upload.php +++ b/includes/upload.php @@ -36,6 +36,10 @@ public static function upload() { $form_unique_id = rgpost("gform_unique_id"); $form = GFFormsModel::get_form_meta($form_id); + if ( empty( $form ) ) { + die(); + } + $target_dir = GFFormsModel::get_upload_path($form_id) . DIRECTORY_SEPARATOR . "tmp" . DIRECTORY_SEPARATOR; wp_mkdir_p($target_dir); @@ -50,6 +54,11 @@ public static function upload() { $file_name = isset($_REQUEST["name"]) ? $_REQUEST["name"] : ''; $field_id = rgpost("field_id"); $field = GFFormsModel::get_field($form, $field_id); + + if ( empty( $field ) ) { + die(); + } + // Clean the fileName for security reasons $file_name = preg_replace('/[^\w\._]+/', '_', $file_name); @@ -154,6 +163,11 @@ public static function upload() { $uploaded_filename = $_FILES["file"]["name"]; + if ( file_exists( $file_path ) ) { + GFFormsModel::set_permissions( $file_path ); + } else { + die( '{"status" : "error", "error" : {"code": 105, "message": "' . __( 'Upload unsuccessful:', 'gravityforms' ) . ' '. $uploaded_filename . '"}}' ); + } $output = array("status" => "ok", "data" => array("temp_filename" => $tmp_file_name , diff --git a/includes/webapi/webapi.php b/includes/webapi/webapi.php index fdd7704..8b7bf27 100644 --- a/includes/webapi/webapi.php +++ b/includes/webapi/webapi.php @@ -1080,7 +1080,7 @@ public function results_cache_exists($form_id) { $key = $this->get_results_cache_key_prefix($form_id); - $key = "%" . like_escape($key) . "%"; + $key = "%" . GFCommon::esc_like( $key ) . "%"; $sql = $wpdb->prepare("SELECT count(option_id) FROM $wpdb->options WHERE option_name LIKE %s", $key); @@ -1099,7 +1099,7 @@ public function delete_cached_results($form_id) { $key = $this->get_results_cache_key_prefix($form_id); - $key = "%" . like_escape($key) . "%"; + $key = "%" . GFCommon::esc_like( $key ) . "%"; $sql = $wpdb->prepare("DELETE FROM $wpdb->options WHERE option_name LIKE %s", $key); diff --git a/js/chosen.jquery.min.js b/js/chosen.jquery.min.js index 1215390..cece231 100644 --- a/js/chosen.jquery.min.js +++ b/js/chosen.jquery.min.js @@ -1,10 +1,2 @@ -// Chosen, a Select Box Enhancer for jQuery and Protoype -// by Patrick Filler for Harvest, http://getharvest.com -// -// Version 0.9.12 -// Full source at https://github.com/harvesthq/chosen -// Copyright (c) 2011 Harvest http://getharvest.com - -// MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md -// This file is generated by `cake build`, do not edit it by hand. -(function(){var e;e=function(){function e(){this.options_index=0,this.parsed=[]}return e.prototype.add_node=function(e){return e.nodeName.toUpperCase()==="OPTGROUP"?this.add_group(e):this.add_option(e)},e.prototype.add_group=function(e){var t,n,r,i,s,o;t=this.parsed.length,this.parsed.push({array_index:t,group:!0,label:e.label,children:0,disabled:e.disabled}),s=e.childNodes,o=[];for(r=0,i=s.length;r"+e.html+"")},e.prototype.results_update_field=function(){return this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.result_single_selected=null,this.results_build()},e.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},e.prototype.results_search=function(e){return this.results_showing?this.winnow_results():this.results_show()},e.prototype.keyup_checker=function(e){var t,n;t=(n=e.which)!=null?n:e.keyCode,this.search_field_scale();switch(t){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:e.preventDefault();if(this.results_showing)return this.result_select(e);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},e.prototype.generate_field_id=function(){var e;return e=this.generate_random_id(),this.form_field.id=e,e},e.prototype.generate_random_char=function(){var e,t,n;return e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",n=Math.floor(Math.random()*e.length),t=e.substring(n,n+1)},e}(),t.AbstractChosen=e}.call(this),function(){var e,t,n,r,i={}.hasOwnProperty,s=function(e,t){function r(){this.constructor=e}for(var n in t)i.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e};r=this,e=jQuery,e.fn.extend({chosen:function(n){var r,i,s;return s=navigator.userAgent.toLowerCase(),i=/(msie) ([\w.]+)/.exec(s)||[],r={name:i[1]||"",version:i[2]||"0"},r.name==="msie"&&(r.version==="6.0"||r.version==="7.0"&&document.documentMode===7)?this:this.each(function(r){var i;i=e(this);if(!i.hasClass("chzn-done"))return i.data("chosen",new t(this,n))})}}),t=function(t){function i(){return i.__super__.constructor.apply(this,arguments)}return s(i,t),i.prototype.setup=function(){return this.form_field_jq=e(this.form_field),this.current_value=this.form_field_jq.val(),this.is_rtl=this.form_field_jq.hasClass("chzn-rtl")},i.prototype.finish_setup=function(){return this.form_field_jq.addClass("chzn-done")},i.prototype.set_up_html=function(){var t,r,i,s,o,u;return this.container_id=this.form_field.id.length?this.form_field.id.replace(/[^\w]/g,"_"):this.generate_field_id(),this.container_id+="_chzn",t=["chzn-container"],t.push("chzn-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&t.push(this.form_field.className),this.is_rtl&&t.push("chzn-rtl"),this.f_width=this.form_field_jq.outerWidth(),i={id:this.container_id,"class":t.join(" "),style:"width: "+this.f_width+"px;",title:this.form_field.title},r=e("
",i),this.is_multiple?r.html('
    '):r.html(''+this.default_text+'
      '),this.form_field_jq.hide().after(r),this.container=e("#"+this.container_id),this.dropdown=this.container.find("div.chzn-drop").first(),s=this.container.height(),o=this.f_width-n(this.dropdown),this.dropdown.css({width:o+"px",top:s+"px"}),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chzn-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chzn-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chzn-search").first(),this.selected_item=this.container.find(".chzn-single").first(),u=o-n(this.search_container)-n(this.search_field),this.search_field.css({width:u+"px"})),this.results_build(),this.set_tab_index(),this.form_field_jq.trigger("liszt:ready",{chosen:this})},i.prototype.register_observers=function(){var e=this;return this.container.mousedown(function(t){return e.container_mousedown(t)}),this.container.mouseup(function(t){return e.container_mouseup(t)}),this.container.mouseenter(function(t){return e.mouse_enter(t)}),this.container.mouseleave(function(t){return e.mouse_leave(t)}),this.search_results.mouseup(function(t){return e.search_results_mouseup(t)}),this.search_results.mouseover(function(t){return e.search_results_mouseover(t)}),this.search_results.mouseout(function(t){return e.search_results_mouseout(t)}),this.form_field_jq.bind("liszt:updated",function(t){return e.results_update_field(t)}),this.form_field_jq.bind("liszt:activate",function(t){return e.activate_field(t)}),this.form_field_jq.bind("liszt:open",function(t){return e.container_mousedown(t)}),this.search_field.blur(function(t){return e.input_blur(t)}),this.search_field.keyup(function(t){return e.keyup_checker(t)}),this.search_field.keydown(function(t){return e.keydown_checker(t)}),this.search_field.focus(function(t){return e.input_focus(t)}),this.is_multiple?this.search_choices.click(function(t){return e.choices_click(t)}):this.container.click(function(e){return e.preventDefault()})},i.prototype.search_field_disabled=function(){this.is_disabled=this.form_field_jq[0].disabled;if(this.is_disabled)return this.container.addClass("chzn-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus",this.activate_action),this.close_field();this.container.removeClass("chzn-disabled"),this.search_field[0].disabled=!1;if(!this.is_multiple)return this.selected_item.bind("focus",this.activate_action)},i.prototype.container_mousedown=function(t){var n;if(!this.is_disabled)return n=t!=null?e(t.target).hasClass("search-choice-close"):!1,t&&t.type==="mousedown"&&!this.results_showing&&t.preventDefault(),!this.pending_destroy_click&&!n?(this.active_field?!this.is_multiple&&t&&(e(t.target)[0]===this.selected_item[0]||e(t.target).parents("a.chzn-single").length)&&(t.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),e(document).click(this.click_test_action),this.results_show()),this.activate_field()):this.pending_destroy_click=!1},i.prototype.container_mouseup=function(e){if(e.target.nodeName==="ABBR"&&!this.is_disabled)return this.results_reset(e)},i.prototype.blur_test=function(e){if(!this.active_field&&this.container.hasClass("chzn-container-active"))return this.close_field()},i.prototype.close_field=function(){return e(document).unbind("click",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},i.prototype.activate_field=function(){return this.container.addClass("chzn-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},i.prototype.test_active_click=function(t){return e(t.target).parents("#"+this.container_id).length?this.active_field=!0:this.close_field()},i.prototype.results_build=function(){var e,t,n,i,s;this.parsing=!0,this.results_data=r.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.find("li.search-choice").remove(),this.choices=0):this.is_multiple||(this.selected_item.addClass("chzn-default").find("span").text(this.default_text),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?this.container.addClass("chzn-container-single-nosearch"):this.container.removeClass("chzn-container-single-nosearch")),e="",s=this.results_data;for(n=0,i=s.length;n'+e("
      ").text(t.label).html()+"")},i.prototype.result_do_highlight=function(e){var t,n,r,i,s;if(e.length){this.result_clear_highlight(),this.result_highlight=e,this.result_highlight.addClass("highlighted"),r=parseInt(this.search_results.css("maxHeight"),10),s=this.search_results.scrollTop(),i=r+s,n=this.result_highlight.position().top+this.search_results.scrollTop(),t=n+this.result_highlight.outerHeight();if(t>=i)return this.search_results.scrollTop(t-r>0?t-r:0);if(n'+t.html+"":r='
    • '+t.html+'
    • ',this.search_container.before(r),i=e("#"+n).find("a").first(),i.click(function(e){return s.choice_destroy_link_click(e)}))},i.prototype.choice_destroy_link_click=function(t){return t.preventDefault(),this.is_disabled?t.stopPropagation:(this.pending_destroy_click=!0,this.choice_destroy(e(t.target)))},i.prototype.choice_destroy=function(e){if(this.result_deselect(e.attr("rel")))return this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.val().length<1&&this.results_hide(),e.parents("li").first().remove(),this.search_field_scale()},i.prototype.results_reset=function(){this.form_field.options[0].selected=!0,this.selected_item.find("span").text(this.default_text),this.is_multiple||this.selected_item.addClass("chzn-default"),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change");if(this.active_field)return this.results_hide()},i.prototype.results_reset_cleanup=function(){return this.current_value=this.form_field_jq.val(),this.selected_item.find("abbr").remove()},i.prototype.result_select=function(e){var t,n,r,i;if(this.result_highlight)return t=this.result_highlight,n=t.attr("id"),this.result_clear_highlight(),this.is_multiple?this.result_deactivate(t):(this.search_results.find(".result-selected").removeClass("result-selected"),this.result_single_selected=t,this.selected_item.removeClass("chzn-default")),t.addClass("result-selected"),i=n.substr(n.lastIndexOf("_")+1),r=this.results_data[i],r.selected=!0,this.form_field.options[r.options_index].selected=!0,this.is_multiple?this.choice_build(r):(this.selected_item.find("span").first().text(r.text),this.allow_single_deselect&&this.single_deselect_control_build()),(!e.metaKey&&!e.ctrlKey||!this.is_multiple)&&this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field_jq.val()!==this.current_value)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[r.options_index].value}),this.current_value=this.form_field_jq.val(),this.search_field_scale()},i.prototype.result_activate=function(e){return e.addClass("active-result")},i.prototype.result_deactivate=function(e){return e.removeClass("active-result")},i.prototype.result_deselect=function(t){var n,r;return r=this.results_data[t],this.form_field.options[r.options_index].disabled?!1:(r.selected=!1,this.form_field.options[r.options_index].selected=!1,n=e("#"+this.container_id+"_o_"+t),n.removeClass("result-selected").addClass("active-result").show(),this.result_clear_highlight(),this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[r.options_index].value}),this.search_field_scale(),!0)},i.prototype.single_deselect_control_build=function(){if(this.allow_single_deselect&&this.selected_item.find("abbr").length<1)return this.selected_item.find("span").first().after('')},i.prototype.winnow_results=function(){var t,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y;this.no_results_clear(),f=0,l=this.search_field.val()===this.default_text?"":e("
      ").text(e.trim(this.search_field.val())).html(),o=this.search_contains?"":"^",s=new RegExp(o+l.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),p=new RegExp(l.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),y=this.results_data;for(d=0,m=y.length;d=0||n.html.indexOf("[")===0)){i=n.html.replace(/\[|\]/g,"").split(" ");if(i.length)for(v=0,g=i.length;v"+n.html.substr(c+l.length),h=h.substr(0,c)+""+h.substr(c)):h=n.html,u.html(h),this.result_activate(u),n.group_array_index!=null&&e("#"+this.results_data[n.group_array_index].dom_id).css("display","list-item")):(this.result_highlight&&a===this.result_highlight.attr("id")&&this.result_clear_highlight(),this.result_deactivate(u))}}return f<1&&l.length?this.no_results(l):this.winnow_results_set_highlight()},i.prototype.winnow_results_clear=function(){var t,n,r,i,s;this.search_field.val(""),n=this.search_results.find("li"),s=[];for(r=0,i=n.length;r'+this.results_none_found+' ""'),n.find("span").first().html(t),this.search_results.append(n)},i.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},i.prototype.keydown_arrow=function(){var t,n;this.result_highlight?this.results_showing&&(n=this.result_highlight.nextAll("li.active-result").first(),n&&this.result_do_highlight(n)):(t=this.search_results.find("li.active-result").first(),t&&this.result_do_highlight(e(t)));if(!this.results_showing)return this.results_show()},i.prototype.keyup_arrow=function(){var e;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight)return e=this.result_highlight.prevAll("li.active-result"),e.length?this.result_do_highlight(e.first()):(this.choices>0&&this.results_hide(),this.result_clear_highlight())},i.prototype.keydown_backstroke=function(){var e;if(this.pending_backstroke)return this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke();e=this.search_container.siblings("li.search-choice").last();if(e.length&&!e.hasClass("search-choice-disabled"))return this.pending_backstroke=e,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")},i.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},i.prototype.keydown_checker=function(e){var t,n;t=(n=e.which)!=null?n:e.keyCode,this.search_field_scale(),t!==8&&this.pending_backstroke&&this.clear_backstroke();switch(t){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(e),this.mouse_on_container=!1;break;case 13:e.preventDefault();break;case 38:e.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},i.prototype.search_field_scale=function(){var t,n,r,i,s,o,u,a,f;if(this.is_multiple){r=0,u=0,s="position:absolute; left: -1000px; top: -1000px; display:none;",o=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(a=0,f=o.length;a",{style:s}),n.text(this.search_field.val()),e("body").append(n),u=n.width()+25,n.remove(),u>this.f_width-10&&(u=this.f_width-10),this.search_field.css({width:u+"px"}),t=this.container.height(),this.dropdown.css({top:t+"px"})}},i.prototype.generate_random_id=function(){var t;t="sel"+this.generate_random_char()+this.generate_random_char()+this.generate_random_char();while(e("#"+t).length>0)t+=this.generate_random_char();return t},i}(AbstractChosen),r.Chosen=t,n=function(e){var t;return t=e.outerWidth()-e.width()},r.get_side_border_padding=n}.call(this); \ No newline at end of file +/* Chosen v1.1.0 | (c) 2011-2013 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */ +!function(){var a,AbstractChosen,Chosen,SelectParser,b,c={}.hasOwnProperty,d=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),children:0,disabled:a.disabled}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"<",">":">",'"':""","'":"'","`":"`"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(c.text));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.style.cssText=a.style,c.setAttribute("data-option-array-index",a.array_index),c.innerHTML=a.search_text,this.outerHTML(c)):"":""},AbstractChosen.prototype.result_add_group=function(a){var b;return a.search_match||a.group_match?a.active_options>0?(b=document.createElement("li"),b.className="group-result",b.innerHTML=a.search_text,this.outerHTML(b)):"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.reset_single_select_options=function(){var a,b,c,d,e;for(d=this.results_data,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.selected?e.push(a.selected=!1):e.push(void 0);return e},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m;for(this.no_results_clear(),e=0,g=this.get_search_text(),a=g.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),d=this.search_contains?"":"^",c=new RegExp(d+a,"i"),j=new RegExp(a,"i"),m=this.results_data,k=0,l=m.length;l>k;k++)b=m[k],b.search_match=!1,f=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(f=this.results_data[b.group_array_index],0===f.active_options&&f.search_match&&(e+=1),f.active_options+=1),(!b.group||this.group_search)&&(b.search_text=b.group?b.label:b.html,b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(e+=1),b.search_match?(g.length&&(h=b.search_text.search(j),i=b.search_text.substr(0,h+g.length)+""+b.search_text.substr(h+g.length),b.search_text=i.substr(0,h)+""+i.substr(h)),null!=f&&(f.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>e&&g.length?(this.update_results_content(""),this.no_results(g)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.clipboard_event_checker=function(){var a=this;return setTimeout(function(){return a.results_search()},50)},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.prototype.search_results_touchstart=function(a){return this.touch_started=!0,this.search_results_mouseover(a)},AbstractChosen.prototype.search_results_touchmove=function(a){return this.touch_started=!1,this.search_results_mouseout(a)},AbstractChosen.prototype.search_results_touchend=function(a){return this.touch_started?this.search_results_mouseup(a):void 0},AbstractChosen.prototype.outerHTML=function(a){var b;return a.outerHTML?a.outerHTML:(b=document.createElement("div"),b.appendChild(a),b.innerHTML)},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),a=jQuery,a.fn.extend({chosen:function(b){return AbstractChosen.browser_is_supported()?this.each(function(){var c,d;c=a(this),d=c.data("chosen"),"destroy"===b&&d?d.destroy():d||c.data("chosen",new Chosen(this,b))}):this}}),Chosen=function(c){function Chosen(){return b=Chosen.__super__.constructor.apply(this,arguments)}return d(Chosen,c),Chosen.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},Chosen.prototype.set_up_html=function(){var b,c;return b=["chosen-container"],b.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&b.push(this.form_field.className),this.is_rtl&&b.push("chosen-rtl"),c={"class":b.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(c.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=a("
      ",c),this.is_multiple?this.container.html('
        '):this.container.html(''+this.default_text+'
          '),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field_jq.trigger("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.bind("mousedown.chosen",function(b){a.container_mousedown(b)}),this.container.bind("mouseup.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mouseenter.chosen",function(b){a.mouse_enter(b)}),this.container.bind("mouseleave.chosen",function(b){a.mouse_leave(b)}),this.search_results.bind("mouseup.chosen",function(b){a.search_results_mouseup(b)}),this.search_results.bind("mouseover.chosen",function(b){a.search_results_mouseover(b)}),this.search_results.bind("mouseout.chosen",function(b){a.search_results_mouseout(b)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(b){a.search_results_mousewheel(b)}),this.search_results.bind("touchstart.chosen",function(b){a.search_results_touchstart(b)}),this.search_results.bind("touchmove.chosen",function(b){a.search_results_touchmove(b)}),this.search_results.bind("touchend.chosen",function(b){a.search_results_touchend(b)}),this.form_field_jq.bind("chosen:updated.chosen",function(b){a.results_update_field(b)}),this.form_field_jq.bind("chosen:activate.chosen",function(b){a.activate_field(b)}),this.form_field_jq.bind("chosen:open.chosen",function(b){a.container_mousedown(b)}),this.form_field_jq.bind("chosen:close.chosen",function(b){a.input_blur(b)}),this.search_field.bind("blur.chosen",function(b){a.input_blur(b)}),this.search_field.bind("keyup.chosen",function(b){a.keyup_checker(b)}),this.search_field.bind("keydown.chosen",function(b){a.keydown_checker(b)}),this.search_field.bind("focus.chosen",function(b){a.input_focus(b)}),this.search_field.bind("cut.chosen",function(b){a.clipboard_event_checker(b)}),this.search_field.bind("paste.chosen",function(b){a.clipboard_event_checker(b)}),this.is_multiple?this.search_choices.bind("click.chosen",function(b){a.choices_click(b)}):this.container.bind("click.chosen",function(a){a.preventDefault()})},Chosen.prototype.destroy=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},Chosen.prototype.container_mousedown=function(b){return this.is_disabled||(b&&"mousedown"===b.type&&!this.results_showing&&b.preventDefault(),null!=b&&a(b.target).hasClass("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!b||a(b.target)[0]!==this.selected_item[0]&&!a(b.target).parents("a.chosen-single").length||(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(this.container[0].ownerDocument).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b;return a.originalEvent&&(b=-a.originalEvent.wheelDelta||a.originalEvent.detail),null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop(b+this.search_results.scrollTop())):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClass("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},Chosen.prototype.test_active_click=function(b){var c;return c=a(b.target).closest(".chosen-container"),c.length&&this.container[0]===c[0]?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){if(this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight(),b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(f>c)return this.search_results.scrollTop(c)}},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.container.addClass("chosen-with-drop"),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results(),this.form_field_jq.trigger("chosen:showing_dropdown",{chosen:this}))},Chosen.prototype.update_results_content=function(a){return this.search_results.html(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var b=this;return this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=a("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0?this.form_field_label.bind("click.chosen",function(a){return b.is_multiple?b.container_mousedown(a):b.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},Chosen.prototype.search_results_mouseup=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c.length?(this.result_highlight=c,this.result_select(b),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c?this.result_do_highlight(c):void 0},Chosen.prototype.search_results_mouseout=function(b){return a(b.target).hasClass("active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(b){var c,d,e=this;return c=a("
        • ",{"class":"search-choice"}).html(""+b.html+""),b.disabled?c.addClass("search-choice-disabled"):(d=a("",{"class":"search-choice-close","data-option-array-index":b.array_index}),d.bind("click.chosen",function(a){return e.choice_destroy_link_click(a)}),c.append(d)),this.search_container.before(c)},Chosen.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),b.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a(b.target))},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a[0].getAttribute("data-option-array-index"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),a.parents("li").first().remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},Chosen.prototype.result_select=function(a){var b,c;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClass("active-result"):this.reset_single_select_options(),c=this.results_data[b[0].getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(c.text),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[c.options_index].value}),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.selected_item.find("span").text(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[b.options_index].value}),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.find("abbr").length||this.selected_item.find("span").first().after(''),this.selected_item.addClass("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":a("
          ").text(a.trim(this.search_field.val())).html()},Chosen.prototype.winnow_results_set_highlight=function(){var a,b;return b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first(),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(b){var c;return c=a('
        • '+this.results_none_found+' ""
        • '),c.find("span").first().html(b),this.search_results.append(c),this.form_field_jq.trigger("chosen:no_results",{chosen:this})},Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a;return this.results_showing||this.is_multiple?this.result_highlight?(a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(a=this.search_container.siblings("li.search-choice").last(),a.length&&!a.hasClass("search-choice-disabled")?(this.pending_backstroke=a,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){for(d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],i=0,j=g.length;j>i;i++)e=g[i],f+=e+":"+this.search_field.css(e)+";";return b=a("
          ",{style:f}),b.text(this.search_field.val()),a("body").append(b),h=b.width()+25,b.remove(),c=this.container.outerWidth(),h>c-10&&(h=c-10),this.search_field.css({width:h+"px"})}},Chosen}(AbstractChosen)}.call(this); \ No newline at end of file diff --git a/js/conditional_logic.js b/js/conditional_logic.js index aa15d50..521e3c0 100644 --- a/js/conditional_logic.js +++ b/js/conditional_logic.js @@ -76,13 +76,13 @@ function gf_is_match(formId, rule){ for(var i=0; i< inputs.length; i++){ fieldValue = gf_get_value(jQuery(inputs[i]).val()); - + //find specific checkbox/radio item. Skip if this is not the specific item and the operator is not one that targets a range of values (i.e. greater than and less than) var isRangeOperator = jQuery.inArray(rule["operator"], ["<", ">", "contains", "starts_with", "ends_with"]) >= 0; if(fieldValue != rule["value"] && !isRangeOperator) { continue; } - + //blank value if item isn't checked if(!jQuery(inputs[i]).is(":checked")) { fieldValue = ""; @@ -94,7 +94,7 @@ function gf_is_match(formId, rule){ if(gf_matches_operation(fieldValue, rule["value"], rule["operator"])) isMatch = true; - } + } } else{ //handling all other fields (non-checkboxes) @@ -238,44 +238,43 @@ function gf_do_next_button_action(formId, action, fieldId, isInit){ } function gf_do_action(action, targetId, useAnimation, defaultValues, isInit, callback){ - if(action == "show"){ - if(useAnimation && !isInit){ - if(jQuery(targetId).length > 0) - jQuery(targetId).slideDown(callback); - else if(callback) - callback(); - - } - else{ - jQuery(targetId).show(); - if(callback) - callback(); - - } - } - else{ - //if field is not already hidden, reset its values to the default - var child = jQuery(targetId).children().first(); + var $target = jQuery(targetId); + if(action == "show"){ + if(useAnimation && !isInit){ + if($target.length > 0){ + $target.slideDown(callback); + } else if(callback){ + callback(); + } + } + else{ + $target.show(); + if(callback){ + callback(); + } + } + } + else{ + //if field is not already hidden, reset its values to the default + var child = $target.children().first(); if (child.length > 0){ - if(!gformIsHidden(child)){ - gf_reset_to_default(targetId, defaultValues); - } + if(!gformIsHidden(child)){ + gf_reset_to_default(targetId, defaultValues); + } } - if(useAnimation && !isInit){ - if(jQuery(targetId).length > 0) { - jQuery(targetId).slideUp(callback); + if(useAnimation && !isInit){ + if($target.length > 0 && $target.is(":visible")) { + $target.slideUp(callback); + } else if(callback) { + callback(); } - else if(callback) { - callback(); - } - } - else{ - jQuery(targetId).hide(); - if(callback){ - callback(); - } - } + } else{ + $target.hide(); + if(callback){ + callback(); + } + } } } @@ -319,7 +318,7 @@ function gf_reset_to_default(targetId, defaultValue){ var element = jQuery(this); if(element.is('select:not([multiple])')){ - val = element.find('option').eq(0).val(); + val = element.find('option' ).not( ':disabled' ).eq(0).val(); } //get name of previous input field to see if it is the radio button which goes with the "Other" text box diff --git a/js/form_admin.js b/js/form_admin.js index a4d050d..e7ff428 100644 --- a/js/form_admin.js +++ b/js/form_admin.js @@ -15,8 +15,24 @@ jQuery(document).ready(function($){ if(typeof form != 'undefined') window.gfMergeTags = new gfMergeTagsObj(form); + $(document).ready(function(){ + $(".gform_currency").bind("change", function(){ + FormatCurrency(this); + }).each(function(){ + FormatCurrency(this); + }); + }); + }); +function FormatCurrency(element){ + if(gf_vars.gf_currency_config){ + var currency = new Currency(gf_vars.gf_currency_config); + var price = currency.toMoney(jQuery(element).val()); + jQuery(element).val(price); + } +} + function ToggleConditionalLogic(isInit, objectType){ var speed = isInit ? "" : "slow"; if(jQuery('#' + objectType + '_conditional_logic').is(":checked")){ @@ -39,36 +55,35 @@ function ToggleConditionalLogic(isInit, objectType){ } function GetConditionalObject(objectType){ - - var object = false; + var obj = false; switch(objectType){ case "page": case "field": - object = GetSelectedField(); + obj = GetSelectedField(); break; case "next_button" : var field = GetSelectedField(); - object = field["nextButton"]; + obj = field["nextButton"]; break; case "confirmation": - object = confirmation; + obj = confirmation; break; case "notification": - object = current_notification; + obj = current_notification; break; default: - object = typeof form != 'undefined' ? form.button : false; + obj = typeof form != 'undefined' ? form.button : false; break; } - object = gform.applyFilters( 'gform_conditional_object', object, objectType ) + obj = gform.applyFilters( 'gform_conditional_object', obj, objectType ) - return object; + return obj; } function CreateConditionalLogic(objectType, obj){ @@ -106,6 +121,7 @@ function CreateConditionalLogic(objectType, obj){ var i, rule; for(i=0; i < obj.conditionalLogic.rules.length; i++){ rule = obj.conditionalLogic.rules[i]; + str += "
          "; str += GetRuleFields(objectType, i, rule.fieldId); str += GetRuleOperators(objectType, i, rule.fieldId, rule.operator); @@ -1334,6 +1350,16 @@ function FeedConditionConditionalDescription( description, descPieces, objectTyp return descPiecesArr.join(' '); } +function SimpleConditionObject( object, objectType ) { + + if( objectType.indexOf('simple_condition') < 0 ) + return object; + + var objectName = objectType.substring(17) + "_object"; + + return window[objectName]; +} + function makeArray( object ) { var array = []; for( i in object ) { diff --git a/js/gravityforms.js b/js/gravityforms.js index 9ac85ca..5425b4f 100644 --- a/js/gravityforms.js +++ b/js/gravityforms.js @@ -740,7 +740,7 @@ function gformInitChosenFields(fieldList, noResultsText){ var element = jQuery(this); //only initialize once - if( element.is(":visible") && element.siblings(".chzn-container").length == 0 ){ + if( element.is(":visible") && element.siblings(".chosen-container").length == 0 ){ var options = gform.applyFilters( 'gform_chosen_options', { no_results_text: noResultsText }, element ); element.chosen( options ); } @@ -797,7 +797,8 @@ var GFCalc = function(formId, formulaFields){ field = jQuery('#field_' + formId + '_' + formulaField.field_id), formulaInput = jQuery('#input_' + formId + '_' + formulaField.field_id), previous_val = formulaInput.val(), - expr = calcObj.replaceFieldTags( formId, formulaField.formula, formulaField ).replace(/(\r\n|\n|\r)/gm,""), + formula = gform.applyFilters( 'gform_calculation_formula', formulaField.formula, formulaField, formId, calcObj ), + expr = calcObj.replaceFieldTags( formId, formula, formulaField ).replace(/(\r\n|\n|\r)/gm,""), result = ''; if(calcObj.exprPatt.test(expr)) { @@ -1381,11 +1382,11 @@ function gformInitSpinner( formId, spinnerUrl ) { if( typeof spinnerUrl == 'undefined' || ! spinnerUrl ) spinnerUrl = gform.applyFilters( "gform_spinner_url", gf_global.spinnerUrl, formId ); - jQuery( '#gform_' + formId ).submit( function(){ - if( jQuery( '#gform_ajax_spinner_' . formId ).length == 0 ) { - jQuery( '#gform_submit_button_' + formId + ', #gform_wrapper_' + formId + ' .gform_next_button, #gform_wrapper_' + formId + ' .gform_image_button') - .after( '' ); - } - } ); + jQuery('#gform_' + formId).submit(function () { + if (jQuery('#gform_ajax_spinner_' + formId).length == 0) { + jQuery('#gform_submit_button_' + formId + ', #gform_wrapper_' + formId + ' .gform_next_button') + .after(''); + } + }); } diff --git a/languages/gravityforms-fi.mo b/languages/gravityforms-fi.mo index 79816d0..9086576 100644 Binary files a/languages/gravityforms-fi.mo and b/languages/gravityforms-fi.mo differ diff --git a/languages/gravityforms-fr_FR.mo b/languages/gravityforms-fr_FR.mo index 1d3862c..eb0707e 100644 Binary files a/languages/gravityforms-fr_FR.mo and b/languages/gravityforms-fr_FR.mo differ diff --git a/notification.php b/notification.php index bb85335..fc429b7 100644 --- a/notification.php +++ b/notification.php @@ -49,7 +49,7 @@ public static function notification_edit_page($form_id, $notification_id) { check_admin_referer('gforms_save_notification', 'gforms_save_notification'); //clear out notification because it could have legacy data populated - $notification = array(); + $notification = array( 'isActive' => isset( $notification['isActive'] ) ? rgar( $notification, 'isActive') : true ); $is_update = true; @@ -861,7 +861,7 @@ private static function is_valid_notification_email($text){ $emails = explode(",", $text); foreach($emails as $email){ $email = trim($email); - $invalid_email = GFCommon::is_invalid_or_empty_email($email); + $invalid_email = GFCommon::is_invalid_or_empty_email( $email ); $invalid_variable = !preg_match('/^({[^{]*?:(\d+(\.\d+)?)(:(.*?))?},? *)+$/', $email); if($invalid_email && $invalid_variable) @@ -1045,7 +1045,12 @@ function prepare_items() { } function display() { - extract( $this->_args ); + + // ...causing issue: Notice: Indirect modification of overloaded property GFNotificationTable::$_args has no effect + //extract( $this->_args ); // gives us $plural, $singular, $ajax, $screen + + $singular = $this->_args['singular']; + ?>
          diff --git a/select_columns.php b/select_columns.php index f15a3c4..2ff54bc 100644 --- a/select_columns.php +++ b/select_columns.php @@ -125,7 +125,7 @@ function SelectColumns(){ foreach($form["fields"] as $field){ if(RGFormsModel::get_input_type($field) == "checkbox" && !in_array($field["id"], $field_ids)){ ?> -
        • ">
        • +
        • ">
        • -
        • ">
        • +
        • ">