diff --git a/change_log.txt b/change_log.txt index 3ac7438..b64332b 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,3 +1,266 @@ +------------------------------------------------------------------------------------------------------------------- +Version 1.8.7.2 + - Fixed issue with chosen script throwing javascript errors on certain situations + +------------------------------------------------------------------------------------------------------------------- +Version 1.8.7.1 + - Added Bulgarian translation file + - Updated the multi-file upload field to support Plupload 2.x in WordPress 3.9 + +------------------------------------------------------------------------------------------------------------------- +Version 1.8.7 + + - Added Text Domain and Domain Path to plugin header so the description may be translated + + - Updated product calculation to improve performance + - Updated width of form title column so form actions do not wrap. + - Updated two notice statements to alleviate confusion + - Updated German translation file with user-provided update + - Updated a few strings so they can be translated + - Updated POT file + - Updated GFFormsModel::save_lead() method to support saving leads on non-admin views + - Updated GFFormDisplay::has_conditional_logic from private to public + + - Fixed an issue with the validation of the number field when set to currency format and the Gravity Forms currency setting is set to a decimal comma formatted currency + - Fixed incorrect domain for translations in a few instances + - Fixed security vulnerabilities + - Fixed issue with nested conditional logic on checkboxes. + - Fixed issue where conditional logic setting was showing up for Hidden products + - Fixed issue where GF Results was being initialized on all admin pages + - Fixed issue with the {pricing_fields} merge tag markup. + + - API: Updated the Web API authentication to accept both url-encoded and unencoded signatures to handle different client behavior + - API: Updated some mysql_*() calls to support WordPress 3.9 under PHP 5.5 or higher + + - AF: Added support for top level "app" menus + - AF: Added support for top level "app settings" + - AF: Added support for app tab UIs + - AF: Fixed an issue with the form settings menu where the menu item for the add-on was appearing in the menu even when the current user did not have adequate permissions + - AF: Fixed filter for app settings menu + +------------------------------------------------------------------------------------------------------------------- +Version 1.8.6 + + - Added logging to help troubleshooting form submissions. + - Added hook to allow multi-file upload settings/behavior to be changed. + - Added "French Polynesia" to countries list. + - Added 'gravityforms_delete_forms' and 'gravityforms_delete_entries' permission checks to form list. + - Added new filter "gform_email_background_color_label" to change the background color for the field label in the html email. + add_filter("gform_email_background_color_label", "set_email_label_color", 10, 3); + function set_email_label_color($color, $field, $lead){ + return "#CC99FF"; + } + - Added new filter "gform_email_background_color_data" to change the background color for the field data in the html email. + add_filter("gform_email_background_color_data", "set_email_data_color", 10, 3); + function set_email_data_color($color, $field, $lead){ + return "#CCCCFF"; + } + - Added gform_form_notification_page filter. + - Added 'gravityforms_delete_entries' permission checks to entry list and entry detail pages. + - Added $input_id as fifth parameter to the "gform_save_field_value" function; better allows overriding values for a specific input ID. + - Added support for state code via gform_us_states and gform_address_types hook. + - Added gform_form_export_page hook. + - Added gform_payment_details hook under gform_entry_info in preparation for a new Payment Details box on the entry page. + - Added support for country codes in country drop down. + - Added support for note type. + - Added support for changing note avatar. + - Added gform_delete_entries to get fired when entries are being deleted in bulk. + + - Fixed security vulnerability which allowed malicious form submissions to bypass validation of certain fields + - Fixed PHP warning on entry list when the created_by field contains the ID of a user that no longer exists + - Fixed issue with conditional logic when configured to start with "0". + - Fixed minor PHP warning for recently imported multi-step forms. + - Fixed issue where editing credit card fields with HTML5 ouptut enabled generated a browser validation error. + - Fixed security vulnerability which allowed malicious form submissions to bypass validation of certain fields. + - Fixed issue with entry detail pagination not working correctly on certain types of searches. + - Fixed issue with with the multi-file upload field generating a JavaScript error on multi-page, ajax-enabled forms with conditional logic. + - Fixed issue with multi file upload throwing AJAX errors when uploading a file with a single quote on certain webservers. + - Added GFs instance of the gfMergeTagsObj to the global scope to allow 3rd party devs to more easily work with merge tags. + - Fixed issue in the Italian translation file where a string was breaking javascript on the entry detail page. + - Fixed issue with entry export not decoding the value of multi file upload fields. + + - Fixed issue with the {pricing_fields} merge tag markup. + - Fixed escaping issue on input mask. + - Fixed issue with the new form modal on IE8. + - Fixed issue with datepicker css being rendered to the page even when no datepicker field is in the form. + - Fixed issue with country not being selected properly when code was provided via hook. + - Fixed styling issue with entry actions on entry detail page. + - Fixed issue where styles/scripts were being output before doctype when including a form in a confirmation. + - Fixed issue with number field validation when set to decimal comma. + - Fixed issue with select columns page not loading in SSL when appropriate. + - Fixed security vulnerability when validating product state. + - Fixed an issue with the entry list where trashed entries appear in the list of active entries when sorting by a field value. + - Fixed an issue with conditional logic when product drop down is used as a target. + + - Removed permissions check from low level GFFormsModel::delete_lead() - moved to page level. + - Removed the value and size attributes from the input tag for the "file" type since they are not supported and cause html validation errors. + - Removed permission checks from GFFormsModel::delete_form() and GFFormsModel::delete_leads_by_form() - moved to page level. + + - AF: Set trial amount to user entered value when trial option set to "Enter amount" for the Payment Add-On. + - AF: Added GFAPI::current_user_can_any() so developers can check permissions before calling any of the other API functions. + - AF: Added some logging for the Payment Add-On. + - AF: Added discounts to the order data for the Payment Add-On. + - AF: Added product options as a separate array to the line items array for the Payment Add-On. + - AF: Added is_shipping indicator to line items to distinguish between shipping field and regular product field for the Payment Add-On + - AF: Added name property to settings_setup_fee and settings_trial for the Payment Add-On. + + - AF: Added integration with the Logging Add-On - all add-ons now appear automatically on the settings page. + - AF: Fixed issue with validation failure icon not being displayed for all field types. + - AF: Fixed issue with checkbox validation. + + - API: Fixed an issue with GFAPI::add_entry() where the status was being ignored. + - API: Fixed an issue with GFAPI:get_entries() where the status was being ignored when sorting by a field value. + - API: Fixed issue with Web API GET entries ignoring is_numeric. + +------------------------------------------------------------------------------------------------------------------- +Version 1.8.5 + + - Added $field and $value parameters to 'gform_duplicate_message' filter. + - Added new hook: "gform_after_update_form_meta", fires any time form meta is updated. + + - Updated shortcode_atts() call in GFForms::parse_shortcode() method to pass 'gravityforms' as the third parameter so 3rd party developers can add/filter shortcode attributes. + + - Fixed Notice when adding a post category field to the form. + - Fixed issue with email notification format when using the {pricing_fields} merge tag. + - Fixed issue with conditional logic when the current number locale is set to decimal comma. + - Fixed issue with export where it was returning results inconsistent with entry list for checkbox items that have been re-ordered. + - Fixed issue where custom field types which posted values as arrays were set to null when filtering for HTML. + - Fixed issue with number format and conditional logic when number was configured with the comma as the decimal separator. + + - AF: Added is_object_locked(). + - AF: Added payment_callback table to track callbacks and prevent duplicate execution of them. + - AF: Added Donation as a dependency value for transaction type for the Payment Add-On. + - AF: Added function to set the onchange event for enabling a trial for the Payment Add-On. + - AF: Added support for a transaction id to be added to the transaction table for subscription recurring payments. + - AF: Added support for a subscription to be retrieved by a transaction id. + - AF: Added new styles for add-on results. + + - AF: Updated payment amount to have a default value of form_total for the Payment Add-On. + - AF: Updated the logic for showing/hiding trial fields for the Payment Add-On. + - AF: Updated radio button setting markup so that it is consistent with WordPress'. + - AF: Updated settings label code; moved it to its own function. + - AF: Updated is_json() method to accept "[" as a valid first character of a JSON string. + - AF: Updated build_choices() method to 'public' from 'protected'. + + - AF: Fixed notices in the Payment Add-On. + + - API: Fixed an issue with get_entries() where incorrect entries were being returned when searching across all forms using an entry meta key that is not currently active for any of the forms. + +------------------------------------------------------------------------------------------------------------------- +Version 1.8.4.1 + - Fixed issue with tooltips not working on Add On pages. Included font-awesome.css to Add On pages to fix the issue. + - Fixed issue where old inputs were not removed when adding new choices via bulk add functionality for Post Custom Fields with a "checkbox" field type + - Fixed an issue with entry export which may result in an empty export file for forms with a large number of entries + - AF: Added logging statements + - AF: Fixed issue with field map validation on fields that are hidden by dependency + - API: Added some logging statements + - API: Updated GFWebAPI::handle_page_request() to check the $HTTP_RAW_POST_DATA global variable before attempting to read the contents of the request body. + +------------------------------------------------------------------------------------------------------------------- +Version 1.8.4 + + - Added "gform_footer_init_scripts_filter" hook to support filtering the footer init scripts string + - Added support for custom wp-includes directory + + - Updated setup to run only in admin for single site installations and always on multisite + - Updated Google Font includes to be protocol-less + - Updated conditional logic to handle the "Other" choice for radio buttons + - Updated INACTIVE trim values setup script to ACTIVE. All leading and trailing spaces are now stripped from all previous entry values, field labels, choice texts, choice values, input labels and conditional logic rule values for fields, notifications and confirmations. + - Updated the form editor, form importer, notification editor and confirmation editor to trim leading and trailing spaces from all labels, choices values and conditional logic values on save/import + - Updated GFFormDisplay::print_form_scripts() to print all scripts at once rather than printing individually + - Updated GFFormsModel::update_lead_property() to return the result of the $wpdb->update() call + - Updated Credit Card field's Security Code input to use "type='text'" and "pattern='[0-9]*' when in HTML5 mode (rather than "type='number'") + - Updated location of gform_form_actions hook so that actions can be filtered when in the trash page + - Updated the entry search criteria to support times in the start_date and end_date + - Updated GFFormsModel::get_form to optionally allow returning a trashed form + + - Fixed issue with number field not properly formatting numbers on the entry edit page and on the individual field merge tag + - Fixed issue with export start and end dates + - Fixed issue with entry list trash view where entry row remains in the list after deleting when a fileupload field in the entry is empty + - Fixed issue with deleting entries on multisite installs where files uploaded using the fileupload field aren't deleted if the site ms_files_rewriting option is not set. This issue affects all new multisite installations of WordPress created after the release of WordPres 3.5. + - Fixed issue with number field configured with the 9.999,99 format displaying browser validation errors when HTML5 is enabled. + - Fixed issue with list field export where "Array" was being displayed under certain conditions. + - Fixed warning thrown in rewrite_rules function when using array_merge with a parameter that wasn't an array + - Fixed issue with dates used when exporting entries + - Fixed number field validation when currency format is specified. + - Fixed issue with how spaces in post image file names were being replaced. + - Fixed notices when Post Image field with enabled Title, Description, and/or Caption were submitted without values + - Fixed styling issue with checkboxes on entry notes + - Fixed number field input type + - Fixed JS error on form editor when user refreshes the page with the scrollbar lower than the top of the page + - Fixed left margin of conditional logic instructions when label position is set to left-aligned. + + - API: Added support for PUT entries/{entry ID}/properties so entry properties (is_read, is_starred etc) can be updated individually + - API: Added GFAPI::update_form_property() and GFAPI::update_forms_property() so form properties from the main forms table (is_trash, is_active etc) can be updated individually + - API: Added support for PUT forms/{form ID}/properties + - API: Added GFAPI::update_entry_property() to update a single property of an entry + - API: Updated the QR Code to include the site title + - API: Updated GFAPI::add_entry() to return an error if the entry object is not an array + - API: Fixed authentication for multisite installations + - API: Fixed loading of scripts on the API settings page when using SSL + - API: Fixed GFAPI::update_entry() to update the entry status + + - AF: Added support for "dynamic_field_map" field setting + - AF: Added icon support to form editor top toolbar + - AF: Added support for displaying an icon next to the form settings page title + - AF: Added support for displaying an icon next to the plugin settings page title + - AF: Added support for configuring a form settings page title (using first section as default) + - AF: Added support for configuring the "No items" message as well as forcing any message to be displayed in the feed list + - AF: Added support for "requires credit card" setting in the Payment Add-On to be used by payment gateways that require a credit card field on the form + - AF: Added replace_field() method to replace a field by name in a given $settings array + - AF: Added get_field() method to retrieve a field by name in a given $settings array + - AF: Updated get_feed() method to return false if no feed is found instead of a non-empty array + - AF: Updated get_payment_choices() from private to public + - AF: Updated the feed add-on feed_condition field to trim values before saving + - AF: Updated payment add-on to better handle different payment actions + - AF: Updated payment add-on get_webhook_url() to use simpler callback parameter + - AF: Updated default icon for the Results menu + - AF: Updated Payment Add-On default settings so that it is easier to add feed settings under the "Other" section + - AF: Updated field_map settings field type so that it is available from GFAddon instead of GFFeedAddOn + - AF: Fixed issue with subscription cancellation + - AF: Fixed results calculation loop to allow add-ons to add custom data to the field_data element. Fixes an issue with the Quiz Add-On correct/incorrect numbers for > 150 entries. + +------------------------------------------------------------------------------------------------------------------- +Version 1.8.3 + - Added new filter "gform_post_category_choices" to alter post category choices sort order. Both globally and form id + field id specific. + add_filter("gform_post_category_choices", "set_sort", 10, 3); + function set_sort($choices, $field, $form_id){ + //usort calls a custom sort function you create + usort($choices, "sort_numerically"); + return $choices; + } + function sort_numerically($a, $b){ + return floatval($a["text"]) > floatval($b["text"]); + } + OR + add_filter("gform_post_category_choices_390_1", "set_sort", 10, 3); + function set_sort($choices, $field, $form_id){ + //usort calls a custom sort function you create + usort($choices, "sort_numerically"); + return $choices; + } + function sort_numerically($a, $b){ + return floatval($a["text"]) > floatval($b["text"]); + } + - Added INACTIVE setup script to trim leading and trailing spaces from all entry values, field labels, choice texts, choice values and input labels. Uncomment line 503 to test. + - Updated GFFormDetail::add_field() to json_encode the field markup before sending it back to the form editor + - Updated GFCommon::calculate() to replace multiple spaces and new lines with a single space + - Updated the fileupload field to use the https protocol in links to file downloads when the entry detail and entry edit pages are using SSL + - Fixed issue with "No duplicates" option displaying on multi-select fields + - Fixed an issue with conditional logic failing and some fields not retaining values after validation and changing page with field choices having leading or trailing spaces. + - Fixed missing delete icon on the entry edit page. + - Fixed a PHP warning on form submission with unsaved imported forms with post fields. + - Fixed inconsistent permission allowing users to import forms without edit form permission. + - Fixed issue where empty fileupload fields were being displayed in the entry detail, entry print page and {all_fields] merge tag. + - Fixed intermittent fatal error calling get_plugins(). + - Fixed missing gform_pre_enqueue_scripts hook causing conflict with Picatcha. + - Fixed the gform_filters_get_users filter. + - Fixed missing ';' on gformInitCurrencyFormatFields() init script. + + - API: Updated GFWebAPI::end() to public static so it can be used by add-ons. + - API: Added gform_webapi_$METHOD_$COLLECTION and gform_webapi_$METHOD_$COLLECTION1_$COLLECTION2 actions. + - API: Removed gform_webapi_$METHOD_$COLLECTION and gform_webapi_$METHOD_$COLLECTION_$COLLECTION2 filters. + ------------------------------------------------------------------------------------------------------------------- Version 1.8.1 @@ -96,7 +359,7 @@ Version 1.8 - Updated the hierarchy indicator in the Post Category field from spaces to continuous lines - Updated the results page to display as a view of the gf_entries page so the gravityforms_view_entries capability is required instead of gravityforms_edit_forms (in addition to the gravityforms_{add-on}_results capability) - Updated the results page filter box from sticky (always visible) and fixed height to static and fluid height - - Updated form submission process to trim leading and trailing spaces before validation and before saving. Added the gform_trim_input_value filter to so it's possible to override this behaviour by field and by form. + - Updated form submission process to trim leading and trailing spaces before validation and before saving. Added the gform_trim_input_value filter so it's possible to override this behaviour by field and by form. - Updated calculation formula so that it is now trimmed in the form editor - Updated single product field. Removed Admin Label setting - Updated conditional logic for fields with choices to display dropdown values for "is" and "is not" operators and a textbox values for other operators @@ -409,7 +672,7 @@ Version 1.8.beta1 - Updated the hierarchy indicator in the Post Category field from spaces to continuous lines - Updated the results page to display as a view of the gf_entries page so the gravityforms_view_entries capability is required instead of gravityforms_edit_forms (in addition to the gravityforms_{add-on}_results capability) - Updated the results page filter box from sticky (always visible) and fixed height to static and fluid height - - Updated form submission process to trim leading and trailing spaces before validation and before saving. Added the gform_trim_input_value filter to so it's possible to override this behaviour by field and by form. + - Updated form submission process to trim leading and trailing spaces before validation and before saving. Added the gform_trim_input_value filter so it's possible to override this behaviour by field and by form. - Updated calculation formula so that it is now trimmed in the form editor - Updated single product field. Removed Admin Label setting - Updated conditional logic for fields with choices to display dropdown values for "is" and "is not" operators and a textbox values for other operators diff --git a/common.php b/common.php index c83321c..c31f86a 100644 --- a/common.php +++ b/common.php @@ -1,5863 +1,5983 @@ -" . $field_label . ""; - } - } - return $str; - } - - public static function is_numeric($value, $number_format=""){ - - switch($number_format){ - case "decimal_dot" : - return preg_match("/^(-?[0-9]{1,3}(?:,?[0-9]{3})*(?:\.[0-9]+)?)$/", $value); - break; - - case "decimal_comma" : - return preg_match("/^(-?[0-9]{1,3}(?:\.?[0-9]{3})*(?:,[0-9]+)?)$/", $value); - break; - - default : - return preg_match("/^(-?[0-9]{1,3}(?:,?[0-9]{3})*(?:\.[0-9]{2})?)$/", $value) || preg_match("/^(-?[0-9]{1,3}(?:\.?[0-9]{3})*(?:,[0-9]{2})?)$/", $value); - - } - } - - public static function trim_all($text){ - $text = trim($text); - do{ - $prev_text = $text; - $text = str_replace(" ", " ", $text); - } - while($text != $prev_text); - - return $text; - } - - public static function format_number($number, $number_format){ - if(!is_numeric($number)) - return $number; - - //replacing commas with dots and dots with commas - if($number_format == "currency"){ - if(false === class_exists('RGCurrency')){ - require_once( GFCommon::get_base_path() . '/currency.php' ); - } - $currency = new RGCurrency( GFCommon::get_currency() ); - $number = $currency->to_money( $number ); - } elseif ($number_format == "decimal_comma"){ - $number = str_replace(",", "|", $number); - $number = str_replace(".", ",", $number); - $number = str_replace("|", ".", $number); - } - - return $number; - } - - public static function recursive_add_index_file($dir) { - if(!is_dir($dir)) - return; - - if(!($dp = opendir($dir))) - return; - - //ignores all errors - set_error_handler(create_function("", "return 0;"), E_ALL); - - //creates an empty index.html file - if($f = fopen($dir . "/index.html", 'w')) - fclose($f); - - //restores error handler - restore_error_handler(); - - while((false !== $file = readdir($dp))){ - if(is_dir("$dir/$file") && $file != '.' && $file !='..') - self::recursive_add_index_file("$dir/$file"); - } - - closedir($dp); - } - - public static function clean_number($number, $number_format=""){ - if(rgblank($number)) - return $number; - - $decimal_char = ""; - if($number_format == "decimal_dot") - $decimal_char = "."; - else if($number_format == "decimal_comma") - $decimal_char = ","; - - $float_number = ""; - $clean_number = ""; - $is_negative = false; - - //Removing all non-numeric characters - $array = str_split($number); - foreach($array as $char){ - if (($char >= '0' && $char <= '9') || $char=="," || $char==".") - $clean_number .= $char; - else if($char == '-') - $is_negative = true; - } - - //Removing thousand separators but keeping decimal point - $array = str_split($clean_number); - for($i=0, $count = sizeof($array); $i<$count; $i++) - { - $char = $array[$i]; - if ($char >= '0' && $char <= '9') - $float_number .= $char; - else if(empty($decimal_char) && ($char == "." || $char == ",") && strlen($clean_number) - $i <= 3) - $float_number .= "."; - else if($decimal_char == $char) - $float_number .= "."; - } - - if($is_negative) - $float_number = "-" . $float_number; - - return $float_number; - - } - - public static function json_encode($value){ - return json_encode($value); - } - - public static function json_decode($str, $is_assoc=true){ - return json_decode($str, $is_assoc); - } - - //Returns the url of the plugin's root folder - public static function get_base_url(){ - return plugins_url( '', __FILE__ ); - } - - //Returns the physical path of the plugin's root folder - public static function get_base_path(){ - return dirname( __FILE__ ); - } - - public static function get_email_fields($form){ - $fields = array(); - foreach($form["fields"] as $field){ - if(RGForms::get("type", $field) == "email" || RGForms::get("inputType", $field) == "email") - $fields[] = $field; - } - - return $fields; - } - - public static function truncate_middle($text, $max_length){ - if(strlen($text) <= $max_length) - return $text; - - $middle = intval($max_length / 2); - return self::safe_substr($text, 0, $middle) . "..." . self::safe_substr($text, strlen($text) - $middle, $middle); - } - - 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_email($email){ - return preg_match('/^(([a-zA-Z0-9_.\-+!#$&\'*+=?^`{|}~])+\@((([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+|localhost) *,? *)+$/', $email); - } - - public static function get_label($field, $input_id = 0, $input_only = false){ - return RGFormsModel::get_label($field, $input_id, $input_only); - } - - public static function get_input($field, $id){ - return RGFormsModel::get_input($field, $id); - } - - public static function insert_variables($fields, $element_id, $hide_all_fields=false, $callback="", $onchange="", $max_label_size=40, $exclude = null, $args="", $class_name=""){ - - if($fields == null) - $fields = array(); - - if($exclude == null) - $exclude = array(); - - $exclude = apply_filters("gform_merge_tag_list_exclude", $exclude, $element_id, $fields); - $merge_tags = self::get_merge_tags($fields, $element_id, $hide_all_fields, $exclude, $args); - - $onchange = empty($onchange) ? "InsertVariable('{$element_id}', '{$callback}');" : $onchange; - $class = trim($class_name . " gform_merge_tags"); - - ?> - - - - '{all_fields}', 'label' => __('All Submitted Fields', 'gravityforms')); - - // group fields by required, optional, and pricing - foreach($fields as $field) { - - if(rgget("displayOnly", $field)) - continue; - - $input_type = RGFormsModel::get_input_type($field); - - // skip field types that should be excluded - if(is_array($exclude_field_types) && in_array($input_type, $exclude_field_types)) - continue; - - if(rgar($field, 'isRequired')) { - - switch($input_type) { - - case "name" : - - if(rgar($field,"nameFormat") == "extended") { - - $prefix = GFCommon::get_input($field, $field["id"] + 0.2); - $suffix = GFCommon::get_input($field, $field["id"] + 0.8); - $optional_field = $field; - $optional_field["inputs"] = array($prefix, $suffix); - - //Add optional name fields to the optional list - $optional_fields[] = $optional_field; - - //Remove optional name field from required list - unset($field["inputs"][0]); - unset($field["inputs"][3]); - - } - - $required_fields[] = $field; - - break; - - default: - $required_fields[] = $field; - } - } - else { - $optional_fields[] = $field; - } - - if(self::is_pricing_field($field["type"])){ - $pricing_fields[] = $field; - } - - } - - if(!empty($required_fields)){ - foreach($required_fields as $field){ - $required_group = array_merge($required_group, self::get_field_merge_tags($field, $option)); - } - } - - if(!empty($optional_fields)){ - foreach($optional_fields as $field){ - $optional_group = array_merge($optional_group, self::get_field_merge_tags($field, $option)); - } - } - - if(!empty($pricing_fields)){ - - if(!$hide_all_fields) - $pricing_group[] = array('tag' => '{pricing_fields}', 'label' => __("All Pricing Fields", "gravityforms")); - - foreach($pricing_fields as $field){ - $pricing_group = array_merge($pricing_group, self::get_field_merge_tags($field, $option)); - } - - } - - $other_group[] = array('tag' => '{ip}', 'label' => __("Client IP Address", "gravityforms")); - $other_group[] = array('tag' => '{date_mdy}', 'label' => __("Date", "gravityforms") . ' (mm/dd/yyyy)'); - $other_group[] = array('tag' => '{date_dmy}', 'label' => __("Date", "gravityforms") . ' (dd/mm/yyyy)'); - $other_group[] = array('tag' => '{embed_post:ID}', 'label' => __("Embed Post/Page Id", "gravityforms")); - $other_group[] = array('tag' => '{embed_post:post_title}', 'label' => __("Embed Post/Page Title", "gravityforms")); - $other_group[] = array('tag' => '{embed_url}', 'label' => __("Embed URL", "gravityforms")); - $other_group[] = array('tag' => '{entry_id}', 'label' => __("Entry Id", "gravityforms")); - $other_group[] = array('tag' => '{entry_url}', 'label' => __("Entry URL", "gravityforms")); - $other_group[] = array('tag' => '{form_id}', 'label' => __("Form Id", "gravityforms")); - $other_group[] = array('tag' => '{form_title}', 'label' => __("Form Title", "gravityforms")); - $other_group[] = array('tag' => '{user_agent}', 'label' => __("HTTP User Agent", "gravityforms")); - $other_group[] = array('tag' => '{referer}', 'label' => __("HTTP Referer URL", "gravityforms")); - - if(self::has_post_field($fields)) { - $other_group[] = array('tag' => '{post_id}', 'label' => __("Post Id", "gravityforms")); - $other_group[] = array('tag' => '{post_edit_url}', 'label' => __("Post Edit URL", "gravityforms")); - } - - $other_group[] = array('tag' => '{user:display_name}', 'label' => __("User Display Name", "gravityforms")); - $other_group[] = array('tag' => '{user:user_email}', 'label' => __("User Email", "gravityforms")); - $other_group[] = array('tag' => '{user:user_login}', 'label' => __("User Login", "gravityforms")); - - $custom_group = apply_filters('gform_custom_merge_tags', array(), rgars($fields, '0/formId'), $fields, $element_id); - - $merge_tags = array( - 'ungrouped' => array( - 'label' => false, - 'tags' => $ungrouped - ), - 'required' => array( - 'label' => __("Required form fields", "gravityforms"), - 'tags' => $required_group - ), - 'optional' => array( - 'label' => __("Optional form fields", "gravityforms"), - 'tags' => $optional_group - ), - 'pricing' => array( - 'label' => __("Pricing form fields", "gravityforms"), - 'tags' => $pricing_group - ), - 'other' => array( - 'label' => __("Other", "gravityforms"), - 'tags' => $other_group - ), - 'custom' => array( - 'label' => __("Custom", "gravityforms"), - 'tags' => $custom_group - ) - ); - - return $merge_tags; - } - - public static function get_field_merge_tags($field, $option="") { - - $merge_tags = array(); - $tag_args = RGFormsModel::get_input_type($field) == "list" ? ":{$option}" : ""; //args currently only supported by list field - - if(isset($field["inputs"]) && is_array($field["inputs"])) { - - if(RGFormsModel::get_input_type($field) == "checkbox") { - $value = "{" . esc_html(GFCommon::get_label($field, $field["id"])) . ":" . $field["id"] . "{$tag_args}}"; - $merge_tags[] = array( 'tag' => $value, 'label' => esc_html(GFCommon::get_label($field, $field["id"])) ); - } - - foreach($field["inputs"] as $input) { - $value = "{" . esc_html(GFCommon::get_label($field, $input["id"])) . ":" . $input["id"] . "{$tag_args}}"; - $merge_tags[] = array( 'tag' => $value, 'label' => esc_html(GFCommon::get_label($field, $input["id"])) ); - } - - } - else { - $value = "{" . esc_html(GFCommon::get_label($field)) . ":" . $field["id"] . "{$tag_args}}"; - $merge_tags[] = array( 'tag' => $value, 'label' => esc_html(GFCommon::get_label($field)) ); - } - - return $merge_tags; - } - - public static function insert_field_variable($field, $max_label_size=40, $args=""){ - - $tag_args = RGFormsModel::get_input_type($field) == "list" ? ":{$args}" : ""; //args currently only supported by list field - - if(is_array($field["inputs"])) - { - if(RGFormsModel::get_input_type($field) == "checkbox"){ - ?> - - - - - - -    - - - - - - post_title; - case "caption" : - $media = get_post($media_id); - return $media->post_excerpt; - case "description" : - $media = get_post($media_id); - return $media->post_content; - - default : - - $img = wp_get_attachment_image($media_id, $arg1, false, array("class" => "size-{$arg1} align{$arg2} wp-image-{$media_id}")); - return $img; - } - } - - public static function replace_variables_post_image($text, $post_images, $lead){ - - preg_match_all('/{[^{]*?:(\d+)(:([^:]*?))?(:([^:]*?))?(:url)?}/mi', $text, $matches, PREG_SET_ORDER); - if(is_array($matches)) - { - foreach($matches as $match){ - $input_id = $match[1]; - - //ignore fields that are not post images - if(!isset($post_images[$input_id])) - continue; - - //Reading alignment and "url" parameters. - //Format could be {image:5:medium:left:url} or {image:5:medium:url} - $size_meta = empty($match[3]) ? "full" : $match[3]; - $align = empty($match[5]) ? "none" : $match[5]; - if($align == "url"){ - $align = "none"; - $is_url = true; - } - else{ - $is_url = rgar($match,6) == ":url"; - } - - $media_id = $post_images[$input_id]; - $value = is_wp_error($media_id) ? "" : self::get_post_image_variable($media_id, $size_meta, $align, $is_url); - - $text = str_replace($match[0], $value , $text); - } - } - - return $text; - } - - public static function implode_non_blank($separator, $array){ - - if(!is_array($array)) - return ""; - - $ary = array(); - foreach($array as $item){ - if(!rgblank($item)) - $ary[] = $item; - } - return implode($separator, $ary); - } - - private static function format_variable_value($value, $url_encode, $esc_html, $format){ - if($esc_html) - $value = esc_html($value); - - if($format == "html") - $value = nl2br($value); - - if($url_encode) - $value = urlencode($value); - - return $value; - } - - public static function replace_variables($text, $form, $lead, $url_encode = false, $esc_html=true, $nl2br = true, $format="html"){ - $text = $nl2br ? nl2br($text) : $text; - - //Replacing field variables: {FIELD_LABEL:FIELD_ID} {My Field:2} - preg_match_all('/{[^{]*?:(\d+(\.\d+)?)(:(.*?))?}/mi', $text, $matches, PREG_SET_ORDER); - if(is_array($matches)) - { - foreach($matches as $match){ - $input_id = $match[1]; - - $field = RGFormsModel::get_field($form,$input_id); - - $value = RGFormsModel::get_lead_field_value($lead, $field); - $raw_value = $value; - - if(is_array($value)) - $value = rgar($value, $input_id); - - $value = self::format_variable_value($value, $url_encode, $esc_html, $format); - - switch(RGFormsModel::get_input_type($field)){ - - 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); - } - - break; - - case "post_image" : - list($url, $title, $caption, $description) = explode("|:|", $value); - $value = str_replace(" ", "%20", $url); - break; - - case "checkbox" : - case "select" : - case "radio" : - - $use_value = rgar($match,4) == "value"; - $use_price = in_array(rgar($match,4), array("price", "currency")); - $format_currency = rgar($match,4) == "currency"; - - if(is_array($raw_value) && (string)intval($input_id) != $input_id){ - $items = array($input_id => $value); //float input Ids. (i.e. 4.1 ). Used when targeting specific checkbox items - } - else if(is_array($raw_value)){ - $items = $raw_value; - } - else{ - $items = array($input_id => $raw_value); - } - - $ary = array(); - - foreach($items as $input_id => $item){ - if($use_value){ - list($val, $price) = rgexplode("|", $item, 2); - } - else if($use_price){ - list($name, $val) = rgexplode("|", $item, 2); - if($format_currency) - $val = GFCommon::to_money($val, rgar($lead, "currency")); - } - else if($field["type"] == "post_category"){ - $use_id = strtolower(rgar($match,4)) == "id"; - $item_value = self::format_post_category($item, $use_id); - - $val = RGFormsModel::is_field_hidden($form, $field, array(), $lead) ? "" : $item_value; - } - else{ - $val = RGFormsModel::is_field_hidden($form, $field, array(), $lead) ? "" : RGFormsModel::get_choice_text($field, $raw_value, $input_id); - } - - $ary[] = self::format_variable_value($val, $url_encode, $esc_html, $format); - } - - $value = self::implode_non_blank(", ", $ary); - - break; - - case "multiselect" : - if($field["type"] == "post_category"){ - $use_id = strtolower(rgar($match,4)) == "id"; - $items = explode(",", $value); - - if(is_array($items)){ - $cats = array(); - foreach($items as $item){ - $cat = self::format_post_category($item, $use_id); - $cats[] = self::format_variable_value($cat, $url_encode, $esc_html, $format); - } - $value = self::implode_non_blank(", ", $cats); - } - } - - break; - - case "date" : - $value = self::date_display($value, rgar($field,"dateFormat")); - break; - - case "total" : - $format_numeric = rgar($match,4) == "price"; - - $value = $format_numeric ? GFCommon::to_number($value) : GFCommon::to_money($value); - - $value = self::format_variable_value($value, $url_encode, $esc_html, $format); - break; - - case "post_category" : - $use_id = strtolower(rgar($match,4)) == "id"; - $value = self::format_post_category($value, $use_id); - $value = self::format_variable_value($value, $url_encode, $esc_html, $format); - break; - - case "list" : - $output_format = in_array(rgar($match,4), array("text", "html", "url")) ? rgar($match,4) : $format; - $value = self::get_lead_field_display($field, $raw_value, $lead["currency"], true, $output_format); - break; - } - - if(rgar($match,4) == "label"){ - $value = empty($value) ? "" : rgar($field, "label"); - } - else if(rgar($match,4) == "qty" && $field["type"] == "product"){ - //getting quantity associated with product field - $products = self::get_product_fields($form, $lead, false, false); - $value = 0; - foreach($products["products"] as $product_id => $product) - { - if($product_id == $field["id"]) - $value = $product["quantity"]; - } - } - - //Encoding left curly bracket so that merge tags entered in the front end are displayed as is and not "executed" - $value = self::encode_merge_tag($value); - - //filter can change merge code variable - $value = apply_filters("gform_merge_tag_filter", $value, $input_id, rgar($match,4), $field, $raw_value); - if($value === false) - $value = ""; - - $text = str_replace($match[0], $value , $text); - } - } - - //replacing global variables - //form title - $text = str_replace("{form_title}", $url_encode ? urlencode($form["title"]) : $form["title"], $text); - - $matches = array(); - preg_match_all("/{all_fields(:(.*?))?}/", $text, $matches, PREG_SET_ORDER); - foreach($matches as $match){ - $options = explode(",", rgar($match,2)); - $use_value = in_array("value", $options); - $display_empty = in_array("empty", $options); - $use_admin_label = in_array("admin", $options); - - //all submitted fields using text - if (strpos($text, $match[0]) !== false){ - $text = str_replace($match[0], self::get_submitted_fields($form, $lead, $display_empty, !$use_value, $format, $use_admin_label, "all_fields", rgar($match,2)), $text); - } - } - - //all submitted fields including empty fields - if (strpos($text, "{all_fields_display_empty}") !== false){ - $text = str_replace("{all_fields_display_empty}", self::get_submitted_fields($form, $lead, true, true, $format, false, "all_fields_display_empty"), $text); - } - - //pricing fields - if (strpos($text, "{pricing_fields}") !== false){ - $text = str_replace("{pricing_fields}", self::get_submitted_pricing_fields($form, $lead, $format), $text); - } - - //form id - $text = str_replace("{form_id}", $url_encode ? urlencode($form["id"]) : $form["id"], $text); - - //entry id - $text = str_replace("{entry_id}", $url_encode ? urlencode(rgar($lead, "id")) : rgar($lead, "id"), $text); - - //entry url - $entry_url = get_bloginfo("wpurl") . "/wp-admin/admin.php?page=gf_entries&view=entry&id=" . $form["id"] . "&lid=" . rgar($lead,"id"); - $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); - - //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"]; - $text = str_replace("{post_edit_url}", $url_encode ? urlencode($post_url) : $post_url, $text); - - $text = self::replace_variables_prepopulate($text, $url_encode); - - // hook allows for custom merge tags - $text = apply_filters('gform_replace_merge_tags', $text, $form, $lead, $url_encode, $esc_html, $nl2br, $format); - - // TODO: Deprecate the 'gform_replace_merge_tags' and replace it with a call to the 'gform_merge_tag_filter' - //$text = apply_filters('gform_merge_tag_filter', $text, false, false, false ); - - $text = self::decode_merge_tag($text); - return $text; - } - - public static function encode_merge_tag($text){ - return str_replace("{", "{", $text); - } - - public static function decode_merge_tag($text){ - return str_replace("{", "{", $text); - } - - public static function format_post_category($value, $use_id){ - - list($item_value, $item_id) = rgexplode(":", $value, 2); - - if($use_id && !empty($item_id)) - $item_value = $item_id; - - return $item_value; - } - - public static function get_embed_post(){ - global $embed_post, $post, $wp_query; - - if($embed_post){ - return $embed_post; - } - - if(!rgempty("gform_embed_post")){ - $post_id = absint(rgpost("gform_embed_post")); - $embed_post = get_post($post_id); - } - else if($wp_query->is_in_loop){ - $embed_post = $post; - } - else{ - $embed_post = array(); - } - } - - public static function replace_variables_prepopulate($text, $url_encode=false){ - - //embed url - $text = str_replace("{embed_url}", $url_encode ? urlencode(RGFormsModel::get_current_page_url()) : RGFormsModel::get_current_page_url(), $text); - - $local_timestamp = self::get_local_timestamp(time()); - - //date (mm/dd/yyyy) - $local_date_mdy = date_i18n("m/d/Y", $local_timestamp, true); - $text = str_replace("{date_mdy}", $url_encode ? urlencode($local_date_mdy) : $local_date_mdy, $text); - - //date (dd/mm/yyyy) - $local_date_dmy = date_i18n("d/m/Y", $local_timestamp, true); - $text = str_replace("{date_dmy}", $url_encode ? urlencode($local_date_dmy) : $local_date_dmy, $text); - - // ip - $ip = GFFormsModel::get_ip(); - $text = str_replace( '{ip}', $url_encode ? urlencode( $ip ) : $ip, $text ); - - global $post; - $post_array = self::object_to_array($post); - preg_match_all("/\{embed_post:(.*?)\}/", $text, $matches, PREG_SET_ORDER); - foreach($matches as $match){ - $full_tag = $match[0]; - $property = $match[1]; - $text = str_replace($full_tag, $url_encode ? urlencode($post_array[$property]) : $post_array[$property], $text); - } - - //embed post custom fields - preg_match_all("/\{custom_field:(.*?)\}/", $text, $matches, PREG_SET_ORDER); - foreach($matches as $match){ - - $full_tag = $match[0]; - $custom_field_name = $match[1]; - $custom_field_value = !empty($post_array["ID"]) ? get_post_meta($post_array["ID"], $custom_field_name, true) : ""; - $text = str_replace($full_tag, $url_encode ? urlencode($custom_field_value) : $custom_field_value, $text); - } - - //user agent - $text = str_replace("{user_agent}", $url_encode ? urlencode(RGForms::get("HTTP_USER_AGENT", $_SERVER)) : RGForms::get("HTTP_USER_AGENT", $_SERVER), $text); - - //referrer - $text = str_replace("{referer}", $url_encode ? urlencode(RGForms::get("HTTP_REFERER", $_SERVER)) : RGForms::get("HTTP_REFERER", $_SERVER), $text); - - //logged in user info - global $userdata, $wp_version, $current_user; - $user_array = self::object_to_array($userdata); - - preg_match_all("/\{user:(.*?)\}/", $text, $matches, PREG_SET_ORDER); - foreach($matches as $match){ - $full_tag = $match[0]; - $property = $match[1]; - - $value = version_compare($wp_version, '3.3', '>=') ? $current_user->get($property) : $user_array[$property]; - $value = $url_encode ? urlencode($value) : $value; - - $text = str_replace($full_tag, $value, $text); - } - - return $text; - } - - public static function object_to_array($object){ - $array=array(); - if(!empty($object)){ - foreach($object as $member=>$data) - $array[$member]=$data; - } - return $array; - } - - public static function is_empty_array($val){ - if(!is_array($val)) - $val = array($val); - - $ary = array_values($val); - foreach($ary as $item){ - if(!rgblank($item)) - return false; - } - return true; - } - - public static function get_submitted_fields($form, $lead, $display_empty=false, $use_text=false, $format="html", $use_admin_label=false, $merge_tag="", $options=""){ - - $field_data = ""; - if($format == "html"){ - $field_data = ' - -
- - '; - } - - $options_array = explode(",", $options); - $no_admin = in_array("noadmin", $options_array); - $no_hidden = in_array("nohidden", $options_array); - $has_product_fields = false; - foreach($form["fields"] as $field){ - $field_value = ""; - - $field_label = $use_admin_label && !rgempty("adminLabel", $field) ? rgar($field, "adminLabel") : esc_html(GFCommon::get_label($field)); - - switch($field["type"]){ - case "captcha" : - break; - - case "section" : - if((!GFCommon::is_section_empty($field, $form, $lead) || $display_empty) && !rgar($field, "adminOnly")){ - - switch($format){ - case "text" : - $field_value = "--------------------------------\n{$field_label}\n\n"; - break; - - default: - $field_value = sprintf(' - - - ', $field_label); - break; - } - } - - $field_value = apply_filters("gform_merge_tag_filter", $field_value, $merge_tag, $options, $field, $field_label); - - $field_data .= $field_value; - - break; - case "password" : - //ignore password fields - break; - - default : - - //ignore product fields as they will be grouped together at the end of the grid - if(self::is_product_field($field["type"])){ - $has_product_fields = true; - continue; - } - else if(RGFormsModel::is_field_hidden($form, $field, array(), $lead)){ - //ignore fields hidden by conditional logic - continue; - } - - $raw_field_value = RGFormsModel::get_lead_field_value($lead, $field); - $field_value = GFCommon::get_lead_field_display($field, $raw_field_value, rgar($lead,"currency"), $use_text, $format, "email"); - - $display_field = true; - //depending on parameters, don't display adminOnly or hidden fields - if($no_admin && rgar($field, "adminOnly")) - $display_field = false; - else if($no_hidden && RGFormsModel::get_input_type($field) == "hidden") - $display_field = false; - - //if field is not supposed to be displayed, pass false to filter. otherwise, pass field's value - if(!$display_field) - $field_value = false; - - $field_value = apply_filters("gform_merge_tag_filter", $field_value, $merge_tag, $options, $field, $raw_field_value); - - if($field_value === false) - continue; - - if( !empty($field_value) || strlen($field_value) > 0 || $display_empty){ - switch($format){ - case "text" : - $field_data .= "{$field_label}: {$field_value}\n\n"; - break; - - default: - - $field_data .= sprintf(' - - - - - - - ', $field_label, empty($field_value) && strlen($field_value) == 0 ? " " : $field_value); - break; - } - } - } - } - - if($has_product_fields) - $field_data .= self::get_submitted_pricing_fields($form, $lead, $format, $use_text, $use_admin_label); - - if($format == "html"){ - $field_data .='
%s
- %s -
  - %s -
-
'; - } - - return $field_data; - } - - public static function get_submitted_pricing_fields($form, $lead, $format, $use_text=true, $use_admin_label=false){ - $form_id = $form["id"]; - $order_label = apply_filters("gform_order_label_{$form["id"]}", apply_filters("gform_order_label", __("Order", "gravityforms"), $form["id"]), $form["id"]); - $products = GFCommon::get_product_fields($form, $lead, $use_text, $use_admin_label); - $total = 0; - $field_data = ""; - - switch($format){ - case "text" : - if(!empty($products["products"])){ - $field_data = "--------------------------------\n" . $order_label . "\n\n"; - foreach($products["products"] as $product){ - $product_name = $product["quantity"] . " " . $product["name"]; - $price = self::to_number($product["price"]); - if(!empty($product["options"])){ - $product_name .= " ("; - $options = array(); - foreach($product["options"] as $option){ - $price += self::to_number($option["price"]); - $options[] = $option["option_name"]; - } - $product_name .= implode(", ", $options) . ")"; - } - $subtotal = floatval($product["quantity"]) * $price; - $total += $subtotal; - - $field_data .= "{$product_name}: " . self::to_money($subtotal, $lead["currency"]) . "\n\n"; - } - $total += floatval($products["shipping"]["price"]); - - if(!empty($products["shipping"]["name"])) - $field_data .= $products["shipping"]["name"] . ": " . self::to_money($products["shipping"]["price"], $lead["currency"]) . "\n\n"; - - $field_data .= __("Total", "gravityforms") . ": " . self::to_money($total, $lead["currency"]) . "\n\n"; - } - break; - - - default : - if(!empty($products["products"])){ - $field_data =' - - ' . $order_label . ' - - - -   - - - - - - - - - '; - - - foreach($products["products"] as $product){ - - $field_data .= ' - - - - - '; - } - $total += floatval($products["shipping"]["price"]); - $field_data .= ' - '; - - if(!empty($products["shipping"]["name"])){ - $field_data .= ' - - - - - - '; - } - - $field_data .= ' - '; - - if(empty($products["shipping"]["name"])){ - $field_data .= ' - '; - } - - $field_data .= ' - - - - -
' . apply_filters("gform_product_{$form_id}", apply_filters("gform_product", __("Product", "gravityforms"), $form_id), $form_id) . '' . apply_filters("gform_product_qty_{$form_id}", apply_filters("gform_product_qty", __("Qty", "gravityforms"), $form_id), $form_id) . '' . apply_filters("gform_product_unitprice_{$form_id}", apply_filters("gform_product_unitprice", __("Unit Price", "gravityforms"), $form_id), $form_id) . '' . apply_filters("gform_product_price_{$form_id}", apply_filters("gform_product_price", __("Price", "gravityforms"), $form_id), $form_id) . '
- ' . $product["name"] .' -
    '; - - $price = self::to_number($product["price"]); - if(is_array(rgar($product,"options"))){ - foreach($product["options"] as $option){ - $price += self::to_number($option["price"]); - $field_data .= '
  • ' . $option["option_label"] .'
  • '; - } - } - $subtotal = floatval($product["quantity"]) * $price; - $total += $subtotal; - - $field_data .='
-
' . $product["quantity"] .'' . self::to_money($price, $lead["currency"]) .'' . self::to_money($subtotal, $lead["currency"]) .'
 ' . $products["shipping"]["name"] . ''. self::to_money($products["shipping"]["price"], $lead["currency"]) . '
 ' . __("Total:", "gravityforms") . ''. self::to_money($total, $lead["currency"]) . '
- - '; - } - break; - } - - return $field_data; - } - - public static function send_user_notification($form, $lead, $override_options = false){ - _deprecated_function("send_user_notification", "1.7", "send_notification"); - - $notification = self::prepare_user_notification($form, $lead, $override_options); - self::send_email($notification["from"], $notification["to"], $notification["bcc"], $notification["reply_to"], $notification["subject"], $notification["message"], $notification["from_name"], $notification["message_format"], $notification["attachments"]); - } - - public static function send_admin_notification($form, $lead, $override_options = false){ - _deprecated_function("send_admin_notification", "1.7", "send_notification"); - - $notification = self::prepare_admin_notification($form, $lead, $override_options); - self::send_email($notification["from"], $notification["to"], $notification["bcc"], $notification["replyTo"], $notification["subject"], $notification["message"], $notification["from_name"], $notification["message_format"], $notification["attachments"]); - } - - private static function prepare_user_notification($form, $lead, $override_options = false){ - $form_id = $form["id"]; - - if(!isset($form["autoResponder"])) - return; - - //handling autoresponder email - $to_field = isset($form["autoResponder"]["toField"]) ? rgget($form["autoResponder"]["toField"], $lead) : ""; - $to = apply_filters("gform_autoresponder_email_{$form_id}", apply_filters("gform_autoresponder_email", $to_field, $form), $form); - $subject = GFCommon::replace_variables(rgget("subject", $form["autoResponder"]), $form, $lead, false, false); - - $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); - - //Running trough variable replacement - $to = GFCommon::replace_variables($to, $form, $lead, false, false); - $from = GFCommon::replace_variables(rgget("from", $form["autoResponder"]), $form, $lead, false, false); - $bcc = GFCommon::replace_variables(rgget("bcc", $form["autoResponder"]), $form, $lead, false, false); - $reply_to = GFCommon::replace_variables(rgget("replyTo", $form["autoResponder"]), $form, $lead, false, false); - $from_name = GFCommon::replace_variables(rgget("fromName", $form["autoResponder"]), $form, $lead, false, false); - - // override default values if override options provided - if($override_options && is_array($override_options)){ - foreach($override_options as $override_key => $override_value){ - ${$override_key} = $override_value; - } - } - - $attachments = apply_filters("gform_user_notification_attachments_{$form_id}", apply_filters("gform_user_notification_attachments", array(), $lead, $form), $lead, $form); - - //Disabling autoformat to prevent double autoformatting of messages - $disableAutoformat = "1"; - - return compact("to", "from", "bcc", "reply_to", "subject", "message", "from_name", "message_format", "attachments", "disableAutoformat"); - } - - private static function prepare_admin_notification($form, $lead, $override_options = false){ - $form_id = $form["id"]; - - //handling admin notification email - $subject = GFCommon::replace_variables(rgget("subject", $form["notification"]), $form, $lead, false, false); - - $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); - - $version_info = self::get_version_info(); - $is_expired = !rgempty("expiration_time", $version_info) && $version_info["expiration_time"] < time(); - if( !rgar($version_info, "is_valid_key") && $is_expired){ - $message .= "

Your Gravity Forms License Key has expired. In order to continue receiving support and software updates you must renew your license key. You can do so by following the renewal instructions on the Gravity Forms Settings page in your WordPress Dashboard or by clicking here."; - } - - $from = rgempty("fromField", $form["notification"]) ? rgget("from", $form["notification"]) : rgget($form["notification"]["fromField"], $lead); - - if(rgempty("fromNameField", $form["notification"])){ - $from_name = rgget("fromName", $form["notification"]); - } - else{ - $field = RGFormsModel::get_field($form, rgget("fromNameField", $form["notification"])); - $value = RGFormsModel::get_lead_field_value($lead, $field); - $from_name = GFCommon::get_lead_field_display($field, $value); - } - - $replyTo = rgempty("replyToField", $form["notification"]) ? rgget("replyTo", $form["notification"]): rgget($form["notification"]["replyToField"], $lead); - - if(rgempty("routing", $form["notification"])){ - $email_to = rgempty("toField", $form["notification"]) ? rgget("to", $form["notification"]) : rgget("toField", $form["notification"]); - } - else{ - $email_to = array(); - foreach($form["notification"]["routing"] as $routing){ - - $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); - - if ($is_value_match) - $email_to[] = $routing["email"]; - } - - $email_to = join(",", $email_to); - } - - //Running through variable replacement - $email_to = GFCommon::replace_variables($email_to, $form, $lead, false, false); - $from = GFCommon::replace_variables($from, $form, $lead, false, false); - $bcc = GFCommon::replace_variables(rgget("bcc", $form["notification"]), $form, $lead, false, false); - $reply_to = GFCommon::replace_variables($replyTo, $form, $lead, false, false); - $from_name = GFCommon::replace_variables($from_name, $form, $lead, false, false); - - //Filters the admin notification email to address. Allows users to change email address before notification is sent - $to = apply_filters("gform_notification_email_{$form_id}" , apply_filters("gform_notification_email", $email_to, $lead), $lead); - - // override default values if override options provided - if($override_options && is_array($override_options)){ - foreach($override_options as $override_key => $override_value){ - ${$override_key} = $override_value; - } - } - - $attachments = apply_filters("gform_admin_notification_attachments_{$form_id}", apply_filters("gform_admin_notification_attachments", array(), $lead, $form), $lead, $form); - - //Disabling autoformat to prevent double autoformatting of messages - $disableAutoformat = "1"; - - return compact("to", "from", "bcc", "replyTo", "subject", "message", "from_name", "message_format", "attachments", "disableAutoformat"); - - } - - public static function send_notification($notification, $form, $lead){ - - $notification = apply_filters("gform_notification_{$form["id"]}", apply_filters("gform_notification", $notification, $form, $lead), $form, $lead); - - $to_field = ""; - if(rgar($notification, "toType") == "field"){ - $to_field = rgar($notification, "toField"); - if(rgempty("toField", $notification)){ - $to_field = rgar($notification, "to"); - } - } - - $email_to = rgar($notification, "to"); - //do routing logic if "to" field doesn't have a value (to support legacy notifications what will run routing prior to this method - if(empty($email_to) && rgar($notification, "toType") == "routing"){ - $email_to = array(); - foreach($notification["routing"] as $routing){ - - $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); - - if ($is_value_match) - $email_to[] = $routing["email"]; - } - - $email_to = join(",", $email_to); - } - else if (!empty($to_field)) { - $source_field = RGFormsModel::get_field($form, $to_field); - $email_to = RGFormsModel::get_lead_field_value($lead, $source_field); - } - - //Running through variable replacement - $to = GFCommon::replace_variables($email_to, $form, $lead, false, false); - $subject = GFCommon::replace_variables(rgar($notification, "subject"), $form, $lead, false, false); - $from = GFCommon::replace_variables(rgar($notification, "from"), $form, $lead, false, false); - $from_name = GFCommon::replace_variables(rgar($notification, "fromName"), $form, $lead, false, false); - $bcc = GFCommon::replace_variables(rgar($notification, "bcc"), $form, $lead, false, false); - $replyTo = GFCommon::replace_variables(rgar($notification, "replyTo"), $form, $lead, false, false); - - $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); - - // 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" ); - if( !empty( $attachments ) ) { - $attachments = is_array( $attachments ) ? $attachments : array( $attachments ); - } else { - $attachments = array(); - } - - self::send_email($from, $to, $bcc, $replyTo, $subject, $message, $from_name, $message_format, $attachments); - - return compact("to", "from", "bcc", "replyTo", "subject", "message", "from_name", "message_format", "attachments"); - - } - - public static function send_notifications($notification_ids, $form, $lead, $do_conditional_logic = true, $event = "form_submission"){ - if(!is_array($notification_ids)){ - return; - } - - foreach($notification_ids as $notification_id){ - if(!isset($form["notifications"][$notification_id])){ - continue; - } - if(isset($form["notifications"][$notification_id]["isActive"]) && ! $form["notifications"][$notification_id]["isActive"]){ - continue; - } - - $notification = $form["notifications"][$notification_id]; - - //check conditional logic when appropriate - if($do_conditional_logic && !GFCommon::evaluate_conditional_logic( rgar($notification,"conditionalLogic"), $form, $lead) ){ - continue; - } - - if(rgar($notification,"type") == "user"){ - - //Getting user notification from legacy structure (for backwards compatibility) - $legacy_notification = GFCommon::prepare_user_notification($form, $lead); - $notification = self::merge_legacy_notification($notification, $legacy_notification); - } - else if(rgar($notification,"type") == "admin"){ - - //Getting admin notification from legacy structure (for backwards compatibility) - $legacy_notification = GFCommon::prepare_admin_notification($form, $lead); - $notification = self::merge_legacy_notification($notification, $legacy_notification); - } - - - //sending notification - self::send_notification($notification, $form, $lead); - } - } - - public static function send_form_submission_notifications($form, $lead){ - $notifications = self::get_notifications_to_send("form_submission", $form, $lead); - $notifications_to_send = array(); - - //running through filters that disable form submission notifications - foreach($notifications as $notification){ - - if(rgar($notification,"type") == "user" && apply_filters("gform_disable_user_notification_{$form["id"]}", apply_filters("gform_disable_user_notification", false, $form, $lead), $form, $lead)){ - //skip user notification if it has been disabled by a hook - continue; - } - else if(rgar($notification,"type") == "admin" && apply_filters("gform_disable_admin_notification_{$form["id"]}", apply_filters("gform_disable_admin_notification", false, $form, $lead), $form, $lead)){ - //skip admin notification if it has been disabled by a hook - continue; - } - - if(apply_filters("gform_disable_notification_{$form["id"]}", apply_filters("gform_disable_notification", false, $notification, $form, $lead), $notification, $form, $lead)){ - //skip notifications if it has been disabled by a hook - continue; - } - - $notifications_to_send[] = $notification["id"]; - } - - self::send_notifications($notifications_to_send, $form, $lead, true, "form_submission"); - } - - private static function merge_legacy_notification($notification, $notification_data){ - - $keys = array("to", "from", "bcc", "replyTo", "subject", "message", "from_name", "message_format", "attachments", "disableAutoformat"); - foreach($keys as $key) - $notification[$key] = rgar($notification_data,$key); - - return $notification; - } - - public static function get_notifications_to_send($action, $form, $lead){ - $notifications = self::get_notifications($action, $form); - $notifications_to_send = array(); - foreach($notifications as $notification){ - if(GFCommon::evaluate_conditional_logic(rgar($notification,"conditionalLogic"), $form, $lead)){ - $notifications_to_send[] = $notification; - } - } - - return $notifications_to_send; - } - - public static function get_notifications($action, $form){ - if(rgempty("notifications", $form)) - return array(); - - $notifications = array(); - foreach($form["notifications"] as $notification){ - if(rgar($notification, "event") == $action) - $notifications[] = $notification; - } - - return $notifications; - } - - public static function has_admin_notification($form){ - - return (!empty($form["notification"]["to"]) || !empty($form["notification"]["routing"])) && (!empty($form["notification"]["subject"]) || !empty($form["notification"]["message"])); - - } - - public static function has_user_notification($form){ - - return !empty($form["autoResponder"]["toField"]) && (!empty($form["autoResponder"]["subject"]) || !empty($form["autoResponder"]["message"])); - - } - - 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); - - //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"); - - //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)); - return; - } - - $content_type = $message_format == "html" ? "text/html" : "text/plain"; - - $name = empty($from_name) ? $from : $from_name; - - $headers = array(); - $headers["From"] = "From: \"{$name}\" <{$from}>"; - - if(GFCommon::is_valid_email($reply_to)) - $headers["Reply-To"] = "Reply-To: {$reply_to}"; - - if(GFCommon::is_valid_email($bcc)) - $headers["Bcc"] = "Bcc: $bcc"; - - $headers["Content-type"] = "Content-type: {$content_type}; charset=" . get_option('blog_charset'); - - $abort_email = false; - extract(apply_filters("gform_pre_send_email", compact("to", "subject", "message", "headers", "attachments", "abort_email"), $message_format)); - - $is_success = false; - if(!$abort_email){ - GFCommon::log_debug("Sending email via wp_mail()"); - GFCommon::log_debug(print_r(compact("to", "subject", "message", "headers", "attachments", "abort_email"), true)); - $is_success = wp_mail($to, $subject, $message, $headers, $attachments); - GFCommon::log_debug("Result from wp_mail(): {$is_success}"); - } - - self::add_emails_sent(); - - do_action("gform_after_email", $is_success, $to, $subject, $message, $headers, $attachments, $message_format); - } - - public static function add_emails_sent(){ - - $count = self::get_emails_sent(); - - update_option("gform_email_count", ++$count); - - } - - public static function get_emails_sent(){ - $count = get_option("gform_email_count"); - - if(!$count) - $count = 0; - - return $count; - } - - public static function get_api_calls(){ - $count = get_option("gform_api_count"); - - if(!$count) - $count = 0; - - return $count; - } - - public static function add_api_call(){ - - $count = self::get_api_calls(); - - update_option("gform_api_count", ++$count); - - } - - public static function has_post_field($fields){ - foreach($fields as $field){ - if(in_array($field["type"], array("post_title", "post_content", "post_excerpt", "post_category", "post_image", "post_tags", "post_custom_field"))) - return true; - } - return false; - } - - public static function has_list_field($form){ - return self::has_field_by_type($form, 'list'); - } - - public static function has_credit_card_field($form){ - return self::has_field_by_type($form, 'creditcard'); - } - - private static function has_field_by_type($form, $type) { - if(is_array($form["fields"])){ - foreach($form["fields"] as $field){ - - if(RGFormsModel::get_input_type($field) == $type) - return true; - } - } - return false; - } - - public static function current_user_can_any($caps){ - - if(!is_array($caps)){ - $has_cap = current_user_can($caps) || current_user_can("gform_full_access"); - return $has_cap; - } - - foreach($caps as $cap){ - if(current_user_can($cap)){ - return true; - } - } - - $has_full_access = current_user_can("gform_full_access"); - return $has_full_access; - } - - public static function current_user_can_which($caps){ - - foreach($caps as $cap){ - if(current_user_can($cap)) - return $cap; - } - - return ""; - } - - public static function is_pricing_field($field_type){ - return self::is_product_field($field_type) || $field_type == "donation"; - } - - public static function is_product_field($field_type){ - return in_array($field_type, array("option", "quantity", "product", "total", "shipping", "calculation")); - } - - public static function all_caps(){ - return array( 'gravityforms_edit_forms', - 'gravityforms_delete_forms', - 'gravityforms_create_form', - 'gravityforms_view_entries', - 'gravityforms_edit_entries', - 'gravityforms_delete_entries', - 'gravityforms_view_settings', - 'gravityforms_edit_settings', - 'gravityforms_export_entries', - 'gravityforms_uninstall', - 'gravityforms_view_entry_notes', - 'gravityforms_edit_entry_notes', - 'gravityforms_view_updates', - 'gravityforms_view_addons', - 'gravityforms_preview_forms' - ); - } - - public static function delete_directory($dir) { - if(!file_exists($dir)) - return; - - if ($handle = opendir($dir)){ - $array = array(); - while (false !== ($file = readdir($handle))) { - if ($file != "." && $file != "..") { - if(is_dir($dir.$file)){ - if(!@rmdir($dir.$file)) // Empty directory? Remove it - self::delete_directory($dir.$file.'/'); // Not empty? Delete the files inside it - } - else{ - @unlink($dir.$file); - } - } - } - closedir($handle); - @rmdir($dir); - } - } - - public static function get_remote_message(){ - return stripslashes(get_option("rg_gforms_message")); - } - - public static function get_key(){ - return get_option("rg_gforms_key"); - } - - public static function has_update($use_cache=true){ - $version_info = GFCommon::get_version_info($use_cache); - $version = rgar($version_info, "version"); - return empty($version) ? false : version_compare(GFCommon::$version, $version, '<'); - } - - public static function get_key_info($key){ - - $options = array('method' => 'POST', 'timeout' => 3); - $options['headers'] = array( - 'Content-Type' => 'application/x-www-form-urlencoded; charset=' . get_option('blog_charset'), - 'User-Agent' => 'WordPress/' . get_bloginfo("version"), - 'Referer' => get_bloginfo("url") - ); - $request_url = GRAVITY_MANAGER_URL . "/api.php?op=get_key&key={$key}"; - $raw_response = wp_remote_request($request_url, $options); - if ( is_wp_error( $raw_response ) || $raw_response['response']['code'] != 200) - return array(); - - $key_info = unserialize(trim($raw_response["body"])); - return $key_info ? $key_info : array(); - } - - public static function get_version_info($cache=true){ - - $raw_response = get_transient("gform_update_info"); - if(!$cache) - $raw_response = null; - - if(!$raw_response){ - //Getting version number - $options = array('method' => 'POST', 'timeout' => 20); - $options['headers'] = array( - 'Content-Type' => 'application/x-www-form-urlencoded; charset=' . get_option('blog_charset'), - 'User-Agent' => 'WordPress/' . get_bloginfo("version"), - 'Referer' => get_bloginfo("url") - ); - $options['body'] = self::get_remote_post_params(); - $options['timeout'] = 15; - - $nocache = $cache ? "" : "?nocache=1"; //disabling server side caching - $request_url = GRAVITY_MANAGER_URL . "/version.php{$nocache}"; - - $raw_response = wp_remote_request($request_url, $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 ) - return array("is_valid_key" => "1", "version" => "", "url" => "", "is_error" => "1"); - - $version_info = json_decode($raw_response['body'], true); - - if( empty($version_info) ) - return array("is_valid_key" => "1", "version" => "", "url" => "", "is_error" => "1"); - - return $version_info; - } - - public static function get_remote_request_params(){ - global $wpdb; - - return sprintf("of=GravityForms&key=%s&v=%s&wp=%s&php=%s&mysql=%s&version=2", urlencode(self::get_key()), urlencode(self::$version), urlencode(get_bloginfo("version")), urlencode(phpversion()), urlencode($wpdb->db_version())); - } - - public static function get_remote_post_params(){ - global $wpdb; - $plugin_list = get_plugins(); - $site_url = get_bloginfo("url"); - $plugins = array(); - - $active_plugins = get_option( 'active_plugins' ); - - foreach ($plugin_list as $key => $plugin) { - $is_active = in_array($key, $active_plugins); - - //filter for only gravityforms ones, may get some others if using our naming convention - if (strpos(strtolower($plugin["Title"]), "gravity forms") !== false){ - $name = substr($key, 0, strpos($key,"/")); - $plugins[] = array("name" => $name, "version" => $plugin["Version"], "is_active" => $is_active); - } - } - $plugins = json_encode($plugins); - - //get theme info - $theme = wp_get_theme(); - $theme_name = $theme->get("Name"); - $theme_uri = $theme->get("ThemeURI"); - $theme_version = $theme->get("Version"); - $theme_author = $theme->get("Author"); - $theme_author_uri = $theme->get("AuthorURI"); - - $form_counts = GFFormsModel::get_form_count(); - $active_count = $form_counts["active"]; - $inactive_count = $form_counts["inactive"]; - $fc = abs($active_count) + abs($inactive_count); - $entry_count = GFFormsModel::get_lead_count_all_forms("active"); - $im = is_multisite(); - - $post = array("of" => "gravityforms", "key" => self::get_key(), "v" => self::$version, "wp" => get_bloginfo("version"), "php" => phpversion(), "mysql" => $wpdb->db_version(), "version" => "2", "plugins" => $plugins, "tn" => $theme_name, "tu" => $theme_uri, "tv" => $theme_version, "ta" => $theme_author, "tau" => $theme_author_uri, "im" => $im, "fc" => $fc, "ec" => $entry_count, "emc" => self::get_emails_sent(), "api" => self::get_api_calls()); - return $post; - } - - public static function ensure_wp_version(){ - if(!GF_SUPPORTED_WP_VERSION){ - echo "
" . sprintf(__("Gravity Forms require WordPress %s or greater. You must upgrade WordPress in order to use Gravity Forms", "gravityforms"), GF_MIN_WP_VERSION) . "
"; - return false; - } - return true; - } - - public static function check_update($option, $cache=true){ - - if(!is_object($option)) - return $option; - - $version_info = self::get_version_info($cache); - - if (!$version_info) - return $option; - - $plugin_path = "gravityforms/gravityforms.php"; - if(empty($option->response[$plugin_path])) - $option->response[$plugin_path] = new stdClass(); - - $version = rgar($version_info, "version"); - //Empty response means that the key is invalid. Do not queue for upgrade - if(!$version_info["is_valid_key"] || version_compare(GFCommon::$version, $version, '>=')){ - unset($option->response[$plugin_path]); - } - else{ - $url = rgar($version_info, "url"); - $option->response[$plugin_path]->url = "http://www.gravityforms.com"; - $option->response[$plugin_path]->slug = "gravityforms"; - $option->response[$plugin_path]->package = str_replace("{KEY}", GFCommon::get_key(), $url); - $option->response[$plugin_path]->new_version = $version; - $option->response[$plugin_path]->id = "0"; - } - - return $option; - - } - - public static function cache_remote_message(){ - //Getting version number - $key = GFCommon::get_key(); - $body = "key=$key"; - $options = array('method' => 'POST', 'timeout' => 3, 'body' => $body); - $options['headers'] = array( - 'Content-Type' => 'application/x-www-form-urlencoded; charset=' . get_option('blog_charset'), - 'Content-Length' => strlen($body), - 'User-Agent' => 'WordPress/' . get_bloginfo("version"), - 'Referer' => get_bloginfo("url") - ); - - $request_url = GRAVITY_MANAGER_URL . "/message.php?" . GFCommon::get_remote_request_params(); - $raw_response = wp_remote_request($request_url, $options); - - if ( is_wp_error( $raw_response ) || 200 != $raw_response['response']['code'] ) - $message = ""; - else - $message = $raw_response['body']; - - //validating that message is a valid Gravity Form message. If message is invalid, don't display anything - if(substr($message, 0, 10) != "") - $message = ""; - - update_option("rg_gforms_message", $message); - } - - public static function get_local_timestamp($timestamp = null){ - if($timestamp == null) - $timestamp = time(); - - return $timestamp + (get_option( 'gmt_offset' ) * 3600 ); - } - - public static function get_gmt_timestamp($local_timestamp){ - return $local_timestamp - (get_option( 'gmt_offset' ) * 3600 ); - } - - public static function format_date($gmt_datetime, $is_human = true, $date_format="", $include_time=true){ - if(empty($gmt_datetime)) - return ""; - - //adjusting date to local configured Time Zone - $lead_gmt_time = mysql2date("G", $gmt_datetime); - $lead_local_time = self::get_local_timestamp($lead_gmt_time); - - if(empty($date_format)) - $date_format = get_option('date_format'); - - if($is_human){ - $time_diff = time() - $lead_gmt_time; - - if ($time_diff > 0 && $time_diff < 24*60*60) - $date_display = sprintf(__('%s ago', 'gravityforms'), human_time_diff($lead_gmt_time)); - else - $date_display = $include_time ? sprintf(__('%1$s at %2$s', 'gravityforms'), date_i18n($date_format, $lead_local_time, true), date_i18n(get_option('time_format'), $lead_local_time, true)) : date_i18n($date_format, $lead_local_time, true); - } - else{ - $date_display = $include_time ? sprintf(__('%1$s at %2$s', 'gravityforms'), date_i18n($date_format, $lead_local_time, true), date_i18n(get_option('time_format'), $lead_local_time, true)) : date_i18n($date_format, $lead_local_time, true); - } - - return $date_display; - } - - public static function get_selection_value($value){ - $ary = explode("|", $value); - $val = $ary[0]; - return $val; - } - - public static function selection_display($value, $field, $currency="", $use_text=false){ - if (is_array($value)){ - return ""; - } - - $ary = explode("|", $value); - $val = $ary[0]; - $price = count($ary) > 1 ? $ary[1] : ""; - - if($use_text) - $val = RGFormsModel::get_choice_text($field, $val); - - if(!empty($price)) - return "$val (" . self::to_money($price, $currency) . ")"; - else - return $val; - } - - public static function date_display($value, $format = "mdy"){ - $date = self::parse_date($value, $format); - if(empty($date)) - return $value; - - list($position, $separator) = rgexplode("_", $format, 2); - switch($separator){ - case "dash" : - $separator = "-"; - break; - case "dot" : - $separator = "."; - break; - default : - $separator = "/"; - break; - } - - switch($position){ - case "ymd" : - return $date["year"] . $separator . $date["month"] . $separator . $date["day"]; - break; - - case "dmy" : - return $date["day"] . $separator . $date["month"] . $separator . $date["year"]; - break; - - default : - return $date["month"] . $separator . $date["day"] . $separator . $date["year"]; - break; - - } - } - - public static function parse_date($date, $format="mdy"){ - $date_info = array(); - - $position = substr($format, 0, 3); - - if(is_array($date)){ - - switch($position){ - case "mdy" : - $date_info["month"] = rgar($date, 0); - $date_info["day"] = rgar($date, 1); - $date_info["year"] = rgar($date, 2); - break; - - case "dmy" : - $date_info["day"] = rgar($date, 0); - $date_info["month"] = rgar($date, 1); - $date_info["year"] = rgar($date, 2); - break; - - case "ymd" : - $date_info["year"] = rgar($date, 0); - $date_info["month"] = rgar($date, 1); - $date_info["day"] = rgar($date, 2); - break; - } - return $date_info; - } - - $date = preg_replace("|[/\.]|", "-", $date); - if(preg_match('/^(\d{1,4})-(\d{1,2})-(\d{1,4})$/', $date, $matches)){ - - if(strlen($matches[1]) == 4){ - //format yyyy-mm-dd - $date_info["year"] = $matches[1]; - $date_info["month"] = $matches[2]; - $date_info["day"] = $matches[3]; - } - else if ($position == "mdy"){ - //format mm-dd-yyyy - $date_info["month"] = $matches[1]; - $date_info["day"] = $matches[2]; - $date_info["year"] = $matches[3]; - } - else{ - //format dd-mm-yyyy - $date_info["day"] = $matches[1]; - $date_info["month"] = $matches[2]; - $date_info["year"] = $matches[3]; - } - } - - return $date_info; - } - - - public static function truncate_url($url){ - $truncated_url = basename($url); - if(empty($truncated_url)) - $truncated_url = dirname($url); - - $ary = explode("?", $truncated_url); - - return $ary[0]; - } - - public static function get_tabindex(){ - return GFCommon::$tab_index > 0 ? "tabindex='" . GFCommon::$tab_index++ . "'" : ""; - } - - public static function get_checkbox_choices($field, $value, $disabled_text){ - $choices = ""; - - if(is_array($field["choices"])){ - $choice_number = 1; - $count = 1; - foreach($field["choices"] as $choice){ - if($choice_number % 10 == 0) //hack to skip numbers ending in 0. so that 5.1 doesn't conflict with 5.10 - $choice_number++; - - $input_id = $field["id"] . '.' . $choice_number; - $id = $field["id"] . '_' . $choice_number++; - - if(empty($_POST) && rgar($choice,"isSelected")){ - $checked = "checked='checked'"; - } - else if(is_array($value) && RGFormsModel::choice_value_match($field, $choice, rgget($input_id, $value))){ - $checked = "checked='checked'"; - } - else if(!is_array($value) && RGFormsModel::choice_value_match($field, $choice, $value)){ - $checked = "checked='checked'"; - } - else{ - $checked = ""; - } - - $logic_event = self::get_logic_event($field, "click"); - - $tabindex = self::get_tabindex(); - $choice_value = $choice["value"]; - if(rgget("enablePrice", $field)) - $choice_value .= "|" . GFCommon::to_number(rgar($choice,"price")); - - $choices.= sprintf("
  • ", $input_id, esc_attr($choice_value), $checked, $id, $disabled_text, $id, $choice["text"]); - - if(IS_ADMIN && RG_CURRENT_VIEW != "entry" && $count >=5) - break; - - $count++; - } - - $total = sizeof($field["choices"]); - if($count < $total) - $choices .= "
  • " . sprintf(__("%d of %d items shown. Edit field to view all", "gravityforms"), $count, $total) . "
  • "; - } - - return apply_filters("gform_field_choices_" . rgget("formId", $field), apply_filters("gform_field_choices", $choices, $field), $field); - - } - - public static function get_radio_choices($field, $value="", $disabled_text){ - $choices = ""; - - if(is_array($field["choices"])){ - $choice_id = 0; - - // add "other" choice to choices if enabled - if(rgar($field, 'enableOtherChoice')) { - $other_default_value = GFCommon::get_other_choice_value(); - $field["choices"][] = array('text' => $other_default_value, 'value' => 'gf_other_choice', 'isSelected' => false, 'isOtherChoice' => true); - } - - $logic_event = self::get_logic_event($field, "click"); - $count = 1; - - foreach($field["choices"] as $choice){ - $id = $field["id"] . '_' . $choice_id++; - - $field_value = !empty($choice["value"]) || rgar($field, "enableChoiceValue") ? $choice["value"] : $choice["text"]; - - if(rgget("enablePrice", $field)) - $field_value .= "|" . GFCommon::to_number(rgar($choice,"price")); - - if(rgblank($value) && RG_CURRENT_VIEW != "entry"){ - $checked = rgar($choice,"isSelected") ? "checked='checked'" : ""; - } - else { - $checked = RGFormsModel::choice_value_match($field, $choice, $value) ? "checked='checked'" : ""; - } - - $tabindex = self::get_tabindex(); - $label = sprintf("", $id, $choice["text"]); - $input_focus = ''; - - // handle "other" choice - if(rgar($choice, 'isOtherChoice')) { - - $onfocus = !IS_ADMIN ? 'jQuery(this).prev("input").attr("checked", true); if(jQuery(this).val() == "' . $other_default_value . '") { jQuery(this).val(""); }' : ''; - $onblur = !IS_ADMIN ? 'if(jQuery(this).val().replace(" ", "") == "") { jQuery(this).val("' . $other_default_value . '"); }' : ''; - - $input_focus = !IS_ADMIN ? "onfocus=\"jQuery(this).next('input').focus();\"" : ""; - $value_exists = RGFormsModel::choices_value_match($field, $field["choices"], $value); - - if($value == 'gf_other_choice' && rgpost("input_{$field["id"]}_other")){ - $other_value = rgpost("input_{$field["id"]}_other"); - } else if(!$value_exists && !empty($value)){ - $other_value = $value; - $value = 'gf_other_choice'; - $checked = "checked='checked'"; - } else { - $other_value = $other_default_value; - } - $label = ""; - } - - $choices .= sprintf("
  • %s
  • ", $field["id"], esc_attr($field_value), $checked, $id, $disabled_text, $input_focus, $label); - - if(IS_ADMIN && RG_CURRENT_VIEW != "entry" && $count >=5) - break; - - $count++; - } - - $total = sizeof($field["choices"]); - if($count < $total) - $choices .= "
  • " . sprintf(__("%d of %d items shown. Edit field to view all", "gravityforms"), $count, $total) . "
  • "; - } - - return apply_filters("gform_field_choices_" . rgget("formId", $field), apply_filters("gform_field_choices", $choices, $field), $field); - } - - public static function get_field_type_title($type){ - switch($type){ - case "text" : - return __("Single Line Text", "gravityforms"); - case "textarea" : - return __("Paragraph Text", "gravityforms"); - case "select" : - return __("Drop Down", "gravityforms"); - case "multiselect" : - return __("Multi Select", "gravityforms"); - case "number" : - return __("Number", "gravityforms"); - case "checkbox" : - return __("Checkboxes", "gravityforms"); - case "radio" : - return __("Radio Buttons", "gravityforms"); - case "hidden" : - return __("Hidden", "gravityforms"); - case "html" : - return __("HTML", "gravityforms"); - case "section" : - return __("Section Break", "gravityforms"); - case "page" : - return __("Page Break", "gravityforms"); - case "name" : - return __("Name", "gravityforms"); - case "date" : - return __("Date", "gravityforms"); - case "time" : - return __("Time", "gravityforms"); - case "phone" : - return __("Phone", "gravityforms"); - case "address" : - return __("Address", "gravityforms"); - case "website" : - return __("Website", "gravityforms"); - case "email" : - return __("Email", "gravityforms"); - case "password" : - return __("Password", "gravityforms"); - case "fileupload" : - return __("File Upload", "gravityforms"); - case "captcha" : - return __("CAPTCHA", "gravityforms"); - case "list" : - return __("List", "gravityforms"); - case "creditcard" : - return __("Credit Card", "gravityforms"); - case "post_title" : - return __("Title", "gravityforms"); - case "post_content" : - return __("Body", "gravityforms"); - case "post_excerpt" : - return __("Excerpt", "gravityforms"); - case "post_tags" : - return __("Tags", "gravityforms"); - case "post_category" : - return __("Category", "gravityforms"); - case "post_image" : - return __("Image", "gravityforms"); - case "post_custom_field" : - return __("Custom Field", "gravityforms"); - case "product" : - return __("Product", "gravityforms"); - case "quantity" : - return __("Quantity", "gravityforms"); - case "option" : - return __("Option", "gravityforms"); - case "shipping" : - return __("Shipping", "gravityforms"); - case "total" : - return __("Total", "gravityforms"); - - default : - return apply_filters("gform_field_type_title", $type, $type); - } - } - - public static function get_select_choices($field, $value=""){ - $choices = ""; - - if(RG_CURRENT_VIEW == "entry" && empty($value)) - $choices .= ""; - - if(is_array(rgar($field, "choices"))){ - foreach($field["choices"] as $choice){ - - //needed for users upgrading from 1.0 - $field_value = !empty($choice["value"]) || rgget("enableChoiceValue", $field) || $field['type'] == 'post_category' ? $choice["value"] : $choice["text"]; - if(rgget("enablePrice", $field)) - $field_value .= "|" . GFCommon::to_number(rgar($choice,"price")); - - if(rgblank($value) && RG_CURRENT_VIEW != "entry"){ - $selected = rgar($choice,"isSelected") ? "selected='selected'" : ""; - } - else{ - if(is_array($value)){ - $is_match = false; - foreach($value as $item){ - if(RGFormsModel::choice_value_match($field, $choice, $item)){ - $is_match = true; - break; - } - } - $selected = $is_match ? "selected='selected'" : ""; - } - else{ - $selected = RGFormsModel::choice_value_match($field, $choice, $value) ? "selected='selected'" : ""; - } - } - - $choices.= sprintf("", esc_attr($field_value), $selected, esc_html($choice["text"])); - } - } - return $choices; - } - - public static function is_section_empty($section_field, $form, $lead){ - $cache_key = "GFCommon::is_section_empty_" . $form["id"] . "_" . $section_field["id"]; - - $value = GFCache::get($cache_key); - - if($value !== false) - return $value == true; - - $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')); - - if(!self::is_product_field($field["type"]) && !rgblank($val)){ - GFCache::set($cache_key, 0); - return false; - } - } - - GFCache::set($cache_key, 1); - - return true; - } - - public static function get_section_fields($form, $section_field_id){ - $fields = array(); - $in_section = false; - foreach($form["fields"] as $field){ - if(in_array($field["type"], array("section", "page")) && $in_section) - return $fields; - - if($field["id"] == $section_field_id) - $in_section = true; - - if($in_section) - $fields[] = $field; - } - - return $fields; - } - - - public static function get_countries(){ - return apply_filters("gform_countries", array( - __('Afghanistan', 'gravityforms'),__('Albania', 'gravityforms'),__('Algeria', 'gravityforms'), __('American Samoa', 'gravityforms'), __('Andorra', 'gravityforms'),__('Angola', 'gravityforms'),__('Antigua and Barbuda', 'gravityforms'),__('Argentina', 'gravityforms'),__('Armenia', 'gravityforms'),__('Australia', 'gravityforms'),__('Austria', 'gravityforms'),__('Azerbaijan', 'gravityforms'),__('Bahamas', 'gravityforms'),__('Bahrain', 'gravityforms'),__('Bangladesh', 'gravityforms'),__('Barbados', 'gravityforms'),__('Belarus', 'gravityforms'),__('Belgium', 'gravityforms'),__('Belize', 'gravityforms'),__('Benin', 'gravityforms'),__('Bermuda', 'gravityforms'),__('Bhutan', 'gravityforms'),__('Bolivia', 'gravityforms'),__('Bosnia and Herzegovina', 'gravityforms'),__('Botswana', 'gravityforms'),__('Brazil', 'gravityforms'),__('Brunei', 'gravityforms'),__('Bulgaria', 'gravityforms'),__('Burkina Faso', 'gravityforms'),__('Burundi', 'gravityforms'),__('Cambodia', 'gravityforms'),__('Cameroon', 'gravityforms'),__('Canada', 'gravityforms'),__('Cape Verde', 'gravityforms'),__('Cayman Islands', 'gravityforms'),__('Central African Republic', 'gravityforms'),__('Chad', 'gravityforms'),__('Chile', 'gravityforms'),__('China', 'gravityforms'),__('Colombia', 'gravityforms'),__('Comoros', 'gravityforms'),__('Congo, Democratic Republic of the', 'gravityforms'),__('Congo, Republic of the', 'gravityforms'),__('Costa Rica', 'gravityforms'),__('Côte d\'Ivoire', 'gravityforms'),__('Croatia', 'gravityforms'),__('Cuba', 'gravityforms'),__('Cyprus', 'gravityforms'),__('Czech Republic', 'gravityforms'),__('Denmark', 'gravityforms'),__('Djibouti', 'gravityforms'),__('Dominica', 'gravityforms'),__('Dominican Republic', 'gravityforms'),__('East Timor', 'gravityforms'),__('Ecuador', 'gravityforms'),__('Egypt', 'gravityforms'),__('El Salvador', 'gravityforms'),__('Equatorial Guinea', 'gravityforms'),__('Eritrea', 'gravityforms'),__('Estonia', 'gravityforms'),__('Ethiopia', 'gravityforms'),__('Fiji', 'gravityforms'),__('Finland', 'gravityforms'),__('France', 'gravityforms'),__('Gabon', 'gravityforms'), - __('Gambia', 'gravityforms'),__('Georgia', 'gravityforms'),__('Germany', 'gravityforms'),__('Ghana', 'gravityforms'),__('Greece', 'gravityforms'),__('Greenland', 'gravityforms'),__('Grenada', 'gravityforms'),__('Guam', 'gravityforms'),__('Guatemala', 'gravityforms'),__('Guinea', 'gravityforms'),__('Guinea-Bissau', 'gravityforms'),__('Guyana', 'gravityforms'),__('Haiti', 'gravityforms'),__('Honduras', 'gravityforms'),__('Hong Kong', 'gravityforms'),__('Hungary', 'gravityforms'),__('Iceland', 'gravityforms'),__('India', 'gravityforms'),__('Indonesia', 'gravityforms'),__('Iran', 'gravityforms'),__('Iraq', 'gravityforms'),__('Ireland', 'gravityforms'),__('Israel', 'gravityforms'),__('Italy', 'gravityforms'),__('Jamaica', 'gravityforms'),__('Japan', 'gravityforms'),__('Jordan', 'gravityforms'),__('Kazakhstan', 'gravityforms'),__('Kenya', 'gravityforms'),__('Kiribati', 'gravityforms'),__('North Korea', 'gravityforms'),__('South Korea', 'gravityforms'),__('Kosovo', 'gravityforms'),__('Kuwait', 'gravityforms'),__('Kyrgyzstan', 'gravityforms'),__('Laos', 'gravityforms'),__('Latvia', 'gravityforms'),__('Lebanon', 'gravityforms'),__('Lesotho', 'gravityforms'),__('Liberia', 'gravityforms'),__('Libya', 'gravityforms'),__('Liechtenstein', 'gravityforms'),__('Lithuania', 'gravityforms'),__('Luxembourg', 'gravityforms'),__('Macedonia', 'gravityforms'),__('Madagascar', 'gravityforms'),__('Malawi', 'gravityforms'),__('Malaysia', 'gravityforms'),__('Maldives', 'gravityforms'),__('Mali', 'gravityforms'),__('Malta', 'gravityforms'),__('Marshall Islands', 'gravityforms'),__('Mauritania', 'gravityforms'),__('Mauritius', 'gravityforms'),__('Mexico', 'gravityforms'),__('Micronesia', 'gravityforms'),__('Moldova', 'gravityforms'),__('Monaco', 'gravityforms'),__('Mongolia', 'gravityforms'),__('Montenegro', 'gravityforms'),__('Morocco', 'gravityforms'),__('Mozambique', 'gravityforms'),__('Myanmar', 'gravityforms'),__('Namibia', 'gravityforms'),__('Nauru', 'gravityforms'),__('Nepal', 'gravityforms'),__('Netherlands', 'gravityforms'),__('New Zealand', 'gravityforms'), - __('Nicaragua', 'gravityforms'),__('Niger', 'gravityforms'),__('Nigeria', 'gravityforms'),__('Norway', 'gravityforms'), __('Northern Mariana Islands', 'gravityforms'), __('Oman', 'gravityforms'),__('Pakistan', 'gravityforms'),__('Palau', 'gravityforms'),__('Palestine', 'gravityforms'),__('Panama', 'gravityforms'),__('Papua New Guinea', 'gravityforms'),__('Paraguay', 'gravityforms'),__('Peru', 'gravityforms'),__('Philippines', 'gravityforms'),__('Poland', 'gravityforms'),__('Portugal', 'gravityforms'),__('Puerto Rico', 'gravityforms'),__('Qatar', 'gravityforms'),__('Romania', 'gravityforms'),__('Russia', 'gravityforms'),__('Rwanda', 'gravityforms'),__('Saint Kitts and Nevis', 'gravityforms'),__('Saint Lucia', 'gravityforms'),__('Saint Vincent and the Grenadines', 'gravityforms'),__('Samoa', 'gravityforms'),__('San Marino', 'gravityforms'),__('Sao Tome and Principe', 'gravityforms'),__('Saudi Arabia', 'gravityforms'),__('Senegal', 'gravityforms'),__('Serbia and Montenegro', 'gravityforms'),__('Seychelles', 'gravityforms'),__('Sierra Leone', 'gravityforms'),__('Singapore', 'gravityforms'),__('Slovakia', 'gravityforms'),__('Slovenia', 'gravityforms'),__('Solomon Islands', 'gravityforms'),__('Somalia', 'gravityforms'),__('South Africa', 'gravityforms'),__('Spain', 'gravityforms'),__('Sri Lanka', 'gravityforms'),__('Sudan', 'gravityforms'),__('Sudan, South', 'gravityforms'),__('Suriname', 'gravityforms'),__('Swaziland', 'gravityforms'),__('Sweden', 'gravityforms'),__('Switzerland', 'gravityforms'),__('Syria', 'gravityforms'),__('Taiwan', 'gravityforms'),__('Tajikistan', 'gravityforms'),__('Tanzania', 'gravityforms'),__('Thailand', 'gravityforms'),__('Togo', 'gravityforms'),__('Tonga', 'gravityforms'),__('Trinidad and Tobago', 'gravityforms'),__('Tunisia', 'gravityforms'),__('Turkey', 'gravityforms'),__('Turkmenistan', 'gravityforms'),__('Tuvalu', 'gravityforms'),__('Uganda', 'gravityforms'),__('Ukraine', 'gravityforms'),__('United Arab Emirates', 'gravityforms'),__('United Kingdom', 'gravityforms'), - __('United States', 'gravityforms'),__('Uruguay', 'gravityforms'),__('Uzbekistan', 'gravityforms'),__('Vanuatu', 'gravityforms'),__('Vatican City', 'gravityforms'),__('Venezuela', 'gravityforms'),__('Vietnam', 'gravityforms'), __('Virgin Islands, British', 'gravityforms'), __('Virgin Islands, U.S.', 'gravityforms'),__('Yemen', 'gravityforms'),__('Zambia', 'gravityforms'),__('Zimbabwe', 'gravityforms'))); - - - } - - public static function get_country_code($country_name) { - $codes = array( - __('AFGHANISTAN', 'gravityforms') => "AF" , - __('ALBANIA', 'gravityforms') => "AL" , - __('ALGERIA', 'gravityforms') => "DZ" , - __('AMERICAN SAMOA', 'gravityforms') => "AS" , - __('ANDORRA', 'gravityforms') => "AD" , - __('ANGOLA', 'gravityforms') => "AO" , - __('ANTIGUA AND BARBUDA', 'gravityforms') => "AG" , - __('ARGENTINA', 'gravityforms') => "AR" , - __('ARMENIA', 'gravityforms') => "AM" , - __('AUSTRALIA', 'gravityforms') => "AU" , - __('AUSTRIA', 'gravityforms') => "AT" , - __('AZERBAIJAN', 'gravityforms') => "AZ" , - __('BAHAMAS', 'gravityforms') => "BS" , - __('BAHRAIN', 'gravityforms') => "BH" , - __('BANGLADESH', 'gravityforms') => "BD" , - __('BARBADOS', 'gravityforms') => "BB" , - __('BELARUS', 'gravityforms') => "BY" , - __('BELGIUM', 'gravityforms') => "BE" , - __('BELIZE', 'gravityforms') => "BZ" , - __('BENIN', 'gravityforms') => "BJ" , - __('BERMUDA', 'gravityforms') => "BM" , - __('BHUTAN', 'gravityforms') => "BT" , - __('BOLIVIA', 'gravityforms') => "BO" , - __('BOSNIA AND HERZEGOVINA', 'gravityforms') => "BA" , - __('BOTSWANA', 'gravityforms') => "BW" , - __('BRAZIL', 'gravityforms') => "BR" , - __('BRUNEI', 'gravityforms') => "BN" , - __('BULGARIA', 'gravityforms') => "BG" , - __('BURKINA FASO', 'gravityforms') => "BF" , - __('BURUNDI', 'gravityforms') => "BI" , - __('CAMBODIA', 'gravityforms') => "KH" , - __('CAMEROON', 'gravityforms') => "CM" , - __('CANADA', 'gravityforms') => "CA" , - __('CAPE VERDE', 'gravityforms') => "CV" , - __('CAYMAN ISLANDS', 'gravityforms') => "KY" , - __('CENTRAL AFRICAN REPUBLIC', 'gravityforms') => "CF" , - __('CHAD', 'gravityforms') => "TD" , - __('CHILE', 'gravityforms') => "CL" , - __('CHINA', 'gravityforms') => "CN" , - __('COLOMBIA', 'gravityforms') => "CO" , - __('COMOROS', 'gravityforms') => "KM" , - __('CONGO, DEMOCRATIC REPUBLIC OF THE', 'gravityforms') => "CD" , - __('CONGO, REPUBLIC OF THE', 'gravityforms') => "CG" , - __('COSTA RICA', 'gravityforms') => "CR" , - __('C&OCIRC;TE D\'IVOIRE', 'gravityforms') => "CI" , - __('CROATIA', 'gravityforms') => "HR" , - __('CUBA', 'gravityforms') => "CU" , - __('CYPRUS', 'gravityforms') => "CY" , - __('CZECH REPUBLIC', 'gravityforms') => "CZ" , - __('DENMARK', 'gravityforms') => "DK" , - __('DJIBOUTI', 'gravityforms') => "DJ" , - __('DOMINICA', 'gravityforms') => "DM" , - __('DOMINICAN REPUBLIC', 'gravityforms') => "DO" , - __('EAST TIMOR', 'gravityforms') => "TL" , - __('ECUADOR', 'gravityforms') => "EC" , - __('EGYPT', 'gravityforms') => "EG" , - __('EL SALVADOR', 'gravityforms') => "SV" , - __('EQUATORIAL GUINEA', 'gravityforms') => "GQ" , - __('ERITREA', 'gravityforms') => "ER" , - __('ESTONIA', 'gravityforms') => "EE" , - __('ETHIOPIA', 'gravityforms') => "ET" , - __('FIJI', 'gravityforms') => "FJ" , - __('FINLAND', 'gravityforms') => "FI" , - __('FRANCE', 'gravityforms') => "FR" , - __('GABON', 'gravityforms') => "GA" , - __('GAMBIA', 'gravityforms') => "GM" , - __('GEORGIA', 'gravityforms') => "GE" , - __('GERMANY', 'gravityforms') => "DE" , - __('GHANA', 'gravityforms') => "GH" , - __('GREECE', 'gravityforms') => "GR" , - __('GREENLAND', 'gravityforms') => "GL" , - __('GRENADA', 'gravityforms') => "GD" , - __('GUAM', 'gravityforms') => "GU" , - __('GUATEMALA', 'gravityforms') => "GT" , - __('GUINEA', 'gravityforms') => "GN" , - __('GUINEA-BISSAU', 'gravityforms') => "GW" , - __('GUYANA', 'gravityforms') => "GY" , - __('HAITI', 'gravityforms') => "HT" , - __('HONDURAS', 'gravityforms') => "HN" , - __('HONG KONG', 'gravityforms') => "HK" , - __('HUNGARY', 'gravityforms') => "HU" , - __('ICELAND', 'gravityforms') => "IS" , - __('INDIA', 'gravityforms') => "IN" , - __('INDONESIA', 'gravityforms') => "ID" , - __('IRAN', 'gravityforms') => "IR" , - __('IRAQ', 'gravityforms') => "IQ" , - __('IRELAND', 'gravityforms') => "IE" , - __('ISRAEL', 'gravityforms') => "IL" , - __('ITALY', 'gravityforms') => "IT" , - __('JAMAICA', 'gravityforms') => "JM" , - __('JAPAN', 'gravityforms') => "JP" , - __('JORDAN', 'gravityforms') => "JO" , - __('KAZAKHSTAN', 'gravityforms') => "KZ" , - __('KENYA', 'gravityforms') => "KE" , - __('KIRIBATI', 'gravityforms') => "KI" , - __('NORTH KOREA', 'gravityforms') => "KP" , - __('SOUTH KOREA', 'gravityforms') => "KR" , - __('KOSOVO', 'gravityforms') => "KV" , - __('KUWAIT', 'gravityforms') => "KW" , - __('KYRGYZSTAN', 'gravityforms') => "KG" , - __('LAOS', 'gravityforms') => "LA" , - __('LATVIA', 'gravityforms') => "LV" , - __('LEBANON', 'gravityforms') => "LB" , - __('LESOTHO', 'gravityforms') => "LS" , - __('LIBERIA', 'gravityforms') => "LR" , - __('LIBYA', 'gravityforms') => "LY" , - __('LIECHTENSTEIN', 'gravityforms') => "LI" , - __('LITHUANIA', 'gravityforms') => "LT" , - __('LUXEMBOURG', 'gravityforms') => "LU" , - __('MACEDONIA', 'gravityforms') => "MK" , - __('MADAGASCAR', 'gravityforms') => "MG" , - __('MALAWI', 'gravityforms') => "MW" , - __('MALAYSIA', 'gravityforms') => "MY" , - __('MALDIVES', 'gravityforms') => "MV" , - __('MALI', 'gravityforms') => "ML" , - __('MALTA', 'gravityforms') => "MT" , - __('MARSHALL ISLANDS', 'gravityforms') => "MH" , - __('MAURITANIA', 'gravityforms') => "MR" , - __('MAURITIUS', 'gravityforms') => "MU" , - __('MEXICO', 'gravityforms') => "MX" , - __('MICRONESIA', 'gravityforms') => "FM" , - __('MOLDOVA', 'gravityforms') => "MD" , - __('MONACO', 'gravityforms') => "MC" , - __('MONGOLIA', 'gravityforms') => "MN" , - __('MONTENEGRO', 'gravityforms') => "ME" , - __('MOROCCO', 'gravityforms') => "MA" , - __('MOZAMBIQUE', 'gravityforms') => "MZ" , - __('MYANMAR', 'gravityforms') => "MM" , - __('NAMIBIA', 'gravityforms') => "NA" , - __('NAURU', 'gravityforms') => "NR" , - __('NEPAL', 'gravityforms') => "NP" , - __('NETHERLANDS', 'gravityforms') => "NL" , - __('NEW ZEALAND', 'gravityforms') => "NZ" , - __('NICARAGUA', 'gravityforms') => "NI" , - __('NIGER', 'gravityforms') => "NE" , - __('NIGERIA', 'gravityforms') => "NG" , - __('NORTHERN MARIANA ISLANDS', 'gravityforms') => "MP" , - __('NORWAY', 'gravityforms') => "NO" , - __('OMAN', 'gravityforms') => "OM" , - __('PAKISTAN', 'gravityforms') => "PK" , - __('PALAU', 'gravityforms') => "PW" , - __('PALESTINE', 'gravityforms') => "PS" , - __('PANAMA', 'gravityforms') => "PA" , - __('PAPUA NEW GUINEA', 'gravityforms') => "PG" , - __('PARAGUAY', 'gravityforms') => "PY" , - __('PERU', 'gravityforms') => "PE" , - __('PHILIPPINES', 'gravityforms') => "PH" , - __('POLAND', 'gravityforms') => "PL" , - __('PORTUGAL', 'gravityforms') => "PT" , - __('PUERTO RICO', 'gravityforms') => "PR" , - __('QATAR', 'gravityforms') => "QA" , - __('ROMANIA', 'gravityforms') => "RO" , - __('RUSSIA', 'gravityforms') => "RU" , - __('RWANDA', 'gravityforms') => "RW" , - __('SAINT KITTS AND NEVIS', 'gravityforms') => "KN" , - __('SAINT LUCIA', 'gravityforms') => "LC" , - __('SAINT VINCENT AND THE GRENADINES', 'gravityforms') => "VC" , - __('SAMOA', 'gravityforms') => "WS" , - __('SAN MARINO', 'gravityforms') => "SM" , - __('SAO TOME AND PRINCIPE', 'gravityforms') => "ST" , - __('SAUDI ARABIA', 'gravityforms') => "SA" , - __('SENEGAL', 'gravityforms') => "SN" , - __('SERBIA AND MONTENEGRO', 'gravityforms') => "RS" , - __('SEYCHELLES', 'gravityforms') => "SC" , - __('SIERRA LEONE', 'gravityforms') => "SL" , - __('SINGAPORE', 'gravityforms') => "SG" , - __('SLOVAKIA', 'gravityforms') => "SK" , - __('SLOVENIA', 'gravityforms') => "SI" , - __('SOLOMON ISLANDS', 'gravityforms') => "SB" , - __('SOMALIA', 'gravityforms') => "SO" , - __('SOUTH AFRICA', 'gravityforms') => "ZA" , - __('SPAIN', 'gravityforms') => "ES" , - __('SRI LANKA', 'gravityforms') => "LK" , - __('SUDAN', 'gravityforms') => "SD" , - __('SUDAN, SOUTH', 'gravityforms') => "SS" , - __('SURINAME', 'gravityforms') => "SR" , - __('SWAZILAND', 'gravityforms') => "SZ" , - __('SWEDEN', 'gravityforms') => "SE" , - __('SWITZERLAND', 'gravityforms') => "CH" , - __('SYRIA', 'gravityforms') => "SY" , - __('TAIWAN', 'gravityforms') => "TW" , - __('TAJIKISTAN', 'gravityforms') => "TJ" , - __('TANZANIA', 'gravityforms') => "TZ" , - __('THAILAND', 'gravityforms') => "TH" , - __('TOGO', 'gravityforms') => "TG" , - __('TONGA', 'gravityforms') => "TO" , - __('TRINIDAD AND TOBAGO', 'gravityforms') => "TT" , - __('TUNISIA', 'gravityforms') => "TN" , - __('TURKEY', 'gravityforms') => "TR" , - __('TURKMENISTAN', 'gravityforms') => "TM" , - __('TUVALU', 'gravityforms') => "TV" , - __('UGANDA', 'gravityforms') => "UG" , - __('UKRAINE', 'gravityforms') => "UA" , - __('UNITED ARAB EMIRATES', 'gravityforms') => "AE" , - __('UNITED KINGDOM', 'gravityforms') => "GB" , - __('UNITED STATES', 'gravityforms') => "US" , - __('URUGUAY', 'gravityforms') => "UY" , - __('UZBEKISTAN', 'gravityforms') => "UZ" , - __('VANUATU', 'gravityforms') => "VU" , - __('VATICAN CITY', 'gravityforms') => "" , - __('VENEZUELA', 'gravityforms') => "VE" , - __('VIRGIN ISLANDS, BRITISH', 'gravityforms') => "VG" , - __('VIRGIN ISLANDS, U.S.', 'gravityforms') => "VI" , - __('VIETNAM', 'gravityforms') => "VN" , - __('YEMEN', 'gravityforms') => "YE" , - __('ZAMBIA', 'gravityforms') => "ZM" , - __('ZIMBABWE', 'gravityforms') => "ZW" ); - - return rgar($codes, strtoupper($country_name)); - } - - public static function get_us_states(){ - return array(__("Alabama","gravityforms"),__("Alaska","gravityforms"),__("Arizona","gravityforms"),__("Arkansas","gravityforms"),__("California","gravityforms"),__("Colorado","gravityforms"),__("Connecticut","gravityforms"),__("Delaware","gravityforms"),__("District of Columbia", "gravityforms"), __("Florida","gravityforms"),__("Georgia","gravityforms"),__("Hawaii","gravityforms"),__("Idaho","gravityforms"),__("Illinois","gravityforms"),__("Indiana","gravityforms"),__("Iowa","gravityforms"),__("Kansas","gravityforms"),__("Kentucky","gravityforms"),__("Louisiana","gravityforms"),__("Maine","gravityforms"),__("Maryland","gravityforms"),__("Massachusetts","gravityforms"),__("Michigan","gravityforms"),__("Minnesota","gravityforms"),__("Mississippi","gravityforms"),__("Missouri","gravityforms"),__("Montana","gravityforms"),__("Nebraska","gravityforms"),__("Nevada","gravityforms"),__("New Hampshire","gravityforms"),__("New Jersey","gravityforms"),__("New Mexico","gravityforms"),__("New York","gravityforms"),__("North Carolina","gravityforms"),__("North Dakota","gravityforms"),__("Ohio","gravityforms"),__("Oklahoma","gravityforms"),__("Oregon","gravityforms"),__("Pennsylvania","gravityforms"),__("Rhode Island","gravityforms"),__("South Carolina","gravityforms"),__("South Dakota","gravityforms"),__("Tennessee","gravityforms"),__("Texas","gravityforms"),__("Utah","gravityforms"),__("Vermont","gravityforms"),__("Virginia","gravityforms"),__("Washington","gravityforms"),__("West Virginia","gravityforms"),__("Wisconsin","gravityforms"),__("Wyoming","gravityforms"), __("Armed Forces Americas","gravityforms"), __("Armed Forces Europe","gravityforms"),__("Armed Forces Pacific","gravityforms")); - } - - public static function get_us_state_code($state_name){ - $states = array( - strtoupper(__("Alabama","gravityforms")) => "AL", - strtoupper(__("Alaska","gravityforms")) => "AK", - strtoupper(__("Arizona","gravityforms")) => "AZ", - strtoupper(__("Arkansas","gravityforms")) => "AR", - strtoupper(__("California","gravityforms")) => "CA", - strtoupper(__("Colorado","gravityforms")) => "CO", - strtoupper(__("Connecticut","gravityforms")) => "CT", - strtoupper(__("Delaware","gravityforms")) => "DE", - strtoupper(__("District of Columbia", "gravityforms")) => "DC", - strtoupper(__("Florida","gravityforms")) => "FL", - strtoupper(__("Georgia","gravityforms")) => "GA", - strtoupper(__("Hawaii","gravityforms")) => "HI", - strtoupper(__("Idaho","gravityforms")) => "ID", - strtoupper(__("Illinois","gravityforms")) => "IL", - strtoupper(__("Indiana","gravityforms")) => "IN", - strtoupper(__("Iowa","gravityforms")) => "IA", - strtoupper(__("Kansas","gravityforms")) => "KS", - strtoupper(__("Kentucky","gravityforms")) => "KY", - strtoupper(__("Louisiana","gravityforms")) => "LA", - strtoupper(__("Maine","gravityforms")) => "ME", - strtoupper(__("Maryland","gravityforms")) => "MD", - strtoupper(__("Massachusetts","gravityforms")) => "MA", - strtoupper(__("Michigan","gravityforms")) => "MI", - strtoupper(__("Minnesota","gravityforms")) => "MN", - strtoupper(__("Mississippi","gravityforms")) => "MS", - strtoupper(__("Missouri","gravityforms")) => "MO", - strtoupper(__("Montana","gravityforms")) => "MT", - strtoupper(__("Nebraska","gravityforms")) => "NE", - strtoupper(__("Nevada","gravityforms")) => "NV", - strtoupper(__("New Hampshire","gravityforms")) => "NH", - strtoupper(__("New Jersey","gravityforms")) => "NJ", - strtoupper(__("New Mexico","gravityforms")) => "NM", - strtoupper(__("New York","gravityforms")) => "NY", - strtoupper(__("North Carolina","gravityforms")) => "NC", - strtoupper(__("North Dakota","gravityforms")) => "ND", - strtoupper(__("Ohio","gravityforms")) => "OH", - strtoupper(__("Oklahoma","gravityforms")) => "OK", - strtoupper(__("Oregon","gravityforms")) => "OR", - strtoupper(__("Pennsylvania","gravityforms")) => "PA", - strtoupper(__("Rhode Island","gravityforms")) => "RI", - strtoupper(__("South Carolina","gravityforms")) => "SC", - strtoupper(__("South Dakota","gravityforms")) => "SD", - strtoupper(__("Tennessee","gravityforms")) => "TN", - strtoupper(__("Texas","gravityforms")) => "TX", - strtoupper(__("Utah","gravityforms")) => "UT", - strtoupper(__("Vermont","gravityforms")) => "VT", - strtoupper(__("Virginia","gravityforms")) => "VA", - strtoupper(__("Washington","gravityforms")) => "WA", - strtoupper(__("West Virginia","gravityforms")) => "WV", - strtoupper(__("Wisconsin","gravityforms")) => "WI", - strtoupper(__("Wyoming","gravityforms")) => "WY", - strtoupper(__("Armed Forces Americas","gravityforms")) => "AA", - strtoupper(__("Armed Forces Europe","gravityforms")) => "AE", - strtoupper(__("Armed Forces Pacific","gravityforms")) => "AP" - ); - - $code = isset($states[strtoupper($state_name)]) ? $states[strtoupper($state_name)] : strtoupper($state_name); - - return $code; - } - - - public static function get_canadian_provinces(){ - return array(__("Alberta","gravityforms"),__("British Columbia","gravityforms"),__("Manitoba","gravityforms"),__("New Brunswick","gravityforms"),__("Newfoundland & Labrador","gravityforms"),__("Northwest Territories","gravityforms"),__("Nova Scotia","gravityforms"),__("Nunavut","gravityforms"),__("Ontario","gravityforms"),__("Prince Edward Island","gravityforms"),__("Quebec","gravityforms"),__("Saskatchewan","gravityforms"),__("Yukon","gravityforms")); - - } - - public static function get_state_dropdown($states, $selected_state=""){ - $str = ""; - foreach($states as $state){ - $selected = $state == $selected_state ? "selected='selected'" : ""; - $str .= ""; - } - return $str; - } - - public static function get_us_state_dropdown($selected_state = ""){ - $states = array_merge(array(''), self::get_us_states()); - foreach($states as $state){ - $selected = $state == $selected_state ? "selected='selected'" : ""; - $str .= ""; - } - return $str; - } - - public static function get_canadian_provinces_dropdown($selected_province = ""){ - $states = array_merge(array(''), self::get_canadian_provinces()); - foreach($states as $state){ - $selected = $state == $selected_province ? "selected='selected'" : ""; - $str .= ""; - } - return $str; - } - - public static function get_country_dropdown($selected_country = ""){ - $str = ""; - $countries = array_merge(array(''), self::get_countries()); - foreach($countries as $country){ - $selected = $country == $selected_country ? "selected='selected'" : ""; - $str .= ""; - } - return $str; - } - - public static function is_post_field($field){ - return in_array($field["type"], array("post_title", "post_tags", "post_category", "post_custom_field", "post_content", "post_excerpt", "post_image")); - } - - public static function get_range_message($field){ - $min = $field["rangeMin"]; - $max = $field["rangeMax"]; - $message = ""; - - if(is_numeric($min) && is_numeric($max)) - $message = sprintf(__("Please enter a value between %s and %s.", "gravityforms"), "$min", "$max") ; - else if(is_numeric($min)) - $message = sprintf(__("Please enter a value greater than or equal to %s.", "gravityforms"), "$min"); - else if(is_numeric($max)) - $message = sprintf(__("Please enter a value less than or equal to %s.", "gravityforms"), "$max"); - else if($field["failed_validation"]) - $message = __("Please enter a valid number", "gravityforms"); - - return $message; - } - - public static function get_fields_by_type($form, $types){ - $fields = array(); - if(!is_array(rgar($form,"fields"))) - return $fields; - - foreach($form["fields"] as $field){ - if(in_array(rgar($field,"type"), $types)) - $fields[] = $field; - } - return $fields; - } - - public static function has_pages($form){ - return sizeof(self::get_fields_by_type($form, array("page"))) > 0; - } - - public static function get_product_fields_by_type($form, $types, $product_id){ - global $_product_fields; - $key = json_encode($types) . "_" . $product_id . "_" . $form["id"]; - if(!isset($_product_fields[$key])){ - $fields = array(); - for($i=0, $count=sizeof($form["fields"]); $i<$count; $i++){ - $field = $form["fields"][$i]; - if(in_array($field["type"], $types) && $field["productField"] == $product_id){ - $fields[] = $field; - } - } - $_product_fields[$key] = $fields; - } - return $_product_fields[$key]; - } - - private static function get_month_dropdown($name="", $id="", $selected_value="", $tabindex="", $disabled_text=""){ - return self::get_number_dropdown($name, $id, $selected_value, $tabindex, $disabled_text, __("Month", "gravityforms"), 1, 12); - } - - private static function get_day_dropdown($name="", $id="", $selected_value="", $tabindex="", $disabled_text=""){ - return self::get_number_dropdown($name, $id, $selected_value, $tabindex, $disabled_text, __("Day", "gravityforms"), 1, 31); - } - - private static function get_year_dropdown($name="", $id="", $selected_value="", $tabindex="", $disabled_text=""){ - $year_min = apply_filters("gform_date_min_year", "1920"); - $year_max = apply_filters("gform_date_max_year", date("Y") + 1); - return self::get_number_dropdown($name, $id, $selected_value, $tabindex, $disabled_text, __("Year", "gravityforms"), $year_max, $year_min); - } - - private static function get_number_dropdown($name, $id, $selected_value, $tabindex, $disabled_text, $placeholder, $start_number, $end_number){ - $str = ""; - return $str; - } - - private static function get_logic_event($field, $event){ - if(empty($field["conditionalLogicFields"]) || IS_ADMIN) - return ""; - - switch($event){ - case "keyup" : - return "onchange='gf_apply_rules(" . $field["formId"] . "," . GFCommon::json_encode($field["conditionalLogicFields"]) . ");' onkeyup='clearTimeout(__gf_timeout_handle); __gf_timeout_handle = setTimeout(\"gf_apply_rules(" . $field["formId"] . "," . GFCommon::json_encode($field["conditionalLogicFields"]) . ")\", 300);'"; - break; - - case "click" : - return "onclick='gf_apply_rules(" . $field["formId"] . "," . GFCommon::json_encode($field["conditionalLogicFields"]) . ");'"; - break; - - case "change" : - return "onchange='gf_apply_rules(" . $field["formId"] . "," . GFCommon::json_encode($field["conditionalLogicFields"]) . ");'"; - break; - } - } - - public static function has_field_calculation($field) { - - if($field['type'] == 'number') { - return rgar($field, 'enableCalculation') && rgar($field, 'calculationFormula'); - } - - return RGFormsModel::get_input_type($field) == 'calculation'; - } - - public static function get_field_input($field, $value="", $lead_id=0, $form_id=0){ - - $id = $field["id"]; - $field_id = IS_ADMIN || $form_id == 0 ? "input_$id" : "input_" . $form_id . "_$id"; - $form_id = IS_ADMIN && empty($form_id) ? rgget("id") : $form_id; - - $size = rgar($field, "size"); - $disabled_text = (IS_ADMIN && RG_CURRENT_VIEW != "entry") ? "disabled='disabled'" : ""; - $class_suffix = RG_CURRENT_VIEW == "entry" ? "_admin" : ""; - $class = $size . $class_suffix; - - $currency = ""; - if(RG_CURRENT_VIEW == "entry"){ - $lead = RGFormsModel::get_lead($lead_id); - $post_id = $lead["post_id"]; - $post_link = ""; - if(is_numeric($post_id) && self::is_post_field($field)){ - $post_link = "You can edit this post from the post page."; - } - $currency = $lead["currency"]; - } - - $field_input = apply_filters("gform_field_input", "", $field, $value, $lead_id, $form_id); - if($field_input) - return $field_input; - - //product fields are not editable - if(RG_CURRENT_VIEW == "entry" && self::is_product_field($field["type"])) - return "
    " . __("Product fields are not editable", "gravityforms") . "
    "; - - else if(RG_CURRENT_VIEW == "entry" && $field["type"] == "donation") - return "
    " . __("Donations are not editable", "gravityforms") . "
    "; - - // add categories as choices for Post Category field - if($field['type'] == 'post_category') - $field = self::add_categories_as_choices($field, $value); - - $max_length = ""; - $html5_attributes = ""; - - switch(RGFormsModel::get_input_type($field)){ - - case "total" : - if(RG_CURRENT_VIEW == "entry") - return "
    "; - else - return "
    " . self::to_money("0") . "
    "; - break; - - case "calculation" : - case "singleproduct" : - - $product_name = !is_array($value) || empty($value[$field["id"] . ".1"]) ? esc_attr($field["label"]) : esc_attr($value[$field["id"] . ".1"]); - $price = !is_array($value) || empty($value[$field["id"] . ".2"]) ? rgget("basePrice", $field) : esc_attr($value[$field["id"] . ".2"]); - $quantity = is_array($value) ? esc_attr($value[$field["id"] . ".3"]) : ""; - - if(empty($price)) - $price = 0; - - $form = RGFormsModel::get_form_meta($form_id); - $has_quantity = sizeof(GFCommon::get_product_fields_by_type($form, array("quantity"), $field["id"])) > 0; - if($has_quantity) - $field["disableQuantity"] = true; - - $quantity_field = ""; - - $qty_input_type = GFFormsModel::is_html5_enabled() ? "number" : "text"; - - if(IS_ADMIN){ - $style = rgget("disableQuantity", $field) ? "style='display:none;'" : ""; - $quantity_field = " " . apply_filters("gform_product_quantity_{$form_id}",apply_filters("gform_product_quantity",__("Quantity:", "gravityforms"), $form_id), $form_id) . " "; - } - else if(!rgget("disableQuantity", $field)){ - $tabindex = self::get_tabindex(); - $quantity_field .= " " . apply_filters("gform_product_quantity_{$form_id}",apply_filters("gform_product_quantity",__("Quantity:", "gravityforms"), $form_id), $form_id) . " "; - } - else{ - if(!is_numeric($quantity)) - $quantity = 1; - - if(!$has_quantity){ - $quantity_field .= ""; - } - } - - return "
    " . apply_filters("gform_product_price_{$form_id}", apply_filters("gform_product_price",__("Price", "gravityforms"), $form_id), $form_id) . ": " . esc_html(GFCommon::to_money($price, $currency)) ."{$quantity_field}
    "; - - break; - - case "hiddenproduct" : - - $form = RGFormsModel::get_form_meta($form_id); - $has_quantity_field = sizeof(GFCommon::get_product_fields_by_type($form, array("quantity"), $field["id"])) > 0; - - $product_name = !is_array($value) || empty($value[$field["id"] . ".1"]) ? esc_attr($field["label"]) : esc_attr($value[$field["id"] . ".1"]); - $quantity = is_array($value) ? esc_attr($value[$field["id"] . ".3"]) : "1"; - $price = !is_array($value) || empty($value[$field["id"] . ".2"]) ? rgget("basePrice", $field) : esc_attr($value[$field["id"] . ".2"]); - if(empty($price)) - $price = 0; - - $quantity_field = $has_quantity_field ? "" : ""; - $product_name_field = ""; - - $field_type = IS_ADMIN ? "text" : "hidden"; - - return $quantity_field . $product_name_field . sprintf("", $id, esc_attr($price), $disabled_text); - - break; - - case "singleshipping" : - - $price = !empty($value) ? $value : rgget("basePrice", $field); - if(empty($price)) - $price = 0; - - return "
    " . GFCommon::to_money($price, $currency) ."
    "; - - break; - - case "website": - $is_html5 = RGFormsModel::is_html5_enabled(); - $value = empty($value) && !$is_html5 ? "http://" : $value; - $html_input_type = $is_html5 ? "url" : "text"; - $html5_attributes = $is_html5 ? "placeholder='http://'" : ""; - case "text": - if(empty($html_input_type)) - $html_input_type = "text"; - - if(rgget("enablePasswordInput", $field) && RG_CURRENT_VIEW != "entry") - $html_input_type = "password"; - - if(is_numeric(rgget("maxLength", $field))) - $max_length = "maxlength='{$field["maxLength"]}'"; - - if(!empty($post_link)) - return $post_link; - - $logic_event = self::get_logic_event($field, "keyup"); - - $tabindex = self::get_tabindex(); - return sprintf("
    ", $id, $field_id, $html_input_type, esc_attr($value), esc_attr($class), $disabled_text); - break; - - case "email": - - if(!empty($post_link)) - return $post_link; - - $html_input_type = RGFormsModel::is_html5_enabled() ? "email" : "text"; - - if(IS_ADMIN && RG_CURRENT_VIEW != "entry"){ - $single_style = rgget("emailConfirmEnabled", $field) ? "style='display:none;'" : ""; - $confirm_style = rgget("emailConfirmEnabled", $field) ? "" : "style='display:none;'"; - return "
    "; - } - else{ - $logic_event = self::get_logic_event($field, "keyup"); - - if(rgget("emailConfirmEnabled", $field) && RG_CURRENT_VIEW != "entry"){ - $first_tabindex = self::get_tabindex(); - $last_tabindex = self::get_tabindex(); - return "
    "; - } - else{ - $tabindex = self::get_tabindex(); - return sprintf("
    ", $id, $field_id, $html_input_type, esc_attr($value), esc_attr($class), $disabled_text); - } - } - - break; - case "honeypot": - $autocomplete = RGFormsModel::is_html5_enabled() ? "autocomplete='off'" : ""; - return "
    "; - break; - - case "hidden" : - if(!empty($post_link)) - return $post_link; - - $field_type = IS_ADMIN ? "text" : "hidden"; - $class_attribute = IS_ADMIN ? "" : "class='gform_hidden'"; - - return sprintf("", $id, $field_id, esc_attr($value), $disabled_text); - break; - - case "html" : - $content = IS_ADMIN ? "
    " . __("HTML Content", "gravityforms") . "" . __("This is a content placeholder. HTML content is not displayed in the form admin. Preview this form to view the content.", "gravityforms") . "
    " : $field["content"]; - $content = GFCommon::replace_variables_prepopulate($content); //adding support for merge tags - $content = do_shortcode($content); //adding support for shortcodes - return $content; - break; - - case "adminonly_hidden" : - if(!is_array($field["inputs"])){ - if(is_array($value)) - $value = json_encode($value); - return sprintf("", $id, $field_id, esc_attr($value)); - } - - - $fields = ""; - foreach($field["inputs"] as $input){ - $fields .= sprintf("", $input["id"], esc_attr(rgar($value, strval($input["id"])))); - } - return $fields; - break; - - case "number" : - if(!empty($post_link)) - return $post_link; - - $instruction = ""; - $read_only = ""; - - if(!IS_ADMIN){ - - if(GFCommon::has_field_calculation($field)) { - - // calculation-enabled fields should be read only - $read_only = 'readonly="readonly"'; - - } else { - - $message = self::get_range_message($field); - $validation_class = $field["failed_validation"] ? "validation_message" : ""; - - if(!$field["failed_validation"] && !empty($message) && empty($field["errorMessage"])) - $instruction = "
    " . $message . "
    "; - - } - - } - $is_html5 = RGFormsModel::is_html5_enabled(); - $html_input_type = $is_html5 && !GFCommon::has_field_calculation($field) && !$field["numberFormat"] == "currency" ? "number" : "text"; // chrome does not allow number fields to have commas, calculations and currency values display numbers with commas - $step_attr = $is_html5 ? "step='any'" : ""; - - $logic_event = self::get_logic_event($field, "keyup"); - - $tabindex = self::get_tabindex(); - return sprintf("
    %s
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text, $instruction); - - case "donation" : - $tabindex = self::get_tabindex(); - return sprintf("
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text); - - case "price" : - $logic_event = self::get_logic_event($field, "keyup"); - - $tabindex = self::get_tabindex(); - return sprintf("
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text); - - case "phone" : - if(!empty($post_link)) - return $post_link; - - $instruction = $field["phoneFormat"] == "standard" ? __("Phone format:", "gravityforms") . " (###)###-####" : ""; - $instruction_div = rgget("failed_validation", $field) && !empty($instruction) ? "
    $instruction
    " : ""; - $html_input_type = RGFormsModel::is_html5_enabled() ? "tel" : "text"; - $logic_event = self::get_logic_event($field, "keyup"); - - $tabindex = self::get_tabindex(); - return sprintf("
    {$instruction_div}
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text); - - case "textarea": - $max_chars = ""; - $logic_event = self::get_logic_event($field, "keyup"); - - $tabindex = self::get_tabindex(); - return sprintf("
    {$max_chars}", $id, $field_id, esc_attr($class), $disabled_text, esc_html($value)); - - case "post_title": - case "post_tags": - case "post_custom_field": - $tabindex = self::get_tabindex(); - $logic_event = self::get_logic_event($field, "keyup"); - - return !empty($post_link) ? $post_link : sprintf("
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text); - break; - - case "post_content": - case "post_excerpt": - $max_chars = ""; - $logic_event = self::get_logic_event($field, "keyup"); - - $tabindex = self::get_tabindex(); - return !empty($post_link) ? $post_link : sprintf("
    {$max_chars}", $id, $field_id, esc_attr($class), $disabled_text, esc_html($value)); - break; - - case "post_category" : - if(!empty($post_link)) - return $post_link; - - if(rgget("displayAllCategories", $field) && !IS_ADMIN){ - $default_category = rgget("categoryInitialItemEnabled", $field) ? "-1" : get_option('default_category'); - $selected = empty($value) ? $default_category : $value; - $args = array('echo' => 0, 'selected' => $selected, "class" => esc_attr($class) . " gfield_select", 'hide_empty' => 0, 'name' => "input_$id", 'orderby' => 'name', 'hierarchical' => true ); - if(self::$tab_index > 0) - $args["tab_index"] = self::$tab_index++; - - if(rgget("categoryInitialItemEnabled", $field)){ - $args["show_option_none"] = empty($field["categoryInitialItem"]) ? " " : $field["categoryInitialItem"]; - } - - $args = apply_filters("gform_post_category_args_{$field["id"]}", apply_filters("gform_post_category_args", $args, $field), $field); - - return "
    " . wp_dropdown_categories($args) . "
    "; - } - else{ - $tabindex = self::get_tabindex(); - if(is_array(rgar($field, "choices"))) - usort($field["choices"], create_function('$a,$b', 'return strcmp($a["text"], $b["text"]);')); - - $choices = self::get_select_choices($field, $value); - - //Adding first option - if(rgget("categoryInitialItemEnabled", $field)){ - $selected = empty($value) ? "selected='selected'" : ""; - $choices = "" . $choices; - } - - return sprintf("
    ", $id, $field_id, esc_attr($class), $disabled_text, $choices); - } - break; - - case "post_image" : - if(!empty($post_link)) - return $post_link; - - $title = esc_attr(rgget($field["id"] . ".1", $value)); - $caption = esc_attr(rgget($field["id"] . ".4", $value)); - $description = esc_attr(rgget($field["id"] . ".7", $value)); - - //hidding meta fields for admin - $hidden_style = "style='display:none;'"; - $title_style = !rgget("displayTitle", $field) && IS_ADMIN ? $hidden_style : ""; - $caption_style = !rgget("displayCaption", $field) && IS_ADMIN ? $hidden_style : ""; - $description_style = !rgget("displayDescription", $field) && IS_ADMIN ? $hidden_style : ""; - $file_label_style = IS_ADMIN && !(rgget("displayTitle", $field) || rgget("displayCaption", $field) || rgget("displayDescription", $field)) ? $hidden_style : ""; - - $hidden_class = $preview = ""; - $file_info = RGFormsModel::get_temp_filename($form_id, "input_{$id}"); - if($file_info){ - $hidden_class = " gform_hidden"; - $file_label_style = $hidden_style; - $preview = "" . esc_html($file_info["uploaded_filename"]) . " | " . __("delete", "gravityforms") . ""; - } - - //in admin, render all meta fields to allow for immediate feedback, but hide the ones not selected - $file_label = (IS_ADMIN || rgget("displayTitle", $field) || rgget("displayCaption", $field) || rgget("displayDescription", $field)) ? "" : ""; - - $tabindex = self::get_tabindex(); - $upload = sprintf("{$preview}$file_label", $id, $field_id, esc_attr($value), esc_attr($class . $hidden_class), $disabled_text); - - $tabindex = self::get_tabindex(); - $title_field = rgget("displayTitle", $field) || IS_ADMIN ? sprintf("", $id, $field_id, $title, $disabled_text, $field_id) : ""; - - $tabindex = self::get_tabindex(); - $caption_field = rgget("displayCaption", $field) || IS_ADMIN ? sprintf("", $id, $field_id, $caption, $disabled_text, $field_id) : ""; - - $tabindex = self::get_tabindex(); - $description_field = rgget("displayDescription", $field) || IS_ADMIN? sprintf("", $id, $field_id, $description, $disabled_text, $field_id) : ""; - - return "
    " . $upload . $title_field . $caption_field . $description_field . "
    "; - - break; - - case "multiselect" : - if(!empty($post_link)) - return $post_link; - - $placeholder = rgar($field, "enableEnhancedUI") ? "data-placeholder='" . esc_attr(apply_filters("gform_multiselect_placeholder_{$form_id}", apply_filters("gform_multiselect_placeholder", __("Click to select...", "gravityforms"), $form_id), $form_id)) . "'" : ""; - $logic_event = self::get_logic_event($field, "keyup"); - $css_class = trim(esc_attr($class) . " gfield_select"); - $size = rgar($field, "multiSelectSize"); - if(empty($size)) - $size = 7; - - $tabindex = self::get_tabindex(); - return sprintf("
    ", $id, $field_id, $css_class, $disabled_text, self::get_select_choices($field, $value)); - - break; - - case "select" : - if(!empty($post_link)) - return $post_link; - - $logic_event = self::get_logic_event($field, "change"); - $css_class = trim(esc_attr($class) . " gfield_select"); - $tabindex = self::get_tabindex(); - return sprintf("
    ", $id, $field_id, $css_class, $disabled_text, self::get_select_choices($field, $value)); - - case "checkbox" : - if(!empty($post_link)) - return $post_link; - - return sprintf("
    ", $field_id, self::get_checkbox_choices($field, $value, $disabled_text)); - - case "radio" : - if(!empty($post_link)) - return $post_link; - - return sprintf("
    ", $field_id, self::get_radio_choices($field, $value, $disabled_text)); - - case "password" : - - $first_tabindex = self::get_tabindex(); - $last_tabindex = self::get_tabindex(); - - $strength_style = !rgar($field,"passwordStrengthEnabled") ? "style='display:none;'" : ""; - $strength = rgar($field,"passwordStrengthEnabled") || IS_ADMIN ? "
    " . __("Strength indicator", "gravityforms") . "
    " : ""; - - $action = !IS_ADMIN ? "gformShowPasswordStrength(\"$field_id\");" : ""; - $onchange= rgar($field,"passwordStrengthEnabled") ? "onchange='{$action}'" : ""; - $onkeyup = rgar($field,"passwordStrengthEnabled") ? "onkeyup='{$action}'" : ""; - - $pass = RGForms::post("input_" . $id ."_2"); - return sprintf("
    {$strength}", $id, $field_id, esc_attr($value), $disabled_text, $field_id, $id, $field_id, esc_attr($pass), $disabled_text, $field_id); - - case "name" : - $prefix = ""; - $first = ""; - $last = ""; - $suffix = ""; - if(is_array($value)){ - $prefix = esc_attr(RGForms::get($field["id"] . ".2", $value)); - $first = esc_attr(RGForms::get($field["id"] . ".3", $value)); - $last = esc_attr(RGForms::get($field["id"] . ".6", $value)); - $suffix = esc_attr(RGForms::get($field["id"] . ".8", $value)); - } - switch(rgget("nameFormat", $field)){ - - case "extended" : - $prefix_tabindex = self::get_tabindex(); - $first_tabindex = self::get_tabindex(); - $last_tabindex = self::get_tabindex(); - $suffix_tabindex = self::get_tabindex(); - return sprintf("
    ", $id, $field_id, $prefix, $disabled_text, $field_id, $id, $field_id, $first, $disabled_text, $field_id, $id, $field_id, $last, $disabled_text, $field_id, $id, $field_id, $suffix, $disabled_text, $field_id); - - case "simple" : - $tabindex = self::get_tabindex(); - return sprintf("
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text); - - default : - $first_tabindex = self::get_tabindex(); - $last_tabindex = self::get_tabindex(); - return sprintf("
    ", $id, $field_id, $first, $disabled_text, $field_id, $id, $field_id, $last, $disabled_text, $field_id); - } - - case "address" : - $street_value =""; - $street2_value =""; - $city_value =""; - $state_value =""; - $zip_value =""; - $country_value =""; - - if(is_array($value)){ - $street_value = esc_attr(rgget($field["id"] . ".1",$value)); - $street2_value = esc_attr(rgget($field["id"] . ".2",$value)); - $city_value = esc_attr(rgget($field["id"] . ".3",$value)); - $state_value = esc_attr(rgget($field["id"] . ".4",$value)); - $zip_value = esc_attr(rgget($field["id"] . ".5",$value)); - $country_value = esc_attr(rgget($field["id"] . ".6",$value)); - } - - $address_types = self::get_address_types($form_id); - $addr_type = empty($field["addressType"]) ? "international" : $field["addressType"]; - $address_type = $address_types[$addr_type]; - - $state_label = empty($address_type["state_label"]) ? __("State", "gravityforms") : $address_type["state_label"]; - $zip_label = empty($address_type["zip_label"]) ? __("Zip Code", "gravityforms") : $address_type["zip_label"]; - $hide_country = !empty($address_type["country"]) || rgget("hideCountry", $field); - - if(empty($country_value)) - $country_value = rgget("defaultCountry", $field); - - if(empty($state_value)) - $state_value = rgget("defaultState", $field); - - $country_list = self::get_country_dropdown($country_value); - - //changing css classes based on field format to ensure proper display - $address_display_format = apply_filters("gform_address_display_format", "default"); - $city_location = $address_display_format == "zip_before_city" ? "right" : "left"; - $zip_location = $address_display_format != "zip_before_city" && rgar($field,"hideState") ? "right" : "left"; - $state_location = $address_display_format == "zip_before_city" ? "left" : "right"; - $country_location = rgar($field,"hideState") ? "left" : "right"; - - //address field - $tabindex = self::get_tabindex(); - $street_address = sprintf("", $id, $field_id, $street_value, $disabled_text, $field_id); - - //address line 2 field - $street_address2 = ""; - $style = (IS_ADMIN && rgget("hideAddress2", $field)) ? "style='display:none;'" : ""; - if(IS_ADMIN || !rgget("hideAddress2", $field)){ - $tabindex = self::get_tabindex(); - $street_address2 = sprintf("", $id, $field_id, $street2_value, $disabled_text, $field_id); - } - - if($address_display_format == "zip_before_city"){ - //zip field - $tabindex = self::get_tabindex(); - $zip = sprintf("", $id, $field_id, $zip_value, $disabled_text, $field_id); - - //city field - $tabindex = self::get_tabindex(); - $city = sprintf("", $id, $field_id, $city_value, $disabled_text, $field_id); - - //state field - $style = (IS_ADMIN && rgget("hideState", $field)) ? "style='display:none;'" : ""; - if(IS_ADMIN || !rgget("hideState", $field)){ - $state_field = self::get_state_field($field, $id, $field_id, $state_value, $disabled_text, $form_id); - $state = sprintf("$state_field", $field_id); - } - else{ - $state = sprintf("", $id, $field_id, $state_value); - } - } - else{ - - //city field - $tabindex = self::get_tabindex(); - $city = sprintf("", $id, $field_id, $city_value, $disabled_text, $field_id); - - //state field - $style = (IS_ADMIN && rgget("hideState", $field)) ? "style='display:none;'" : ""; - if(IS_ADMIN || !rgget("hideState", $field)){ - $state_field = self::get_state_field($field, $id, $field_id, $state_value, $disabled_text, $form_id); - $state = sprintf("$state_field", $field_id); - } - else{ - $state = sprintf("", $id, $field_id, $state_value); - } - - //zip field - $tabindex = self::get_tabindex(); - $zip = sprintf("", $id, $field_id, $zip_value, $disabled_text, $field_id); - - } - - if(IS_ADMIN || !$hide_country){ - $style = $hide_country ? "style='display:none;'" : ""; - $tabindex = self::get_tabindex(); - $country = sprintf("", $id, $field_id, $disabled_text, $country_list, $field_id); - } - else{ - $country = sprintf("", $id, $field_id, $country_value); - } - - $inputs = $address_display_format == "zip_before_city" ? $street_address . $street_address2 . $zip . $city . $state . $country : $street_address . $street_address2 . $city . $state . $zip . $country; - - return "
    " . $inputs . "
    "; - - case "date" : - if(!empty($post_link)) - return $post_link; - - $format = empty($field["dateFormat"]) ? "mdy" : esc_attr($field["dateFormat"]); - $field_position = substr($format, 0, 3); - if(IS_ADMIN && RG_CURRENT_VIEW != "entry"){ - $datepicker_display = in_array(rgget("dateType", $field), array("datefield", "datedropdown")) ? "none" : "inline"; - $datefield_display = rgget("dateType", $field) == "datefield" ? "inline" : "none"; - $dropdown_display = rgget("dateType", $field) == "datedropdown" ? "inline" : "none"; - $icon_display = rgget("calendarIconType", $field) == "calendar" ? "inline" : "none"; - - $month_field = "
    "; - $day_field = "
    "; - $year_field = "
    "; - - $month_dropdown = "
    " . self::get_month_dropdown("","","","","disabled='disabled'") . "
    "; - $day_dropdown = "
    " . self::get_day_dropdown("","","","","disabled='disabled'") . "
    "; - $year_dropdown = "
    " . self::get_year_dropdown("","","","","disabled='disabled'") . "
    "; - - $field_string ="
    "; - - switch($field_position){ - case "dmy" : - $field_string .= $day_field . $month_field . $year_field . $day_dropdown . $month_dropdown . $year_dropdown; - break; - - case "ymd" : - $field_string .= $year_field . $month_field . $day_field . $year_dropdown . $month_dropdown . $day_dropdown; - break; - - default : - $field_string .= $month_field . $day_field . $year_field . $month_dropdown . $day_dropdown . $year_dropdown; - break; - } - - return $field_string; - } - else{ - $date_info = self::parse_date($value, $format); - $date_type = rgget("dateType", $field); - if(in_array($date_type, array("datefield", "datedropdown"))) - { - switch($field_position){ - - case "dmy" : - $tabindex = self::get_tabindex(); - $field_str = $date_type == "datedropdown" - ? "
    " . self::get_day_dropdown("input_{$id}[]", "{$field_id}_2", rgar($date_info,"day"), $tabindex, $disabled_text) . "
    " - : sprintf("
    ", $field_id, $id, $field_id, rgget("day", $date_info), $disabled_text, $field_id); - - $tabindex = self::get_tabindex(); - $field_str .= $date_type == "datedropdown" - ? "
    " . self::get_month_dropdown("input_{$id}[]", "{$field_id}_1", rgar($date_info,"month"), $tabindex, $disabled_text) . "
    " - : sprintf("
    ", $field_id, $id, $field_id, rgget("month", $date_info), $disabled_text, $field_id); - - $tabindex = self::get_tabindex(); - $field_str .= $date_type == "datedropdown" - ? "
    " . self::get_year_dropdown("input_{$id}[]", "{$field_id}_3", rgar($date_info,"year"), $tabindex, $disabled_text) . "
    " - : sprintf("
    ", $field_id, $id, $field_id, rgget("year", $date_info), $disabled_text, $field_id); - - break; - - case "ymd" : - $tabindex = self::get_tabindex(); - $field_str = $date_type == "datedropdown" - ? "
    " . self::get_year_dropdown("input_{$id}[]", "{$field_id}_3", rgar($date_info,"year"), $tabindex, $disabled_text) . "
    " - : sprintf("
    ", $field_id, $id, $field_id, rgget("year", $date_info), $disabled_text, $field_id); - - $field_str .= $date_type == "datedropdown" - ? "
    " . self::get_month_dropdown("input_{$id}[]", "{$field_id}_1", rgar($date_info,"month"), $tabindex, $disabled_text) . "
    " - : sprintf("
    ", $field_id, $id, $field_id, rgar($date_info,"month"), $disabled_text, $field_id); - - $tabindex = self::get_tabindex(); - $field_str .= $date_type == "datedropdown" - ? "
    " . self::get_day_dropdown("input_{$id}[]", "{$field_id}_2", rgar($date_info,"day"), $tabindex, $disabled_text) . "
    " - : sprintf("
    ", $field_id, $id, $field_id, rgar($date_info,"day"), $disabled_text, $field_id); - - break; - - default : - $tabindex = self::get_tabindex(); - - $field_str = $date_type == "datedropdown" - ? "
    " . self::get_month_dropdown("input_{$id}[]", "{$field_id}_1", rgar($date_info,"month"), $tabindex, $disabled_text) . "
    " - : sprintf("
    ", $field_id, $id, $field_id, rgar($date_info,"month"), $disabled_text, $field_id); - - $tabindex = self::get_tabindex(); - $field_str .= $date_type == "datedropdown" - ? "
    " . self::get_day_dropdown("input_{$id}[]", "{$field_id}_2", rgar($date_info,"day"), $tabindex, $disabled_text) . "
    " - : sprintf("
    ", $field_id, $id, $field_id, rgar($date_info,"day"), $disabled_text, $field_id); - - $tabindex = self::get_tabindex(); - $field_str .= $date_type == "datedropdown" - ? "
    " . self::get_year_dropdown("input_{$id}[]", "{$field_id}_3", rgar($date_info,"year"), $tabindex, $disabled_text) . "
    " - : sprintf("
    ", $field_id, $id, $field_id, rgget("year", $date_info), $disabled_text, $field_id); - - break; - } - - return $field_str; - } - else - { - $value = GFCommon::date_display($value, $format); - $icon_class = $field["calendarIconType"] == "none" ? "datepicker_no_icon" : "datepicker_with_icon"; - $icon_url = empty($field["calendarIconUrl"]) ? GFCommon::get_base_url() . "/images/calendar.png" : $field["calendarIconUrl"]; - $tabindex = self::get_tabindex(); - return sprintf("
    ", $id, $field_id, esc_attr($value), esc_attr($class), $format, $icon_class, $disabled_text); - } - } - - case "time" : - if(!empty($post_link)) - return $post_link; - - $hour = $minute = $am_selected = $pm_selected = ""; - - if(!is_array($value) && !empty($value)){ - preg_match('/^(\d*):(\d*) ?(.*)$/', $value, $matches); - $hour = esc_attr($matches[1]); - $minute = esc_attr($matches[2]); - $am_selected = rgar($matches,3) == "am" ? "selected='selected'" : ""; - $pm_selected = rgar($matches,3) == "pm" ? "selected='selected'" : ""; - } - else if(is_array($value)){ - $hour = esc_attr($value[0]); - $minute = esc_attr($value[1]); - $am_selected = rgar($value,2) == "am" ? "selected='selected'" : ""; - $pm_selected = rgar($value,2) == "pm" ? "selected='selected'" : ""; - } - $hour_tabindex = self::get_tabindex(); - $minute_tabindex = self::get_tabindex(); - $ampm_tabindex = self::get_tabindex(); - - $ampm_field_style = is_admin() && rgar($field, "timeFormat") == "24" ? "style='display:none;'" : ""; - $ampm_field = is_admin() || rgar($field, "timeFormat") != "24" ? "
    " : ""; - - return sprintf("
    :
    {$ampm_field}
    ", $field_id, $id, $field_id, $hour, $disabled_text, $field_id, $id, $field_id, $minute, $disabled_text, $field_id); - - case "fileupload" : - $tabindex = self::get_tabindex(); - $multiple_files = rgar($field, "multipleFiles"); - $file_list_id = "gform_preview_" . $form_id . "_". $id; - $max_upload_size = ! IS_ADMIN && isset($field["maxFileSize"]) && $field["maxFileSize"] > 0 ? $field["maxFileSize"] * 1048576: wp_max_upload_size(); - if($multiple_files){ - $upload_action_url = trailingslashit(site_url()) . "?gf_page=upload"; - $max_files = isset($field["maxFiles"]) && $field["maxFiles"] > 0 ? $field["maxFiles"]: 0; - $browse_button_id = 'gform_browse_button_' . $form_id . "_" . $id; - $container_id = 'gform_multifile_upload_' . $form_id . "_" . $id; - $drag_drop_id = 'gform_drag_drop_area_' . $form_id . "_" . $id; - - $messages_id = "gform_multifile_messages_{$form_id}_{$id}"; - $allowed_extensions = isset($field["allowedExtensions"]) && !empty($field["allowedExtensions"]) ? join(",", GFCommon::clean_extensions(explode(",", strtolower($field["allowedExtensions"])))) : array(); - if(empty($allowed_extensions)) - $allowed_extensions="*"; - $disallowed_extensions = GFCommon::get_disallowed_file_extensions(); - $plupload_init = defined('DOING_AJAX') && DOING_AJAX && "rg_change_input_type" === rgpost('action') ? array() : array( - 'runtimes' => 'html5,flash,html4', - 'browse_button' => $browse_button_id, - 'container' => $container_id, - 'drop_element' => $drag_drop_id, - 'filelist' => $file_list_id, - 'unique_names' => true, - 'file_data_name' => 'file', - 'multiple_queues' => true, - /*'chunk_size' => '10mb',*/ // chunking doesn't currently have very good cross-browser support - 'max_file_size' => $max_upload_size . 'b', - 'url' => $upload_action_url, - 'flash_swf_url' => includes_url('js/plupload/plupload.flash.swf'), - 'silverlight_xap_url' => includes_url('js/plupload/plupload.silverlight.xap'), - 'filters' => array( array('title' => __( 'Allowed Files', 'gravityforms' ), 'extensions' => $allowed_extensions) ), - 'multipart' => true, - 'urlstream_upload' => false, - 'multipart_params' => array( - "form_id" => $form_id, - "field_id" => $id - ), - 'gf_vars' => array( - 'max_files' => $max_files, - 'message_id' => $messages_id, - 'disallowed_extensions' => $disallowed_extensions - ) - ); - - // Multi-file uploading doesn't currently work in iOS Safari, - // single-file allows the built-in camera to be used as source for images - if ( wp_is_mobile() ) - $plupload_init['multi_selection'] = false; - - $plupload_init_json = htmlspecialchars(json_encode($plupload_init), ENT_QUOTES, 'UTF-8'); - $upload = sprintf("
    %s
    ",$container_id, $plupload_init_json, $drag_drop_id, __("Drop files here or" ,"gravityforms"), $browse_button_id, __("Select files", "gravityforms") ) ; - if(!IS_ADMIN) - $upload .= "
    "; - - if(IS_ADMIN && RG_CURRENT_VIEW === "entry") - $upload .= sprintf('', $id, esc_attr($value)); - - } else { - $upload = sprintf("", $max_upload_size); - $upload .= sprintf("", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text); - } - - if(IS_ADMIN && RG_CURRENT_VIEW === "entry" && !empty($value)){ // edit entry - $file_urls = $multiple_files ? json_decode($value) : array($value); - $upload_display = $multiple_files ? "" : "style='display:none'"; - $preview = "
    $upload
    "; - $preview .= sprintf("
    ", $file_list_id); - $preview .= sprintf("
    ", $id); - - foreach($file_urls as $file_index => $file_url){ - $file_url = esc_attr($file_url); - $preview .= sprintf("
    %s
    ", $file_index, $file_url, $file_url, $file_url, GFCommon::truncate_url($file_url), $file_url, GFCommon::get_base_url() . "/images/download.png", $lead_id, $id, GFCommon::get_base_url() . "/images/icon-delete.png"); - } - - $preview .="
    "; - - return $preview; - } else { - $input_name = "input_{$id}"; - $uploaded_files = isset(GFFormsModel::$uploaded_files[$form_id][$input_name]) ? GFFormsModel::$uploaded_files[$form_id][$input_name] : array(); - $file_infos = $multiple_files ? $uploaded_files : RGFormsModel::get_temp_filename($form_id, $input_name); - - if(!empty($file_infos)){ - $preview = sprintf("
    ", $file_list_id); - $file_infos = $multiple_files ? $uploaded_files : array($file_infos); - foreach($file_infos as $file_info){ - $preview .= "
    " . esc_html($file_info["uploaded_filename"]) . "
    "; - } - $preview .= "
    "; - if(!$multiple_files) - $upload = str_replace(" class='", " class='gform_hidden ", $upload); - return "
    " . $upload . " {$preview}
    "; - } - else{ - - $preview = $multiple_files ? sprintf("
    ", $file_list_id) : ""; - - return "
    $upload
    " . $preview; - } - } - - case "captcha" : - - switch(rgget("captchaType", $field)){ - case "simple_captcha" : - $size = rgempty("simpleCaptchaSize", $field) ? "medium" : $field["simpleCaptchaSize"]; - $captcha = self::get_captcha($field); - - $tabindex = self::get_tabindex(); - - $dimensions = IS_ADMIN ? "" : "width='" . rgar($captcha,"width") . "' height='" . rgar($captcha,"height") . "'"; - return "
    "; - break; - - case "math" : - $size = empty($field["simpleCaptchaSize"]) ? "medium" : $field["simpleCaptchaSize"]; - $captcha_1 = self::get_math_captcha($field, 1); - $captcha_2 = self::get_math_captcha($field, 2); - $captcha_3 = self::get_math_captcha($field, 3); - - $tabindex = self::get_tabindex(); - - $dimensions = IS_ADMIN ? "" : "width='{$captcha_1["width"]}' height='{$captcha_1["height"]}'"; - return "
    "; - break; - - default: - - if(!function_exists("recaptcha_get_html")){ - require_once(GFCommon::get_base_path() . '/recaptchalib.php'); - } - - $theme = empty($field["captchaTheme"]) ? "red" : esc_attr($field["captchaTheme"]); - $publickey = get_option("rg_gforms_captcha_public_key"); - $privatekey = get_option("rg_gforms_captcha_private_key"); - if(IS_ADMIN){ - if(empty($publickey) || empty($privatekey)){ - return "
    " . __("To use the reCaptcha field you must first do the following:", "gravityforms") . "
    1 - " . sprintf(__("Sign up%s for a free reCAPTCHA account", "gravityforms"), "") . "
    2 - " . sprintf(__("Enter your reCAPTCHA keys in the %ssettings page%s", "gravityforms"), "", "") . "
    "; - } - else{ - return "
    reCAPTCHA
    "; - } - } - else{ - $language = empty($field["captchaLanguage"]) ? "en" : esc_attr($field["captchaLanguage"]); - - if(empty(self::$tab_index)) - self::$tab_index = 1; - - $options = ""; - - $is_ssl = !empty($_SERVER['HTTPS']); - return $options . "
    " . recaptcha_get_html($publickey, null, $is_ssl, $language) . "
    "; - } - } - break; - - case "creditcard" : - - $card_number = ""; - $card_name = ""; - $expiration_date = ""; - $expiration_month = ""; - $expiration_year = ""; - $security_code = ""; - $autocomplete = RGFormsModel::is_html5_enabled() ? "autocomplete='off'" : ""; - - if(is_array($value)){ - $card_number = esc_attr(rgget($field["id"] . ".1",$value)); - $card_name = esc_attr(rgget($field["id"] . ".5",$value)); - $expiration_date = rgget($field["id"] . ".2",$value); - if(!is_array($expiration_date) && !empty($expiration_date)) - $expiration_date = explode("/", $expiration_date); - - if(is_array($expiration_date) && count($expiration_date) == 2){ - $expiration_month = $expiration_date[0]; - $expiration_year = $expiration_date[1]; - } - - $security_code = esc_attr(rgget($field["id"] . ".3",$value)); - } - - $action = !IS_ADMIN ? "gformMatchCard(\"{$field_id}_1\");" : ""; - - $onchange= "onchange='{$action}'"; - $onkeyup = "onkeyup='{$action}'"; - - $card_icons = ''; - $cards = GFCommon::get_card_types(); - $card_style = rgar($field, 'creditCardStyle') ? rgar($field, 'creditCardStyle') : 'style1'; - - foreach($cards as $card) { - - $style = ""; - if(self::is_card_supported($field, $card["slug"])){ - $print_card = true; - } - else if (IS_ADMIN){ - $print_card = true; - $style = "style='display:none;'"; - } - else{ - $print_card = false; - } - - if($print_card){ - $card_icons .= "
    {$card['name']}
    "; - } - } - - $payment_methods = apply_filters("gform_payment_methods", array(), $field, $form_id); - $payment_options = ""; - if(is_array($payment_methods)){ - foreach($payment_methods as $payment_method){ - $checked = rgpost("gform_payment_method") == $payment_method["key"] ? "checked='checked'" : ""; - $payment_options .="
    {$payment_method["label"]}
    "; - } - } - $checked = rgpost("gform_payment_method") == "creditcard" || rgempty("gform_payment_method") ? "checked='checked'" : ""; - $card_radio_button = empty($payment_options) ? "" : ""; - $card_icons = "{$payment_options}
    {$card_radio_button}{$card_icons}
    "; - - - - //card number fields - $tabindex = self::get_tabindex(); - $html5_output = GFFormsModel::is_html5_enabled() ? "pattern='[0-9]*' title='" . __("Only digits are allowed", "gravityforms") . "'" : ""; - $card_field = sprintf("{$card_icons}", $id, $field_id, $card_number, $disabled_text, $field_id); - - //expiration date field - $expiration_field = "". - - "". - - "". - - // month selector - "". - - // year selector - "". - - // label for the expiration fields - "". - - "". - ""; - - //security code field - $tabindex = self::get_tabindex(); - $html_input_type = GFFormsModel::is_html5_enabled() ? "number" : "text"; - $security_field = "". - "". - " ". - "". - "". - ""; - - $tabindex = self::get_tabindex(); - $card_name_field = sprintf("", $id, $field_id, $card_name, $disabled_text, $field_id); - - return "
    " . $card_field . $expiration_field . $security_field . $card_name_field . "
    "; - - break; - - case "list" : - - if(!empty($value)) - $value = maybe_unserialize($value); - - if(!is_array($value)) - $value = array(array()); - - $has_columns = is_array(rgar($field, "choices")); - $columns = $has_columns ? rgar($field, "choices") : array(array()); - - $list = "
    " . - ""; - - $class_attr = ""; - if($has_columns){ - - $list .= ""; - $colnum = 1; - foreach($columns as $column){ - $odd_even = ($colnum % 2) == 0 ? "even" : "odd"; - $list .= ""; - $colnum++; - } - $list .= ""; - - $list .= ""; - foreach($columns as $column){ - $list .= ""; - } - $list .= ""; - } - else{ - $list .= ""; - } - - $delete_display = count($value) == 1 ? "visibility:hidden;" : ""; - $maxRow = intval(rgar($field, "maxRows")); - $disabled_icon_class = !empty($maxRow) && count($value) >= $maxRow ? "gfield_icon_disabled" : ""; - - $list .= ""; - $rownum = 1; - foreach($value as $item){ - - $odd_even = ($rownum % 2) == 0 ? "even" : "odd"; - - $list .= ""; - $colnum = 1; - foreach($columns as $column){ - - //getting value. taking into account columns being added/removed from form meta - if(is_array($item)){ - if($has_columns){ - $val = rgar($item, $column["text"]); - } - else{ - $vals = array_values($item); - $val = rgar($vals, 0); - } - } - else{ - $val = $colnum == 1 ? $item : ""; - } - - $list .= ""; - $colnum++; - } - - $add_icon = !rgempty("addIconUrl", $field) ? $field["addIconUrl"] : GFCommon::get_base_url() . "/images/add.png"; - $delete_icon = !rgempty("deleteIconUrl", $field) ? $field["deleteIconUrl"] : GFCommon::get_base_url() . "/images/remove.png"; - - $on_click = IS_ADMIN && RG_CURRENT_VIEW != "entry" ? "" : "onclick='gformAddListItem(this, {$maxRow})'"; - - if(rgar($field, "maxRows") != 1){ - - // can't replace these icons with the webfont versions since they appear on the front end. - - $list .=""; - } - - $list .= ""; - - if(!empty($maxRow) && $rownum >= $maxRow) - break; - - $rownum++; - } - - $list .="
    " . esc_html($column["text"]) . " 
    " . self::get_list_input($field, $has_columns, $column, $val, $form_id) . ""; - $list .=" " . __("Add a row", "gravityforms") . "" . - " " . __("Remove this row", "gravityforms") . ""; - - $list .="
    "; - - return $list; - break; - } - } - - public static function is_ssl(){ - global $wordpress_https; - $is_ssl = false; - - $has_https_plugin = class_exists('WordPressHTTPS') && isset($wordpress_https); - $has_is_ssl_method = $has_https_plugin && method_exists('WordPressHTTPS', 'is_ssl'); - $has_isSsl_method = $has_https_plugin && method_exists('WordPressHTTPS', 'isSsl'); - - //Use the WordPress HTTPs plugin if installed - if ($has_https_plugin && $has_is_ssl_method){ - $is_ssl = $wordpress_https->is_ssl(); - } - else if ($has_https_plugin && $has_isSsl_method){ - $is_ssl = $wordpress_https->isSsl(); - } - else{ - $is_ssl = is_ssl(); - } - - - if(!$is_ssl && isset($_SERVER["HTTP_CF_VISITOR"]) && strpos($_SERVER["HTTP_CF_VISITOR"], "https")){ - $is_ssl=true; - } - - return apply_filters("gform_is_ssl", $is_ssl); - } - - public static function is_card_supported($field, $card_slug){ - $supported_cards = rgar($field, 'creditCards'); - $default_cards = array('amex', 'discover', 'mastercard', 'visa'); - - if(!empty($supported_cards) && in_array($card_slug, $supported_cards)) { - return true; - } - else if(empty($supported_cards) && in_array($card_slug, $default_cards)) { - return true; - } - - return false; - - } - - public static function is_preview(){ - $url_info = parse_url(RGFormsModel::get_current_page_url()); - $file_name = basename($url_info["path"]); - return $file_name == "preview.php" || rgget("gf_page", $_GET) == "preview"; - } - - private static function get_expiration_months($selected_month){ - $str = ""; - for($i=1; $i<13; $i++){ - $selected = intval($selected_month) == $i ? "selected='selected'" : ""; - $month = str_pad($i, 2, "0", STR_PAD_LEFT); - $str .= ""; - } - return $str; - } - - private static function get_expiration_years($selected_year){ - $str = ""; - $year = intval(date("Y")); - for($i=$year; $i < ($year + 20); $i++){ - $selected = intval($selected_year) == $i ? "selected='selected'" : ""; - $str .= ""; - } - return $str; - } - - private static function get_list_input($field, $has_columns, $column, $value, $form_id){ - - $tabindex = GFCommon::get_tabindex(); - - $column_index = 1; - if($has_columns && is_array(rgar($field, "choices"))){ - foreach($field["choices"] as $choice){ - if($choice["text"] == $column["text"]) - break; - - $column_index++; - } - } - $input_info = array("type" => "text"); - - $input_info = apply_filters("gform_column_input_{$form_id}_{$field["id"]}_{$column_index}", apply_filters("gform_column_input", $input_info, $field, rgar($column, "text"), $value, $form_id), $field, rgar($column, "text"), $value, $form_id); - - switch($input_info["type"]){ - - case "select" : - $input = ""; - - break; - - default : - $input = ""; - break; - } - - return apply_filters("gform_column_input_content_{$form_id}_{$field["id"]}_{$column_index}", - apply_filters("gform_column_input_content", $input, $input_info, $field, rgar($column, "text"), $value, $form_id), - $input_info, $field, rgar($column, "text"), $value, $form_id); - - } - - public static function clean_extensions($extensions){ - $count = sizeof($extensions); - for($i=0; $i<$count; $i++){ - $extensions[$i] = str_replace(".", "",str_replace(" ", "", $extensions[$i])); - } - return $extensions; - } - - public static function get_disallowed_file_extensions(){ - return array("php", "asp", "exe", "com", "htaccess"); - } - - public static function to_money($number, $currency_code=""){ - if(!class_exists("RGCurrency")) - require_once("currency.php"); - - if(empty($currency_code)) - $currency_code = self::get_currency(); - - $currency = new RGCurrency($currency_code); - return $currency->to_money($number); - } - - public static function to_number($text, $currency_code=""){ - if(!class_exists("RGCurrency")) - require_once("currency.php"); - - if(empty($currency_code)) - $currency_code = self::get_currency(); - - $currency = new RGCurrency($currency_code); - - return $currency->to_number($text); - } - - public static function get_currency(){ - $currency = get_option("rg_gforms_currency"); - $currency = empty($currency) ? "USD" : $currency; - - return apply_filters("gform_currency", $currency); - } - - - public static function get_simple_captcha(){ - $captcha = new ReallySimpleCaptcha(); - $captcha->tmp_dir = RGFormsModel::get_upload_path("captcha") . "/"; - return $captcha; - } - - public static function get_captcha($field){ - if(!class_exists("ReallySimpleCaptcha")) - return array(); - - $captcha = self::get_simple_captcha(); - - //If captcha folder does not exist and can't be created, return an empty captcha - if(!wp_mkdir_p($captcha->tmp_dir)) - return array(); - - $captcha->char_length = 5; - switch(rgar($field,"simpleCaptchaSize")){ - case "small" : - $captcha->img_size = array( 100, 28 ); - $captcha->font_size = 18; - $captcha->base = array( 8, 20 ); - $captcha->font_char_width = 17; - - break; - - case "large" : - $captcha->img_size = array( 200, 56 ); - $captcha->font_size = 32; - $captcha->base = array( 18, 42 ); - $captcha->font_char_width = 35; - break; - - default : - $captcha->img_size = array( 150, 42 ); - $captcha->font_size = 26; - $captcha->base = array( 15, 32 ); - $captcha->font_char_width = 25; - break; - } - - if(!empty($field["simpleCaptchaFontColor"])){ - $captcha->fg = self::hex2rgb($field["simpleCaptchaFontColor"]); - } - if(!empty($field["simpleCaptchaBackgroundColor"])){ - $captcha->bg = self::hex2rgb($field["simpleCaptchaBackgroundColor"]); - } - - $word = $captcha->generate_random_word(); - $prefix = mt_rand(); - $filename = $captcha->generate_image($prefix, $word); - $url = RGFormsModel::get_upload_url("captcha") . "/" . $filename; - $path = $captcha->tmp_dir . $filename; - - if(self::is_ssl() && strpos($url, "http:") !== false ){ - $url = str_replace("http:", "https:", $url); - } - - return array("path"=>$path, "url"=> $url, "height" => $captcha->img_size[1], "width" => $captcha->img_size[0], "prefix" => $prefix); - } - - public static function get_math_captcha($field, $pos){ - if(!class_exists("ReallySimpleCaptcha")) - return array(); - - $captcha = self::get_simple_captcha(); - - //If captcha folder does not exist and can't be created, return an empty captcha - if(!wp_mkdir_p($captcha->tmp_dir)) - return array(); - - $captcha->char_length = 1; - if($pos == 1 || $pos == 3) - $captcha->chars = '0123456789'; - else - $captcha->chars = '+'; - - switch(rgar($field,"simpleCaptchaSize")){ - case "small" : - $captcha->img_size = array( 23, 28 ); - $captcha->font_size = 18; - $captcha->base = array( 6, 20 ); - $captcha->font_char_width = 17; - - break; - - case "large" : - $captcha->img_size = array( 36, 56 ); - $captcha->font_size = 32; - $captcha->base = array( 10, 42 ); - $captcha->font_char_width = 35; - break; - - default : - $captcha->img_size = array( 30, 42 ); - $captcha->font_size = 26; - $captcha->base = array( 9, 32 ); - $captcha->font_char_width = 25; - break; - } - - if(!empty($field["simpleCaptchaFontColor"])){ - $captcha->fg = self::hex2rgb($field["simpleCaptchaFontColor"]); - } - if(!empty($field["simpleCaptchaBackgroundColor"])){ - $captcha->bg = self::hex2rgb($field["simpleCaptchaBackgroundColor"]); - } - - $word = $captcha->generate_random_word(); - $prefix = mt_rand(); - $filename = $captcha->generate_image($prefix, $word); - $url = RGFormsModel::get_upload_url("captcha") . "/" . $filename; - $path = $captcha->tmp_dir . $filename; - - return array("path"=>$path, "url"=> $url, "height" => $captcha->img_size[1], "width" => $captcha->img_size[0], "prefix" => $prefix); - } - - private static function hex2rgb($color){ - if ($color[0] == '#') - $color = substr($color, 1); - - if (strlen($color) == 6) - list($r, $g, $b) = array($color[0].$color[1], - $color[2].$color[3], - $color[4].$color[5]); - elseif (strlen($color) == 3) - list($r, $g, $b) = array($color[0].$color[0], $color[1].$color[1], $color[2].$color[2]); - else - return false; - - $r = hexdec($r); $g = hexdec($g); $b = hexdec($b); - - return array($r, $g, $b); - } - - public static function get_address_types($form_id){ - - $addressTypes = array( - "international" => array("label" => __("International", "gravityforms"),"zip_label" => apply_filters("gform_address_zip_{$form_id}",apply_filters("gform_address_zip", __("ZIP / Postal Code", "gravityforms"), $form_id), $form_id),"state_label" => apply_filters("gform_address_state_{$form_id}",apply_filters("gform_address_state",__("State / Province / Region", "gravityforms"), $form_id), $form_id)), - "us" => array("label" => __("United States", "gravityforms"),"zip_label" => apply_filters("gform_address_zip_{$form_id}",apply_filters("gform_address_zip", __("ZIP Code", "gravityforms"), $form_id), $form_id), "state_label" => apply_filters("gform_address_state_{$form_id}",apply_filters("gform_address_state",__("State", "gravityforms"), $form_id), $form_id), "country" => "United States", "states" => array_merge(array(''), GFCommon::get_us_states())), - "canadian" => array("label" => __("Canadian", "gravityforms"), "zip_label" => apply_filters("gform_address_zip_{$form_id}",apply_filters("gform_address_zip", __("Postal Code", "gravityforms"), $form_id), $form_id), "state_label" => apply_filters("gform_address_state_{$form_id}",apply_filters("gform_address_state",__("Province", "gravityforms"), $form_id), $form_id),"country" => "Canada", "states" => array_merge(array(''), GFCommon::get_canadian_provinces())) - ); - - return apply_filters("gform_address_types_{$form_id}", apply_filters("gform_address_types", $addressTypes, $form_id), $form_id); - } - - private static function get_state_field($field, $id, $field_id, $state_value, $disabled_text, $form_id){ - $state_dropdown_class = $state_text_class = $state_style = $text_style = $state_field_id = ""; - - if(empty($state_value)){ - $state_value = rgget("defaultState", $field); - - //for backwards compatibility (canadian address type used to store the default state into the defaultProvince property) - if (rgget("addressType", $field) == "canadian" && !rgempty("defaultProvince", $field)) - $state_value = $field["defaultProvince"]; - } - - $address_type = rgempty("addressType", $field) ? "international" : $field["addressType"]; - $address_types = self::get_address_types($form_id); - $has_state_drop_down = isset($address_types[$address_type]["states"]) && is_array($address_types[$address_type]["states"]); - - if(IS_ADMIN && RG_CURRENT_VIEW != "entry"){ - $state_dropdown_class = "class='state_dropdown'"; - $state_text_class = "class='state_text'"; - $state_style = !$has_state_drop_down ? "style='display:none;'" : ""; - $text_style = $has_state_drop_down ? "style='display:none;'" : ""; - $state_field_id = ""; - } - else{ - //id only displayed on front end - $state_field_id = "id='" . $field_id . "_4'"; - } - - $tabindex = self::get_tabindex(); - $states = empty($address_types[$address_type]["states"]) ? array() : $address_types[$address_type]["states"]; - $state_dropdown = sprintf("", $id, $state_field_id, $disabled_text, GFCommon::get_state_dropdown($states, $state_value)); - - $tabindex = self::get_tabindex(); - $state_text = sprintf("", $id, $state_field_id, $state_value, $disabled_text); - - if(IS_ADMIN && RG_CURRENT_VIEW != "entry") - return $state_dropdown . $state_text; - else if($has_state_drop_down) - return $state_dropdown; - else - return $state_text; - } - - public static function get_lead_field_display($field, $value, $currency="", $use_text=false, $format="html", $media="screen"){ - - if($field['type'] == 'post_category') - $value = self::prepare_post_category_value($value, $field); - - switch(RGFormsModel::get_input_type($field)){ - case "name" : - if(is_array($value)){ - $prefix = trim(rgget($field["id"] . ".2", $value)); - $first = trim(rgget($field["id"] . ".3", $value)); - $last = trim(rgget($field["id"] . ".6", $value)); - $suffix = trim(rgget($field["id"] . ".8", $value)); - - $name = $prefix; - $name .= !empty($name) && !empty($first) ? " $first" : $first; - $name .= !empty($name) && !empty($last) ? " $last" : $last; - $name .= !empty($name) && !empty($suffix) ? " $suffix" : $suffix; - - return $name; - } - else{ - return $value; - } - - break; - case "creditcard" : - if(is_array($value)){ - $card_number = trim(rgget($field["id"] . ".1", $value)); - $card_type = trim(rgget($field["id"] . ".4", $value)); - $separator = $format == "html" ? "
    " : "\n"; - return empty($card_number) ? "" : $card_type . $separator . $card_number; - } - else{ - return ""; - } - break; - - case "address" : - if(is_array($value)){ - $street_value = trim(rgget($field["id"] . ".1", $value)); - $street2_value = trim(rgget($field["id"] . ".2", $value)); - $city_value = trim(rgget($field["id"] . ".3", $value)); - $state_value = trim(rgget($field["id"] . ".4", $value)); - $zip_value = trim(rgget($field["id"] . ".5", $value)); - $country_value = trim(rgget($field["id"] . ".6", $value)); - - $line_break = $format == "html" ? "
    " : "\n"; - - $address_display_format = apply_filters("gform_address_display_format", "default"); - if($address_display_format == "zip_before_city"){ - /* - Sample: - 3333 Some Street - suite 16 - 2344 City, State - Country - */ - - $addr_ary = array(); - $addr_ary[] = $street_value; - - if(!empty($street2_value)) - $addr_ary[] = $street2_value; - - $zip_line = trim($zip_value . " " . $city_value); - $zip_line .= !empty($zip_line) && !empty($state_value) ? ", {$state_value}" : $state_value; - $zip_line = trim($zip_line); - if(!empty($zip_line)) - $addr_ary[] = $zip_line; - - if(!empty($country_value)) - $addr_ary[] = $country_value; - - $address = implode("
    ", $addr_ary); - - } - else{ - $address = $street_value; - $address .= !empty($address) && !empty($street2_value) ? $line_break . $street2_value : $street2_value; - $address .= !empty($address) && (!empty($city_value) || !empty($state_value)) ? $line_break. $city_value : $city_value; - $address .= !empty($address) && !empty($city_value) && !empty($state_value) ? ", $state_value" : $state_value; - $address .= !empty($address) && !empty($zip_value) ? " $zip_value" : $zip_value; - $address .= !empty($address) && !empty($country_value) ? $line_break . $country_value : $country_value; - } - - //adding map link - if(!empty($address) && $format == "html"){ - $address_qs = str_replace($line_break, " ", $address); //replacing
    and \n with spaces - $address_qs = urlencode($address_qs); - $address .= "
    Map It"; - } - - return $address; - } - else{ - return ""; - } - break; - - case "email" : - return GFCommon::is_valid_email($value) && $format == "html" ? "$value" : $value; - break; - - case "website" : - return GFCommon::is_valid_url($value) && $format == "html" ? "$value" : $value; - break; - - case "checkbox" : - if(is_array($value)){ - - $items = ''; - - foreach($value as $key => $item){ - if(!empty($item)){ - switch($format){ - case "text" : - $items .= GFCommon::selection_display($item, $field, $currency, $use_text) . ", "; - break; - - default: - $items .= "
  • " . GFCommon::selection_display($item, $field, $currency, $use_text) . "
  • "; - break; - } - } - } - if(empty($items)){ - return ""; - } - else if($format == "text"){ - return substr($items, 0, strlen($items)-2); //removing last comma - } - else{ - return ""; - } - } - else{ - return $value; - } - break; - - case "post_image" : - $ary = explode("|:|", $value); - $url = count($ary) > 0 ? $ary[0] : ""; - $title = count($ary) > 1 ? $ary[1] : ""; - $caption = count($ary) > 2 ? $ary[2] : ""; - $description = count($ary) > 3 ? $ary[3] : ""; - - if(!empty($url)){ - $url = str_replace(" ", "%20", $url); - - switch($format){ - case "text" : - $value = $url; - $value .= !empty($title) ? "\n\n" . $field["label"] . " (" . __("Title", "gravityforms") . "): " . $title : ""; - $value .= !empty($caption) ? "\n\n" . $field["label"] . " (" . __("Caption", "gravityforms") . "): " . $caption : ""; - $value .= !empty($description) ? "\n\n" . $field["label"] . " (" . __("Description", "gravityforms") . "): " . $description : ""; - break; - - default : - $value = ""; - $value .= !empty($title) ? "
    Title: $title
    " : ""; - $value .= !empty($caption) ? "
    Caption: $caption
    " : ""; - $value .= !empty($description) ? "
    Description: $description
    ": ""; - - break; - } - } - return $value; - - case "fileupload" : - $output = $format == "text" ? "" : ""; - return $output; - break; - - case "date" : - return GFCommon::date_display($value, rgar($field, "dateFormat")); - break; - - case "radio" : - case "select" : - return GFCommon::selection_display($value, $field, $currency, $use_text); - break; - - case "multiselect" : - if(empty($value) || $format == "text") - return $value; - - $value = explode(",", $value); - - $items = ''; - foreach($value as $item){ - $items .= "
  • " . GFCommon::selection_display($item, $field, $currency, $use_text) . "
  • "; - } - - return ""; - - break; - - case "calculation" : - case "singleproduct" : - if(is_array($value) && !empty($value)){ - $product_name = trim($value[$field["id"] . ".1"]); - $price = trim($value[$field["id"] . ".2"]); - $quantity = trim($value[$field["id"] . ".3"]); - - $product = $product_name . ", " . __("Qty: ", "gravityforms") . $quantity . ", " . __("Price: ", "gravityforms") . $price; - return $product; - } - else{ - return ""; - } - break; - - case "number" : - return GFCommon::format_number($value, rgar($field, "numberFormat")); - break; - - case "singleshipping" : - case "donation" : - case "total" : - case "price" : - return GFCommon::to_money($value, $currency); - - case "list" : - if(empty($value)) - return ""; - $value = unserialize($value); - - $has_columns = is_array($value[0]); - - if(!$has_columns){ - $items = ''; - foreach($value as $key => $item){ - if(!empty($item)){ - switch($format){ - case "text" : - $items .= $item . ", "; - break; - case "url" : - $items .= $item . ","; - break; - default : - if($media == "email"){ - $items .= "
  • {$item}
  • "; - } - else{ - $items .= "
  • {$item}
  • "; - } - break; - } - } - } - - if(empty($items)){ - return ""; - } - else if($format == "text"){ - return substr($items, 0, strlen($items)-2); //removing last comma - } - else if($format == "url"){ - return substr($items, 0, strlen($items)-1); //removing last comma - } - else if($media == "email"){ - return ""; - } - else{ - return ""; - } - } - else if(is_array($value)){ - $columns = array_keys($value[0]); - - $list = ""; - - switch($format){ - case "text" : - $is_first_row = true; - foreach($value as $item){ - if(!$is_first_row) - $list .= "\n\n" . $field["label"] . ": "; - $list .= implode(",", array_values($item)); - - $is_first_row = false; - } - break; - - case "url" : - foreach($value as $item){ - $list .= implode("|", array_values($item)) . ","; - } - if(!empty($list)) - $list = substr($list, 0, strlen($list)-1); - break; - - default : - if($media == "email"){ - $list = ""; - - //reading columns from entry data - foreach($columns as $column){ - $list .= ""; - } - $list .= ""; - - $list .= ""; - foreach($value as $item){ - $list .= ""; - foreach($columns as $column){ - $val = rgar($item, $column); - $list .= ""; - } - - $list .=""; - } - - $list .="
    " . esc_html($column) . "
    {$val}
    "; - } - else{ - $list = ""; - - //reading columns from entry data - foreach($columns as $column){ - $list .= ""; - } - $list .= ""; - - $list .= ""; - foreach($value as $item){ - $list .= ""; - foreach($columns as $column){ - $val = rgar($item, $column); - $list .= ""; - } - - $list .=""; - } - - $list .="
    " . esc_html($column) . "
    {$val}
    "; - } - break; - } - - return $list; - } - return ""; - break; - - default : - if (!is_array($value)) - { - return nl2br($value); - } - break; - } - } - - public static function get_product_fields($form, $lead, $use_choice_text=false, $use_admin_label=false){ - $products = array(); - - $product_info = null; - // retrieve static copy of product info (only for "real" entries) - if(!rgempty("id", $lead)){ - $product_info = gform_get_meta(rgar($lead,'id'), "gform_product_info_{$use_choice_text}_{$use_admin_label}"); - } - - // if no static copy, generate from form/lead info - if(!$product_info) { - - foreach($form["fields"] as $field){ - $id = $field["id"]; - $lead_value = RGFormsModel::get_lead_field_value($lead, $field); - - $quantity_field = self::get_product_fields_by_type($form, array("quantity"), $id); - $quantity = sizeof($quantity_field) > 0 && !RGFormsModel::is_field_hidden($form, $quantity_field[0], array(), $lead) ? RGFormsModel::get_lead_field_value($lead, $quantity_field[0]) : 1; - - switch($field["type"]){ - - case "product" : - - //ignore products that have been hidden by conditional logic - $is_hidden = RGFormsModel::is_field_hidden($form, $field, array(), $lead); - if($is_hidden) - continue; - - //if single product, get values from the multiple inputs - if(is_array($lead_value)){ - $product_quantity = sizeof($quantity_field) == 0 && !rgar($field,"disableQuantity") ? rgget($id . ".3", $lead_value) : $quantity; - if(empty($product_quantity)) - continue; - - if(!rgget($id, $products)) - $products[$id] = array(); - - $products[$id]["name"] = $use_admin_label && !rgempty("adminLabel", $field) ? $field["adminLabel"] : $lead_value[$id . ".1"]; - $products[$id]["price"] = rgar($lead_value, $id . ".2"); - $products[$id]["quantity"] = $product_quantity; - } - else if(!empty($lead_value)){ - - if(empty($quantity)) - continue; - - if(!rgar($products,$id)) - $products[$id] = array(); - - if($field["inputType"] == "price"){ - $name = $field["label"]; - $price = $lead_value; - } - else{ - list($name, $price) = explode("|", $lead_value); - } - - $products[$id]["name"] = !$use_choice_text ? $name : RGFormsModel::get_choice_text($field, $name); - $products[$id]["price"] = $price; - $products[$id]["quantity"] = $quantity; - $products[$id]["options"] = array(); - } - - if(isset($products[$id])){ - $options = self::get_product_fields_by_type($form, array("option"), $id); - foreach($options as $option){ - $option_value = RGFormsModel::get_lead_field_value($lead, $option); - $option_label = empty($option["adminLabel"]) ? $option["label"] : $option["adminLabel"]; - if(is_array($option_value)){ - foreach($option_value as $value){ - $option_info = self::get_option_info($value, $option, $use_choice_text); - if(!empty($option_info)) - $products[$id]["options"][] = array("field_label" => rgar($option, "label"), "option_name"=> rgar($option_info, "name"), "option_label" => $option_label . ": " . rgar($option_info, "name"), "price" => rgar($option_info,"price")); - } - } - else if(!empty($option_value)){ - $option_info = self::get_option_info($option_value, $option, $use_choice_text); - $products[$id]["options"][] = array("field_label" => rgar($option, "label"), "option_name"=> rgar($option_info, "name"), "option_label" => $option_label . ": " . rgar($option_info, "name"), "price" => rgar($option_info,"price")); - } - - } - } - break; - } - } - - $shipping_field = self::get_fields_by_type($form, array("shipping")); - $shipping_price = $shipping_name = ""; - $shipping_field_id = ""; - if(!empty($shipping_field) && !RGFormsModel::is_field_hidden($form, $shipping_field[0], array(), $lead)){ - $shipping_price = RGFormsModel::get_lead_field_value($lead, $shipping_field[0]); - $shipping_name = $shipping_field[0]["label"]; - $shipping_field_id = $shipping_field[0]["id"]; - if($shipping_field[0]["inputType"] != "singleshipping"){ - list($shipping_method, $shipping_price) = explode("|", $shipping_price); - $shipping_name = $shipping_field[0]["label"] . " ($shipping_method)"; - } - } - $shipping_price = self::to_number($shipping_price); - - $product_info = array("products" => $products, "shipping" => array("id"=> $shipping_field_id, "name" => $shipping_name, "price" => $shipping_price)); - - $product_info = apply_filters("gform_product_info_{$form["id"]}", apply_filters("gform_product_info", $product_info, $form, $lead), $form, $lead); - - // save static copy of product info (only for "real" entries) - if(!rgempty("id", $lead) && !empty($product_info["products"])){ - gform_update_meta($lead['id'], "gform_product_info_{$use_choice_text}_{$use_admin_label}", $product_info); - } - } - - return $product_info; - } - - public static function get_order_total($form, $lead) { - - $products = self::get_product_fields($form, $lead, false); - return self::get_total($products); - } - - public static function get_total($products) { - - $total = 0; - foreach($products["products"] as $product){ - - $price = self::to_number($product["price"]); - if(is_array(rgar($product,"options"))){ - foreach($product["options"] as $option){ - $price += self::to_number($option["price"]); - } - } - $subtotal = floatval($product["quantity"]) * $price; - $total += $subtotal; - - } - - $total += floatval($products["shipping"]["price"]); - - return $total; - } - - public static function get_option_info($value, $option, $use_choice_text){ - if(empty($value)) - return array(); - - list($name, $price) = explode("|", $value); - if($use_choice_text) - $name = RGFormsModel::get_choice_text($option, $name); - - return array("name" => $name, "price" => $price); - } - - public static function gform_do_shortcode($content){ - - $is_ajax = false; - $forms = GFFormDisplay::get_embedded_forms($content, $is_ajax); - - foreach($forms as $form){ - GFFormDisplay::print_form_scripts($form, $is_ajax); - } - - return do_shortcode($content); - } - - public static function has_akismet(){ - return function_exists('akismet_http_post'); - } - - public static function akismet_enabled($form_id) { - - if(!self::has_akismet()) - return false; - - // if no option is set, leave akismet enabled; otherwise, use option value true/false - $enabled_by_setting = get_option('rg_gforms_enable_akismet') === false ? true : get_option('rg_gforms_enable_akismet') == true; - $enabled_by_filter = apply_filters("gform_akismet_enabled_$form_id", apply_filters("gform_akismet_enabled", $enabled_by_setting)); - - return $enabled_by_filter; - - } - - public static function is_akismet_spam($form, $lead){ - - global $akismet_api_host, $akismet_api_port; - - $fields = self::get_akismet_fields($form, $lead); - - //Submitting info do Akismet - $response = akismet_http_post($fields, $akismet_api_host, '/1.1/comment-check', $akismet_api_port ); - $is_spam = trim(rgar($response, 1)) == "true"; - - return $is_spam; - } - - public static function mark_akismet_spam($form, $lead, $is_spam){ - - global $akismet_api_host, $akismet_api_port; - - $fields = self::get_akismet_fields($form, $lead); - $as = $is_spam ? "spam" : "ham"; - - //Submitting info do Akismet - akismet_http_post($fields, $akismet_api_host, '/1.1/submit-'.$as, $akismet_api_port ); - } - - private static function get_akismet_fields($form, $lead){ - //Gathering Akismet information - $akismet_info = array(); - $akismet_info['comment_type'] = 'gravity_form'; - $akismet_info['comment_author'] = self::get_akismet_field("name", $form, $lead); - $akismet_info['comment_author_email'] = self::get_akismet_field("email", $form, $lead); - $akismet_info['comment_author_url'] = self::get_akismet_field("website", $form, $lead); - $akismet_info['comment_content'] = self::get_akismet_field("textarea", $form, $lead); - $akismet_info['contact_form_subject'] = $form["title"]; - $akismet_info['comment_author_IP'] = $lead["ip"]; - $akismet_info['permalink'] = $lead["source_url"]; - $akismet_info['user_ip'] = preg_replace( '/[^0-9., ]/', '', $lead["ip"] ); - $akismet_info['user_agent'] = $lead["user_agent"]; - $akismet_info['referrer'] = is_admin() ? "" : $_SERVER['HTTP_REFERER']; - $akismet_info['blog'] = get_option('home'); - - $akismet_info = apply_filters("gform_akismet_fields_{$form["id"]}", apply_filters("gform_akismet_fields", $akismet_info, $form, $lead), $form, $lead); - - return http_build_query($akismet_info); - } - - private static function get_akismet_field($field_type, $form, $lead){ - $fields = GFCommon::get_fields_by_type($form, array($field_type)); - if(empty($fields)) - return ""; - - $value = RGFormsModel::get_lead_field_value($lead, $fields[0]); - switch($field_type){ - case "name" : - $value = GFCommon::get_lead_field_display($fields[0], $value); - break; - } - - return $value; - } - - public static function get_other_choice_value(){ - $value = apply_filters('gform_other_choice_value', __("Other", "gravityforms")); - return $value; - } - - public static function get_browser_class() { - global $is_lynx, $is_gecko, $is_IE, $is_opera, $is_NS4, $is_safari, $is_chrome, $is_iphone, $post; - - $classes = array(); - - //adding browser related class - if($is_lynx) $classes[] = 'gf_browser_lynx'; - else if($is_gecko) $classes[] = 'gf_browser_gecko'; - else if($is_opera) $classes[] = 'gf_browser_opera'; - else if($is_NS4) $classes[] = 'gf_browser_ns4'; - else if($is_safari) $classes[] = 'gf_browser_safari'; - else if($is_chrome) $classes[] = 'gf_browser_chrome'; - else if($is_IE) $classes[] = 'gf_browser_ie'; - else $classes[] = 'gf_browser_unknown'; - - - //adding IE version - if($is_IE){ - if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6') !== false) - $classes[] = 'gf_browser_ie6'; - else if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 7') !== false) - $classes[] = 'gf_browser_ie7'; - if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 8') !== false) - $classes[] = 'gf_browser_ie8'; - if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 9') !== false) - $classes[] = 'gf_browser_ie9'; - } - - if($is_iphone) $classes[] = 'gf_browser_iphone'; - - return implode(" " , $classes); - } - - public static function create_post($form, &$lead) { - $disable_post = apply_filters("gform_disable_post_creation_{$form["id"]}", apply_filters("gform_disable_post_creation", false, $form, $lead), $form, $lead); - $post_id = 0; - if(!$disable_post){ - //creates post if the form has any post fields - $post_id = RGFormsModel::create_post($form, $lead); - } - - return $post_id; - } - - public static function evaluate_conditional_logic($logic, $form, $lead) { - - if(!$logic || !is_array(rgar($logic,"rules"))) - return true; - - $entry_meta_keys = array_keys(GFFormsModel::get_entry_meta($form["id"])); - $match_count = 0; - if(is_array($logic["rules"])){ - 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"]);; - } 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); - } - - if($is_value_match) - $match_count++; - - } - } - - $do_action = ($logic["logicType"] == "all" && $match_count == sizeof($logic["rules"]) ) || ($logic["logicType"] == "any" && $match_count > 0); - return $do_action; - } - - public static function get_card_types(){ - $cards = array ( - - array ( 'name' => 'American Express', - 'slug' => 'amex', - 'lengths' => '15', - 'prefixes' => '34,37', - 'checksum' => true - ), - array ( 'name' => 'Discover', - 'slug' => 'discover', - 'lengths' => '16', - 'prefixes' => '6011,622,64,65', - 'checksum' => true - ), - array ( 'name' => 'MasterCard', - 'slug' => 'mastercard', - 'lengths' => '16', - 'prefixes' => '51,52,53,54,55', - 'checksum' => true - ), - array ( 'name' => 'Visa', - 'slug' => 'visa', - 'lengths' => '13,16', - 'prefixes' => '4,417500,4917,4913,4508,4844', - 'checksum' => true - ), - array ( 'name' => 'JCB', - 'slug' => 'jcb', - 'lengths' => '16', - 'prefixes' => '35', - 'checksum' => true - ), - array ( 'name' => 'Maestro', - 'slug' => 'maestro', - 'lengths' => '12,13,14,15,16,18,19', - 'prefixes' => '5018,5020,5038,6304,6759,6761', - 'checksum' => true - ) - - ); - - $cards = apply_filters("gform_creditcard_types", $cards); - - return $cards; - } - - public static function get_card_type($number){ - - //removing spaces from number - $number = str_replace (' ', '', $number); - - if(empty($number)) - return false; - - $cards = self::get_card_types(); - - $matched_card = false; - foreach($cards as $card){ - if(self::matches_card_type($number, $card)){ - $matched_card = $card; - break; - } - } - - if($matched_card && $matched_card["checksum"] && !self::is_valid_card_checksum($number)) - $matched_card = false; - - return $matched_card ? $matched_card : false; - - } - - private static function matches_card_type($number, $card){ - - //checking prefix - $prefixes = explode(',',$card['prefixes']); - $matches_prefix = false; - foreach($prefixes as $prefix){ - if(preg_match("|^{$prefix}|", $number)){ - $matches_prefix = true; - break; - } - } - - //checking length - $lengths = explode(',',$card['lengths']); - $matches_length = false; - foreach($lengths as $length){ - if(strlen($number) == absint($length)){ - $matches_length = true; - break; - } - } - - return $matches_prefix && $matches_length; - - } - - private static function is_valid_card_checksum($number){ - $checksum = 0; - $num = 0; - $multiplier = 1; - - // Process each character starting at the right - for ($i = strlen($number) - 1; $i >= 0; $i--) { - - //Multiply current digit by multiplier (1 or 2) - $num = $number{$i} * $multiplier; - - // If the result is in greater than 9, add 1 to the checksum total - if ($num >= 10) { - $checksum++; - $num -= 10; - } - - //Update checksum - $checksum += $num; - - //Update multiplier - $multiplier = $multiplier == 1 ? 2 : 1; - } - - return $checksum % 10 == 0; - - } - - public static function is_wp_version($min_version){ - return !version_compare(get_bloginfo("version"), "{$min_version}.dev1", '<'); - } - - public static function add_categories_as_choices($field, $value) { - - $choices = $inputs = array(); - $is_post = isset($_POST["gform_submit"]); - $has_placeholder = rgar($field, 'categoryInitialItemEnabled') && RGFormsModel::get_input_type($field) == 'select'; - - if($has_placeholder) - $choices[] = array('text' => rgar($field, 'categoryInitialItem'), 'value' => '', 'isSelected' => true); - - $display_all = rgar($field, "displayAllCategories"); - - $args = array('hide_empty' => false, 'orderby' => 'name'); - - if(!$display_all){ - foreach($field["choices"] as $field_choice_to_include){ - $args["include"][] = $field_choice_to_include["value"]; - } - } - - $args = apply_filters("gform_post_category_args_{$field["id"]}", apply_filters("gform_post_category_args", $args, $field), $field); - $terms = get_terms('category', $args); - - $terms_copy = unserialize(serialize($terms)); // deep copy the terms to avoid repeating GFCategoryWalker on previously cached terms. - $walker = new GFCategoryWalker(); - $categories = $walker->walk($terms_copy, 0, array(0)); // 3rd parameter prevents notices triggered by $walker::display_element() function which checks $args[0] - - foreach($categories as $category) { - if($display_all) { - $selected = $value == $category->term_id || - ( - empty($value) && - get_option('default_category') == $category->term_id && - RGFormsModel::get_input_type($field) == 'select' && // only preselect default category on select fields - !$is_post && - !$has_placeholder - ); - $choices[] = array('text' => $category->name, 'value' => $category->term_id, 'isSelected' => $selected); - } else { - foreach($field["choices"] as $field_choice){ - if($field_choice["value"] == $category->term_id){ - $choices[] = array('text' => $category->name, 'value' => $category->term_id); - break; - } - } - } - } - - if(empty($choices)) - $choices[] = array('text' => 'You must select at least one category.', 'value' => ''); - - $choice_number = 1; - foreach($choices as $choice) { - - if($choice_number % 10 == 0) //hack to skip numbers ending in 0. so that 5.1 doesn't conflict with 5.10 - $choice_number++; - - $input_id = $field["id"] . '.' . $choice_number; - $inputs[] = array('id' => $input_id, 'label' => $choice['text'], 'name' => ''); - $choice_number++; - } - - $field['choices'] = $choices; - - if(RGFormsModel::get_input_type($field) == 'checkbox') - $field['inputs'] = $inputs; - - return $field; - } - - public static function prepare_post_category_value($value, $field, $mode = 'entry_detail') { - - if(!is_array($value)) - $value = explode(',', $value); - - $cat_names = array(); - $cat_ids = array(); - foreach($value as $cat_string) { - $ary = explode(":", $cat_string); - $cat_name = count($ary) > 0 ? $ary[0] : ""; - $cat_id = count($ary) > 1 ? $ary[1] : $ary[0]; - - if(!empty($cat_name)) - $cat_names[] = $cat_name; - - if(!empty($cat_id)) - $cat_ids[] = $cat_id; - } - - sort($cat_names); - - switch($mode) { - case 'entry_list': - $value = self::implode_non_blank(', ', $cat_names); - break; - case 'entry_detail': - $value = RGFormsModel::get_input_type($field) == 'checkbox' ? $cat_names : self::implode_non_blank(', ', $cat_names); - break; - case 'conditional_logic': - $value = array_values($cat_ids); - break; - } - - return $value; - } - - public static function calculate($field, $form, $lead) { - - $formula = apply_filters('gform_calculation_formula', rgar($field, 'calculationFormula'), $field, $form, $lead); - - preg_match_all('/{[^{]*?:(\d+(\.\d+)?)(:(.*?))?}/mi', $formula, $matches, PREG_SET_ORDER); - - if(is_array($matches)) { - foreach($matches as $match) { - - list($text, $input_id) = $match; - - $value = self::get_calculation_value($match[1], $form, $lead); - $formula = str_replace($match[0], $value, $formula); - - } - } - $result = preg_match("/^[0-9 -\/*\(\)]+$/", $formula) ? eval("return {$formula};") : false; - return $result; - } - - public static function round_number($number, $rounding ){ - if(is_numeric($rounding) && $rounding >= 0){ - $number = round($number, $rounding); - } - return $number; - } - - public static function get_calculation_value($field_id, $form, $lead) { - - $filters = array('price', 'value', ''); - $value = false; - - foreach($filters as $filter) { - if (is_numeric($value)){ - //value found, exit loop - break; - } - $value = GFCommon::to_number(GFCommon::replace_variables("{:{$field_id}:$filter}", $form, $lead)); - } - - if(!$value || !is_numeric($value)) - $value = 0; - - return $value; - } - - public static function conditional_shortcode($attributes, $content = null) { - - extract(shortcode_atts(array( - 'merge_tag' => '', - 'condition' => '', - 'value' => '' - ), $attributes)); - - return RGFormsModel::matches_operation($merge_tag, $value, $condition) ? do_shortcode($content) : ''; - - } - - public static function is_valid_for_calcuation($field) { - - $supported_input_types = array('text', 'select', 'number', 'checkbox', 'radio', 'hidden', 'singleproduct', 'price', 'hiddenproduct', 'calculation', 'singleshipping'); - $unsupported_field_types = array('category'); - $input_type = RGFormsModel::get_input_type($field); - - return in_array($input_type, $supported_input_types) && !in_array($input_type, $unsupported_field_types); - } - - public static function log_error($message){ - if(class_exists("GFLogging")) - { - GFLogging::include_logger(); - GFLogging::log_message("gravityforms", $message, KLogger::ERROR); - } - } - - public static function log_debug($message){ - if(class_exists("GFLogging")) - { - GFLogging::include_logger(); - GFLogging::log_message("gravityforms", $message, KLogger::DEBUG); - } - } - - public static function echo_if($condition, $text) { - - switch($text) { - case 'checked': - $text = 'checked="checked"'; - break; - case 'selected': - $text = 'selected="selected"'; - } - - echo $condition ? $text : ''; - } - - public static function gf_global($echo = true) { - - require_once(GFCommon::get_base_path() . '/currency.php'); - - $gf_global = array(); - $gf_global["gf_currency_config"] = RGCurrency::get_currency(GFCommon::get_currency()); - $gf_global["base_url"] = GFCommon::get_base_url(); - $gf_global["number_formats"] = array(); - $gf_global["spinnerUrl"] = GFCommon::get_base_url() . '/images/spinner.gif'; - - $gf_global_json = 'var gf_global = ' . json_encode($gf_global) . ';'; - - if(!$echo) - return $gf_global_json; - - echo $gf_global_json; - } - - public static function gf_vars($echo = true) { - if(!class_exists("RGCurrency")) - require_once("currency.php"); - - $gf_vars = array(); - $gf_vars["active"] = __("Active", "gravityforms"); - $gf_vars["inactive"] = __("Inactive", "gravityforms"); - $gf_vars["save"] = __("Save", "gravityforms"); - $gf_vars["update"] = __("Update", "gravityforms"); - $gf_vars["previousLabel" ] = __("Previous", "gravityforms"); - $gf_vars["selectFormat" ] = __("Select a format", "gravityforms"); - $gf_vars["editToViewAll" ] = __("5 of %d items shown. Edit field to view all", "gravityforms"); - $gf_vars["enterValue" ] = __("Enter a value", "gravityforms"); - $gf_vars["formTitle" ] = __("Untitled Form", "gravityforms"); - $gf_vars["formDescription" ] = __("We would love to hear from you! Please fill out this form and we will get in touch with you shortly.", "gravityforms"); - $gf_vars["formConfirmationMessage" ] = __("Thanks for contacting us! We will get in touch with you shortly.", "gravityforms"); - $gf_vars["buttonText" ] = __("Submit", "gravityforms"); - $gf_vars["loading" ] = __("Loading...", "gravityforms"); - $gf_vars["thisFieldIf"] = __('this field if', 'gravityforms'); - $gf_vars["thisPage"] = __("this page", "gravityforms"); - $gf_vars["thisFormButton"] = __('this form button', 'gravityforms'); - $gf_vars["show"] = __('Show', 'gravityforms'); - $gf_vars["hide"] = __('Hide', 'gravityforms'); - $gf_vars["all"] = __('All', 'gravityforms'); - $gf_vars["any"] = __('Any', 'gravityforms'); - $gf_vars["ofTheFollowingMatch"] = __('of the following match:', 'gravityforms'); - $gf_vars["is"] = __('is', 'gravityforms'); - $gf_vars["isNot"] = __('is not', 'gravityforms'); - $gf_vars["greaterThan"] = __('greater than', 'gravityforms'); - $gf_vars["lessThan"] = __('less than', 'gravityforms'); - $gf_vars["contains"] = __('contains', 'gravityforms'); - $gf_vars["startsWith"] = __('starts with', 'gravityforms'); - $gf_vars["endsWith"] = __('ends with', 'gravityforms'); - - $gf_vars["thisConfirmation"] = __('Use this confirmation if', 'gravityforms'); - $gf_vars["thisNotification"] = __('Send this notification if', 'gravityforms'); - $gf_vars["confirmationSave"] = __('Save', 'gravityforms'); - $gf_vars["confirmationSaving"] = __('Saving...', 'gravityforms'); - $gf_vars["confirmationAreYouSure"] = __('Are you sure you wish to cancel these changes?', 'gravityforms'); - $gf_vars["confirmationIssueSaving"] = __('There was an issue saving this confirmation.', 'gravityforms'); - $gf_vars["confirmationConfirmDelete"] = __('Are you sure you wish to delete this confirmation?', 'gravityforms'); - $gf_vars["confirmationIssueDeleting"] = __('There was an issue deleting this confirmation.', 'gravityforms'); - $gf_vars["confirmationConfirmDiscard"] = __('There are unsaved changes to the current confirmation. Would you like to discard these changes?', 'gravityforms'); - $gf_vars["confirmationDefaultName"] = __('Untitled Confirmation', 'gravityforms'); - $gf_vars["confirmationDefaultMessage"] = __('Thanks for contacting us! We will get in touch with you shortly.', 'gravityforms'); - $gf_vars["confirmationInvalidPageSelection"] = __('Please select a page.', "gravityforms"); - $gf_vars["confirmationInvalidRedirect"] = __('Please enter a URL.', "gravityforms"); - $gf_vars["confirmationInvalidName"] = __('Please enter a confirmation name.', "gravityforms"); - - $gf_vars["conditionalLogicDependency"] = __('This form contains conditional logic dependent upon this field. Are you sure you want to delete this field? \'OK\' to delete, \'Cancel\' to abort.', 'gravityforms'); - $gf_vars["conditionalLogicDependencyChoice"] = __('This form contains conditional logic dependent upon this choice. Are you sure you want to delete this choice? \'OK\' to delete, \'Cancel\' to abort.', 'gravityforms'); - $gf_vars["conditionalLogicDependencyChoiceEdit"] = __('This form contains conditional logic dependent upon this choice. Are you sure you want to modify this choice? \'OK\' to delete, \'Cancel\' to abort.', 'gravityforms'); - - $gf_vars["mergeTagsTooltip"] = __('
    Merge Tags
    Merge tags allow you to dynamically populate submitted field values in your form content wherever this merge tag icon is present.', 'gravityforms'); - - $gf_vars["baseUrl"] = GFCommon::get_base_url(); - $gf_vars["gf_currency_config"] = RGCurrency::get_currency(GFCommon::get_currency()); - $gf_vars["otherChoiceValue"] = GFCommon::get_other_choice_value(); - $gf_vars["isFormTrash"] = false; - $gf_vars["currentlyAddingField"] = false; - - $gf_vars["addFieldFilter"] = __("Add a condition", "gravityforms"); - $gf_vars["removeFieldFilter"] = __("Remove a condition", "gravityforms"); - $gf_vars["filterAndAny"] = __("Include results if {0} match:", "gravityforms"); - - if(is_admin() && rgget('id')) { - $form = RGFormsModel::get_form_meta(rgget('id')); - $gf_vars["mergeTags"] = GFCommon::get_merge_tags($form['fields'], '', false); - } - - $gf_vars_json = 'var gf_vars = ' . json_encode($gf_vars) . ';'; - - if(!$echo){ - return $gf_vars_json; - } - else { - echo $gf_vars_json; - } - } - - public static function is_bp_active() { - return defined('BP_VERSION') ? true : false; - } - - public static function add_message($message, $is_error = false) { - if($is_error) { - self::$errors[] = $message; - } else { - self::$messages[] = $message; - } - } - - public static function add_error_message($message) { - self::add_message($message, true); - } - - public static function display_admin_message($errors = false, $messages = false) { - - if(!$errors) - $errors = self::$errors; - - if(!$messages) - $messages = self::$messages; - - $errors = apply_filters('gform_admin_error_messages', $errors); - $messages = apply_filters('gform_admin_messages', $messages); - - if(!empty($errors)) { ?> -
    - 1) { ?> - - -

    - -
    - -
    - 1) { ?> - - -

    - -
    - ' . self::gf_vars(false) . ''; - } - } - - public static function maybe_add_leading_zero($value){ - $first_char = GFCommon::safe_substr($value, 0, 1, 'utf-8'); - if(in_array($first_char, array(".", ","))) - $value = "0" . $value; - return $value; - } - - // used by the gfFieldFilterUI() jQuery plugin - public static function get_field_filter_settings($form) { - - $all_fields = $form["fields"]; - - // set up filters - $fields = $all_fields; - $exclude_types = array("rank", "page", "html"); - - $operators_by_field_type = array( - "default" => array("is", "isnot", ">", "<"), - "checkbox" => array("is"), - "multiselect" => array("contains"), - "number" => array("is", "isnot", ">", "<"), - "likert" => array("is", "isnot"), - "list" => array("contains") - ); - - for ($i = 0; $i < count($all_fields); $i++) { - $field_type = GFFormsmodel::get_input_type($all_fields[$i]); - if (in_array($field_type, $exclude_types)) - unset($fields[$i]); - } - $fields = array_values($fields); - - $field_filters = array( - array( - "key"=> "0", - "text" => __("Any form field", "gravityforms"), - "operators" => array("contains", "is") - ) - ); - - foreach ($fields as $field) { - - $field_type = GFFormsModel::get_input_type($field); - - $operators = isset($operators_by_field_type[$field_type]) ? $operators_by_field_type[$field_type] : $operators_by_field_type["default"]; - if (!isset($field["choices"]) && !in_array("contains", $operators)) - $operators[] = "contains"; - - $field_filter = array(); - $key = $field["id"]; - if ($field_type == "likert" && rgar($field, "gsurveyLikertEnableMultipleRows")) { - // multi-row likert fields - $field_filter["key"] = $key; - $field_filter["group"] = true; - $field_filter["text"] = GFFormsModel::get_label($field); - $sub_filters = array(); - $rows = rgar($field, "gsurveyLikertRows"); - foreach ($rows as $row) { - $sub_filter = array(); - $sub_filter["key"] = $key . "|" . rgar($row, "value"); - $sub_filter["text"] = rgar($row, "text"); - $sub_filter["type"] = "field"; - $sub_filter["preventMultiple"] = false; - $sub_filter["operators"] = $operators; - $sub_filter["values"] = $field["choices"]; - $sub_filters[] = $sub_filter; - } - $field_filter["filters"] = $sub_filters; - } elseif ($field_type == "name" && rgar($field, "nameFormat") == "" || $field_type == "address") { - // standard two input name field - $field_filter["key"] = $key; - $field_filter["group"] = true; - $field_filter["text"] = GFFormsModel::get_label($field); - $sub_filters = array(); - $inputs = rgar($field, "inputs"); - foreach ($inputs as $input) { - $sub_filter = array(); - $sub_filter["key"] = rgar($input, "id"); - $sub_filter["text"] = rgar($input, "label"); - $sub_filter["preventMultiple"] = false; - $sub_filter["operators"] = $operators; - $sub_filters[] = $sub_filter; - } - $field_filter["filters"] = $sub_filters; - } else { - $field_filter["key"] = $key; - $field_filter["preventMultiple"] = false; - $field_filter["text"] = GFFormsModel::get_label($field); - - $field_filter["operators"] = $operators; - - if (isset($field["choices"])) - $field_filter["values"] = $field["choices"]; - - - } - $field_filters[] = $field_filter; - - } - $form_id = $form["id"]; - $entry_meta_filters = self::get_entry_meta_filter_settings($form_id); - $field_filters = array_merge($field_filters, $entry_meta_filters); - $field_filters = array_values($field_filters); // reset the numeric keys in case some filters have been unset - $info_filters = self::get_entry_info_filter_settings(); - $field_filters = array_merge($field_filters, $info_filters); - $field_filters = array_values($field_filters); - return $field_filters; - } - - public static function get_entry_info_filter_settings() { - $settings = array(); - $info_columns = self::get_entry_info_filter_columns(); - foreach($info_columns as $key => $info_column){ - $info_column["key"] = $key; - $info_column["preventMultiple"] = false; - $settings[] = $info_column; - } - - return $settings; - } - - public static function get_entry_info_filter_columns($get_users = true){ - $account_choices = array(); - if($get_users){ - $args = apply_filters("gform_filters_get_users", array("number" => 200)); - $accounts = get_users(); - $account_choices = array(); - foreach ($accounts as $account) { - $account_choices[] = array("text" => $account->user_login, "value" => $account->ID); - } - } - return array( - "entry_id" => array( - "text" => __("Entry ID", "gravityforms"), - "operators" => array( "is", "isnot", ">", "<") - ), - "date_created" => array( - "text" => __("Entry Date", "gravityforms"), - "operators" => array( "is", ">", "<"), - "placeholder" => __("yyyy-mm-dd", "gravityforms") - ), - "is_starred" => array( - "text" => __("Starred", "gravityforms"), - "operators" => array( "is", "isnot"), - "values" => array( - array( - "text" => "Yes", - "value" => "1" - ), - array( - "text" => "No", - "value" => "0" - ) - ) - ), - "ip" => array( - "text" => __("IP Address", "gravityforms"), - "operators" => array( "is", "isnot", ">", "<", "contains") - ), - "source_url" => array( - "text" => __("Source URL", "gravityforms"), - "operators" => array( "is", "isnot", ">", "<", "contains") - ), - "payment_status" => array( - "text" => __("Payment Status", "gravityforms"), - "operators" => array( "is", "isnot"), - "values" => array( - array( - "text" => "Approved", - "value" => "Approved" - ), - array( - "text" => "Failed", - "value" => "Failed" - ), - array( - "text" => "Active", - "value" => "Active" - ), - array( - "text" => "Cancelled", - "value" => "Cancelled" - ) - ) - ), - "payment_date" => array( - "text" => __("Payment Date", "gravityforms"), - "operators" => array( "is", "isnot", ">", "<") - ), - "payment_amount" => array( - "text" => __("Payment Amount", "gravityforms"), - "operators" => array( "is", "isnot", ">", "<", "contains") - ), - "transaction_id" => array( - "text" => __("Transaction ID", "gravityforms"), - "operators" => array( "is", "isnot", ">", "<", "contains") - ), - "created_by" => array( - "text" => __("User", "gravityforms"), - "operators" => array( "is", "isnot"), - "values" => $account_choices - ) - ); - } - - public static function get_entry_meta_filter_settings($form_id) { - $filters = array(); - $entry_meta = GFFormsModel::get_entry_meta($form_id); - if (empty($entry_meta)) - return $filters; - - foreach ($entry_meta as $key => $meta) { - if (isset($meta["filter"])) { - $filter = array(); - $filter["key"] = $key; - $filter["preventMultiple"] = isset($meta["filter"]["preventMultiple"]) ? $meta["filter"]["preventMultiple"] : false; - $filter["text"] = rgar($meta, "label"); - $filter["operators"] = isset($meta["filter"]["operators"]) ? $meta["filter"]["operators"] : array("is", "isnot"); - if (isset($meta["filter"]["choices"])) - $filter["values"] = $meta["filter"]["choices"]; - $filters[] = $filter; - } - - } - - return $filters; - } - - - public static function get_field_filters_from_post(){ - $field_filters = array(); - $filter_fields = rgpost("f"); - if (is_array($filter_fields)) { - $filter_operators = rgpost("o"); - $filter_values = rgpost("v"); - for ($i = 0; $i < count($filter_fields); $i++) { - $field_filter = array(); - $key = $filter_fields[$i]; - if("entry_id" == $key){ - $key = "id"; - } - $operator = $filter_operators[$i]; - $val = $filter_values[$i]; - $strpos_row_key = strpos($key, "|"); - if ($strpos_row_key !== false) { //multi-row likert - $key_array = explode("|", $key); - $key = $key_array[0]; - $val = $key_array[1] . ":" . $val; - } - $field_filter["key"] = $key; - $field_filter["operator"] = $operator; - $field_filter["value"] = $val; - $field_filters[] = $field_filter; - } - } - $field_filters["mode"] = rgpost("mode"); - return $field_filters; - } - - public static function has_multifile_fileupload_field($form){ - $fileupload_fields = GFCommon::get_fields_by_type($form, array("fileupload", "post_custom_field")); - if(is_array($fileupload_fields)){ - foreach($fileupload_fields as $field){ - if(rgar($field, "multipleFiles")) - return true; - } - } - return false; - } - - public static function localize_gform_gravityforms_multifile(){ - wp_localize_script( 'gform_gravityforms', 'gform_gravityforms', array( - 'strings' => array( - 'invalid_file_extension' => __("This type of file is not allowed. Must be one of the following: ", "gravityforms" ), - 'delete_file' => __("Delete this file", "gravityforms"), - 'in_progress' => __("in progress", "gravityforms"), - 'file_exceeds_limit' => __("File exceeds size limit", "gravityforms"), - 'illegal_extension' => __("This type of file is not allowed." , "gravityforms"), - "max_reached" => __("Maximum number of files reached", "gravityforms"), - "unknown_error" => __("There was an problem while saving the file on the server", "gravityforms"), - "currently_uploading" => __("Please wait for the uploading to complete", "gravityforms"), - "cancel" => __("Cancel", "gravityforms"), - "cancel_upload" => __("Cancel this upload", "gravityforms"), - "cancelled" => __("Cancelled", "gravityforms") - ), - 'vars' => array( - 'images_url' => GFCommon::get_base_url() . "/images" - ) - ) ); - } - - public static function safe_strlen($string){ - - if(function_exists("mb_strlen")) - return mb_strlen($string); - else - return strlen($string); - - } - - public static function safe_substr($string, $start, $length = null){ - if(function_exists("mb_substr")) - return mb_substr($string, $start, $length); - else - return substr($string, $start, $length); - } - - /** - * Reliablty compare floats. - * @param [float] $float1 - * @param [float] $float2 - * @param [string] $operator Supports: '<', '<=', '>', '>=', '==', '=', '!=' - * @return [bool] - */ - public static function compare_floats( $float1, $float2, $operator ) { - - $epsilon = 0.00001; - $is_equal = abs( floatval( $float1 ) - floatval( $float2 ) ) < $epsilon; - $is_greater = floatval( $float1 ) > floatval( $float2 ); - $is_less = floatval( $float1 ) < floatval( $float2 ); - - switch( $operator ) { - case '<': - return $is_less; - case '<=': - return $is_less || $is_equal; - case '>' : - return $is_greater; - case '>=': - return $is_greater || $is_equal; - case '==': - case '=': - return $is_equal; - case '!=': - return ! $is_equal; - } - - } - -} - -class GFCategoryWalker extends Walker { - /** - * @see Walker::$tree_type - * @since 2.1.0 - * @var string - */ - var $tree_type = 'category'; - - /** - * @see Walker::$db_fields - * @since 2.1.0 - * @todo Decouple this - * @var array - */ - var $db_fields = array ('parent' => 'parent', 'id' => 'term_id'); - - /** - * @see Walker::start_el() - * @since 2.1.0 - * - * @param string $output Passed by reference. Used to append additional content. - * @param object $category Category data object. - * @param int $depth Depth of category. Used for padding. - * @param array $args Uses 'selected' and 'show_count' keys, if they exist. - */ - function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0) { - //$pad = str_repeat(' ', $depth * 3); - $pad = str_repeat('─', $depth); - if(!empty($pad)) - $pad .= " "; - $object->name = "{$pad}{$object->name}"; - $output[] = $object; - } -} - -/** - * - * Notes: - * 1. The WordPress Transients API does not support boolean - * values so boolean values should be converted to integers - * or arrays before setting the values as persistent. - * - * 2. The transients API only deletes the transient from the database - * when the transient is accessed after it has expired. WordPress doesn't - * do any garbage collection of transients. - * - */ -class GFCache { - private static $_transient_prefix = "GFCache_"; - private static $_cache = array(); - - public static function get($key, &$found = null) { - global $blog_id; - if (is_multisite()) - $key = $blog_id . ':' . $key; - - if (isset(self::$_cache[$key])) { - $found = true; - $data = rgar(self::$_cache[$key], "data"); - - return $data; - } - - $data = self::get_transient($key); - - if (false === ($data)) { - $found = false; - - return false; - } else { - self::$_cache[$key] = array("data" => $data, "is_persistent" => true); - $found = true; - - return $data; - } - - } - - public static function set($key, $data, $is_persistent = false, $expiration = 0) { - global $blog_id; - $success = true; - - if (is_multisite()) - $key = $blog_id . ':' . $key; - - if ($is_persistent) - $success = self::set_transient($key, $data, $expiration); - - self::$_cache[$key] = array("data" => $data, "is_persistent" => $is_persistent); - - return $success; - } - - public static function delete($key) { - global $blog_id; - $success = true; - - if (is_multisite()) - $key = $blog_id . ':' . $key; - - if (isset(self::$_cache[$key])) { - if (self::$_cache[$key]["is_persistent"]) - $success = self::delete_transient($key); - - unset(self::$_cache[$key]); - } else { - $success = self::delete_transient($key); - - } - - return $success; - } - - public static function flush($flush_persistent = false) { - global $wpdb; - - self::$_cache = array(); - - if(false === $flush_persistent) - return true; - - if (is_multisite()) { - $sql = " - DELETE FROM $wpdb->sitemeta - WHERE meta_key LIKE '_site_transient_timeout_GFCache_%' OR - meta_key LIKE '_site_transient_GFCache_%' - "; - } else { - $sql = " - DELETE FROM $wpdb->options - WHERE option_name LIKE '_transient_timeout_GFCache_%' OR - option_name LIKE '_transient_GFCache_%' - "; - - } - $rows_deleted = $wpdb->query($sql); - - $success = $rows_deleted !== false ? true : false; - - return $success; - } - - private static function delete_transient($key) { - $key = self::$_transient_prefix . wp_hash($key); - if (is_multisite()) - $success = delete_site_transient($key); - else - $success = delete_transient($key); - - return $success; - } - - private static function set_transient($key, $data, $expiration) { - $key = self::$_transient_prefix . wp_hash($key); - if (is_multisite()) - $success = set_site_transient($key, $data, $expiration); - else - $success = set_transient($key, $data, $expiration); - - return $success; - } - - private static function get_transient($key) { - $key = self::$_transient_prefix . wp_hash($key); - if (is_multisite()) - $data = get_site_transient($key); - else - $data = get_transient($key); - - return $data; - } - +" . $field_label . ""; + } + } + return $str; + } + + public static function is_numeric($value, $number_format=""){ + + if($number_format == "currency"){ + + $number_format = self::is_currency_decimal_dot() ? "decimal_dot" : "decimal_comma"; + } + + switch($number_format){ + case "decimal_dot" : + return preg_match("/^(-?[0-9]{1,3}(?:,?[0-9]{3})*(?:\.[0-9]+)?)$/", $value); + break; + + case "decimal_comma" : + return preg_match("/^(-?[0-9]{1,3}(?:\.?[0-9]{3})*(?:,[0-9]+)?)$/", $value); + break; + + default : + return preg_match("/^(-?[0-9]{1,3}(?:,?[0-9]{3})*(?:\.[0-9]{2})?)$/", $value) || preg_match("/^(-?[0-9]{1,3}(?:\.?[0-9]{3})*(?:,[0-9]{2})?)$/", $value); + + } + } + + public static function is_currency_decimal_dot($currency = null){ + + if($currency == null){ + $code = GFCommon::get_currency(); + if(empty($code)) + $code = "USD"; + + $currency = RGCurrency::get_currency($code); + } + + return rgar($currency, "decimal_separator") == "."; + } + + public static function trim_all($text){ + $text = trim($text); + do{ + $prev_text = $text; + $text = str_replace(" ", " ", $text); + } + while($text != $prev_text); + + return $text; + } + + public static function format_number($number, $number_format){ + if(!is_numeric($number)) + return $number; + + //replacing commas with dots and dots with commas + if($number_format == "currency"){ + if(false === class_exists('RGCurrency')){ + require_once( GFCommon::get_base_path() . '/currency.php' ); + } + $currency = new RGCurrency( GFCommon::get_currency() ); + $number = $currency->to_money( $number ); + } elseif ($number_format == "decimal_comma"){ + $number = str_replace(",", "|", $number); + $number = str_replace(".", ",", $number); + $number = str_replace("|", ".", $number); + } + + return $number; + } + + public static function recursive_add_index_file($dir) { + if(!is_dir($dir)) + return; + + if(!($dp = opendir($dir))) + return; + + //ignores all errors + set_error_handler(create_function("", "return 0;"), E_ALL); + + //creates an empty index.html file + if($f = fopen($dir . "/index.html", 'w')) + fclose($f); + + //restores error handler + restore_error_handler(); + + while((false !== $file = readdir($dp))){ + if(is_dir("$dir/$file") && $file != '.' && $file !='..') + self::recursive_add_index_file("$dir/$file"); + } + + closedir($dp); + } + + public static function clean_number($number, $number_format=""){ + if(rgblank($number)) + return $number; + + $decimal_char = ""; + if($number_format == "decimal_dot") + $decimal_char = "."; + else if($number_format == "decimal_comma") + $decimal_char = ","; + + $float_number = ""; + $clean_number = ""; + $is_negative = false; + + //Removing all non-numeric characters + $array = str_split($number); + foreach($array as $char){ + if (($char >= '0' && $char <= '9') || $char=="," || $char==".") + $clean_number .= $char; + else if($char == '-') + $is_negative = true; + } + + //Removing thousand separators but keeping decimal point + $array = str_split($clean_number); + for($i=0, $count = sizeof($array); $i<$count; $i++) + { + $char = $array[$i]; + if ($char >= '0' && $char <= '9') + $float_number .= $char; + else if(empty($decimal_char) && ($char == "." || $char == ",") && strlen($clean_number) - $i <= 3) + $float_number .= "."; + else if($decimal_char == $char) + $float_number .= "."; + } + + if($is_negative) + $float_number = "-" . $float_number; + + return $float_number; + + } + + public static function json_encode($value){ + return json_encode($value); + } + + public static function json_decode($str, $is_assoc=true){ + return json_decode($str, $is_assoc); + } + + //Returns the url of the plugin's root folder + public static function get_base_url(){ + return plugins_url( '', __FILE__ ); + } + + //Returns the physical path of the plugin's root folder + public static function get_base_path(){ + return dirname( __FILE__ ); + } + + public static function get_email_fields($form){ + $fields = array(); + foreach($form["fields"] as $field){ + if(RGForms::get("type", $field) == "email" || RGForms::get("inputType", $field) == "email") + $fields[] = $field; + } + + return $fields; + } + + public static function truncate_middle($text, $max_length){ + if(strlen($text) <= $max_length) + return $text; + + $middle = intval($max_length / 2); + return self::safe_substr($text, 0, $middle) . "..." . self::safe_substr($text, strlen($text) - $middle, $middle); + } + + 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_email($email){ + return preg_match('/^(([a-zA-Z0-9_.\-+!#$&\'*+=?^`{|}~])+\@((([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+|localhost) *,? *)+$/', $email); + } + + public static function get_label($field, $input_id = 0, $input_only = false){ + return RGFormsModel::get_label($field, $input_id, $input_only); + } + + public static function get_input($field, $id){ + return RGFormsModel::get_input($field, $id); + } + + public static function insert_variables($fields, $element_id, $hide_all_fields=false, $callback="", $onchange="", $max_label_size=40, $exclude = null, $args="", $class_name=""){ + + if($fields == null) + $fields = array(); + + if($exclude == null) + $exclude = array(); + + $exclude = apply_filters("gform_merge_tag_list_exclude", $exclude, $element_id, $fields); + $merge_tags = self::get_merge_tags($fields, $element_id, $hide_all_fields, $exclude, $args); + + $onchange = empty($onchange) ? "InsertVariable('{$element_id}', '{$callback}');" : $onchange; + $class = trim($class_name . " gform_merge_tags"); + + ?> + + + + '{all_fields}', 'label' => __('All Submitted Fields', 'gravityforms')); + + // group fields by required, optional, and pricing + foreach($fields as $field) { + + if(rgget("displayOnly", $field)) + continue; + + $input_type = RGFormsModel::get_input_type($field); + + // skip field types that should be excluded + if(is_array($exclude_field_types) && in_array($input_type, $exclude_field_types)) + continue; + + if(rgar($field, 'isRequired')) { + + switch($input_type) { + + case "name" : + + if(rgar($field,"nameFormat") == "extended") { + + $prefix = GFCommon::get_input($field, $field["id"] + 0.2); + $suffix = GFCommon::get_input($field, $field["id"] + 0.8); + $optional_field = $field; + $optional_field["inputs"] = array($prefix, $suffix); + + //Add optional name fields to the optional list + $optional_fields[] = $optional_field; + + //Remove optional name field from required list + unset($field["inputs"][0]); + unset($field["inputs"][3]); + + } + + $required_fields[] = $field; + + break; + + default: + $required_fields[] = $field; + } + } + else { + $optional_fields[] = $field; + } + + if(self::is_pricing_field($field["type"])){ + $pricing_fields[] = $field; + } + + } + + if(!empty($required_fields)){ + foreach($required_fields as $field){ + $required_group = array_merge($required_group, self::get_field_merge_tags($field, $option)); + } + } + + if(!empty($optional_fields)){ + foreach($optional_fields as $field){ + $optional_group = array_merge($optional_group, self::get_field_merge_tags($field, $option)); + } + } + + if(!empty($pricing_fields)){ + + if(!$hide_all_fields) + $pricing_group[] = array('tag' => '{pricing_fields}', 'label' => __("All Pricing Fields", "gravityforms")); + + foreach($pricing_fields as $field){ + $pricing_group = array_merge($pricing_group, self::get_field_merge_tags($field, $option)); + } + + } + + $other_group[] = array('tag' => '{ip}', 'label' => __("Client IP Address", "gravityforms")); + $other_group[] = array('tag' => '{date_mdy}', 'label' => __("Date", "gravityforms") . ' (mm/dd/yyyy)'); + $other_group[] = array('tag' => '{date_dmy}', 'label' => __("Date", "gravityforms") . ' (dd/mm/yyyy)'); + $other_group[] = array('tag' => '{embed_post:ID}', 'label' => __("Embed Post/Page Id", "gravityforms")); + $other_group[] = array('tag' => '{embed_post:post_title}', 'label' => __("Embed Post/Page Title", "gravityforms")); + $other_group[] = array('tag' => '{embed_url}', 'label' => __("Embed URL", "gravityforms")); + $other_group[] = array('tag' => '{entry_id}', 'label' => __("Entry Id", "gravityforms")); + $other_group[] = array('tag' => '{entry_url}', 'label' => __("Entry URL", "gravityforms")); + $other_group[] = array('tag' => '{form_id}', 'label' => __("Form Id", "gravityforms")); + $other_group[] = array('tag' => '{form_title}', 'label' => __("Form Title", "gravityforms")); + $other_group[] = array('tag' => '{user_agent}', 'label' => __("HTTP User Agent", "gravityforms")); + $other_group[] = array('tag' => '{referer}', 'label' => __("HTTP Referer URL", "gravityforms")); + + if(self::has_post_field($fields)) { + $other_group[] = array('tag' => '{post_id}', 'label' => __("Post Id", "gravityforms")); + $other_group[] = array('tag' => '{post_edit_url}', 'label' => __("Post Edit URL", "gravityforms")); + } + + $other_group[] = array('tag' => '{user:display_name}', 'label' => __("User Display Name", "gravityforms")); + $other_group[] = array('tag' => '{user:user_email}', 'label' => __("User Email", "gravityforms")); + $other_group[] = array('tag' => '{user:user_login}', 'label' => __("User Login", "gravityforms")); + + $custom_group = apply_filters('gform_custom_merge_tags', array(), rgars($fields, '0/formId'), $fields, $element_id); + + $merge_tags = array( + 'ungrouped' => array( + 'label' => false, + 'tags' => $ungrouped + ), + 'required' => array( + 'label' => __("Required form fields", "gravityforms"), + 'tags' => $required_group + ), + 'optional' => array( + 'label' => __("Optional form fields", "gravityforms"), + 'tags' => $optional_group + ), + 'pricing' => array( + 'label' => __("Pricing form fields", "gravityforms"), + 'tags' => $pricing_group + ), + 'other' => array( + 'label' => __("Other", "gravityforms"), + 'tags' => $other_group + ), + 'custom' => array( + 'label' => __("Custom", "gravityforms"), + 'tags' => $custom_group + ) + ); + + return $merge_tags; + } + + public static function get_field_merge_tags($field, $option="") { + + $merge_tags = array(); + $tag_args = RGFormsModel::get_input_type($field) == "list" ? ":{$option}" : ""; //args currently only supported by list field + + if(isset($field["inputs"]) && is_array($field["inputs"])) { + + if(RGFormsModel::get_input_type($field) == "checkbox") { + $value = "{" . esc_html(GFCommon::get_label($field, $field["id"])) . ":" . $field["id"] . "{$tag_args}}"; + $merge_tags[] = array( 'tag' => $value, 'label' => esc_html(GFCommon::get_label($field, $field["id"])) ); + } + + foreach($field["inputs"] as $input) { + $value = "{" . esc_html(GFCommon::get_label($field, $input["id"])) . ":" . $input["id"] . "{$tag_args}}"; + $merge_tags[] = array( 'tag' => $value, 'label' => esc_html(GFCommon::get_label($field, $input["id"])) ); + } + + } + else { + $value = "{" . esc_html(GFCommon::get_label($field)) . ":" . $field["id"] . "{$tag_args}}"; + $merge_tags[] = array( 'tag' => $value, 'label' => esc_html(GFCommon::get_label($field)) ); + } + + return $merge_tags; + } + + public static function insert_field_variable($field, $max_label_size=40, $args=""){ + + $tag_args = RGFormsModel::get_input_type($field) == "list" ? ":{$args}" : ""; //args currently only supported by list field + + if(is_array($field["inputs"])) + { + if(RGFormsModel::get_input_type($field) == "checkbox"){ + ?> + + + + + + +    + + + + + + post_title; + case "caption" : + $media = get_post($media_id); + return $media->post_excerpt; + case "description" : + $media = get_post($media_id); + return $media->post_content; + + default : + + $img = wp_get_attachment_image($media_id, $arg1, false, array("class" => "size-{$arg1} align{$arg2} wp-image-{$media_id}")); + return $img; + } + } + + public static function replace_variables_post_image($text, $post_images, $lead){ + + preg_match_all('/{[^{]*?:(\d+)(:([^:]*?))?(:([^:]*?))?(:url)?}/mi', $text, $matches, PREG_SET_ORDER); + if(is_array($matches)) + { + foreach($matches as $match){ + $input_id = $match[1]; + + //ignore fields that are not post images + if(!isset($post_images[$input_id])) + continue; + + //Reading alignment and "url" parameters. + //Format could be {image:5:medium:left:url} or {image:5:medium:url} + $size_meta = empty($match[3]) ? "full" : $match[3]; + $align = empty($match[5]) ? "none" : $match[5]; + if($align == "url"){ + $align = "none"; + $is_url = true; + } + else{ + $is_url = rgar($match,6) == ":url"; + } + + $media_id = $post_images[$input_id]; + $value = is_wp_error($media_id) ? "" : self::get_post_image_variable($media_id, $size_meta, $align, $is_url); + + $text = str_replace($match[0], $value , $text); + } + } + + return $text; + } + + public static function implode_non_blank($separator, $array){ + + if(!is_array($array)) + return ""; + + $ary = array(); + foreach($array as $item){ + if(!rgblank($item)) + $ary[] = $item; + } + return implode($separator, $ary); + } + + private static function format_variable_value($value, $url_encode, $esc_html, $format){ + if($esc_html) + $value = esc_html($value); + + if($format == "html") + $value = nl2br($value); + + if($url_encode) + $value = urlencode($value); + + return $value; + } + + public static function replace_variables($text, $form, $lead, $url_encode = false, $esc_html=true, $nl2br = true, $format="html"){ + $text = $nl2br ? nl2br($text) : $text; + + //Replacing field variables: {FIELD_LABEL:FIELD_ID} {My Field:2} + preg_match_all('/{[^{]*?:(\d+(\.\d+)?)(:(.*?))?}/mi', $text, $matches, PREG_SET_ORDER); + if(is_array($matches)) + { + foreach($matches as $match){ + $input_id = $match[1]; + + $field = RGFormsModel::get_field($form,$input_id); + + $value = RGFormsModel::get_lead_field_value($lead, $field); + $raw_value = $value; + + if(is_array($value)) + $value = rgar($value, $input_id); + + $value = self::format_variable_value($value, $url_encode, $esc_html, $format); + + switch(RGFormsModel::get_input_type($field)){ + + case "number" : + + $value = GFCommon::format_number($value, rgar($field, "numberFormat")); + + break; + + 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); + } + + break; + + case "post_image" : + list( $url, $title, $caption, $description ) = array_pad( explode( '|:|', $value ), 4, false ); + $value = str_replace( ' ', '%20', $url ); + break; + + case "checkbox" : + case "select" : + case "radio" : + + $use_value = rgar($match,4) == "value"; + $use_price = in_array(rgar($match,4), array("price", "currency")); + $format_currency = rgar($match,4) == "currency"; + + if(is_array($raw_value) && (string)intval($input_id) != $input_id){ + $items = array($input_id => $value); //float input Ids. (i.e. 4.1 ). Used when targeting specific checkbox items + } + else if(is_array($raw_value)){ + $items = $raw_value; + } + else{ + $items = array($input_id => $raw_value); + } + + $ary = array(); + + foreach($items as $input_id => $item){ + if($use_value){ + list($val, $price) = rgexplode("|", $item, 2); + } + else if($use_price){ + list($name, $val) = rgexplode("|", $item, 2); + if($format_currency) + $val = GFCommon::to_money($val, rgar($lead, "currency")); + } + else if($field["type"] == "post_category"){ + $use_id = strtolower(rgar($match,4)) == "id"; + $item_value = self::format_post_category($item, $use_id); + + $val = RGFormsModel::is_field_hidden($form, $field, array(), $lead) ? "" : $item_value; + } + else{ + $val = RGFormsModel::is_field_hidden($form, $field, array(), $lead) ? "" : RGFormsModel::get_choice_text($field, $raw_value, $input_id); + } + + $ary[] = self::format_variable_value($val, $url_encode, $esc_html, $format); + } + + $value = self::implode_non_blank(", ", $ary); + + break; + + case "multiselect" : + if($field["type"] == "post_category"){ + $use_id = strtolower(rgar($match,4)) == "id"; + $items = explode(",", $value); + + if(is_array($items)){ + $cats = array(); + foreach($items as $item){ + $cat = self::format_post_category($item, $use_id); + $cats[] = self::format_variable_value($cat, $url_encode, $esc_html, $format); + } + $value = self::implode_non_blank(", ", $cats); + } + } + + break; + + case "date" : + $value = self::date_display($value, rgar($field,"dateFormat")); + break; + + case "total" : + $format_numeric = rgar($match,4) == "price"; + + $value = $format_numeric ? GFCommon::to_number($value) : GFCommon::to_money($value); + + $value = self::format_variable_value($value, $url_encode, $esc_html, $format); + break; + + case "post_category" : + $use_id = strtolower(rgar($match,4)) == "id"; + $value = self::format_post_category($value, $use_id); + $value = self::format_variable_value($value, $url_encode, $esc_html, $format); + break; + + case "list" : + $output_format = in_array(rgar($match,4), array("text", "html", "url")) ? rgar($match,4) : $format; + $value = self::get_lead_field_display($field, $raw_value, $lead["currency"], true, $output_format); + break; + } + + if(rgar($match,4) == "label"){ + $value = empty($value) ? "" : rgar($field, "label"); + } + else if(rgar($match,4) == "qty" && $field["type"] == "product"){ + //getting quantity associated with product field + $products = self::get_product_fields($form, $lead, false, false); + $value = 0; + foreach($products["products"] as $product_id => $product) + { + if($product_id == $field["id"]) + $value = $product["quantity"]; + } + } + + //Encoding left curly bracket so that merge tags entered in the front end are displayed as is and not "executed" + $value = self::encode_merge_tag($value); + + //filter can change merge code variable + $value = apply_filters("gform_merge_tag_filter", $value, $input_id, rgar($match,4), $field, $raw_value); + if($value === false) + $value = ""; + + $text = str_replace($match[0], $value , $text); + } + } + + //replacing global variables + //form title + $text = str_replace("{form_title}", $url_encode ? urlencode($form["title"]) : $form["title"], $text); + + $matches = array(); + preg_match_all("/{all_fields(:(.*?))?}/", $text, $matches, PREG_SET_ORDER); + foreach($matches as $match){ + $options = explode(",", rgar($match,2)); + $use_value = in_array("value", $options); + $display_empty = in_array("empty", $options); + $use_admin_label = in_array("admin", $options); + + //all submitted fields using text + if (strpos($text, $match[0]) !== false){ + $text = str_replace($match[0], self::get_submitted_fields($form, $lead, $display_empty, !$use_value, $format, $use_admin_label, "all_fields", rgar($match,2)), $text); + } + } + + //all submitted fields including empty fields + if (strpos($text, "{all_fields_display_empty}") !== false){ + $text = str_replace("{all_fields_display_empty}", self::get_submitted_fields($form, $lead, true, true, $format, false, "all_fields_display_empty"), $text); + } + + //pricing fields + if (strpos($text, "{pricing_fields}") !== false){ + $text = str_replace("{pricing_fields}", ' + +
    + ' . + self::get_submitted_pricing_fields($form, $lead, $format) . + '
    +
    ', + $text); + } + + //form id + $text = str_replace("{form_id}", $url_encode ? urlencode($form["id"]) : $form["id"], $text); + + //entry id + $text = str_replace("{entry_id}", $url_encode ? urlencode(rgar($lead, "id")) : rgar($lead, "id"), $text); + + //entry url + $entry_url = get_bloginfo("wpurl") . "/wp-admin/admin.php?page=gf_entries&view=entry&id=" . $form["id"] . "&lid=" . rgar($lead,"id"); + $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); + + //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"]; + $text = str_replace("{post_edit_url}", $url_encode ? urlencode($post_url) : $post_url, $text); + + $text = self::replace_variables_prepopulate($text, $url_encode); + + // hook allows for custom merge tags + $text = apply_filters('gform_replace_merge_tags', $text, $form, $lead, $url_encode, $esc_html, $nl2br, $format); + + // TODO: Deprecate the 'gform_replace_merge_tags' and replace it with a call to the 'gform_merge_tag_filter' + //$text = apply_filters('gform_merge_tag_filter', $text, false, false, false ); + + $text = self::decode_merge_tag($text); + return $text; + } + + public static function encode_merge_tag($text){ + return str_replace("{", "{", $text); + } + + public static function decode_merge_tag($text){ + return str_replace("{", "{", $text); + } + + public static function format_post_category($value, $use_id){ + + list($item_value, $item_id) = rgexplode(":", $value, 2); + + if($use_id && !empty($item_id)) + $item_value = $item_id; + + return $item_value; + } + + public static function get_embed_post(){ + global $embed_post, $post, $wp_query; + + if($embed_post){ + return $embed_post; + } + + if(!rgempty("gform_embed_post")){ + $post_id = absint(rgpost("gform_embed_post")); + $embed_post = get_post($post_id); + } + else if($wp_query->is_in_loop){ + $embed_post = $post; + } + else{ + $embed_post = array(); + } + } + + public static function replace_variables_prepopulate($text, $url_encode=false){ + + //embed url + $text = str_replace("{embed_url}", $url_encode ? urlencode(RGFormsModel::get_current_page_url()) : RGFormsModel::get_current_page_url(), $text); + + $local_timestamp = self::get_local_timestamp(time()); + + //date (mm/dd/yyyy) + $local_date_mdy = date_i18n("m/d/Y", $local_timestamp, true); + $text = str_replace("{date_mdy}", $url_encode ? urlencode($local_date_mdy) : $local_date_mdy, $text); + + //date (dd/mm/yyyy) + $local_date_dmy = date_i18n("d/m/Y", $local_timestamp, true); + $text = str_replace("{date_dmy}", $url_encode ? urlencode($local_date_dmy) : $local_date_dmy, $text); + + // ip + $ip = GFFormsModel::get_ip(); + $text = str_replace( '{ip}', $url_encode ? urlencode( $ip ) : $ip, $text ); + + global $post; + $post_array = self::object_to_array($post); + preg_match_all("/\{embed_post:(.*?)\}/", $text, $matches, PREG_SET_ORDER); + foreach($matches as $match){ + $full_tag = $match[0]; + $property = $match[1]; + $text = str_replace($full_tag, $url_encode ? urlencode($post_array[$property]) : $post_array[$property], $text); + } + + //embed post custom fields + preg_match_all("/\{custom_field:(.*?)\}/", $text, $matches, PREG_SET_ORDER); + foreach($matches as $match){ + + $full_tag = $match[0]; + $custom_field_name = $match[1]; + $custom_field_value = !empty($post_array["ID"]) ? get_post_meta($post_array["ID"], $custom_field_name, true) : ""; + $text = str_replace($full_tag, $url_encode ? urlencode($custom_field_value) : $custom_field_value, $text); + } + + //user agent + $text = str_replace("{user_agent}", $url_encode ? urlencode(RGForms::get("HTTP_USER_AGENT", $_SERVER)) : RGForms::get("HTTP_USER_AGENT", $_SERVER), $text); + + //referrer + $text = str_replace("{referer}", $url_encode ? urlencode(RGForms::get("HTTP_REFERER", $_SERVER)) : RGForms::get("HTTP_REFERER", $_SERVER), $text); + + //logged in user info + global $userdata, $wp_version, $current_user; + $user_array = self::object_to_array($userdata); + + preg_match_all("/\{user:(.*?)\}/", $text, $matches, PREG_SET_ORDER); + foreach($matches as $match){ + $full_tag = $match[0]; + $property = $match[1]; + + $value = version_compare($wp_version, '3.3', '>=') ? $current_user->get($property) : $user_array[$property]; + $value = $url_encode ? urlencode($value) : $value; + + $text = str_replace($full_tag, $value, $text); + } + + return $text; + } + + public static function object_to_array($object){ + $array=array(); + if(!empty($object)){ + foreach($object as $member=>$data) + $array[$member]=$data; + } + return $array; + } + + public static function is_empty_array($val){ + if(!is_array($val)) + $val = array($val); + + $ary = array_values($val); + foreach($ary as $item){ + if(!rgblank($item)) + return false; + } + return true; + } + + public static function get_submitted_fields($form, $lead, $display_empty=false, $use_text=false, $format="html", $use_admin_label=false, $merge_tag="", $options=""){ + + $field_data = ""; + if($format == "html"){ + $field_data = ' + +
    + + '; + } + + $options_array = explode(",", $options); + $no_admin = in_array("noadmin", $options_array); + $no_hidden = in_array("nohidden", $options_array); + $has_product_fields = false; + foreach($form["fields"] as $field){ + $field_value = ""; + + $field_label = $use_admin_label && !rgempty("adminLabel", $field) ? rgar($field, "adminLabel") : esc_html(GFCommon::get_label($field)); + + switch($field["type"]){ + case "captcha" : + break; + + case "section" : + if((!GFCommon::is_section_empty($field, $form, $lead) || $display_empty) && !rgar($field, "adminOnly")){ + + switch($format){ + case "text" : + $field_value = "--------------------------------\n{$field_label}\n\n"; + break; + + default: + $field_value = sprintf(' + + + ', $field_label); + break; + } + } + + $field_value = apply_filters("gform_merge_tag_filter", $field_value, $merge_tag, $options, $field, $field_label); + + $field_data .= $field_value; + + break; + case "password" : + //ignore password fields + break; + + default : + + //ignore product fields as they will be grouped together at the end of the grid + if(self::is_product_field($field["type"])){ + $has_product_fields = true; + continue; + } + else if(RGFormsModel::is_field_hidden($form, $field, array(), $lead)){ + //ignore fields hidden by conditional logic + continue; + } + + $raw_field_value = RGFormsModel::get_lead_field_value($lead, $field); + $field_value = GFCommon::get_lead_field_display($field, $raw_field_value, rgar($lead,"currency"), $use_text, $format, "email"); + + $display_field = true; + //depending on parameters, don't display adminOnly or hidden fields + if($no_admin && rgar($field, "adminOnly")) + $display_field = false; + else if($no_hidden && RGFormsModel::get_input_type($field) == "hidden") + $display_field = false; + + //if field is not supposed to be displayed, pass false to filter. otherwise, pass field's value + if(!$display_field) + $field_value = false; + + $field_value = apply_filters("gform_merge_tag_filter", $field_value, $merge_tag, $options, $field, $raw_field_value); + + if($field_value === false) + continue; + + if( !empty($field_value) || strlen($field_value) > 0 || $display_empty){ + switch($format){ + case "text" : + $field_data .= "{$field_label}: {$field_value}\n\n"; + break; + + default: + + $field_data .= sprintf(' + + + + + + + ', $field_label, empty($field_value) && strlen($field_value) == 0 ? " " : $field_value, apply_filters("gform_email_background_color_label", '#EAF2FA', $field, $lead), apply_filters("gform_email_background_color_data", '#FFFFFF', $field, $lead) ); + break; + } + } + } + } + + if($has_product_fields) + $field_data .= self::get_submitted_pricing_fields($form, $lead, $format, $use_text, $use_admin_label); + + if($format == "html"){ + $field_data .='
    %s
    + %1$s +
      + %2$s +
    +
    '; + } + + return $field_data; + } + + public static function get_submitted_pricing_fields($form, $lead, $format, $use_text=true, $use_admin_label=false){ + $form_id = $form["id"]; + $order_label = apply_filters("gform_order_label_{$form["id"]}", apply_filters("gform_order_label", __("Order", "gravityforms"), $form["id"]), $form["id"]); + $products = GFCommon::get_product_fields($form, $lead, $use_text, $use_admin_label); + $total = 0; + $field_data = ""; + + switch($format){ + case "text" : + if(!empty($products["products"])){ + $field_data = "--------------------------------\n" . $order_label . "\n\n"; + foreach($products["products"] as $product){ + $product_name = $product["quantity"] . " " . $product["name"]; + $price = self::to_number($product["price"]); + if(!empty($product["options"])){ + $product_name .= " ("; + $options = array(); + foreach($product["options"] as $option){ + $price += self::to_number($option["price"]); + $options[] = $option["option_name"]; + } + $product_name .= implode(", ", $options) . ")"; + } + $subtotal = floatval($product["quantity"]) * $price; + $total += $subtotal; + + $field_data .= "{$product_name}: " . self::to_money($subtotal, $lead["currency"]) . "\n\n"; + } + $total += floatval($products["shipping"]["price"]); + + if(!empty($products["shipping"]["name"])) + $field_data .= $products["shipping"]["name"] . ": " . self::to_money($products["shipping"]["price"], $lead["currency"]) . "\n\n"; + + $field_data .= __("Total", "gravityforms") . ": " . self::to_money($total, $lead["currency"]) . "\n\n"; + } + break; + + + default : + if(!empty($products["products"])){ + $field_data =' + + ' . $order_label . ' + + + +   + + + + + + + + + '; + + + foreach($products["products"] as $product){ + + $field_data .= ' + + + + + '; + } + $total += floatval($products["shipping"]["price"]); + $field_data .= ' + '; + + if(!empty($products["shipping"]["name"])){ + $field_data .= ' + + + + + + '; + } + + $field_data .= ' + '; + + if(empty($products["shipping"]["name"])){ + $field_data .= ' + '; + } + + $field_data .= ' + + + + +
    ' . apply_filters("gform_product_{$form_id}", apply_filters("gform_product", __("Product", "gravityforms"), $form_id), $form_id) . '' . apply_filters("gform_product_qty_{$form_id}", apply_filters("gform_product_qty", __("Qty", "gravityforms"), $form_id), $form_id) . '' . apply_filters("gform_product_unitprice_{$form_id}", apply_filters("gform_product_unitprice", __("Unit Price", "gravityforms"), $form_id), $form_id) . '' . apply_filters("gform_product_price_{$form_id}", apply_filters("gform_product_price", __("Price", "gravityforms"), $form_id), $form_id) . '
    + ' . $product["name"] .' +
      '; + + $price = self::to_number($product["price"]); + if(is_array(rgar($product,"options"))){ + foreach($product["options"] as $option){ + $price += self::to_number($option["price"]); + $field_data .= '
    • ' . $option["option_label"] .'
    • '; + } + } + $subtotal = floatval($product["quantity"]) * $price; + $total += $subtotal; + + $field_data .='
    +
    ' . $product["quantity"] .'' . self::to_money($price, $lead["currency"]) .'' . self::to_money($subtotal, $lead["currency"]) .'
     ' . $products["shipping"]["name"] . ''. self::to_money($products["shipping"]["price"], $lead["currency"]) . '
     ' . __("Total:", "gravityforms") . ''. self::to_money($total, $lead["currency"]) . '
    + + '; + } + break; + } + + return $field_data; + } + + public static function send_user_notification($form, $lead, $override_options = false){ + _deprecated_function("send_user_notification", "1.7", "send_notification"); + + $notification = self::prepare_user_notification($form, $lead, $override_options); + self::send_email($notification["from"], $notification["to"], $notification["bcc"], $notification["reply_to"], $notification["subject"], $notification["message"], $notification["from_name"], $notification["message_format"], $notification["attachments"]); + } + + public static function send_admin_notification($form, $lead, $override_options = false){ + _deprecated_function("send_admin_notification", "1.7", "send_notification"); + + $notification = self::prepare_admin_notification($form, $lead, $override_options); + self::send_email($notification["from"], $notification["to"], $notification["bcc"], $notification["replyTo"], $notification["subject"], $notification["message"], $notification["from_name"], $notification["message_format"], $notification["attachments"]); + } + + private static function prepare_user_notification($form, $lead, $override_options = false){ + $form_id = $form["id"]; + + if(!isset($form["autoResponder"])) + return; + + //handling autoresponder email + $to_field = isset($form["autoResponder"]["toField"]) ? rgget($form["autoResponder"]["toField"], $lead) : ""; + $to = apply_filters("gform_autoresponder_email_{$form_id}", apply_filters("gform_autoresponder_email", $to_field, $form), $form); + $subject = GFCommon::replace_variables(rgget("subject", $form["autoResponder"]), $form, $lead, false, false); + + $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); + + //Running trough variable replacement + $to = GFCommon::replace_variables($to, $form, $lead, false, false); + $from = GFCommon::replace_variables(rgget("from", $form["autoResponder"]), $form, $lead, false, false); + $bcc = GFCommon::replace_variables(rgget("bcc", $form["autoResponder"]), $form, $lead, false, false); + $reply_to = GFCommon::replace_variables(rgget("replyTo", $form["autoResponder"]), $form, $lead, false, false); + $from_name = GFCommon::replace_variables(rgget("fromName", $form["autoResponder"]), $form, $lead, false, false); + + // override default values if override options provided + if($override_options && is_array($override_options)){ + foreach($override_options as $override_key => $override_value){ + ${$override_key} = $override_value; + } + } + + $attachments = apply_filters("gform_user_notification_attachments_{$form_id}", apply_filters("gform_user_notification_attachments", array(), $lead, $form), $lead, $form); + + //Disabling autoformat to prevent double autoformatting of messages + $disableAutoformat = "1"; + + return compact("to", "from", "bcc", "reply_to", "subject", "message", "from_name", "message_format", "attachments", "disableAutoformat"); + } + + private static function prepare_admin_notification($form, $lead, $override_options = false){ + $form_id = $form["id"]; + + //handling admin notification email + $subject = GFCommon::replace_variables(rgget("subject", $form["notification"]), $form, $lead, false, false); + + $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); + + $version_info = self::get_version_info(); + $is_expired = !rgempty("expiration_time", $version_info) && $version_info["expiration_time"] < time(); + if( !rgar($version_info, "is_valid_key") && $is_expired){ + $message .= "

    Your Gravity Forms License Key has expired. In order to continue receiving support and software updates you must renew your license key. You can do so by following the renewal instructions on the Gravity Forms Settings page in your WordPress Dashboard or by clicking here."; + } + + $from = rgempty("fromField", $form["notification"]) ? rgget("from", $form["notification"]) : rgget($form["notification"]["fromField"], $lead); + + if(rgempty("fromNameField", $form["notification"])){ + $from_name = rgget("fromName", $form["notification"]); + } + else{ + $field = RGFormsModel::get_field($form, rgget("fromNameField", $form["notification"])); + $value = RGFormsModel::get_lead_field_value($lead, $field); + $from_name = GFCommon::get_lead_field_display($field, $value); + } + + $replyTo = rgempty("replyToField", $form["notification"]) ? rgget("replyTo", $form["notification"]): rgget($form["notification"]["replyToField"], $lead); + + if(rgempty("routing", $form["notification"])){ + $email_to = rgempty("toField", $form["notification"]) ? rgget("to", $form["notification"]) : rgget("toField", $form["notification"]); + } + else{ + $email_to = array(); + foreach($form["notification"]["routing"] as $routing){ + + $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); + + if ($is_value_match) + $email_to[] = $routing["email"]; + } + + $email_to = join(",", $email_to); + } + + //Running through variable replacement + $email_to = GFCommon::replace_variables($email_to, $form, $lead, false, false); + $from = GFCommon::replace_variables($from, $form, $lead, false, false); + $bcc = GFCommon::replace_variables(rgget("bcc", $form["notification"]), $form, $lead, false, false); + $reply_to = GFCommon::replace_variables($replyTo, $form, $lead, false, false); + $from_name = GFCommon::replace_variables($from_name, $form, $lead, false, false); + + //Filters the admin notification email to address. Allows users to change email address before notification is sent + $to = apply_filters("gform_notification_email_{$form_id}" , apply_filters("gform_notification_email", $email_to, $lead), $lead); + + // override default values if override options provided + if($override_options && is_array($override_options)){ + foreach($override_options as $override_key => $override_value){ + ${$override_key} = $override_value; + } + } + + $attachments = apply_filters("gform_admin_notification_attachments_{$form_id}", apply_filters("gform_admin_notification_attachments", array(), $lead, $form), $lead, $form); + + //Disabling autoformat to prevent double autoformatting of messages + $disableAutoformat = "1"; + + return compact("to", "from", "bcc", "replyTo", "subject", "message", "from_name", "message_format", "attachments", "disableAutoformat"); + + } + + public static function send_notification($notification, $form, $lead){ + + $notification = apply_filters("gform_notification_{$form["id"]}", apply_filters("gform_notification", $notification, $form, $lead), $form, $lead); + + $to_field = ""; + if(rgar($notification, "toType") == "field"){ + $to_field = rgar($notification, "toField"); + if(rgempty("toField", $notification)){ + $to_field = rgar($notification, "to"); + } + } + + $email_to = rgar($notification, "to"); + //do routing logic if "to" field doesn't have a value (to support legacy notifications what will run routing prior to this method + if(empty($email_to) && rgar($notification, "toType") == "routing"){ + $email_to = array(); + foreach($notification["routing"] as $routing){ + + $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); + + if ($is_value_match) + $email_to[] = $routing["email"]; + } + + $email_to = join(",", $email_to); + } + else if (!empty($to_field)) { + $source_field = RGFormsModel::get_field($form, $to_field); + $email_to = RGFormsModel::get_lead_field_value($lead, $source_field); + } + + //Running through variable replacement + $to = GFCommon::replace_variables($email_to, $form, $lead, false, false); + $subject = GFCommon::replace_variables(rgar($notification, "subject"), $form, $lead, false, false); + $from = GFCommon::replace_variables(rgar($notification, "from"), $form, $lead, false, false); + $from_name = GFCommon::replace_variables(rgar($notification, "fromName"), $form, $lead, false, false); + $bcc = GFCommon::replace_variables(rgar($notification, "bcc"), $form, $lead, false, false); + $replyTo = GFCommon::replace_variables(rgar($notification, "replyTo"), $form, $lead, false, false); + + $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); + + // 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" ); + if( !empty( $attachments ) ) { + $attachments = is_array( $attachments ) ? $attachments : array( $attachments ); + } else { + $attachments = array(); + } + + self::send_email($from, $to, $bcc, $replyTo, $subject, $message, $from_name, $message_format, $attachments); + + return compact("to", "from", "bcc", "replyTo", "subject", "message", "from_name", "message_format", "attachments"); + + } + + public static function send_notifications($notification_ids, $form, $lead, $do_conditional_logic = true, $event = "form_submission"){ + if(!is_array($notification_ids)){ + GFCommon::log_debug("No notifications to be sent."); + return; + } + + GFCommon::log_debug( 'Processing notifications: ' . print_r( $notification_ids, true ) . "\n(only active/applicable notifications are sent)" ); + + foreach($notification_ids as $notification_id){ + if(!isset($form["notifications"][$notification_id])){ + continue; + } + if(isset($form["notifications"][$notification_id]["isActive"]) && ! $form["notifications"][$notification_id]["isActive"]){ + continue; + } + + $notification = $form["notifications"][$notification_id]; + + //check conditional logic when appropriate + if($do_conditional_logic && !GFCommon::evaluate_conditional_logic( rgar($notification,"conditionalLogic"), $form, $lead) ){ + continue; + } + + if(rgar($notification,"type") == "user"){ + + //Getting user notification from legacy structure (for backwards compatibility) + $legacy_notification = GFCommon::prepare_user_notification($form, $lead); + $notification = self::merge_legacy_notification($notification, $legacy_notification); + } + else if(rgar($notification,"type") == "admin"){ + + //Getting admin notification from legacy structure (for backwards compatibility) + $legacy_notification = GFCommon::prepare_admin_notification($form, $lead); + $notification = self::merge_legacy_notification($notification, $legacy_notification); + } + + + //sending notification + self::send_notification($notification, $form, $lead); + } + + } + + public static function send_form_submission_notifications($form, $lead){ + $notifications = self::get_notifications_to_send("form_submission", $form, $lead); + $notifications_to_send = array(); + + + + //running through filters that disable form submission notifications + foreach($notifications as $notification){ + + if(rgar($notification,"type") == "user" && apply_filters("gform_disable_user_notification_{$form["id"]}", apply_filters("gform_disable_user_notification", false, $form, $lead), $form, $lead)){ + //skip user notification if it has been disabled by a hook + continue; + } + else if(rgar($notification,"type") == "admin" && apply_filters("gform_disable_admin_notification_{$form["id"]}", apply_filters("gform_disable_admin_notification", false, $form, $lead), $form, $lead)){ + //skip admin notification if it has been disabled by a hook + continue; + } + + if(apply_filters("gform_disable_notification_{$form["id"]}", apply_filters("gform_disable_notification", false, $notification, $form, $lead), $notification, $form, $lead)){ + //skip notifications if it has been disabled by a hook + continue; + } + + $notifications_to_send[] = $notification["id"]; + } + + + self::send_notifications($notifications_to_send, $form, $lead, true, "form_submission"); + } + + private static function merge_legacy_notification($notification, $notification_data){ + + $keys = array("to", "from", "bcc", "replyTo", "subject", "message", "from_name", "message_format", "attachments", "disableAutoformat"); + foreach($keys as $key) + $notification[$key] = rgar($notification_data,$key); + + return $notification; + } + + public static function get_notifications_to_send($action, $form, $lead){ + $notifications = self::get_notifications($action, $form); + $notifications_to_send = array(); + foreach($notifications as $notification){ + if(GFCommon::evaluate_conditional_logic(rgar($notification,"conditionalLogic"), $form, $lead)){ + $notifications_to_send[] = $notification; + } + } + + return $notifications_to_send; + } + + public static function get_notifications($action, $form){ + if(rgempty("notifications", $form)) + return array(); + + $notifications = array(); + foreach($form["notifications"] as $notification){ + if(rgar($notification, "event") == $action) + $notifications[] = $notification; + } + + return $notifications; + } + + public static function has_admin_notification($form){ + + return (!empty($form["notification"]["to"]) || !empty($form["notification"]["routing"])) && (!empty($form["notification"]["subject"]) || !empty($form["notification"]["message"])); + + } + + public static function has_user_notification($form){ + + return !empty($form["autoResponder"]["toField"]) && (!empty($form["autoResponder"]["subject"]) || !empty($form["autoResponder"]["message"])); + + } + + 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); + + //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"); + + //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)); + return; + } + + $content_type = $message_format == "html" ? "text/html" : "text/plain"; + + $name = empty($from_name) ? $from : $from_name; + + $headers = array(); + $headers["From"] = "From: \"{$name}\" <{$from}>"; + + if(GFCommon::is_valid_email($reply_to)) + $headers["Reply-To"] = "Reply-To: {$reply_to}"; + + if(GFCommon::is_valid_email($bcc)) + $headers["Bcc"] = "Bcc: $bcc"; + + $headers["Content-type"] = "Content-type: {$content_type}; charset=" . get_option('blog_charset'); + + $abort_email = false; + extract(apply_filters("gform_pre_send_email", compact("to", "subject", "message", "headers", "attachments", "abort_email"), $message_format)); + + $is_success = false; + if(!$abort_email){ + GFCommon::log_debug("Sending email via wp_mail()"); + GFCommon::log_debug(print_r(compact("to", "subject", "message", "headers", "attachments", "abort_email"), true)); + $is_success = wp_mail($to, $subject, $message, $headers, $attachments); + GFCommon::log_debug( "Result from wp_mail(): {$is_success}" ); + if( $is_success ) { + GFCommon::log_debug( 'Mail was passed from WordPress to the mail server.' ); + } else { + GFCommon::log_debug( 'The mail message was passed off to WordPress for processing, but WordPress was unable to send the message.' ); + } + + } + + self::add_emails_sent(); + + do_action("gform_after_email", $is_success, $to, $subject, $message, $headers, $attachments, $message_format); + } + + public static function add_emails_sent(){ + + $count = self::get_emails_sent(); + + update_option("gform_email_count", ++$count); + + } + + public static function get_emails_sent(){ + $count = get_option("gform_email_count"); + + if(!$count) + $count = 0; + + return $count; + } + + public static function get_api_calls(){ + $count = get_option("gform_api_count"); + + if(!$count) + $count = 0; + + return $count; + } + + public static function add_api_call(){ + + $count = self::get_api_calls(); + + update_option("gform_api_count", ++$count); + + } + + public static function has_post_field($fields){ + foreach($fields as $field){ + if(in_array($field["type"], array("post_title", "post_content", "post_excerpt", "post_category", "post_image", "post_tags", "post_custom_field"))) + return true; + } + return false; + } + + public static function has_list_field($form){ + return self::has_field_by_type($form, 'list'); + } + + public static function has_credit_card_field($form){ + return self::has_field_by_type($form, 'creditcard'); + } + + private static function has_field_by_type($form, $type) { + if(is_array($form["fields"])){ + foreach($form["fields"] as $field){ + + if(RGFormsModel::get_input_type($field) == $type) + return true; + } + } + return false; + } + + public static function current_user_can_any($caps){ + + if(!is_array($caps)){ + $has_cap = current_user_can($caps) || current_user_can("gform_full_access"); + return $has_cap; + } + + foreach($caps as $cap){ + if(current_user_can($cap)){ + return true; + } + } + + $has_full_access = current_user_can("gform_full_access"); + return $has_full_access; + } + + public static function current_user_can_which($caps){ + + foreach($caps as $cap){ + if(current_user_can($cap)) + return $cap; + } + + return ""; + } + + public static function is_pricing_field($field_type){ + return self::is_product_field($field_type) || $field_type == "donation"; + } + + public static function is_product_field($field_type){ + return in_array($field_type, array("option", "quantity", "product", "total", "shipping", "calculation")); + } + + public static function all_caps(){ + return array( 'gravityforms_edit_forms', + 'gravityforms_delete_forms', + 'gravityforms_create_form', + 'gravityforms_view_entries', + 'gravityforms_edit_entries', + 'gravityforms_delete_entries', + 'gravityforms_view_settings', + 'gravityforms_edit_settings', + 'gravityforms_export_entries', + 'gravityforms_uninstall', + 'gravityforms_view_entry_notes', + 'gravityforms_edit_entry_notes', + 'gravityforms_view_updates', + 'gravityforms_view_addons', + 'gravityforms_preview_forms' + ); + } + + public static function delete_directory($dir) { + if(!file_exists($dir)) + return; + + if ($handle = opendir($dir)){ + $array = array(); + while (false !== ($file = readdir($handle))) { + if ($file != "." && $file != "..") { + if(is_dir($dir.$file)){ + if(!@rmdir($dir.$file)) // Empty directory? Remove it + self::delete_directory($dir.$file.'/'); // Not empty? Delete the files inside it + } + else{ + @unlink($dir.$file); + } + } + } + closedir($handle); + @rmdir($dir); + } + } + + public static function get_remote_message(){ + return stripslashes(get_option("rg_gforms_message")); + } + + public static function get_key(){ + return get_option("rg_gforms_key"); + } + + public static function has_update($use_cache=true){ + $version_info = GFCommon::get_version_info($use_cache); + $version = rgar($version_info, "version"); + return empty($version) ? false : version_compare(GFCommon::$version, $version, '<'); + } + + public static function get_key_info($key){ + + $options = array('method' => 'POST', 'timeout' => 3); + $options['headers'] = array( + 'Content-Type' => 'application/x-www-form-urlencoded; charset=' . get_option('blog_charset'), + 'User-Agent' => 'WordPress/' . get_bloginfo("version"), + 'Referer' => get_bloginfo("url") + ); + $request_url = GRAVITY_MANAGER_URL . "/api.php?op=get_key&key={$key}"; + $raw_response = wp_remote_request($request_url, $options); + if ( is_wp_error( $raw_response ) || $raw_response['response']['code'] != 200) + return array(); + + $key_info = unserialize(trim($raw_response["body"])); + return $key_info ? $key_info : array(); + } + + public static function get_version_info($cache=true){ + + $raw_response = get_transient("gform_update_info"); + if(!$cache) + $raw_response = null; + + if(!$raw_response){ + //Getting version number + $options = array('method' => 'POST', 'timeout' => 20); + $options['headers'] = array( + 'Content-Type' => 'application/x-www-form-urlencoded; charset=' . get_option('blog_charset'), + 'User-Agent' => 'WordPress/' . get_bloginfo("version"), + 'Referer' => get_bloginfo("url") + ); + $options['body'] = self::get_remote_post_params(); + $options['timeout'] = 15; + + $nocache = $cache ? "" : "?nocache=1"; //disabling server side caching + $request_url = GRAVITY_MANAGER_URL . "/version.php{$nocache}"; + + $raw_response = wp_remote_request($request_url, $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 ) + return array("is_valid_key" => "1", "version" => "", "url" => "", "is_error" => "1"); + + $version_info = json_decode($raw_response['body'], true); + + if( empty($version_info) ) + return array("is_valid_key" => "1", "version" => "", "url" => "", "is_error" => "1"); + + return $version_info; + } + + public static function get_remote_request_params(){ + global $wpdb; + + return sprintf("of=GravityForms&key=%s&v=%s&wp=%s&php=%s&mysql=%s&version=2", urlencode(self::get_key()), urlencode(self::$version), urlencode(get_bloginfo("version")), urlencode(phpversion()), urlencode($wpdb->db_version())); + } + + public static function get_remote_post_params(){ + global $wpdb; + + if(!function_exists('get_plugins')){ + require_once(ABSPATH . 'wp-admin/includes/plugin.php'); + } + $plugin_list = get_plugins(); + $site_url = get_bloginfo("url"); + $plugins = array(); + + $active_plugins = get_option( 'active_plugins' ); + + foreach ($plugin_list as $key => $plugin) { + $is_active = in_array($key, $active_plugins); + + //filter for only gravityforms ones, may get some others if using our naming convention + if (strpos(strtolower($plugin["Title"]), "gravity forms") !== false){ + $name = substr($key, 0, strpos($key,"/")); + $plugins[] = array("name" => $name, "version" => $plugin["Version"], "is_active" => $is_active); + } + } + $plugins = json_encode($plugins); + + //get theme info + $theme = wp_get_theme(); + $theme_name = $theme->get("Name"); + $theme_uri = $theme->get("ThemeURI"); + $theme_version = $theme->get("Version"); + $theme_author = $theme->get("Author"); + $theme_author_uri = $theme->get("AuthorURI"); + + $form_counts = GFFormsModel::get_form_count(); + $active_count = $form_counts["active"]; + $inactive_count = $form_counts["inactive"]; + $fc = abs($active_count) + abs($inactive_count); + $entry_count = GFFormsModel::get_lead_count_all_forms("active"); + $im = is_multisite(); + + $post = array("of" => "gravityforms", "key" => self::get_key(), "v" => self::$version, "wp" => get_bloginfo("version"), "php" => phpversion(), "mysql" => $wpdb->db_version(), "version" => "2", "plugins" => $plugins, "tn" => $theme_name, "tu" => $theme_uri, "tv" => $theme_version, "ta" => $theme_author, "tau" => $theme_author_uri, "im" => $im, "fc" => $fc, "ec" => $entry_count, "emc" => self::get_emails_sent(), "api" => self::get_api_calls()); + return $post; + } + + public static function ensure_wp_version(){ + if(!GF_SUPPORTED_WP_VERSION){ + echo "
    " . sprintf(__("Gravity Forms require WordPress %s or greater. You must upgrade WordPress in order to use Gravity Forms", "gravityforms"), GF_MIN_WP_VERSION) . "
    "; + return false; + } + return true; + } + + public static function check_update($option, $cache=true){ + + if(!is_object($option)) + return $option; + + $version_info = self::get_version_info($cache); + + if (!$version_info) + return $option; + + $plugin_path = "gravityforms/gravityforms.php"; + if(empty($option->response[$plugin_path])) + $option->response[$plugin_path] = new stdClass(); + + $version = rgar($version_info, "version"); + //Empty response means that the key is invalid. Do not queue for upgrade + if(!$version_info["is_valid_key"] || version_compare(GFCommon::$version, $version, '>=')){ + unset($option->response[$plugin_path]); + } + else{ + $url = rgar($version_info, "url"); + $option->response[$plugin_path]->url = "http://www.gravityforms.com"; + $option->response[$plugin_path]->slug = "gravityforms"; + $option->response[$plugin_path]->package = str_replace("{KEY}", GFCommon::get_key(), $url); + $option->response[$plugin_path]->new_version = $version; + $option->response[$plugin_path]->id = "0"; + } + + return $option; + + } + + public static function cache_remote_message(){ + //Getting version number + $key = GFCommon::get_key(); + $body = "key=$key"; + $options = array('method' => 'POST', 'timeout' => 3, 'body' => $body); + $options['headers'] = array( + 'Content-Type' => 'application/x-www-form-urlencoded; charset=' . get_option('blog_charset'), + 'Content-Length' => strlen($body), + 'User-Agent' => 'WordPress/' . get_bloginfo("version"), + 'Referer' => get_bloginfo("url") + ); + + $request_url = GRAVITY_MANAGER_URL . "/message.php?" . GFCommon::get_remote_request_params(); + $raw_response = wp_remote_request($request_url, $options); + + if ( is_wp_error( $raw_response ) || 200 != $raw_response['response']['code'] ) + $message = ""; + else + $message = $raw_response['body']; + + //validating that message is a valid Gravity Form message. If message is invalid, don't display anything + if(substr($message, 0, 10) != "") + $message = ""; + + update_option("rg_gforms_message", $message); + } + + public static function get_local_timestamp($timestamp = null){ + if($timestamp == null) + $timestamp = time(); + + return $timestamp + (get_option( 'gmt_offset' ) * 3600 ); + } + + public static function get_gmt_timestamp($local_timestamp){ + return $local_timestamp - (get_option( 'gmt_offset' ) * 3600 ); + } + + public static function format_date($gmt_datetime, $is_human = true, $date_format="", $include_time=true){ + if(empty($gmt_datetime)) + return ""; + + //adjusting date to local configured Time Zone + $lead_gmt_time = mysql2date("G", $gmt_datetime); + $lead_local_time = self::get_local_timestamp($lead_gmt_time); + + if(empty($date_format)) + $date_format = get_option('date_format'); + + if($is_human){ + $time_diff = time() - $lead_gmt_time; + + if ($time_diff > 0 && $time_diff < 24*60*60) + $date_display = sprintf(__('%s ago', 'gravityforms'), human_time_diff($lead_gmt_time)); + else + $date_display = $include_time ? sprintf(__('%1$s at %2$s', 'gravityforms'), date_i18n($date_format, $lead_local_time, true), date_i18n(get_option('time_format'), $lead_local_time, true)) : date_i18n($date_format, $lead_local_time, true); + } + else{ + $date_display = $include_time ? sprintf(__('%1$s at %2$s', 'gravityforms'), date_i18n($date_format, $lead_local_time, true), date_i18n(get_option('time_format'), $lead_local_time, true)) : date_i18n($date_format, $lead_local_time, true); + } + + return $date_display; + } + + public static function get_selection_value($value){ + $ary = explode("|", $value); + $val = $ary[0]; + return $val; + } + + public static function selection_display($value, $field, $currency="", $use_text=false){ + if (is_array($value)){ + return ""; + } + + $ary = explode("|", $value); + $val = $ary[0]; + $price = count($ary) > 1 ? $ary[1] : ""; + + if($use_text) + $val = RGFormsModel::get_choice_text($field, $val); + + if(!empty($price)) + return "$val (" . self::to_money($price, $currency) . ")"; + else + return $val; + } + + public static function date_display($value, $format = "mdy"){ + $date = self::parse_date($value, $format); + if(empty($date)) + return $value; + + list($position, $separator) = rgexplode("_", $format, 2); + switch($separator){ + case "dash" : + $separator = "-"; + break; + case "dot" : + $separator = "."; + break; + default : + $separator = "/"; + break; + } + + switch($position){ + case "ymd" : + return $date["year"] . $separator . $date["month"] . $separator . $date["day"]; + break; + + case "dmy" : + return $date["day"] . $separator . $date["month"] . $separator . $date["year"]; + break; + + default : + return $date["month"] . $separator . $date["day"] . $separator . $date["year"]; + break; + + } + } + + public static function parse_date($date, $format="mdy"){ + $date_info = array(); + + $position = substr($format, 0, 3); + + if(is_array($date)){ + + switch($position){ + case "mdy" : + $date_info["month"] = rgar($date, 0); + $date_info["day"] = rgar($date, 1); + $date_info["year"] = rgar($date, 2); + break; + + case "dmy" : + $date_info["day"] = rgar($date, 0); + $date_info["month"] = rgar($date, 1); + $date_info["year"] = rgar($date, 2); + break; + + case "ymd" : + $date_info["year"] = rgar($date, 0); + $date_info["month"] = rgar($date, 1); + $date_info["day"] = rgar($date, 2); + break; + } + return $date_info; + } + + $date = preg_replace("|[/\.]|", "-", $date); + if(preg_match('/^(\d{1,4})-(\d{1,2})-(\d{1,4})$/', $date, $matches)){ + + if(strlen($matches[1]) == 4){ + //format yyyy-mm-dd + $date_info["year"] = $matches[1]; + $date_info["month"] = $matches[2]; + $date_info["day"] = $matches[3]; + } + else if ($position == "mdy"){ + //format mm-dd-yyyy + $date_info["month"] = $matches[1]; + $date_info["day"] = $matches[2]; + $date_info["year"] = $matches[3]; + } + else{ + //format dd-mm-yyyy + $date_info["day"] = $matches[1]; + $date_info["month"] = $matches[2]; + $date_info["year"] = $matches[3]; + } + } + + return $date_info; + } + + + public static function truncate_url($url){ + $truncated_url = basename($url); + if(empty($truncated_url)) + $truncated_url = dirname($url); + + $ary = explode("?", $truncated_url); + + return $ary[0]; + } + + public static function get_tabindex(){ + return GFCommon::$tab_index > 0 ? "tabindex='" . GFCommon::$tab_index++ . "'" : ""; + } + + public static function get_checkbox_choices($field, $value, $disabled_text){ + $choices = ""; + + if(is_array($field["choices"])){ + $choice_number = 1; + $count = 1; + foreach($field["choices"] as $choice){ + if($choice_number % 10 == 0) //hack to skip numbers ending in 0. so that 5.1 doesn't conflict with 5.10 + $choice_number++; + + $input_id = $field["id"] . '.' . $choice_number; + $id = $field["id"] . '_' . $choice_number++; + + if(empty($_POST) && rgar($choice,"isSelected")){ + $checked = "checked='checked'"; + } + else if(is_array($value) && RGFormsModel::choice_value_match($field, $choice, rgget($input_id, $value))){ + $checked = "checked='checked'"; + } + else if(!is_array($value) && RGFormsModel::choice_value_match($field, $choice, $value)){ + $checked = "checked='checked'"; + } + else{ + $checked = ""; + } + + $logic_event = self::get_logic_event($field, "click"); + + $tabindex = self::get_tabindex(); + $choice_value = $choice["value"]; + if(rgget("enablePrice", $field)) + $choice_value .= "|" . GFCommon::to_number(rgar($choice,"price")); + + $choices.= sprintf("
  • ", $input_id, esc_attr($choice_value), $checked, $id, $disabled_text, $id, $id, $choice["text"]); + + if(IS_ADMIN && RG_CURRENT_VIEW != "entry" && $count >=5) + break; + + $count++; + } + + $total = sizeof($field["choices"]); + if($count < $total) + $choices .= "
  • " . sprintf(__("%d of %d items shown. Edit field to view all", "gravityforms"), $count, $total) . "
  • "; + } + + return apply_filters("gform_field_choices_" . rgget("formId", $field), apply_filters("gform_field_choices", $choices, $field), $field); + + } + + public static function get_radio_choices($field, $value="", $disabled_text){ + $choices = ""; + + if(is_array($field["choices"])){ + $choice_id = 0; + + // add "other" choice to choices if enabled + if(rgar($field, 'enableOtherChoice')) { + $other_default_value = GFCommon::get_other_choice_value(); + $field["choices"][] = array('text' => $other_default_value, 'value' => 'gf_other_choice', 'isSelected' => false, 'isOtherChoice' => true); + } + + $logic_event = self::get_logic_event($field, "click"); + $count = 1; + + foreach($field["choices"] as $choice){ + $id = $field["id"] . '_' . $choice_id++; + + $field_value = !empty($choice["value"]) || rgar($field, "enableChoiceValue") ? $choice["value"] : $choice["text"]; + + if(rgget("enablePrice", $field)) + $field_value .= "|" . GFCommon::to_number(rgar($choice,"price")); + + if(rgblank($value) && RG_CURRENT_VIEW != "entry"){ + $checked = rgar($choice,"isSelected") ? "checked='checked'" : ""; + } + else { + $checked = RGFormsModel::choice_value_match($field, $choice, $value) ? "checked='checked'" : ""; + } + + $tabindex = self::get_tabindex(); + $label = sprintf("", $id, $id, $choice["text"]); + $input_focus = ''; + + // handle "other" choice + if(rgar($choice, 'isOtherChoice')) { + + $onfocus = !IS_ADMIN ? 'jQuery(this).prev("input").attr("checked", true); if(jQuery(this).val() == "' . $other_default_value . '") { jQuery(this).val(""); }' : ''; + $onblur = !IS_ADMIN ? 'if(jQuery(this).val().replace(" ", "") == "") { jQuery(this).val("' . $other_default_value . '"); }' : ''; + $onkeyup = self::get_logic_event($field, "keyup"); + + $input_focus = !IS_ADMIN ? "onfocus=\"jQuery(this).next('input').focus();\"" : ""; + $value_exists = RGFormsModel::choices_value_match($field, $field["choices"], $value); + + if($value == 'gf_other_choice' && rgpost("input_{$field["id"]}_other")){ + $other_value = rgpost("input_{$field["id"]}_other"); + } else if(!$value_exists && !empty($value)){ + $other_value = $value; + $value = 'gf_other_choice'; + $checked = "checked='checked'"; + } else { + $other_value = $other_default_value; + } + $label = ""; + } + + $choices .= sprintf("
  • %s
  • ", $field["id"], esc_attr($field_value), $checked, $id, $disabled_text, $input_focus, $label); + + if(IS_ADMIN && RG_CURRENT_VIEW != "entry" && $count >=5) + break; + + $count++; + } + + $total = sizeof($field["choices"]); + if($count < $total) + $choices .= "
  • " . sprintf(__("%d of %d items shown. Edit field to view all", "gravityforms"), $count, $total) . "
  • "; + } + + return apply_filters("gform_field_choices_" . rgget("formId", $field), apply_filters("gform_field_choices", $choices, $field), $field); + } + + public static function get_field_type_title($type){ + switch($type){ + case "text" : + return __("Single Line Text", "gravityforms"); + case "textarea" : + return __("Paragraph Text", "gravityforms"); + case "select" : + return __("Drop Down", "gravityforms"); + case "multiselect" : + return __("Multi Select", "gravityforms"); + case "number" : + return __("Number", "gravityforms"); + case "checkbox" : + return __("Checkboxes", "gravityforms"); + case "radio" : + return __("Radio Buttons", "gravityforms"); + case "hidden" : + return __("Hidden", "gravityforms"); + case "html" : + return __("HTML", "gravityforms"); + case "section" : + return __("Section Break", "gravityforms"); + case "page" : + return __("Page Break", "gravityforms"); + case "name" : + return __("Name", "gravityforms"); + case "date" : + return __("Date", "gravityforms"); + case "time" : + return __("Time", "gravityforms"); + case "phone" : + return __("Phone", "gravityforms"); + case "address" : + return __("Address", "gravityforms"); + case "website" : + return __("Website", "gravityforms"); + case "email" : + return __("Email", "gravityforms"); + case "password" : + return __("Password", "gravityforms"); + case "fileupload" : + return __("File Upload", "gravityforms"); + case "captcha" : + return __("CAPTCHA", "gravityforms"); + case "list" : + return __("List", "gravityforms"); + case "creditcard" : + return __("Credit Card", "gravityforms"); + case "post_title" : + return __("Title", "gravityforms"); + case "post_content" : + return __("Body", "gravityforms"); + case "post_excerpt" : + return __("Excerpt", "gravityforms"); + case "post_tags" : + return __("Tags", "gravityforms"); + case "post_category" : + return __("Category", "gravityforms"); + case "post_image" : + return __("Image", "gravityforms"); + case "post_custom_field" : + return __("Custom Field", "gravityforms"); + case "product" : + return __("Product", "gravityforms"); + case "quantity" : + return __("Quantity", "gravityforms"); + case "option" : + return __("Option", "gravityforms"); + case "shipping" : + return __("Shipping", "gravityforms"); + case "total" : + return __("Total", "gravityforms"); + + default : + return apply_filters("gform_field_type_title", $type, $type); + } + } + + public static function get_select_choices($field, $value=""){ + $choices = ""; + + if(RG_CURRENT_VIEW == "entry" && empty($value)) + $choices .= ""; + + if(is_array(rgar($field, "choices"))){ + foreach($field["choices"] as $choice){ + + //needed for users upgrading from 1.0 + $field_value = !empty($choice["value"]) || rgget("enableChoiceValue", $field) || $field['type'] == 'post_category' ? $choice["value"] : $choice["text"]; + if(rgget("enablePrice", $field)) + $field_value .= "|" . GFCommon::to_number(rgar($choice,"price")); + + if(rgblank($value) && RG_CURRENT_VIEW != "entry"){ + $selected = rgar($choice,"isSelected") ? "selected='selected'" : ""; + } + else{ + if(is_array($value)){ + $is_match = false; + foreach($value as $item){ + if(RGFormsModel::choice_value_match($field, $choice, $item)){ + $is_match = true; + break; + } + } + $selected = $is_match ? "selected='selected'" : ""; + } + else{ + $selected = RGFormsModel::choice_value_match($field, $choice, $value) ? "selected='selected'" : ""; + } + } + + $choices.= sprintf("", esc_attr($field_value), $selected, esc_html($choice["text"])); + } + } + return $choices; + } + + public static function is_section_empty($section_field, $form, $lead){ + $cache_key = "GFCommon::is_section_empty_" . $form["id"] . "_" . $section_field["id"]; + + $value = GFCache::get($cache_key); + + if($value !== false) + return $value == true; + + $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')); + + if(!self::is_product_field($field["type"]) && !rgblank($val)){ + GFCache::set($cache_key, 0); + return false; + } + } + + GFCache::set($cache_key, 1); + + return true; + } + + public static function get_section_fields($form, $section_field_id){ + $fields = array(); + $in_section = false; + foreach($form["fields"] as $field){ + if(in_array($field["type"], array("section", "page")) && $in_section) + return $fields; + + if($field["id"] == $section_field_id) + $in_section = true; + + if($in_section) + $fields[] = $field; + } + + return $fields; + } + + + public static function get_countries(){ + return apply_filters("gform_countries", array( + __('Afghanistan', 'gravityforms'),__('Albania', 'gravityforms'),__('Algeria', 'gravityforms'), __('American Samoa', 'gravityforms'), __('Andorra', 'gravityforms'),__('Angola', 'gravityforms'),__('Antigua and Barbuda', 'gravityforms'),__('Argentina', 'gravityforms'),__('Armenia', 'gravityforms'),__('Australia', 'gravityforms'),__('Austria', 'gravityforms'),__('Azerbaijan', 'gravityforms'),__('Bahamas', 'gravityforms'),__('Bahrain', 'gravityforms'),__('Bangladesh', 'gravityforms'),__('Barbados', 'gravityforms'),__('Belarus', 'gravityforms'),__('Belgium', 'gravityforms'),__('Belize', 'gravityforms'),__('Benin', 'gravityforms'),__('Bermuda', 'gravityforms'),__('Bhutan', 'gravityforms'),__('Bolivia', 'gravityforms'),__('Bosnia and Herzegovina', 'gravityforms'),__('Botswana', 'gravityforms'),__('Brazil', 'gravityforms'),__('Brunei', 'gravityforms'),__('Bulgaria', 'gravityforms'),__('Burkina Faso', 'gravityforms'),__('Burundi', 'gravityforms'),__('Cambodia', 'gravityforms'),__('Cameroon', 'gravityforms'),__('Canada', 'gravityforms'),__('Cape Verde', 'gravityforms'),__('Cayman Islands', 'gravityforms'),__('Central African Republic', 'gravityforms'),__('Chad', 'gravityforms'),__('Chile', 'gravityforms'),__('China', 'gravityforms'),__('Colombia', 'gravityforms'),__('Comoros', 'gravityforms'),__('Congo, Democratic Republic of the', 'gravityforms'),__('Congo, Republic of the', 'gravityforms'),__('Costa Rica', 'gravityforms'),__('Côte d\'Ivoire', 'gravityforms'),__('Croatia', 'gravityforms'),__('Cuba', 'gravityforms'),__('Cyprus', 'gravityforms'),__('Czech Republic', 'gravityforms'),__('Denmark', 'gravityforms'),__('Djibouti', 'gravityforms'),__('Dominica', 'gravityforms'),__('Dominican Republic', 'gravityforms'),__('East Timor', 'gravityforms'),__('Ecuador', 'gravityforms'),__('Egypt', 'gravityforms'),__('El Salvador', 'gravityforms'),__('Equatorial Guinea', 'gravityforms'),__('Eritrea', 'gravityforms'),__('Estonia', 'gravityforms'),__('Ethiopia', 'gravityforms'),__('Fiji', 'gravityforms'),__('Finland', 'gravityforms'),__('France', 'gravityforms'), __('French Polynesia', 'gravityforms'), __('Gabon', 'gravityforms'), + __('Gambia', 'gravityforms'),__('Georgia', 'gravityforms'),__('Germany', 'gravityforms'),__('Ghana', 'gravityforms'),__('Greece', 'gravityforms'),__('Greenland', 'gravityforms'),__('Grenada', 'gravityforms'),__('Guam', 'gravityforms'),__('Guatemala', 'gravityforms'),__('Guinea', 'gravityforms'),__('Guinea-Bissau', 'gravityforms'),__('Guyana', 'gravityforms'),__('Haiti', 'gravityforms'),__('Honduras', 'gravityforms'),__('Hong Kong', 'gravityforms'),__('Hungary', 'gravityforms'),__('Iceland', 'gravityforms'),__('India', 'gravityforms'),__('Indonesia', 'gravityforms'),__('Iran', 'gravityforms'),__('Iraq', 'gravityforms'),__('Ireland', 'gravityforms'),__('Israel', 'gravityforms'),__('Italy', 'gravityforms'),__('Jamaica', 'gravityforms'),__('Japan', 'gravityforms'),__('Jordan', 'gravityforms'),__('Kazakhstan', 'gravityforms'),__('Kenya', 'gravityforms'),__('Kiribati', 'gravityforms'),__('North Korea', 'gravityforms'),__('South Korea', 'gravityforms'),__('Kosovo', 'gravityforms'),__('Kuwait', 'gravityforms'),__('Kyrgyzstan', 'gravityforms'),__('Laos', 'gravityforms'),__('Latvia', 'gravityforms'),__('Lebanon', 'gravityforms'),__('Lesotho', 'gravityforms'),__('Liberia', 'gravityforms'),__('Libya', 'gravityforms'),__('Liechtenstein', 'gravityforms'),__('Lithuania', 'gravityforms'),__('Luxembourg', 'gravityforms'),__('Macedonia', 'gravityforms'),__('Madagascar', 'gravityforms'),__('Malawi', 'gravityforms'),__('Malaysia', 'gravityforms'),__('Maldives', 'gravityforms'),__('Mali', 'gravityforms'),__('Malta', 'gravityforms'),__('Marshall Islands', 'gravityforms'),__('Mauritania', 'gravityforms'),__('Mauritius', 'gravityforms'),__('Mexico', 'gravityforms'),__('Micronesia', 'gravityforms'),__('Moldova', 'gravityforms'),__('Monaco', 'gravityforms'),__('Mongolia', 'gravityforms'),__('Montenegro', 'gravityforms'),__('Morocco', 'gravityforms'),__('Mozambique', 'gravityforms'),__('Myanmar', 'gravityforms'),__('Namibia', 'gravityforms'),__('Nauru', 'gravityforms'),__('Nepal', 'gravityforms'),__('Netherlands', 'gravityforms'),__('New Zealand', 'gravityforms'), + __('Nicaragua', 'gravityforms'),__('Niger', 'gravityforms'),__('Nigeria', 'gravityforms'),__('Norway', 'gravityforms'), __('Northern Mariana Islands', 'gravityforms'), __('Oman', 'gravityforms'),__('Pakistan', 'gravityforms'),__('Palau', 'gravityforms'),__('Palestine', 'gravityforms'),__('Panama', 'gravityforms'),__('Papua New Guinea', 'gravityforms'),__('Paraguay', 'gravityforms'),__('Peru', 'gravityforms'),__('Philippines', 'gravityforms'),__('Poland', 'gravityforms'),__('Portugal', 'gravityforms'),__('Puerto Rico', 'gravityforms'),__('Qatar', 'gravityforms'),__('Romania', 'gravityforms'),__('Russia', 'gravityforms'),__('Rwanda', 'gravityforms'),__('Saint Kitts and Nevis', 'gravityforms'),__('Saint Lucia', 'gravityforms'),__('Saint Vincent and the Grenadines', 'gravityforms'),__('Samoa', 'gravityforms'),__('San Marino', 'gravityforms'),__('Sao Tome and Principe', 'gravityforms'),__('Saudi Arabia', 'gravityforms'),__('Senegal', 'gravityforms'),__('Serbia and Montenegro', 'gravityforms'),__('Seychelles', 'gravityforms'),__('Sierra Leone', 'gravityforms'),__('Singapore', 'gravityforms'),__('Slovakia', 'gravityforms'),__('Slovenia', 'gravityforms'),__('Solomon Islands', 'gravityforms'),__('Somalia', 'gravityforms'),__('South Africa', 'gravityforms'),__('Spain', 'gravityforms'),__('Sri Lanka', 'gravityforms'),__('Sudan', 'gravityforms'),__('Sudan, South', 'gravityforms'),__('Suriname', 'gravityforms'),__('Swaziland', 'gravityforms'),__('Sweden', 'gravityforms'),__('Switzerland', 'gravityforms'),__('Syria', 'gravityforms'),__('Taiwan', 'gravityforms'),__('Tajikistan', 'gravityforms'),__('Tanzania', 'gravityforms'),__('Thailand', 'gravityforms'),__('Togo', 'gravityforms'),__('Tonga', 'gravityforms'),__('Trinidad and Tobago', 'gravityforms'),__('Tunisia', 'gravityforms'),__('Turkey', 'gravityforms'),__('Turkmenistan', 'gravityforms'),__('Tuvalu', 'gravityforms'),__('Uganda', 'gravityforms'),__('Ukraine', 'gravityforms'),__('United Arab Emirates', 'gravityforms'),__('United Kingdom', 'gravityforms'), + __('United States', 'gravityforms'),__('Uruguay', 'gravityforms'),__('Uzbekistan', 'gravityforms'),__('Vanuatu', 'gravityforms'),__('Vatican City', 'gravityforms'),__('Venezuela', 'gravityforms'),__('Vietnam', 'gravityforms'), __('Virgin Islands, British', 'gravityforms'), __('Virgin Islands, U.S.', 'gravityforms'),__('Yemen', 'gravityforms'),__('Zambia', 'gravityforms'),__('Zimbabwe', 'gravityforms'))); + + + } + + public static function get_country_code($country_name) { + $codes = array( + __('AFGHANISTAN', 'gravityforms') => "AF" , + __('ALBANIA', 'gravityforms') => "AL" , + __('ALGERIA', 'gravityforms') => "DZ" , + __('AMERICAN SAMOA', 'gravityforms') => "AS" , + __('ANDORRA', 'gravityforms') => "AD" , + __('ANGOLA', 'gravityforms') => "AO" , + __('ANTIGUA AND BARBUDA', 'gravityforms') => "AG" , + __('ARGENTINA', 'gravityforms') => "AR" , + __('ARMENIA', 'gravityforms') => "AM" , + __('AUSTRALIA', 'gravityforms') => "AU" , + __('AUSTRIA', 'gravityforms') => "AT" , + __('AZERBAIJAN', 'gravityforms') => "AZ" , + __('BAHAMAS', 'gravityforms') => "BS" , + __('BAHRAIN', 'gravityforms') => "BH" , + __('BANGLADESH', 'gravityforms') => "BD" , + __('BARBADOS', 'gravityforms') => "BB" , + __('BELARUS', 'gravityforms') => "BY" , + __('BELGIUM', 'gravityforms') => "BE" , + __('BELIZE', 'gravityforms') => "BZ" , + __('BENIN', 'gravityforms') => "BJ" , + __('BERMUDA', 'gravityforms') => "BM" , + __('BHUTAN', 'gravityforms') => "BT" , + __('BOLIVIA', 'gravityforms') => "BO" , + __('BOSNIA AND HERZEGOVINA', 'gravityforms') => "BA" , + __('BOTSWANA', 'gravityforms') => "BW" , + __('BRAZIL', 'gravityforms') => "BR" , + __('BRUNEI', 'gravityforms') => "BN" , + __('BULGARIA', 'gravityforms') => "BG" , + __('BURKINA FASO', 'gravityforms') => "BF" , + __('BURUNDI', 'gravityforms') => "BI" , + __('CAMBODIA', 'gravityforms') => "KH" , + __('CAMEROON', 'gravityforms') => "CM" , + __('CANADA', 'gravityforms') => "CA" , + __('CAPE VERDE', 'gravityforms') => "CV" , + __('CAYMAN ISLANDS', 'gravityforms') => "KY" , + __('CENTRAL AFRICAN REPUBLIC', 'gravityforms') => "CF" , + __('CHAD', 'gravityforms') => "TD" , + __('CHILE', 'gravityforms') => "CL" , + __('CHINA', 'gravityforms') => "CN" , + __('COLOMBIA', 'gravityforms') => "CO" , + __('COMOROS', 'gravityforms') => "KM" , + __('CONGO, DEMOCRATIC REPUBLIC OF THE', 'gravityforms') => "CD" , + __('CONGO, REPUBLIC OF THE', 'gravityforms') => "CG" , + __('COSTA RICA', 'gravityforms') => "CR" , + __('C&OCIRC;TE D\'IVOIRE', 'gravityforms') => "CI" , + __('CROATIA', 'gravityforms') => "HR" , + __('CUBA', 'gravityforms') => "CU" , + __('CYPRUS', 'gravityforms') => "CY" , + __('CZECH REPUBLIC', 'gravityforms') => "CZ" , + __('DENMARK', 'gravityforms') => "DK" , + __('DJIBOUTI', 'gravityforms') => "DJ" , + __('DOMINICA', 'gravityforms') => "DM" , + __('DOMINICAN REPUBLIC', 'gravityforms') => "DO" , + __('EAST TIMOR', 'gravityforms') => "TL" , + __('ECUADOR', 'gravityforms') => "EC" , + __('EGYPT', 'gravityforms') => "EG" , + __('EL SALVADOR', 'gravityforms') => "SV" , + __('EQUATORIAL GUINEA', 'gravityforms') => "GQ" , + __('ERITREA', 'gravityforms') => "ER" , + __('ESTONIA', 'gravityforms') => "EE" , + __('ETHIOPIA', 'gravityforms') => "ET" , + __('FIJI', 'gravityforms') => "FJ" , + __('FINLAND', 'gravityforms') => "FI" , + __('FRANCE', 'gravityforms') => "FR" , + __('GABON', 'gravityforms') => "GA" , + __('GAMBIA', 'gravityforms') => "GM" , + __('GEORGIA', 'gravityforms') => "GE" , + __('GERMANY', 'gravityforms') => "DE" , + __('GHANA', 'gravityforms') => "GH" , + __('GREECE', 'gravityforms') => "GR" , + __('GREENLAND', 'gravityforms') => "GL" , + __('GRENADA', 'gravityforms') => "GD" , + __('GUAM', 'gravityforms') => "GU" , + __('GUATEMALA', 'gravityforms') => "GT" , + __('GUINEA', 'gravityforms') => "GN" , + __('GUINEA-BISSAU', 'gravityforms') => "GW" , + __('GUYANA', 'gravityforms') => "GY" , + __('HAITI', 'gravityforms') => "HT" , + __('HONDURAS', 'gravityforms') => "HN" , + __('HONG KONG', 'gravityforms') => "HK" , + __('HUNGARY', 'gravityforms') => "HU" , + __('ICELAND', 'gravityforms') => "IS" , + __('INDIA', 'gravityforms') => "IN" , + __('INDONESIA', 'gravityforms') => "ID" , + __('IRAN', 'gravityforms') => "IR" , + __('IRAQ', 'gravityforms') => "IQ" , + __('IRELAND', 'gravityforms') => "IE" , + __('ISRAEL', 'gravityforms') => "IL" , + __('ITALY', 'gravityforms') => "IT" , + __('JAMAICA', 'gravityforms') => "JM" , + __('JAPAN', 'gravityforms') => "JP" , + __('JORDAN', 'gravityforms') => "JO" , + __('KAZAKHSTAN', 'gravityforms') => "KZ" , + __('KENYA', 'gravityforms') => "KE" , + __('KIRIBATI', 'gravityforms') => "KI" , + __('NORTH KOREA', 'gravityforms') => "KP" , + __('SOUTH KOREA', 'gravityforms') => "KR" , + __('KOSOVO', 'gravityforms') => "KV" , + __('KUWAIT', 'gravityforms') => "KW" , + __('KYRGYZSTAN', 'gravityforms') => "KG" , + __('LAOS', 'gravityforms') => "LA" , + __('LATVIA', 'gravityforms') => "LV" , + __('LEBANON', 'gravityforms') => "LB" , + __('LESOTHO', 'gravityforms') => "LS" , + __('LIBERIA', 'gravityforms') => "LR" , + __('LIBYA', 'gravityforms') => "LY" , + __('LIECHTENSTEIN', 'gravityforms') => "LI" , + __('LITHUANIA', 'gravityforms') => "LT" , + __('LUXEMBOURG', 'gravityforms') => "LU" , + __('MACEDONIA', 'gravityforms') => "MK" , + __('MADAGASCAR', 'gravityforms') => "MG" , + __('MALAWI', 'gravityforms') => "MW" , + __('MALAYSIA', 'gravityforms') => "MY" , + __('MALDIVES', 'gravityforms') => "MV" , + __('MALI', 'gravityforms') => "ML" , + __('MALTA', 'gravityforms') => "MT" , + __('MARSHALL ISLANDS', 'gravityforms') => "MH" , + __('MAURITANIA', 'gravityforms') => "MR" , + __('MAURITIUS', 'gravityforms') => "MU" , + __('MEXICO', 'gravityforms') => "MX" , + __('MICRONESIA', 'gravityforms') => "FM" , + __('MOLDOVA', 'gravityforms') => "MD" , + __('MONACO', 'gravityforms') => "MC" , + __('MONGOLIA', 'gravityforms') => "MN" , + __('MONTENEGRO', 'gravityforms') => "ME" , + __('MOROCCO', 'gravityforms') => "MA" , + __('MOZAMBIQUE', 'gravityforms') => "MZ" , + __('MYANMAR', 'gravityforms') => "MM" , + __('NAMIBIA', 'gravityforms') => "NA" , + __('NAURU', 'gravityforms') => "NR" , + __('NEPAL', 'gravityforms') => "NP" , + __('NETHERLANDS', 'gravityforms') => "NL" , + __('NEW ZEALAND', 'gravityforms') => "NZ" , + __('NICARAGUA', 'gravityforms') => "NI" , + __('NIGER', 'gravityforms') => "NE" , + __('NIGERIA', 'gravityforms') => "NG" , + __('NORTHERN MARIANA ISLANDS', 'gravityforms') => "MP" , + __('NORWAY', 'gravityforms') => "NO" , + __('OMAN', 'gravityforms') => "OM" , + __('PAKISTAN', 'gravityforms') => "PK" , + __('PALAU', 'gravityforms') => "PW" , + __('PALESTINE', 'gravityforms') => "PS" , + __('PANAMA', 'gravityforms') => "PA" , + __('PAPUA NEW GUINEA', 'gravityforms') => "PG" , + __('PARAGUAY', 'gravityforms') => "PY" , + __('PERU', 'gravityforms') => "PE" , + __('PHILIPPINES', 'gravityforms') => "PH" , + __('POLAND', 'gravityforms') => "PL" , + __('PORTUGAL', 'gravityforms') => "PT" , + __('PUERTO RICO', 'gravityforms') => "PR" , + __('QATAR', 'gravityforms') => "QA" , + __('ROMANIA', 'gravityforms') => "RO" , + __('RUSSIA', 'gravityforms') => "RU" , + __('RWANDA', 'gravityforms') => "RW" , + __('SAINT KITTS AND NEVIS', 'gravityforms') => "KN" , + __('SAINT LUCIA', 'gravityforms') => "LC" , + __('SAINT VINCENT AND THE GRENADINES', 'gravityforms') => "VC" , + __('SAMOA', 'gravityforms') => "WS" , + __('SAN MARINO', 'gravityforms') => "SM" , + __('SAO TOME AND PRINCIPE', 'gravityforms') => "ST" , + __('SAUDI ARABIA', 'gravityforms') => "SA" , + __('SENEGAL', 'gravityforms') => "SN" , + __('SERBIA AND MONTENEGRO', 'gravityforms') => "RS" , + __('SEYCHELLES', 'gravityforms') => "SC" , + __('SIERRA LEONE', 'gravityforms') => "SL" , + __('SINGAPORE', 'gravityforms') => "SG" , + __('SLOVAKIA', 'gravityforms') => "SK" , + __('SLOVENIA', 'gravityforms') => "SI" , + __('SOLOMON ISLANDS', 'gravityforms') => "SB" , + __('SOMALIA', 'gravityforms') => "SO" , + __('SOUTH AFRICA', 'gravityforms') => "ZA" , + __('SPAIN', 'gravityforms') => "ES" , + __('SRI LANKA', 'gravityforms') => "LK" , + __('SUDAN', 'gravityforms') => "SD" , + __('SUDAN, SOUTH', 'gravityforms') => "SS" , + __('SURINAME', 'gravityforms') => "SR" , + __('SWAZILAND', 'gravityforms') => "SZ" , + __('SWEDEN', 'gravityforms') => "SE" , + __('SWITZERLAND', 'gravityforms') => "CH" , + __('SYRIA', 'gravityforms') => "SY" , + __('TAIWAN', 'gravityforms') => "TW" , + __('TAJIKISTAN', 'gravityforms') => "TJ" , + __('TANZANIA', 'gravityforms') => "TZ" , + __('THAILAND', 'gravityforms') => "TH" , + __('TOGO', 'gravityforms') => "TG" , + __('TONGA', 'gravityforms') => "TO" , + __('TRINIDAD AND TOBAGO', 'gravityforms') => "TT" , + __('TUNISIA', 'gravityforms') => "TN" , + __('TURKEY', 'gravityforms') => "TR" , + __('TURKMENISTAN', 'gravityforms') => "TM" , + __('TUVALU', 'gravityforms') => "TV" , + __('UGANDA', 'gravityforms') => "UG" , + __('UKRAINE', 'gravityforms') => "UA" , + __('UNITED ARAB EMIRATES', 'gravityforms') => "AE" , + __('UNITED KINGDOM', 'gravityforms') => "GB" , + __('UNITED STATES', 'gravityforms') => "US" , + __('URUGUAY', 'gravityforms') => "UY" , + __('UZBEKISTAN', 'gravityforms') => "UZ" , + __('VANUATU', 'gravityforms') => "VU" , + __('VATICAN CITY', 'gravityforms') => "" , + __('VENEZUELA', 'gravityforms') => "VE" , + __('VIRGIN ISLANDS, BRITISH', 'gravityforms') => "VG" , + __('VIRGIN ISLANDS, U.S.', 'gravityforms') => "VI" , + __('VIETNAM', 'gravityforms') => "VN" , + __('YEMEN', 'gravityforms') => "YE" , + __('ZAMBIA', 'gravityforms') => "ZM" , + __('ZIMBABWE', 'gravityforms') => "ZW" ); + + return rgar($codes, strtoupper($country_name)); + } + + public static function get_us_states(){ + return apply_filters("gform_us_states", array( + __("Alabama","gravityforms"),__("Alaska","gravityforms"),__("Arizona","gravityforms"),__("Arkansas","gravityforms"), + __("California","gravityforms"),__("Colorado","gravityforms"),__("Connecticut","gravityforms"),__("Delaware","gravityforms"), + __("District of Columbia", "gravityforms"), __("Florida","gravityforms"),__("Georgia","gravityforms"), + __("Hawaii","gravityforms"),__("Idaho","gravityforms"),__("Illinois","gravityforms"),__("Indiana","gravityforms"), + __("Iowa","gravityforms"),__("Kansas","gravityforms"),__("Kentucky","gravityforms"),__("Louisiana","gravityforms"), + __("Maine","gravityforms"),__("Maryland","gravityforms"),__("Massachusetts","gravityforms"),__("Michigan","gravityforms"), + __("Minnesota","gravityforms"),__("Mississippi","gravityforms"),__("Missouri","gravityforms"),__("Montana","gravityforms"), + __("Nebraska","gravityforms"),__("Nevada","gravityforms"),__("New Hampshire","gravityforms"),__("New Jersey","gravityforms"), + __("New Mexico","gravityforms"),__("New York","gravityforms"),__("North Carolina","gravityforms"), + __("North Dakota","gravityforms"),__("Ohio","gravityforms"),__("Oklahoma","gravityforms"),__("Oregon","gravityforms"), + __("Pennsylvania","gravityforms"),__("Rhode Island","gravityforms"),__("South Carolina","gravityforms"), + __("South Dakota","gravityforms"),__("Tennessee","gravityforms"),__("Texas","gravityforms"),__("Utah","gravityforms"), + __("Vermont","gravityforms"),__("Virginia","gravityforms"),__("Washington","gravityforms"),__("West Virginia","gravityforms"), + __("Wisconsin","gravityforms"),__("Wyoming","gravityforms"), __("Armed Forces Americas","gravityforms"), + __("Armed Forces Europe","gravityforms"),__("Armed Forces Pacific","gravityforms")) + ); + } + + public static function get_us_state_code($state_name){ + $states = array( + strtoupper(__("Alabama","gravityforms")) => "AL", + strtoupper(__("Alaska","gravityforms")) => "AK", + strtoupper(__("Arizona","gravityforms")) => "AZ", + strtoupper(__("Arkansas","gravityforms")) => "AR", + strtoupper(__("California","gravityforms")) => "CA", + strtoupper(__("Colorado","gravityforms")) => "CO", + strtoupper(__("Connecticut","gravityforms")) => "CT", + strtoupper(__("Delaware","gravityforms")) => "DE", + strtoupper(__("District of Columbia", "gravityforms")) => "DC", + strtoupper(__("Florida","gravityforms")) => "FL", + strtoupper(__("Georgia","gravityforms")) => "GA", + strtoupper(__("Hawaii","gravityforms")) => "HI", + strtoupper(__("Idaho","gravityforms")) => "ID", + strtoupper(__("Illinois","gravityforms")) => "IL", + strtoupper(__("Indiana","gravityforms")) => "IN", + strtoupper(__("Iowa","gravityforms")) => "IA", + strtoupper(__("Kansas","gravityforms")) => "KS", + strtoupper(__("Kentucky","gravityforms")) => "KY", + strtoupper(__("Louisiana","gravityforms")) => "LA", + strtoupper(__("Maine","gravityforms")) => "ME", + strtoupper(__("Maryland","gravityforms")) => "MD", + strtoupper(__("Massachusetts","gravityforms")) => "MA", + strtoupper(__("Michigan","gravityforms")) => "MI", + strtoupper(__("Minnesota","gravityforms")) => "MN", + strtoupper(__("Mississippi","gravityforms")) => "MS", + strtoupper(__("Missouri","gravityforms")) => "MO", + strtoupper(__("Montana","gravityforms")) => "MT", + strtoupper(__("Nebraska","gravityforms")) => "NE", + strtoupper(__("Nevada","gravityforms")) => "NV", + strtoupper(__("New Hampshire","gravityforms")) => "NH", + strtoupper(__("New Jersey","gravityforms")) => "NJ", + strtoupper(__("New Mexico","gravityforms")) => "NM", + strtoupper(__("New York","gravityforms")) => "NY", + strtoupper(__("North Carolina","gravityforms")) => "NC", + strtoupper(__("North Dakota","gravityforms")) => "ND", + strtoupper(__("Ohio","gravityforms")) => "OH", + strtoupper(__("Oklahoma","gravityforms")) => "OK", + strtoupper(__("Oregon","gravityforms")) => "OR", + strtoupper(__("Pennsylvania","gravityforms")) => "PA", + strtoupper(__("Rhode Island","gravityforms")) => "RI", + strtoupper(__("South Carolina","gravityforms")) => "SC", + strtoupper(__("South Dakota","gravityforms")) => "SD", + strtoupper(__("Tennessee","gravityforms")) => "TN", + strtoupper(__("Texas","gravityforms")) => "TX", + strtoupper(__("Utah","gravityforms")) => "UT", + strtoupper(__("Vermont","gravityforms")) => "VT", + strtoupper(__("Virginia","gravityforms")) => "VA", + strtoupper(__("Washington","gravityforms")) => "WA", + strtoupper(__("West Virginia","gravityforms")) => "WV", + strtoupper(__("Wisconsin","gravityforms")) => "WI", + strtoupper(__("Wyoming","gravityforms")) => "WY", + strtoupper(__("Armed Forces Americas","gravityforms")) => "AA", + strtoupper(__("Armed Forces Europe","gravityforms")) => "AE", + strtoupper(__("Armed Forces Pacific","gravityforms")) => "AP" + ); + + $code = isset($states[strtoupper($state_name)]) ? $states[strtoupper($state_name)] : strtoupper($state_name); + + return $code; + } + + + public static function get_canadian_provinces(){ + return array(__("Alberta","gravityforms"),__("British Columbia","gravityforms"),__("Manitoba","gravityforms"),__("New Brunswick","gravityforms"),__("Newfoundland & Labrador","gravityforms"),__("Northwest Territories","gravityforms"),__("Nova Scotia","gravityforms"),__("Nunavut","gravityforms"),__("Ontario","gravityforms"),__("Prince Edward Island","gravityforms"),__("Quebec","gravityforms"),__("Saskatchewan","gravityforms"),__("Yukon","gravityforms")); + + } + + public static function get_state_dropdown($states, $selected_state=""){ + $str = ""; + foreach($states as $code => $state){ + if(is_numeric($code)) + $code = $state; + + $selected = $code == $selected_state ? "selected='selected'" : ""; + $str .= ""; + } + return $str; + } + + public static function get_us_state_dropdown($selected_state = ""){ + $states = array_merge(array(''), self::get_us_states()); + foreach($states as $code => $state){ + if(is_numeric($code)) + $code = $state; + + $selected = $code == $selected_state ? "selected='selected'" : ""; + $str .= ""; + } + return $str; + } + + public static function get_canadian_provinces_dropdown($selected_province = ""){ + $states = array_merge(array(''), self::get_canadian_provinces()); + foreach($states as $state){ + $selected = $state == $selected_province ? "selected='selected'" : ""; + $str .= ""; + } + return $str; + } + + public static function get_country_dropdown($selected_country = ""){ + $str = ""; + $countries = array_merge(array(''), self::get_countries()); + foreach($countries as $code => $country){ + if(is_numeric($code)) + $code = $country; + + $selected = $code == $selected_country ? "selected='selected'" : ""; + $str .= ""; + } + return $str; + } + + public static function is_post_field($field){ + return in_array($field["type"], array("post_title", "post_tags", "post_category", "post_custom_field", "post_content", "post_excerpt", "post_image")); + } + + public static function get_range_message($field){ + $min = $field["rangeMin"]; + $max = $field["rangeMax"]; + $message = ""; + + if(is_numeric($min) && is_numeric($max)) + $message = sprintf(__("Please enter a value between %s and %s.", "gravityforms"), "$min", "$max") ; + else if(is_numeric($min)) + $message = sprintf(__("Please enter a value greater than or equal to %s.", "gravityforms"), "$min"); + else if(is_numeric($max)) + $message = sprintf(__("Please enter a value less than or equal to %s.", "gravityforms"), "$max"); + else if($field["failed_validation"]) + $message = __("Please enter a valid number", "gravityforms"); + + return $message; + } + + public static function get_fields_by_type($form, $types){ + $fields = array(); + if(!is_array(rgar($form,"fields"))) + return $fields; + + foreach($form["fields"] as $field){ + if(in_array(rgar($field,"type"), $types)) + $fields[] = $field; + } + return $fields; + } + + public static function has_pages($form){ + return sizeof(self::get_fields_by_type($form, array("page"))) > 0; + } + + public static function get_product_fields_by_type($form, $types, $product_id){ + global $_product_fields; + $key = json_encode($types) . "_" . $product_id . "_" . $form["id"]; + if(!isset($_product_fields[$key])){ + $fields = array(); + for($i=0, $count=sizeof($form["fields"]); $i<$count; $i++){ + $field = $form["fields"][$i]; + if(in_array($field["type"], $types) && $field["productField"] == $product_id){ + $fields[] = $field; + } + } + $_product_fields[$key] = $fields; + } + return $_product_fields[$key]; + } + + private static function get_month_dropdown($name="", $id="", $selected_value="", $tabindex="", $disabled_text=""){ + return self::get_number_dropdown($name, $id, $selected_value, $tabindex, $disabled_text, __("Month", "gravityforms"), 1, 12); + } + + private static function get_day_dropdown($name="", $id="", $selected_value="", $tabindex="", $disabled_text=""){ + return self::get_number_dropdown($name, $id, $selected_value, $tabindex, $disabled_text, __("Day", "gravityforms"), 1, 31); + } + + private static function get_year_dropdown($name="", $id="", $selected_value="", $tabindex="", $disabled_text=""){ + $year_min = apply_filters("gform_date_min_year", "1920"); + $year_max = apply_filters("gform_date_max_year", date("Y") + 1); + return self::get_number_dropdown($name, $id, $selected_value, $tabindex, $disabled_text, __("Year", "gravityforms"), $year_max, $year_min); + } + + private static function get_number_dropdown($name, $id, $selected_value, $tabindex, $disabled_text, $placeholder, $start_number, $end_number){ + $str = ""; + return $str; + } + + private static function get_logic_event($field, $event){ + if(empty($field["conditionalLogicFields"]) || IS_ADMIN) + return ""; + + switch($event){ + case "keyup" : + return "onchange='gf_apply_rules(" . $field["formId"] . "," . GFCommon::json_encode($field["conditionalLogicFields"]) . ");' onkeyup='clearTimeout(__gf_timeout_handle); __gf_timeout_handle = setTimeout(\"gf_apply_rules(" . $field["formId"] . "," . GFCommon::json_encode($field["conditionalLogicFields"]) . ")\", 300);'"; + break; + + case "click" : + return "onclick='gf_apply_rules(" . $field["formId"] . "," . GFCommon::json_encode($field["conditionalLogicFields"]) . ");'"; + break; + + case "change" : + return "onchange='gf_apply_rules(" . $field["formId"] . "," . GFCommon::json_encode($field["conditionalLogicFields"]) . ");'"; + break; + } + } + + public static function has_field_calculation($field) { + + if($field['type'] == 'number') { + return rgar($field, 'enableCalculation') && rgar($field, 'calculationFormula'); + } + + return RGFormsModel::get_input_type($field) == 'calculation'; + } + + public static function get_field_input($field, $value="", $lead_id=0, $form_id=0){ + + $id = $field["id"]; + $field_id = IS_ADMIN || $form_id == 0 ? "input_$id" : "input_" . $form_id . "_$id"; + $form_id = IS_ADMIN && empty($form_id) ? rgget("id") : $form_id; + + $size = rgar($field, "size"); + $disabled_text = (IS_ADMIN && RG_CURRENT_VIEW != "entry") ? "disabled='disabled'" : ""; + $class_suffix = RG_CURRENT_VIEW == "entry" ? "_admin" : ""; + $class = $size . $class_suffix; + + $currency = ""; + if(RG_CURRENT_VIEW == "entry"){ + $lead = RGFormsModel::get_lead($lead_id); + $post_id = $lead["post_id"]; + $post_link = ""; + if(is_numeric($post_id) && self::is_post_field($field)){ + $post_link = "You can edit this post from the post page."; + } + $currency = $lead["currency"]; + } + + $field_input = apply_filters("gform_field_input", "", $field, $value, $lead_id, $form_id); + if($field_input) + return $field_input; + + //product fields are not editable + if(RG_CURRENT_VIEW == "entry" && self::is_product_field($field["type"])) + return "
    " . __("Product fields are not editable", "gravityforms") . "
    "; + + else if(RG_CURRENT_VIEW == "entry" && $field["type"] == "donation") + return "
    " . __("Donations are not editable", "gravityforms") . "
    "; + + // add categories as choices for Post Category field + if($field['type'] == 'post_category'){ + $field = self::add_categories_as_choices($field, $value); + } + + $max_length = ""; + $html5_attributes = ""; + + switch(RGFormsModel::get_input_type($field)){ + + case "total" : + if(RG_CURRENT_VIEW == "entry") + return "
    "; + else + return "
    " . self::to_money("0") . "
    "; + break; + + case "calculation" : + case "singleproduct" : + + $product_name = !is_array($value) || empty($value[$field["id"] . ".1"]) ? esc_attr($field["label"]) : esc_attr($value[$field["id"] . ".1"]); + $price = !is_array($value) || empty($value[$field["id"] . ".2"]) ? rgget("basePrice", $field) : esc_attr($value[$field["id"] . ".2"]); + $quantity = is_array($value) ? esc_attr($value[$field["id"] . ".3"]) : ""; + + if(empty($price)) + $price = 0; + + $form = RGFormsModel::get_form_meta($form_id); + $has_quantity = sizeof(GFCommon::get_product_fields_by_type($form, array("quantity"), $field["id"])) > 0; + if($has_quantity) + $field["disableQuantity"] = true; + + $quantity_field = ""; + + $qty_input_type = GFFormsModel::is_html5_enabled() ? "number" : "text"; + + if(IS_ADMIN){ + $style = rgget("disableQuantity", $field) ? "style='display:none;'" : ""; + $quantity_field = " " . apply_filters("gform_product_quantity_{$form_id}",apply_filters("gform_product_quantity",__("Quantity:", "gravityforms"), $form_id), $form_id) . " "; + } + else if(!rgget("disableQuantity", $field)){ + $tabindex = self::get_tabindex(); + $quantity_field .= " " . apply_filters("gform_product_quantity_{$form_id}",apply_filters("gform_product_quantity",__("Quantity:", "gravityforms"), $form_id), $form_id) . " "; + } + else{ + if(!is_numeric($quantity)) + $quantity = 1; + + if(!$has_quantity){ + $quantity_field .= ""; + } + } + + return "
    " . apply_filters("gform_product_price_{$form_id}", apply_filters("gform_product_price",__("Price", "gravityforms"), $form_id), $form_id) . ": " . esc_html(GFCommon::to_money($price, $currency)) ."{$quantity_field}
    "; + + break; + + case "hiddenproduct" : + + $form = RGFormsModel::get_form_meta($form_id); + $has_quantity_field = sizeof(GFCommon::get_product_fields_by_type($form, array("quantity"), $field["id"])) > 0; + + $product_name = !is_array($value) || empty($value[$field["id"] . ".1"]) ? esc_attr($field["label"]) : esc_attr($value[$field["id"] . ".1"]); + $quantity = is_array($value) ? esc_attr($value[$field["id"] . ".3"]) : "1"; + $price = !is_array($value) || empty($value[$field["id"] . ".2"]) ? rgget("basePrice", $field) : esc_attr($value[$field["id"] . ".2"]); + if(empty($price)) + $price = 0; + + $quantity_field = $has_quantity_field ? "" : ""; + $product_name_field = ""; + + $field_type = IS_ADMIN ? "text" : "hidden"; + + return $quantity_field . $product_name_field . sprintf("", $id, esc_attr($price), $disabled_text); + + break; + + case "singleshipping" : + + $price = !empty($value) ? $value : rgget("basePrice", $field); + if(empty($price)) + $price = 0; + + return "
    " . GFCommon::to_money($price, $currency) ."
    "; + + break; + + case "website": + $is_html5 = RGFormsModel::is_html5_enabled(); + $value = empty($value) && !$is_html5 ? "http://" : $value; + $html_input_type = $is_html5 ? "url" : "text"; + $html5_attributes = $is_html5 ? "placeholder='http://'" : ""; + case "text": + if(empty($html_input_type)) + $html_input_type = "text"; + + if(rgget("enablePasswordInput", $field) && RG_CURRENT_VIEW != "entry") + $html_input_type = "password"; + + if(is_numeric(rgget("maxLength", $field))) + $max_length = "maxlength='{$field["maxLength"]}'"; + + if(!empty($post_link)) + return $post_link; + + $logic_event = self::get_logic_event($field, "keyup"); + + $tabindex = self::get_tabindex(); + return sprintf("
    ", $id, $field_id, $html_input_type, esc_attr($value), esc_attr($class), $disabled_text); + break; + + case "email": + + if(!empty($post_link)) + return $post_link; + + $html_input_type = RGFormsModel::is_html5_enabled() ? "email" : "text"; + + if(IS_ADMIN && RG_CURRENT_VIEW != "entry"){ + $single_style = rgget("emailConfirmEnabled", $field) ? "style='display:none;'" : ""; + $confirm_style = rgget("emailConfirmEnabled", $field) ? "" : "style='display:none;'"; + return "
    "; + } + else{ + $logic_event = self::get_logic_event($field, "keyup"); + + if(rgget("emailConfirmEnabled", $field) && RG_CURRENT_VIEW != "entry"){ + $first_tabindex = self::get_tabindex(); + $last_tabindex = self::get_tabindex(); + return "
    "; + } + else{ + $tabindex = self::get_tabindex(); + return sprintf("
    ", $id, $field_id, $html_input_type, esc_attr($value), esc_attr($class), $disabled_text); + } + } + + break; + case "honeypot": + $autocomplete = RGFormsModel::is_html5_enabled() ? "autocomplete='off'" : ""; + return "
    "; + break; + + case "hidden" : + if(!empty($post_link)) + return $post_link; + + $field_type = IS_ADMIN ? "text" : "hidden"; + $class_attribute = IS_ADMIN ? "" : "class='gform_hidden'"; + + return sprintf("", $id, $field_id, esc_attr($value), $disabled_text); + break; + + case "html" : + $content = IS_ADMIN ? "
    " . __("HTML Content", "gravityforms") . "" . __("This is a content placeholder. HTML content is not displayed in the form admin. Preview this form to view the content.", "gravityforms") . "
    " : $field["content"]; + $content = GFCommon::replace_variables_prepopulate($content); //adding support for merge tags + $content = do_shortcode($content); //adding support for shortcodes + return $content; + break; + + case "adminonly_hidden" : + if(!is_array($field["inputs"])){ + if(is_array($value)) + $value = json_encode($value); + return sprintf("", $id, $field_id, esc_attr($value)); + } + + + $fields = ""; + foreach($field["inputs"] as $input){ + $fields .= sprintf("", $input["id"], esc_attr(rgar($value, strval($input["id"])))); + } + return $fields; + break; + + case "number" : + if(!empty($post_link)) + return $post_link; + + $instruction = ""; + $read_only = ""; + + if(!IS_ADMIN){ + + if(GFCommon::has_field_calculation($field)) { + + // calculation-enabled fields should be read only + $read_only = 'readonly="readonly"'; + + } else { + + $message = self::get_range_message($field); + $validation_class = $field["failed_validation"] ? "validation_message" : ""; + + if(!$field["failed_validation"] && !empty($message) && empty($field["errorMessage"])) + $instruction = "
    " . $message . "
    "; + + } + + } + else if( RG_CURRENT_VIEW == "entry" ){ + $value = GFCommon::format_number($value, rgar($field, "numberFormat")); + } + + $is_html5 = RGFormsModel::is_html5_enabled(); + $html_input_type = $is_html5 && !GFCommon::has_field_calculation($field) && ($field["numberFormat"] != "currency" && $field["numberFormat"] != "decimal_comma" ) ? "number" : "text"; // chrome does not allow number fields to have commas, calculations and currency values display numbers with commas + $step_attr = $is_html5 ? "step='any'" : ""; + + $logic_event = self::get_logic_event($field, "keyup"); + + $value = GFCommon::format_number($value, $field["numberFormat"]); + + $tabindex = self::get_tabindex(); + return sprintf("
    %s
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text, $instruction); + + case "donation" : + $tabindex = self::get_tabindex(); + return sprintf("
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text); + + case "price" : + $logic_event = self::get_logic_event($field, "keyup"); + + $tabindex = self::get_tabindex(); + return sprintf("
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text); + + case "phone" : + if(!empty($post_link)) + return $post_link; + + $instruction = $field["phoneFormat"] == "standard" ? __("Phone format:", "gravityforms") . " (###)###-####" : ""; + $instruction_div = rgget("failed_validation", $field) && !empty($instruction) ? "
    $instruction
    " : ""; + $html_input_type = RGFormsModel::is_html5_enabled() ? "tel" : "text"; + $logic_event = self::get_logic_event($field, "keyup"); + + $tabindex = self::get_tabindex(); + return sprintf("
    {$instruction_div}
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text); + + case "textarea": + $max_chars = ""; + $logic_event = self::get_logic_event($field, "keyup"); + + $tabindex = self::get_tabindex(); + return sprintf("
    {$max_chars}", $id, $field_id, esc_attr($class), $disabled_text, esc_html($value)); + + case "post_title": + case "post_tags": + case "post_custom_field": + $tabindex = self::get_tabindex(); + $logic_event = self::get_logic_event($field, "keyup"); + + return !empty($post_link) ? $post_link : sprintf("
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text); + break; + + case "post_content": + case "post_excerpt": + $max_chars = ""; + $logic_event = self::get_logic_event($field, "keyup"); + + $tabindex = self::get_tabindex(); + return !empty($post_link) ? $post_link : sprintf("
    {$max_chars}", $id, $field_id, esc_attr($class), $disabled_text, esc_html($value)); + break; + + case "post_category" : + if(!empty($post_link)) + return $post_link; + + if(rgget("displayAllCategories", $field) && !IS_ADMIN){ + $default_category = rgget("categoryInitialItemEnabled", $field) ? "-1" : get_option('default_category'); + $selected = empty($value) ? $default_category : $value; + $args = array('echo' => 0, 'selected' => $selected, "class" => esc_attr($class) . " gfield_select", 'hide_empty' => 0, 'name' => "input_$id", 'orderby' => 'name', 'hierarchical' => true ); + if(self::$tab_index > 0) + $args["tab_index"] = self::$tab_index++; + + if(rgget("categoryInitialItemEnabled", $field)){ + $args["show_option_none"] = empty($field["categoryInitialItem"]) ? " " : $field["categoryInitialItem"]; + } + + $args = apply_filters("gform_post_category_args_{$field["id"]}", apply_filters("gform_post_category_args", $args, $field), $field); + + return "
    " . wp_dropdown_categories($args) . "
    "; + } + else{ + $tabindex = self::get_tabindex(); + if(is_array(rgar($field, "choices"))) + usort($field["choices"], create_function('$a,$b', 'return strcmp($a["text"], $b["text"]);')); + + $choices = self::get_select_choices($field, $value); + + //Adding first option + if(rgget("categoryInitialItemEnabled", $field)){ + $selected = empty($value) ? "selected='selected'" : ""; + $choices = "" . $choices; + } + + return sprintf("
    ", $id, $field_id, esc_attr($class), $disabled_text, $choices); + } + break; + + case "post_image" : + if(!empty($post_link)) + return $post_link; + + $title = esc_attr(rgget($field["id"] . ".1", $value)); + $caption = esc_attr(rgget($field["id"] . ".4", $value)); + $description = esc_attr(rgget($field["id"] . ".7", $value)); + + //hidding meta fields for admin + $hidden_style = "style='display:none;'"; + $title_style = !rgget("displayTitle", $field) && IS_ADMIN ? $hidden_style : ""; + $caption_style = !rgget("displayCaption", $field) && IS_ADMIN ? $hidden_style : ""; + $description_style = !rgget("displayDescription", $field) && IS_ADMIN ? $hidden_style : ""; + $file_label_style = IS_ADMIN && !(rgget("displayTitle", $field) || rgget("displayCaption", $field) || rgget("displayDescription", $field)) ? $hidden_style : ""; + + $hidden_class = $preview = ""; + $file_info = RGFormsModel::get_temp_filename($form_id, "input_{$id}"); + if($file_info){ + $hidden_class = " gform_hidden"; + $file_label_style = $hidden_style; + $preview = "" . esc_html($file_info["uploaded_filename"]) . " | " . __("delete", "gravityforms") . ""; + } + + //in admin, render all meta fields to allow for immediate feedback, but hide the ones not selected + $file_label = (IS_ADMIN || rgget("displayTitle", $field) || rgget("displayCaption", $field) || rgget("displayDescription", $field)) ? "" : ""; + + $tabindex = self::get_tabindex(); + $upload = sprintf("{$preview}$file_label", $id, $field_id, esc_attr($value), esc_attr($class . $hidden_class), $disabled_text); + + $tabindex = self::get_tabindex(); + $title_field = rgget("displayTitle", $field) || IS_ADMIN ? sprintf("", $id, $field_id, $title, $disabled_text, $field_id) : ""; + + $tabindex = self::get_tabindex(); + $caption_field = rgget("displayCaption", $field) || IS_ADMIN ? sprintf("", $id, $field_id, $caption, $disabled_text, $field_id) : ""; + + $tabindex = self::get_tabindex(); + $description_field = rgget("displayDescription", $field) || IS_ADMIN? sprintf("", $id, $field_id, $description, $disabled_text, $field_id) : ""; + + return "
    " . $upload . $title_field . $caption_field . $description_field . "
    "; + + break; + + case "multiselect" : + if(!empty($post_link)) + return $post_link; + + $placeholder = rgar($field, "enableEnhancedUI") ? "data-placeholder='" . esc_attr(apply_filters("gform_multiselect_placeholder_{$form_id}", apply_filters("gform_multiselect_placeholder", __("Click to select...", "gravityforms"), $form_id), $form_id)) . "'" : ""; + $logic_event = self::get_logic_event($field, "keyup"); + $css_class = trim(esc_attr($class) . " gfield_select"); + $size = rgar($field, "multiSelectSize"); + if(empty($size)) + $size = 7; + + $tabindex = self::get_tabindex(); + return sprintf("
    ", $id, $field_id, $css_class, $disabled_text, self::get_select_choices($field, $value)); + + break; + + case "select" : + if(!empty($post_link)) + return $post_link; + + $logic_event = self::get_logic_event($field, "change"); + $css_class = trim(esc_attr($class) . " gfield_select"); + $tabindex = self::get_tabindex(); + return sprintf("
    ", $id, $field_id, $css_class, $disabled_text, self::get_select_choices($field, $value)); + + case "checkbox" : + if(!empty($post_link)) + return $post_link; + + return sprintf("
    ", $field_id, self::get_checkbox_choices($field, $value, $disabled_text)); + + case "radio" : + if(!empty($post_link)) + return $post_link; + + return sprintf("
    ", $field_id, self::get_radio_choices($field, $value, $disabled_text)); + + case "password" : + + $first_tabindex = self::get_tabindex(); + $last_tabindex = self::get_tabindex(); + + $strength_style = !rgar($field,"passwordStrengthEnabled") ? "style='display:none;'" : ""; + $strength = rgar($field,"passwordStrengthEnabled") || IS_ADMIN ? "
    " . __("Strength indicator", "gravityforms") . "
    " : ""; + + $action = !IS_ADMIN ? "gformShowPasswordStrength(\"$field_id\");" : ""; + $onchange= rgar($field,"passwordStrengthEnabled") ? "onchange='{$action}'" : ""; + $onkeyup = rgar($field,"passwordStrengthEnabled") ? "onkeyup='{$action}'" : ""; + + $pass = RGForms::post("input_" . $id ."_2"); + return sprintf("
    {$strength}", $id, $field_id, esc_attr($value), $disabled_text, $field_id, $id, $field_id, esc_attr($pass), $disabled_text, $field_id); + + case "name" : + $prefix = ""; + $first = ""; + $last = ""; + $suffix = ""; + if(is_array($value)){ + $prefix = esc_attr(RGForms::get($field["id"] . ".2", $value)); + $first = esc_attr(RGForms::get($field["id"] . ".3", $value)); + $last = esc_attr(RGForms::get($field["id"] . ".6", $value)); + $suffix = esc_attr(RGForms::get($field["id"] . ".8", $value)); + } + switch(rgget("nameFormat", $field)){ + + case "extended" : + $prefix_tabindex = self::get_tabindex(); + $first_tabindex = self::get_tabindex(); + $last_tabindex = self::get_tabindex(); + $suffix_tabindex = self::get_tabindex(); + return sprintf("
    ", $id, $field_id, $prefix, $disabled_text, $field_id, $id, $field_id, $first, $disabled_text, $field_id, $id, $field_id, $last, $disabled_text, $field_id, $id, $field_id, $suffix, $disabled_text, $field_id); + + case "simple" : + $tabindex = self::get_tabindex(); + return sprintf("
    ", $id, $field_id, esc_attr($value), esc_attr($class), $disabled_text); + + default : + $first_tabindex = self::get_tabindex(); + $last_tabindex = self::get_tabindex(); + return sprintf("
    ", $id, $field_id, $first, $disabled_text, $field_id, $id, $field_id, $last, $disabled_text, $field_id); + } + + case "address" : + $street_value =""; + $street2_value =""; + $city_value =""; + $state_value =""; + $zip_value =""; + $country_value =""; + + if(is_array($value)){ + $street_value = esc_attr(rgget($field["id"] . ".1",$value)); + $street2_value = esc_attr(rgget($field["id"] . ".2",$value)); + $city_value = esc_attr(rgget($field["id"] . ".3",$value)); + $state_value = esc_attr(rgget($field["id"] . ".4",$value)); + $zip_value = esc_attr(rgget($field["id"] . ".5",$value)); + $country_value = esc_attr(rgget($field["id"] . ".6",$value)); + } + + $address_types = self::get_address_types($form_id); + $addr_type = empty($field["addressType"]) ? "international" : $field["addressType"]; + $address_type = $address_types[$addr_type]; + + $state_label = empty($address_type["state_label"]) ? __("State", "gravityforms") : $address_type["state_label"]; + $zip_label = empty($address_type["zip_label"]) ? __("Zip Code", "gravityforms") : $address_type["zip_label"]; + $hide_country = !empty($address_type["country"]) || rgget("hideCountry", $field); + + if(empty($country_value)) + $country_value = rgget("defaultCountry", $field); + + if(empty($state_value)) + $state_value = rgget("defaultState", $field); + + $country_list = self::get_country_dropdown($country_value); + + //changing css classes based on field format to ensure proper display + $address_display_format = apply_filters("gform_address_display_format", "default"); + $city_location = $address_display_format == "zip_before_city" ? "right" : "left"; + $zip_location = $address_display_format != "zip_before_city" && rgar($field,"hideState") ? "right" : "left"; + $state_location = $address_display_format == "zip_before_city" ? "left" : "right"; + $country_location = rgar($field,"hideState") ? "left" : "right"; + + //address field + $tabindex = self::get_tabindex(); + $street_address = sprintf("", $id, $field_id, $street_value, $disabled_text, $field_id); + + //address line 2 field + $street_address2 = ""; + $style = (IS_ADMIN && rgget("hideAddress2", $field)) ? "style='display:none;'" : ""; + if(IS_ADMIN || !rgget("hideAddress2", $field)){ + $tabindex = self::get_tabindex(); + $street_address2 = sprintf("", $id, $field_id, $street2_value, $disabled_text, $field_id); + } + + if($address_display_format == "zip_before_city"){ + //zip field + $tabindex = self::get_tabindex(); + $zip = sprintf("", $id, $field_id, $zip_value, $disabled_text, $field_id); + + //city field + $tabindex = self::get_tabindex(); + $city = sprintf("", $id, $field_id, $city_value, $disabled_text, $field_id); + + //state field + $style = (IS_ADMIN && rgget("hideState", $field)) ? "style='display:none;'" : ""; + if(IS_ADMIN || !rgget("hideState", $field)){ + $state_field = self::get_state_field($field, $id, $field_id, $state_value, $disabled_text, $form_id); + $state = sprintf("$state_field", $field_id); + } + else{ + $state = sprintf("", $id, $field_id, $state_value); + } + } + else{ + + //city field + $tabindex = self::get_tabindex(); + $city = sprintf("", $id, $field_id, $city_value, $disabled_text, $field_id); + + //state field + $style = (IS_ADMIN && rgget("hideState", $field)) ? "style='display:none;'" : ""; + if(IS_ADMIN || !rgget("hideState", $field)){ + $state_field = self::get_state_field($field, $id, $field_id, $state_value, $disabled_text, $form_id); + $state = sprintf("$state_field", $field_id); + } + else{ + $state = sprintf("", $id, $field_id, $state_value); + } + + //zip field + $tabindex = self::get_tabindex(); + $zip = sprintf("", $id, $field_id, $zip_value, $disabled_text, $field_id); + + } + + if(IS_ADMIN || !$hide_country){ + $style = $hide_country ? "style='display:none;'" : ""; + $tabindex = self::get_tabindex(); + $country = sprintf("", $id, $field_id, $disabled_text, $country_list, $field_id); + } + else{ + $country = sprintf("", $id, $field_id, $country_value); + } + + $inputs = $address_display_format == "zip_before_city" ? $street_address . $street_address2 . $zip . $city . $state . $country : $street_address . $street_address2 . $city . $state . $zip . $country; + + return "
    " . $inputs . "
    "; + + case "date" : + if(!empty($post_link)) + return $post_link; + + $format = empty($field["dateFormat"]) ? "mdy" : esc_attr($field["dateFormat"]); + $field_position = substr($format, 0, 3); + if(IS_ADMIN && RG_CURRENT_VIEW != "entry"){ + $datepicker_display = in_array(rgget("dateType", $field), array("datefield", "datedropdown")) ? "none" : "inline"; + $datefield_display = rgget("dateType", $field) == "datefield" ? "inline" : "none"; + $dropdown_display = rgget("dateType", $field) == "datedropdown" ? "inline" : "none"; + $icon_display = rgget("calendarIconType", $field) == "calendar" ? "inline" : "none"; + + $month_field = "
    "; + $day_field = "
    "; + $year_field = "
    "; + + $month_dropdown = "
    " . self::get_month_dropdown("","","","","disabled='disabled'") . "
    "; + $day_dropdown = "
    " . self::get_day_dropdown("","","","","disabled='disabled'") . "
    "; + $year_dropdown = "
    " . self::get_year_dropdown("","","","","disabled='disabled'") . "
    "; + + $field_string ="
    "; + + switch($field_position){ + case "dmy" : + $field_string .= $day_field . $month_field . $year_field . $day_dropdown . $month_dropdown . $year_dropdown; + break; + + case "ymd" : + $field_string .= $year_field . $month_field . $day_field . $year_dropdown . $month_dropdown . $day_dropdown; + break; + + default : + $field_string .= $month_field . $day_field . $year_field . $month_dropdown . $day_dropdown . $year_dropdown; + break; + } + + return $field_string; + } + else{ + $date_info = self::parse_date($value, $format); + $date_type = rgget("dateType", $field); + if(in_array($date_type, array("datefield", "datedropdown"))) + { + switch($field_position){ + + case "dmy" : + $tabindex = self::get_tabindex(); + $field_str = $date_type == "datedropdown" + ? "
    " . self::get_day_dropdown("input_{$id}[]", "{$field_id}_2", rgar($date_info,"day"), $tabindex, $disabled_text) . "
    " + : sprintf("
    ", $field_id, $id, $field_id, esc_attr(rgget("day", $date_info)), $disabled_text, $field_id); + + $tabindex = self::get_tabindex(); + $field_str .= $date_type == "datedropdown" + ? "
    " . self::get_month_dropdown("input_{$id}[]", "{$field_id}_1", rgar($date_info,"month"), $tabindex, $disabled_text) . "
    " + : sprintf("
    ", $field_id, $id, $field_id, esc_attr(rgget("month", $date_info)), $disabled_text, $field_id); + + $tabindex = self::get_tabindex(); + $field_str .= $date_type == "datedropdown" + ? "
    " . self::get_year_dropdown("input_{$id}[]", "{$field_id}_3", rgar($date_info,"year"), $tabindex, $disabled_text) . "
    " + : sprintf("
    ", $field_id, $id, $field_id, esc_attr(rgget("year", $date_info)), $disabled_text, $field_id); + + break; + + case "ymd" : + $tabindex = self::get_tabindex(); + $field_str = $date_type == "datedropdown" + ? "
    " . self::get_year_dropdown("input_{$id}[]", "{$field_id}_3", rgar($date_info,"year"), $tabindex, $disabled_text) . "
    " + : sprintf("
    ", $field_id, $id, $field_id, esc_attr(rgget("year", $date_info)), $disabled_text, $field_id); + + $field_str .= $date_type == "datedropdown" + ? "
    " . self::get_month_dropdown("input_{$id}[]", "{$field_id}_1", rgar($date_info,"month"), $tabindex, $disabled_text) . "
    " + : sprintf("
    ", $field_id, $id, $field_id, esc_attr(rgar($date_info,"month")), $disabled_text, $field_id); + + $tabindex = self::get_tabindex(); + $field_str .= $date_type == "datedropdown" + ? "
    " . self::get_day_dropdown("input_{$id}[]", "{$field_id}_2", rgar($date_info,"day"), $tabindex, $disabled_text) . "
    " + : sprintf("
    ", $field_id, $id, $field_id, esc_attr(rgar($date_info,"day")), $disabled_text, $field_id); + + break; + + default : + $tabindex = self::get_tabindex(); + + $field_str = $date_type == "datedropdown" + ? "
    " . self::get_month_dropdown("input_{$id}[]", "{$field_id}_1", rgar($date_info,"month"), $tabindex, $disabled_text) . "
    " + : sprintf("
    ", $field_id, $id, $field_id, esc_attr(rgar($date_info,"month")), $disabled_text, $field_id); + + $tabindex = self::get_tabindex(); + $field_str .= $date_type == "datedropdown" + ? "
    " . self::get_day_dropdown("input_{$id}[]", "{$field_id}_2", rgar($date_info,"day"), $tabindex, $disabled_text) . "
    " + : sprintf("
    ", $field_id, $id, $field_id, esc_attr(rgar($date_info,"day")), $disabled_text, $field_id); + + $tabindex = self::get_tabindex(); + $field_str .= $date_type == "datedropdown" + ? "
    " . self::get_year_dropdown("input_{$id}[]", "{$field_id}_3", rgar($date_info,"year"), $tabindex, $disabled_text) . "
    " + : sprintf("
    ", $field_id, $id, $field_id, esc_attr(rgget("year", $date_info)), $disabled_text, $field_id); + + break; + } + + return $field_str; + } + else + { + $value = GFCommon::date_display($value, $format); + $icon_class = $field["calendarIconType"] == "none" ? "datepicker_no_icon" : "datepicker_with_icon"; + $icon_url = empty($field["calendarIconUrl"]) ? GFCommon::get_base_url() . "/images/calendar.png" : $field["calendarIconUrl"]; + $tabindex = self::get_tabindex(); + return sprintf("
    ", $id, $field_id, esc_attr($value), esc_attr($class), $format, $icon_class, $disabled_text); + } + } + + case "time" : + if(!empty($post_link)) + return $post_link; + + $hour = $minute = $am_selected = $pm_selected = ""; + + if(!is_array($value) && !empty($value)){ + preg_match('/^(\d*):(\d*) ?(.*)$/', $value, $matches); + $hour = esc_attr($matches[1]); + $minute = esc_attr($matches[2]); + $am_selected = rgar($matches,3) == "am" ? "selected='selected'" : ""; + $pm_selected = rgar($matches,3) == "pm" ? "selected='selected'" : ""; + } + else if(is_array($value)){ + $hour = esc_attr($value[0]); + $minute = esc_attr($value[1]); + $am_selected = rgar($value,2) == "am" ? "selected='selected'" : ""; + $pm_selected = rgar($value,2) == "pm" ? "selected='selected'" : ""; + } + $hour_tabindex = self::get_tabindex(); + $minute_tabindex = self::get_tabindex(); + $ampm_tabindex = self::get_tabindex(); + + $ampm_field_style = is_admin() && rgar($field, "timeFormat") == "24" ? "style='display:none;'" : ""; + $ampm_field = is_admin() || rgar($field, "timeFormat") != "24" ? "
    " : ""; + + return sprintf("
    :
    {$ampm_field}
    ", $field_id, $id, $field_id, $hour, $disabled_text, $field_id, $id, $field_id, $minute, $disabled_text, $field_id); + + case "fileupload" : + $tabindex = self::get_tabindex(); + $multiple_files = rgar($field, "multipleFiles"); + $file_list_id = "gform_preview_" . $form_id . "_". $id; + $max_upload_size = ! IS_ADMIN && isset($field["maxFileSize"]) && $field["maxFileSize"] > 0 ? $field["maxFileSize"] * 1048576: wp_max_upload_size(); + if($multiple_files){ + $upload_action_url = trailingslashit(site_url()) . "?gf_page=upload"; + $max_files = isset($field["maxFiles"]) && $field["maxFiles"] > 0 ? $field["maxFiles"]: 0; + $browse_button_id = 'gform_browse_button_' . $form_id . "_" . $id; + $container_id = 'gform_multifile_upload_' . $form_id . "_" . $id; + $drag_drop_id = 'gform_drag_drop_area_' . $form_id . "_" . $id; + + $messages_id = "gform_multifile_messages_{$form_id}_{$id}"; + $allowed_extensions = isset($field["allowedExtensions"]) && !empty($field["allowedExtensions"]) ? join(",", GFCommon::clean_extensions(explode(",", strtolower($field["allowedExtensions"])))) : array(); + if(empty($allowed_extensions)) + $allowed_extensions="*"; + $disallowed_extensions = GFCommon::get_disallowed_file_extensions(); + + if( defined('DOING_AJAX') && DOING_AJAX && "rg_change_input_type" === rgpost('action')){ + $plupload_init = array(); + } else { + $plupload_init = array( + 'runtimes' => 'html5,flash,html4', + 'browse_button' => $browse_button_id, + 'container' => $container_id, + 'drop_element' => $drag_drop_id, + 'filelist' => $file_list_id, + 'unique_names' => true, + 'file_data_name' => 'file', + /*'chunk_size' => '10mb',*/ // chunking doesn't currently have very good cross-browser support + 'url' => $upload_action_url, + 'flash_swf_url' => includes_url('js/plupload/plupload.flash.swf'), + 'silverlight_xap_url' => includes_url('js/plupload/plupload.silverlight.xap'), + 'filters' => array( + 'mime_types' => array(array('title' => __( 'Allowed Files', 'gravityforms' ), 'extensions' => $allowed_extensions)), + 'max_file_size' => $max_upload_size . 'b' + ), + 'multipart' => true, + 'urlstream_upload' => false, + 'multipart_params' => array( + "form_id" => $form_id, + "field_id" => $id + ), + 'gf_vars' => array( + 'max_files' => $max_files, + 'message_id' => $messages_id, + 'disallowed_extensions' => $disallowed_extensions + ) + ); + + // plupload 2 was introduced in WordPress 3.9. Plupload 1 accepts a slightly different init array. + if (version_compare(get_bloginfo('version'), "3.9-RC1", "<")) { + $plupload_init['max_file_size'] = $max_upload_size . 'b'; + $plupload_init['filters'] = array(array('title' => __('Allowed Files', 'gravityforms'), 'extensions' => $allowed_extensions)); + } + } + + + $plupload_init = apply_filters("gform_plupload_settings_{$form_id}", apply_filters('gform_plupload_settings', $plupload_init, $form_id, $field), $form_id, $field); + + // Multi-file uploading doesn't currently work in iOS Safari, + // single-file allows the built-in camera to be used as source for images + if ( wp_is_mobile() ) + $plupload_init['multi_selection'] = false; + + $plupload_init_json = htmlspecialchars(json_encode($plupload_init), ENT_QUOTES, 'UTF-8'); + $upload = sprintf("
    %s
    ",$container_id, $plupload_init_json, $drag_drop_id, __("Drop files here or" ,"gravityforms"), $browse_button_id, __("Select files", "gravityforms") ) ; + if(!IS_ADMIN) + $upload .= "
    "; + + if(IS_ADMIN && RG_CURRENT_VIEW === "entry") + $upload .= sprintf('', $id, esc_attr($value)); + + } else { + $upload = sprintf("", $max_upload_size); + $upload .= sprintf("", $id, $field_id, esc_attr($class), $disabled_text); + } + + if(IS_ADMIN && RG_CURRENT_VIEW === "entry" && !empty($value)){ // edit entry + $file_urls = $multiple_files ? json_decode($value) : array($value); + $upload_display = $multiple_files ? "" : "style='display:none'"; + $preview = "
    $upload
    "; + $preview .= sprintf("
    ", $file_list_id); + $preview .= sprintf("
    ", $id); + + foreach($file_urls as $file_index => $file_url){ + if(self::is_ssl() && strpos($file_url, "http:") !== false ){ + $file_url = str_replace("http:", "https:", $file_url); + } + $file_url = esc_attr($file_url); + $preview .= sprintf("
    %s
    ", $file_index, $file_url, $file_url, $file_url, GFCommon::truncate_url($file_url), $file_url, GFCommon::get_base_url() . "/images/download.png", $lead_id, $id, GFCommon::get_base_url() . "/images/delete.png"); + } + + $preview .="
    "; + + return $preview; + } else { + $input_name = "input_{$id}"; + $uploaded_files = isset(GFFormsModel::$uploaded_files[$form_id][$input_name]) ? GFFormsModel::$uploaded_files[$form_id][$input_name] : array(); + $file_infos = $multiple_files ? $uploaded_files : RGFormsModel::get_temp_filename($form_id, $input_name); + + if(!empty($file_infos)){ + $preview = sprintf("
    ", $file_list_id); + $file_infos = $multiple_files ? $uploaded_files : array($file_infos); + foreach($file_infos as $file_info){ + $preview .= "
    " . esc_html($file_info["uploaded_filename"]) . "
    "; + } + $preview .= "
    "; + if(!$multiple_files) + $upload = str_replace(" class='", " class='gform_hidden ", $upload); + return "
    " . $upload . " {$preview}
    "; + } + else{ + + $preview = $multiple_files ? sprintf("
    ", $file_list_id) : ""; + + return "
    $upload
    " . $preview; + } + } + + case "captcha" : + + switch(rgget("captchaType", $field)){ + case "simple_captcha" : + $size = rgempty("simpleCaptchaSize", $field) ? "medium" : $field["simpleCaptchaSize"]; + $captcha = self::get_captcha($field); + + $tabindex = self::get_tabindex(); + + $dimensions = IS_ADMIN ? "" : "width='" . rgar($captcha,"width") . "' height='" . rgar($captcha,"height") . "'"; + return "
    "; + break; + + case "math" : + $size = empty($field["simpleCaptchaSize"]) ? "medium" : $field["simpleCaptchaSize"]; + $captcha_1 = self::get_math_captcha($field, 1); + $captcha_2 = self::get_math_captcha($field, 2); + $captcha_3 = self::get_math_captcha($field, 3); + + $tabindex = self::get_tabindex(); + + $dimensions = IS_ADMIN ? "" : "width='{$captcha_1["width"]}' height='{$captcha_1["height"]}'"; + return "
    "; + break; + + default: + + if(!function_exists("recaptcha_get_html")){ + require_once(GFCommon::get_base_path() . '/recaptchalib.php'); + } + + $theme = empty($field["captchaTheme"]) ? "red" : esc_attr($field["captchaTheme"]); + $publickey = get_option("rg_gforms_captcha_public_key"); + $privatekey = get_option("rg_gforms_captcha_private_key"); + if(IS_ADMIN){ + if(empty($publickey) || empty($privatekey)){ + return "
    " . __("To use the reCaptcha field you must first do the following:", "gravityforms") . "
    1 - " . sprintf(__("Sign up%s for a free reCAPTCHA account", "gravityforms"), "") . "
    2 - " . sprintf(__("Enter your reCAPTCHA keys in the %ssettings page%s", "gravityforms"), "", "") . "
    "; + } + else{ + return "
    reCAPTCHA
    "; + } + } + else{ + $language = empty($field["captchaLanguage"]) ? "en" : esc_attr($field["captchaLanguage"]); + + if(empty(self::$tab_index)) + self::$tab_index = 1; + + $options = ""; + + $is_ssl = !empty($_SERVER['HTTPS']); + return $options . "
    " . recaptcha_get_html($publickey, null, $is_ssl, $language) . "
    "; + } + } + break; + + case "creditcard" : + + $card_number = ""; + $card_name = ""; + $expiration_date = ""; + $expiration_month = ""; + $expiration_year = ""; + $security_code = ""; + $autocomplete = RGFormsModel::is_html5_enabled() ? "autocomplete='off'" : ""; + + if(is_array($value)){ + $card_number = esc_attr(rgget($field["id"] . ".1",$value)); + $card_name = esc_attr(rgget($field["id"] . ".5",$value)); + $expiration_date = rgget($field["id"] . ".2",$value); + if(!is_array($expiration_date) && !empty($expiration_date)) + $expiration_date = explode("/", $expiration_date); + + if(is_array($expiration_date) && count($expiration_date) == 2){ + $expiration_month = $expiration_date[0]; + $expiration_year = $expiration_date[1]; + } + + $security_code = esc_attr(rgget($field["id"] . ".3",$value)); + } + + $action = !IS_ADMIN ? "gformMatchCard(\"{$field_id}_1\");" : ""; + + $onchange= "onchange='{$action}'"; + $onkeyup = "onkeyup='{$action}'"; + + $card_icons = ''; + $cards = GFCommon::get_card_types(); + $card_style = rgar($field, 'creditCardStyle') ? rgar($field, 'creditCardStyle') : 'style1'; + + foreach($cards as $card) { + + $style = ""; + if(self::is_card_supported($field, $card["slug"])){ + $print_card = true; + } + else if (IS_ADMIN){ + $print_card = true; + $style = "style='display:none;'"; + } + else{ + $print_card = false; + } + + if($print_card){ + $card_icons .= "
    {$card['name']}
    "; + } + } + + $payment_methods = apply_filters("gform_payment_methods", array(), $field, $form_id); + $payment_options = ""; + if(is_array($payment_methods)){ + foreach($payment_methods as $payment_method){ + $checked = rgpost("gform_payment_method") == $payment_method["key"] ? "checked='checked'" : ""; + $payment_options .="
    {$payment_method["label"]}
    "; + } + } + $checked = rgpost("gform_payment_method") == "creditcard" || rgempty("gform_payment_method") ? "checked='checked'" : ""; + $card_radio_button = empty($payment_options) ? "" : ""; + $card_icons = "{$payment_options}
    {$card_radio_button}{$card_icons}
    "; + + + + //card number fields + $tabindex = self::get_tabindex(); + $html5_output = ! is_admin() && GFFormsModel::is_html5_enabled() ? "pattern='[0-9]*' title='" . __("Only digits are allowed", "gravityforms") . "'" : ""; + $card_field = sprintf("{$card_icons}", $id, $field_id, $card_number, $disabled_text, $field_id); + + //expiration date field + $expiration_field = "". + + "". + + "". + + // month selector + "". + + // year selector + "". + + // label for the expiration fields + "". + + "". + ""; + + //security code field + $tabindex = self::get_tabindex(); + $html5_output = GFFormsModel::is_html5_enabled() ? "pattern='[0-9]*' title='" . __("Only digits are allowed", "gravityforms") . "'" : ""; + $security_field = "". + "". + " ". + "". + "". + ""; + + $tabindex = self::get_tabindex(); + $card_name_field = sprintf("", $id, $field_id, $card_name, $disabled_text, $field_id); + + return "
    " . $card_field . $expiration_field . $security_field . $card_name_field . "
    "; + + break; + + case "list" : + + if(!empty($value)) + $value = maybe_unserialize($value); + + if(!is_array($value)) + $value = array(array()); + + $has_columns = is_array(rgar($field, "choices")); + $columns = $has_columns ? rgar($field, "choices") : array(array()); + + $list = "
    " . + ""; + + $class_attr = ""; + if($has_columns){ + + $list .= ""; + $colnum = 1; + foreach($columns as $column){ + $odd_even = ($colnum % 2) == 0 ? "even" : "odd"; + $list .= ""; + $colnum++; + } + $list .= ""; + + $list .= ""; + foreach($columns as $column){ + $list .= ""; + } + $list .= ""; + } + else{ + $list .= ""; + } + + $delete_display = count($value) == 1 ? "visibility:hidden;" : ""; + $maxRow = intval(rgar($field, "maxRows")); + $disabled_icon_class = !empty($maxRow) && count($value) >= $maxRow ? "gfield_icon_disabled" : ""; + + $list .= ""; + $rownum = 1; + foreach($value as $item){ + + $odd_even = ($rownum % 2) == 0 ? "even" : "odd"; + + $list .= ""; + $colnum = 1; + foreach($columns as $column){ + + //getting value. taking into account columns being added/removed from form meta + if(is_array($item)){ + if($has_columns){ + $val = rgar($item, $column["text"]); + } + else{ + $vals = array_values($item); + $val = rgar($vals, 0); + } + } + else{ + $val = $colnum == 1 ? $item : ""; + } + + $list .= ""; + $colnum++; + } + + $add_icon = !rgempty("addIconUrl", $field) ? $field["addIconUrl"] : GFCommon::get_base_url() . "/images/add.png"; + $delete_icon = !rgempty("deleteIconUrl", $field) ? $field["deleteIconUrl"] : GFCommon::get_base_url() . "/images/remove.png"; + + $on_click = IS_ADMIN && RG_CURRENT_VIEW != "entry" ? "" : "onclick='gformAddListItem(this, {$maxRow})'"; + + if(rgar($field, "maxRows") != 1){ + + // can't replace these icons with the webfont versions since they appear on the front end. + + $list .=""; + } + + $list .= ""; + + if(!empty($maxRow) && $rownum >= $maxRow) + break; + + $rownum++; + } + + $list .="
    " . esc_html($column["text"]) . " 
    " . self::get_list_input($field, $has_columns, $column, $val, $form_id) . ""; + $list .=" " . __("Add a row", "gravityforms") . "" . + " " . __("Remove this row", "gravityforms") . ""; + + $list .="
    "; + + return $list; + break; + } + } + + public static function is_ssl(){ + global $wordpress_https; + $is_ssl = false; + + $has_https_plugin = class_exists('WordPressHTTPS') && isset($wordpress_https); + $has_is_ssl_method = $has_https_plugin && method_exists('WordPressHTTPS', 'is_ssl'); + $has_isSsl_method = $has_https_plugin && method_exists('WordPressHTTPS', 'isSsl'); + + //Use the WordPress HTTPs plugin if installed + if ($has_https_plugin && $has_is_ssl_method){ + $is_ssl = $wordpress_https->is_ssl(); + } + else if ($has_https_plugin && $has_isSsl_method){ + $is_ssl = $wordpress_https->isSsl(); + } + else{ + $is_ssl = is_ssl(); + } + + + if(!$is_ssl && isset($_SERVER["HTTP_CF_VISITOR"]) && strpos($_SERVER["HTTP_CF_VISITOR"], "https")){ + $is_ssl=true; + } + + return apply_filters("gform_is_ssl", $is_ssl); + } + + public static function is_card_supported($field, $card_slug){ + $supported_cards = rgar($field, 'creditCards'); + $default_cards = array('amex', 'discover', 'mastercard', 'visa'); + + if(!empty($supported_cards) && in_array($card_slug, $supported_cards)) { + return true; + } + else if(empty($supported_cards) && in_array($card_slug, $default_cards)) { + return true; + } + + return false; + + } + + public static function is_preview(){ + $url_info = parse_url(RGFormsModel::get_current_page_url()); + $file_name = basename($url_info["path"]); + return $file_name == "preview.php" || rgget("gf_page", $_GET) == "preview"; + } + + private static function get_expiration_months($selected_month){ + $str = ""; + for($i=1; $i<13; $i++){ + $selected = intval($selected_month) == $i ? "selected='selected'" : ""; + $month = str_pad($i, 2, "0", STR_PAD_LEFT); + $str .= ""; + } + return $str; + } + + private static function get_expiration_years($selected_year){ + $str = ""; + $year = intval(date("Y")); + for($i=$year; $i < ($year + 20); $i++){ + $selected = intval($selected_year) == $i ? "selected='selected'" : ""; + $str .= ""; + } + return $str; + } + + private static function get_list_input($field, $has_columns, $column, $value, $form_id){ + + $tabindex = GFCommon::get_tabindex(); + + $column_index = 1; + if($has_columns && is_array(rgar($field, "choices"))){ + foreach($field["choices"] as $choice){ + if($choice["text"] == $column["text"]) + break; + + $column_index++; + } + } + $input_info = array("type" => "text"); + + $input_info = apply_filters("gform_column_input_{$form_id}_{$field["id"]}_{$column_index}", apply_filters("gform_column_input", $input_info, $field, rgar($column, "text"), $value, $form_id), $field, rgar($column, "text"), $value, $form_id); + + switch($input_info["type"]){ + + case "select" : + $input = ""; + + break; + + default : + $input = ""; + break; + } + + return apply_filters("gform_column_input_content_{$form_id}_{$field["id"]}_{$column_index}", + apply_filters("gform_column_input_content", $input, $input_info, $field, rgar($column, "text"), $value, $form_id), + $input_info, $field, rgar($column, "text"), $value, $form_id); + + } + + public static function clean_extensions($extensions){ + $count = sizeof($extensions); + for($i=0; $i<$count; $i++){ + $extensions[$i] = str_replace(".", "",str_replace(" ", "", $extensions[$i])); + } + return $extensions; + } + + public static function get_disallowed_file_extensions(){ + return array("php", "asp", "exe", "com", "htaccess"); + } + + public static function to_money($number, $currency_code=""){ + if(!class_exists("RGCurrency")) + require_once("currency.php"); + + if(empty($currency_code)) + $currency_code = self::get_currency(); + + $currency = new RGCurrency($currency_code); + return $currency->to_money($number); + } + + public static function to_number($text, $currency_code=""){ + if(!class_exists("RGCurrency")) + require_once("currency.php"); + + if(empty($currency_code)) + $currency_code = self::get_currency(); + + $currency = new RGCurrency($currency_code); + + return $currency->to_number($text); + } + + public static function get_currency(){ + $currency = get_option("rg_gforms_currency"); + $currency = empty($currency) ? "USD" : $currency; + + return apply_filters("gform_currency", $currency); + } + + + public static function get_simple_captcha(){ + $captcha = new ReallySimpleCaptcha(); + $captcha->tmp_dir = RGFormsModel::get_upload_path("captcha") . "/"; + return $captcha; + } + + public static function get_captcha($field){ + if(!class_exists("ReallySimpleCaptcha")) + return array(); + + $captcha = self::get_simple_captcha(); + + //If captcha folder does not exist and can't be created, return an empty captcha + if(!wp_mkdir_p($captcha->tmp_dir)) + return array(); + + $captcha->char_length = 5; + switch(rgar($field,"simpleCaptchaSize")){ + case "small" : + $captcha->img_size = array( 100, 28 ); + $captcha->font_size = 18; + $captcha->base = array( 8, 20 ); + $captcha->font_char_width = 17; + + break; + + case "large" : + $captcha->img_size = array( 200, 56 ); + $captcha->font_size = 32; + $captcha->base = array( 18, 42 ); + $captcha->font_char_width = 35; + break; + + default : + $captcha->img_size = array( 150, 42 ); + $captcha->font_size = 26; + $captcha->base = array( 15, 32 ); + $captcha->font_char_width = 25; + break; + } + + if(!empty($field["simpleCaptchaFontColor"])){ + $captcha->fg = self::hex2rgb($field["simpleCaptchaFontColor"]); + } + if(!empty($field["simpleCaptchaBackgroundColor"])){ + $captcha->bg = self::hex2rgb($field["simpleCaptchaBackgroundColor"]); + } + + $word = $captcha->generate_random_word(); + $prefix = mt_rand(); + $filename = $captcha->generate_image($prefix, $word); + $url = RGFormsModel::get_upload_url("captcha") . "/" . $filename; + $path = $captcha->tmp_dir . $filename; + + if(self::is_ssl() && strpos($url, "http:") !== false ){ + $url = str_replace("http:", "https:", $url); + } + + return array("path"=>$path, "url"=> $url, "height" => $captcha->img_size[1], "width" => $captcha->img_size[0], "prefix" => $prefix); + } + + public static function get_math_captcha($field, $pos){ + if(!class_exists("ReallySimpleCaptcha")) + return array(); + + $captcha = self::get_simple_captcha(); + + //If captcha folder does not exist and can't be created, return an empty captcha + if(!wp_mkdir_p($captcha->tmp_dir)) + return array(); + + $captcha->char_length = 1; + if($pos == 1 || $pos == 3) + $captcha->chars = '0123456789'; + else + $captcha->chars = '+'; + + switch(rgar($field,"simpleCaptchaSize")){ + case "small" : + $captcha->img_size = array( 23, 28 ); + $captcha->font_size = 18; + $captcha->base = array( 6, 20 ); + $captcha->font_char_width = 17; + + break; + + case "large" : + $captcha->img_size = array( 36, 56 ); + $captcha->font_size = 32; + $captcha->base = array( 10, 42 ); + $captcha->font_char_width = 35; + break; + + default : + $captcha->img_size = array( 30, 42 ); + $captcha->font_size = 26; + $captcha->base = array( 9, 32 ); + $captcha->font_char_width = 25; + break; + } + + if(!empty($field["simpleCaptchaFontColor"])){ + $captcha->fg = self::hex2rgb($field["simpleCaptchaFontColor"]); + } + if(!empty($field["simpleCaptchaBackgroundColor"])){ + $captcha->bg = self::hex2rgb($field["simpleCaptchaBackgroundColor"]); + } + + $word = $captcha->generate_random_word(); + $prefix = mt_rand(); + $filename = $captcha->generate_image($prefix, $word); + $url = RGFormsModel::get_upload_url("captcha") . "/" . $filename; + $path = $captcha->tmp_dir . $filename; + + return array("path"=>$path, "url"=> $url, "height" => $captcha->img_size[1], "width" => $captcha->img_size[0], "prefix" => $prefix); + } + + private static function hex2rgb($color){ + if ($color[0] == '#') + $color = substr($color, 1); + + if (strlen($color) == 6) + list($r, $g, $b) = array($color[0].$color[1], + $color[2].$color[3], + $color[4].$color[5]); + elseif (strlen($color) == 3) + list($r, $g, $b) = array($color[0].$color[0], $color[1].$color[1], $color[2].$color[2]); + else + return false; + + $r = hexdec($r); $g = hexdec($g); $b = hexdec($b); + + return array($r, $g, $b); + } + + public static function get_address_types($form_id){ + + $addressTypes = array( + "international" => array("label" => __("International", "gravityforms"),"zip_label" => apply_filters("gform_address_zip_{$form_id}",apply_filters("gform_address_zip", __("ZIP / Postal Code", "gravityforms"), $form_id), $form_id),"state_label" => apply_filters("gform_address_state_{$form_id}",apply_filters("gform_address_state",__("State / Province / Region", "gravityforms"), $form_id), $form_id)), + "us" => array("label" => __("United States", "gravityforms"),"zip_label" => apply_filters("gform_address_zip_{$form_id}",apply_filters("gform_address_zip", __("ZIP Code", "gravityforms"), $form_id), $form_id), "state_label" => apply_filters("gform_address_state_{$form_id}",apply_filters("gform_address_state",__("State", "gravityforms"), $form_id), $form_id), "country" => "United States", "states" => array_merge(array(''), GFCommon::get_us_states())), + "canadian" => array("label" => __("Canadian", "gravityforms"), "zip_label" => apply_filters("gform_address_zip_{$form_id}",apply_filters("gform_address_zip", __("Postal Code", "gravityforms"), $form_id), $form_id), "state_label" => apply_filters("gform_address_state_{$form_id}",apply_filters("gform_address_state",__("Province", "gravityforms"), $form_id), $form_id),"country" => "Canada", "states" => array_merge(array(''), GFCommon::get_canadian_provinces())) + ); + + return apply_filters("gform_address_types_{$form_id}", apply_filters("gform_address_types", $addressTypes, $form_id), $form_id); + } + + private static function get_state_field($field, $id, $field_id, $state_value, $disabled_text, $form_id){ + $state_dropdown_class = $state_text_class = $state_style = $text_style = $state_field_id = ""; + + if(empty($state_value)){ + $state_value = rgget("defaultState", $field); + + //for backwards compatibility (canadian address type used to store the default state into the defaultProvince property) + if (rgget("addressType", $field) == "canadian" && !rgempty("defaultProvince", $field)) + $state_value = $field["defaultProvince"]; + } + + $address_type = rgempty("addressType", $field) ? "international" : $field["addressType"]; + $address_types = self::get_address_types($form_id); + $has_state_drop_down = isset($address_types[$address_type]["states"]) && is_array($address_types[$address_type]["states"]); + + if(IS_ADMIN && RG_CURRENT_VIEW != "entry"){ + $state_dropdown_class = "class='state_dropdown'"; + $state_text_class = "class='state_text'"; + $state_style = !$has_state_drop_down ? "style='display:none;'" : ""; + $text_style = $has_state_drop_down ? "style='display:none;'" : ""; + $state_field_id = ""; + } + else{ + //id only displayed on front end + $state_field_id = "id='" . $field_id . "_4'"; + } + + $tabindex = self::get_tabindex(); + $states = empty($address_types[$address_type]["states"]) ? array() : $address_types[$address_type]["states"]; + $state_dropdown = sprintf("", $id, $state_field_id, $disabled_text, GFCommon::get_state_dropdown($states, $state_value)); + + $tabindex = self::get_tabindex(); + $state_text = sprintf("", $id, $state_field_id, $state_value, $disabled_text); + + if(IS_ADMIN && RG_CURRENT_VIEW != "entry") + return $state_dropdown . $state_text; + else if($has_state_drop_down) + return $state_dropdown; + else + return $state_text; + } + + public static function get_lead_field_display($field, $value, $currency="", $use_text=false, $format="html", $media="screen"){ + + if($field['type'] == 'post_category') + $value = self::prepare_post_category_value($value, $field); + + switch(RGFormsModel::get_input_type($field)){ + case "name" : + if(is_array($value)){ + $prefix = trim(rgget($field["id"] . ".2", $value)); + $first = trim(rgget($field["id"] . ".3", $value)); + $last = trim(rgget($field["id"] . ".6", $value)); + $suffix = trim(rgget($field["id"] . ".8", $value)); + + $name = $prefix; + $name .= !empty($name) && !empty($first) ? " $first" : $first; + $name .= !empty($name) && !empty($last) ? " $last" : $last; + $name .= !empty($name) && !empty($suffix) ? " $suffix" : $suffix; + + return $name; + } + else{ + return $value; + } + + break; + case "creditcard" : + if(is_array($value)){ + $card_number = trim(rgget($field["id"] . ".1", $value)); + $card_type = trim(rgget($field["id"] . ".4", $value)); + $separator = $format == "html" ? "
    " : "\n"; + return empty($card_number) ? "" : $card_type . $separator . $card_number; + } + else{ + return ""; + } + break; + + case "address" : + if(is_array($value)){ + $street_value = trim(rgget($field["id"] . ".1", $value)); + $street2_value = trim(rgget($field["id"] . ".2", $value)); + $city_value = trim(rgget($field["id"] . ".3", $value)); + $state_value = trim(rgget($field["id"] . ".4", $value)); + $zip_value = trim(rgget($field["id"] . ".5", $value)); + $country_value = trim(rgget($field["id"] . ".6", $value)); + + $line_break = $format == "html" ? "
    " : "\n"; + + $address_display_format = apply_filters("gform_address_display_format", "default"); + if($address_display_format == "zip_before_city"){ + /* + Sample: + 3333 Some Street + suite 16 + 2344 City, State + Country + */ + + $addr_ary = array(); + $addr_ary[] = $street_value; + + if(!empty($street2_value)) + $addr_ary[] = $street2_value; + + $zip_line = trim($zip_value . " " . $city_value); + $zip_line .= !empty($zip_line) && !empty($state_value) ? ", {$state_value}" : $state_value; + $zip_line = trim($zip_line); + if(!empty($zip_line)) + $addr_ary[] = $zip_line; + + if(!empty($country_value)) + $addr_ary[] = $country_value; + + $address = implode("
    ", $addr_ary); + + } + else{ + $address = $street_value; + $address .= !empty($address) && !empty($street2_value) ? $line_break . $street2_value : $street2_value; + $address .= !empty($address) && (!empty($city_value) || !empty($state_value)) ? $line_break. $city_value : $city_value; + $address .= !empty($address) && !empty($city_value) && !empty($state_value) ? ", $state_value" : $state_value; + $address .= !empty($address) && !empty($zip_value) ? " $zip_value" : $zip_value; + $address .= !empty($address) && !empty($country_value) ? $line_break . $country_value : $country_value; + } + + //adding map link + if(!empty($address) && $format == "html"){ + $address_qs = str_replace($line_break, " ", $address); //replacing
    and \n with spaces + $address_qs = urlencode($address_qs); + $address .= "
    Map It"; + } + + return $address; + } + else{ + return ""; + } + break; + + case "email" : + return GFCommon::is_valid_email($value) && $format == "html" ? "$value" : $value; + break; + + case "website" : + return GFCommon::is_valid_url($value) && $format == "html" ? "$value" : $value; + break; + + case "checkbox" : + if(is_array($value)){ + + $items = ''; + + foreach($value as $key => $item){ + if(!empty($item)){ + switch($format){ + case "text" : + $items .= GFCommon::selection_display($item, $field, $currency, $use_text) . ", "; + break; + + default: + $items .= "
  • " . GFCommon::selection_display($item, $field, $currency, $use_text) . "
  • "; + break; + } + } + } + if(empty($items)){ + return ""; + } + else if($format == "text"){ + return substr($items, 0, strlen($items)-2); //removing last comma + } + else{ + return ""; + } + } + else{ + return $value; + } + break; + + case "post_image" : + $ary = explode("|:|", $value); + $url = count($ary) > 0 ? $ary[0] : ""; + $title = count($ary) > 1 ? $ary[1] : ""; + $caption = count($ary) > 2 ? $ary[2] : ""; + $description = count($ary) > 3 ? $ary[3] : ""; + + if(!empty($url)){ + $url = str_replace(" ", "%20", $url); + + switch($format){ + case "text" : + $value = $url; + $value .= !empty($title) ? "\n\n" . $field["label"] . " (" . __("Title", "gravityforms") . "): " . $title : ""; + $value .= !empty($caption) ? "\n\n" . $field["label"] . " (" . __("Caption", "gravityforms") . "): " . $caption : ""; + $value .= !empty($description) ? "\n\n" . $field["label"] . " (" . __("Description", "gravityforms") . "): " . $description : ""; + break; + + default : + $value = ""; + $value .= !empty($title) ? "
    Title: $title
    " : ""; + $value .= !empty($caption) ? "
    Caption: $caption
    " : ""; + $value .= !empty($description) ? "
    Description: $description
    ": ""; + + break; + } + } + return $value; + + case "fileupload" : + $output = ""; + if(!empty($value)){ + $output_arr = array(); + $file_paths = rgar($field,"multipleFiles") ? json_decode($value) : array($value); + foreach($file_paths as $file_path){ + $info = pathinfo($file_path); + if(self::is_ssl() && strpos($file_path, "http:") !== false ){ + $file_path = str_replace("http:", "https:", $file_path); + } + $file_path = esc_attr(str_replace(" ", "%20", $file_path)); + $output_arr[] = $format == "text" ? $file_path . PHP_EOL: "
  • " . $info["basename"] . "
  • "; + } + $output = join(PHP_EOL, $output_arr); + } + $output = empty($output) || $format == "text" ? $output : sprintf("", $output); + return $output; + break; + + case "date" : + return GFCommon::date_display($value, rgar($field, "dateFormat")); + break; + + case "radio" : + case "select" : + return GFCommon::selection_display($value, $field, $currency, $use_text); + break; + + case "multiselect" : + if(empty($value) || $format == "text") + return $value; + + $value = explode(",", $value); + + $items = ''; + foreach($value as $item){ + $items .= "
  • " . GFCommon::selection_display($item, $field, $currency, $use_text) . "
  • "; + } + + return ""; + + break; + + case "calculation" : + case "singleproduct" : + if(is_array($value) && !empty($value)){ + $product_name = trim($value[$field["id"] . ".1"]); + $price = trim($value[$field["id"] . ".2"]); + $quantity = trim($value[$field["id"] . ".3"]); + + $product = $product_name . ", " . __("Qty: ", "gravityforms") . $quantity . ", " . __("Price: ", "gravityforms") . $price; + return $product; + } + else{ + return ""; + } + break; + + case "number" : + return GFCommon::format_number($value, rgar($field, "numberFormat")); + break; + + case "singleshipping" : + case "donation" : + case "total" : + case "price" : + return GFCommon::to_money($value, $currency); + + case "list" : + if(empty($value)) + return ""; + $value = unserialize($value); + + $has_columns = is_array($value[0]); + + if(!$has_columns){ + $items = ''; + foreach($value as $key => $item){ + if(!empty($item)){ + switch($format){ + case "text" : + $items .= $item . ", "; + break; + case "url" : + $items .= $item . ","; + break; + default : + if($media == "email"){ + $items .= "
  • {$item}
  • "; + } + else{ + $items .= "
  • {$item}
  • "; + } + break; + } + } + } + + if(empty($items)){ + return ""; + } + else if($format == "text"){ + return substr($items, 0, strlen($items)-2); //removing last comma + } + else if($format == "url"){ + return substr($items, 0, strlen($items)-1); //removing last comma + } + else if($media == "email"){ + return ""; + } + else{ + return ""; + } + } + else if(is_array($value)){ + $columns = array_keys($value[0]); + + $list = ""; + + switch($format){ + case "text" : + $is_first_row = true; + foreach($value as $item){ + if(!$is_first_row) + $list .= "\n\n" . $field["label"] . ": "; + $list .= implode(",", array_values($item)); + + $is_first_row = false; + } + break; + + case "url" : + foreach($value as $item){ + $list .= implode("|", array_values($item)) . ","; + } + if(!empty($list)) + $list = substr($list, 0, strlen($list)-1); + break; + + default : + if($media == "email"){ + $list = ""; + + //reading columns from entry data + foreach($columns as $column){ + $list .= ""; + } + $list .= ""; + + $list .= ""; + foreach($value as $item){ + $list .= ""; + foreach($columns as $column){ + $val = rgar($item, $column); + $list .= ""; + } + + $list .=""; + } + + $list .="
    " . esc_html($column) . "
    {$val}
    "; + } + else{ + $list = ""; + + //reading columns from entry data + foreach($columns as $column){ + $list .= ""; + } + $list .= ""; + + $list .= ""; + foreach($value as $item){ + $list .= ""; + foreach($columns as $column){ + $val = rgar($item, $column); + $list .= ""; + } + + $list .=""; + } + + $list .="
    " . esc_html($column) . "
    {$val}
    "; + } + break; + } + + return $list; + } + return ""; + break; + + default : + if (!is_array($value)) + { + return nl2br($value); + } + break; + } + } + + public static function get_product_fields($form, $lead, $use_choice_text=false, $use_admin_label=false){ + $products = array(); + + $product_info = null; + // retrieve static copy of product info (only for "real" entries) + if(!rgempty("id", $lead)){ + $product_info = gform_get_meta(rgar($lead,'id'), "gform_product_info_{$use_choice_text}_{$use_admin_label}"); + } + + // if no static copy, generate from form/lead info + if(!$product_info) { + + foreach($form["fields"] as $field){ + $id = $field["id"]; + $lead_value = RGFormsModel::get_lead_field_value($lead, $field); + + $quantity_field = self::get_product_fields_by_type($form, array("quantity"), $id); + $quantity = sizeof($quantity_field) > 0 && !RGFormsModel::is_field_hidden($form, $quantity_field[0], array(), $lead) ? RGFormsModel::get_lead_field_value($lead, $quantity_field[0]) : 1; + + switch($field["type"]){ + + case "product" : + + //ignore products that have been hidden by conditional logic + $is_hidden = RGFormsModel::is_field_hidden($form, $field, array(), $lead); + if($is_hidden) + continue; + + //if single product, get values from the multiple inputs + if(is_array($lead_value)){ + $product_quantity = sizeof($quantity_field) == 0 && !rgar($field,"disableQuantity") ? rgget($id . ".3", $lead_value) : $quantity; + if(empty($product_quantity)) + continue; + + if(!rgget($id, $products)) + $products[$id] = array(); + + $products[$id]["name"] = $use_admin_label && !rgempty("adminLabel", $field) ? $field["adminLabel"] : $lead_value[$id . ".1"]; + $products[$id]["price"] = rgar($lead_value, $id . ".2"); + $products[$id]["quantity"] = $product_quantity; + } + else if(!empty($lead_value)){ + + if(empty($quantity)) + continue; + + if(!rgar($products,$id)) + $products[$id] = array(); + + if($field["inputType"] == "price"){ + $name = $field["label"]; + $price = $lead_value; + } + else{ + list($name, $price) = explode("|", $lead_value); + } + + $products[$id]["name"] = !$use_choice_text ? $name : RGFormsModel::get_choice_text($field, $name); + $products[$id]["price"] = $price; + $products[$id]["quantity"] = $quantity; + $products[$id]["options"] = array(); + } + + if(isset($products[$id])){ + $options = self::get_product_fields_by_type($form, array("option"), $id); + foreach($options as $option){ + $option_value = RGFormsModel::get_lead_field_value($lead, $option); + $option_label = empty($option["adminLabel"]) ? $option["label"] : $option["adminLabel"]; + if(is_array($option_value)){ + foreach($option_value as $value){ + $option_info = self::get_option_info($value, $option, $use_choice_text); + if(!empty($option_info)) + $products[$id]["options"][] = array("field_label" => rgar($option, "label"), "option_name"=> rgar($option_info, "name"), "option_label" => $option_label . ": " . rgar($option_info, "name"), "price" => rgar($option_info,"price")); + } + } + else if(!empty($option_value)){ + $option_info = self::get_option_info($option_value, $option, $use_choice_text); + $products[$id]["options"][] = array("field_label" => rgar($option, "label"), "option_name"=> rgar($option_info, "name"), "option_label" => $option_label . ": " . rgar($option_info, "name"), "price" => rgar($option_info,"price")); + } + + } + } + break; + } + } + + $shipping_field = self::get_fields_by_type($form, array("shipping")); + $shipping_price = $shipping_name = ""; + $shipping_field_id = ""; + if(!empty($shipping_field) && !RGFormsModel::is_field_hidden($form, $shipping_field[0], array(), $lead)){ + $shipping_price = RGFormsModel::get_lead_field_value($lead, $shipping_field[0]); + $shipping_name = $shipping_field[0]["label"]; + $shipping_field_id = $shipping_field[0]["id"]; + if($shipping_field[0]["inputType"] != "singleshipping"){ + list($shipping_method, $shipping_price) = explode("|", $shipping_price); + $shipping_name = $shipping_field[0]["label"] . " ($shipping_method)"; + } + } + $shipping_price = self::to_number($shipping_price); + + $product_info = array("products" => $products, "shipping" => array("id"=> $shipping_field_id, "name" => $shipping_name, "price" => $shipping_price)); + + $product_info = apply_filters("gform_product_info_{$form["id"]}", apply_filters("gform_product_info", $product_info, $form, $lead), $form, $lead); + + // save static copy of product info (only for "real" entries) + if(!rgempty("id", $lead) && !empty($product_info["products"])){ + gform_update_meta($lead['id'], "gform_product_info_{$use_choice_text}_{$use_admin_label}", $product_info); + } + } + + return $product_info; + } + + public static function get_order_total($form, $lead) { + + $products = self::get_product_fields($form, $lead, false); + return self::get_total($products); + } + + public static function get_total($products) { + + $total = 0; + foreach($products["products"] as $product){ + + $price = self::to_number($product["price"]); + if(is_array(rgar($product,"options"))){ + foreach($product["options"] as $option){ + $price += self::to_number($option["price"]); + } + } + $subtotal = floatval($product["quantity"]) * $price; + $total += $subtotal; + + } + + $total += floatval($products["shipping"]["price"]); + + return $total; + } + + public static function get_option_info($value, $option, $use_choice_text){ + if(empty($value)) + return array(); + + list($name, $price) = explode("|", $value); + if($use_choice_text) + $name = RGFormsModel::get_choice_text($option, $name); + + return array("name" => $name, "price" => $price); + } + + public static function gform_do_shortcode($content){ + + $is_ajax = false; + $forms = GFFormDisplay::get_embedded_forms($content, $is_ajax); + + foreach($forms as $form){ + if( headers_sent() ) { + GFFormDisplay::print_form_scripts( $form, $is_ajax ); + } else { + GFFormDisplay::enqueue_form_scripts( $form, $is_ajax ); + } + } + + return do_shortcode($content); + } + + public static function has_akismet(){ + return function_exists('akismet_http_post'); + } + + public static function akismet_enabled($form_id) { + + if(!self::has_akismet()) + return false; + + // if no option is set, leave akismet enabled; otherwise, use option value true/false + $enabled_by_setting = get_option('rg_gforms_enable_akismet') === false ? true : get_option('rg_gforms_enable_akismet') == true; + $enabled_by_filter = apply_filters("gform_akismet_enabled_$form_id", apply_filters("gform_akismet_enabled", $enabled_by_setting)); + + return $enabled_by_filter; + + } + + public static function is_akismet_spam($form, $lead){ + + global $akismet_api_host, $akismet_api_port; + + $fields = self::get_akismet_fields($form, $lead); + + //Submitting info do Akismet + $response = akismet_http_post($fields, $akismet_api_host, '/1.1/comment-check', $akismet_api_port ); + $is_spam = trim(rgar($response, 1)) == "true"; + + return $is_spam; + } + + public static function mark_akismet_spam($form, $lead, $is_spam){ + + global $akismet_api_host, $akismet_api_port; + + $fields = self::get_akismet_fields($form, $lead); + $as = $is_spam ? "spam" : "ham"; + + //Submitting info do Akismet + akismet_http_post($fields, $akismet_api_host, '/1.1/submit-'.$as, $akismet_api_port ); + } + + private static function get_akismet_fields($form, $lead){ + //Gathering Akismet information + $akismet_info = array(); + $akismet_info['comment_type'] = 'gravity_form'; + $akismet_info['comment_author'] = self::get_akismet_field("name", $form, $lead); + $akismet_info['comment_author_email'] = self::get_akismet_field("email", $form, $lead); + $akismet_info['comment_author_url'] = self::get_akismet_field("website", $form, $lead); + $akismet_info['comment_content'] = self::get_akismet_field("textarea", $form, $lead); + $akismet_info['contact_form_subject'] = $form["title"]; + $akismet_info['comment_author_IP'] = $lead["ip"]; + $akismet_info['permalink'] = $lead["source_url"]; + $akismet_info['user_ip'] = preg_replace( '/[^0-9., ]/', '', $lead["ip"] ); + $akismet_info['user_agent'] = $lead["user_agent"]; + $akismet_info['referrer'] = is_admin() ? "" : $_SERVER['HTTP_REFERER']; + $akismet_info['blog'] = get_option('home'); + + $akismet_info = apply_filters("gform_akismet_fields_{$form["id"]}", apply_filters("gform_akismet_fields", $akismet_info, $form, $lead), $form, $lead); + + return http_build_query($akismet_info); + } + + private static function get_akismet_field($field_type, $form, $lead){ + $fields = GFCommon::get_fields_by_type($form, array($field_type)); + if(empty($fields)) + return ""; + + $value = RGFormsModel::get_lead_field_value($lead, $fields[0]); + switch($field_type){ + case "name" : + $value = GFCommon::get_lead_field_display($fields[0], $value); + break; + } + + return $value; + } + + public static function get_other_choice_value(){ + $value = apply_filters('gform_other_choice_value', __("Other", "gravityforms")); + return $value; + } + + public static function get_browser_class() { + global $is_lynx, $is_gecko, $is_IE, $is_opera, $is_NS4, $is_safari, $is_chrome, $is_iphone, $post; + + $classes = array(); + + //adding browser related class + if($is_lynx) $classes[] = 'gf_browser_lynx'; + else if($is_gecko) $classes[] = 'gf_browser_gecko'; + else if($is_opera) $classes[] = 'gf_browser_opera'; + else if($is_NS4) $classes[] = 'gf_browser_ns4'; + else if($is_safari) $classes[] = 'gf_browser_safari'; + else if($is_chrome) $classes[] = 'gf_browser_chrome'; + else if($is_IE) $classes[] = 'gf_browser_ie'; + else $classes[] = 'gf_browser_unknown'; + + + //adding IE version + if($is_IE){ + if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6') !== false) + $classes[] = 'gf_browser_ie6'; + else if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 7') !== false) + $classes[] = 'gf_browser_ie7'; + if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 8') !== false) + $classes[] = 'gf_browser_ie8'; + if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 9') !== false) + $classes[] = 'gf_browser_ie9'; + } + + if($is_iphone) $classes[] = 'gf_browser_iphone'; + + return implode(" " , $classes); + } + + public static function create_post($form, &$lead) { + $disable_post = apply_filters("gform_disable_post_creation_{$form["id"]}", apply_filters("gform_disable_post_creation", false, $form, $lead), $form, $lead); + $post_id = 0; + if(!$disable_post){ + //creates post if the form has any post fields + $post_id = RGFormsModel::create_post($form, $lead); + } + + return $post_id; + } + + public static function evaluate_conditional_logic($logic, $form, $lead) { + + if(!$logic || !is_array(rgar($logic,"rules"))) + return true; + + $entry_meta_keys = array_keys(GFFormsModel::get_entry_meta($form["id"])); + $match_count = 0; + if(is_array($logic["rules"])){ + 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"]);; + } 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); + } + + if($is_value_match) + $match_count++; + + } + } + + $do_action = ($logic["logicType"] == "all" && $match_count == sizeof($logic["rules"]) ) || ($logic["logicType"] == "any" && $match_count > 0); + return $do_action; + } + + public static function get_card_types(){ + $cards = array ( + + array ( 'name' => 'American Express', + 'slug' => 'amex', + 'lengths' => '15', + 'prefixes' => '34,37', + 'checksum' => true + ), + array ( 'name' => 'Discover', + 'slug' => 'discover', + 'lengths' => '16', + 'prefixes' => '6011,622,64,65', + 'checksum' => true + ), + array ( 'name' => 'MasterCard', + 'slug' => 'mastercard', + 'lengths' => '16', + 'prefixes' => '51,52,53,54,55', + 'checksum' => true + ), + array ( 'name' => 'Visa', + 'slug' => 'visa', + 'lengths' => '13,16', + 'prefixes' => '4,417500,4917,4913,4508,4844', + 'checksum' => true + ), + array ( 'name' => 'JCB', + 'slug' => 'jcb', + 'lengths' => '16', + 'prefixes' => '35', + 'checksum' => true + ), + array ( 'name' => 'Maestro', + 'slug' => 'maestro', + 'lengths' => '12,13,14,15,16,18,19', + 'prefixes' => '5018,5020,5038,6304,6759,6761', + 'checksum' => true + ) + + ); + + $cards = apply_filters("gform_creditcard_types", $cards); + + return $cards; + } + + public static function get_card_type($number){ + + //removing spaces from number + $number = str_replace (' ', '', $number); + + if(empty($number)) + return false; + + $cards = self::get_card_types(); + + $matched_card = false; + foreach($cards as $card){ + if(self::matches_card_type($number, $card)){ + $matched_card = $card; + break; + } + } + + if($matched_card && $matched_card["checksum"] && !self::is_valid_card_checksum($number)) + $matched_card = false; + + return $matched_card ? $matched_card : false; + + } + + private static function matches_card_type($number, $card){ + + //checking prefix + $prefixes = explode(',',$card['prefixes']); + $matches_prefix = false; + foreach($prefixes as $prefix){ + if(preg_match("|^{$prefix}|", $number)){ + $matches_prefix = true; + break; + } + } + + //checking length + $lengths = explode(',',$card['lengths']); + $matches_length = false; + foreach($lengths as $length){ + if(strlen($number) == absint($length)){ + $matches_length = true; + break; + } + } + + return $matches_prefix && $matches_length; + + } + + private static function is_valid_card_checksum($number){ + $checksum = 0; + $num = 0; + $multiplier = 1; + + // Process each character starting at the right + for ($i = strlen($number) - 1; $i >= 0; $i--) { + + //Multiply current digit by multiplier (1 or 2) + $num = $number{$i} * $multiplier; + + // If the result is in greater than 9, add 1 to the checksum total + if ($num >= 10) { + $checksum++; + $num -= 10; + } + + //Update checksum + $checksum += $num; + + //Update multiplier + $multiplier = $multiplier == 1 ? 2 : 1; + } + + return $checksum % 10 == 0; + + } + + public static function is_wp_version($min_version){ + return !version_compare(get_bloginfo("version"), "{$min_version}.dev1", '<'); + } + + public static function add_categories_as_choices($field, $value) { + + $choices = $inputs = array(); + $is_post = isset($_POST["gform_submit"]); + $has_placeholder = rgar($field, 'categoryInitialItemEnabled') && RGFormsModel::get_input_type($field) == 'select'; + + if($has_placeholder) + $choices[] = array('text' => rgar($field, 'categoryInitialItem'), 'value' => '', 'isSelected' => true); + + $display_all = rgar($field, "displayAllCategories"); + + $args = array('hide_empty' => false, 'orderby' => 'name'); + + if(!$display_all){ + foreach($field["choices"] as $field_choice_to_include){ + $args["include"][] = $field_choice_to_include["value"]; + } + } + + $args = apply_filters("gform_post_category_args_{$field["id"]}", apply_filters("gform_post_category_args", $args, $field), $field); + $terms = get_terms('category', $args); + + $terms_copy = unserialize(serialize($terms)); // deep copy the terms to avoid repeating GFCategoryWalker on previously cached terms. + $walker = new GFCategoryWalker(); + $categories = $walker->walk($terms_copy, 0, array(0)); // 3rd parameter prevents notices triggered by $walker::display_element() function which checks $args[0] + + foreach($categories as $category) { + if($display_all) { + $selected = $value == $category->term_id || + ( + empty($value) && + get_option('default_category') == $category->term_id && + RGFormsModel::get_input_type($field) == 'select' && // only preselect default category on select fields + !$is_post && + !$has_placeholder + ); + $choices[] = array('text' => $category->name, 'value' => $category->term_id, 'isSelected' => $selected); + } else { + foreach($field["choices"] as $field_choice){ + if($field_choice["value"] == $category->term_id){ + $choices[] = array('text' => $category->name, 'value' => $category->term_id); + break; + } + } + } + } + + if(empty($choices)) + $choices[] = array('text' => 'You must select at least one category.', 'value' => ''); + + $choice_number = 1; + foreach($choices as $choice) { + + if($choice_number % 10 == 0) //hack to skip numbers ending in 0. so that 5.1 doesn't conflict with 5.10 + $choice_number++; + + $input_id = $field["id"] . '.' . $choice_number; + $inputs[] = array('id' => $input_id, 'label' => $choice['text'], 'name' => ''); + $choice_number++; + } + + $field['choices'] = $choices; + + $form_id = IS_ADMIN ? rgget("id") : rgar($field,"formId"); + + $field['choices'] = apply_filters("gform_post_category_choices", $field["choices"], $field, $form_id); + $field['choices'] = apply_filters("gform_post_category_choices_{$form_id}_{$field["id"]}", $field["choices"], $field, $form_id); + + if(RGFormsModel::get_input_type($field) == 'checkbox') + $field['inputs'] = $inputs; + + return $field; + } + + public static function prepare_post_category_value($value, $field, $mode = 'entry_detail') { + + if(!is_array($value)) + $value = explode(',', $value); + + $cat_names = array(); + $cat_ids = array(); + foreach($value as $cat_string) { + $ary = explode(":", $cat_string); + $cat_name = count($ary) > 0 ? $ary[0] : ""; + $cat_id = count($ary) > 1 ? $ary[1] : $ary[0]; + + if(!empty($cat_name)) + $cat_names[] = $cat_name; + + if(!empty($cat_id)) + $cat_ids[] = $cat_id; + } + + sort($cat_names); + + switch($mode) { + case 'entry_list': + $value = self::implode_non_blank(', ', $cat_names); + break; + case 'entry_detail': + $value = RGFormsModel::get_input_type($field) == 'checkbox' ? $cat_names : self::implode_non_blank(', ', $cat_names); + break; + case 'conditional_logic': + $value = array_values($cat_ids); + break; + } + + return $value; + } + + public static function calculate($field, $form, $lead) { + + $formula = (string) apply_filters( 'gform_calculation_formula', rgar( $field, 'calculationFormula' ), $field, $form, $lead ); + + // replace multiple spaces and new lines with single space + // @props: http://stackoverflow.com/questions/3760816/remove-new-lines-from-string + $formula = trim( preg_replace( '/\s+/', ' ', $formula ) ); + + preg_match_all( '/{[^{]*?:(\d+(\.\d+)?)(:(.*?))?}/mi', $formula, $matches, PREG_SET_ORDER ); + + if( is_array( $matches ) ) { + foreach( $matches as $match ) { + + list( $text, $input_id ) = $match; + $value = self::get_calculation_value( $input_id, $form, $lead); + $formula = str_replace( $text, $value, $formula); + + } + } + + $result = preg_match( '/^[0-9 -\/*\(\)]+$/', $formula ) ? eval( "return {$formula};" ) : false; + + return $result; + } + + public static function round_number($number, $rounding ){ + if(is_numeric($rounding) && $rounding >= 0){ + $number = round($number, $rounding); + } + return $number; + } + + public static function get_calculation_value($field_id, $form, $lead) { + + $filters = array('price', 'value', ''); + $value = false; + + foreach($filters as $filter) { + if (is_numeric($value)){ + //value found, exit loop + break; + } + $value = GFCommon::to_number(GFCommon::replace_variables("{:{$field_id}:$filter}", $form, $lead)); + } + + if(!$value || !is_numeric($value)) + $value = 0; + + return $value; + } + + public static function conditional_shortcode($attributes, $content = null) { + + extract(shortcode_atts(array( + 'merge_tag' => '', + 'condition' => '', + 'value' => '' + ), $attributes)); + + return RGFormsModel::matches_operation($merge_tag, $value, $condition) ? do_shortcode($content) : ''; + + } + + public static function is_valid_for_calcuation($field) { + + $supported_input_types = array('text', 'select', 'number', 'checkbox', 'radio', 'hidden', 'singleproduct', 'price', 'hiddenproduct', 'calculation', 'singleshipping'); + $unsupported_field_types = array('category'); + $input_type = RGFormsModel::get_input_type($field); + + return in_array($input_type, $supported_input_types) && !in_array($input_type, $unsupported_field_types); + } + + public static function log_error($message){ + if(class_exists("GFLogging")) + { + GFLogging::include_logger(); + GFLogging::log_message("gravityforms", $message, KLogger::ERROR); + } + } + + public static function log_debug($message){ + if(class_exists("GFLogging")) + { + GFLogging::include_logger(); + GFLogging::log_message("gravityforms", $message, KLogger::DEBUG); + } + } + + public static function echo_if($condition, $text) { + + switch($text) { + case 'checked': + $text = 'checked="checked"'; + break; + case 'selected': + $text = 'selected="selected"'; + } + + echo $condition ? $text : ''; + } + + public static function gf_global($echo = true) { + + require_once(GFCommon::get_base_path() . '/currency.php'); + + $gf_global = array(); + $gf_global["gf_currency_config"] = RGCurrency::get_currency(GFCommon::get_currency()); + $gf_global["base_url"] = GFCommon::get_base_url(); + $gf_global["number_formats"] = array(); + $gf_global["spinnerUrl"] = GFCommon::get_base_url() . '/images/spinner.gif'; + + $gf_global_json = 'var gf_global = ' . json_encode($gf_global) . ';'; + + if(!$echo) + return $gf_global_json; + + echo $gf_global_json; + } + + public static function gf_vars($echo = true) { + if(!class_exists("RGCurrency")) + require_once("currency.php"); + + $gf_vars = array(); + $gf_vars["active"] = __("Active", "gravityforms"); + $gf_vars["inactive"] = __("Inactive", "gravityforms"); + $gf_vars["save"] = __("Save", "gravityforms"); + $gf_vars["update"] = __("Update", "gravityforms"); + $gf_vars["previousLabel" ] = __("Previous", "gravityforms"); + $gf_vars["selectFormat" ] = __("Select a format", "gravityforms"); + $gf_vars["editToViewAll" ] = __("5 of %d items shown. Edit field to view all", "gravityforms"); + $gf_vars["enterValue" ] = __("Enter a value", "gravityforms"); + $gf_vars["formTitle" ] = __("Untitled Form", "gravityforms"); + $gf_vars["formDescription" ] = __("We would love to hear from you! Please fill out this form and we will get in touch with you shortly.", "gravityforms"); + $gf_vars["formConfirmationMessage" ] = __("Thanks for contacting us! We will get in touch with you shortly.", "gravityforms"); + $gf_vars["buttonText" ] = __("Submit", "gravityforms"); + $gf_vars["loading" ] = __("Loading...", "gravityforms"); + $gf_vars["thisFieldIf"] = __('this field if', 'gravityforms'); + $gf_vars["thisPage"] = __("this page", "gravityforms"); + $gf_vars["thisFormButton"] = __('this form button', 'gravityforms'); + $gf_vars["show"] = __('Show', 'gravityforms'); + $gf_vars["hide"] = __('Hide', 'gravityforms'); + $gf_vars["all"] = __('All', 'gravityforms'); + $gf_vars["any"] = __('Any', 'gravityforms'); + $gf_vars["ofTheFollowingMatch"] = __('of the following match:', 'gravityforms'); + $gf_vars["is"] = __('is', 'gravityforms'); + $gf_vars["isNot"] = __('is not', 'gravityforms'); + $gf_vars["greaterThan"] = __('greater than', 'gravityforms'); + $gf_vars["lessThan"] = __('less than', 'gravityforms'); + $gf_vars["contains"] = __('contains', 'gravityforms'); + $gf_vars["startsWith"] = __('starts with', 'gravityforms'); + $gf_vars["endsWith"] = __('ends with', 'gravityforms'); + + $gf_vars["thisConfirmation"] = __('Use this confirmation if', 'gravityforms'); + $gf_vars["thisNotification"] = __('Send this notification if', 'gravityforms'); + $gf_vars["confirmationSave"] = __('Save', 'gravityforms'); + $gf_vars["confirmationSaving"] = __('Saving...', 'gravityforms'); + $gf_vars["confirmationAreYouSure"] = __('Are you sure you wish to cancel these changes?', 'gravityforms'); + $gf_vars["confirmationIssueSaving"] = __('There was an issue saving this confirmation.', 'gravityforms'); + $gf_vars["confirmationConfirmDelete"] = __('Are you sure you wish to delete this confirmation?', 'gravityforms'); + $gf_vars["confirmationIssueDeleting"] = __('There was an issue deleting this confirmation.', 'gravityforms'); + $gf_vars["confirmationConfirmDiscard"] = __('There are unsaved changes to the current confirmation. Would you like to discard these changes?', 'gravityforms'); + $gf_vars["confirmationDefaultName"] = __('Untitled Confirmation', 'gravityforms'); + $gf_vars["confirmationDefaultMessage"] = __('Thanks for contacting us! We will get in touch with you shortly.', 'gravityforms'); + $gf_vars["confirmationInvalidPageSelection"] = __('Please select a page.', "gravityforms"); + $gf_vars["confirmationInvalidRedirect"] = __('Please enter a URL.', "gravityforms"); + $gf_vars["confirmationInvalidName"] = __('Please enter a confirmation name.', "gravityforms"); + + $gf_vars["conditionalLogicDependency"] = __('This form contains conditional logic dependent upon this field. Are you sure you want to delete this field? \'OK\' to delete, \'Cancel\' to abort.', 'gravityforms'); + $gf_vars["conditionalLogicDependencyChoice"] = __('This form contains conditional logic dependent upon this choice. Are you sure you want to delete this choice? \'OK\' to delete, \'Cancel\' to abort.', 'gravityforms'); + $gf_vars["conditionalLogicDependencyChoiceEdit"] = __('This form contains conditional logic dependent upon this choice. Are you sure you want to modify this choice? \'OK\' to delete, \'Cancel\' to abort.', 'gravityforms'); + + $gf_vars["mergeTagsTooltip"] = __('
    Merge Tags
    Merge tags allow you to dynamically populate submitted field values in your form content wherever this merge tag icon is present.', 'gravityforms'); + + $gf_vars["baseUrl"] = GFCommon::get_base_url(); + $gf_vars["gf_currency_config"] = RGCurrency::get_currency(GFCommon::get_currency()); + $gf_vars["otherChoiceValue"] = GFCommon::get_other_choice_value(); + $gf_vars["isFormTrash"] = false; + $gf_vars["currentlyAddingField"] = false; + + $gf_vars["addFieldFilter"] = __("Add a condition", "gravityforms"); + $gf_vars["removeFieldFilter"] = __("Remove a condition", "gravityforms"); + $gf_vars["filterAndAny"] = __("Include results if {0} match:", "gravityforms"); + + if(is_admin() && rgget('id')) { + $form = RGFormsModel::get_form_meta(rgget('id')); + $gf_vars["mergeTags"] = GFCommon::get_merge_tags($form['fields'], '', false); + } + + $gf_vars_json = 'var gf_vars = ' . json_encode($gf_vars) . ';'; + + if(!$echo){ + return $gf_vars_json; + } + else { + echo $gf_vars_json; + } + } + + public static function is_bp_active() { + return defined('BP_VERSION') ? true : false; + } + + public static function add_message($message, $is_error = false) { + if($is_error) { + self::$errors[] = $message; + } else { + self::$messages[] = $message; + } + } + + public static function add_error_message($message) { + self::add_message($message, true); + } + + public static function display_admin_message($errors = false, $messages = false) { + + if(!$errors) + $errors = self::$errors; + + if(!$messages) + $messages = self::$messages; + + $errors = apply_filters('gform_admin_error_messages', $errors); + $messages = apply_filters('gform_admin_messages', $messages); + + if(!empty($errors)) { ?> +
    + 1) { ?> + + +

    + +
    + +
    + 1) { ?> + + +

    + +
    + ' . self::gf_vars(false) . ''; + } + } + + public static function maybe_add_leading_zero($value){ + $first_char = GFCommon::safe_substr($value, 0, 1, 'utf-8'); + if(in_array($first_char, array(".", ","))) + $value = "0" . $value; + return $value; + } + + // used by the gfFieldFilterUI() jQuery plugin + public static function get_field_filter_settings($form) { + + $all_fields = $form["fields"]; + + // set up filters + $fields = $all_fields; + $exclude_types = array("rank", "page", "html"); + + $operators_by_field_type = array( + "default" => array("is", "isnot", ">", "<"), + "checkbox" => array("is"), + "multiselect" => array("contains"), + "number" => array("is", "isnot", ">", "<"), + "likert" => array("is", "isnot"), + "list" => array("contains") + ); + + for ($i = 0; $i < count($all_fields); $i++) { + $field_type = GFFormsmodel::get_input_type($all_fields[$i]); + if (in_array($field_type, $exclude_types)) + unset($fields[$i]); + } + $fields = array_values($fields); + + $field_filters = array( + array( + "key"=> "0", + "text" => __("Any form field", "gravityforms"), + "operators" => array("contains", "is") + ) + ); + + foreach ($fields as $field) { + + $field_type = GFFormsModel::get_input_type($field); + + $operators = isset($operators_by_field_type[$field_type]) ? $operators_by_field_type[$field_type] : $operators_by_field_type["default"]; + if (!isset($field["choices"]) && !in_array("contains", $operators)) + $operators[] = "contains"; + + $field_filter = array(); + $key = $field["id"]; + if ($field_type == "likert" && rgar($field, "gsurveyLikertEnableMultipleRows")) { + // multi-row likert fields + $field_filter["key"] = $key; + $field_filter["group"] = true; + $field_filter["text"] = GFFormsModel::get_label($field); + $sub_filters = array(); + $rows = rgar($field, "gsurveyLikertRows"); + foreach ($rows as $row) { + $sub_filter = array(); + $sub_filter["key"] = $key . "|" . rgar($row, "value"); + $sub_filter["text"] = rgar($row, "text"); + $sub_filter["type"] = "field"; + $sub_filter["preventMultiple"] = false; + $sub_filter["operators"] = $operators; + $sub_filter["values"] = $field["choices"]; + $sub_filters[] = $sub_filter; + } + $field_filter["filters"] = $sub_filters; + } elseif ($field_type == "name" && rgar($field, "nameFormat") == "" || $field_type == "address") { + // standard two input name field + $field_filter["key"] = $key; + $field_filter["group"] = true; + $field_filter["text"] = GFFormsModel::get_label($field); + $sub_filters = array(); + $inputs = rgar($field, "inputs"); + foreach ($inputs as $input) { + $sub_filter = array(); + $sub_filter["key"] = rgar($input, "id"); + $sub_filter["text"] = rgar($input, "label"); + $sub_filter["preventMultiple"] = false; + $sub_filter["operators"] = $operators; + $sub_filters[] = $sub_filter; + } + $field_filter["filters"] = $sub_filters; + } else { + $field_filter["key"] = $key; + $field_filter["preventMultiple"] = false; + $field_filter["text"] = GFFormsModel::get_label($field); + + $field_filter["operators"] = $operators; + + if (isset($field["choices"])) + $field_filter["values"] = $field["choices"]; + + + } + $field_filters[] = $field_filter; + + } + $form_id = $form["id"]; + $entry_meta_filters = self::get_entry_meta_filter_settings($form_id); + $field_filters = array_merge($field_filters, $entry_meta_filters); + $field_filters = array_values($field_filters); // reset the numeric keys in case some filters have been unset + $info_filters = self::get_entry_info_filter_settings(); + $field_filters = array_merge($field_filters, $info_filters); + $field_filters = array_values($field_filters); + return $field_filters; + } + + public static function get_entry_info_filter_settings() { + $settings = array(); + $info_columns = self::get_entry_info_filter_columns(); + foreach($info_columns as $key => $info_column){ + $info_column["key"] = $key; + $info_column["preventMultiple"] = false; + $settings[] = $info_column; + } + + return $settings; + } + + public static function get_entry_info_filter_columns($get_users = true){ + $account_choices = array(); + if($get_users){ + $args = apply_filters("gform_filters_get_users", array("number" => 200)); + $accounts = get_users($args); + $account_choices = array(); + foreach ($accounts as $account) { + $account_choices[] = array("text" => $account->user_login, "value" => $account->ID); + } + } + return array( + "entry_id" => array( + "text" => __("Entry ID", "gravityforms"), + "operators" => array( "is", "isnot", ">", "<") + ), + "date_created" => array( + "text" => __("Entry Date", "gravityforms"), + "operators" => array( "is", ">", "<"), + "placeholder" => __("yyyy-mm-dd", "gravityforms") + ), + "is_starred" => array( + "text" => __("Starred", "gravityforms"), + "operators" => array( "is", "isnot"), + "values" => array( + array( + "text" => "Yes", + "value" => "1" + ), + array( + "text" => "No", + "value" => "0" + ) + ) + ), + "ip" => array( + "text" => __("IP Address", "gravityforms"), + "operators" => array( "is", "isnot", ">", "<", "contains") + ), + "source_url" => array( + "text" => __("Source URL", "gravityforms"), + "operators" => array( "is", "isnot", ">", "<", "contains") + ), + "payment_status" => array( + "text" => __("Payment Status", "gravityforms"), + "operators" => array( "is", "isnot"), + "values" => array( + array( + "text" => "Approved", + "value" => "Approved" + ), + array( + "text" => "Failed", + "value" => "Failed" + ), + array( + "text" => "Active", + "value" => "Active" + ), + array( + "text" => "Cancelled", + "value" => "Cancelled" + ) + ) + ), + "payment_date" => array( + "text" => __("Payment Date", "gravityforms"), + "operators" => array( "is", "isnot", ">", "<") + ), + "payment_amount" => array( + "text" => __("Payment Amount", "gravityforms"), + "operators" => array( "is", "isnot", ">", "<", "contains") + ), + "transaction_id" => array( + "text" => __("Transaction ID", "gravityforms"), + "operators" => array( "is", "isnot", ">", "<", "contains") + ), + "created_by" => array( + "text" => __("User", "gravityforms"), + "operators" => array( "is", "isnot"), + "values" => $account_choices + ) + ); + } + + public static function get_entry_meta_filter_settings($form_id) { + $filters = array(); + $entry_meta = GFFormsModel::get_entry_meta($form_id); + if (empty($entry_meta)) + return $filters; + + foreach ($entry_meta as $key => $meta) { + if (isset($meta["filter"])) { + $filter = array(); + $filter["key"] = $key; + $filter["preventMultiple"] = isset($meta["filter"]["preventMultiple"]) ? $meta["filter"]["preventMultiple"] : false; + $filter["text"] = rgar($meta, "label"); + $filter["operators"] = isset($meta["filter"]["operators"]) ? $meta["filter"]["operators"] : array("is", "isnot"); + if (isset($meta["filter"]["choices"])) + $filter["values"] = $meta["filter"]["choices"]; + $filters[] = $filter; + } + + } + + return $filters; + } + + + public static function get_field_filters_from_post(){ + $field_filters = array(); + $filter_fields = rgpost("f"); + if (is_array($filter_fields)) { + $filter_operators = rgpost("o"); + $filter_values = rgpost("v"); + for ($i = 0; $i < count($filter_fields); $i++) { + $field_filter = array(); + $key = $filter_fields[$i]; + if("entry_id" == $key){ + $key = "id"; + } + $operator = $filter_operators[$i]; + $val = $filter_values[$i]; + $strpos_row_key = strpos($key, "|"); + if ($strpos_row_key !== false) { //multi-row likert + $key_array = explode("|", $key); + $key = $key_array[0]; + $val = $key_array[1] . ":" . $val; + } + $field_filter["key"] = $key; + $field_filter["operator"] = $operator; + $field_filter["value"] = $val; + $field_filters[] = $field_filter; + } + } + $field_filters["mode"] = rgpost("mode"); + return $field_filters; + } + + public static function has_multifile_fileupload_field($form){ + $fileupload_fields = GFCommon::get_fields_by_type($form, array("fileupload", "post_custom_field")); + if(is_array($fileupload_fields)){ + foreach($fileupload_fields as $field){ + if(rgar($field, "multipleFiles")) + return true; + } + } + return false; + } + + public static function localize_gform_gravityforms_multifile(){ + wp_localize_script( 'gform_gravityforms', 'gform_gravityforms', array( + 'strings' => array( + 'invalid_file_extension' => __("This type of file is not allowed. Must be one of the following: ", "gravityforms" ), + 'delete_file' => __("Delete this file", "gravityforms"), + 'in_progress' => __("in progress", "gravityforms"), + 'file_exceeds_limit' => __("File exceeds size limit", "gravityforms"), + 'illegal_extension' => __("This type of file is not allowed." , "gravityforms"), + "max_reached" => __("Maximum number of files reached", "gravityforms"), + "unknown_error" => __("There was a problem while saving the file on the server", "gravityforms"), + "currently_uploading" => __("Please wait for the uploading to complete", "gravityforms"), + "cancel" => __("Cancel", "gravityforms"), + "cancel_upload" => __("Cancel this upload", "gravityforms"), + "cancelled" => __("Cancelled", "gravityforms") + ), + 'vars' => array( + 'images_url' => GFCommon::get_base_url() . "/images" + ) + ) ); + } + + public static function safe_strlen($string){ + + if(function_exists("mb_strlen")) + return mb_strlen($string); + else + return strlen($string); + + } + + public static function safe_substr($string, $start, $length = null){ + if(function_exists("mb_substr")) + return mb_substr($string, $start, $length); + else + return substr($string, $start, $length); + } + + /** + * Reliablty compare floats. + * @param [float] $float1 + * @param [float] $float2 + * @param [string] $operator Supports: '<', '<=', '>', '>=', '==', '=', '!=' + * @return [bool] + */ + public static function compare_floats( $float1, $float2, $operator ) { + + $epsilon = 0.00001; + $is_equal = abs( floatval( $float1 ) - floatval( $float2 ) ) < $epsilon; + $is_greater = floatval( $float1 ) > floatval( $float2 ); + $is_less = floatval( $float1 ) < floatval( $float2 ); + + switch( $operator ) { + case '<': + return $is_less; + case '<=': + return $is_less || $is_equal; + case '>' : + return $is_greater; + case '>=': + return $is_greater || $is_equal; + case '==': + case '=': + return $is_equal; + case '!=': + return ! $is_equal; + } + + } + +} + +class GFCategoryWalker extends Walker { + /** + * @see Walker::$tree_type + * @since 2.1.0 + * @var string + */ + var $tree_type = 'category'; + + /** + * @see Walker::$db_fields + * @since 2.1.0 + * @todo Decouple this + * @var array + */ + var $db_fields = array ('parent' => 'parent', 'id' => 'term_id'); + + /** + * @see Walker::start_el() + * @since 2.1.0 + * + * @param string $output Passed by reference. Used to append additional content. + * @param object $category Category data object. + * @param int $depth Depth of category. Used for padding. + * @param array $args Uses 'selected' and 'show_count' keys, if they exist. + */ + function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0) { + //$pad = str_repeat(' ', $depth * 3); + $pad = str_repeat('─', $depth); + if(!empty($pad)) + $pad .= " "; + $object->name = "{$pad}{$object->name}"; + $output[] = $object; + } +} + +/** + * + * Notes: + * 1. The WordPress Transients API does not support boolean + * values so boolean values should be converted to integers + * or arrays before setting the values as persistent. + * + * 2. The transients API only deletes the transient from the database + * when the transient is accessed after it has expired. WordPress doesn't + * do any garbage collection of transients. + * + */ +class GFCache { + private static $_transient_prefix = "GFCache_"; + private static $_cache = array(); + + public static function get($key, &$found = null) { + global $blog_id; + if (is_multisite()) + $key = $blog_id . ':' . $key; + + if (isset(self::$_cache[$key])) { + $found = true; + $data = rgar(self::$_cache[$key], "data"); + + return $data; + } + + $data = self::get_transient($key); + + if (false === ($data)) { + $found = false; + + return false; + } else { + self::$_cache[$key] = array("data" => $data, "is_persistent" => true); + $found = true; + + return $data; + } + + } + + public static function set($key, $data, $is_persistent = false, $expiration = 0) { + global $blog_id; + $success = true; + + if (is_multisite()) + $key = $blog_id . ':' . $key; + + if ($is_persistent) + $success = self::set_transient($key, $data, $expiration); + + self::$_cache[$key] = array("data" => $data, "is_persistent" => $is_persistent); + + return $success; + } + + public static function delete($key) { + global $blog_id; + $success = true; + + if (is_multisite()) + $key = $blog_id . ':' . $key; + + if (isset(self::$_cache[$key])) { + if (self::$_cache[$key]["is_persistent"]) + $success = self::delete_transient($key); + + unset(self::$_cache[$key]); + } else { + $success = self::delete_transient($key); + + } + + return $success; + } + + public static function flush($flush_persistent = false) { + global $wpdb; + + self::$_cache = array(); + + if(false === $flush_persistent) + return true; + + if (is_multisite()) { + $sql = " + DELETE FROM $wpdb->sitemeta + WHERE meta_key LIKE '_site_transient_timeout_GFCache_%' OR + meta_key LIKE '_site_transient_GFCache_%' + "; + } else { + $sql = " + DELETE FROM $wpdb->options + WHERE option_name LIKE '_transient_timeout_GFCache_%' OR + option_name LIKE '_transient_GFCache_%' + "; + + } + $rows_deleted = $wpdb->query($sql); + + $success = $rows_deleted !== false ? true : false; + + return $success; + } + + private static function delete_transient($key) { + $key = self::$_transient_prefix . wp_hash($key); + if (is_multisite()) + $success = delete_site_transient($key); + else + $success = delete_transient($key); + + return $success; + } + + private static function set_transient($key, $data, $expiration) { + $key = self::$_transient_prefix . wp_hash($key); + if (is_multisite()) + $success = set_site_transient($key, $data, $expiration); + else + $success = set_transient($key, $data, $expiration); + + return $success; + } + + private static function get_transient($key) { + $key = self::$_transient_prefix . wp_hash($key); + if (is_multisite()) + $data = get_site_transient($key); + else + $data = get_transient($key); + + return $data; + } + } \ No newline at end of file diff --git a/css/admin.css b/css/admin.css index 85dac72..a0be5c1 100644 --- a/css/admin.css +++ b/css/admin.css @@ -1400,6 +1400,16 @@ div.detail-note-content p { line-height: 1.8; } +div.detail-note-content.gforms_note_success{ + background-color: #ECFCDE; + border: 1px solid #A7C886; + +} +div.detail-note-content.gforms_note_error{ + background-color: #FFEBE8; + border: 1px solid #CC0000; + +} /* edit details form styles ------------------------------------------------------*/ #namediv_admin { @@ -2584,13 +2594,6 @@ div#gravity-title-icon { background-position: 0 -350px; } -div#publishing-action { - float: none !important; - text-align: left !important; - clear: both; - margin: 14px 0 5px -} - div#major-publishing-actions { clear: both; } diff --git a/css/datepicker.css b/css/datepicker.css index a703bd4..ba0cf92 100644 --- a/css/datepicker.css +++ b/css/datepicker.css @@ -3,7 +3,7 @@ Gravity Forms Date Picker Styles http: //www.gravityforms.com -updated: October 15, 2013 11:05 AM +updated: January 31, 2014 3:32 PM Customized styles for the jQuery UI Datepicker 1.9.2 copyright 2012 jQuery Foundation and other contributors @@ -12,7 +12,7 @@ http://jquery.org/license some styles courtesty of http://www.hongkiat.com/ Gravity Forms is a Rocketgenius project -copyright 2013 Rocketgenius Inc. +copyright 2008 - 2014 Rocketgenius Inc. http: //www.rocketgenius.com NOTE: DO NOT EDIT THIS FILE! MAKE ANY MODIFICATIONS IN YOUR @@ -51,7 +51,7 @@ to no. background-color: #666; /* set the header background color */ color: #e0e0e0; font-weight: bold; - -webkit-box-shadow: inset 0px 1px 1px 0px rgba(250, 250, 250, 2); + -webkit-box-shadow: inset 0px 1px 1px 0px rgba(250, 250, 250, .2); -moz-box-shadow: inset 0px 1px 1px 0px rgba(250, 250, 250, .2); box-shadow: inset 0px 1px 1px 0px rgba(250, 250, 250, .2); text-shadow: 1px -1px 0px #000; diff --git a/css/formsmain.css b/css/formsmain.css index 1e10524..abd14b5 100644 --- a/css/formsmain.css +++ b/css/formsmain.css @@ -4,10 +4,10 @@ Gravity Forms Front End Form Styles Version 1.8 http: //www.gravityforms.com -updated: December 12 2013, 12:07 PM +updated: January 31, 2014 3:35 PM Gravity Forms is a Rocketgenius project -copyright 2013 Rocketgenius Inc. +copyright 2008-2014 Rocketgenius Inc. http: //www.rocketgenius.com this may not be redistributed without the express written permission of the author. @@ -1325,7 +1325,7 @@ body .gform_wrapper div.gform_body ul.gform_fields li.gfield.gfield_html dl dd { 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: -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; @@ -1367,7 +1367,7 @@ body .gform_wrapper div.gform_body ul.gform_fields li.gfield.gfield_html dl dd { 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 ); + 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; @@ -1426,7 +1426,7 @@ body .gform_wrapper div.gform_body ul.gform_fields li.gfield.gfield_html dl dd { 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 ); + 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; @@ -1478,7 +1478,7 @@ body .gform_wrapper div.gform_body ul.gform_fields li.gfield.gfield_html dl dd { 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 ); + 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; @@ -1509,7 +1509,7 @@ body .gform_wrapper div.gform_body ul.gform_fields li.gfield.gfield_html dl dd { background-repeat: no-repeat; } -.gform_wrapper .chzn-container-multi .chzn-choices .search-choice .search-choice-close: hover { +.gform_wrapper .chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover { background-position: right -9px; } @@ -1594,7 +1594,7 @@ body .gform_wrapper div.gform_body ul.gform_fields li.gfield.gfield_html dl dd { 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 ); + 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; diff --git a/css/rtl.css b/css/rtl.css index 274ac94..6b36a27 100644 --- a/css/rtl.css +++ b/css/rtl.css @@ -1,13 +1,14 @@ + /* ---------------------------------------------------------------- rtl.css Gravity Forms RTL Language Support http://www.gravityforms.com -updated: May 7, 2013 10:52 PM +updated: February 24, 2014 7:49 AM Gravity Forms is a Rocketgenius project -copyright 2013 Rocketgenius Inc. +copyright 2013-2014 Rocketgenius Inc. http: //www.rocketgenius.com this may not be redistributed without the express written permission of the author. @@ -508,7 +509,6 @@ html[dir="rtl"] body.wp-admin .gform_tabs li.active a { html[dir="rtl"] body.wp-admin a.tooltip, html[dir="rtl"] body.wp-admin a.tooltip_left, html[dir="rtl"] body.wp-admin a.tooltip_bottomleft { - text-indent: 9000px; overflow: hidden; } diff --git a/currency.php b/currency.php index 6518f63..979b66b 100644 --- a/currency.php +++ b/currency.php @@ -1,4 +1,9 @@ $key, - "type" => rgempty("type", $_GET) ? "field" : rgget("type"), + "type" => $type, "operator" => rgempty("operator", $_GET) ? "is" : rgget("operator"), "value" => $val ); @@ -157,6 +167,8 @@ public static function lead_detail_page(){ 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"]); ?> " . $confirmation_message . ""; + $progress_confirmation = apply_filters('gform_ajax_iframe_content', " " . $confirmation_message . ""); } else { @@ -710,6 +732,9 @@ public static function footer_init_scripts($form_id){ $current_page = self::get_current_page($form_id); $form_string .= ""; + $form_string = apply_filters( 'gform_footer_init_scripts_filter', $form_string, $form, $current_page ); + $form_string = apply_filters( 'gform_footer_init_scripts_filter_' . $form['id'], $form_string, $form, $current_page ); + if(!isset($_init_forms[$form_id])){ echo $form_string; if(!is_array($_init_forms)) @@ -827,6 +852,11 @@ private static function get_honeypot_labels(){ } public static function is_empty($field, $form_id=0){ + + if(empty($_POST["is_submit_" . $field["formId"]])){ + return true; + } + switch(RGFormsModel::get_input_type($field)){ case "post_image" : case "fileupload" : @@ -893,15 +923,20 @@ public static function is_empty($field, $form_id=0){ } - + /** + * Validates the range of the number according to the field settings. + * + * @param array $field + * @param array $value A decimal_dot formatted string + * @return true|false True on valid or false on invalid + */ private static function validate_range($field, $value){ - if( !GFCommon::is_numeric($value, rgar($field, "numberFormat")) ) + if( !GFCommon::is_numeric($value, "decimal_dot") ) return false; - $number = GFCommon::clean_number($value, rgar($field, "numberFormat")); - if( (is_numeric($field["rangeMin"]) && $number < $field["rangeMin"]) || - (is_numeric($field["rangeMax"]) && $number > $field["rangeMax"]) + if( (is_numeric($field["rangeMin"]) && $value < $field["rangeMin"]) || + (is_numeric($field["rangeMax"]) && $value > $field["rangeMax"]) ) return false; else @@ -939,6 +974,9 @@ public static function handle_submission($form, &$lead, $ajax=false){ //if Akismet plugin is installed, run lead through Akismet and mark it as Spam when appropriate $is_spam = GFCommon::akismet_enabled($form['id']) && GFCommon::is_akismet_spam($form, $lead); + GFCommon::log_debug("Checking for spam..."); + GFCommon::log_debug("Is entry considered spam? {$is_spam}."); + if(!$is_spam){ GFCommon::create_post($form, $lead); //send notifications @@ -980,6 +1018,8 @@ public static function clean_up_files($form){ public static function handle_confirmation($form, $lead, $ajax=false){ + GFCommon::log_debug("Sending confirmation"); + //run the function to populate the legacy confirmation format to be safe $form = self::update_confirmation($form, $lead); @@ -1037,6 +1077,8 @@ public static function handle_confirmation($form, $lead, $ajax=false){ $confirmation = self::get_js_redirect_confirmation($confirmation["redirect"], $ajax); //redirecting via client side } + GFCommon::log_debug("Confirmation: " . print_r($confirmation, true)); + return $confirmation; } @@ -1074,6 +1116,10 @@ public static function validate(&$form, $field_values, $page_number=0, &$failed_ if(self::validate_entry_limit($form)) return false; + if(empty($_POST["is_submit_" . $form["id"]])){ + return false; + } + foreach($form["fields"] as &$field){ //If a page number is specified, only validates fields that are on current page @@ -1117,7 +1163,7 @@ public static function validate(&$form, $field_values, $page_number=0, &$failed_ break; } - $field["validation_message"] = apply_filters("gform_duplicate_message_{$form["id"]}", apply_filters("gform_duplicate_message", $default_message, $form), $form); + $field["validation_message"] = apply_filters( "gform_duplicate_message_{$form["id"]}", apply_filters("gform_duplicate_message", $default_message, $form, $field, $value ), $form, $field, $value ); } else{ @@ -1232,6 +1278,8 @@ public static function validate(&$form, $field_values, $page_number=0, &$failed_ case "number" : + // the POST value has already been converted from currency or decimal_comma to decimal_dot and then cleaned in get_field_value() + $value = GFCommon::maybe_add_leading_zero($value); if(!rgblank($value) && !self::validate_range($field, $value) && !GFCommon::has_field_calculation($field)) { @@ -1534,11 +1582,11 @@ public static function failed_state_validation($form_id, $field, $value){ //making sure state wasn't tampered with by validating checksum $checksum = wp_hash(crc32($state[0])); - if($checksum != $state[1]){ + if($checksum !== $state[1]){ return true; } - $_gf_state = unserialize($state[0]); + $_gf_state = json_decode($state[0], true); } if(!is_array($value)){ @@ -1594,10 +1642,17 @@ public static function get_embedded_forms($post_content, &$ajax){ public static function enqueue_form_scripts( $form, $ajax = false ){ + // adding pre enqueue scripts hook so that scripts can be added first if a need exists + do_action("gform_pre_enqueue_scripts_{$form["id"]}", do_action("gform_pre_enqueue_scripts", $form, $ajax), $ajax); + if(!get_option('rg_gforms_disable_css')){ wp_enqueue_style("gforms_reset_css", GFCommon::get_base_url() . "/css/formreset.css", null, GFCommon::$version); - wp_enqueue_style("gforms_datepicker_css", GFCommon::get_base_url() . "/css/datepicker.css", null, GFCommon::$version); + + if( self::has_datepicker_field( $form ) ) { + wp_enqueue_style("gforms_datepicker_css", GFCommon::get_base_url() . "/css/datepicker.css", null, GFCommon::$version); + } + wp_enqueue_style("gforms_formsmain_css", GFCommon::get_base_url() . "/css/formsmain.css", null, GFCommon::$version); wp_enqueue_style("gforms_ready_class_css", GFCommon::get_base_url() . "/css/readyclass.css", null, GFCommon::$version); wp_enqueue_style("gforms_browsers_css", GFCommon::get_base_url() . "/css/browsers.css", null, GFCommon::$version); @@ -1660,13 +1715,17 @@ public static function print_form_scripts( $form, $ajax ) { if( ! wp_style_is( 'gforms_css' ) ) { wp_enqueue_style("gforms_reset_css", GFCommon::get_base_url() . "/css/formreset.css", null, GFCommon::$version); - wp_enqueue_style("gforms_datepicker_css", GFCommon::get_base_url() . "/css/datepicker.css", null, GFCommon::$version); wp_enqueue_style("gforms_formsmain_css", GFCommon::get_base_url() . "/css/formsmain.css", null, GFCommon::$version); wp_enqueue_style("gforms_ready_class_css", GFCommon::get_base_url() . "/css/readyclass.css", null, GFCommon::$version); wp_enqueue_style("gforms_browsers_css", GFCommon::get_base_url() . "/css/browsers.css", null, GFCommon::$version); wp_print_styles(array("gforms_reset_css")); - wp_print_styles(array("gforms_datepicker_css")); + + if( self::has_datepicker_field( $form ) ) { + wp_enqueue_style("gforms_datepicker_css", GFCommon::get_base_url() . "/css/datepicker.css", null, GFCommon::$version); + wp_print_styles(array("gforms_datepicker_css")); + } + wp_print_styles(array("gforms_formsmain_css")); wp_print_styles(array("gforms_ready_class_css")); wp_print_styles(array("gforms_browsers_css")); @@ -1715,16 +1774,17 @@ public static function print_form_scripts( $form, $ajax ) { foreach( $scripts as $script ) { wp_enqueue_script( $script ); - wp_print_scripts( array( $script ) ); } + wp_print_scripts( $scripts ); + if( wp_script_is( 'gform_gravityforms' ) ) { echo ''; } } - private static function has_conditional_logic( $form ) { + public static function has_conditional_logic( $form ) { $has_conditional_logic = self::has_conditional_logic_legwork( $form ); return apply_filters( 'gform_has_conditional_logic', $has_conditional_logic, $form ); } @@ -2017,7 +2077,7 @@ public static function get_form_init_scripts($form) { public static function get_chosen_init_script($form){ $chosen_fields = array(); foreach($form["fields"] as $field){ - if(rgar($field, "enableEnhancedUI")) + if(rgar($field, "enableEnhancedUI") && in_array($input_type, array("select", "multiselect"))) $chosen_fields[] = "#input_{$form["id"]}_{$field["id"]}"; } return "gformInitChosenFields('" . implode(",", $chosen_fields) . "','" . esc_attr(apply_filters("gform_dropdown_no_results_text_{$form["id"]}", apply_filters("gform_dropdown_no_results_text", __("No results matched", "gravityforms"), $form["id"]), $form["id"])) . "');"; @@ -2030,7 +2090,7 @@ public static function get_currency_format_init_script($form){ $currency_fields[] = "#input_{$form["id"]}_{$field["id"]}"; } - return "gformInitCurrencyFormatFields('" . implode(",", $currency_fields) . "')"; + return "gformInitCurrencyFormatFields('" . implode(",", $currency_fields) . "');"; } public static function get_counter_init_script($form){ @@ -2111,7 +2171,7 @@ public static function get_input_mask_init_script($form) { continue; $mask = rgar($field, 'inputMaskValue'); - $script = "jQuery('#input_{$form['id']}_{$field['id']}').mask('{$mask}').bind('keypress', function(e){if(e.which == 13){jQuery(this).blur();} } );"; + $script = "jQuery('#input_{$form['id']}_{$field['id']}').mask('" . esc_js($mask). "').bind('keypress', function(e){if(e.which == 13){jQuery(this).blur();} } );"; $script_str .= apply_filters("gform_input_mask_script_{$form['id']}", apply_filters("gform_input_mask_script", $script, $form['id'], $field['id'], $mask), $form['id'], $field['id'], $mask); } diff --git a/form_list.php b/form_list.php index ae5b82e..425c1c8 100644 --- a/form_list.php +++ b/form_list.php @@ -1,4 +1,9 @@ - + @@ -405,7 +424,7 @@ function gfConfirmBulkAction(element_id){ ?> - + @@ -492,8 +511,11 @@ function gfConfirmBulkAction(element_id){ 'menu_class' => 'trash', 'priority' => 500 ); - $form_actions = apply_filters("gform_form_actions", $form_actions, $form->id); + } + + $form_actions = apply_filters("gform_form_actions", $form_actions, $form->id); + echo GFForms::format_toolbar_menu_items($form_actions, true); ?> @@ -616,5 +638,3 @@ public static function save_new_form() { } } - -?> \ No newline at end of file diff --git a/form_settings.php b/form_settings.php index 01b3e46..31a3fc2 100644 --- a/form_settings.php +++ b/form_settings.php @@ -1,5 +1,9 @@ get_results($wpdb->prepare("SELECT * FROM $table_name WHERE id=%d AND is_trash = 0", $form_id)); + $trash_clause = $allow_trash ? "" : "AND is_trash = 0"; + $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE id=%d {$trash_clause}", $form_id)); return isset($results[0]) ? $results[0] : false; } @@ -558,7 +563,7 @@ public static function update_lead_property($lead_id, $property_name, $property_ } //updating lead - $wpdb->update($lead_table, array($property_name => $property_value ), array("id" => $lead_id)); + $result = $wpdb->update($lead_table, array($property_name => $property_value ), array("id" => $lead_id)); if(!$disable_hook){ @@ -576,6 +581,7 @@ public static function update_lead_property($lead_id, $property_name, $property_ } } + return $result; } public static function update_lead($lead){ @@ -644,14 +650,13 @@ public static function restore_forms($form_ids){ public static function delete_leads_by_form($form_id, $status=""){ global $wpdb; - if(!GFCommon::current_user_can_any("gravityforms_delete_entries")) - die(__("You don't have adequate permission to delete entries.", "gravityforms")); - $lead_table = self::get_lead_table_name(); $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(); + do_action("gform_delete_entries", $form_id, $status); + //deleting uploaded files self::delete_files_by_form($form_id, $status); @@ -698,9 +703,6 @@ public static function delete_views($form_id){ public static function delete_form($form_id){ global $wpdb; - if(!GFCommon::current_user_can_any("gravityforms_delete_forms")) - die(__("You don't have adequate permission to delete forms.", "gravityforms")); - do_action("gform_before_delete_form", $form_id); $form_meta_table = self::get_meta_table_name(); @@ -826,6 +828,9 @@ public static function update_form_meta($form_id, $form_meta, $meta_name="displa self::$_current_forms[$form_id] = null; + add_action( 'gform_after_update_form_meta', $form_meta, $form_id, $meta_name ); + add_action( "gform_after_update_form_meta_{$form_id}", $form_meta, $form_id, $meta_name ); + return $result; } @@ -840,9 +845,13 @@ public static function delete_files($lead_id, $form=null){ foreach($fields as $field){ if(rgar($field, "multipleFiles")){ $value_json = self::get_lead_field_value($lead, $field); - $files = json_decode($value_json, true); - foreach ($files as $file){ - self::delete_physical_file($file); + if(!empty($value_json)){ + $files = json_decode($value_json, true); + if(false === empty($files) && is_array($files)){ + foreach ($files as $file){ + self::delete_physical_file($file); + } + } } } else { $value = self::get_lead_field_value($lead, $field); @@ -908,10 +917,9 @@ private static function delete_physical_file($file_url){ return; //Convert from url to physical path - if (is_multisite()) { + if (is_multisite() && get_site_option( 'ms_files_rewriting' )) { $file_path = preg_replace("|^(.*?)/files/gravity_forms/|", BLOGUPLOADDIR . "gravity_forms/", $url); - } - else { + } else { $file_path = str_replace(WP_CONTENT_URL, WP_CONTENT_DIR, $url); } @@ -1031,9 +1039,6 @@ public static function delete_field($form_id, $field_id){ public static function delete_lead($lead_id){ global $wpdb; - if(!GFCommon::current_user_can_any("gravityforms_delete_entries")) - die(__("You don't have adequate permission to delete entries.", "gravityforms")); - do_action("gform_delete_lead", $lead_id); $lead_table = self::get_lead_table_name(); @@ -1068,11 +1073,11 @@ public static function delete_lead($lead_id){ } - public static function add_note($lead_id, $user_id, $user_name, $note){ + public static function add_note($lead_id, $user_id, $user_name, $note, $note_type = "note"){ global $wpdb; $table_name = self::get_lead_notes_table_name(); - $sql = $wpdb->prepare("INSERT INTO $table_name(lead_id, user_id, user_name, value, date_created) values(%d, %d, %s, %s, utc_timestamp())", $lead_id, $user_id, $user_name, $note); + $sql = $wpdb->prepare("INSERT INTO $table_name(lead_id, user_id, user_name, value, note_type, date_created) values(%d, %d, %s, %s, %s, utc_timestamp())", $lead_id, $user_id, $user_name, $note, $note_type); $wpdb->query($sql); } @@ -1123,9 +1128,11 @@ public static function save_lead($form, &$lead){ die(__("You don't have adequate permission to edit entries.", "gravityforms")); $lead_detail_table = self::get_lead_details_table_name(); + $is_new_lead = $lead == null; //Inserting lead if null - if($lead == null){ + if( $is_new_lead ) { + global $current_user; $user_id = $current_user && $current_user->ID ? $current_user->ID : 'NULL'; @@ -1139,7 +1146,7 @@ public static function save_lead($form, &$lead){ //reading newly created lead id $lead_id = $wpdb->insert_id; - $lead = array("id" => $lead_id); + $lead = array( 'id' => $lead_id ); GFCommon::log_debug("Entry record created in the database. ID: {$lead_id}"); } @@ -1173,7 +1180,7 @@ public static function save_lead($form, &$lead){ } //only save fields that are not hidden (except on entry screen) - if(RG_CURRENT_VIEW == "entry" || !RGFormsModel::is_field_hidden($form, $field, array()) ){ + if( RG_CURRENT_VIEW == 'entry' || ! GFFormsModel::is_field_hidden( $form, $field, array(), $is_new_lead ? null : $lead ) ) { // process calculation fields after all fields have been saved (moved after the is hidden check) if( GFCommon::has_field_calculation($field) ) { @@ -1350,7 +1357,7 @@ public static function get_prepared_input_value($form, $field, $lead, $input_id) } - return apply_filters("gform_save_field_value", $value, $lead, $field, $form); + return apply_filters( 'gform_save_field_value', $value, $lead, $field, $form, $input_id ); } public static function refresh_product_cache($form, $lead, $use_choice_text = false, $use_admin_label = false) { @@ -1465,18 +1472,21 @@ public static function is_value_match( $field_value, $target_value, $operation=" if (!empty($field_value) && !is_array($field_value) && $source_field["type"] == "multiselect") $field_value = explode(",", $field_value); // convert the comma-delimited string into an array + $target_value = GFFormsModel::maybe_trim_input($target_value, rgar($source_field, "formId"),$source_field); + if(is_array($field_value)){ $field_value = array_values($field_value); //returning array values, ignoring keys if array is associative $match_count = 0; foreach($field_value as $val){ - if(self::matches_operation(GFCommon::get_selection_value($val), $target_value, $operation)){ + $val = GFFormsModel::maybe_trim_input(GFCommon::get_selection_value($val), rgar($source_field,"formId"),$source_field); + if(self::matches_operation($val, $target_value, $operation)){ $match_count++; } } // if operation is Is Not, none of the values in the array can match the target value. $is_match = $operation == "isnot" ? $match_count == count($field_value) : $match_count > 0; } - else if(self::matches_operation(GFCommon::get_selection_value($field_value), $target_value, $operation)){ + else if(self::matches_operation(GFFormsModel::maybe_trim_input(GFCommon::get_selection_value($field_value), rgar($source_field,"formId"),$source_field), $target_value, $operation)){ $is_match = true; } @@ -1487,8 +1497,12 @@ private static function try_convert_float($text){ global $wp_locale; $number_format = $wp_locale->number_format['decimal_point'] == "," ? "decimal_comma" : "decimal_dot"; - if(GFCommon::is_numeric($text, $number_format)) + if(is_numeric($text) && $number_format == "decimal_comma"){ + return GFCommon::format_number($text, "decimal_comma"); + } + else if(GFCommon::is_numeric($text, $number_format)){ return GFCommon::clean_number($text, $number_format); + } return $text; } @@ -1528,7 +1542,7 @@ public static function matches_operation($val1, $val2, $operation){ break; case "starts_with" : - return !empty($val2) && strpos($val1, $val2) === 0; + return !rgblank($val2) && strpos($val1, $val2) === 0; break; case "ends_with" : @@ -1653,6 +1667,20 @@ public static function get_field_value(&$field, $field_values = array(), $get_fr $currency = new RGCurrency(GFCommon::get_currency()); $value = $currency->to_number( $value ); } + else if($field["numberFormat"] == "decimal_comma"){ + $value = GFCommon::clean_number($value, "decimal_comma"); + } + else if($field["numberFormat"] == "decimal_dot"){ + $value = GFCommon::clean_number($value, "decimal_dot"); + } + break; + + case "radio" : + $value = self::get_input_value($field, "input_" . $field["id"], rgar($field, "inputName"), $field_values, $get_from_post); + if ($value == "gf_other_choice"){ + //get value from text box + $value = self::get_input_value($field, "input_" . $field["id"] . "_other", rgar($field, "inputName"), $field_values, $get_from_post); + } break; default: @@ -1752,7 +1780,7 @@ public static function get_input_type($field){ private static function get_post_field_value($field, $lead){ - if(is_array($field["inputs"])){ + if(isset($field["inputs"]) && is_array($field["inputs"])){ $value = array(); foreach($field["inputs"] as $input){ $val = isset($lead[strval($input["id"])]) ? $lead[strval($input["id"])] : ""; @@ -2075,12 +2103,17 @@ public static function prepare_value($form, $field, $value, $input_name, $lead_i default: - //allow HTML for certain field types - $allow_html = in_array($field["type"], array("post_custom_field", "post_title", "post_content", "post_excerpt", "post_tags")) || in_array($input_type, array("checkbox", "radio")) ? true : false; - $allowable_tags = apply_filters("gform_allowable_tags_{$form_id}", apply_filters("gform_allowable_tags", $allow_html, $field, $form_id), $field, $form_id); + // only filter HTML on non-array based values + if( ! is_array( $value ) ) { + + //allow HTML for certain field types + $allow_html = in_array($field["type"], array("post_custom_field", "post_title", "post_content", "post_excerpt", "post_tags")) || in_array($input_type, array("checkbox", "radio")) ? true : false; + $allowable_tags = apply_filters("gform_allowable_tags_{$form_id}", apply_filters("gform_allowable_tags", $allow_html, $field, $form_id), $field, $form_id); - if($allowable_tags !== true) - $value = strip_tags($value, $allowable_tags); + if($allowable_tags !== true) + $value = strip_tags($value, $allowable_tags); + + } break; } @@ -2115,6 +2148,41 @@ public static function prepare_value($form, $field, $value, $input_name, $lead_i return $value; } + public static function is_checkbox_checked($field_id, $field_label, $lead, $form){ + + //looping through lead detail values trying to find an item identical to the column label. Mark with a tick if found. + $lead_field_keys = array_keys($lead); + foreach($lead_field_keys as $input_id){ + //mark as a tick if input label (from form meta) is equal to submitted value (from lead) + if(is_numeric($input_id) && absint($input_id) == absint($field_id)){ + if($lead[$input_id] == $field_label){ + return $lead[$input_id]; + } + else{ + $field = RGFormsModel::get_field($form, $field_id); + if(rgar($field, "enableChoiceValue") || rgar($field, "enablePrice")){ + foreach($field["choices"] as $choice){ + if($choice["value"] == $lead[$field_id]){ + return $choice["value"]; + } + else if(rgar($field,"enablePrice")){ + $ary = explode("|", $lead[$field_id]); + $val = count($ary) > 0 ? $ary[0] : ""; + $price = count($ary) > 1 ? $ary[1] : ""; + + if($val == $choice["value"]){ + return $choice["value"]; + } + } + } + } + } + } + } + + return false; + } + private static function create_list_array($field, $value){ if(!rgar($field,"enableColumns")){ return $value; @@ -2218,8 +2286,9 @@ public static function get_choice_text($field, $value, $input_id=0){ public static function choice_value_match($field, $choice, $value){ - - if($choice["value"] == $value){ + $choice_value = GFFormsModel::maybe_trim_input($choice["value"], rgar($field, "formId"), $field); + $value = GFFormsModel::maybe_trim_input($value, rgar($field, "formId"), $field); + if($choice_value == $value){ return true; } else if(rgget("enablePrice", $field)){ @@ -2233,7 +2302,7 @@ public static function choice_value_match($field, $choice, $value){ // add support for prepopulating multiselects @alex else if(RGFormsModel::get_input_type($field) == 'multiselect') { $values = explode(',', $value); - if(in_array($choice['value'], $values)) + if(in_array($choice_value, $values)) return true; } return false; @@ -2619,7 +2688,7 @@ public static function update_lead_field_value($form, $lead, $field, $lead_detai if(!rgblank($value)){ - $value = apply_filters("gform_save_field_value", $value, $lead, $field, $form); + $value = apply_filters("gform_save_field_value", $value, $lead, $field, $form, $input_id ); $truncated_value = GFCommon::safe_substr($value, 0, GFORMS_MAX_FIELD_LENGTH); if($lead_detail_id > 0){ @@ -2940,7 +3009,7 @@ public static function get_lead_notes($lead_id){ global $wpdb; $notes_table = self::get_lead_notes_table_name(); - return $wpdb->get_results($wpdb->prepare(" SELECT n.id, n.user_id, n.date_created, n.value, ifnull(u.display_name,n.user_name) as user_name, u.user_email + return $wpdb->get_results($wpdb->prepare(" SELECT n.id, n.user_id, n.date_created, n.value, n.note_type, ifnull(u.display_name,n.user_name) as user_name, u.user_email FROM $notes_table n LEFT OUTER JOIN $wpdb->users u ON n.user_id = u.id WHERE lead_id=%d ORDER BY id", $lead_id)); @@ -3060,8 +3129,6 @@ public static function get_leads($form_id, $sort_field_number=0, $sort_direction //initializing rownum $wpdb->query("select @rownum:=0"); - GFCommon::log_debug($sql); - //getting results $results = $wpdb->get_results($sql); @@ -3717,33 +3784,14 @@ private static function sort_by_field_query($form_id, $search_criteria, $sorting $orderby = $is_numeric_sort ? "ORDER BY query, (value+0) $sort_direction" : "ORDER BY query, value $sort_direction"; + $form_id_where = self::get_form_id_where($form_id); - $field_filters_where = self::get_field_filters_where($form_id, $search_criteria); - if (!empty($field_filters_where)) - $where_arr[]=$field_filters_where; - - $info_search_where = self::get_info_search_where($search_criteria); - if(!empty($info_search_where)) - $where_arr[] = $info_search_where; - - $search_operator = self::get_search_operator($search_criteria); - $where = empty($where_arr) ? "" : join(" $search_operator ", $where_arr); - - $date_range_where = self::get_date_range_where($search_criteria); - if(!empty($date_range_where)) - $where = empty($where) ? $date_range_where : $where . " AND " . $date_range_where; - - if(!empty($where)) - $where = "WHERE " . $where; - - if(is_array($form_id)){ - $in_str_arr = array_fill(0, count($form_id), '%s'); - $in_str = esc_sql(join(",", $in_str_arr)); - $form_id_where = $wpdb->prepare(" AND form_id IN ($in_str)", $form_id); - } else { - $form_id_where = $form_id > 0 ? $wpdb->prepare(" AND l.form_id=%d", $form_id) : ""; + if(!empty($form_id_where)){ + $form_id_where = " AND " . $form_id_where; } + $where = self::get_search_where($form_id, $search_criteria); + $field_number_min = $sort_field_number - 0.001; $field_number_max = $sort_field_number + 0.001; @@ -3802,14 +3850,15 @@ private static function sort_by_column_query($form_id, $search_criteria, $sortin $entry_meta_sql_join = ""; $sort_field_is_entry_meta = false; if (false === empty($entry_meta) && array_key_exists($sort_field, $entry_meta)) { - $entry_meta_sql_join = $wpdb->prepare("INNER JOIN - ( - SELECT - lead_id, meta_value as $sort_field - from $lead_meta_table_name - WHERE meta_key=%s - ) lead_meta_data ON lead_meta_data.lead_id = l.id - ", $sort_field); + $entry_meta_sql_join = $wpdb->prepare(" + INNER JOIN + ( + SELECT + lead_id, meta_value as $sort_field + from $lead_meta_table_name + WHERE meta_key=%s + ) lead_meta_data ON lead_meta_data.lead_id = l.id + ", $sort_field); $is_numeric_sort = $entry_meta[$sort_field]['is_numeric']; $sort_field_is_entry_meta = true; } else { @@ -3839,7 +3888,7 @@ private static function sort_by_column_query($form_id, $search_criteria, $sortin FROM $lead_table_name l INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id $entry_meta_sql_join - $where + $where $orderby LIMIT $offset,$page_size ) page @@ -3850,9 +3899,24 @@ private static function sort_by_column_query($form_id, $search_criteria, $sortin return $sql; } + private static function get_form_id_where($form_id){ + global $wpdb; + + if(is_array($form_id)){ + $in_str_arr = array_fill(0, count($form_id), '%s'); + $in_str = esc_sql(join(",", $in_str_arr)); + $form_id_where = $wpdb->prepare("l.form_id IN ($in_str)", $form_id); + } else { + $form_id_where = $form_id > 0 ? $wpdb->prepare("l.form_id=%d", $form_id) : ""; + } + + return $form_id_where; + } + private static function get_search_where($form_id, $search_criteria){ global $wpdb; + $where_arr = array(); $field_filters_where = self::get_field_filters_where($form_id, $search_criteria); @@ -3864,14 +3928,6 @@ private static function get_search_where($form_id, $search_criteria){ if(!empty($info_search_where)) $where_arr[] = $info_search_where; - if(is_array($form_id)){ - $in_str_arr = array_fill(0, count($form_id), '%s'); - $in_str = esc_sql(join(",", $in_str_arr)); - $form_id_where = $wpdb->prepare("l.form_id IN ($in_str)", $form_id); - } else { - $form_id_where = $form_id > 0 ? $wpdb->prepare("l.form_id=%d", $form_id) : ""; - } - $search_operator = self::get_search_operator($search_criteria); $where = empty($where_arr) ? "" : "(" . join( " $search_operator ", $where_arr) . ")" ; @@ -3881,6 +3937,8 @@ private static function get_search_where($form_id, $search_criteria){ if(!empty($date_range_where)) $where_and_clause_arr[] = $date_range_where; + $form_id_where = self::get_form_id_where($form_id); + if(!empty($form_id_where)) $where_and_clause_arr[] = $form_id_where; @@ -3956,10 +4014,8 @@ private static function get_field_filters_where($form_id, $search_criteria) { $search_type = "global"; } elseif (is_numeric($key)){ $search_type = "field"; - } elseif(isset($entry_meta[$key])){ - $search_type = "meta"; } else { - $search_type = "global"; + $search_type = "meta"; } } @@ -3967,25 +4023,25 @@ private static function get_field_filters_where($form_id, $search_criteria) { case "field": $upper_field_number_limit = (string)(int)$key === $key ? (float)$key + 0.9999 : (float)$key + 0.0001; /* doesn't support "<>" for checkboxes */ - $field_query = $wpdb->prepare("l.id IN - ( - SELECT - lead_id - from $lead_details_table_name - WHERE (field_number BETWEEN %s AND %s AND value $operator %s) - $form_id_where - ) - ", (float)$key - 0.0001, $upper_field_number_limit, $search_term); + $field_query = $wpdb->prepare(" + l.id IN + ( + SELECT + lead_id + from $lead_details_table_name + WHERE (field_number BETWEEN %s AND %s AND value $operator %s) + $form_id_where + )", (float)$key - 0.0001, $upper_field_number_limit, $search_term); if(empty($val) || "%%" === $val || "<>" === $operator){ - $skipped_field_query = $wpdb->prepare("l.id NOT IN - ( - SELECT - lead_id - from $lead_details_table_name - WHERE (field_number BETWEEN %s AND %s) - $form_id_where - ) - ", (float)$key - 0.0001, $upper_field_number_limit, $search_term); + $skipped_field_query = $wpdb->prepare(" + l.id NOT IN + ( + SELECT + lead_id + from $lead_details_table_name + WHERE (field_number BETWEEN %s AND %s) + $form_id_where + )", (float)$key - 0.0001, $upper_field_number_limit, $search_term); $field_query = "(" . $field_query . " OR " . $skipped_field_query . ")"; } @@ -4018,15 +4074,15 @@ private static function get_field_filters_where($form_id, $search_criteria) { $meta = rgar($entry_meta, $key); $placeholder = rgar($meta, "is_numeric") ? "%s" : "%s"; $search_term = "like" == $operator ? "%$val%" : $val; - $sql_array[] = $wpdb->prepare("l.id IN - ( - SELECT - lead_id - FROM $lead_meta_table_name - WHERE meta_key=%s AND meta_value $operator $placeholder - $form_id_where - ) - ", $search["key"], $search_term); + $sql_array[] = $wpdb->prepare(" + l.id IN + ( + SELECT + lead_id + FROM $lead_meta_table_name + WHERE meta_key=%s AND meta_value $operator $placeholder + $form_id_where + )", $search["key"], $search_term); break; } @@ -4041,10 +4097,26 @@ private static function get_field_filters_where($form_id, $search_criteria) { private static function get_date_range_where($search_criteria) { global $wpdb; - if(isset($search_criteria["start_date"])) - $where_array[] = $wpdb->prepare("datediff(date_created, %s) >= 0", $search_criteria["start_date"]); - if(isset($search_criteria["end_date"])) - $where_array[] = $wpdb->prepare("datediff(date_created, %s) <= 0", $search_criteria["end_date"]); + if(isset($search_criteria["start_date"])){ + $where_array[] = $wpdb->prepare("date_created >= %s", $search_criteria["start_date"]); + } + + if(isset($search_criteria["end_date"])){ + + $end_date = new DateTime($search_criteria["end_date"]); + $end_datetime_str = $end_date->format('Y-m-d H:i:s'); + $end_date_str = $end_date->format('Y-m-d'); + + // extend end date till the end of the day unless a time was specified. 00:00:00 is ignored. + if($end_datetime_str == $end_date_str . " 00:00:00" ){ + $end_date = $end_date->format('Y-m-d') . " 23:59:59"; + } else { + $end_date = $end_date->format('Y-m-d H:i:s'); + } + + $where_array[] = $wpdb->prepare("date_created <= %s", $end_date); + } + $sql = empty($where_array) ? "" : "(" . join(" AND ", $where_array) . ")"; @@ -4078,14 +4150,18 @@ private static function get_info_search_where($search_criteria) { $info_column_keys = self::get_lead_db_columns(); array_push($info_column_keys, "id"); - $int_columns = array("id", "post_id", "is_starred", "is_read", "is_fulfilled"); + $int_columns = array("id", "post_id", "is_starred", "is_read", "is_fulfilled", "entry_id"); $where_array = array(); foreach ($field_filters as $filter) { $key = strtolower(rgar($filter, "key")); - if(!in_array($key, $info_column_keys)) - continue; - if("entry_id" === $key) + + if("entry_id" === $key){ $key = "id"; + } + + if(!in_array($key, $info_column_keys)){ + continue; + } $operator = isset($filter["operator"]) ? strtolower($filter["operator"]) : "="; @@ -4168,6 +4244,103 @@ public static function get_db_charset(){ return $charset_collate; } + + /** + * Trims values inside choice texts, choice values, input labels, field labels and field conditionalLogic + * + * @param array $form Form object. + * @param bool $form_updated Output parameter. + * @return array $form + */ + public static function trim_form_meta_values($form, &$form_updated = false){ + $form_id = $form["id"]; + GFCommon::log_debug("Starting GFFormsModel::trim_form_meta_values()"); + if(isset($form["fields"]) && is_array($form["fields"])){ + foreach($form["fields"] as &$field){ + $trim_value = apply_filters("gform_trim_input_value", true, $form_id, $field); + if(!$trim_value){ + continue; + } + + if(isset($field["label"]) && $field["label"] != trim($field["label"])){ + $field["label"] = trim($field["label"]); + $form_updated = true; + } + if(isset($field["choices"]) && is_array($field["choices"])){ + foreach($field["choices"] as &$choice){ + if(isset($choice["text"]) && $choice["text"] != trim($choice["text"])){ + $choice["text"] = trim($choice["text"]); + $form_updated = true; + } + if(isset($choice["value"]) && $choice["value"] != trim($choice["value"])){ + $choice["value"] = trim($choice["value"]); + $form_updated = true; + } + } + } + if(isset($field["inputs"]) && is_array($field["inputs"])){ + foreach($field["inputs"] as &$input){ + if(isset($input["label"]) && $input["label"] != trim($input["label"])){ + $input["label"] = trim($input["label"]); + $form_updated = true; + } + } + } + } + $form["fields"] = GFFormsModel::trim_conditional_logic_values($form["fields"], $form, $form_updated); + } + if($form_updated){ + GFCommon::log_debug("Trimmed form values"); + } + return $form; + } + + /** + * Trims values from an array of elements e.g. notifications and confirmations + * + * @param array $meta_array Form object. + * @param array $form Form object. + * @param bool $updated Output parameter. + * @return array $meta_array + */ + public static function trim_conditional_logic_values($meta_array, $form, &$updated = false){ + GFCommon::log_debug("Starting GFFormsModel::trim_conditional_logic_values()"); + if(is_array($meta_array)){ + foreach($meta_array as &$meta){ + $meta = self::trim_conditional_logic_values_from_element($meta, $form, $updated); + } + } + if($updated){ + GFCommon::log_debug("Trimmed conditional logic values"); + } + return $meta_array; + } + + /** + * Trims values from elements e.g. fields, notifications and confirmations + * + * @param array $element Form object. + * @param array $form Form object. + * @param bool $updated Output parameter. + * @return array $element + */ + public static function trim_conditional_logic_values_from_element($element, $form = array(), &$updated = false){ + if(isset($element["conditionalLogic"]) && is_array($element["conditionalLogic"]) && isset($element["conditionalLogic"]["rules"]) && is_array($element["conditionalLogic"]["rules"])){ + foreach($element["conditionalLogic"]["rules"] as &$rule){ + $value = (string) $rule["value"]; + if($value !== trim($value)){ + $field = isset($form["fields"]) ? GFFormsModel::get_field($form, $rule["fieldId"]) : array(); + $trim_value = apply_filters("gform_trim_input_value", true, rgar($form, "id"), $field); + if($trim_value){ + $rule["value"] = trim($rule["value"]); + $updated = true; + } + + } + } + } + return $element; + } } class RGFormsModel extends GFFormsModel { } diff --git a/gravityforms.php b/gravityforms.php index 2adeab7..6253d91 100644 --- a/gravityforms.php +++ b/gravityforms.php @@ -3,9 +3,11 @@ 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.1 +Version: 1.8.7.2 Author: rocketgenius Author URI: http://www.rocketgenius.com +Text Domain: gravityforms +Domain Path: /languages ------------------------------------------------------------------------ Copyright 2009-2013 Rocketgenius Inc. @@ -53,6 +55,10 @@ //define('GF_RECAPTCHA_PUBLIC_KEY','YOUR_PUBLIC_KEY_GOES_HERE'); //------------------------------------------------------------------------------------------------------------------ +if(!defined("ABSPATH")){ + die(); +} + if(!defined("RG_CURRENT_PAGE")) define("RG_CURRENT_PAGE", basename($_SERVER['PHP_SELF'])); @@ -96,7 +102,7 @@ class GFForms { - public static $version = '1.8.1'; + public static $version = '1.8.7.2'; public static function has_members_plugin(){ return function_exists( 'members_get_capabilities' ); @@ -113,8 +119,11 @@ public static function init(){ self::register_scripts(); - //Setting up Gravity Forms - self::setup(); + //Maybe set up Gravity Forms: only on admin requests for single site installation and always for multisite + if( (IS_ADMIN && false === ( defined("DOING_AJAX") && true === DOING_AJAX ) ) || is_multisite() ){ + self::setup(); + } + if(IS_ADMIN){ @@ -333,6 +342,7 @@ public static function setup($force_setup = false){ //Auto-importing forms based on GF_IMPORT_FILE AND GF_THEME_IMPORT_FILE self::maybe_import_forms(); + //The format the version info changed to JSON. Make sure the old format is not cached. if(version_compare(get_option("rg_form_version"), "1.8.0.3", "<" )){ delete_transient("gform_update_info"); } @@ -439,6 +449,7 @@ public static function setup_database() user_id bigint(20), date_created datetime not null, value longtext, + note_type varchar(50), PRIMARY KEY (id), KEY lead_id (lead_id), KEY lead_user_key (lead_id,user_id) @@ -495,6 +506,55 @@ public static function setup_database() //fix checkbox value. needed for version 1.0 and below but won't hurt for higher versions self::fix_checkbox_value(); + + //fix leading and trailing spaces in Form objects and entry values + if(version_compare(get_option("rg_form_version"), "1.8.3.1", "<" )){ + self::fix_leading_and_trailing_spaces(); + } + + } + + private static function fix_leading_and_trailing_spaces(){ + + global $wpdb; + + $meta_table_name = GFFormsModel::get_meta_table_name(); + $lead_details_table = GFFormsModel::get_lead_details_table_name(); + $lead_details_long_table = GFFormsModel::get_lead_details_long_table_name(); + + $result = $wpdb->query("UPDATE $lead_details_table SET value = TRIM(value)"); + $result = $wpdb->query("UPDATE $lead_details_long_table SET value = TRIM(value)"); + + + $results = $wpdb->get_results("SELECT form_id, display_meta, confirmations, notifications FROM {$meta_table_name}", ARRAY_A); + + foreach ($results as &$result) { + $form_id = $result["form_id"]; + + $form = GFFormsModel::unserialize($result["display_meta"]); + $form_updated = false; + $form = GFFormsModel::trim_form_meta_values($form, $form_updated); + if($form_updated){ + GFFormsModel::update_form_meta($form_id, $form); + } + + $confirmations = GFFormsModel::unserialize($result["confirmations"]); + $confirmations_updated = false; + $confirmations = GFFormsModel::trim_conditional_logic_values($confirmations, $form, $confirmations_updated); + if($confirmations_updated){ + GFFormsModel::update_form_meta($form_id, $confirmations, "confirmations"); + } + + $notifications = GFFormsModel::unserialize($result["notifications"]); + $notifications_updated = false; + $notifications = GFFormsModel::trim_conditional_logic_values($notifications, $form, $notifications_updated); + if($notifications_updated){ + GFFormsModel::update_form_meta($form_id, $notifications, "notifications"); + } + + } + + return $results; } private static function maybe_import_forms() @@ -561,7 +621,7 @@ public static function get_wp_option($option_name){ return $wpdb->get_var($wpdb->prepare("SELECT option_value FROM {$wpdb->prefix}options WHERE option_name=%s", $option_name)); } - //Changes form_id values from default value "0" to the correct value. Neededed when upgrading users from 1.6.11 + //Changes form_id values from default value "0" to the correct value. Needed when upgrading users from 1.6.11 private static function fix_lead_meta_form_id_values(){ global $wpdb; @@ -988,7 +1048,7 @@ public static function parse_shortcode( $attributes, $content = null ) { 'ajax' => false, 'tabindex' => 1, 'action' => 'form' - ), $attributes ) ); + ), $attributes, 'gravityforms' ) ); $shortcode_string = ""; @@ -1043,9 +1103,9 @@ public static function ajax_parse_request($wp) { if (isset($_POST["gform_ajax"])) { parse_str($_POST["gform_ajax"]); - + $tabindex = isset($tabindex) ? absint($tabindex) : 1; require_once(GFCommon::get_base_path() . "/form_display.php"); - // GFCommon::$tab_index = $tabindex; + $result = GFFormDisplay::get_form($form_id, $title, $description, false, $_POST["gform_field_values"], true, $tabindex); die($result); } @@ -1903,7 +1963,9 @@ public static function update_lead_status(){ break; case "delete" : - RGFormsModel::delete_lead($lead_id); + if(GFCommon::current_user_can_any("gravityforms_delete_entries")){ + RGFormsModel::delete_lead($lead_id); + } break; default : @@ -1968,6 +2030,9 @@ public static function select_export_form(){ check_ajax_referer("rg_select_export_form", "rg_select_export_form"); $form_id = intval($_POST["form_id"]); $form = RGFormsModel::get_form_meta($form_id); + + $form = apply_filters("gform_form_export_page_{$form_id}", apply_filters("gform_form_export_page", $form)); + $filter_settings = GFCommon::get_field_filter_settings($form); $filter_settings_json = json_encode($filter_settings); $fields = array(); diff --git a/help.php b/help.php index 2aebeb8..8770e71 100644 --- a/help.php +++ b/help.php @@ -1,4 +1,9 @@ _addon->get_locking_object_id(); } + + protected function is_object_locked($object_id){ + return $this->is_object_locked($object_id); + } } \ No newline at end of file diff --git a/includes/addon/class-gf-addon.php b/includes/addon/class-gf-addon.php index d3f9529..d8f798f 100644 --- a/includes/addon/class-gf-addon.php +++ b/includes/addon/class-gf-addon.php @@ -1,5 +1,9 @@ _slug, FALSE, $this->_slug . '/languages'); + add_filter("gform_logging_supported", array($this, "set_logging_supported")); + if(RG_CURRENT_PAGE == 'admin-ajax.php') { //If gravity forms is supported, initialize AJAX @@ -181,12 +199,20 @@ protected function init_admin(){ } } + // creates the top level app left menu + if (self::has_app_menu()) { + if ($this->current_user_can_any($this->_capabilities_app_menu)) { + add_action('admin_menu', array($this, 'create_app_menu')); + } + } + + // Members plugin integration if (self::has_members_plugin()) add_filter('members_get_capabilities', array($this, 'members_get_capabilities')); // Results page - if ($this->method_is_overridden('get_results_page_config')) { + if ($this->method_is_overridden('get_results_page_config') ) { $results_page_config = $this->get_results_page_config(); $results_capabilities = rgar($results_page_config, "capabilities"); if($results_page_config && $this->current_user_can_any($results_capabilities)) @@ -280,7 +306,7 @@ protected function upgrade($previous_version) { protected function styles(){ return array( array( "handle" => "gaddon_form_settings_css", - "src" => GFAddOn::get_gfaddon_base_url() . "/css/gaddon_form_settings.css", + "src" => GFAddOn::get_gfaddon_base_url() . "/css/gaddon_settings.css", "version" => GFCommon::$version, "enqueue" => array( array("admin_page" => array("form_settings", "plugin_settings", "plugin_page") ) @@ -374,6 +400,19 @@ protected function scripts(){ "enqueue" => array( array("admin_page" => array("results")), ) + ), + array( + 'handle' => 'gaddon_repeater', + 'src' => GFAddOn::get_gfaddon_base_url() . '/js/repeater.js', + 'version' => GFCommon::$version, + 'deps' => array( 'jquery' ), + 'enqueue' => array( + array( + 'admin_page' => array( 'form_settings' ) +// , +// 'field_types' => array( 'dynamic_field_map' ) + ) + ) ) ); } @@ -562,6 +601,12 @@ private function _page_condition_matches($pages, $tab){ break; + case "app_settings" : + if($this->is_app_settings($tab)) + return true; + + break; + case "plugin_page" : if($this->is_plugin_page()) return true; @@ -693,6 +738,13 @@ protected function results_page_init($results_page_config) { $gf_results->init(); } + //-------------- Logging integration -------------------------------------- + + function set_logging_supported($plugins){ + $plugins[$this->_slug] = $this->_title; + return $plugins; + } + //-------------- Members plugin integration -------------------------------------- @@ -810,10 +862,10 @@ class="" -

    +
    - +
    " */ protected function single_setting_row( $field ) { - $display = rgar( $field, 'hidden' ) ? 'style="display:none;"' : ''; + $display = rgar( $field, 'hidden' ) || rgar( $field, 'type' ) == 'hidden' ? 'style="display:none;"' : ''; ?> " > + _column_value_callback)) { $value = call_user_func($this->_column_value_callback, $item, $column); } @@ -997,18 +913,6 @@ function add_action_links($item, $column, $value){ return sprintf('%1$s %2$s', $value, $this->row_actions($actions)); } - /*function column_feed_name($item) { - $name = isset($item["name"]) ? $item["name"] : __("Untitled feed", "gravityforms"); - $feed_id = rgar($item, "id"); - $edit_url = add_query_arg(array("fid" => $feed_id)); - $actions = apply_filters($this->_slug . '_feed_actions', array( - 'edit' => '' . __('Edit', 'gravityforms') . '', - 'delete' => '' . __('Delete', 'gravityforms') . '' - )); - - return sprintf('%1$s %2$s', $name, $this->row_actions($actions)); - }*/ - function column_is_active($item) { $is_active = intval(rgar($item, "is_active")); $src = GFCommon::get_base_url() . "/images/active{$is_active}.png"; diff --git a/includes/addon/class-gf-payment-addon.php b/includes/addon/class-gf-payment-addon.php index 6420728..541a645 100644 --- a/includes/addon/class-gf-payment-addon.php +++ b/includes/addon/class-gf-payment-addon.php @@ -1,4 +1,9 @@ payment_method_is_overridden("check_status")) $this->setup_cron(); @@ -37,7 +55,9 @@ public function init_admin() { add_filter("gform_currencies", array($this, "supported_currencies")); if(rgget("page") == "gf_entries"){ - add_action('gform_entry_info',array($this, "entry_info"), 10, 2); + add_action('gform_payment_details',array($this, "entry_info"), 10, 2); + + add_filter("gform_notes_avatar", array($this, "notes_avatar"), 10, 2); } } @@ -54,22 +74,37 @@ public function init_frontend(){ public function init_ajax(){ parent::init_ajax(); - add_action('wp_ajax_gaddon_cancel_subscription', array($this, 'start_cancel_subscription')); + add_action('wp_ajax_gaddon_cancel_subscription', array($this, 'ajax_cancel_subscription')); } protected function setup(){ parent::setup(); - //upgrading Feed Add-On base class $installed_version = get_option("gravityformsaddon_payment_version"); - if ($installed_version != $this->_payment_version) + + $installed_addons = get_option("gravityformsaddon_payment_addons"); + if( !is_array($installed_addons) ) + $installed_addons = array(); + + if ( $installed_version != $this->_payment_version ){ $this->upgrade_payment($installed_version); + $installed_addons = array($this->_slug); + update_option("gravityformsaddon_payment_addons", $installed_addons); + } + else if( !in_array($this->_slug, $installed_addons) ){ + $this->upgrade_payment($installed_version); + + $installed_addons[] = $this->_slug; + update_option("gravityformsaddon_payment_addons", $installed_addons); + } + update_option("gravityformsaddon_payment_version", $this->_payment_version); + } - private function upgrade_payment($previous_version) { + private function upgrade_payment($previous_versions) { global $wpdb; $charset_collate = GFFormsModel::get_db_charset(); @@ -89,6 +124,23 @@ private function upgrade_payment($previous_version) { ) $charset_collate;"; GFFormsModel::dbDelta($sql); + + + if($this->_supports_callbacks){ + $sql = "CREATE TABLE {$wpdb->prefix}gf_addon_payment_callback ( + id int(10) unsigned not null auto_increment, + lead_id int(10) unsigned not null, + addon_slug varchar(250) not null, + callback_id varchar(250), + date_created datetime, + PRIMARY KEY (id), + KEY slug_callback_id (addon_slug,callback_id) + ) $charset_collate;"; + + GFFormsModel::dbDelta($sql); + } + + } //--------- Submission Process ------ @@ -99,8 +151,10 @@ public function confirmation($confirmation, $form, $entry, $ajax){ $feed = $this->get_payment_feed($entry, $form); - if(!$feed) + if(!$feed){ + $this->log_debug("No payment feed was located for form_id = " . $form["id"] . " - NOT sending to " . $this->_slug); return $confirmation; + } $submission_data = $this->get_submission_data($feed, $form, $entry); @@ -155,11 +209,13 @@ public function validation( $validation_result ) { $this->authorization = $this->authorize($feed, $submission_data, $form, $entry); } else if($do_subscription){ - $subscription = $this->subscribe($feed, $submission_data, $form, $entry); + + $subscription = $this->subscribe( $feed, $submission_data, $form, $entry ); $this->authorization["is_authorized"] = $subscription["is_success"]; $this->authorization["error_message"] = rgar($subscription, "error_message"); $this->authorization["subscription"] = $subscription; + } @@ -241,6 +297,17 @@ protected function subscribe($feed, $submission_data, $form, $entry){ } + /** + * Override this method to add integration code to the payment processor in order to cancel a subscription. This method is executed when a subscription is canceled from the Payment Gateway (i.e. Stripe or PayPal) + * @param $entry - Current entry array containing entry information (i.e data submitted by users). + * @param $feed - Current configured payment feed + + * @return bool - Returns true if the subscription was cancelled successfully and false otherwise. + * + */ + protected function cancel($entry, $feed){ + return false; + } protected function get_validation_result($validation_result, $authorization_result){ @@ -284,8 +351,11 @@ public function entry_post_save($entry, $form){ else if($feed["meta"]["transactionType"] == "subscription"){ $this->process_subscription($this->authorization, $feed, $this->authorization["submission_data"], $form, $entry); + } + gform_update_meta($entry["id"], "payment_gateway", $this->_slug); + return $entry; } @@ -308,11 +378,12 @@ protected function process_capture($authorization, $feed, $submission_data, $for $this->insert_transaction($entry["id"], "payment", $entry["transaction_id"], $entry["payment_amount"]); - GFFormsModel::add_note($entry["id"], 0, "System", sprintf(__("Payment has been captured successfully. Amount: %s. Transaction Id: %s", "gravityforms"), GFCommon::to_money($payment["amount"], $entry["currency"]),$payment["transaction_id"])); + + $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"); } else{ $entry["payment_status"] = "Failed"; - GFFormsModel::add_note($entry["id"], 0, "System", sprintf( __("Payment failed to be captured. Reason: %s", "gravityforms") , $payment["error_message"] )); + $this->add_note($entry["id"], sprintf( __("Payment failed to be captured. Reason: %s", "gravityforms") , $payment["error_message"] ), "error"); } GFAPI::update_entry($entry); @@ -323,54 +394,50 @@ protected function process_capture($authorization, $feed, $submission_data, $for protected function process_subscription($authorization, $feed, $submission_data, $form, $entry){ - $subscription = rgar($authorization,"subscription"); - if(empty($subscription)) + $subscription = rgar( $authorization, 'subscription' ); + if( empty( $subscription ) ) return; - //If setup fee / trial is captured as part of a separate transaction - $payment = rgar($subscription,"captured_payment"); - $payment_name = rgempty("name", $payment) ? __("Initial payment", "gravityforms") : $payment["name"]; - if($payment && $payment["is_success"]){ + // if setup fee / trial is captured as part of a separate transaction + $payment = rgar( $subscription, 'captured_payment' ); + $payment_name = rgempty( 'name', $payment ) ? __( 'Initial payment', 'gravityforms' ) : $payment['name']; - $this->insert_transaction($entry["id"], "payment", $payment["transaction_id"], $payment["amount"]); - GFFormsModel::add_note($entry["id"], 0, "System", sprintf(__("%s has been captured successfully. Amount: %s. Transaction Id: %s", "gravityforms"), $payment_name, GFCommon::to_money($payment["amount"], $entry["currency"]),$payment["transaction_id"])); + if( $payment && $payment['is_success'] ) { - } - else if($payment && !$payment["is_success"]){ + $this->insert_transaction($entry['id'], 'payment', $payment['transaction_id'], $payment['amount'], false ); + + $amount_formatted = GFCommon::to_money( $payment['amount'], $entry['currency'] ); + $note = sprintf( __( '%s has been captured successfully. Amount: %s. Transaction Id: %s', 'gravityforms' ), $payment_name, $amount_formatted, $payment['transaction_id'] ); + $this->add_note( $entry['id'], $note, "success" ); - GFFormsModel::add_note($entry["id"], 0, "System", sprintf(__("Failed to capture %s. Reason: %s.", "gravityforms"), $payment("error_message"), $payment_name)); } + else if( $payment && ! $payment['is_success'] ) { - //Updating subscription information - if($subscription["is_success"]){ + $this->add_note( $entry['id'], sprintf( __( 'Failed to capture %s. Reason: %s.', 'gravityforms' ), $payment['error_message'], $payment_name ), "error" ); - $entry["transaction_id"] = $subscription["subscription_id"]; - $entry["transaction_type"] = "2"; - $entry["is_fulfilled"] = true; - $entry["currency"] = GFCommon::get_currency(); - $entry["payment_amount"] = $subscription["amount"]; - $entry["payment_status"] = "Active"; - $entry["payment_date"] = gmdate("Y-m-d H:i:s"); + } - GFFormsModel::add_note($entry["id"], 0, "System", sprintf(__("Subscription successfully created. Subscription Id: %s.", "gravityforms"), $subscription["subscription_id"])); + // updating subscription information + if( $subscription['is_success'] ) { - } - else{ - $entry["payment_status"] = "Failed"; + $this->start_subscription( $entry, $subscription ); - GFFormsModel::add_note($entry["id"], 0, "System", sprintf( __("Subscription failed to be created. Reason: %s", "gravityforms") , $subscription["error_message"])); } + else { - GFFormsModel::update_lead($entry); + $entry['payment_status'] = 'Failed'; + GFAPI::update_entry( $entry ); - return $entry; - } + $this->add_note( $entry['id'], sprintf( __( 'Subscription failed to be created. Reason: %s', 'gravityforms' ), $subscription['error_message'] ), "error" ); + } + } - protected function insert_transaction($entry_id, $transaction_type, $transaction_id, $amount){ + protected function insert_transaction( $entry_id, $transaction_type, $transaction_id, $amount, $is_recurring = null ) { global $wpdb; + // @todo: make sure stats does not show setup fee as a recurring payment $payment_count = $wpdb->get_var($wpdb->prepare("SELECT count(id) FROM {$wpdb->prefix}gf_addon_payment_transaction WHERE lead_id=%d", $entry_id)); $is_recurring = $payment_count > 0 && $transaction_type == "payment" ? 1 : 0; @@ -381,16 +448,17 @@ protected function insert_transaction($entry_id, $transaction_type, $transaction return $wpdb->insert_id; } - public function get_payment_feed($entry, $form) { - $submission_feed = GFCache::get("payment_feed"); + public function get_payment_feed( $entry, $form = false ) { + + $submission_feed = GFCache::get( 'payment_feed' ); - if(!$submission_feed){ + if( ! $submission_feed ) { - if(!empty($entry["id"])){ - $feeds = $this->get_processed_feeds($entry["id"]); - $submission_feed = $this->get_feed($feeds[0]); + if( $entry['id'] ) { + $feeds = $this->get_feeds_by_entry( $entry['id'] ); + $submission_feed = $this->get_feed( $feeds[0] ); } - else{ + else if( $form ) { // getting all active feeds $feeds = $this->get_feeds( $form['id'] ); @@ -401,14 +469,19 @@ public function get_payment_feed($entry, $form) { } } } - GFCache::set("payment_feed", $submission_feed); + + // if called without $form, there is assumption that cache has already been set; let's avoid issues where the cache has not been set and form was not provided + // so that the cache will only be set when an $entry and $form object are provided + if( $entry && $form ) + GFCache::set( 'payment_feed', $submission_feed ); + } return $submission_feed; } protected function is_payment_gateway($entry_id){ - $feeds = $this->get_processed_feeds($entry_id); + $feeds = $this->get_feeds_by_entry($entry_id); return is_array($feeds) && count($feeds) > 0; } @@ -426,7 +499,7 @@ protected function get_submission_data($feed, $form, $entry){ } //getting credit card field data - $card_field = $this->get_creditcard_field($form); + $card_field = $this->get_credit_card_field($form); if($card_field){ $form_data["card_number"] = rgpost("input_{$card_field["id"]}_1"); @@ -434,10 +507,6 @@ protected function get_submission_data($feed, $form, $entry){ $form_data["card_security_code"] = rgpost("input_{$card_field["id"]}_3"); $form_data["card_name"] = rgpost("input_{$card_field["id"]}_5"); -// $names = explode(" ", $form_data["card_name"]); -// $form_data["card_first_name"] = rgar($names,0); -// $form_data["card_last_name"] = rgempty(1,$names) ? rgar($names,0) : rgar($names,1); - } //getting product field data @@ -447,21 +516,26 @@ protected function get_submission_data($feed, $form, $entry){ return $form_data; } - protected function get_creditcard_field($form){ + protected function get_credit_card_field( $form ) { $fields = GFCommon::get_fields_by_type($form, array("creditcard")); return empty($fields) ? false : $fields[0]; } - private function get_order_data($feed, $form, $entry){ + protected function has_credit_card_field( $form ) { + return $this->get_credit_card_field( $form ) !== false; + } + + protected function get_order_data($feed, $form, $entry){ $products = GFCommon::get_product_fields($form, $entry); $payment_field = $feed["meta"]["transactionType"] == "product" ? $feed["meta"]["paymentAmount"] : $feed["meta"]["recurringAmount"]; $setup_fee_field = rgar($feed["meta"],"setupFee_enabled") ? $feed["meta"]["setupFee_product"] : false; - $trial_field = rgar($feed["meta"], "trial_enabled") ? $feed["meta"]["trial_product"] : false; + $trial_field = rgar($feed["meta"], "trial_enabled") ? rgars( $feed, 'meta/trial_product' ) : false; $amount = 0; $line_items = array(); + $discounts = array(); $fee_amount = 0; $trial_amount = 0; foreach($products["products"] as $field_id => $product) @@ -496,45 +570,303 @@ private function get_order_data($feed, $form, $entry){ $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)); + $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"){ + $trial_amount = rgar($feed["meta"], "trial_amount") ? rgar($feed["meta"], "trial_amount") : 0; + } + if(!empty($products["shipping"]["name"]) && !is_numeric($payment_field)){ - $line_items[] = array("id" => "", "name"=>$products["shipping"]["name"], "description" =>"", "quantity" =>1, "unit_price"=>GFCommon::to_number($products["shipping"]["price"])); + $line_items[] = array("id" => "", "name"=>$products["shipping"]["name"], "description" =>"", "quantity" =>1, "unit_price"=>GFCommon::to_number($products["shipping"]["price"]), "is_shipping" => 1); $amount += $products["shipping"]["price"]; } - return array("payment_amount" => $amount, "setup_fee" => $fee_amount, "trial" => $trial_amount, "line_items" => $line_items); + return array("payment_amount" => $amount, "setup_fee" => $fee_amount, "trial" => $trial_amount, "line_items" => $line_items, "discounts" => $discounts); } - //--------- Callback ---------------- - public function maybe_process_callback(){ + //--------- Callback (aka Webhook)---------------- + + public function maybe_process_callback() { - //Ignoring requests that are not this addon's callbacks - if( rgget("callback") != $this->_slug || !$this->payment_method_is_overridden("callback")) + // ignoring requests that are not this addon's callbacks + if( rgget( 'callback' ) != $this->_slug ) return; + // returns either false or an array of data about the callback request which payment add-on will then use + // to generically process the callback data + GFCommon::log_debug("Initialing callback processing for: " . $this->_slug); + $result = $this->callback(); - if(is_wp_error($result)){ - status_header(500); + GFCommon::log_debug("Result from gateway callback: " . print_r($result, true)); + + if( is_array( $result ) && rgar( $result, 'type' ) ) { + $result = $this->process_callback_action( $result ); + } + + if(is_wp_error( $result )) { + $data = $result->get_error_data(); + $status = !rgempty("status_header", $data) ? $data["status_header"] : 200; + + status_header( $status ); echo $result->get_error_message(); } - else{ - status_header(200); - echo "Callback processed successfully."; + else if( !$result ){ + status_header( 200 ); + echo "Callback bypassed"; + } + else { + + status_header( 200 ); + echo 'Callback processed successfully.'; } die(); } - protected function callback(){ + /** + * Processes callback based on provided data. + * + * $action = array( + * 'type' => 'cancel_subscription', // required + * 'transaction_id' => '', // required (if payment) + * 'subscription_id' => '', // required (if subscription) + * 'amount' => '0.00', // required (some exceptions) + * 'entry_id' => 1, // required (some exceptions) + * 'transaction_type' => '', + * 'payment_status' => '', + * 'note' => '' + * ); + * + * @param [type] $data [description] + * @return [type] [description] + */ + private function process_callback_action( $action ) { + GFCommon::log_debug("Processing callback action: " . print_r($action, true)); + $action = wp_parse_args( $action, array( + 'type' => false, + 'amount' => false, + 'transaction_type' => false, + 'transaction_id' => false, + 'subscription_id' => false, + 'entry_id' => false, + 'payment_status' => false, + 'note' => false + ) ); + + $result = false; + + if(rgar($action, "id") && $this->is_duplicate_callback($action["id"])){ + return new WP_Error("duplicate", sprintf(__("This webhook has already been processed (Event Id: %s)", "gravityforms"), $action["id"])); + } + + $entry = GFAPI::get_entry( $action['entry_id'] ); + if( ! $entry || is_wp_error($entry) ) + return $result; + + switch( $action['type'] ) { + case 'complete_payment': + $result = $this->complete_payment( $entry, $action ); + break; + case 'refund_payment': + $result = $this->refund_payment( $entry, $action ); + break; + case 'cancel_subscription': + $feed = $this->get_payment_feed( $entry ); + $result = $this->cancel_subscription( $entry, $feed, $action["note"] ); + break; + case 'add_subscription_payment': + $result = $this->add_subscription_payment( $entry, $action ); + break; + case 'fail_subscription_payment': + $result = $this->fail_subscription_payment( $entry, $action ); + break; + default: + // handle custom events + if( is_callable( array( $this, rgar( $action, 'callback' ) ) ) ) + $result = call_user_func( array( $this, $action['callback'] ) ); + break; + } + + GFCommon::log_debug("Callback action successfull? {$result}"); + + if(rgar($action, "id") && $result){ + $this->register_callback($action["id"], $action['entry_id']); + } + + return $result; + } + + + protected function register_callback($callback_id, $entry_id){ + global $wpdb; + + $wpdb->insert("{$wpdb->prefix}gf_addon_payment_callback", array("addon_slug" => $this->_slug, "callback_id" => $callback_id, "lead_id" => $entry_id, "date_created" => gmdate("Y-m-d H:i:s"))); + } + + protected function is_duplicate_callback($callback_id){ + global $wpdb; + + $sql = $wpdb->prepare("SELECT id FROM {$wpdb->prefix}gf_addon_payment_callback WHERE addon_slug=%s AND callback_id=%s", $this->_slug, $callback_id); + if($wpdb->get_var($sql)) + return true; + + return false; + } + + protected function callback() { } + + + // # PAYMENT INTERACTION FUNCTIONS + + public function complete_payment( $entry, $action ) { + + if( ! $action['payment_status'] ) + $action['payment_status'] = 'Paid'; + + if( ! $action['transaction_type'] ) + $action['transaction_type'] = 'payment'; + + if( ! $action['note'] ) { + $amount_formatted = GFCommon::to_money( $action['amount'], $entry['currency'] ); + $action['note'] = sprintf( __( 'Subscription has been paid. 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" ); + + return true; + } + + public function refund_payment( $entry, $action ) { + + if( ! $action['payment_status'] ) + $action['payment_status'] = 'Refunded'; + + if( ! $action['transaction_type'] ) + $action['transaction_type'] = 'refund'; + + if( ! $action['note'] ) { + $amount_formatted = GFCommon::to_money( $action['amount'], $entry['currency'] ); + $action['note'] = sprintf( __( 'Payment has been refunded. 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'] ); + + return true; + } + + /** + * Used to start a new subscription. Updates the associcated entry with the payment and transaction details and adds an entry note. + * + * @param [array] $entry Entry object + * @param [string] $subscription_id ID of the subscription + * @param [float] $amount Numeric amount of the initial subscription payment + * @return [bool] $result + */ + public function start_subscription( $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'] = true; + + $result = GFAPI::update_entry( $entry ); + + $this->add_note( $entry['id'], sprintf( __( 'Subscription has been created. Subscription Id: %s.', 'gravityforms' ), $subscription['subscription_id'] ), "success" ); } + /** + * A payment on an existing subscription. + * + * @param [array] $data Transaction data including 'amount' and 'subscriber_id' + * @param [array] $entry Entry object + * @return [null] + */ + public function add_subscription_payment( $entry, $action ) { + + if( ! $action['transaction_type'] ) + $action['transaction_type'] = 'payment'; + + if( ! $action['note'] ) { + $amount_formatted = GFCommon::to_money( $action['amount'], $entry['currency'] ); + $action['note'] = sprintf( __( 'Subscription has been paid. Amount: %s. Subscription Id: %s', 'gravityforms' ), $amount_formatted, $action['subscription_id'] ); + } + + $transaction_id = !empty($action['transaction_id']) ? $action['transaction_id'] : $action['subscription_id']; + + $this->insert_transaction( $entry['id'], $action['transaction_type'], $transaction_id, $action['amount'] ); + $this->add_note( $entry['id'], $action['note'], "success" ); + + do_action( 'gform_post_add_subscription_payment', $entry, $action ); + + return true; + } + + public function fail_subscription_payment( $entry, $action ) { + + if( ! $action['note'] ) { + $amount_formatted = GFCommon::to_money( $action['amount'], $entry['currency'] ); + $action['note'] = sprintf( __( 'Subscription payment has failed. Amount: %s. Subscription Id: %s.', 'gravityforms' ), $amount_formatted, $action['subscription_id'] ); + } + + $this->add_note( $entry['id'], $action['note'], "error" ); + + // keep 'gform_subscription_payment_failed' for backward compatability + do_action( 'gform_subscription_payment_failed', $entry, $action['subscription_id'] ); + do_action( 'gform_post_fail_subscription_payment', $entry, $action ); + + return true; + } + + public function cancel_subscription( $entry, $feed, $note = null ) { + + if( !$note ) + $note = sprintf( __( 'Subscription has been cancelled. Subscription Id: %s.', 'gravityforms' ), $entry['transaction_id'] ); + + if( strtolower( $entry['payment_status'] ) == 'cancelled' ) { + $this->log( 'Subscription is already canceled.' ); + return false; + } + + 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 compatability + do_action( 'gform_subscription_canceled', $entry, $feed, $entry['transaction_id'] ); + + return true; + } + + protected function get_entry_by_transaction_id( $transaction_id ) { + global $wpdb; + + $sql = $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}rg_lead WHERE transaction_id = %s", $transaction_id ); + $entry_id = $wpdb->get_var( $sql ); + +// //Try transaction table +// if( empty($entry_id) ){ +// $sql = $wpdb->prepare( "SELECT lead_id FROM {$wpdb->prefix}gf_addon_payment_transaction WHERE transaction_id = %s", $transaction_id ); +// $entry_id = $wpdb->get_var( $sql ); +// } + + return $entry_id ? $entry_id : false; + } + // -------- Cron -------------------- protected function setup_cron() @@ -571,6 +903,9 @@ public function get_column_value_transactionType($feed){ case "product" : return __("Products and Services", "gravityforms"); break; + case "donation" : + return __("Donations", "gravityforms"); + break; } return __("Unsupported transaction type", "gravityforms"); @@ -578,7 +913,7 @@ public function get_column_value_transactionType($feed){ public function get_column_value_amount($feed){ $form = $this->get_current_form(); - $field_id = $feed["meta"]["transactionType"] == "subscription" ? $feed["meta"]["recurringAmount"] : $feed["meta"]["paymentAmount"]; + $field_id = $feed["meta"]["transactionType"] == "subscription" ? rgars ($feed, "meta/recurringAmount") : rgars($feed, "meta/paymentAmount"); if($field_id == "form_total"){ $label = __("Form Total", "gravityforms"); } @@ -592,11 +927,25 @@ public function get_column_value_amount($feed){ //--------- Feed Settings ---------------- + + public function feed_list_message(){ + + if( $this->_requires_credit_card && ! $this->has_credit_card_field( $this->get_current_form() ) ) { + return $this->requires_credit_card_message(); + } + return false; + } + + public function requires_credit_card_message() { + return sprintf(__( "You must add a Credit Card field to your form before creating a feed. Let's go %sadd one%s!", 'gravityforms' ), "", ""); + } + public function feed_settings_fields() { + return array( array( - //"title" => __("Feed Settings", "gravityforms"), + //"title" => __("General Settings", "gravityforms"), "description" => '', "fields" => array( array( @@ -609,7 +958,7 @@ public function feed_settings_fields() { "name"=> "transactionType", "label" => __("Transaction Type", "gravityforms"), "type" => "select", - "onchange" => "jQuery(this).parents('form').submit();", //TODO: move this to base class + "onchange" => "jQuery(this).parents('form').submit();", //@TODO: move this to base class "choices" => array( array("label" => __("Select a transaction type", "gravityforms"), "value" => ""), array("label" => __("Products and Services", "gravityforms"), "value" => "product"), @@ -647,7 +996,7 @@ public function feed_settings_fields() { array( "name" => "setupFee", "label" => __("Setup Fee", "gravityforms"), - "type" => "setup_fee", + "type" => "setup_fee" ), array( "name" => "trial", @@ -659,10 +1008,10 @@ public function feed_settings_fields() { ), array( - 'title' => 'Product & Services Settings', + 'title' => 'Products & Services Settings', 'dependency' => array( 'field' => 'transactionType', - 'values' => array( 'product' ) + 'values' => array( 'product','donation' ) ), 'fields' => array( array( @@ -670,7 +1019,8 @@ public function feed_settings_fields() { "label" => __("Payment Amount", "gravityforms"), "type" => "select", "choices" => $this->product_amount_choices(), - "required" => true + "required" => true, + "default_value" => "form_total" ) ) ), @@ -679,32 +1029,43 @@ public function feed_settings_fields() { 'title' => __( 'Other Settings', 'gravityforms' ), 'dependency' => array( 'field' => 'transactionType', - 'values' => array( 'subscription', 'product' ) + 'values' => array( 'subscription', 'product', 'donation' ) ), - 'fields' => array( - array( - "name" => "billingInformation", - "label" => __("Billing Information", "gravityforms"), - "type" => "field_map", - "field_map" => $this->billing_info_fields() - ), - array( - "name" => "options", - "label" => __("Options", "gravityforms"), - "type" => "checkbox", - "choices" => $this->option_choices() - ), - array( - "name" => "conditionalLogic", - "label" => __("Conditional Logic", "gravityforms"), - "type" => "feed_condition" - ) - ) + 'fields' => $this->other_settings_fields() ) ); } + public function other_settings_fields(){ + $other_settings = array( + array( + "name" => "billingInformation", + "label" => __("Billing Information", "gravityforms"), + "type" => "field_map", + "field_map" => $this->billing_info_fields() + ) + ); + + $option_choices = $this->option_choices(); + if(!empty($option_choices)){ + $other_settings[] = array( + "name" => "options", + "label" => __("Options", "gravityforms"), + "type" => "checkbox", + "choices" => $option_choices + ); + } + + $other_settings[] = array( + "name" => "conditionalLogic", + "label" => __("Conditional Logic", "gravityforms"), + "type" => "feed_condition" + ); + + return $other_settings; + } + public function settings_billing_cycle( $field, $echo = true ) { $intervals = $this->supported_billing_intervals(); @@ -747,6 +1108,7 @@ public function settings_billing_cycle( $field, $echo = true ) { public function settings_setup_fee( $field, $echo = true ) { $enabled_field = array( + "name" => $field["name"], "type" => "checkbox", "horizontal" => true, "choices" => array( @@ -778,17 +1140,24 @@ public function settings_setup_fee( $field, $echo = true ) { return $html; } + 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');}"; + + } + public function settings_trial( $field, $echo = true ) { //--- Enabled field --- $enabled_field = array( + "name" => $field["name"], "type" => "checkbox", "horizontal" => true, "choices" => array( array( "label" => __("Enabled", "gravityforms"), "name" => $field["name"] . "_enabled", "value"=>"1", - "onchange" => "if(jQuery(this).prop('checked')){jQuery('#{$field["name"]}_product').show('slow'); } else {jQuery('#{$field["name"]}_product').hide('slow');}" + "onchange" => $this->set_trial_onchange($field) )) ); @@ -812,7 +1181,7 @@ public function settings_trial( $field, $echo = true ) { $amount_field = array( "type" => "text", "name" => "{$field["name"]}_amount", - "class" => $this->get_setting("{$field["name"]}_product") == "enter_amount" ? "" : "hidden", + "class" => $this->get_setting("{$field["name"]}_enabled") && $this->get_setting("{$field["name"]}_product") == "enter_amount" ? "" : "hidden", ); $html .= " " . $this->settings_text($amount_field, false); @@ -884,7 +1253,7 @@ protected function supported_billing_intervals(){ return $billing_cycles; } - private function get_payment_choices($form){ + protected function get_payment_choices($form){ $fields = GFCommon::get_fields_by_type($form, array("product")); $choices = array( array("label" => __("Select a product field", "gravityforms"), "value" => "") @@ -1326,7 +1695,9 @@ protected function uninstall(){ // deleting transactions $sql = $wpdb->prepare( "DELETE FROM {$wpdb->prefix}gf_addon_payment_transaction - WHERE feed_id IN (SELECT id FROM {$wpdb->prefix}gf_addon_feed WHERE addon_slug=%s)", $this->_slug); + 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); //clear cron @@ -1349,9 +1720,10 @@ public function scripts() { "subscriptionCanceled" => __("Canceled", "gravityforms"), "subscriptionError" => __("The subscription could not be canceled. Please try again later.", "gravityforms") ), - 'enqueue' => array( array( "admin_page" => array("form_settings"), "tab" => "gravityformspaypal" ), - array( "admin_page" => array("entry_view") ) - ) + 'enqueue' => array( + array( "admin_page" => array( "form_settings" ), "tab" => $this->_slug ), + array( "admin_page" => array( "entry_view" ) ) + ) ) ); @@ -1373,13 +1745,13 @@ public function supported_currencies($currencies){ //-------- Cancel Subscription ----------- public function entry_info($form_id, $entry) { - //abort if subscription cancelation isn't supported by the addon - if(!$this->payment_method_is_overridden("cancel_subscription")) + //abort if subscription cancelation isn't supported by the addon or if it has already been canceled + if( !$this->payment_method_is_overridden("cancel") ) return; // adding cancel subscription button and script to entry info section $cancelsub_button = ""; - if($entry["transaction_type"] == "2" && $entry["payment_status"] <> "Canceled" && $this->is_payment_gateway($entry["id"])) + if($entry["transaction_type"] == "2" && $entry["payment_status"] <> "Cancelled" && $this->is_payment_gateway($entry["id"])) { ?> " class="button" onclick="cancel_subscription();"/> @@ -1393,7 +1765,7 @@ public function entry_info($form_id, $entry) { } } - public function start_cancel_subscription() { + public function ajax_cancel_subscription() { check_ajax_referer("gaddon_cancel_subscription","gaddon_cancel_subscription"); $entry_id = $_POST["entry_id"]; @@ -1402,56 +1774,93 @@ public function start_cancel_subscription() { $form = GFAPI::get_form($entry["form_id"]); $feed = $this->get_payment_feed($entry, $form); - if($this->cancel_subscription($entry, $form, $feed)) - { - $this->process_subscription_canceled($entry, $feed); - die("1"); + if( $this->cancel( $entry, $feed ) ) { + $this->cancel_subscription($entry, $feed); + die( '1' ); } - else{ - die("0"); + else { + die( '0' ); + } + + } + + //--------------- Notes ------------------ + /** + * Override this function to specify a custom avatar (i.e. the payment gateway logo) for entry notes created by the Add-On + * @return string - A fully qualified URL for the avatar + */ + public function note_avatar(){ + return false; + } + + public function notes_avatar($avatar, $note){ + if($note->user_name == $this->_short_title && empty($note->user_id) && $this->payment_method_is_overridden("note_avatar")){ + $new_avatar = $this->note_avatar(); } + return empty($new_avatar) ? $avatar : "{$this->_short_title}"; + } + + + // # HELPERS + + private function payment_method_is_overridden( $method_name, $base_class = 'GFPaymentAddOn' ){ + return parent::method_is_overridden( $method_name, $base_class ); } - protected function process_subscription_canceled($entry, $feed){ + public function authorization_error( $error_message ) { + return array( 'error_message' => $error_message, 'is_success' => false, 'is_authorized' => false ); + } - //Updating entry payment status - $entry["payment_status"] = "Canceled"; - RGFormsModel::update_lead($entry); + protected function modify_post( $post_id, $action ) { + + $result = false; + + if( ! $post_id ) + return $result; - //Delete post or mark it as a draft based on feed configuration - if(rgars($feed, "meta/update_post_action") == "draft" && !rgempty("post_id", $entry)){ - $post = get_post($entry["post_id"]); + switch( $action ) { + case 'draft': + $post = get_post( $post_id ); $post->post_status = 'draft'; - wp_update_post($post); - } - else if(rgars($feed, "meta/update_post_action") == "delete" && !rgempty("post_id", $entry)){ - wp_delete_post($entry["post_id"]); + $result = wp_update_post( $post ); + $this->log( "Set post (#{$post_id}) status to \"draft\"." ); + break; + case 'delete': + $result = wp_delete_post( $post_id ); + $this->log( "Deleted post (#{$post_id})." ); + break; } + return $result; } - protected function cancel_subscription($entry, $form, $feed){ - return true; - } + public function add_note( $entry_id, $note, $note_type = null ) { + + $user_id = 0; + $user_name = $this->_short_title; + + + GFFormsModel::add_note( $entry_id, $user_id, $user_name, $note, $note_type ); - //-------- Helpers ----------------------- - private function payment_method_is_overridden($method_name, $base_class='GFPaymentAddOn'){ - return parent::method_is_overridden($method_name, $base_class); } - public function authorization_error( $error_message ) { - return array( 'is_authorized' => false, 'error_message' => $error_message ); + public function log( $message ) { + // log it! } + } +if( ! class_exists( 'WP_List_Table' ) ) + require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); + + class GFPaymentStatsTable extends WP_List_Table { private $_rows = array(); private $_page_size = 10; private $_total_items = 0; - function __construct($columns, $rows, $total_count, $page_size) { $this->_rows = $rows; $this->_total_items = $total_count; @@ -1471,7 +1880,6 @@ function __construct($columns, $rows, $total_count, $page_size) { )); } - function prepare_items() { $this->items = $this->_rows; @@ -1486,14 +1894,13 @@ function column_default($item, $column){ return rgar($item, $column); } - function pagination( $which ) { if ( empty( $this->_pagination_args ) ) return; extract( $this->_pagination_args, EXTR_SKIP ); - $output = '' . sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . ''; + $output = '' . sprintf( _n( '1 item', '%s items', $total_items, 'gravityforms' ), number_format_i18n( $total_items ) ) . ''; $current = $this->get_pagenum(); @@ -1522,7 +1929,7 @@ function pagination( $which ) { $html_current_page = $current; $html_total_pages = sprintf( "%s", number_format_i18n( $total_pages ) ); - $page_links[] = '' . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . ''; + $page_links[] = '' . sprintf( _x( '%1$s of %2$s', 'paging', 'gravityforms' ), $html_current_page, $html_total_pages ) . ''; $page_links[] = sprintf( "%s", 'next-page' . $disable_last, diff --git a/includes/addon/class-gf-results.php b/includes/addon/class-gf-results.php index 728956e..f871f4c 100644 --- a/includes/addon/class-gf-results.php +++ b/includes/addon/class-gf-results.php @@ -1,10 +1,15 @@ _slug = $slug; $this->_title = rgar($config, "title"); + $this->_icon = rgar($config, "icon"); $this->_search_title = rgempty("search_title", $config) ? __("Results Filters", "gravityforms") : rgar($config, "search_title"); $this->_callbacks = isset($config["callbacks"]) ? $config["callbacks"] : array(); $this->_capabilities = isset($config["capabilities"]) ? $config["capabilities"] : array(); @@ -19,21 +25,32 @@ public function __construct($slug, $config) { public function init() { - if (!GFCommon::current_user_can_any($this->_capabilities)) + if( ! GFCommon::current_user_can_any( $this->_capabilities ) ) return; - //add top toolbar menu item - add_filter("gform_toolbar_menu", array($this, 'add_toolbar_menu_item'), 10, 2); - //add custom form action - add_filter("gform_form_actions", array($this, 'add_form_action'), 10, 2); - //add the results view - add_action("gform_entries_view", array($this, 'add_view'), 10, 2); + // is any GF page + if( GFForms::is_gravity_page() ) { - add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts')); + // add top toolbar menu item + add_filter( 'gform_toolbar_menu', array( $this, 'add_toolbar_menu_item' ), 10, 2 ); - require_once(GFCommon::get_base_path() . "/tooltips.php"); + // add custom form action + add_filter( 'gform_form_actions', array($this, 'add_form_action' ), 10, 2 ); + + } - add_filter('gform_tooltips', array($this, 'add_tooltips')); + // is results page + if( rgget( 'view' ) == "gf_results_{$this->_slug}" ) { + + // add the results view + add_action( 'gform_entries_view', array( $this, 'add_view' ), 10, 2 ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) ); + + // tooltips + require_once( GFCommon::get_base_path() . '/tooltips.php' ); + add_filter( 'gform_tooltips', array( $this, 'add_tooltips' ) ); + + } } @@ -91,9 +108,22 @@ public function filter_menu_items($menu_items, $form_id, $compact) { else if (rgget("page") == "gf_entries" && rgget("view") == "gf_results_" . $this->_slug) $link_class = "gf_toolbar_active"; + $id = rgget("id"); + if (empty($id)){ + //on the form list page, do not use icons + $icon = ""; + } + else{ + $icon = $this->_icon; + if (empty($icon)){ + $icon = ''; + } + } + $sub_menu_items = array(); $sub_menu_items[] = array( 'label' => $this->_title, + 'icon' => $icon, 'title' => __("View results generated by this form", "gravityforms"), 'link_class' => $link_class, 'url' => admin_url("admin.php?page=gf_entries&view=gf_results_{$this->_slug}&id={$form_id}"), @@ -118,11 +148,13 @@ public function filter_menu_items($menu_items, $form_id, $compact) { $menu_items["results"]["capabilities"] = $merged_capabilities; $menu_items["results"]["sub_menu_items"] = $merged_sub_menu_items; $menu_items["results"]["label"] = __("Results", "gravityforms"); + $menu_items["results"]["icon"] = ''; } else { // so far during the page cycle this is the only menu item for this key $menu_items["results"] = array( 'label' => $compact ? __("Results", "gravityforms") : $this->_title, + 'icon' => $icon, 'title' => __("View results generated by this form", "gravityforms"), 'url' => "", 'onclick' => "return false;", @@ -270,9 +302,9 @@ class="gresults-datepicker"
    + class="button button-primary button-large" value="">
    _callbacks["calculation"])) + if (isset($this->_callbacks["calculation"])){ $data = call_user_func($this->_callbacks["calculation"], $data, $form, $fields, $leads); + $field_data = $data["field_data"]; + } + $offset += $page_size; $entries_left -= $page_size; @@ -823,4 +858,4 @@ public static function get_default_field_results($form_id, $field, $search_crite } } -} +} \ No newline at end of file diff --git a/includes/addon/css/gaddon_results.css b/includes/addon/css/gaddon_results.css index b2264f6..0024a00 100644 --- a/includes/addon/css/gaddon_results.css +++ b/includes/addon/css/gaddon_results.css @@ -19,9 +19,9 @@ table#gquiz-results-summary td.gquiz-results-summary-data { } .gquiz-results-summary-data-box { - border: 1px solid silver; - padding: 10px; width: 75%; + padding: 15px 0; + min-width: 0; margin: auto; } @@ -37,7 +37,7 @@ table#gquiz-results-summary td.gquiz-results-summary-data { .gquiz-field-precentages-correct { float: left; - margin: 15px 0 0 50px; + margin: 8px 0 0 64px; } /* -------------------------------------*/ @@ -85,8 +85,8 @@ table#gaddon-results-summary td.gaddon-results-summary-data { } .gresults-results-field-label { - font-size:1.2em; - margin-bottom:10px; + font-size: 1.2em; + padding: 0 0 14px; } .gresults-results-field table{ @@ -250,4 +250,16 @@ td.gresults-rank-field-rank{ .gsurvey-likert-score{ margin-top:5px; -} \ No newline at end of file +} + +/* NEW */ + +#gquiz-results-summary { margin: 60px 0; } + +.gresults-chart-wrapper { border-top: 1px solid #dfdfdf; margin: 0 0 28px; } + .gquiz-field-precentages-correct + .gresults-chart-wrapper { margin: 0 0 14px; } + +.gresults-label-group { display: block; clear: right; } +.gresults-label-group .gresults-label { display: inline-block; width: 65px; } +.gresults-group-correct .gresults-value { color: green; } +.gresults-group-incorrect .gresults-value { color: red; } \ No newline at end of file diff --git a/includes/addon/css/gaddon_settings.css b/includes/addon/css/gaddon_settings.css new file mode 100644 index 0000000..62c61ac --- /dev/null +++ b/includes/addon/css/gaddon_settings.css @@ -0,0 +1,17 @@ + +.settings-field-map-table { } +.settings-field-map-table thead th { font-weight: bold; border-bottom: 1px solid #ccc; } +.settings-field-map-table tbody td { border-bottom: 1px dotted #eee; } +.settings-field-map-table select { max-width: 90%; } +.gaddon-section .required { color: #f00; } +.gaddon-setting-inline{ + display:inline; + margin-right:6px; +} + +.gaddon-section-description ol { } +.gaddon-section-description ol li { + list-style: decimal; +} + +.repeater-buttons .add-item { margin-right: 6px; } \ No newline at end of file diff --git a/includes/addon/js/repeater.js b/includes/addon/js/repeater.js new file mode 100644 index 0000000..ffd7f02 --- /dev/null +++ b/includes/addon/js/repeater.js @@ -0,0 +1,311 @@ +/** + * jQuery Repeater + * + * Easily create a section of repeatable items. + * + * 1. Include repeater.js + * 2. Define a template to be used by the repeater. + * a. Input elements should have a class "property_{i}" (do not replace {i} with an index, the script will handle this. + * b. The template should include a container for the "row" of elements. + * c. Use the {buttons} merge tag to indicate the location of the repeater buttons. + * + * Example: + *
    + * + *
    + * + * + * {buttons} + *
    + * + *
    + * + * 3. Define a "save" callback to handle how your data is saved. It will give you an array of objects representing your data. + * + */ + +jQuery.fn.repeater = function( options ) { + + var self = this, + defaults = { + template: '', + limit: 5, + items: [{}], + saveEvents: 'blur change', + saveElements: 'input, select', + addButtonMarkup: '+', + removeButtonMarkup: '-', + callbacks: { + save: function() { }, + beforeAdd: function() { }, + add: function() { }, + beforeAddNew: function() { }, + addNew: function() { }, + beforeRemove: function() { }, + remove: function() { }, + repeaterButtons: function() { return false; } + } + } + + self.options = jQuery.extend( true, {}, defaults, options ); + self.elem = jQuery( this ); + self.items = self.options.items; + self.callbacks = self.options.callbacks; + self._template = self.options.template; + + self.init = function() { + + self.stashTemplate(); + + self.elem.addClass( 'repeater' ); + self.refresh(); + + self.bindEvents(); + + return self; + } + + self.bindEvents = function() { + + self.options.saveEvents = self.getNamespacedEvents( self.options.saveEvents ); + + self.elem.off( 'click.repeater', 'a.add-item' ); + self.elem.on( 'click.repeater', 'a.add-item:not(.inactive)', function() { + self.addNewItem( this ); + }); + + self.elem.off( 'click.repeater', 'a.remove-item' ); + self.elem.on( 'click.repeater', 'a.remove-item', function( event ){ + self.removeItem( this ); + }); + + self.elem.off( self.options.saveEvents, self.options.saveElements ); + self.elem.on( self.options.saveEvents, self.options.saveElements, function() { + self.save(); + }); + + } + + self.stashTemplate = function() { + + // if no template provided or in "storage", use current HTML + if( ! self._template ) + self._template = self.elem.html(); + + // move template html into "stash" + //jQuery( 'body' ).append( '' ); + + } + + self.getStashedTemplate = function() { + return jQuery( self.elem.attr( 'id' ) + '-repeater-template').html(); + } + + self.addItem = function( item, index ) { + + var itemMarkup = self.getItemMarkup( item, index), + itemElem = jQuery( itemMarkup ).addClass( 'item-' + index ); + + self.callbacks.beforeAdd( self, itemElem, item ); + + self.append( itemElem ); + self.populateSelects( item, index ); + + self.callbacks.add( self, itemElem, item ); + + } + + self.getItemMarkup = function( item, index ) { + + var itemMarkup = self._template; + + for( var property in item ) { + + if( ! item.hasOwnProperty( property ) ) + continue; + + itemMarkup = itemMarkup.replace( /{i}/g, index ); + itemMarkup = itemMarkup.replace( '{buttons}', self.getRepeaterButtonsMarkup( index ) ); + itemMarkup = itemMarkup.replace( new RegExp( '{' + property + '}', 'g' ), item[property] ); + + } + + return itemMarkup; + } + + self.getRepeaterButtonsMarkup = function( index ) { + + var buttonsMarkup = self.callbacks.repeaterButtons( self, index ); + + if( ! buttonsMarkup ) + buttonsMarkup = self.getDefaultButtonsMarkup( index ); + + return buttonsMarkup; + } + + self.getDefaultButtonsMarkup = function( index ) { + + var cssClass = self.items.length >= self.options.limit && self.options.limit !== 0 ? 'inactive' : '', + buttons = '' + self.options.addButtonMarkup + ''; + + if( self.items.length > 1 ) + buttons += '' + self.options.removeButtonMarkup + ''; + + return '
    ' + buttons + '
    '; + } + + self.populateSelects = function( item, index ) { + + // after appending the row, check each property to see if it is a select and then populate + for( var property in item ) { + + if( ! item.hasOwnProperty( property ) ) + continue; + + var input = self.elem.find( '.' + property + '_' + index ); + if( input.is( 'select' ) ) + input.find( 'option[value="' + item[property] + '"]' ).prop( 'selected', true ); + } + + } + + self.addNewItem = function( elem ) { + + var index = jQuery( elem ).attr( 'data-index' ); + + self.callbacks.beforeAddNew( this, index ); + self.items.splice( index + 1, 0, self.getBaseObject() ); + self.callbacks.addNew( this, index ); + + self.refresh(); + + return self; + } + + self.removeItem = function( elem ) { + + var index = jQuery( elem ).attr( 'data-index' ); + + self.callbacks.beforeRemove( self, index ); + + // using delete (over splice) to maintain the correct indexes for + // the items array when saving the data from the UI + delete self.items[index]; + + self.callbacks.remove( self, index ); + + self.save().refresh(); + + } + + self.refresh = function() { + + self.elem.empty(); + + for( var i = 0; i < self.items.length; i++ ) { + self.addItem( self.items[i], i ); + } + + return self; + } + + self.save = function() { + + var keys = self.getBaseObjectKeys(), + data = []; + + for( var i = 0; i < self.items.length; i++ ) { + + if( typeof self.items[i] == 'undefined' ) + continue; + + var item = {}; + + for( var j = 0; j < keys.length; j++ ) { + + var key = keys[j], + id = '.' + key + '_' + i, + value = self.elem.find( id ).val(); + + item[key] = typeof value == 'undefined' ? false : value; + + } + + data.push( item ); + + } + + // save data to items + self.items = data; + + // save data externally via callback + self.callbacks.save( self, data ); + + return self; + } + + /** + * Loops through the current items array and retrieves the object properties of the + * first valid item object. Originally this would simply pull the object keys from + * the first index of the items array; however, when the first item has been + * 'deleted' (see the save() method), it will be undefined. + */ + self.getBaseObjectKeys = function() { + + var keys = []; + + for( var i = 0; i < self.items.length; i++ ) { + + if( typeof self.items[i] == 'undefined' ) + continue; + + for( var key in self.items[i] ) { + if( ! self.items[i].hasOwnProperty( key ) ) + continue; + keys.push( key ); + } + + break; + } + + return keys; + } + + self.getBaseObject = function() { + + var item = {}, + keys = self.getBaseObjectKeys(); + + for( var i = 0; i < keys.length; i++ ) { + item[keys[i]] = ''; + } + + return item; + } + + self.getNamespacedEvents = function( events ) { + + var events = events.split( ' ' ), + namespacedEvents = []; + + for( var i = 0; i < events.length; i++ ) { + namespacedEvents.push( events[i] + '.repeater' ); + } + + return namespacedEvents.join( ' ' ); + } + + return self.init(); +}; + +//$(this).repeater({ +// limit: 0, +// items: wpvflow.getActionRuleEvents( i ), +// template: wpvflow.getEventTemplate(), +// addImageSrc: '', +// removeImageSrc: '', +// callbacks: { +// save: wpvflow.saveActionRuleEvents +// } +//}); + diff --git a/includes/api.php b/includes/api.php index d3e69ac..36a69d5 100644 --- a/includes/api.php +++ b/includes/api.php @@ -1,4 +1,9 @@ is_active; $form["date_created"] = $form_info->date_created; + $form["is_trash"] = $form_info->is_trash; return $form; @@ -147,6 +153,59 @@ public static function update_form($form_meta, $form_id = null) { return true; } + /** + * Updates a form property - a column in the main forms table. e.g. is_trash, is_active, title + * + * @since 1.8.3.15 + * @access public + * @static + * + * @param array $form_ids The IDs of the forms to update + * @param array $property_key The name of the column in the database e.g. is_trash, is_active, title + * @param array $value The new value + * + * @return mixed Either a WP_Error instance or the result of the query + */ + public static function update_forms_property($form_ids, $property_key, $value){ + global $wpdb; + $table = GFFormsModel::get_form_table_name(); + $property_key = esc_sql($property_key); + $value = esc_sql($value); + if(!is_numeric($value)){ + $value = sprintf("'%s'", $value); + } + $in_str_arr = array_fill(0, count($form_ids), '%d'); + $in_str = join($in_str_arr, ","); + $result = $wpdb->query($wpdb->prepare( + " + UPDATE $table + SET {$property_key} = {$value} + WHERE id IN ($in_str) + ", $form_ids + ) + ); + + return $result; + } + + /** + * Updates the property of one form - columns in the main forms table. e.g. is_trash, is_active, title + * + * @since 1.8.3.15 + * @access public + * @static + * + * @param array $form_id The ID of the forms to update + * @param string|int $property_key The name of the column in the database e.g. is_trash, is_active, title + * @param string $value The new value + * + * @return mixed Either a WP_Error instance or the result of the query + */ + public static function update_form_property($form_id, $property_key, $value){ + return self::update_forms_property(array($form_id), $property_key, $value); + } + + /** * Adds multiple form objects. * @@ -449,22 +508,23 @@ public static function update_entry($entry, $entry_id = null) { // use values in the entry object if present $post_id = isset($entry["post_id"]) ? intval($entry["post_id"]) : 'NULL'; - $date_created = isset($entry["date_created"]) ? sprintf("'%s'", mysql_real_escape_string($entry["date_created"])) : "utc_timestamp()"; + $date_created = isset($entry["date_created"]) ? sprintf("'%s'", esc_sql($entry["date_created"])) : "utc_timestamp()"; $is_starred = isset($entry["is_starred"]) ? $entry["is_starred"] : 0; $is_read = isset($entry["is_read"]) ? $entry["is_read"] : 0; $ip = isset($entry["ip"]) ? $entry["ip"] : GFFormsModel::get_ip(); $source_url = isset($entry["source_url"]) ? $entry["source_url"] : GFFormsModel::get_current_page_url(); $user_agent = isset($entry["user_agent"]) ? $entry["user_agent"] : "API"; $currency = isset($entry["currency"]) ? $entry["currency"] : GFCommon::get_currency(); - $payment_status = isset($entry["payment_status"]) ? sprintf("'%s'", mysql_real_escape_string($entry["payment_status"])) : 'NULL'; + $payment_status = isset($entry["payment_status"]) ? sprintf("'%s'", esc_sql($entry["payment_status"])) : 'NULL'; $payment_date = strtotime(rgar($entry, "payment_date")) ? "'" . gmdate('Y-m-d H:i:s', strtotime("{$entry["payment_date"]}")) . "'" : "NULL"; $payment_amount = isset($entry["payment_amount"]) ? (float)$entry["payment_amount"] : 'NULL'; $payment_method = isset($entry["payment_method"]) ? $entry["payment_method"] : ''; - $transaction_id = isset($entry["transaction_id"]) ? sprintf("'%s'", mysql_real_escape_string($entry["transaction_id"])) : 'NULL'; + $transaction_id = isset($entry["transaction_id"]) ? sprintf("'%s'", esc_sql($entry["transaction_id"])) : 'NULL'; $is_fulfilled = isset($entry["is_fulfilled"]) ? intval($entry["is_fulfilled"]) : 'NULL'; + $status = isset($entry["status"]) ? $entry["status"] : "active"; global $current_user; - $user_id = isset($entry["created_by"]) ? mysql_real_escape_string($entry["created_by"]) : ""; + $user_id = isset($entry["created_by"]) ? esc_sql($entry["created_by"]) : ""; if (empty($user_id)) $user_id = $current_user && $current_user->ID ? $current_user->ID : 'NULL'; @@ -490,10 +550,11 @@ public static function update_entry($entry, $entry_id = null) { is_fulfilled = {$is_fulfilled}, created_by = {$user_id}, transaction_type = {$transaction_type}, + status = %s, payment_method = %s WHERE id = %d - ", $form_id, $is_starred, $is_read, $ip, $source_url, $user_agent, $currency, $payment_method, $entry_id)); + ", $form_id, $is_starred, $is_read, $ip, $source_url, $user_agent, $currency, $status, $payment_method, $entry_id)); if (false === $result) return new WP_Error("update_entry_properties_failed", __("There was a problem while updating the entry properties", "gravityforms"), $wpdb->last_error); @@ -580,32 +641,39 @@ public static function update_entry($entry, $entry_id = null) { public static function add_entry($entry) { global $wpdb; + if(!is_array($entry)){ + return new WP_Error("invalid_entry_object", __("The entry object must be an array", "gravityforms")); + } + // make sure the form id exists $form_id = rgar($entry, "form_id"); - if (empty($form_id)) + if (empty($form_id)){ return new WP_Error("empty_form_id", __("The form id must be specified", "gravityforms")); + } - if (false === self::form_id_exists($form_id)) + if (false === self::form_id_exists($form_id)){ return new WP_Error("invalid_form_id", __("The form for this entry does not exist", "gravityforms")); + } // use values in the entry object if present $post_id = isset($entry["post_id"]) ? intval($entry["post_id"]) : 'NULL'; - $date_created = isset($entry["date_created"]) && $entry["date_created"] != "" ? sprintf("'%s'", mysql_real_escape_string($entry["date_created"])) : "utc_timestamp()"; + $date_created = isset($entry["date_created"]) && $entry["date_created"] != "" ? sprintf("'%s'", esc_sql($entry["date_created"])) : "utc_timestamp()"; $is_starred = isset($entry["is_starred"]) ? $entry["is_starred"] : 0; $is_read = isset($entry["is_read"]) ? $entry["is_read"] : 0; $ip = isset($entry["ip"]) ? $entry["ip"] : GFFormsModel::get_ip(); $source_url = isset($entry["source_url"]) ? $entry["source_url"] : GFFormsModel::get_current_page_url(); $user_agent = isset($entry["user_agent"]) ? $entry["user_agent"] : "API"; $currency = isset($entry["currency"]) ? $entry["currency"] : GFCommon::get_currency(); - $payment_status = isset($entry["payment_status"]) ? sprintf("'%s'", mysql_real_escape_string($entry["payment_status"])) : 'NULL'; + $payment_status = isset($entry["payment_status"]) ? sprintf("'%s'", esc_sql($entry["payment_status"])) : 'NULL'; $payment_date = strtotime(rgar($entry, "payment_date")) ? sprintf("'%s'", gmdate('Y-m-d H:i:s', strtotime("{$entry["payment_date"]}"))) : "NULL"; $payment_amount = isset($entry["payment_amount"]) ? (float)$entry["payment_amount"] : 'NULL'; $payment_method = isset($entry["payment_method"]) ? $entry["payment_method"] : ''; - $transaction_id = isset($entry["transaction_id"]) ? sprintf("'%s'", mysql_real_escape_string($entry["transaction_id"])) : 'NULL'; + $transaction_id = isset($entry["transaction_id"]) ? sprintf("'%s'", esc_sql($entry["transaction_id"])) : 'NULL'; $is_fulfilled = isset($entry["is_fulfilled"]) ? intval($entry["is_fulfilled"]) : 'NULL'; + $status = isset($entry["status"]) ? $entry["status"] : "active"; global $current_user; - $user_id = isset($entry["created_by"]) ? mysql_real_escape_string($entry["created_by"]) : ""; + $user_id = isset($entry["created_by"]) ? esc_sql($entry["created_by"]) : ""; if (empty($user_id)) $user_id = $current_user && $current_user->ID ? $current_user->ID : 'NULL'; @@ -614,10 +682,10 @@ public static function add_entry($entry) { $lead_table = GFFormsModel::get_lead_table_name(); $result = $wpdb->query($wpdb->prepare(" INSERT INTO $lead_table - (form_id, post_id, date_created, is_starred, is_read, ip, source_url, user_agent, currency, payment_status, payment_date, payment_amount, transaction_id, is_fulfilled, created_by, transaction_type, payment_method) + (form_id, post_id, date_created, is_starred, is_read, ip, source_url, user_agent, currency, payment_status, payment_date, payment_amount, transaction_id, is_fulfilled, created_by, transaction_type, status, payment_method) VALUES - (%d, {$post_id}, {$date_created}, %d, %d, %s, %s, %s, %s, {$payment_status}, {$payment_date}, {$payment_amount}, {$transaction_id}, {$is_fulfilled}, {$user_id}, {$transaction_type}, %s) - ", $form_id, $is_starred, $is_read, $ip, $source_url, $user_agent, $currency, $payment_method)); + (%d, {$post_id}, {$date_created}, %d, %d, %s, %s, %s, %s, {$payment_status}, {$payment_date}, {$payment_amount}, {$transaction_id}, {$is_fulfilled}, {$user_id}, {$transaction_type}, %s, %s) + ", $form_id, $is_starred, $is_read, $ip, $source_url, $user_agent, $currency, $status, $payment_method)); if (false === $result) return new WP_Error("insert_entry_properties_failed", __("There was a problem while inserting the entry properties", "gravityforms"), $wpdb->last_error); // reading newly created lead id @@ -682,6 +750,23 @@ public static function delete_entry($entry_id) { return true; } + /** + * Updates a single property of an entry. + * + * @since 1.8.3.1 + * @access public + * @static + * + * @param int $entry_id The ID of the Entry object + * @param string $property The property of the Entry object to be updated + * @param mixed $value The value to which the property should be set + * + * @return bool Whether the entry property was updated successfully + */ + public static function update_entry_property( $entry_id, $property, $value ) { + return GFFormsModel::update_lead_property( $entry_id, $property, $value ); + } + // FEEDS ------------------------------------------------------ /** @@ -810,6 +895,23 @@ public static function add_feed($form_id, $feed_meta, $addon_slug) { return $wpdb->insert_id; } + // PERMISSIONS ------------------------------------------------ + /** + * Checks the permissions for the current user. Returns true if the current user has any of the specified capabilities. + * IMPORTANT: Call this before calling any of the other API Functions as permission checks are not performed at lower levels. + * + * @since 1.8.5.10 + * @access public + * @static + * + * @param array|string $capabilities An array of capabilities, or a single capability + * @return bool Returns true if the current user has any of the specified capabilities + */ + public static function current_user_can_any($capabilities){ + return GFCommon::current_user_can_any($capabilities); + } + + // HELPERS ---------------------------------------------------- diff --git a/includes/locking/class-gf-locking.php b/includes/locking/class-gf-locking.php index f770ee6..ff9ba72 100644 --- a/includes/locking/class-gf-locking.php +++ b/includes/locking/class-gf-locking.php @@ -1,5 +1,9 @@ 1) { $eccLevel = $mode[1]; } - + $qrTab = QRcode::text($code, false, $eccLevel); $size = count($qrTab); - + $barcode_array['num_rows'] = $size; $barcode_array['num_cols'] = $size; $barcode_array['bcode'] = array(); - + foreach ($qrTab as $line) { $arrAdd = array(); foreach(str_split($line) as $char) $arrAdd[] = ($char=='1')?1:0; $barcode_array['bcode'][] = $arrAdd; } - + return $barcode_array; } - + //---------------------------------------------------------------------- public static function clearCache() { self::$frames = array(); } - + //---------------------------------------------------------------------- public static function buildCache() { QRtools::markTime('before_build_cache'); - + $mask = new QRmask(); for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) { $frame = QRspec::newFrame($a); @@ -220,13 +224,13 @@ public static function buildCache() $fileName = QR_CACHE_DIR.'frame_'.$a.'.png'; QRimage::png(self::binarize($frame), $fileName, 1, 0); } - + $width = count($frame); $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); for ($maskNo=0; $maskNo<8; $maskNo++) $mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true); } - + QRtools::markTime('after_build_cache'); } @@ -240,12 +244,12 @@ public static function log($outfile, $err) } else { file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND); } - } + } } } - + //---------------------------------------------------------------------- - public static function dumpMask($frame) + public static function dumpMask($frame) { $width = count($frame); for($y=0;$y<$width;$y++) { @@ -254,24 +258,24 @@ public static function dumpMask($frame) } } } - + //---------------------------------------------------------------------- public static function markTime($markerId) { list($usec, $sec) = explode(" ", microtime()); $time = ((float)$usec + (float)$sec); - + if (!isset($GLOBALS['qr_time_bench'])) $GLOBALS['qr_time_bench'] = array(); - + $GLOBALS['qr_time_bench'][$markerId] = $time; } - + //---------------------------------------------------------------------- public static function timeBenchmark() { self::markTime('finish'); - + $lastTime = 0; $startTime = 0; $p = 0; @@ -286,30 +290,30 @@ public static function timeBenchmark() } else { $startTime = $thisTime; } - + $p++; $lastTime = $thisTime; } - + echo '
    - get_required_indicator( $field ); - - if( isset( $field['tooltip'] ) ) - echo ' ' . gform_tooltip( $field['tooltip'], rgar( $field, 'tooltip_class'), true ); - - ?> + single_setting_label( $field ); ?> single_setting( $field ); ?> @@ -870,6 +912,18 @@ protected function single_setting_row( $field ) { get_required_indicator( $field ); + + } + protected function single_setting_row_save( $field ) { ?> @@ -951,7 +1005,7 @@ protected static function maybe_decode_json($value) { } protected static function is_json($value) { - if (is_string($value) && substr($value, 0, 1) == '{' && is_array(json_decode($value, ARRAY_A))) + if (is_string($value) && in_array( substr($value, 0, 1), array( '{', '[' ) ) && is_array(json_decode($value, ARRAY_A))) return true; return false; @@ -1005,6 +1059,68 @@ protected function get_setting( $setting_name, $default_value = "" , $settings = return $setting; } + protected function get_mapped_field_value( $setting_name, $form, $entry, $settings = false ){ + + $field_id = $this->get_setting($setting_name, "", $settings); + + $field_type = GFFormsModel::get_input_type(GFFormsModel::get_field($form, $field_id)); + $is_field_id_integer = ctype_digit($field_id); + + if($is_field_id_integer && $field_type == "name"){ + //Full Name + $value = $this->get_full_name($entry, $field_id); + } + else if($is_field_id_integer && $field_type == "address"){ + //Full Address + $value = $this->get_full_address($entry, $field_id); + } + else{ + $value = rgar($entry, $field_id); + } + + return $value; + } + + protected function get_full_address($entry, $field_id){ + $street_value = str_replace(" ", " ", trim($entry[$field_id . ".1"])); + $street2_value = str_replace(" ", " ", trim($entry[$field_id . ".2"])); + $city_value = str_replace(" ", " ", trim($entry[$field_id . ".3"])); + $state_value = str_replace(" ", " ", trim($entry[$field_id . ".4"])); + $zip_value = trim($entry[$field_id . ".5"]); + $country_value = GFCommon::get_country_code(trim($entry[$field_id . ".6"])); + + $address = $street_value; + $address .= !empty($address) && !empty($street2_value) ? " $street2_value" : $street2_value; + $address .= !empty($address) && (!empty($city_value) || !empty($state_value)) ? ", $city_value," : $city_value; + $address .= !empty($address) && !empty($city_value) && !empty($state_value) ? " $state_value" : $state_value; + $address .= !empty($address) && !empty($zip_value) ? " $zip_value," : $zip_value; + $address .= !empty($address) && !empty($country_value) ? " $country_value" : $country_value; + + + return $address; + } + + protected function get_full_name($entry, $field_id){ + + //If field is aweber (one input), simply return full content + $name = rgar($entry,$field_id); + if(!empty($name)) + return $name; + + //Complex field (multiple inputs). Join all pieces and create name + $prefix = trim(rgar($entry,$field_id . ".2")); + $first = trim(rgar($entry,$field_id . ".3")); + $last = trim(rgar($entry,$field_id . ".6")); + $suffix = trim(rgar($entry,$field_id . ".8")); + + $name = $prefix; + $name .= !empty($name) && !empty($first) ? " $first" : $first; + $name .= !empty($name) && !empty($last) ? " $last" : $last; + $name .= !empty($name) && !empty($suffix) ? " $suffix" : $suffix; + return $name; + } + + /*** * Determines if a dependent field has been populated. * @@ -1164,6 +1280,9 @@ protected function settings_textarea($field, $echo = true) { esc_html($value) . ''; + if( $this->field_failed_validation( $field ) ) + $html .= $this->get_error_icon( $field ); + if ($echo) echo $html; @@ -1239,6 +1358,9 @@ protected function settings_checkbox( $field, $echo = true ) { } } + if( $this->field_failed_validation( $field ) ) + $html .= $this->get_error_icon( $field ); + if ($echo) echo $html; @@ -1272,20 +1394,24 @@ protected function settings_radio($field, $echo = true) { $checked = checked($selected_value, $radio_value, false); $html .= '
    - - +
    '; } } + if( $this->field_failed_validation( $field ) ) + $html .= $this->get_error_icon( $field ); + if ($echo) echo $html; @@ -1302,40 +1428,319 @@ protected function settings_radio($field, $echo = true) { */ protected function settings_select( $field, $echo = true ) { - $field["type"] = "select"; //making sure type is set to select - $attributes = $this->get_field_attributes($field); - $value = $this->get_setting($field["name"], rgar($field, "default_value")); - $name = '' . esc_attr($field["name"]); + $field['type'] = 'select'; // making sure type is set to select + $attributes = $this->get_field_attributes($field); + $value = $this->get_setting( $field['name'], rgar( $field, 'default_value' ) ); + $name = '' . esc_attr( $field['name'] ); - $options = ""; - if(is_array($field["choices"])){ - foreach( $field["choices"] as $choice ) { + $html = sprintf( + '', + '_gaddon_setting_' . $name, implode( ' ', $attributes ), $this->get_select_options( $field['choices'], $value ) + ); + + if( $this->field_failed_validation( $field ) ) + $html .= $this->get_error_icon( $field ); + + if( $echo ) + echo $html; + + return $html; + } + + public function get_select_options( $choices, $selected_value ) { + + $options = ''; + + foreach( $choices as $choice ) { + + if( isset( $choice['choices'] ) ) { + + $options .= sprintf( '%2$s', $choice['label'], $this->get_select_options( $choice['choices'], $selected_value ) ); + + } else { - if(!isset($choice["value"])) - $choice["value"] = $choice["label"]; + if( ! isset( $choice['value'] ) ) + $choice['value'] = $choice['label']; + + $options .= $this->get_select_option( $choice, $selected_value ); - $options .= ''; } + } - $html = ''; + return $options; + } - if( $this->field_failed_validation( $field ) ) - $html .= $this->get_error_icon( $field ); + protected function get_select_option( $choice, $selected_value ) { + return sprintf( '', esc_attr( $choice['value'] ), selected( $selected_value, $choice['value'], false ), $choice['label'] ); + } - if ($echo) + + //------------- Field Map Field Type -------------------------- + + public function settings_field_map( $field, $echo = true ) { + + $html = ''; + $field_map = rgar( $field, 'field_map' ); + + if( empty( $field_map ) ) + return $html; + + $form_id = rgget( 'id' ); + + $html .= ' + + + + + + + + '; + + foreach( $field['field_map'] as $child_field ) { + + if( ! $this->setting_dependency_met( rgar( $child_field, 'dependency' ) ) ) + continue; + + $child_field['name'] = $this->get_mapped_field_name( $field, $child_field['name'] ); + $required = rgar( $child_field, 'required' ) ? $this->get_required_indicator( $child_field ) : ''; + + $html .= ' + + + + '; + } + + $html .= ' + +
    ' . $this->field_map_title() . '' . __( "Form Field", "gravityforms" ) . '
    + ' . + $this->settings_field_map_select( $child_field, $form_id ) . + '
    '; + + if( $echo ) + echo $html; + + return $html; + } + + public function settings_field_map_select( $field, $form_id ) { + $field['choices'] = $this->get_field_map_choices( $form_id ); + return $this->settings_select( $field, false ); + } + + protected function field_map_title(){ + return __("Field", "gravityforms"); + } + + public static function get_field_map_choices( $form_id ) { + + $form = RGFormsModel::get_form_meta($form_id); + + $fields = array(); + + // Adding default fields + $fields[] = array( "value" => "", "label" => "" ); + $fields[] = array( "value" => "date_created" , "label" => __("Entry Date", "gravityforms") ); + $fields[] = array( "value" => "ip" , "label" => __("User IP", "gravityforms") ); + $fields[] = array( "value" => "source_url" , "label" => __("Source Url", "gravityforms") ); + $fields[] = array( "value" => "form_title" , "label" => __("Form Title", "gravityforms") ); + + // Populate entry meta + $entry_meta = GFFormsModel::get_entry_meta( $form["id"] ); + foreach( $entry_meta as $meta_key => $meta ) { + $fields[] = array( 'value' => $meta_key , 'label' => rgars($entry_meta, "{$meta_key}/label") ); + } + + // Populate form fields + if( is_array( $form["fields"] ) ) { + foreach( $form["fields"] as $field ) { + if( is_array( rgar( $field, "inputs") ) ) { + + //If this is an address field, add full name to the list + if(RGFormsModel::get_input_type($field) == "address") + $fields[] = array( 'value' => $field["id"], 'label' => GFCommon::get_label($field) . " (" . __("Full" , "gravityforms") . ")" ); + + //If this is a name field, add full name to the list + if(RGFormsModel::get_input_type($field) == "name") + $fields[] = array( 'value' => $field["id"], 'label' => GFCommon::get_label($field) . " (" . __("Full" , "gravityforms") . ")" ); + + //If this is a checkbox field, add to the list + if(RGFormsModel::get_input_type($field) == "checkbox") + $fields[] = array( 'value' => $field["id"], 'label' => GFCommon::get_label($field) . " (" . __("Selected" , "gravityforms") . ")" ); + + foreach($field["inputs"] as $input) + $fields[] = array( 'value' => $input["id"], 'label' => GFCommon::get_label($field, $input["id"]) ); + } + else if(!rgar($field,"displayOnly")){ + $fields[] = array( 'value' => $field["id"], 'label' => GFCommon::get_label($field)); + } + } + } + + return $fields; + } + + public function get_mapped_field_name( $parent_field, $field_name ) { + return "{$parent_field['name']}_{$field_name}"; + } + + public static function get_field_map_fields( $feed, $field_name ) { + + $fields = array(); + $prefix = "field_map_{$field_name}_"; + + foreach( $feed['meta'] as $name => $value ) { + if( strpos( $name, $prefix ) === 0 ) { + $name = str_replace( $prefix, '', $name ); + $fields[$name] = $value; + } + } + + return $fields; + } + + //---------------------------------------------------------------- + + + public function settings_dynamic_field_map( $field, $echo = true ) { + + $html = ''; + $form = $this->get_current_form(); + + $field = wp_parse_args( $field, array( + 'label' => false, + 'name' => false, + 'key_choices' => array(), + 'enable_custom_key' => true + ) ); + + $field['choices'] = $field['key_choices']; + if( $field['enable_custom_key'] ) + $field['choices']['_gf_add_custom'] = array( 'value' => '_gf_add_custom', 'label' => __( 'Add Custom', 'gravityforms' ) ); + + $key_field = $field; + $key_field['name'] .= '_key'; + $key_field['class'] = 'key_{i}'; + + $value_field = $field; + $value_field['name'] = '_value'; + $value_field['class'] = 'value_{i}'; + + $html .= ' + + + + + + + + + + + + + + + +
    ' . $this->field_map_title() . '' . __( 'Form Field', 'gravityforms' ) . ' 
    ' . + $this->settings_select( $key_field, false ) . + '' . + $this->settings_field_map_select( $value_field, $form['id'] ) . + '{buttons}
    '; + + $html .= $this->settings_hidden( $field, false ); + + if( $echo ) + echo $html; + + return $html; + + } + + public function settings_field_select( $field, $echo = true ) { + + $args = is_array( rgar( $field, 'args' ) ) ? rgar( $field, 'args' ) : array( rgar( $field, 'args' ) ); + + $args = wp_parse_args( $args, array( + 'append_choices' => array(), + 'disable_first_choice' => false + ) ); + + $field['choices'] = array(); + + if( ! $args['disable_first_choice'] ) + $field['choices'][] = array( 'value' => '', 'label' => '' ); + + $field['choices'] = array_merge( $field['choices'], $this->get_form_fields_as_choices( $this->get_current_form(), $args ) ); + + if( ! empty( $args['append_choices'] ) ) + $field['choices'] = array_merge( $field['choices'], $args['append_choices'] ); + + $html = $this->settings_select( $field, false ); + + if( $echo ) echo $html; return $html; } + public function get_form_fields_as_choices( $form, $args = array() ) { + + $fields = array(); + + if( ! is_array( $form['fields'] ) ) + return $fields; + + $args = wp_parse_args( $args, array( + 'field_types' => array(), + 'input_types' => array() + ) ); + + foreach( $form['fields'] as $field ) { + + $input_type = GFFormsModel::get_input_type( $field ); + + if( ! empty( $args['input_types'] ) && ! in_array( $input_type, $args['input_types'] ) ) + continue; + + if( is_array( rgar( $field, 'inputs' ) ) ) { + + // if this is an address field, add full name to the list + if( $input_type == 'address' ) + $fields[] = array( 'value' => $field['id'], 'label' => GFCommon::get_label( $field ) . ' (' . __( 'Full' , 'gravityforms' ) . ')' ); + + // if this is a name field, add full name to the list + if( $input_type == 'name' ) + $fields[] = array( 'value' => $field["id"], 'label' => GFCommon::get_label($field) . ' (' . __( 'Full', 'gravityforms' ) . ')' ); + + // if this is a checkbox field, add to the list + if( $input_type == 'checkbox' ) + $fields[] = array( 'value' => $field['id'], 'label' => GFCommon::get_label($field) . ' (' . __( 'Selected', 'gravityforms' ) . ')' ); + + foreach( $field['inputs'] as $input ) { + $fields[] = array( 'value' => $input['id'], 'label' => GFCommon::get_label( $field, $input['id'] ) ); + } + + } + else if( ! rgar( $field, 'displayOnly' ) ) { + + $fields[] = array( 'value' => $field['id'], 'label' => GFCommon::get_label( $field ) ); + + } + } + + return $fields; + } + + + + + + /*** * Renders the save button for settings pages * @@ -1444,7 +1849,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' ), $field ); + 'validation_callback', 'required', 'hidden', 'tooltip', 'dependency', "messages" ), $field ); $default_props = array( 'class' => '', // will default to gaddon-setting @@ -1534,15 +1939,34 @@ protected function validate_settings( $fields, $settings ) { if( ! $this->setting_dependency_met( rgar( $field, 'dependency' ) ) ) continue; - $field_setting = rgar( $settings, rgar( $field, 'name' ) ); - if( is_callable( rgar( $field, 'validation_callback' ) ) ) { call_user_func( rgar( $field, 'validation_callback' ), $field, $field_setting ); - } else if( rgar( $field, 'required' ) ) { - if( rgblank( $field_setting ) ) - $this->set_field_error( $field, rgar( $field, 'error_message' ) ); + continue; } + switch($field["type"]){ + case "field_map" : + + $this->validate_field_map_settings($field, $settings); + + break; + + case "checkbox" : + + $this->validate_checkbox_settings($field, $settings); + + break; + + default : + + $field_setting = rgar( $settings, rgar( $field, 'name' ) ); + + if( rgar( $field, 'required' ) && rgblank( $field_setting )) { + $this->set_field_error( $field, rgar( $field, 'error_message' ) ); + } + + break; + } } } @@ -1552,6 +1976,48 @@ protected function validate_settings( $fields, $settings ) { return $is_valid; } + protected function validate_checkbox_settings( $field, $settings ) { + + if( !rgar( $field, 'required' ) ) + return; + + if(!is_array(rgar($field, "choices"))) + return; + + foreach($field["choices"] as $choice){ + $choice_setting = rgar( $settings, rgar( $choice, 'name' ) ); + if(!empty($choice_setting)) + return; + } + + $this->set_field_error( $field, rgar( $field, 'error_message' ) ); + } + + protected function validate_field_map_settings( $field, $settings ) { + + $field_map = rgar( $field, 'field_map' ); + + if( empty( $field_map ) ) + return; + + foreach( $field_map as $child_field ) { + + if( ! $this->setting_dependency_met( rgar( $child_field, 'dependency' ) ) ) + continue; + + $child_field['name'] = $this->get_mapped_field_name( $field, $child_field['name'] ); + $setting_value = rgar( $settings, $child_field['name'] ); + + if( rgar( $child_field, 'required' ) && rgblank( $setting_value ) ) { + $this->set_field_error( $child_field ); + } else if( rgar( $child_field, 'validation_callback' ) && is_callable( rgar( $child_field, 'validation_callback' ) ) ) { + call_user_func( rgar( $child_field, 'validation_callback' ), $child_field, $field ); + } + + } + + } + /** * Sets the validation error message * Sets the error message to be displayed when a field fails validation. @@ -1663,30 +2129,80 @@ protected function remove_field( $name, $settings ) { return $settings; } - //-------------- Form settings --------------------------------------------------- + protected function replace_field( $name, $fields, $settings ) { - /** - * Initializes form settings page - * Hooks up the required scripts and actions for the Form Settings page - */ - protected function form_settings_init() { - $view = rgget("view"); - $subview = rgget("subview"); - add_action('gform_form_settings_menu', array($this, 'add_form_settings_menu'), 10, 2); - if (rgget("page") == "gf_edit_forms" && $view == "settings" && $subview == $this->_slug && $this->current_user_can_any($this->_capabilities_form_settings)) { - require_once(GFCommon::get_base_path() . "/tooltips.php"); - add_action("gform_form_settings_page_" . $this->_slug, array($this, 'form_settings_page')); + if( rgar( $fields, 'name' ) ) + $fields = array( $fields ); + + foreach( $settings as &$section ) { + for( $i = 0; $i < count( $section['fields'] ); $i++ ) { + if( $section['fields'][$i]['name'] == $name ) { + array_splice( $section['fields'], $i, 1, $fields ); + break 2; + } + } } - } - /** - * Initializes plugin settings page - * Hooks up the required scripts and actions for the Plugin Settings page - */ - protected function plugin_page_init(){ + return $settings; - if($this->current_user_can_any($this->_capabilities_plugin_page)){ - //creates the subnav left menu + } + + protected function get_field( $name, $settings ) { + foreach( $settings as $section ) { + for( $i = 0; $i < count( $section['fields'] ); $i++ ) { + if( $section['fields'][$i]['name'] == $name ) + return $section['fields'][$i]; + } + } + return false; + } + + public function build_choices( $key_value_pairs ) { + + $choices = array(); + + if( ! is_array( $key_value_pairs ) ) + return $choices; + + $first_key = key( $key_value_pairs ); + $is_numeric = is_int( $first_key ) && $first_key === 0; + + foreach( $key_value_pairs as $value => $label ) { + if( $is_numeric ) + $value = $label; + $choices[] = array( 'value' => $value, 'label' => $label ); + } + + return $choices; + } + + //-------------- Form settings --------------------------------------------------- + + /** + * Initializes form settings page + * Hooks up the required scripts and actions for the Form Settings page + */ + protected function form_settings_init() { + $view = rgget("view"); + $subview = rgget("subview"); + if($this->current_user_can_any($this->_capabilities_form_settings)){ + add_action('gform_form_settings_menu', array($this, 'add_form_settings_menu'), 10, 2); + } + + if (rgget("page") == "gf_edit_forms" && $view == "settings" && $subview == $this->_slug && $this->current_user_can_any($this->_capabilities_form_settings)) { + require_once(GFCommon::get_base_path() . "/tooltips.php"); + add_action("gform_form_settings_page_" . $this->_slug, array($this, 'form_settings_page')); + } + } + + /** + * Initializes plugin settings page + * Hooks up the required scripts and actions for the Plugin Settings page + */ + protected function plugin_page_init(){ + + if($this->current_user_can_any($this->_capabilities_plugin_page)){ + //creates the subnav left menu add_filter("gform_addon_navigation", array($this, 'create_plugin_page_menu')); } @@ -1746,6 +2262,22 @@ public function form_settings_page() { GFCommon::display_admin_message(); + $page_title = $this->form_settings_page_title(); + if(empty($page_title)){ + $page_title = rgar($sections[0], "title"); + + //using first section title as page title, so disable section title + $sections[0]["title"] = false; + } + $icon = $this->form_settings_icon(); + if (empty($icon)){ + $icon = ''; + } + + ?> +

    + render_settings( $sections ); } @@ -1821,6 +2353,23 @@ private function has_form_settings_page() { */ protected function form_settings($form){} + /** + * Custom form settings title + * Override this function to display a custom title on the Form Settings Page. + * By default, the first section in the configuration done in form_settings_fields() will be used as the page title. + * Use this function to override that behavior and add a custom page title. + */ + protected function form_settings_page_title(){ + return ""; + } + + /** + * Override this function to customize the form settings icon + */ + protected function form_settings_icon(){ + return ""; + } + /** * Checks whether the current Add-On has a plugin page. * @@ -1843,6 +2392,9 @@ protected function plugin_page_icon(){ return ""; } + /** + * Override this function to customize the plugin page title + */ protected function plugin_page_title(){ return $this->_title; } @@ -1873,6 +2425,207 @@ public function plugin_page_container(){ has_app_settings() || $this->method_is_overridden('get_app_menu_items'); + } + + /** + * Creates a top level app menu. Adds the app settings page automatically if it's configured. + * Target of the WordPress admin_menu action. + * Not intended to be overridden or called directly by add-ons. + */ + public function create_app_menu() { + + $has_full_access = current_user_can("gform_full_access"); + $min_cap = GFCommon::current_user_can_which($this->_capabilities_app_menu); + if (empty($min_cap)) + $min_cap = "gform_full_access"; + + $menu_items = $this->get_app_menu_items(); + + $addon_menus = array(); + + $addon_menus = apply_filters('gform_addon_app_navigation_' . $this->_slug, $addon_menus); + + $parent_menu = self::get_parent_menu($menu_items, $addon_menus); + + if(empty($parent_menu)){ + return; + } + + // Add a top-level left nav + $callback = isset($parent_menu["callback"]) ? $parent_menu["callback"] : array($this, "app_tab_page"); + $this->app_hook_suffix = add_menu_page($this->get_short_title(), $this->get_short_title(), $has_full_access ? "gform_full_access" : $min_cap, $parent_menu["name"], $callback, $this->get_app_menu_icon(), apply_filters('gform_app_menu_position_', "16.10")); + + add_action("load-$this->app_hook_suffix", array($this, "load_screen_options")); + + // Adding submenu pages + foreach($menu_items as $menu_item){ + $callback = isset($menu_item["callback"]) ? $menu_item["callback"] : array($this, "app_tab_page"); + add_submenu_page($parent_menu["name"], $menu_item["label"], $menu_item["label"], $has_full_access || empty($menu_item["permission"]) ? "gform_full_access" : $menu_item["permission"], $menu_item["name"], $callback); + } + + if (is_array($addon_menus)) { + foreach ($addon_menus as $addon_menu){ + add_submenu_page($parent_menu["name"], $addon_menu["label"], $addon_menu["label"], $has_full_access ? "gform_full_access" : $addon_menu["permission"], $addon_menu["name"], $addon_menu["callback"]); + } + } + + if($this->has_app_settings()){ + add_submenu_page($parent_menu["name"], __("Settings", "gravityforms"), __("Settings", "gravityforms"), $has_full_access ? "gform_full_access" : $this->_capabilities_app_settings, $this->_slug . "_settings", array($this, 'app_tab_page')); + } + + } + + /** + * Returns the parent menu item + * + * @param $menu_items + * @param $addon_menus + * + * @return array|bool The parent menu araray or false if none + */ + private function get_parent_menu($menu_items, $addon_menus) { + $parent = false; + if (GFCommon::current_user_can_any($this->_capabilities_app_menu)){ + foreach ($menu_items as $menu_item){ + if ($this->current_user_can_any($menu_item["permission"])) { + $parent = $menu_item; + break; + } + } + } elseif (is_array($addon_menus) && sizeof($addon_menus) > 0) { + foreach ($addon_menus as $addon_menu){ + if ($this->current_user_can_any($addon_menu["permission"])) { + $parent = array("name" => $addon_menu["name"], "callback" => $addon_menu["callback"]); + break; + } + } + } elseif ($this->has_app_settings() && $this->current_user_can_any($this->_capabilities_app_settings)){ + $parent = array("name" => $this->_slug . "_settings", "callback" => array($this, "app_settings")); + } + + return $parent; + } + + /** + * Override this function to create a top level app menu. + * + * e.g. + * $menu_item["name"] = "gravitycontacts"; + * $menu_item["label"] = __("Contacts", "gravitycontacts"); + * $menu_item["permission"] = "gravitycontacts_view_contacts"; + * $menu_item["callback"] = array($this, "app_menu"); + * + * @return array The array of menu items + */ + protected function get_app_menu_items(){ + return array(); + } + + + /** + * Override this function to specify a custom icon for the top level app menu. + * Accepts a dashicon class or a URL. + * + * @return string + */ + protected function get_app_menu_icon(){ return ""; } + + /** + * Override this function to load custom screen options. + * + * e.g. + * $screen = get_current_screen(); + * if(!is_object($screen) || $screen->id != $this->app_hook_suffix) + * return; + * + * if($this->is_contact_list_page()){ + * $args = array( + * 'label' => __('Contacts per page', 'gravitycontacts'), + * 'default' => 20, + * 'option' => 'gcontacts_per_page' + * ); + * add_screen_option( 'per_page', $args ); + */ + protected function load_screen_options(){ } + + + /** + * Handles the rendering of app menu items that implement the tabs UI. + * + * Not intended to be overridden or called directly by add-ons. + */ + public function app_tab_page(){ + $page = rgget("page"); + $current_tab = rgget("view"); + + if($page == $this->_slug . "_settings"){ + + $tabs = $this->get_app_settings_tabs(); + + } else { + + $menu_items = $this->get_app_menu_items(); + + $current_menu_item = false; + foreach($menu_items as $menu_item){ + if($menu_item["name"] == $page){ + $current_menu_item = $menu_item; + break; + } + } + + if(empty($current_menu_item)){ + return; + } + + if(empty($current_menu_item["tabs"])){ + return; + } + + $tabs = $current_menu_item["tabs"]; + } + + if(empty($current_tab)){ + foreach($tabs as $tab){ + if(!isset($tab["permission"]) || $this->current_user_can_any($tab["permission"])){ + $current_tab = $tab["name"]; + break; + } + } + } + + if(empty($current_tab)){ + wp_die(__("You don't have adequate permissions to view this page", "gravityforms")); + } + + foreach($tabs as $tab){ + if($tab["name"] == $current_tab && isset($tab["callback"]) && is_callable($tab["callback"])){ + if(isset($tab["permission"]) && !$this->current_user_can_any($tab["permission"])){ + wp_die(__("You don't have adequate permissions to view this page", "gravityforms")); + } + $title = isset($tab["label"]) ? $tab['label'] : $tab['name']; + $this->app_tab_page_header($tabs, $current_tab, $title, ""); + call_user_func($tab["callback"]); + $this->app_tab_page_footer(); + + return; + } + } + + $this->app_tab_page_header($tabs, $current_tab, $current_tab, ""); + $action_hook = "gform_addon_app_" . $page . "_" . str_replace(" ", "_", $current_tab); + do_action($action_hook); + $this->app_tab_page_footer(); + + } + /** * Returns the form settings for the Add-On @@ -1921,15 +2674,31 @@ protected function plugin_settings_init() { if (rgget("page") == "gf_settings" && $subview == $this->get_short_title() && $this->current_user_can_any($this->_capabilities_settings_page)) { require_once(GFCommon::get_base_path() . "/tooltips.php"); } + + add_filter('plugin_action_links', array($this, 'plugin_settings_link'),10,2); + } + + public function plugin_settings_link( $links, $file ) { + if ( $file != $this->_path ){ + return $links; + } + + array_unshift($links, 'get_short_title() . '">' . __( 'Settings', 'gravityforms' ) . ''); + + return $links; } /** * Plugin settings page */ public function plugin_settings_page() { + $icon = $this->plugin_settings_icon(); + if (empty($icon)){ + $icon = ''; + } ?> -

    plugin_settings_title() ?>

    +

    plugin_settings_title() ?>

    get_short_title() . ' ' . __( "Settings", "gravityforms" ); } + protected function plugin_settings_icon(){ + return ""; + } + /** * Override this function to add a custom settings page. */ protected function plugin_settings(){ } - /** * Checks whether the current Add-On has a settings page. * @@ -2030,10 +2802,14 @@ protected function maybe_save_plugin_settings(){ $sections = $this->plugin_settings_fields(); $is_valid = $this->validate_settings( $sections, $settings ); - if( $is_valid ) + if( $is_valid ){ $this->update_plugin_settings( $settings ); + GFCommon::add_message( $this->get_save_success_message( $sections ) ); + } + else{ + GFCommon::add_error_message( $this->get_save_error_message( $sections ) ); + } - GFCommon::add_message( $this->get_save_success_message( $sections ) ); } } @@ -2047,6 +2823,281 @@ public function plugin_settings_fields(){ return array(); } + //-------------- App Settings --------------------------------------------------- + + /** + * Returns the tabs for the settings app menu item + * + * Not intended to be overridden or called directly by add-ons. + * + * @return array|mixed|void + */ + public function get_app_settings_tabs(){ + + //build left side options, always have app Settings first and Uninstall last, put add-ons in the middle + + $setting_tabs = array(array("name" => "settings", "label" => __("Settings", "gravityforms"), "callback" => array($this, "app_settings_tab"))); + + $setting_tabs = apply_filters("gform_addon_app_settings_menu_" . $this->_slug, $setting_tabs); + + if($this->current_user_can_any($this->_capabilities_uninstall)){ + $setting_tabs[] = array("name" => "uninstall" , "label" => __("Uninstall", "gravityforms"), "callback" => array($this, "app_settings_uninstall_tab") ); + } + + ksort($setting_tabs, SORT_NUMERIC); + return $setting_tabs; + } + + /** + * Renders the app settings uninstall tab. + * + * Not intended to be overridden or called directly by add-ons. + */ + protected function app_settings_uninstall_tab(){ + + if($this->maybe_uninstall()){ + ?> +
    + _title, "", ""), "gravityforms")?> +
    + +
    + + current_user_can_any($this->_capabilities_uninstall) && (!function_exists("is_multisite") || !is_multisite() || is_super_admin())) { ?> +

    _title); ?>

    +
    + +

    +
    + _title) . '" class="button" onclick="return confirm(\'' . __("Warning! ALL settings will be deleted. This cannot be undone. \'OK\' to delete, \'Cancel\' to stop", "gravityforms") . '\');"/>'; + echo $uninstall_button; + ?> +
    + + + + +
    + + +

    + + +

    + +
    +
      + current_user_can_any($tab["permission"])){ + continue; + } + $label = isset($tab["label"]) ? $tab['label'] : $tab['name']; + ?> +
    • > + $tab["name"]))); ?>"> +
    • + +
    + +
    +
    + + +
    +
    +
    + +
    + +
    + + + + app_settings_icon(); + if (empty($icon)){ + $icon = ''; + } + ?> + +

    app_settings_title() ?>

    + + method_is_overridden('app_settings')){ + //enables plugins to override settings page by implementing a plugin_settings() function + $this->app_settings(); + } + else if($this->maybe_uninstall()){ + ?> +
    + _title, "", ""), "gravityforms")?> +
    + maybe_save_app_settings(); + + //reads main addon settings + $settings = $this->get_app_settings(); + $this->set_settings( $settings ); + + //reading addon fields + $sections = $this->app_settings_fields(); + + GFCommon::display_admin_message(); + + //rendering settings based on fields and current settings + $this->render_settings( $sections, $settings); + + } + + } + + /** + * Override this function to specific a custom app settings title + * + * @return string + */ + protected function app_settings_title(){ + return $this->get_short_title() . ' ' . __( "Settings", "gravityforms" ); + } + + /** + * Override this function to specific a custom app settings icon + * + * @return string + */ + protected function app_settings_icon(){ + return ""; + } + + /** + * Checks whether the current Add-On has a settings page. + * + * @return bool + */ + public function has_app_settings() { + return $this->method_is_overridden('app_settings_fields') || $this->method_is_overridden('app_settings'); + } + + /** + * Override this function to add a custom app settings page. + */ + protected function app_settings(){ + } + + /** + * Returns the currently saved plugin settings + * @return mixed + */ + protected function get_app_settings() { + return get_option("gravityformsaddon_" . $this->_slug . "_app_settings"); + } + + /** + * Get app setting + * Returns the app setting specified by the $setting_name parameter + * @param string $setting_name - Plugin setting to be returned + * @return mixed - Returns the specified plugin setting or null if the setting doesn't exist + */ + protected function get_app_setting($setting_name){ + $settings = $this->get_app_settings(); + return isset($settings[$setting_name]) ? $settings[$setting_name] : null; + } + + /** + * Updates app settings with the provided settings + * + * @param array $settings - App settings to be saved + */ + protected function update_app_settings($settings){ + update_option("gravityformsaddon_" . $this->_slug . "_app_settings", $settings); + } + + /** + * Saves the plugin settings if the submit button was pressed + * + */ + protected function maybe_save_app_settings(){ + + if( $this->is_save_postback() ) { + + // store a copy of the previous settings for cases where action whould only happen if value has changed + $this->set_previous_settings( $this->get_app_settings() ); + + $settings = $this->get_posted_settings(); + $sections = $this->app_settings_fields(); + $is_valid = $this->validate_settings( $sections, $settings ); + + if( $is_valid ){ + $this->update_app_settings( $settings ); + GFCommon::add_message( $this->get_save_success_message( $sections ) ); + } + else{ + GFCommon::add_error_message( $this->get_save_error_message( $sections ) ); + } + + } + + } + + /** + * Override this function to specify the settings fields to be rendered on the plugin settings page + * @return array + */ + public function app_settings_fields(){ + // should return an array of sections, each section contains a title, description and an array of fields + return array(); + } + /** * Returns an flattened array of field settings for the specified settings type ignoring sections. * @param string $settings_type The settings type. e.g. 'plugin' @@ -2339,11 +3390,20 @@ public function list_row_class($object_id, $echo = true) { return $class; } - + /** + * Checked whether an object is locked + * + * @param int|mixed $object_id The object ID + * @return bool + */ + public function is_object_locked($object_id) { + $gf_locking = new GFAddonLocking($this->get_locking_config(),$this); + return $gf_locking->is_locked($object_id); + } //-------------- Helper functions --------------------------------------------------- - protected final function method_is_overridden($method_name, $base_class="GFAddOn"){ + protected final function method_is_overridden( $method_name, $base_class = 'GFAddOn' ) { $reflector = new ReflectionMethod($this, $method_name); $name = $reflector->getDeclaringClass()->getName(); return $name !== $base_class; @@ -2563,6 +3623,25 @@ protected function is_plugin_settings($tab = ""){ } } + /** + * Returns TRUE if the current page is the app settings main page, or a specific apps settings tab (specified by the $tab parameter). Otherwise returns FALSE + * + * @param string $tab - Specifies a specific app setting page/tab. + * @return bool + */ + protected function is_app_settings($tab = ""){ + + $is_app_settings = rgget("page") == $this->_slug. "_settings"; + $is_tab = $this->_tab_matches($tab); + + if($is_app_settings && $is_tab){ + return true; + } + else{ + return false; + } + } + /** * Returns TRUE if the current page is the plugin page. Otherwise returns FALSE * @return bool diff --git a/includes/addon/class-gf-auto-upgrade.php b/includes/addon/class-gf-auto-upgrade.php index 230511f..ee4b9cb 100644 --- a/includes/addon/class-gf-auto-upgrade.php +++ b/includes/addon/class-gf-auto-upgrade.php @@ -1,4 +1,9 @@ get_feeds( $form['id'] ); - $paypal_feed = $this->get_paypal_feed( $form['id'], $entry ); - $has_payment = self::get_paypal_payment_amount($form, $entry, $paypal_feed) > 0; 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; + return $entry; } + // getting all active feeds + $feeds = $this->get_feeds( $form['id'] ); + $processed_feeds = array(); foreach ( $feeds as $feed ) { if ( $this->is_feed_condition_met( $feed, $form, $entry ) ) { @@ -138,6 +142,12 @@ public function maybe_process_feed( $entry, $form, $is_delayed = false ) { gform_update_meta( $entry["id"], "processed_feeds", $meta ); } + + return $entry; + } + + public function get_feed_by_entry( $entry_id ) { + return gform_update_meta( $entry["id"], "processed_feeds", $meta ); } public function process_feed( $feed, $entry, $form ) { @@ -213,15 +223,18 @@ public function get_current_feed_id(){ public function get_feed( $id ) { global $wpdb; - $sql = $wpdb->prepare("SELECT * FROM {$wpdb->prefix}gf_addon_feed WHERE id=%d", $id); + $sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}gf_addon_feed WHERE id=%d", $id ); + + $row = $wpdb->get_row( $sql, ARRAY_A ); + if( ! $row ) + return false; - $row = $wpdb->get_row($sql, ARRAY_A); - $row["meta"] = json_decode($row["meta"], true); + $row['meta'] = json_decode( $row['meta'], true ); return $row; } - public function get_processed_feeds($entry_id){ + public function get_feeds_by_entry($entry_id){ $processed_feeds = gform_get_meta($entry_id, "processed_feeds"); if(!$processed_feeds) return false; @@ -365,21 +378,16 @@ public function feed_list_page($form=null){ $this->process_single_action($single_action); } - $columns = $this->feed_list_columns(); - $column_value_callback = array($this, "get_column_value"); - $feeds = $this->get_feeds(rgar($form,"id")); - $bulk_actions = $this->get_bulk_actions(); - $action_links = $this->get_action_links(); - ?> +

    feed_list_title() ?>

    - _slug, $columns, $bulk_actions, $action_links, $column_value_callback); + get_feed_table( $form ); $feed_list->prepare_items(); $feed_list->display(); - ?> + @@ -395,6 +403,19 @@ public function feed_list_page($form=null){ feed_list_columns(); + $column_value_callback = array( $this, 'get_column_value' ); + $feeds = $this->get_feeds( rgar( $form, 'id' ) ); + $bulk_actions = $this->get_bulk_actions(); + $action_links = $this->get_action_links(); + $no_item_callback = array($this, "feed_list_no_item_message"); + $message_callback = array($this, "feed_list_message"); + + return new GFAddOnFeedsTable( $feeds, $this->_slug, $columns, $bulk_actions, $action_links, $column_value_callback, $no_item_callback, $message_callback ); + } + public function feed_list_title(){ $url = add_query_arg(array("fid" => "0")); return $this->get_short_title() . " " . __("Feeds", "gravityforms") . " " . __("Add New", "gravityforms") . ""; @@ -405,12 +426,13 @@ protected function maybe_save_feed_settings( $feed_id, $form_id ){ if( ! rgpost( 'gform-settings-save' ) ) return $feed_id; - // store a copy of the previous settings for cases where action whould only happen if value has changed + // store a copy of the previous settings for cases where action would only happen if value has changed $feed = $this->get_feed( $feed_id ); $this->set_previous_settings( $feed['meta'] ); $settings = $this->get_posted_settings(); $sections = $this->get_feed_settings_fields(); + $settings = $this->trim_conditional_logic_vales($settings, $form_id); $is_valid = $this->validate_settings( $sections, $settings ); $result = false; @@ -431,6 +453,16 @@ protected function maybe_save_feed_settings( $feed_id, $form_id ){ return $feed_id; } + protected function trim_conditional_logic_vales($settings, $form_id){ + if(!is_array($settings)) + return $settings; + if(isset($settings["feed_condition_conditional_logic_object"]) && is_array($settings["feed_condition_conditional_logic_object"])){ + $form = GFFormsModel::get_form_meta($form_id); + $settings["feed_condition_conditional_logic_object"] = GFFormsModel::trim_conditional_logic_values_from_element($settings["feed_condition_conditional_logic_object"], $form); + } + return $settings; + } + protected function get_save_success_message( $sections ) { $save_button = $this->get_save_button($sections); return isset($save_button["messages"]["success"]) ? $save_button["messages"]["success"] : __("Feed updated successfully.", "gravityforms") ; @@ -472,14 +504,11 @@ public function add_default_feed_settings_fields_props( $fields ) { foreach( $fields as &$section ) { foreach( $section['fields'] as &$field ) { switch( $field['type'] ) { - case 'field_map': - if( !rgar( $field, 'validation_callback' ) ) - $field['validation_callback'] = array( $this, 'validate_feed_map_settings' ); - break; - case 'hidden': - $field['hidden'] = true; - break; - } + + case 'hidden': + $field['hidden'] = true; + break; + } } } @@ -540,6 +569,22 @@ protected function feed_list_columns() { return array(); } + /** + * Override this function to change the message that is displayed when the feed list is empty + * @return string The message + */ + public function feed_list_no_item_message(){ + return sprintf(__("You don't have any feeds configured. Let's go %screate one%s!", "gravityforms"), "", ""); + } + + /** + * Override this function to force a message to be displayed in the feed list (instead of data). Useful to alert users when main plugin settings haven't been completed. + * @return string|false + */ + public function feed_list_message(){ + return false; + } + public function get_column_value($item, $column) { if(is_callable(array($this, "get_column_value_{$column}"))){ return call_user_func(array($this, "get_column_value_{$column}"), $item); @@ -552,6 +597,8 @@ public function get_column_value($item, $column) { } } + + protected function update_form_settings($form, $new_form_settings) { $feed_id = rgar($new_form_settings, "id"); foreach ($new_form_settings as $key => $value) { @@ -587,8 +634,15 @@ protected function settings_feed_condition( $field, $echo = true ) { ), 'onclick' => 'ToggleConditionalLogic( false, "feed_condition" );' ); + $conditional_logic_object = $this->get_setting( 'feed_condition_conditional_logic_object' ); + if($conditional_logic_object){ + $form_id = rgget("id"); + $form = GFFormsModel::get_form_meta($form_id); + $conditional_logic = json_encode( GFFormsModel::trim_conditional_logic_values_from_element($conditional_logic_object, $form) ) ; + } else { + $conditional_logic = '{}'; + } - $conditional_logic = $this->get_setting( 'feed_condition_conditional_logic_object' ) ? json_encode( $this->get_setting( 'feed_condition_conditional_logic_object' ) ) : '{}'; $hidden_field = array( 'name' => 'feed_condition_conditional_logic_object', 'value' => $conditional_logic @@ -608,114 +662,6 @@ protected function settings_feed_condition( $field, $echo = true ) { return $html; } - protected function field_map_title(){ - return __("Field", "gravityforms"); - } - - public function settings_field_map( $field, $echo = true ) { - - $html = ''; - $field_map = rgar( $field, 'field_map' ); - - if( empty( $field_map ) ) - return $html; - - $form_id = rgget( 'id' ); - - $html .= ' - - - - - - - - '; - - foreach( $field['field_map'] as $child_field ) { - - if( ! $this->setting_dependency_met( rgar( $child_field, 'dependency' ) ) ) - continue; - - $child_field['name'] = $this->get_mapped_field_name( $field, $child_field['name'] ); - $required = rgar( $child_field, 'required' ) ? $this->get_required_indicator( $child_field ) : ''; - - $html .= ' - - - - '; - } - - $html .= ' - -
    ' . $this->field_map_title() . '' . __("Form Field", "gravityforms") . '
    - ' . - $this->settings_field_map_select( $child_field, $form_id ) . - '
    '; - - if( $echo ) - echo $html; - - return $html; - } - - public function settings_field_map_select( $field, $form_id ) { - - $field['choices'] = self::get_field_map_choices( $form_id ); - - return $this->settings_select( $field, false ); - } - - public static function get_field_map_choices( $form_id ) { - - $form = RGFormsModel::get_form_meta($form_id); - - $fields = array(); - - // Adding default fields - $fields[] = array( "value" => "", "label" => "" ); - $fields[] = array( "value" => "date_created" , "label" => __("Entry Date", "gravityforms") ); - $fields[] = array( "value" => "ip" , "label" => __("User IP", "gravityforms") ); - $fields[] = array( "value" => "source_url" , "label" => __("Source Url", "gravityforms") ); - $fields[] = array( "value" => "form_title" , "label" => __("Form Title", "gravityforms") ); - - // Populate entry meta - $entry_meta = GFFormsModel::get_entry_meta( $form["id"] ); - foreach( $entry_meta as $meta_key => $meta ) { - $fields[] = array( 'value' => $meta_key , 'label' => rgars($entry_meta, "{$meta_key}/label") ); - } - - // Populate form fields - if( is_array( $form["fields"] ) ) { - foreach( $form["fields"] as $field ) { - if( is_array( rgar( $field, "inputs") ) ) { - - //If this is an address field, add full name to the list - if(RGFormsModel::get_input_type($field) == "address") - $fields[] = array( 'value' => $field["id"], 'label' => GFCommon::get_label($field) . " (" . __("Full" , "gravityforms") . ")" ); - - //If this is a name field, add full name to the list - if(RGFormsModel::get_input_type($field) == "name") - $fields[] = array( 'value' => $field["id"], 'label' => GFCommon::get_label($field) . " (" . __("Full" , "gravityforms") . ")" ); - - //If this is a checkbox field, add to the list - if(RGFormsModel::get_input_type($field) == "checkbox") - $fields[] = array( 'value' => $field["id"], 'label' => GFCommon::get_label($field) . " (" . __("Selected" , "gravityforms") . ")" ); - - foreach($field["inputs"] as $input) - $fields[] = array( 'value' => $input["id"], 'label' => GFCommon::get_label($field, $input["id"]) ); - } - else if(!rgar($field,"displayOnly")){ - $fields[] = array( 'value' => $field["id"], 'label' => GFCommon::get_label($field)); - } - } - } - - return $fields; - } - public static function add_entry_meta($form){ $entry_meta = GFFormsModel::get_entry_meta($form["id"]); $keys = array_keys($entry_meta); @@ -725,51 +671,6 @@ public static function add_entry_meta($form){ return $form; } - public function get_mapped_field_name( $parent_field, $field_name ) { - return "{$parent_field['name']}_{$field_name}"; - } - - public function validate_feed_map_settings( $field ) { - - $settings = $this->get_posted_settings(); - $field_map = rgar( $field, 'field_map' ); - - if( empty( $field_map ) ) - return; - - foreach( $field_map as $child_field ) { - - if( ! $this->setting_dependency_met( rgar( $child_field, 'dependency' ) ) ) - continue; - - $child_field['name'] = $this->get_mapped_field_name( $field, $child_field['name'] ); - $setting_value = rgar( $settings, $child_field['name'] ); - - if( rgar( $child_field, 'required' ) && rgblank( $setting_value ) ) { - $this->set_field_error( $child_field ); - } else if( rgar( $child_field, 'validation_callback' ) && is_callable( rgar( $child_field, 'validation_callback' ) ) ) { - call_user_func( rgar( $child_field, 'validation_callback' ), $child_field, $field ); - } - - } - - } - - public static function get_field_map_fields( $feed, $field_name ) { - - $fields = array(); - $prefix = "field_map_{$field_name}_"; - - foreach( $feed['meta'] as $name => $value ) { - if( strpos( $name, $prefix ) === 0 ) { - $name = str_replace( $prefix, '', $name ); - $fields[$name] = $value; - } - } - - return $fields; - } - protected function has_feed_condition_field() { $fields = $this->settings_fields_only( 'feed' ); @@ -910,16 +811,17 @@ protected function has_feed( $form_id ) { class GFAddOnFeedsTable extends WP_List_Table { - public $_column_value_callback = array(); - public $_no_items_callback = array(); - private $_feeds; private $_slug; private $_columns; private $_bulk_actions; private $_action_links; - function __construct($feeds, $slug, $columns = array(), $bulk_actions, $action_links, $column_value_callback, $no_items_callback=null) { + private $_column_value_callback = array(); + private $_no_items_callback = array(); + private $_message_callback = array(); + + function __construct($feeds, $slug, $columns = array(), $bulk_actions, $action_links, $column_value_callback, $no_items_callback, $message_callback) { $this->_bulk_actions = $bulk_actions; $this->_feeds = $feeds; $this->_slug = $slug; @@ -927,6 +829,7 @@ function __construct($feeds, $slug, $columns = array(), $bulk_actions, $action_l $this->_column_value_callback = $column_value_callback; $this->_action_links = $action_links; $this->_no_items_callback = $no_items_callback; + $this->_message_callback = $message_callback; $standard_cols = array( 'cb' => __('Checkbox', 'gravityforms'), @@ -957,13 +860,26 @@ function get_bulk_actions() { } function no_items() { - $default = sprintf(__("You don't have any feeds configured. Let's go %screate one%s", "gravityforms"), "", ""); - $message = is_callable($this->_no_items_callback) ? $value = call_user_func($this->_no_items_callback) : $default; + echo call_user_func($this->_no_items_callback); + } + + function display_rows_or_placeholder() { + $message = call_user_func($this->_message_callback); + + if( $message !== false) { + ?> +
    + +
    TOTAL: '.number_format($lastTime-$startTime, 6).'s
    '; } - + } - + //########################################################################## - + QRtools::markTime('start'); - - - - -//---- qrspec.php ----------------------------- - - - + + + + +//---- qrspec.php ----------------------------- + + + /* * PHP QR Code encoder @@ -325,7 +329,7 @@ public static function timeBenchmark() * The following data / specifications are taken from * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) * or - * "Automatic identification and data capture techniques -- + * "Automatic identification and data capture techniques -- * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) * * This library is free software; you can redistribute it and/or @@ -342,7 +346,7 @@ public static function timeBenchmark() * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - + define('QRSPEC_VERSION_MAX', 40); define('QRSPEC_WIDTH_MAX', 177); @@ -352,7 +356,7 @@ public static function timeBenchmark() define('QRCAP_EC', 3); class QRspec { - + public static $capacity = array( array( 0, 0, 0, array( 0, 0, 0, 0)), array( 21, 26, 0, array( 7, 10, 13, 17)), // 1 @@ -396,59 +400,59 @@ class QRspec { array(173, 3532, 0, array( 720, 1316, 1950, 2310)), array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40 ); - + //---------------------------------------------------------------------- public static function getDataLength($version, $level) { return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level]; } - + //---------------------------------------------------------------------- public static function getECCLength($version, $level) { return self::$capacity[$version][QRCAP_EC][$level]; } - + //---------------------------------------------------------------------- public static function getWidth($version) { return self::$capacity[$version][QRCAP_WIDTH]; } - + //---------------------------------------------------------------------- public static function getRemainder($version) { return self::$capacity[$version][QRCAP_REMINDER]; } - + //---------------------------------------------------------------------- public static function getMinimumVersion($size, $level) { for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) { $words = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level]; - if($words >= $size) + if($words >= $size) return $i; } return -1; } - + //###################################################################### - + public static $lengthTableBits = array( array(10, 12, 14), array( 9, 11, 13), array( 8, 16, 16), array( 8, 10, 12) ); - + //---------------------------------------------------------------------- public static function lengthIndicator($mode, $version) { if ($mode == QR_MODE_STRUCTURE) return 0; - + if ($version <= 9) { $l = 0; } else if ($version <= 26) { @@ -459,13 +463,13 @@ public static function lengthIndicator($mode, $version) return self::$lengthTableBits[$mode][$l]; } - + //---------------------------------------------------------------------- public static function maximumWords($mode, $version) { - if($mode == QR_MODE_STRUCTURE) + if($mode == QR_MODE_STRUCTURE) return 3; - + if($version <= 9) { $l = 0; } else if($version <= 26) { @@ -476,7 +480,7 @@ public static function maximumWords($mode, $version) $bits = self::$lengthTableBits[$mode][$l]; $words = (1 << $bits) - 1; - + if($mode == QR_MODE_KANJI) { $words *= 2; // the number of bytes is required } @@ -530,11 +534,11 @@ public static function maximumWords($mode, $version) array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)), array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)), array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)),//40 - ); + ); //---------------------------------------------------------------------- // CACHEABLE!!! - + public static function getEccSpec($version, $level, array &$spec) { if (count($spec) < 5) { @@ -550,7 +554,7 @@ public static function getEccSpec($version, $level, array &$spec) $spec[0] = $b1; $spec[1] = (int)($data / $b1); $spec[2] = (int)($ecc / $b1); - $spec[3] = 0; + $spec[3] = 0; $spec[4] = 0; } else { $spec[0] = $b1; @@ -564,13 +568,13 @@ public static function getEccSpec($version, $level, array &$spec) // Alignment pattern --------------------------------------------------- // Positions of alignment patterns. - // This array includes only the second and the third position of the - // alignment patterns. Rest of them can be calculated from the distance + // This array includes only the second and the third position of the + // alignment patterns. Rest of them can be calculated from the distance // between them. - + // See Table 1 in Appendix E (pp.71) of JIS X0510:2004. - - public static $alignmentPattern = array( + + public static $alignmentPattern = array( array( 0, 0), array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5 array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10 @@ -580,9 +584,9 @@ public static function getEccSpec($version, $level, array &$spec) array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30 array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35 array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40 - ); + ); + - /** -------------------------------------------------------------------- * Put an alignment marker. * @param frame @@ -597,11 +601,11 @@ public static function putAlignmentMarker(array &$frame, $ox, $oy) "\xa1\xa0\xa1\xa0\xa1", "\xa1\xa0\xa0\xa0\xa1", "\xa1\xa1\xa1\xa1\xa1" - ); - - $yStart = $oy-2; + ); + + $yStart = $oy-2; $xStart = $ox-2; - + for($y=0; $y<5; $y++) { QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]); } @@ -649,9 +653,9 @@ public static function putAlignmentPattern($version, &$frame, $width) // Version information pattern (BCH coded). // See Table 1 in Appendix D (pp.68) of JIS X0510:2004. - + // size: [QRSPEC_VERSION_MAX - 6] - + public static $versionPattern = array( 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, @@ -671,7 +675,7 @@ public static function getVersionPattern($version) // Format information -------------------------------------------------- // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib) - + public static $formatInfo = array( array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976), array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0), @@ -683,16 +687,16 @@ public static function getFormatInfo($mask, $level) { if($mask < 0 || $mask > 7) return 0; - + if($level < 0 || $level > 3) - return 0; + return 0; return self::$formatInfo[$level][$mask]; } // Frame --------------------------------------------------------------- // Cache of initial frames. - + public static $frames = array(); /** -------------------------------------------------------------------- @@ -711,8 +715,8 @@ public static function putFinderPattern(&$frame, $ox, $oy) "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", "\xc1\xc1\xc1\xc1\xc1\xc1\xc1" - ); - + ); + for($y=0; $y<7; $y++) { QRstr::set($frame, $ox, $oy+$y, $finder[$y]); } @@ -729,28 +733,28 @@ public static function createFrame($version) self::putFinderPattern($frame, 0, 0); self::putFinderPattern($frame, $width - 7, 0); self::putFinderPattern($frame, 0, $width - 7); - + // Separator $yOffset = $width - 7; - + for($y=0; $y<7; $y++) { $frame[$y][7] = "\xc0"; $frame[$y][$width - 8] = "\xc0"; $frame[$yOffset][7] = "\xc0"; $yOffset++; } - + $setPattern = str_repeat("\xc0", 8); - + QRstr::set($frame, 0, 7, $setPattern); QRstr::set($frame, $width-8, 7, $setPattern); QRstr::set($frame, 0, $width - 8, $setPattern); - + // Format info $setPattern = str_repeat("\x84", 9); QRstr::set($frame, 0, 8, $setPattern); QRstr::set($frame, $width - 8, 8, $setPattern, 8); - + $yOffset = $width - 8; for($y=0; $y<8; $y++,$yOffset++) { @@ -758,22 +762,22 @@ public static function createFrame($version) $frame[$yOffset][8] = "\x84"; } - // Timing pattern - + // Timing pattern + for($i=1; $i<$width-15; $i++) { $frame[6][7+$i] = chr(0x90 | ($i & 1)); $frame[7+$i][6] = chr(0x90 | ($i & 1)); } - - // Alignment pattern + + // Alignment pattern self::putAlignmentPattern($version, $frame, $width); - - // Version information + + // Version information if($version >= 7) { $vinf = self::getVersionPattern($version); $v = $vinf; - + for($x=0; $x<6; $x++) { for($y=0; $y<3; $y++) { $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1)); @@ -789,10 +793,10 @@ public static function createFrame($version) } } } - - // and a little bit... + + // and a little bit... $frame[$width - 8][8] = "\x81"; - + return $frame; } @@ -800,12 +804,12 @@ public static function createFrame($version) public static function debug($frame, $binary_mode = false) { if ($binary_mode) { - + foreach ($frame as &$frameLine) { $frameLine = join('  ', explode('0', $frameLine)); $frameLine = join('██', explode('1', $frameLine)); } - + ?> -


            '; - echo join("
            ", $frame); - echo '






    '; - - } else { - - foreach ($frame as &$frameLine) { - $frameLine = join(' ', explode("\xc0", $frameLine)); - $frameLine = join('', explode("\xc1", $frameLine)); - $frameLine = join(' ', explode("\xa0", $frameLine)); - $frameLine = join('', explode("\xa1", $frameLine)); - $frameLine = join('', explode("\x84", $frameLine)); //format 0 - $frameLine = join('', explode("\x85", $frameLine)); //format 1 - $frameLine = join('', explode("\x81", $frameLine)); //special bit - $frameLine = join(' ', explode("\x90", $frameLine)); //clock 0 - $frameLine = join('', explode("\x91", $frameLine)); //clock 1 - $frameLine = join(' ', explode("\x88", $frameLine)); //version - $frameLine = join('', explode("\x89", $frameLine)); //version - $frameLine = join('♦', explode("\x01", $frameLine)); - $frameLine = join('⋅', explode("\0", $frameLine)); - } - - ?> - - "; - echo join("
    ", $frame); - echo "
    "; - - } - } - - //---------------------------------------------------------------------- - public static function serial($frame) - { - return gzcompress(join("\n", $frame), 9); - } - - //---------------------------------------------------------------------- - public static function unserial($code) - { - return explode("\n", gzuncompress($code)); - } - - //---------------------------------------------------------------------- - public static function newFrame($version) - { - if($version < 1 || $version > QRSPEC_VERSION_MAX) - return null; - - if(!isset(self::$frames[$version])) { - - $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat'; - - if (QR_CACHEABLE) { - if (file_exists($fileName)) { - self::$frames[$version] = self::unserial(file_get_contents($fileName)); - } else { - self::$frames[$version] = self::createFrame($version); - file_put_contents($fileName, self::serial(self::$frames[$version])); - } - } else { - self::$frames[$version] = self::createFrame($version); - } - } - - if(is_null(self::$frames[$version])) - return null; - - return self::$frames[$version]; - } - - //---------------------------------------------------------------------- - public static function rsBlockNum($spec) { return $spec[0] + $spec[3]; } - public static function rsBlockNum1($spec) { return $spec[0]; } - public static function rsDataCodes1($spec) { return $spec[1]; } - public static function rsEccCodes1($spec) { return $spec[2]; } - public static function rsBlockNum2($spec) { return $spec[3]; } - public static function rsDataCodes2($spec) { return $spec[4]; } - public static function rsEccCodes2($spec) { return $spec[2]; } - public static function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); } - public static function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; } - - } - - - -//---- qrimage.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Image output of code using GD2 - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - define('QR_IMAGE', true); - - class QRimage { - - //---------------------------------------------------------------------- - public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE) - { - $image = self::image($frame, $pixelPerPoint, $outerFrame); - - if ($filename === false) { - Header("Content-type: image/png"); - ImagePng($image); - } else { - if($saveandprint===TRUE){ - ImagePng($image, $filename); - header("Content-type: image/png"); - ImagePng($image); - }else{ - ImagePng($image, $filename); - } - } - - ImageDestroy($image); - } - - //---------------------------------------------------------------------- - public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85) - { - $image = self::image($frame, $pixelPerPoint, $outerFrame); - - if ($filename === false) { - Header("Content-type: image/jpeg"); - ImageJpeg($image, null, $q); - } else { - ImageJpeg($image, $filename, $q); - } - - ImageDestroy($image); - } - - //---------------------------------------------------------------------- - private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4) - { - $h = count($frame); - $w = strlen($frame[0]); - - $imgW = $w + 2*$outerFrame; - $imgH = $h + 2*$outerFrame; - - $base_image =ImageCreate($imgW, $imgH); - - $col[0] = ImageColorAllocate($base_image,255,255,255); - $col[1] = ImageColorAllocate($base_image,0,0,0); - - imagefill($base_image, 0, 0, $col[0]); - - for($y=0; $y<$h; $y++) { - for($x=0; $x<$w; $x++) { - if ($frame[$y][$x] == '1') { - ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]); - } - } - } - - $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint); - ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH); - ImageDestroy($base_image); - - return $target_image; - } - } - - - -//---- qrinput.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Input encoding class - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - define('STRUCTURE_HEADER_BITS', 20); - define('MAX_STRUCTURED_SYMBOLS', 16); - - class QRinputItem { - - public $mode; - public $size; - public $data; - public $bstream; - - public function __construct($mode, $size, $data, $bstream = null) - { - $setData = array_slice($data, 0, $size); - - if (count($setData) < $size) { - $setData = array_merge($setData, array_fill(0,$size-count($setData),0)); - } - - if(!QRinput::check($mode, $size, $setData)) { - throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData)); - return null; - } - - $this->mode = $mode; - $this->size = $size; - $this->data = $setData; - $this->bstream = $bstream; - } - - //---------------------------------------------------------------------- - public function encodeModeNum($version) - { - try { - - $words = (int)($this->size / 3); - $bs = new QRbitstream(); - - $val = 0x1; - $bs->appendNum(4, $val); - $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size); - - for($i=0; $i<$words; $i++) { - $val = (ord($this->data[$i*3 ]) - ord('0')) * 100; - $val += (ord($this->data[$i*3+1]) - ord('0')) * 10; - $val += (ord($this->data[$i*3+2]) - ord('0')); - $bs->appendNum(10, $val); - } - - if($this->size - $words * 3 == 1) { - $val = ord($this->data[$words*3]) - ord('0'); - $bs->appendNum(4, $val); - } else if($this->size - $words * 3 == 2) { - $val = (ord($this->data[$words*3 ]) - ord('0')) * 10; - $val += (ord($this->data[$words*3+1]) - ord('0')); - $bs->appendNum(7, $val); - } - - $this->bstream = $bs; - return 0; - - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function encodeModeAn($version) - { - try { - $words = (int)($this->size / 2); - $bs = new QRbitstream(); - - $bs->appendNum(4, 0x02); - $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size); - - for($i=0; $i<$words; $i++) { - $val = (int)QRinput::lookAnTable(ord($this->data[$i*2 ])) * 45; - $val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1])); - - $bs->appendNum(11, $val); - } - - if($this->size & 1) { - $val = QRinput::lookAnTable(ord($this->data[$words * 2])); - $bs->appendNum(6, $val); - } - - $this->bstream = $bs; - return 0; - - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function encodeMode8($version) - { - try { - $bs = new QRbitstream(); - - $bs->appendNum(4, 0x4); - $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size); - - for($i=0; $i<$this->size; $i++) { - $bs->appendNum(8, ord($this->data[$i])); - } - - $this->bstream = $bs; - return 0; - - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function encodeModeKanji($version) - { - try { - - $bs = new QRbitrtream(); - - $bs->appendNum(4, 0x8); - $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2)); - - for($i=0; $i<$this->size; $i+=2) { - $val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]); - if($val <= 0x9ffc) { - $val -= 0x8140; - } else { - $val -= 0xc140; - } - - $h = ($val >> 8) * 0xc0; - $val = ($val & 0xff) + $h; - - $bs->appendNum(13, $val); - } - - $this->bstream = $bs; - return 0; - - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function encodeModeStructure() - { - try { - $bs = new QRbitstream(); - - $bs->appendNum(4, 0x03); - $bs->appendNum(4, ord($this->data[1]) - 1); - $bs->appendNum(4, ord($this->data[0]) - 1); - $bs->appendNum(8, ord($this->data[2])); - - $this->bstream = $bs; - return 0; - - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function estimateBitStreamSizeOfEntry($version) - { - $bits = 0; - - if($version == 0) - $version = 1; - - switch($this->mode) { - case QR_MODE_NUM: $bits = QRinput::estimateBitsModeNum($this->size); break; - case QR_MODE_AN: $bits = QRinput::estimateBitsModeAn($this->size); break; - case QR_MODE_8: $bits = QRinput::estimateBitsMode8($this->size); break; - case QR_MODE_KANJI: $bits = QRinput::estimateBitsModeKanji($this->size);break; - case QR_MODE_STRUCTURE: return STRUCTURE_HEADER_BITS; - default: - return 0; - } - - $l = QRspec::lengthIndicator($this->mode, $version); - $m = 1 << $l; - $num = (int)(($this->size + $m - 1) / $m); - - $bits += $num * (4 + $l); - - return $bits; - } - - //---------------------------------------------------------------------- - public function encodeBitStream($version) - { - try { - - unset($this->bstream); - $words = QRspec::maximumWords($this->mode, $version); - - if($this->size > $words) { - - $st1 = new QRinputItem($this->mode, $words, $this->data); - $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words)); - - $st1->encodeBitStream($version); - $st2->encodeBitStream($version); - - $this->bstream = new QRbitstream(); - $this->bstream->append($st1->bstream); - $this->bstream->append($st2->bstream); - - unset($st1); - unset($st2); - - } else { - - $ret = 0; - - switch($this->mode) { - case QR_MODE_NUM: $ret = $this->encodeModeNum($version); break; - case QR_MODE_AN: $ret = $this->encodeModeAn($version); break; - case QR_MODE_8: $ret = $this->encodeMode8($version); break; - case QR_MODE_KANJI: $ret = $this->encodeModeKanji($version);break; - case QR_MODE_STRUCTURE: $ret = $this->encodeModeStructure(); break; - - default: - break; - } - - if($ret < 0) - return -1; - } - - return $this->bstream->size(); - - } catch (Exception $e) { - return -1; - } - } - }; - - //########################################################################## - - class QRinput { - - public $items; - - private $version; - private $level; - - //---------------------------------------------------------------------- - public function __construct($version = 0, $level = QR_ECLEVEL_L) - { - if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) { - throw new Exception('Invalid version no'); - return NULL; - } - - $this->version = $version; - $this->level = $level; - } - - //---------------------------------------------------------------------- - public function getVersion() - { - return $this->version; - } - - //---------------------------------------------------------------------- - public function setVersion($version) - { - if($version < 0 || $version > QRSPEC_VERSION_MAX) { - throw new Exception('Invalid version no'); - return -1; - } - - $this->version = $version; - - return 0; - } - - //---------------------------------------------------------------------- - public function getErrorCorrectionLevel() - { - return $this->level; - } - - //---------------------------------------------------------------------- - public function setErrorCorrectionLevel($level) - { - if($level > QR_ECLEVEL_H) { - throw new Exception('Invalid ECLEVEL'); - return -1; - } - - $this->level = $level; - - return 0; - } - - //---------------------------------------------------------------------- - public function appendEntry(QRinputItem $entry) - { - $this->items[] = $entry; - } - - //---------------------------------------------------------------------- - public function append($mode, $size, $data) - { - try { - $entry = new QRinputItem($mode, $size, $data); - $this->items[] = $entry; - return 0; - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - - public function insertStructuredAppendHeader($size, $index, $parity) - { - if( $size > MAX_STRUCTURED_SYMBOLS ) { - throw new Exception('insertStructuredAppendHeader wrong size'); - } - - if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) { - throw new Exception('insertStructuredAppendHeader wrong index'); - } - - $buf = array($size, $index, $parity); - - try { - $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf); - array_unshift($this->items, $entry); - return 0; - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function calcParity() - { - $parity = 0; - - foreach($this->items as $item) { - if($item->mode != QR_MODE_STRUCTURE) { - for($i=$item->size-1; $i>=0; $i--) { - $parity ^= $item->data[$i]; - } - } - } - - return $parity; - } - - //---------------------------------------------------------------------- - public static function checkModeNum($size, $data) - { - for($i=0; $i<$size; $i++) { - if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){ - return false; - } - } - - return true; - } - - //---------------------------------------------------------------------- - public static function estimateBitsModeNum($size) - { - $w = (int)$size / 3; - $bits = $w * 10; - - switch($size - $w * 3) { - case 1: - $bits += 4; - break; - case 2: - $bits += 7; - break; - default: - break; - } - - return $bits; - } - - //---------------------------------------------------------------------- - public static $anTable = array( - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - ); - - //---------------------------------------------------------------------- - public static function lookAnTable($c) - { - return (($c > 127)?-1:self::$anTable[$c]); - } - - //---------------------------------------------------------------------- - public static function checkModeAn($size, $data) - { - for($i=0; $i<$size; $i++) { - if (self::lookAnTable(ord($data[$i])) == -1) { - return false; - } - } - - return true; - } - - //---------------------------------------------------------------------- - public static function estimateBitsModeAn($size) - { - $w = (int)($size / 2); - $bits = $w * 11; - - if($size & 1) { - $bits += 6; - } - - return $bits; - } - - //---------------------------------------------------------------------- - public static function estimateBitsMode8($size) - { - return $size * 8; - } - - //---------------------------------------------------------------------- - public function estimateBitsModeKanji($size) - { - return (int)(($size / 2) * 13); - } - - //---------------------------------------------------------------------- - public static function checkModeKanji($size, $data) - { - if($size & 1) - return false; - - for($i=0; $i<$size; $i+=2) { - $val = (ord($data[$i]) << 8) | ord($data[$i+1]); - if( $val < 0x8140 - || ($val > 0x9ffc && $val < 0xe040) - || $val > 0xebbf) { - return false; - } - } - - return true; - } - - /*********************************************************************** - * Validation - **********************************************************************/ - - public static function check($mode, $size, $data) - { - if($size <= 0) - return false; - - switch($mode) { - case QR_MODE_NUM: return self::checkModeNum($size, $data); break; - case QR_MODE_AN: return self::checkModeAn($size, $data); break; - case QR_MODE_KANJI: return self::checkModeKanji($size, $data); break; - case QR_MODE_8: return true; break; - case QR_MODE_STRUCTURE: return true; break; - - default: - break; - } - - return false; - } - - - //---------------------------------------------------------------------- - public function estimateBitStreamSize($version) - { - $bits = 0; - - foreach($this->items as $item) { - $bits += $item->estimateBitStreamSizeOfEntry($version); - } - - return $bits; - } - - //---------------------------------------------------------------------- - public function estimateVersion() - { - $version = 0; - $prev = 0; - do { - $prev = $version; - $bits = $this->estimateBitStreamSize($prev); - $version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level); - if ($version < 0) { - return -1; - } - } while ($version > $prev); - - return $version; - } - - //---------------------------------------------------------------------- - public static function lengthOfCode($mode, $version, $bits) - { - $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version); - switch($mode) { - case QR_MODE_NUM: - $chunks = (int)($payload / 10); - $remain = $payload - $chunks * 10; - $size = $chunks * 3; - if($remain >= 7) { - $size += 2; - } else if($remain >= 4) { - $size += 1; - } - break; - case QR_MODE_AN: - $chunks = (int)($payload / 11); - $remain = $payload - $chunks * 11; - $size = $chunks * 2; - if($remain >= 6) - $size++; - break; - case QR_MODE_8: - $size = (int)($payload / 8); - break; - case QR_MODE_KANJI: - $size = (int)(($payload / 13) * 2); - break; - case QR_MODE_STRUCTURE: - $size = (int)($payload / 8); - break; - default: - $size = 0; - break; - } - - $maxsize = QRspec::maximumWords($mode, $version); - if($size < 0) $size = 0; - if($size > $maxsize) $size = $maxsize; - - return $size; - } - - //---------------------------------------------------------------------- - public function createBitStream() - { - $total = 0; - - foreach($this->items as $item) { - $bits = $item->encodeBitStream($this->version); - - if($bits < 0) - return -1; - - $total += $bits; - } - - return $total; - } - - //---------------------------------------------------------------------- - public function convertData() - { - $ver = $this->estimateVersion(); - if($ver > $this->getVersion()) { - $this->setVersion($ver); - } - - for(;;) { - $bits = $this->createBitStream(); - - if($bits < 0) - return -1; - - $ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level); - if($ver < 0) { - throw new Exception('WRONG VERSION'); - return -1; - } else if($ver > $this->getVersion()) { - $this->setVersion($ver); - } else { - break; - } - } - - return 0; - } - - //---------------------------------------------------------------------- - public function appendPaddingBit(&$bstream) - { - $bits = $bstream->size(); - $maxwords = QRspec::getDataLength($this->version, $this->level); - $maxbits = $maxwords * 8; - - if ($maxbits == $bits) { - return 0; - } - - if ($maxbits - $bits < 5) { - return $bstream->appendNum($maxbits - $bits, 0); - } - - $bits += 4; - $words = (int)(($bits + 7) / 8); - - $padding = new QRbitstream(); - $ret = $padding->appendNum($words * 8 - $bits + 4, 0); - - if($ret < 0) - return $ret; - - $padlen = $maxwords - $words; - - if($padlen > 0) { - - $padbuf = array(); - for($i=0; $i<$padlen; $i++) { - $padbuf[$i] = ($i&1)?0x11:0xec; - } - - $ret = $padding->appendBytes($padlen, $padbuf); - - if($ret < 0) - return $ret; - - } - - $ret = $bstream->append($padding); - - return $ret; - } - - //---------------------------------------------------------------------- - public function mergeBitStream() - { - if($this->convertData() < 0) { - return null; - } - - $bstream = new QRbitstream(); - - foreach($this->items as $item) { - $ret = $bstream->append($item->bstream); - if($ret < 0) { - return null; - } - } - - return $bstream; - } - - //---------------------------------------------------------------------- - public function getBitStream() - { - - $bstream = $this->mergeBitStream(); - - if($bstream == null) { - return null; - } - - $ret = $this->appendPaddingBit($bstream); - if($ret < 0) { - return null; - } - - return $bstream; - } - - //---------------------------------------------------------------------- - public function getByteStream() - { - $bstream = $this->getBitStream(); - if($bstream == null) { - return null; - } - - return $bstream->toByte(); - } - } - - - - - - -//---- qrbitstream.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Bitstream class - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - class QRbitstream { - - public $data = array(); - - //---------------------------------------------------------------------- - public function size() - { - return count($this->data); - } - - //---------------------------------------------------------------------- - public function allocate($setLength) - { - $this->data = array_fill(0, $setLength, 0); - return 0; - } - - //---------------------------------------------------------------------- - public static function newFromNum($bits, $num) - { - $bstream = new QRbitstream(); - $bstream->allocate($bits); - - $mask = 1 << ($bits - 1); - for($i=0; $i<$bits; $i++) { - if($num & $mask) { - $bstream->data[$i] = 1; - } else { - $bstream->data[$i] = 0; - } - $mask = $mask >> 1; - } - - return $bstream; - } - - //---------------------------------------------------------------------- - public static function newFromBytes($size, $data) - { - $bstream = new QRbitstream(); - $bstream->allocate($size * 8); - $p=0; - - for($i=0; $i<$size; $i++) { - $mask = 0x80; - for($j=0; $j<8; $j++) { - if($data[$i] & $mask) { - $bstream->data[$p] = 1; - } else { - $bstream->data[$p] = 0; - } - $p++; - $mask = $mask >> 1; - } - } - - return $bstream; - } - - //---------------------------------------------------------------------- - public function append(QRbitstream $arg) - { - if (is_null($arg)) { - return -1; - } - - if($arg->size() == 0) { - return 0; - } - - if($this->size() == 0) { - $this->data = $arg->data; - return 0; - } - - $this->data = array_values(array_merge($this->data, $arg->data)); - - return 0; - } - - //---------------------------------------------------------------------- - public function appendNum($bits, $num) - { - if ($bits == 0) - return 0; - - $b = QRbitstream::newFromNum($bits, $num); - - if(is_null($b)) - return -1; - - $ret = $this->append($b); - unset($b); - - return $ret; - } - - //---------------------------------------------------------------------- - public function appendBytes($size, $data) - { - if ($size == 0) - return 0; - - $b = QRbitstream::newFromBytes($size, $data); - - if(is_null($b)) - return -1; - - $ret = $this->append($b); - unset($b); - - return $ret; - } - - //---------------------------------------------------------------------- - public function toByte() - { - - $size = $this->size(); - - if($size == 0) { - return array(); - } - - $data = array_fill(0, (int)(($size + 7) / 8), 0); - $bytes = (int)($size / 8); - - $p = 0; - - for($i=0; $i<$bytes; $i++) { - $v = 0; - for($j=0; $j<8; $j++) { - $v = $v << 1; - $v |= $this->data[$p]; - $p++; - } - $data[$i] = $v; - } - - if($size & 7) { - $v = 0; - for($j=0; $j<($size & 7); $j++) { - $v = $v << 1; - $v |= $this->data[$p]; - $p++; - } - $data[$bytes] = $v; - } - - return $data; - } - - } - - - - -//---- qrsplit.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Input splitting classes - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * The following data / specifications are taken from - * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) - * or - * "Automatic identification and data capture techniques -- - * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - class QRsplit { - - public $dataStr = ''; - public $input; - public $modeHint; - - //---------------------------------------------------------------------- - public function __construct($dataStr, $input, $modeHint) - { - $this->dataStr = $dataStr; - $this->input = $input; - $this->modeHint = $modeHint; - } - - //---------------------------------------------------------------------- - public static function isdigitat($str, $pos) - { - if ($pos >= strlen($str)) - return false; - - return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9'))); - } - - //---------------------------------------------------------------------- - public static function isalnumat($str, $pos) - { - if ($pos >= strlen($str)) - return false; - - return (QRinput::lookAnTable(ord($str[$pos])) >= 0); - } - - //---------------------------------------------------------------------- - public function identifyMode($pos) - { - if ($pos >= strlen($this->dataStr)) - return QR_MODE_NUL; - - $c = $this->dataStr[$pos]; - - if(self::isdigitat($this->dataStr, $pos)) { - return QR_MODE_NUM; - } else if(self::isalnumat($this->dataStr, $pos)) { - return QR_MODE_AN; - } else if($this->modeHint == QR_MODE_KANJI) { - - if ($pos+1 < strlen($this->dataStr)) - { - $d = $this->dataStr[$pos+1]; - $word = (ord($c) << 8) | ord($d); - if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) { - return QR_MODE_KANJI; - } - } - } - - return QR_MODE_8; - } - - //---------------------------------------------------------------------- - public function eatNum() - { - $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); - - $p = 0; - while(self::isdigitat($this->dataStr, $p)) { - $p++; - } - - $run = $p; - $mode = $this->identifyMode($p); - - if($mode == QR_MODE_8) { - $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln - + QRinput::estimateBitsMode8(1) // + 4 + l8 - - QRinput::estimateBitsMode8($run + 1); // - 4 - l8 - if($dif > 0) { - return $this->eat8(); - } - } - if($mode == QR_MODE_AN) { - $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln - + QRinput::estimateBitsModeAn(1) // + 4 + la - - QRinput::estimateBitsModeAn($run + 1);// - 4 - la - if($dif > 0) { - return $this->eatAn(); - } - } - - $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr)); - if($ret < 0) - return -1; - - return $run; - } - - //---------------------------------------------------------------------- - public function eatAn() - { - $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion()); - $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); - - $p = 0; - - while(self::isalnumat($this->dataStr, $p)) { - if(self::isdigitat($this->dataStr, $p)) { - $q = $p; - while(self::isdigitat($this->dataStr, $q)) { - $q++; - } - - $dif = QRinput::estimateBitsModeAn($p) // + 4 + la - + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln - - QRinput::estimateBitsModeAn($q); // - 4 - la - - if($dif < 0) { - break; - } else { - $p = $q; - } - } else { - $p++; - } - } - - $run = $p; - - if(!self::isalnumat($this->dataStr, $p)) { - $dif = QRinput::estimateBitsModeAn($run) + 4 + $la - + QRinput::estimateBitsMode8(1) // + 4 + l8 - - QRinput::estimateBitsMode8($run + 1); // - 4 - l8 - if($dif > 0) { - return $this->eat8(); - } - } - - $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr)); - if($ret < 0) - return -1; - - return $run; - } - - //---------------------------------------------------------------------- - public function eatKanji() - { - $p = 0; - - while($this->identifyMode($p) == QR_MODE_KANJI) { - $p += 2; - } - - $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr)); - if($ret < 0) - return -1; - - return $run; - } - - //---------------------------------------------------------------------- - public function eat8() - { - $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion()); - $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); - - $p = 1; - $dataStrLen = strlen($this->dataStr); - - while($p < $dataStrLen) { - - $mode = $this->identifyMode($p); - if($mode == QR_MODE_KANJI) { - break; - } - if($mode == QR_MODE_NUM) { - $q = $p; - while(self::isdigitat($this->dataStr, $q)) { - $q++; - } - $dif = QRinput::estimateBitsMode8($p) // + 4 + l8 - + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln - - QRinput::estimateBitsMode8($q); // - 4 - l8 - if($dif < 0) { - break; - } else { - $p = $q; - } - } else if($mode == QR_MODE_AN) { - $q = $p; - while(self::isalnumat($this->dataStr, $q)) { - $q++; - } - $dif = QRinput::estimateBitsMode8($p) // + 4 + l8 - + QRinput::estimateBitsModeAn($q - $p) + 4 + $la - - QRinput::estimateBitsMode8($q); // - 4 - l8 - if($dif < 0) { - break; - } else { - $p = $q; - } - } else { - $p++; - } - } - - $run = $p; - $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr)); - - if($ret < 0) - return -1; - - return $run; - } - - //---------------------------------------------------------------------- - public function splitString() - { - while (strlen($this->dataStr) > 0) - { - if($this->dataStr == '') - return 0; - - $mode = $this->identifyMode(0); - - switch ($mode) { - case QR_MODE_NUM: $length = $this->eatNum(); break; - case QR_MODE_AN: $length = $this->eatAn(); break; - case QR_MODE_KANJI: - if ($hint == QR_MODE_KANJI) - $length = $this->eatKanji(); - else $length = $this->eat8(); - break; - default: $length = $this->eat8(); break; - - } - - if($length == 0) return 0; - if($length < 0) return -1; - - $this->dataStr = substr($this->dataStr, $length); - } - } - - //---------------------------------------------------------------------- - public function toUpper() - { - $stringLen = strlen($this->dataStr); - $p = 0; - - while ($p<$stringLen) { - $mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint); - if($mode == QR_MODE_KANJI) { - $p += 2; - } else { - if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) { - $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32); - } - $p++; - } - } - - return $this->dataStr; - } - - //---------------------------------------------------------------------- - public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true) - { - if(is_null($string) || $string == '\0' || $string == '') { - throw new Exception('empty string!!!'); - } - - $split = new QRsplit($string, $input, $modeHint); - - if(!$casesensitive) - $split->toUpper(); - - return $split->splitString(); - } - } - - - -//---- qrrscode.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Reed-Solomon error correction support - * - * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q - * (libfec is released under the GNU Lesser General Public License.) - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - class QRrsItem { - - public $mm; // Bits per symbol - public $nn; // Symbols per block (= (1<= $this->nn) { - $x -= $this->nn; - $x = ($x >> $this->mm) + ($x & $this->nn); - } - - return $x; - } - - //---------------------------------------------------------------------- - public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) - { - // Common code for intializing a Reed-Solomon control block (char or int symbols) - // Copyright 2004 Phil Karn, KA9Q - // May be used under the terms of the GNU Lesser General Public License (LGPL) - - $rs = null; - - // Check parameter ranges - if($symsize < 0 || $symsize > 8) return $rs; - if($fcr < 0 || $fcr >= (1<<$symsize)) return $rs; - if($prim <= 0 || $prim >= (1<<$symsize)) return $rs; - if($nroots < 0 || $nroots >= (1<<$symsize)) return $rs; // Can't have more roots than symbol values! - if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding - - $rs = new QRrsItem(); - $rs->mm = $symsize; - $rs->nn = (1<<$symsize)-1; - $rs->pad = $pad; - - $rs->alpha_to = array_fill(0, $rs->nn+1, 0); - $rs->index_of = array_fill(0, $rs->nn+1, 0); - - // PHP style macro replacement ;) - $NN =& $rs->nn; - $A0 =& $NN; - - // Generate Galois field lookup tables - $rs->index_of[0] = $A0; // log(zero) = -inf - $rs->alpha_to[$A0] = 0; // alpha**-inf = 0 - $sr = 1; - - for($i=0; $i<$rs->nn; $i++) { - $rs->index_of[$sr] = $i; - $rs->alpha_to[$i] = $sr; - $sr <<= 1; - if($sr & (1<<$symsize)) { - $sr ^= $gfpoly; - } - $sr &= $rs->nn; - } - - if($sr != 1){ - // field generator polynomial is not primitive! - $rs = NULL; - return $rs; - } - - /* Form RS code generator polynomial from its roots */ - $rs->genpoly = array_fill(0, $nroots+1, 0); - - $rs->fcr = $fcr; - $rs->prim = $prim; - $rs->nroots = $nroots; - $rs->gfpoly = $gfpoly; - - /* Find prim-th root of 1, used in decoding */ - for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn) - ; // intentional empty-body loop! - - $rs->iprim = (int)($iprim / $prim); - $rs->genpoly[0] = 1; - - for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) { - $rs->genpoly[$i+1] = 1; - - // Multiply rs->genpoly[] by @**(root + x) - for ($j = $i; $j > 0; $j--) { - if ($rs->genpoly[$j] != 0) { - $rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)]; - } else { - $rs->genpoly[$j] = $rs->genpoly[$j-1]; - } - } - // rs->genpoly[0] can never be zero - $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)]; - } - - // convert rs->genpoly[] to index form for quicker encoding - for ($i = 0; $i <= $nroots; $i++) - $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]]; - - return $rs; - } - - //---------------------------------------------------------------------- - public function encode_rs_char($data, &$parity) - { - $MM =& $this->mm; - $NN =& $this->nn; - $ALPHA_TO =& $this->alpha_to; - $INDEX_OF =& $this->index_of; - $GENPOLY =& $this->genpoly; - $NROOTS =& $this->nroots; - $FCR =& $this->fcr; - $PRIM =& $this->prim; - $IPRIM =& $this->iprim; - $PAD =& $this->pad; - $A0 =& $NN; - - $parity = array_fill(0, $NROOTS, 0); - - for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) { - - $feedback = $INDEX_OF[$data[$i] ^ $parity[0]]; - if($feedback != $A0) { - // feedback term is non-zero - - // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must - // always be for the polynomials constructed by init_rs() - $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback); - - for($j=1;$j<$NROOTS;$j++) { - $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])]; - } - } - - // Shift - array_shift($parity); - if($feedback != $A0) { - array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]); - } else { - array_push($parity, 0); - } - } - } - } - - //########################################################################## - - class QRrs { - - public static $items = array(); - - //---------------------------------------------------------------------- - public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) - { - foreach(self::$items as $rs) { - if($rs->pad != $pad) continue; - if($rs->nroots != $nroots) continue; - if($rs->mm != $symsize) continue; - if($rs->gfpoly != $gfpoly) continue; - if($rs->fcr != $fcr) continue; - if($rs->prim != $prim) continue; - - return $rs; - } - - $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad); - array_unshift(self::$items, $rs); - - return $rs; - } - } - - - -//---- qrmask.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Masking - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - define('N1', 3); - define('N2', 3); - define('N3', 40); - define('N4', 10); - - class QRmask { - - public $runLength = array(); - - //---------------------------------------------------------------------- - public function __construct() - { - $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0); - } - - //---------------------------------------------------------------------- - public function writeFormatInformation($width, &$frame, $mask, $level) - { - $blacks = 0; - $format = QRspec::getFormatInfo($mask, $level); - - for($i=0; $i<8; $i++) { - if($format & 1) { - $blacks += 2; - $v = 0x85; - } else { - $v = 0x84; - } - - $frame[8][$width - 1 - $i] = chr($v); - if($i < 6) { - $frame[$i][8] = chr($v); - } else { - $frame[$i + 1][8] = chr($v); - } - $format = $format >> 1; - } - - for($i=0; $i<7; $i++) { - if($format & 1) { - $blacks += 2; - $v = 0x85; - } else { - $v = 0x84; - } - - $frame[$width - 7 + $i][8] = chr($v); - if($i == 0) { - $frame[8][7] = chr($v); - } else { - $frame[8][6 - $i] = chr($v); - } - - $format = $format >> 1; - } - - return $blacks; - } - - //---------------------------------------------------------------------- - public function mask0($x, $y) { return ($x+$y)&1; } - public function mask1($x, $y) { return ($y&1); } - public function mask2($x, $y) { return ($x%3); } - public function mask3($x, $y) { return ($x+$y)%3; } - public function mask4($x, $y) { return (((int)($y/2))+((int)($x/3)))&1; } - public function mask5($x, $y) { return (($x*$y)&1)+($x*$y)%3; } - public function mask6($x, $y) { return ((($x*$y)&1)+($x*$y)%3)&1; } - public function mask7($x, $y) { return ((($x*$y)%3)+(($x+$y)&1))&1; } - - //---------------------------------------------------------------------- - private function generateMaskNo($maskNo, $width, $frame) - { - $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); - - for($y=0; $y<$width; $y++) { - for($x=0; $x<$width; $x++) { - if(ord($frame[$y][$x]) & 0x80) { - $bitMask[$y][$x] = 0; - } else { - $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y); - $bitMask[$y][$x] = ($maskFunc == 0)?1:0; - } - - } - } - - return $bitMask; - } - - //---------------------------------------------------------------------- - public static function serial($bitFrame) - { - $codeArr = array(); - - foreach ($bitFrame as $line) - $codeArr[] = join('', $line); - - return gzcompress(join("\n", $codeArr), 9); - } - - //---------------------------------------------------------------------- - public static function unserial($code) - { - $codeArr = array(); - - $codeLines = explode("\n", gzuncompress($code)); - foreach ($codeLines as $line) - $codeArr[] = str_split($line); - - return $codeArr; - } - - //---------------------------------------------------------------------- - public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false) - { - $b = 0; - $bitMask = array(); - - $fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat'; - - if (QR_CACHEABLE) { - if (file_exists($fileName)) { - $bitMask = self::unserial(file_get_contents($fileName)); - } else { - $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); - if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo)) - mkdir(QR_CACHE_DIR.'mask_'.$maskNo); - file_put_contents($fileName, self::serial($bitMask)); - } - } else { - $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); - } - - if ($maskGenOnly) - return; - - $d = $s; - - for($y=0; $y<$width; $y++) { - for($x=0; $x<$width; $x++) { - if($bitMask[$y][$x] == 1) { - $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]); - } - $b += (int)(ord($d[$y][$x]) & 1); - } - } - - return $b; - } - - //---------------------------------------------------------------------- - public function makeMask($width, $frame, $maskNo, $level) - { - $masked = array_fill(0, $width, str_repeat("\0", $width)); - $this->makeMaskNo($maskNo, $width, $frame, $masked); - $this->writeFormatInformation($width, $masked, $maskNo, $level); - - return $masked; - } - - //---------------------------------------------------------------------- - public function calcN1N3($length) - { - $demerit = 0; - - for($i=0; $i<$length; $i++) { - - if($this->runLength[$i] >= 5) { - $demerit += (N1 + ($this->runLength[$i] - 5)); - } - if($i & 1) { - if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) { - $fact = (int)($this->runLength[$i] / 3); - if(($this->runLength[$i-2] == $fact) && - ($this->runLength[$i-1] == $fact) && - ($this->runLength[$i+1] == $fact) && - ($this->runLength[$i+2] == $fact)) { - if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) { - $demerit += N3; - } else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) { - $demerit += N3; - } - } - } - } - } - return $demerit; - } - - //---------------------------------------------------------------------- - public function evaluateSymbol($width, $frame) - { - $head = 0; - $demerit = 0; - - for($y=0; $y<$width; $y++) { - $head = 0; - $this->runLength[0] = 1; - - $frameY = $frame[$y]; - - if ($y>0) - $frameYM = $frame[$y-1]; - - for($x=0; $x<$width; $x++) { - if(($x > 0) && ($y > 0)) { - $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]); - $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]); - - if(($b22 | ($w22 ^ 1))&1) { - $demerit += N2; - } - } - if(($x == 0) && (ord($frameY[$x]) & 1)) { - $this->runLength[0] = -1; - $head = 1; - $this->runLength[$head] = 1; - } else if($x > 0) { - if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) { - $head++; - $this->runLength[$head] = 1; - } else { - $this->runLength[$head]++; - } - } - } - - $demerit += $this->calcN1N3($head+1); - } - - for($x=0; $x<$width; $x++) { - $head = 0; - $this->runLength[0] = 1; - - for($y=0; $y<$width; $y++) { - if($y == 0 && (ord($frame[$y][$x]) & 1)) { - $this->runLength[0] = -1; - $head = 1; - $this->runLength[$head] = 1; - } else if($y > 0) { - if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) { - $head++; - $this->runLength[$head] = 1; - } else { - $this->runLength[$head]++; - } - } - } - - $demerit += $this->calcN1N3($head+1); - } - - return $demerit; - } - - - //---------------------------------------------------------------------- - public function mask($width, $frame, $level) - { - $minDemerit = PHP_INT_MAX; - $bestMaskNum = 0; - $bestMask = array(); - - $checked_masks = array(0,1,2,3,4,5,6,7); - - if (QR_FIND_FROM_RANDOM !== false) { - - $howManuOut = 8-(QR_FIND_FROM_RANDOM % 9); - for ($i = 0; $i < $howManuOut; $i++) { - $remPos = rand (0, count($checked_masks)-1); - unset($checked_masks[$remPos]); - $checked_masks = array_values($checked_masks); - } - - } - - $bestMask = $frame; - - foreach($checked_masks as $i) { - $mask = array_fill(0, $width, str_repeat("\0", $width)); - - $demerit = 0; - $blacks = 0; - $blacks = $this->makeMaskNo($i, $width, $frame, $mask); - $blacks += $this->writeFormatInformation($width, $mask, $i, $level); - $blacks = (int)(100 * $blacks / ($width * $width)); - $demerit = (int)((int)(abs($blacks - 50) / 5) * N4); - $demerit += $this->evaluateSymbol($width, $mask); - - if($demerit < $minDemerit) { - $minDemerit = $demerit; - $bestMask = $mask; - $bestMaskNum = $i; - } - } - - return $bestMask; - } - - //---------------------------------------------------------------------- - } - - - - -//---- qrencode.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Main encoder classes. - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - class QRrsblock { - public $dataLength; - public $data = array(); - public $eccLength; - public $ecc = array(); - - public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs) - { - $rs->encode_rs_char($data, $ecc); - - $this->dataLength = $dl; - $this->data = $data; - $this->eccLength = $el; - $this->ecc = $ecc; - } - }; - - //########################################################################## - - class QRrawcode { - public $version; - public $datacode = array(); - public $ecccode = array(); - public $blocks; - public $rsblocks = array(); //of RSblock - public $count; - public $dataLength; - public $eccLength; - public $b1; - - //---------------------------------------------------------------------- - public function __construct(QRinput $input) - { - $spec = array(0,0,0,0,0); - - $this->datacode = $input->getByteStream(); - if(is_null($this->datacode)) { - throw new Exception('null imput string'); - } - - QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec); - - $this->version = $input->getVersion(); - $this->b1 = QRspec::rsBlockNum1($spec); - $this->dataLength = QRspec::rsDataLength($spec); - $this->eccLength = QRspec::rsEccLength($spec); - $this->ecccode = array_fill(0, $this->eccLength, 0); - $this->blocks = QRspec::rsBlockNum($spec); - - $ret = $this->init($spec); - if($ret < 0) { - throw new Exception('block alloc error'); - return null; - } - - $this->count = 0; - } - - //---------------------------------------------------------------------- - public function init(array $spec) - { - $dl = QRspec::rsDataCodes1($spec); - $el = QRspec::rsEccCodes1($spec); - $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); - - - $blockNo = 0; - $dataPos = 0; - $eccPos = 0; - for($i=0; $iecccode,$eccPos); - $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); - $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); - - $dataPos += $dl; - $eccPos += $el; - $blockNo++; - } - - if(QRspec::rsBlockNum2($spec) == 0) - return 0; - - $dl = QRspec::rsDataCodes2($spec); - $el = QRspec::rsEccCodes2($spec); - $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); - - if($rs == NULL) return -1; - - for($i=0; $iecccode,$eccPos); - $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); - $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); - - $dataPos += $dl; - $eccPos += $el; - $blockNo++; - } - - return 0; - } - - //---------------------------------------------------------------------- - public function getCode() - { - $ret; - - if($this->count < $this->dataLength) { - $row = $this->count % $this->blocks; - $col = $this->count / $this->blocks; - if($col >= $this->rsblocks[0]->dataLength) { - $row += $this->b1; - } - $ret = $this->rsblocks[$row]->data[$col]; - } else if($this->count < $this->dataLength + $this->eccLength) { - $row = ($this->count - $this->dataLength) % $this->blocks; - $col = ($this->count - $this->dataLength) / $this->blocks; - $ret = $this->rsblocks[$row]->ecc[$col]; - } else { - return 0; - } - $this->count++; - - return $ret; - } - } - - //########################################################################## - - class QRcode { - - public $version; - public $width; - public $data; - - //---------------------------------------------------------------------- - public function encodeMask(QRinput $input, $mask) - { - if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) { - throw new Exception('wrong version'); - } - if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) { - throw new Exception('wrong level'); - } - - $raw = new QRrawcode($input); - - QRtools::markTime('after_raw'); - - $version = $raw->version; - $width = QRspec::getWidth($version); - $frame = QRspec::newFrame($version); - - $filler = new FrameFiller($width, $frame); - if(is_null($filler)) { - return NULL; - } - - // inteleaved data and ecc codes - for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) { - $code = $raw->getCode(); - $bit = 0x80; - for($j=0; $j<8; $j++) { - $addr = $filler->next(); - $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0)); - $bit = $bit >> 1; - } - } - - QRtools::markTime('after_filler'); - - unset($raw); - - // remainder bits - $j = QRspec::getRemainder($version); - for($i=0; $i<$j; $i++) { - $addr = $filler->next(); - $filler->setFrameAt($addr, 0x02); - } - - $frame = $filler->frame; - unset($filler); - - - // masking - $maskObj = new QRmask(); - if($mask < 0) { - - if (QR_FIND_BEST_MASK) { - $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel()); - } else { - $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel()); - } - } else { - $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel()); - } - - if($masked == NULL) { - return NULL; - } - - QRtools::markTime('after_mask'); - - $this->version = $version; - $this->width = $width; - $this->data = $masked; - - return $this; - } - - //---------------------------------------------------------------------- - public function encodeInput(QRinput $input) - { - return $this->encodeMask($input, -1); - } - - //---------------------------------------------------------------------- - public function encodeString8bit($string, $version, $level) - { - if(string == NULL) { - throw new Exception('empty string!'); - return NULL; - } - - $input = new QRinput($version, $level); - if($input == NULL) return NULL; - - $ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string)); - if($ret < 0) { - unset($input); - return NULL; - } - return $this->encodeInput($input); - } - - //---------------------------------------------------------------------- - public function encodeString($string, $version, $level, $hint, $casesensitive) - { - - if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) { - throw new Exception('bad hint'); - return NULL; - } - - $input = new QRinput($version, $level); - if($input == NULL) return NULL; - - $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive); - if($ret < 0) { - return NULL; - } - - return $this->encodeInput($input); - } - - //---------------------------------------------------------------------- - public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false) - { - $enc = QRencode::factory($level, $size, $margin); - return $enc->encodePNG($text, $outfile, $saveandprint=false); - } - - //---------------------------------------------------------------------- - public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) - { - $enc = QRencode::factory($level, $size, $margin); - return $enc->encode($text, $outfile); - } - - //---------------------------------------------------------------------- - public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) - { - $enc = QRencode::factory($level, $size, $margin); - return $enc->encodeRAW($text, $outfile); - } - } - - //########################################################################## - - class FrameFiller { - - public $width; - public $frame; - public $x; - public $y; - public $dir; - public $bit; - - //---------------------------------------------------------------------- - public function __construct($width, &$frame) - { - $this->width = $width; - $this->frame = $frame; - $this->x = $width - 1; - $this->y = $width - 1; - $this->dir = -1; - $this->bit = -1; - } - - //---------------------------------------------------------------------- - public function setFrameAt($at, $val) - { - $this->frame[$at['y']][$at['x']] = chr($val); - } - - //---------------------------------------------------------------------- - public function getFrameAt($at) - { - return ord($this->frame[$at['y']][$at['x']]); - } - - //---------------------------------------------------------------------- - public function next() - { - do { - - if($this->bit == -1) { - $this->bit = 0; - return array('x'=>$this->x, 'y'=>$this->y); - } - - $x = $this->x; - $y = $this->y; - $w = $this->width; - - if($this->bit == 0) { - $x--; - $this->bit++; - } else { - $x++; - $y += $this->dir; - $this->bit--; - } - - if($this->dir < 0) { - if($y < 0) { - $y = 0; - $x -= 2; - $this->dir = 1; - if($x == 6) { - $x--; - $y = 9; - } - } - } else { - if($y == $w) { - $y = $w - 1; - $x -= 2; - $this->dir = -1; - if($x == 6) { - $x--; - $y -= 8; - } - } - } - if($x < 0 || $y < 0) return null; - - $this->x = $x; - $this->y = $y; - - } while(ord($this->frame[$y][$x]) & 0x80); - - return array('x'=>$x, 'y'=>$y); - } - - } ; - - //########################################################################## - - class QRencode { - - public $casesensitive = true; - public $eightbit = false; - - public $version = 0; - public $size = 3; - public $margin = 4; - - public $structured = 0; // not supported yet - - public $level = QR_ECLEVEL_L; - public $hint = QR_MODE_8; - - //---------------------------------------------------------------------- - public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4) - { - $enc = new QRencode(); - $enc->size = $size; - $enc->margin = $margin; - - switch ($level.'') { - case '0': - case '1': - case '2': - case '3': - $enc->level = $level; - break; - case 'l': - case 'L': - $enc->level = QR_ECLEVEL_L; - break; - case 'm': - case 'M': - $enc->level = QR_ECLEVEL_M; - break; - case 'q': - case 'Q': - $enc->level = QR_ECLEVEL_Q; - break; - case 'h': - case 'H': - $enc->level = QR_ECLEVEL_H; - break; - } - - return $enc; - } - - //---------------------------------------------------------------------- - public function encodeRAW($intext, $outfile = false) - { - $code = new QRcode(); - - if($this->eightbit) { - $code->encodeString8bit($intext, $this->version, $this->level); - } else { - $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive); - } - - return $code->data; - } - - //---------------------------------------------------------------------- - public function encode($intext, $outfile = false) - { - $code = new QRcode(); - - if($this->eightbit) { - $code->encodeString8bit($intext, $this->version, $this->level); - } else { - $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive); - } - - QRtools::markTime('after_encode'); - - if ($outfile!== false) { - file_put_contents($outfile, join("\n", QRtools::binarize($code->data))); - } else { - return QRtools::binarize($code->data); - } - } - - //---------------------------------------------------------------------- - public function encodePNG($intext, $outfile = false,$saveandprint=false) - { - try { - - ob_start(); - $tab = $this->encode($intext); - $err = ob_get_contents(); - ob_end_clean(); - - if ($err != '') - QRtools::log($outfile, $err); - - $maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin)); - - QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint); - - } catch (Exception $e) { - - QRtools::log($outfile, $e->getMessage()); - - } - } - } - - diff --git a/includes/webapi/webapi.php b/includes/webapi/webapi.php index 70bad13..fdd7704 100644 --- a/includes/webapi/webapi.php +++ b/includes/webapi/webapi.php @@ -1,13 +1,8 @@ "gfwebapi_hmac_sha1", - "src" => "http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha1.js", + "src" => "https://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha1.js", "enqueue" => array( array("admin_page" => array("plugin_settings")) ) ), array("handle" => "gfwebapi_enc_base64", - "src" => "http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js", + "src" => "https://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js", "deps" => array('gfwebapi_hmac_sha1'), "callback" => array($this, "localize_form_settings_scripts"), "enqueue" => array( @@ -152,7 +147,7 @@ public function render_uninstall() { // ------- Plugin settings ------- public function plugin_settings_title() { - return " " . __("Gravity Forms API Settings", "gravityforms") . ""; + return "" . __("Gravity Forms API Settings", "gravityforms") . ""; } public function plugin_settings_fields() { @@ -322,7 +317,13 @@ public function rewrite_rules($rules) { $gfapi_rules[GFWEBAPI_SLUG . '/(.*)'] = 'index.php?' . GFWEBAPI_ROUTE_VAR . '=$matches[1]'; - $rules = $gfapi_rules + $rules; + if (is_array($rules)){ + // the array operator instead of array_merge avoids tampering with the keys in the original array + $rules = $gfapi_rules + $rules; + } + else{ + $rules = $gfapi_rules; + } return $rules; } @@ -337,6 +338,8 @@ public function query_vars($query_vars) { public function handle_page_request() { + global $HTTP_RAW_POST_DATA; + $route = get_query_var(GFWEBAPI_ROUTE_VAR); if (false == $route) return; @@ -347,10 +350,12 @@ public function handle_page_request() { if ($test_mode) die("test mode"); - $settings = get_site_option('gravityformsaddon_gravityformswebapi_settings'); + $settings = get_option('gravityformsaddon_gravityformswebapi_settings'); - if (empty($settings)) + if (empty($settings)){ $this->die_not_authorized(); + } + $account_id = $settings["impersonate_account"]; wp_set_current_user($account_id); @@ -373,8 +378,7 @@ public function handle_page_request() { if (strpos($id2, ";") !== false) $id2 = explode(";", $id2); - else - $id2 = intval($id2); + if (empty($format)) $format = "json"; @@ -385,161 +389,180 @@ public function handle_page_request() { $method = strtoupper($_SERVER['REQUEST_METHOD']); $args = compact("offset", "page_size", "schema"); - $filter_suffix = empty($collection2) ? $collection : "_" . $collection2; - - $output = apply_filters("gform_webapi_" . strtolower($method) . "_" . $filter_suffix, "", $id, $collection2, $id2, $format, $args); - - if ("" == $output) { - $data = file_get_contents("php://input"); - $data = json_decode($data, true); - switch ($collection) { - case "forms" : - switch ($collection2) { - case "results" : - switch ($method) { - case 'GET' : - $this->get_results($id); - break; - case 'DELETE': - case 'PUT': - case 'POST': - default: - $this->die_bad_request(); - } - break; - case "feeds" : - if (false == empty($id2)) - $this->die_bad_request(); - switch ($method) { - case 'GET' : - $this->get_feeds(null, $id); - break; - case 'DELETE' : - $this->delete_feeds(null, $id); - break; - case 'PUT' : - $this->die_not_implemented(); - break; - case 'POST' : - $this->post_feeds($data, $id); - break; - default : - $this->die_bad_request(); - } - break; - case "entries" : - if (false == empty($id2)) - $this->die_bad_request(); - switch ($method) { - case 'GET' : - $this->get_entries(null, $id, $schema); - break; - case 'POST' : - $this->post_entries($data, $id); - break; - case 'PUT' : - case 'DELETE' : - case 'POST' : - $this->die_not_implemented(); - break; - default: - $this->die_bad_request(); - } - break; + if(empty($collection2)){ + do_action("gform_webapi_" . strtolower($method) . "_" . $collection, $id, $format, $args); + } else { + do_action("gform_webapi_" . strtolower($method) . "_" . $collection . "_" . $collection2, $id, $id2, $format, $args); + } - case "" : - switch ($method) { - case 'GET': - $this->get_forms($id, $schema); - break; - case 'DELETE': - $this->delete_forms($id); - break; - case 'PUT': - $this->put_forms($data, $id, $id2); - break; - case 'POST': - if (false === empty($id)) - $this->die_bad_request(); - $this->post_forms($data, $id); - break; - default: - $this->die_bad_request(); - } - break; - default : - $this->die_bad_request(); - break; + if (!isset($HTTP_RAW_POST_DATA)) { + $HTTP_RAW_POST_DATA = file_get_contents('php://input'); + } - } - break; - case "entries" : // route = /entries/{id} - switch ($method) { - case 'GET': - switch ($collection2) { - case "fields" : // route = /entries/{id}/fields/{id2} - switch ($method) { - case 'GET' : - $this->get_entries($id, null, $schema, $id2); - break; - case 'DELETE' : - case 'PUT' : - case 'POST' : - default: - $this->die_bad_request(); - } - break; - case "" : - $this->get_entries($id, null, $schema); - break; - } + GFCommon::log_debug("WebAPI: HTTP_RAW_POST_DATA = " . $HTTP_RAW_POST_DATA); - break; - case 'DELETE' : - $this->delete_entries($id); - break; - case 'PUT' : - $this->put_entries($data, $id); - break; - case 'POST' : - if (false === empty($id)) + + $data = json_decode($HTTP_RAW_POST_DATA, true); + + + // todo: tidy up this mess + + switch ($collection) { + case "forms" : + switch ($collection2) { + case "results" : + switch ($method) { + case 'GET' : + $this->get_results($id); + break; + case 'DELETE': + case 'PUT': + case 'POST': + default: $this->die_bad_request(); - $this->post_entries($data); - break; - default: - $this->die_bad_request(); - } - break; - case "feeds" : - switch ($method) { - case 'GET' : - $this->get_feeds($id); - break; - case 'DELETE' : - if (empty($id)) + } + break; + case "properties" : + switch ($method) { + case 'PUT' : + $this->put_forms_properties($data, $id); + break; + default: $this->die_bad_request(); - $this->delete_feeds($id); - break; - case 'PUT' : - $this->put_feeds($data, $id); - break; - case 'POST' : - if (false === empty($id)) + } + break; + case "feeds" : + if (false == empty($id2)) + $this->die_bad_request(); + switch ($method) { + case 'GET' : + $this->get_feeds(null, $id); + break; + case 'DELETE' : + $this->delete_feeds(null, $id); + break; + case 'PUT' : + $this->die_not_implemented(); + break; + case 'POST' : + $this->post_feeds($data, $id); + break; + default : $this->die_bad_request(); - $this->post_feeds($data); - break; - default : + } + break; + case "entries" : + if (false == empty($id2)) $this->die_bad_request(); - } - break; - default : - $this->die_bad_request(); - break; - } + switch ($method) { + case 'GET' : + $this->get_entries(null, $id, $schema); + break; + case 'POST' : + $this->post_entries($data, $id); + break; + case 'PUT' : + case 'DELETE' : + case 'POST' : + $this->die_not_implemented(); + break; + default: + $this->die_bad_request(); + } + break; + + case "" : + switch ($method) { + case 'GET': + $this->get_forms($id, $schema); + break; + case 'DELETE': + $this->delete_forms($id); + break; + case 'PUT': + $this->put_forms($data, $id, $id2); + break; + case 'POST': + if (false === empty($id)) + $this->die_bad_request(); + $this->post_forms($data, $id); + break; + default: + $this->die_bad_request(); + } + break; + default : + $this->die_bad_request(); + break; + } + break; + case "entries" : // route = /entries/{id} + switch ($method) { + case 'GET': + switch ($collection2) { + case "fields" : // route = /entries/{id}/fields/{id2} + $this->get_entries($id, null, $schema, $id2); + break; + case "" : + $this->get_entries($id, null, $schema); + break; + default : + $this->die_bad_request(); + } + + break; + case 'DELETE' : + $this->delete_entries($id); + break; + case 'PUT' : + switch ($collection2) { + case "properties" : // route = /entries/{id}/properties/{id2} + $this->put_entry_properties($data, $id); + break; + case "" : + $this->put_entries($data, $id); + break; + } + break; + case 'POST' : + if (false === empty($id)) + $this->die_bad_request(); + $this->post_entries($data); + break; + default: + $this->die_bad_request(); + } + break; + case "feeds" : + switch ($method) { + case 'GET' : + $this->get_feeds($id); + break; + case 'DELETE' : + if (empty($id)) + $this->die_bad_request(); + $this->delete_feeds($id); + break; + case 'PUT' : + $this->put_feeds($data, $id); + break; + case 'POST' : + if (false === empty($id)) + $this->die_bad_request(); + $this->post_feeds($data); + break; + default : + $this->die_bad_request(); + } + break; + default : + $this->die_bad_request(); + break; } + $this->die_bad_request(); } @@ -738,6 +761,60 @@ public function put_entries($data, $entry_id = null) { $this->end($status, $response); } + public function put_forms_properties($property_values, $form_id){ + $this->authorize("gravityforms_edit_forms"); + + foreach($property_values as $key => $property_value){ + $result = GFAPI::update_form_property($form_id, $key, $property_value); + if(is_wp_error($result)){ + break; + } + } + + if (is_wp_error($result)) { + $response = $this->get_error_response($result); + $status = $this->get_error_status($result); + } else { + $status = 200; + $response = __("Success", "gravityforms"); + } + + $this->end($status, $response); + + } + + public function put_entry_properties($property_values, $entry_id){ + $this->authorize("gravityforms_edit_entries"); + + if(is_array($property_values)){ + foreach($property_values as $key => $property_value){ + $result = GFAPI::update_entry_property($entry_id, $key, $property_value); + if(is_wp_error($result)){ + break; + } + } + + if (is_wp_error($result)) { + $response = $this->get_error_response($result); + $status = $this->get_error_status($result); + } else { + $status = 200; + $response = __("Success", "gravityforms"); + } + + } else { + $status = 400; + if(empty($property_values)){ + $response = __("No property values were found in the request body", "gravityforms"); + } else { + $response = __("Property values should be sent as an array", "gravityforms"); + } + } + + $this->end($status, $response); + + } + public function post_forms($data) { $this->authorize("gravityforms_create_form"); @@ -839,6 +916,9 @@ public function get_entries($entry_ids, $form_ids = null, $schema = "", $field_i $sort_key = isset($_GET["sorting"]["key"]) && !empty($_GET["sorting"]["key"]) ? $_GET["sorting"]["key"] : "id"; $sort_dir = isset($_GET["sorting"]["direction"]) && !empty($_GET["sorting"]["direction"]) ? $_GET["sorting"]["direction"] : "DESC"; $sorting = array('key' => $sort_key, 'direction' => $sort_dir); + if(isset($_GET["sorting"]["is_numeric"])){ + $sorting["is_numeric"] = $_GET["sorting"]["is_numeric"]; + } //paging parameters $page_size = isset($_GET["paging"]["page_size"]) ? intval($_GET["paging"]["page_size"]) : 10; @@ -1313,7 +1393,7 @@ private function check_signature() { if (time() >= $expires) return false; - $is_valid = $signature == $calculated_sig; + $is_valid = $signature == $calculated_sig || $signature == rawurlencode($calculated_sig); return $is_valid; } @@ -1325,7 +1405,7 @@ private function calculate_signature($string) { return $sig; } - public function end($status, $response) { + public static function end($status, $response) { $output["status"] = $status; $output["response"] = $response; @@ -1403,7 +1483,8 @@ public static function ajax_qrcode() { if (empty($settings)) die(); - $data["site"] = site_url(); + $data["url"] = site_url(); + $data["name"] = get_bloginfo(); $data["public_key"] = rgar($settings, "public_key"); $data["private_key"] = rgar($settings, "private_key"); diff --git a/js.php b/js.php index a66c589..26549b3 100644 --- a/js.php +++ b/js.php @@ -1,3 +1,9 @@ + +