%PDF- %PDF-
Direktori : /var/www/html/bbw/farmaci/wordpress/wp-content/plugins/gravityforms/ |
Current File : /var/www/html/bbw/farmaci/wordpress/wp-content/plugins/gravityforms/forms_model.php |
<?php if ( ! class_exists( 'GFForms' ) ) { die(); } require_once( ABSPATH . WPINC . '/post.php' ); define( 'GFORMS_MAX_FIELD_LENGTH', 200 ); class GFFormsModel { public static $uploaded_files = array(); public static $unique_ids = array(); private static $_confirmations = array(); private static $_current_forms = array(); private static $_current_lead = null; public static function flush_current_forms() { self::$_current_forms = null; } public static function flush_current_lead() { self::$_current_lead = null; } public static function flush_confirmations() { self::$_confirmations = null; } public static function get_form_table_name() { global $wpdb; return $wpdb->prefix . 'rg_form'; } public static function get_meta_table_name() { global $wpdb; return $wpdb->prefix . 'rg_form_meta'; } public static function get_form_view_table_name() { global $wpdb; return $wpdb->prefix . 'rg_form_view'; } public static function get_lead_table_name() { global $wpdb; return $wpdb->prefix . 'rg_lead'; } public static function get_lead_meta_table_name() { global $wpdb; return $wpdb->prefix . 'rg_lead_meta'; } public static function get_lead_notes_table_name() { global $wpdb; return $wpdb->prefix . 'rg_lead_notes'; } public static function get_lead_details_table_name() { global $wpdb; return $wpdb->prefix . 'rg_lead_detail'; } public static function get_lead_details_long_table_name() { global $wpdb; return $wpdb->prefix . 'rg_lead_detail_long'; } public static function get_lead_view_name() { global $wpdb; return $wpdb->prefix . 'rg_lead_view'; } public static function get_incomplete_submissions_table_name() { global $wpdb; return $wpdb->prefix . 'rg_incomplete_submissions'; } public static function get_forms( $is_active = null, $sort_column = 'title', $sort_dir = 'ASC', $is_trash = false ) { global $wpdb; $form_table_name = self::get_form_table_name(); $lead_table_name = self::get_lead_table_name(); $view_table_name = self::get_form_view_table_name(); $where_arr = array(); $where_arr[] = $wpdb->prepare( 'is_trash=%d', $is_trash ); if ( $is_active !== null ) { $where_arr[] = $wpdb->prepare( 'is_active=%d', $is_active ); } $where_clause = 'WHERE ' . join( ' AND ', $where_arr ); $sort_keyword = $sort_dir == 'ASC' ? 'ASC' : 'DESC'; $db_columns = self::get_form_db_columns(); if ( ! in_array( strtolower( $sort_column ), $db_columns ) ) { $sort_column = 'title'; } $order_by = ! empty( $sort_column ) ? "ORDER BY $sort_column $sort_keyword" : ''; $sql = "SELECT f.id, f.title, f.date_created, f.is_active, 0 as lead_count, 0 view_count FROM $form_table_name f $where_clause $order_by"; //Getting all forms $forms = $wpdb->get_results( $sql ); //Getting entry count per form $sql = "SELECT form_id, count(id) as lead_count FROM $lead_table_name l WHERE status='active' GROUP BY form_id"; $entry_count = $wpdb->get_results( $sql ); //Getting view count per form $sql = "SELECT form_id, sum(count) as view_count FROM $view_table_name GROUP BY form_id"; $view_count = $wpdb->get_results( $sql ); //Adding entry counts and to form array foreach ( $forms as &$form ) { foreach ( $view_count as $count ) { if ( $count->form_id == $form->id ) { $form->view_count = $count->view_count; break; } } foreach ( $entry_count as $count ) { if ( $count->form_id == $form->id ) { $form->lead_count = $count->lead_count; break; } } } return $forms; } public static function get_form_db_columns() { return array( 'id', 'title', 'date_created', 'is_active', 'is_trash' ); } public static function get_forms_by_id( $ids ) { _deprecated_function( 'get_forms_by_id', '1.7', 'get_form_meta_by_id' ); return self::get_form_meta_by_id( $ids ); } public static function get_form_payment_totals( $form_id ) { global $wpdb; $lead_table_name = self::get_lead_table_name(); $sql = $wpdb->prepare( " SELECT sum(payment_amount) revenue, count(l.id) orders FROM $lead_table_name l WHERE form_id=%d AND payment_amount IS NOT null", $form_id ); $totals = $wpdb->get_row( $sql, ARRAY_A ); $active = $wpdb->get_var( $wpdb->prepare( " SELECT count(id) as active FROM $lead_table_name WHERE form_id=%d AND payment_status='Active'", $form_id ) ); if ( empty( $active ) ) { $active = 0; } $totals['active'] = $active; return $totals; } public static function get_form_counts( $form_id ) { global $wpdb; $lead_table_name = self::get_lead_table_name(); $lead_detail_table_name = self::get_lead_details_table_name(); $sql = $wpdb->prepare( "SELECT (SELECT count(0) FROM $lead_table_name l INNER JOIN $lead_detail_table_name ld ON l.id=ld.lead_id WHERE l.form_id=%d AND l.status='active') as total, (SELECT count(0) FROM $lead_table_name l INNER JOIN $lead_detail_table_name ld ON l.id=ld.lead_id WHERE l.is_read=0 AND l.status='active' AND l.form_id=%d) as unread, (SELECT count(0) FROM $lead_table_name l INNER JOIN $lead_detail_table_name ld ON l.id=ld.lead_id WHERE l.is_starred=1 AND l.status='active' AND l.form_id=%d) as starred, (SELECT count(0) FROM $lead_table_name l INNER JOIN $lead_detail_table_name ld ON l.id=ld.lead_id WHERE l.status='spam' AND l.form_id=%d) as spam, (SELECT count(0) FROM $lead_table_name l INNER JOIN $lead_detail_table_name ld ON l.id=ld.lead_id WHERE l.status='trash' AND l.form_id=%d) as trash", $form_id, $form_id, $form_id, $form_id, $form_id ); $results = $wpdb->get_results( $sql, ARRAY_A ); return $results[0]; } public static function get_form_summary() { global $wpdb; $form_table_name = self::get_form_table_name(); $lead_table_name = self::get_lead_table_name(); $sql = "SELECT l.form_id, count(l.id) as unread_count FROM $lead_table_name l WHERE is_read=0 AND status='active' GROUP BY form_id"; //getting number of unread and total leads for all forms $unread_results = $wpdb->get_results( $sql, ARRAY_A ); $sql = "SELECT l.form_id, max(l.date_created) as last_lead_date, count(l.id) as total_leads FROM $lead_table_name l WHERE status='active' GROUP BY form_id"; $lead_date_results = $wpdb->get_results( $sql, ARRAY_A ); $sql = "SELECT id, title, '' as last_lead_date, 0 as unread_count FROM $form_table_name WHERE is_active=1 ORDER BY title"; $forms = $wpdb->get_results( $sql, ARRAY_A ); for ( $i = 0; $count = sizeof( $forms ), $i < $count; $i ++ ) { if ( is_array( $unread_results ) ) { foreach ( $unread_results as $unread_result ) { if ( $unread_result['form_id'] == $forms[ $i ]['id'] ) { $forms[ $i ]['unread_count'] = $unread_result['unread_count']; break; } } } if ( is_array( $lead_date_results ) ) { foreach ( $lead_date_results as $lead_date_result ) { if ( $lead_date_result['form_id'] == $forms[ $i ]['id'] ) { $forms[ $i ]['last_lead_date'] = $lead_date_result['last_lead_date']; $forms[ $i ]['total_leads'] = $lead_date_result['total_leads']; break; } } } } return $forms; } public static function get_form_count() { global $wpdb; $form_table_name = self::get_form_table_name(); $results = $wpdb->get_results( " SELECT (SELECT count(0) FROM $form_table_name WHERE is_trash = 0) as total, (SELECT count(0) FROM $form_table_name WHERE is_active=1 AND is_trash = 0 ) as active, (SELECT count(0) FROM $form_table_name WHERE is_active=0 AND is_trash = 0 ) as inactive, (SELECT count(0) FROM $form_table_name WHERE is_trash=1) as trash " ); return array( 'total' => intval( $results[0]->total ), 'active' => intval( $results[0]->active ), 'inactive' => intval( $results[0]->inactive ), 'trash' => intval( $results[0]->trash ) ); } public static function get_form_id( $form_title ) { $forms = self::get_forms(); foreach ( $forms as $form ) { $sanitized_name = str_replace( '[', '', str_replace( ']', '', $form->title ) ); if ( $form->title == $form_title || $sanitized_name == $form_title ) { return $form->id; } } return 0; } public static function get_form( $form_id, $allow_trash = false ) { global $wpdb; $table_name = self::get_form_table_name(); $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; } public static function unserialize( $string ) { if ( is_serialized( $string ) ) { $obj = @unserialize( $string ); } else { $obj = json_decode( $string, true ); } return $obj; } public static function get_form_meta( $form_id ) { global $wpdb; // return cached version if form meta has been previously retrieved for this form if ( isset( self::$_current_forms[ $form_id ] ) ) { return self::$_current_forms[ $form_id ]; } $table_name = self::get_meta_table_name(); $form_row = $wpdb->get_row( $wpdb->prepare( "SELECT display_meta, notifications FROM {$table_name} WHERE form_id=%d", $form_id ), ARRAY_A ); //Loading main form object (supports serialized strings as well as JSON strings) $form = self::unserialize( $form_row['display_meta'] ); if ( ! $form ) { return null; } //loading notifications $form['notifications'] = self::unserialize( $form_row['notifications'] ); //creating field objects and copying some form variables down to fields for easier access $form = self::convert_field_objects( $form ); // loading confirmations from legacy structure into new structure $form = self::load_confirmations( $form ); //only migrate legacy notification if there isn't any notification configured in new structure if ( ! isset( $form['notifications'] ) ) { $form = self::load_notifications_from_legacy( $form ); //moving notification data from legacy structure into new 'notifications' array } //load notifications to legacy structure to maintain backward compatibility with legacy hooks and functions $form = self::load_notifications_to_legacy( $form ); $form = apply_filters( 'gform_form_post_get_meta', $form ); // cached form meta for cheaper retrieval on subsequent requests self::$_current_forms[ $form_id ] = $form; return $form; } public static function convert_field_objects( $form ) { $page_number = 1; if ( is_array( rgar( $form, 'fields' ) ) ) { foreach ( $form['fields'] as &$field ) { $field = GF_Fields::create( $field ); if ( isset( $form['id'] ) ) { $field->formId = $form['id']; } $field->pageNumber = $page_number; if ( $field->type == 'page' ) { $page_number ++; $field->pageNumber = $page_number; } } } return $form; } public static function get_form_meta_by_id( $ids ) { global $wpdb; $form_table_name = self::get_form_table_name(); $meta_table_name = self::get_meta_table_name(); if ( is_array( $ids ) ) { $ids = implode( ',', array_map( 'intval', $ids ) ); } else { $ids = intval( $ids ); } $results = $wpdb->get_results( " SELECT display_meta, confirmations, notifications FROM {$form_table_name} f INNER JOIN {$meta_table_name} m ON f.id = m.form_id WHERE id in({$ids})", ARRAY_A ); foreach ( $results as &$result ) { $form = self::unserialize( $result['display_meta'] ); $form['confirmations'] = self::unserialize( $result['confirmations'] ); $form['notifications'] = self::unserialize( $result['notifications'] ); //creating field objects and copying some form variables down to fields for easier access $form = self::convert_field_objects( $form ); $result = $form; } return $results; } private static function load_notifications_to_legacy( $form ) { if ( ! is_array( rgar( $form, 'notifications' ) ) ) { return $form; } foreach ( $form['notifications'] as $notification ) { if ( ! in_array( rgar( $notification, 'type' ), array( 'user', 'admin' ) ) ) { continue; } $legacy_notification = $notification; if ( $notification['toType'] == 'field' ) { $legacy_notification['toField'] = $notification['to']; unset( $legacy_notification['to'] ); } //unsetting new properties unset( $legacy_notification['toType'] ); unset( $legacy_notification['id'] ); unset( $legacy_notification['event'] ); unset( $legacy_notification['name'] ); if ( isset( $legacy_notification['type'] ) ) { unset( $legacy_notification['type'] ); } //saving into form object $property = $notification['type'] == 'user' ? 'autoResponder' : 'notification'; $form[ $property ] = $legacy_notification; } return $form; } private static function load_notifications_from_legacy( $form ) { $form['notifications'] = array(); if ( GFCommon::has_admin_notification( $form ) ) { $admin_notification = $form['notification']; //if there is a fromField configured, move it to 'from' as a merge tag $admin_notification = self::convert_property_to_merge_tag( $form, $admin_notification, 'from', 'fromField' ); //if there is a fromNameField configured, move it to 'fromName' as a merge tag $admin_notification = self::convert_property_to_merge_tag( $form, $admin_notification, 'fromName', 'fromNameField' ); //if there is a replyToField configured, move it to 'replyTo' as a merge tag $admin_notification = self::convert_property_to_merge_tag( $form, $admin_notification, 'replyTo', 'replyToField' ); //if routing is configured, set toType to routing, otherwise, set it to email $admin_notification['toType'] = ! rgempty( 'routing', $admin_notification ) ? 'routing' : 'email'; $notification_id = uniqid(); //assigning this notification to the form_submission action $admin_notification['event'] = 'form_submission'; $admin_notification['name'] = __( 'Admin Notification', 'gravityforms' ); $admin_notification['type'] = 'admin'; $admin_notification['id'] = $notification_id; //copying admin notification as an item in the new notifications array $form['notifications'][ $notification_id ] = $admin_notification; } if ( GFCommon::has_user_notification( $form ) ) { $user_notification = $form['autoResponder']; //if there is a toField configured, set toType to field, if not, set it toemail $to_field = rgar( $user_notification, 'toField' ); if ( ! empty( $to_field ) ) { $user_notification['toType'] = 'field'; $user_notification['to'] = $to_field; } else { $user_notification['toType'] = 'email'; } $notification_id = uniqid(); //assigning this notification to the form_submission action $user_notification['event'] = 'form_submission'; $user_notification['name'] = __( 'User Notification', 'gravityforms' ); $user_notification['type'] = 'user'; $user_notification['id'] = $notification_id; //copying user notification as an item in the new notifications array $form['notifications'][ $notification_id ] = $user_notification; } self::save_form_notifications( $form['id'], $form['notifications'] ); return $form; } private static function convert_property_to_merge_tag( $form, $array, $target_property, $source_property ) { $merge_tag = self::get_field_merge_tag( $form, rgar( $array, $source_property ) ); if ( $merge_tag ) { $array[ $target_property ] = $merge_tag; unset( $array[ $source_property ] ); } return $array; } private static function get_field_merge_tag( $form, $field_id ) { $field = self::get_field( $form, $field_id ); if ( ! $field ) { return false; } return '{' . GFCommon::get_label( $field, $field_id ) . ':' . $field_id . '}'; } public static function add_default_properties( $form ) { _deprecated_function( 'GFFormsModel::add_default_properties', '1.9' ); if ( is_array( rgar( $form, 'fields' ) ) ) { $all_fields = array( 'adminLabel' => '', 'adminOnly' => '', 'allowsPrepopulate' => '', 'defaultValue' => '', 'description' => '', 'content' => '', 'cssClass' => '', 'errorMessage' => '', 'id' => '', 'inputName' => '', 'isRequired' => '', 'label' => '', 'noDuplicates' => '', 'size' => '', 'type' => '', 'postCustomFieldName' => '', 'displayAllCategories' => '', 'displayCaption' => '', 'displayDescription' => '', 'displayTitle' => '', 'inputType' => '', 'rangeMin' => '', 'rangeMax' => '', 'calendarIconType' => '', 'calendarIconUrl' => '', 'dateType' => '', 'dateFormat' => '', 'phoneFormat' => '', 'addressType' => '', 'defaultCountry' => '', 'defaultProvince' => '', 'defaultState' => '', 'hideAddress2' => '', 'hideCountry' => '', 'hideState' => '', 'inputs' => '', 'nameFormat' => '', 'allowedExtensions' => '', 'captchaType' => '', 'pageNumber' => '', 'captchaTheme' => '', 'simpleCaptchaSize' => '', 'simpleCaptchaFontColor' => '', 'simpleCaptchaBackgroundColor' => '', 'failed_validation' => '', 'productField' => '', 'enablePasswordInput' => '', 'maxLength' => '', 'enablePrice' => '', 'basePrice' => '', ); foreach ( $form['fields'] as &$field ) { if ( is_array( $field ) ) { $field = wp_parse_args( $field, $all_fields ); } } } return $form; } public static function get_grid_column_meta( $form_id ) { global $wpdb; $table_name = self::get_meta_table_name(); return maybe_unserialize( $wpdb->get_var( $wpdb->prepare( "SELECT entries_grid_meta FROM $table_name WHERE form_id=%d", $form_id ) ) ); } public static function update_grid_column_meta( $form_id, $columns ) { global $wpdb; $table_name = self::get_meta_table_name(); $meta = maybe_serialize( stripslashes_deep( $columns ) ); $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET entries_grid_meta=%s WHERE form_id=%d", $meta, $form_id ) ); } public static function get_lead_detail_id( $current_fields, $field_number ) { foreach ( $current_fields as $field ) { if ( $field->field_number == $field_number ) { return $field->id; } } return 0; } public static function update_form_active( $form_id, $is_active ) { global $wpdb; $form_table = self::get_form_table_name(); $sql = $wpdb->prepare( "UPDATE $form_table SET is_active=%d WHERE id=%d", $is_active, $form_id ); $wpdb->query( $sql ); if ( $is_active ) { do_action( 'gform_post_form_activated', $form_id ); } else { do_action( 'gform_post_form_deactivated', $form_id ); } } public static function update_notification_active( $form_id, $notification_id, $is_active ) { $form = GFFormsModel::get_form_meta( $form_id ); if ( ! isset( $form['notifications'][ $notification_id ] ) ) { return new WP_Error( 'not_found', __( 'Notification not found', 'gravityforms' ) ); } $form['notifications'][ $notification_id ]['isActive'] = (bool) $is_active; if ( (bool) $is_active ) { do_action( 'gform_pre_notification_activated', $form['notifications'][ $notification_id ], $form ); } else { do_action( 'gform_pre_notification_deactivated', $form['notifications'][ $notification_id ], $form ); } $result = GFFormsModel::update_form_meta( $form_id, $form['notifications'], 'notifications' ); return $result; } public static function update_confirmation_active( $form_id, $confirmation_id, $is_active ) { $form = GFFormsModel::get_form_meta( $form_id ); if ( ! isset( $form['confirmations'][ $confirmation_id ] ) ) { return new WP_Error( 'not_found', __( 'Notification not found', 'gravityforms' ) ); } $form['confirmations'][ $confirmation_id ]['isActive'] = (bool) $is_active; $result = GFFormsModel::update_form_meta( $form_id, $form['confirmations'], 'confirmations' ); return $result; } public static function update_forms_active( $forms, $is_active ) { foreach ( $forms as $form_id ) { self::update_form_active( $form_id, $is_active ); } } public static function update_leads_property( $leads, $property_name, $property_value ) { foreach ( $leads as $lead ) { self::update_lead_property( $lead, $property_name, $property_value ); } } public static function update_lead_property( $lead_id, $property_name, $property_value, $update_akismet = true, $disable_hook = false ) { global $wpdb; $lead_table = self::get_lead_table_name(); $lead = self::get_lead( $lead_id ); //marking entry as 'spam' or 'not spam' with Akismet if the plugin is installed if ( $update_akismet && GFCommon::akismet_enabled( $lead['form_id'] ) && $property_name == 'status' && in_array( $property_value, array( 'active', 'spam' ) ) ) { $current_status = $lead['status']; if ( $current_status == 'spam' && $property_value == 'active' ) { $form = self::get_form_meta( $lead['form_id'] ); GFCommon::mark_akismet_spam( $form, $lead, false ); } else if ( $current_status == 'active' && $property_value == 'spam' ) { $form = self::get_form_meta( $lead['form_id'] ); GFCommon::mark_akismet_spam( $form, $lead, true ); } } //updating lead $result = $wpdb->update( $lead_table, array( $property_name => $property_value ), array( 'id' => $lead_id ) ); if ( ! $disable_hook ) { $previous_value = rgar( $lead, $property_name ); if ( $previous_value != $property_value ) { // if property is status, prev value is spam and new value is active if ( $property_name == 'status' && $previous_value == 'spam' && $property_value == 'active' && ! rgar( $lead, 'post_id' ) ) { $lead[ $property_name ] = $property_value; $lead['post_id'] = GFCommon::create_post( $form, $lead ); } do_action( "gform_update_{$property_name}", $lead_id, $property_value, $previous_value ); } } return $result; } public static function update_lead( $lead ) { _deprecated_function( 'GFFormsModel::update_lead()', '1.8.8', 'GFAPI::update_entry()' ); global $wpdb; $lead_table = self::get_lead_table_name(); $payment_date = strtotime( rgar( $lead, 'payment_date' ) ) ? "'" . gmdate( 'Y-m-d H:i:s', strtotime( "{$lead['payment_date']}" ) ) . "'" : 'NULL'; $payment_amount = ! rgblank( rgar( $lead, 'payment_amount' ) ) ? (float) rgar( $lead, 'payment_amount' ) : 'NULL'; $transaction_type = ! rgempty( 'transaction_type', $lead ) ? intval( $lead['transaction_type'] ) : 'NULL'; $status = ! rgempty( 'status', $lead ) ? $lead['status'] : 'active'; $source_url = self::truncate( rgar( $lead, 'source_url' ), 200 ); $user_agent = self::truncate( rgar( $lead, 'user_agent' ), 250 ); $sql = $wpdb->prepare( "UPDATE $lead_table SET form_id=%d, post_id=%d, is_starred=%d, is_read=%d, ip=%s, source_url=%s, user_agent=%s, currency=%s, payment_status=%s, payment_date={$payment_date}, payment_amount={$payment_amount}, transaction_id=%s, is_fulfilled=%d, transaction_type={$transaction_type}, payment_method=%s, status='{$status}' WHERE id=%d", rgar( $lead, 'form_id' ), rgar( $lead, 'post_id' ), rgar( $lead, 'is_starred' ), rgar( $lead, 'is_read' ), rgar( $lead, 'ip' ), $source_url, $user_agent, rgar( $lead, 'currency' ), rgar( $lead, 'payment_status' ), rgar( $lead, 'transaction_id' ), rgar( $lead, 'is_fulfilled' ), rgar( $lead, 'payment_method' ), rgar( $lead, 'id' ) ); $wpdb->query( $sql ); self::set_current_lead( $lead ); } private static function truncate( $str, $length ) { if ( strlen( $str ) > $length ) { $str = substr( $str, 0, $length ); } return $str; } public static function delete_leads( $leads ) { foreach ( $leads as $lead_id ) { self::delete_lead( $lead_id ); } } public static function delete_forms( $forms ) { foreach ( $forms as $form_id ) { self::delete_form( $form_id ); } } public static function trash_forms( $form_ids ) { foreach ( $form_ids as $form_id ) { self::trash_form( $form_id ); } } public static function restore_forms( $form_ids ) { foreach ( $form_ids as $form_id ) { self::restore_form( $form_id ); } } public static function delete_leads_by_form( $form_id, $status = '' ) { global $wpdb; $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(); $lead_meta_table = self::get_lead_meta_table_name(); do_action( 'gform_delete_entries', $form_id, $status ); //deleting uploaded files self::delete_files_by_form( $form_id, $status ); $status_filter = empty( $status ) ? '' : $wpdb->prepare( 'AND status=%s', $status ); //Delete from detail long $sql = $wpdb->prepare( " DELETE FROM $lead_detail_long_table WHERE lead_detail_id IN( SELECT ld.id FROM $lead_detail_table ld INNER JOIN $lead_table l ON l.id = ld.lead_id WHERE l.form_id=%d AND ld.form_id=%d {$status_filter} )", $form_id, $form_id ); $wpdb->query( $sql ); //Delete from lead details $sql = $wpdb->prepare( " DELETE FROM $lead_detail_table WHERE lead_id IN ( SELECT id FROM $lead_table WHERE form_id=%d {$status_filter} )", $form_id ); $wpdb->query( $sql ); //Delete from lead notes $sql = $wpdb->prepare( " DELETE FROM $lead_notes_table WHERE lead_id IN ( SELECT id FROM $lead_table WHERE form_id=%d {$status_filter} )", $form_id ); $wpdb->query( $sql ); //Delete from lead meta $sql = $wpdb->prepare( " DELETE FROM $lead_meta_table WHERE lead_id IN ( SELECT id FROM $lead_table WHERE form_id=%d {$status_filter} )", $form_id ); $wpdb->query( $sql ); //Delete from lead $sql = $wpdb->prepare( "DELETE FROM $lead_table WHERE form_id=%d {$status_filter}", $form_id ); $wpdb->query( $sql ); } public static function delete_views( $form_id ) { global $wpdb; $form_view_table = self::get_form_view_table_name(); //Delete form view $sql = $wpdb->prepare( "DELETE FROM $form_view_table WHERE form_id=%d", $form_id ); $wpdb->query( $sql ); do_action( 'gform_post_form_views_deleted', $form_id ); } public static function delete_form( $form_id ) { global $wpdb; do_action( 'gform_before_delete_form', $form_id ); $form_meta_table = self::get_meta_table_name(); $form_table = self::get_form_table_name(); //Deleting form Entries self::delete_leads_by_form( $form_id ); //Delete form meta $sql = $wpdb->prepare( "DELETE FROM $form_meta_table WHERE form_id=%d", $form_id ); $wpdb->query( $sql ); //Deleting form Views self::delete_views( $form_id ); //Delete form $sql = $wpdb->prepare( "DELETE FROM $form_table WHERE id=%d", $form_id ); $wpdb->query( $sql ); do_action( 'gform_after_delete_form', $form_id ); } public static function trash_form( $form_id ) { global $wpdb; $form_table_name = self::get_form_table_name(); $sql = $wpdb->prepare( "UPDATE $form_table_name SET is_trash=1 WHERE id=%d", $form_id ); $result = $wpdb->query( $sql ); self::$_current_forms[ $form_id ] = null; $success = $result == false; do_action( 'gform_post_form_trashed', $form_id ); return $success; } public static function restore_form( $form_id ) { global $wpdb; $form_table_name = self::get_form_table_name(); $sql = $wpdb->prepare( "UPDATE $form_table_name SET is_trash=0 WHERE id=%d", $form_id ); $result = $wpdb->query( $sql ); self::$_current_forms[ $form_id ] = null; $success = $result == false; do_action( 'gform_post_form_restored', $form_id ); return $success; } public static function duplicate_form( $form_id ) { global $wpdb; if ( ! GFCommon::current_user_can_any( 'gravityforms_create_form' ) ) { die( __( "You don't have adequate permission to create forms.", 'gravityforms' ) ); } //finding unique title $form = self::get_form( $form_id ); $count = 2; $title = $form->title . ' - Copy 1'; while ( ! self::is_unique_title( $title ) ) { $title = $form->title . " - Copy $count"; $count ++; } //creating new form $new_id = self::insert_form( $title ); //copying form meta $meta = self::get_form_meta( $form_id ); $meta['title'] = $title; $meta['id'] = $new_id; $notifications = $meta['notifications']; $confirmations = $meta['confirmations']; unset( $meta['notifications'] ); unset( $meta['confirmations'] ); self::update_form_meta( $new_id, $meta ); //copying notification meta self::update_form_meta( $new_id, $notifications, 'notifications' ); //copying confirmation meta self::update_form_meta( $new_id, $confirmations, 'confirmations' ); // The gform_after_duplicate_form action is deprecated since version 1.9. Please use gform_post_form_duplicated instead do_action( 'gform_after_duplicate_form', $form_id, $new_id ); do_action( 'gform_post_form_duplicated', $form_id, $new_id ); return $new_id; } public static function is_unique_title( $title ) { $forms = self::get_forms(); foreach ( $forms as $form ) { if ( strtolower( $form->title ) == strtolower( $title ) ) { return false; } } return true; } public static function ensure_tables_exist() { global $wpdb; $form_table_name = self::get_form_table_name(); $form_count = $wpdb->get_var( "SELECT count(0) FROM {$form_table_name}" ); if ( $wpdb->last_error ) { GFCommon::log_debug( 'GFFormsModel::ensure_tables_exist(): Blog ' . get_current_blog_id() . ' - Form database table does not exist. Forcing database setup.' ); GFForms::setup_database(); } } public static function insert_form( $form_title ) { global $wpdb; $form_table_name = $wpdb->prefix . 'rg_form'; //creating new form $wpdb->query( $wpdb->prepare( "INSERT INTO $form_table_name(title, date_created) VALUES(%s, utc_timestamp())", $form_title ) ); //returning newly created form id return $wpdb->insert_id; } public static function update_form_meta( $form_id, $form_meta, $meta_name = 'display_meta' ) { global $wpdb; $form_meta = apply_filters( 'gform_form_update_meta', $form_meta, $form_id, $meta_name ); $form_meta = apply_filters( "gform_form_update_meta_{$form_id}", $form_meta, $form_id, $meta_name ); $meta_table_name = self::get_meta_table_name(); $form_meta = json_encode( $form_meta ); if ( intval( $wpdb->get_var( $wpdb->prepare( "SELECT count(0) FROM $meta_table_name WHERE form_id=%d", $form_id ) ) ) > 0 ) { $result = $wpdb->query( $wpdb->prepare( "UPDATE $meta_table_name SET $meta_name=%s WHERE form_id=%d", $form_meta, $form_id ) ); } else { $result = $wpdb->query( $wpdb->prepare( "INSERT INTO $meta_table_name(form_id, $meta_name) VALUES(%d, %s)", $form_id, $form_meta ) ); } self::$_current_forms[ $form_id ] = null; do_action( 'gform_post_update_form_meta', $form_meta, $form_id, $meta_name ); do_action( "gform_post_update_form_meta_{$form_id}", $form_meta, $form_id, $meta_name ); return $result; } public static function delete_files( $lead_id, $form = null ) { $lead = self::get_lead( $lead_id ); if ( $form == null ) { $form = self::get_form_meta( $lead['form_id'] ); } $fields = GFCommon::get_fields_by_type( $form, array( 'fileupload', 'post_image' ) ); if ( is_array( $fields ) ) { foreach ( $fields as $field ) { if ( $field->multipleFiles ) { $value_json = self::get_lead_field_value( $lead, $field ); 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 ); self::delete_physical_file( $value ); } } } } public static function delete_files_by_form( $form_id, $status = '' ) { global $wpdb; $form = self::get_form_meta( $form_id ); $fields = GFCommon::get_fields_by_type( $form, array( 'fileupload', 'post_image' ) ); if ( empty( $fields ) ) { return; } $status_filter = empty( $status ) ? '' : $wpdb->prepare( 'AND status=%s', $status ); $results = $wpdb->get_results( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}rg_lead WHERE form_id=%d {$status_filter}", $form_id ), ARRAY_A ); foreach ( $results as $result ) { self::delete_files( $result['id'], $form ); } } public static function delete_file( $entry_id, $field_id, $file_index = 0 ) { global $wpdb; if ( $entry_id == 0 || $field_id == 0 ) { return; } $entry = self::get_lead( $entry_id ); $form_id = $entry['form_id']; $form = self::get_form_meta( $form_id ); $field = self::get_field( $form, $field_id ); $multiple_files = $field->multipleFiles; if ( $multiple_files ) { $file_urls = json_decode( $entry[ $field_id ], true ); $file_url = $file_urls[ $file_index ]; unset( $file_urls[ $file_index ] ); $file_urls = array_values( $file_urls ); $field_value = empty( $file_urls ) ? '' : json_encode( $file_urls ); } else { $file_url = $entry[ $field_id ]; $field_value = ''; } self::delete_physical_file( $file_url ); // update lead field value - simulate form submission $lead_detail_table = self::get_lead_details_table_name(); $sql = $wpdb->prepare( "SELECT id FROM $lead_detail_table WHERE lead_id=%d AND field_number BETWEEN %s AND %s", $entry_id, doubleval( $field_id ) - 0.0001, doubleval( $field_id ) + 0.0001 ); $entry_detail_id = $wpdb->get_var( $sql ); self::update_lead_field_value( $form, $entry, $field, $entry_detail_id, $field_id, $field_value ); } private static function delete_physical_file( $file_url ) { $ary = explode( '|:|', $file_url ); $url = rgar( $ary, 0 ); if ( empty( $url ) ) { return; } //Convert from url to physical path if ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) { $file_path = preg_replace( "|^(.*?)/files/gravity_forms/|", BLOGUPLOADDIR . 'gravity_forms/', $url ); } else { $file_path = str_replace( WP_CONTENT_URL, WP_CONTENT_DIR, $url ); } if ( file_exists( $file_path ) ) { unlink( $file_path ); } } public static function delete_field( $form_id, $field_id ) { global $wpdb; if ( $form_id == 0 ) { return; } do_action( 'gform_before_delete_field', $form_id, $field_id ); $lead_table = self::get_lead_table_name(); $lead_detail_table = self::get_lead_details_table_name(); $lead_detail_long_table = self::get_lead_details_long_table_name(); $form = self::get_form_meta( $form_id ); $field_type = ''; //Deleting field from form meta $count = sizeof( $form['fields'] ); for ( $i = $count - 1; $i >= 0; $i -- ) { $field = $form['fields'][ $i ]; //Deleting associated conditional logic rules if ( ! empty( $field->conditionalLogic ) ) { $rule_count = sizeof( $field->conditionalLogic['rules'] ); for ( $j = $rule_count - 1; $j >= 0; $j -- ) { if ( $field->conditionalLogic['rules'][ $j ]['fieldId'] == $field_id ) { unset( $form['fields'][ $i ]->conditionalLogic['rules'][ $j ] ); } } $form['fields'][ $i ]->conditionalLogic['rules'] = array_values( $form['fields'][ $i ]->conditionalLogic['rules'] ); //If there aren't any rules, remove the conditional logic if ( sizeof( $form['fields'][ $i ]->conditionalLogic['rules'] ) == 0 ) { $form['fields'][ $i ]->conditionalLogic = false; } } //Deleting field from form meta if ( $field->id == $field_id ) { $field_type = $field->type; unset( $form['fields'][ $i ] ); } } //removing post content and title template if the field being deleted is a post content field or post title field if ( $field_type == 'post_content' ) { $form['postContentTemplateEnabled'] = false; $form['postContentTemplate'] = ''; } else if ( $field_type == 'post_title' ) { $form['postTitleTemplateEnabled'] = false; $form['postTitleTemplate'] = ''; } //Deleting associated routing rules if ( ! empty( $form['notification']['routing'] ) ) { $routing_count = sizeof( $form['notification']['routing'] ); for ( $j = $routing_count - 1; $j >= 0; $j -- ) { if ( intval( $form['notification']['routing'][ $j ]['fieldId'] ) == $field_id ) { unset( $form['notification']['routing'][ $j ] ); } } $form['notification']['routing'] = array_values( $form['notification']['routing'] ); //If there aren't any routing, remove it if ( sizeof( $form['notification']['routing'] ) == 0 ) { $form['notification']['routing'] = null; } } $form['fields'] = array_values( $form['fields'] ); self::update_form_meta( $form_id, $form ); //Delete from grid column meta $columns = self::get_grid_column_meta( $form_id ); $count = sizeof( $columns ); for ( $i = $count - 1; $i >= 0; $i -- ) { if ( intval( rgar( $columns, $i ) ) == intval( $field_id ) ) { unset( $columns[ $i ] ); } } self::update_grid_column_meta( $form_id, $columns ); //Delete from detail long $sql = $wpdb->prepare( " DELETE FROM $lead_detail_long_table WHERE lead_detail_id IN( SELECT id FROM $lead_detail_table WHERE form_id=%d AND field_number >= %d AND field_number < %d )", $form_id, $field_id, $field_id + 1 ); $wpdb->query( $sql ); //Delete from lead details $sql = $wpdb->prepare( "DELETE FROM $lead_detail_table WHERE form_id=%d AND field_number >= %d AND field_number < %d", $form_id, $field_id, $field_id + 1 ); $wpdb->query( $sql ); //Delete leads with no details $sql = $wpdb->prepare( " DELETE FROM $lead_table WHERE form_id=%d AND id NOT IN( SELECT DISTINCT(lead_id) FROM $lead_detail_table WHERE form_id=%d )", $form_id, $form_id ); $wpdb->query( $sql ); do_action( 'gform_after_delete_field', $form_id, $field_id ); } public static function delete_lead( $lead_id ) { global $wpdb; do_action( 'gform_delete_lead', $lead_id ); $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(); //deleting uploaded files self::delete_files( $lead_id ); //Delete from detail long $sql = $wpdb->prepare( " DELETE FROM $lead_detail_long_table WHERE lead_detail_id IN( SELECT id FROM $lead_detail_table WHERE lead_id=%d )", $lead_id ); $wpdb->query( $sql ); //Delete from lead details $sql = $wpdb->prepare( "DELETE FROM $lead_detail_table WHERE lead_id=%d", $lead_id ); $wpdb->query( $sql ); //Delete from lead notes $sql = $wpdb->prepare( "DELETE FROM $lead_notes_table WHERE lead_id=%d", $lead_id ); $wpdb->query( $sql ); //Delete from lead meta gform_delete_meta( $lead_id ); //Delete from lead $sql = $wpdb->prepare( "DELETE FROM $lead_table WHERE id=%d", $lead_id ); $wpdb->query( $sql ); } 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, note_type, date_created) values(%d, %d, %s, %s, %s, utc_timestamp())", $lead_id, $user_id, $user_name, $note, $note_type ); $wpdb->query( $sql ); do_action( 'gform_post_note_added', $wpdb->insert_id, $lead_id, $user_id, $user_name, $note, $note_type ); } public static function delete_note( $note_id ) { global $wpdb; $table_name = self::get_lead_notes_table_name(); $lead_id = $wpdb->get_var( $wpdb->prepare( "SELECT lead_id FROM $table_name WHERE id = %d", $note_id ) ); do_action( 'gform_pre_note_deleted', $note_id, $lead_id ); $sql = $wpdb->prepare( "DELETE FROM $table_name WHERE id=%d", $note_id ); $wpdb->query( $sql ); } public static function delete_notes( $notes ) { if ( ! is_array( $notes ) ) { return; } foreach ( $notes as $note_id ) { self::delete_note( $note_id ); } } public static function get_ip() { $ip = ''; $headers = array( 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR' ); foreach ( $headers as $header ) { $ip = rgar( $_SERVER, $header ); if ( $ip ) { break; } } // HTTP_X_FORWARDED_FOR can return a comma separated list of IPs; using the first one $ips = explode( ',', $ip ); return $ips[0]; } public static function save_lead( $form, &$lead ) { global $wpdb; GFCommon::log_debug( 'GFFormsModel::save_lead(): Saving entry.' ); $is_form_editor = GFCommon::is_form_editor(); $is_entry_detail = GFCommon::is_entry_detail(); $is_admin = $is_form_editor || $is_entry_detail; if ( $is_admin && ! GFCommon::current_user_can_any( 'gravityforms_edit_entries' ) ) { 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 ( $is_new_lead ) { global $current_user; $user_id = $current_user && $current_user->ID ? $current_user->ID : 'NULL'; $lead_table = RGFormsModel::get_lead_table_name(); $user_agent = self::truncate( $_SERVER['HTTP_USER_AGENT'], 250 ); $currency = GFCommon::get_currency(); $source_url = self::truncate( self::get_current_page_url(), 200 ); $wpdb->query( $wpdb->prepare( "INSERT INTO $lead_table(form_id, ip, source_url, date_created, user_agent, currency, created_by) VALUES(%d, %s, %s, utc_timestamp(), %s, %s, {$user_id})", $form['id'], self::get_ip(), $source_url, $user_agent, $currency ) ); //reading newly created lead id $lead_id = $wpdb->insert_id; $lead = array( 'id' => $lead_id ); GFCommon::log_debug( "GFFormsModel::save_lead(): Entry record created in the database. ID: {$lead_id}." ); } $current_fields = $wpdb->get_results( $wpdb->prepare( "SELECT id, field_number FROM $lead_detail_table WHERE lead_id=%d", $lead['id'] ) ); $total_fields = array(); /* @var $calculation_fields GF_Field[] */ $calculation_fields = array(); $recalculate_total = false; GFCommon::log_debug( 'GFFormsModel::save_lead(): Saving entry fields.' ); foreach ( $form['fields'] as $field ) { /* @var $field GF_Field */ //Ignore fields that are marked as display only if ( $field->displayOnly && $field->type != 'password' ) { continue; } //ignore pricing fields in the entry detail if ( RG_CURRENT_VIEW == 'entry' && GFCommon::is_pricing_field( $field->type ) ) { continue; } //process total field after all fields have been saved if ( $field->type == 'total' ) { $total_fields[] = $field; continue; } $is_entry_update = RG_CURRENT_VIEW == 'entry' || ! $is_new_lead; $read_value_from_post = $is_new_lead || ! isset( $lead[ 'date_created' ] ); //only save fields that are not hidden (except when updating an entry) if( $is_entry_update || ! GFFormsModel::is_field_hidden( $form, $field, array(), $read_value_from_post ? null : $lead ) ) { // process calculation fields after all fields have been saved (moved after the is hidden check) if ( $field->has_calculation() ) { $calculation_fields[] = $field; continue; } GFCommon::log_debug( "GFFormsModel::save_lead(): Saving field {$field->label}(#{$field->id} - {$field->type})." ); if ( $field->type == 'post_category' ) { $field = GFCommon::add_categories_as_choices( $field, '' ); } $inputs = $field->get_entry_inputs(); if ( is_array( $inputs ) ) { foreach ( $inputs as $input ) { self::save_input( $form, $field, $lead, $current_fields, $input['id'] ); } } else { self::save_input( $form, $field, $lead, $current_fields, $field->id ); } } } if ( ! empty( $calculation_fields ) ) { foreach ( $calculation_fields as $calculation_field ) { GFCommon::log_debug( "GFFormsModel::save_lead(): Saving calculated field {$calculation_field->label}(#{$calculation_field->id} - {$calculation_field->type})." ); $inputs = $calculation_field->get_entry_inputs(); if ( is_array( $inputs ) ) { foreach ( $inputs as $input ) { self::save_input( $form, $calculation_field, $lead, $current_fields, $input['id'] ); self::refresh_lead_field_value( $lead['id'], $input['id'] ); } } else { self::save_input( $form, $calculation_field, $lead, $current_fields, $calculation_field->id ); self::refresh_lead_field_value( $lead['id'], $calculation_field->id ); } } self::refresh_product_cache( $form, $lead = RGFormsModel::get_lead( $lead['id'] ) ); } //saving total field as the last field of the form. if ( ! empty( $total_fields ) ) { foreach ( $total_fields as $total_field ) { GFCommon::log_debug( 'GFFormsModel::save_lead(): Saving total field.' ); self::save_input( $form, $total_field, $lead, $current_fields, $total_field->id ); self::refresh_lead_field_value( $lead['id'], $total_field['id'] ); } } } public static function create_lead( $form ) { global $current_user; $total_fields = array(); $calculation_fields = array(); $lead = array(); $lead['id'] = null; $lead['post_id'] = null; $lead['date_created'] = null; $lead['form_id'] = $form['id']; $lead['ip'] = self::get_ip(); $lead['source_url'] = self::truncate( self::get_current_page_url(), 200 ); $lead['user_agent'] = strlen( $_SERVER['HTTP_USER_AGENT'] ) > 250 ? substr( $_SERVER['HTTP_USER_AGENT'], 0, 250 ) : $_SERVER['HTTP_USER_AGENT']; $lead['currency'] = GFCommon::get_currency(); $lead['created_by'] = $current_user && $current_user->ID ? $current_user->ID : 'NULL'; foreach ( $form['fields'] as $field ) { /* @var $field GF_Field */ // ignore fields that are marked as display only if ( $field->displayOnly && $field->type != 'password' ) { continue; } // process total field after all fields have been saved if ( $field->type == 'total' ) { $total_fields[] = $field; continue; } // process calculation fields after all fields have been saved if ( $field->has_calculation() ) { $calculation_fields[] = $field; continue; } // only save fields that are not hidden if ( ! RGFormsModel::is_field_hidden( $form, $field, array() ) ) { if ( $field->type == 'post_category' ) { $field = GFCommon::add_categories_as_choices( $field, '' ); } $inputs = $field->get_entry_inputs(); if ( is_array( $inputs ) ) { foreach ( $field->inputs as $input ) { $lead[ (string) $input['id'] ] = self::get_prepared_input_value( $form, $field, $lead, $input['id'] ); } } else { $lead[ $field->id ] = self::get_prepared_input_value( $form, $field, $lead, $field->id ); } } } if ( ! empty( $calculation_fields ) ) { foreach ( $calculation_fields as $field ) { /* @var $field GF_Field */ // only save fields that are not hidden if ( RGFormsModel::is_field_hidden( $form, $field, array() ) ) { continue; } $inputs = $field->get_entry_inputs(); if ( is_array( $inputs ) ) { foreach ( $inputs as $input ) { $lead[ (string) $input['id'] ] = self::get_prepared_input_value( $form, $field, $lead, $input['id'] ); } } else { $lead[ $field->id ] = self::get_prepared_input_value( $form, $field, $lead, $field->id ); } } self::refresh_product_cache( $form, $lead ); } // saving total field as the last field of the form. if ( ! empty( $total_fields ) ) { foreach ( $total_fields as $total_field ) { $lead[ $total_field->id ] = self::get_prepared_input_value( $form, $total_field, $lead, $total_field->id ); } } return $lead; } public static function get_prepared_input_value( $form, $field, $lead, $input_id ) { $input_name = 'input_' . str_replace( '.', '_', $input_id ); if ( $field->enableCopyValuesOption && rgpost( 'input_' . $field->id . '_copy_values_activated' ) ) { $source_field_id = $field->copyValuesOptionField; $source_input_name = str_replace( 'input_' . $field->id, 'input_' . $source_field_id, $input_name ); $value = rgpost( $source_input_name ); } else { $value = rgpost( $input_name ); } $is_form_editor = GFCommon::is_form_editor(); $is_entry_detail = GFCommon::is_entry_detail(); $is_admin = $is_form_editor || $is_entry_detail; if ( empty( $value ) && $field->adminOnly && ! $is_admin ) { $value = self::get_default_value( $field, $input_id ); } switch ( self::get_input_type( $field ) ) { case 'post_image': $file_info = self::get_temp_filename( $form['id'], $input_name ); if ( ! empty( $file_info ) ) { $file_path = self::get_file_upload_path( $form['id'], $file_info['uploaded_filename'] ); $url = $file_path['url']; $image_title = isset( $_POST[ "{$input_name}_1" ] ) ? strip_tags( $_POST[ "{$input_name}_1" ] ) : ''; $image_caption = isset( $_POST[ "{$input_name}_4" ] ) ? strip_tags( $_POST[ "{$input_name}_4" ] ) : ''; $image_description = isset( $_POST[ "{$input_name}_7" ] ) ? strip_tags( $_POST[ "{$input_name}_7" ] ) : ''; $value = ! empty( $url ) ? $url . '|:|' . $image_title . '|:|' . $image_caption . '|:|' . $image_description : ''; } break; case 'fileupload' : if ( $field->multipleFiles ) { if ( ! empty( $value ) ) { $value = json_encode( $value ); } } else { $file_info = self::get_temp_filename( $form['id'], $input_name ); if ( ! empty( $file_info ) ) { $file_path = self::get_file_upload_path( $form['id'], $file_info['uploaded_filename'] ); $value = $file_path['url']; } } break; default: // processing values so that they are in the correct format for each input type $value = self::prepare_value( $form, $field, $value, $input_name, rgar( $lead, 'id' ), $lead ); } 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 ) { $cache_options = array( array( false, false ), array( false, true ), array( true, false ), array( true, true ), ); foreach ( $form['fields'] as $field ) { /* @var $field GF_Field */ if ( $field->has_calculation() ) { //deleting field value cache for calculated fields $cache_key = 'GFFormsModel::get_lead_field_value_' . $lead['id'] . '_' . $field->id; GFCache::delete( $cache_key ); } } foreach ( $cache_options as $cache_option ) { list( $use_choice_text, $use_admin_label ) = $cache_option; if ( gform_get_meta( rgar( $lead, 'id' ), "gform_product_info_{$use_choice_text}_{$use_admin_label}" ) ) { gform_delete_meta( rgar( $lead, 'id' ), "gform_product_info_{$use_choice_text}_{$use_admin_label}" ); GFCommon::get_product_fields( $form, $lead, $use_choice_text, $use_admin_label ); } } } /** * Check whether a field is hidden via conditional logic. * * @param array $form Form object. * @param GF_Field $field Field object. * @param array $field_values Default field values for this form. Used when form has not yet been submitted. Pass an array if no default field values are available/required. * @param array $lead Optional, default is null. If lead object is available, pass the lead. * * @return mixed */ public static function is_field_hidden( $form, $field, $field_values, $lead = null ) { if ( empty( $field ) ) { return false; } $cache_key = 'GFFormsModel::is_field_hidden_' . $form['id'] . '_' . $field->id; $display = GFCache::get( $cache_key ); if ( $display !== false ) { return $display; } $section = self::get_section( $form, $field->id ); $section_display = self::get_field_display( $form, $section, $field_values, $lead ); //if section is hidden, hide field no matter what. if section is visible, see if field is supposed to be visible if ( $section_display == 'hide' ) { $display = 'hide'; } else if ( self::is_page_hidden( $form, $field->pageNumber, $field_values, $lead ) ) { $display = 'hide'; } else { $display = self::get_field_display( $form, $field, $field_values, $lead ); return $display == 'hide'; } GFCache::set( $cache_key, $display ); return $display == 'hide'; } public static function is_page_hidden( $form, $page_number, $field_values, $lead = null ) { $page = self::get_page_by_number( $form, $page_number ); if ( ! $page ) { return false; } $display = self::get_field_display( $form, $page, $field_values, $lead ); return $display == 'hide'; } public static function get_page_by_number( $form, $page_number ) { foreach ( $form['fields'] as $field ) { if ( $field->type == 'page' && $field->pageNumber == $page_number ) { return $field; } } return null; } //gets the section that the specified field belongs to, or null if none public static function get_section( $form, $field_id ) { $current_section = null; foreach ( $form['fields'] as $field ) { if ( $field->type == 'section' ) { $current_section = $field; } //stop section at a page break (sections don't go cross page) if ( $field->type == 'page' ) { $current_section = null; } if ( $field->id == $field_id ) { return $current_section; } } return null; } public static function is_value_match( $field_value, $target_value, $operation = 'is', $source_field = null, $rule = null, $form = null ) { $is_match = false; if ( $source_field && is_subclass_of( $source_field, 'GF_Field' ) && $source_field->type == 'post_category' ) { $field_value = GFCommon::prepare_post_category_value( $field_value, $source_field, 'conditional_logic' ); } if ( ! empty( $field_value ) && ! is_array( $field_value ) && is_subclass_of( $source_field, 'GF_Field' ) && $source_field->type == 'multiselect' ) { $field_value = explode( ',', $field_value ); } // convert the comma-delimited string into an array $form_id = $source_field instanceof GF_Field ? $source_field->formId : 0; $target_value = GFFormsModel::maybe_trim_input( $target_value, $form_id, $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 ) { $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( GFFormsModel::maybe_trim_input( GFCommon::get_selection_value( $field_value ), $form_id, $source_field ), $target_value, $operation ) ) { $is_match = true; } return apply_filters( 'gform_is_value_match', $is_match, $field_value, $target_value, $operation, $source_field, $rule ); } private static function try_convert_float( $text ) { global $wp_locale; $number_format = $wp_locale->number_format['decimal_point'] == ',' ? 'decimal_comma' : 'decimal_dot'; 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; } public static function matches_operation( $val1, $val2, $operation ) { $val1 = ! rgblank( $val1 ) ? strtolower( $val1 ) : ''; $val2 = ! rgblank( $val2 ) ? strtolower( $val2 ) : ''; switch ( $operation ) { case 'is' : return $val1 == $val2; break; case 'isnot' : return $val1 != $val2; break; case 'greater_than': case '>' : $val1 = self::try_convert_float( $val1 ); $val2 = self::try_convert_float( $val2 ); return $val1 > $val2; break; case 'less_than': case '<' : $val1 = self::try_convert_float( $val1 ); $val2 = self::try_convert_float( $val2 ); return $val1 < $val2; break; case 'contains' : return ! empty( $val2 ) && strpos( $val1, $val2 ) !== false; break; case 'starts_with' : return ! rgblank( $val2 ) && strpos( $val1, $val2 ) === 0; break; case 'ends_with' : $start = strlen( $val1 ) - strlen( $val2 ); if ( $start < 0 ) { return false; } $tail = substr( $val1, $start ); return $val2 == $tail; break; } return false; } /** * @param $form * @param GF_Field $field * @param $field_values * @param null $lead * * @return string */ private static function get_field_display( $form, $field, $field_values, $lead = null ) { if ( empty( $field ) ) { return 'show'; } $logic = $field->conditionalLogic; //if this field does not have any conditional logic associated with it, it won't be hidden if ( empty( $logic ) ) { return 'show'; } $match_count = 0; foreach ( $logic['rules'] as $rule ) { $source_field = RGFormsModel::get_field( $form, $rule['fieldId'] ); $field_value = empty( $lead ) ? self::get_field_value( $source_field, $field_values ) : self::get_lead_field_value( $lead, $source_field ); $is_value_match = self::is_value_match( $field_value, $rule['value'], $rule['operator'], $source_field, $rule, $form ); if ( $is_value_match ) { $match_count ++; } } $do_action = ( $logic['logicType'] == 'all' && $match_count == sizeof( $logic['rules'] ) ) || ( $logic['logicType'] == 'any' && $match_count > 0 ); $is_hidden = ( $do_action && $logic['actionType'] == 'hide' ) || ( ! $do_action && $logic['actionType'] == 'show' ); return $is_hidden ? 'hide' : 'show'; } public static function get_custom_choices() { $choices = get_option( 'gform_custom_choices' ); if ( ! $choices ) { $choices = array(); } return $choices; } public static function delete_custom_choice( $name ) { $choices = self::get_custom_choices(); if ( array_key_exists( $name, $choices ) ) { unset( $choices[ $name ] ); } update_option( 'gform_custom_choices', $choices ); } public static function save_custom_choice( $previous_name, $new_name, $choices ) { $all_choices = self::get_custom_choices(); if ( array_key_exists( $previous_name, $all_choices ) ) { unset( $all_choices[ $previous_name ] ); } $all_choices[ $new_name ] = $choices; update_option( 'gform_custom_choices', $all_choices ); } /** * @param GF_Field $field * @param array $field_values * @param bool $get_from_post Whether to get the value from the $_POST array as opposed to $field_values * * @return array|mixed|string|void */ public static function get_field_value( &$field, $field_values = array(), $get_from_post = true ) { if ( ! $field instanceof GF_Field ) { $field = GF_Fields::create( $field ); } if ( $field->type == 'post_category' ) { $field = GFCommon::add_categories_as_choices( $field, '' ); } $value = $field->get_value_submission( $field_values, $get_from_post ); return $value; } public static function purge_expired_incomplete_submissions( $expiration_days = 30 ) { global $wpdb; $expiration_days = apply_filters( 'gform_incomplete_submissions_expiration_days', $expiration_days ); $expiration_date = gmdate( 'Y-m-d H:i:s', time() - ( $expiration_days * 24 * 60 * 60 ) ); $table = self::get_incomplete_submissions_table_name(); $result = $wpdb->query( "DELETE FROM $table WHERE date_created < '$expiration_date'" ); return $result; } public static function delete_incomplete_submission( $token ) { global $wpdb; $table = self::get_incomplete_submissions_table_name(); $result = $wpdb->query( $wpdb->prepare( "DELETE FROM $table WHERE uuid = %s", $token ) ); return $result; } public static function save_incomplete_submission( $form, $entry, $field_values, $page_number, $files, $form_unique_id, $ip, $source_url, $resume_token = '' ) { if ( ! is_array( $form['fields'] ) ) { return; } global $wpdb; $submitted_values = array(); foreach ( $form['fields'] as $field ) { /* @var GF_Field $field */ $submitted_values[ $field->id ] = RGFormsModel::get_field_value( $field, $field_values ); } $submitted_values = apply_filters( 'gform_submission_values_pre_save', $submitted_values, $form ); $submission['submitted_values'] = $submitted_values; $submission['partial_entry'] = $entry; $submission['field_values'] = $field_values; $submission['page_number'] = $page_number; $submission['files'] = $files; $submission['gform_unique_id'] = $form_unique_id; if ( empty( $resume_token ) ) { $resume_token = self::get_uuid(); $result = $wpdb->insert( self::get_incomplete_submissions_table_name(), array( 'uuid' => $resume_token, 'form_id' => $form['id'], 'date_created' => current_time( 'mysql', true ), 'submission' => json_encode( $submission ), 'ip' => $ip, 'source_url' => $source_url, ), array( '%s', '%d', '%s', '%s', '%s', '%s', ) ); } else { $result = $wpdb->update( self::get_incomplete_submissions_table_name(), array( 'form_id' => $form['id'], 'date_created' => current_time( 'mysql', true ), 'submission' => json_encode( $submission ), 'ip' => $ip, 'source_url' => $source_url, ), array( 'uuid' => $resume_token ), array( '%d', '%s', '%s', '%s', '%s', ), array( '%s' ) ); } do_action( 'gform_incomplete_submission_post_save', $submission, $resume_token, $form, $entry ); return $result ? $resume_token : $result; } /** * Returns a UUID. Uses openssl_random_pseudo_bytes() if available and falls back to mt_rand(). * * source: http://stackoverflow.com/questions/2040240/php-function-to-generate-v4-uuid * * @param string $s The separator e.g. '-' * * @return string */ public static function get_uuid( $s = '' ) { if ( function_exists( 'openssl_random_pseudo_bytes' ) ) { // PHP 5 >= 5.3.0 $data = openssl_random_pseudo_bytes( 16 ); $data[6] = chr( ord( $data[6] ) & 0x0f | 0x40 ); // set version to 0100 $data[8] = chr( ord( $data[8] ) & 0x3f | 0x80 ); // set bits 6-7 to 10 return vsprintf( "%s%s{$s}%s{$s}%s{$s}%s{$s}%s%s%s", str_split( bin2hex( $data ), 4 ) ); } else { return sprintf( "%04x%04x{$s}%04x{$s}%04x{$s}%04x{$s}%04x%04x%04x", // 32 bits for "time_low" mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), // 16 bits for 'time_mid' mt_rand( 0, 0xffff ), // 16 bits for 'time_hi_and_version', // four most significant bits holds version number 4 mt_rand( 0, 0x0fff ) | 0x4000, // 16 bits, 8 bits for 'clk_seq_hi_res', // 8 bits for 'clk_seq_low', // two most significant bits holds zero and one for variant DCE1.1 mt_rand( 0, 0x3fff ) | 0x8000, // 48 bits for 'node' mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) ); } } public static function get_incomplete_submission_values( $token ) { global $wpdb; self::purge_expired_incomplete_submissions(); $table = self::get_incomplete_submissions_table_name(); $sql = $wpdb->prepare( "SELECT date_created, form_id, submission FROM {$table} WHERE uuid = %s", $token ); $row = $wpdb->get_row( $sql, ARRAY_A ); return $row; } public static function add_email_to_incomplete_sumbmission( $token, $email ) { global $wpdb; self::purge_expired_incomplete_submissions(); $table = self::get_incomplete_submissions_table_name(); $sql = $wpdb->prepare( "UPDATE $table SET email = %s WHERE uuid = %s", $email, $token ); $result = $wpdb->query( $sql ); return $result; } public static function maybe_trim_input( $value, $form_id, $field ) { $trim_value = apply_filters( 'gform_trim_input_value', true, $form_id, $field ); if ( $trim_value ) { $value = is_array( $value ) ? array_map( 'trim', $value ) : trim( $value ); } return $value; } public static function get_parameter_value( $name, $field_values, $field ) { $value = stripslashes( rgget( $name ) ); if ( empty( $value ) ) { $value = rgget( $name, $field_values ); } //converting list format if ( RGFormsModel::get_input_type( $field ) == 'list' ) { //transforms this: col1|col2,col1b|col2b into this: col1,col2,col1b,col2b $column_count = count( $field->choices ); $rows = explode( ',', $value ); $ary_rows = array(); if ( ! empty( $rows ) ) { foreach ( $rows as $row ) { $ary_rows = array_merge( $ary_rows, rgexplode( '|', $row, $column_count ) ); } $value = $ary_rows; } } return apply_filters( "gform_field_value_$name", apply_filters( 'gform_field_value', $value, $field, $name ), $field, $name ); } public static function get_default_value( $field, $input_id ) { if ( ! is_array( $field->choices ) ) { if ( is_array( $field->inputs ) ) { $input = RGFormsModel::get_input( $field, $input_id ); return rgar( $input, 'defaultValue' ); } else { return IS_ADMIN ? $field->defaultValue : GFCommon::replace_variables_prepopulate( $field->defaultValue ); } } else if ( $field->type == 'checkbox' ) { for ( $i = 0, $count = sizeof( $field->inputs ); $i < $count; $i ++ ) { $input = $field->inputs[ $i ]; $choice = $field->choices[ $i ]; if ( $input['id'] == $input_id && rgar( $choice, 'isSelected' ) ) { return $choice['value']; } } return ''; } else { foreach ( $field->choices as $choice ) { if ( rgar( $choice, 'isSelected' ) || $field->type == 'post_category' ) { return $choice['value']; } } return ''; } } /** * @param GF_Field $field * * @return string */ public static function get_input_type( $field ) { if ( ! $field instanceof GF_Field ) { return empty( $field['inputType'] ) ? $field['type'] : $field['inputType']; } return empty( $field->inputType ) ? $field->type : $field->inputType; } private static function get_post_field_value( $field, $lead ) { if ( is_array( $field->inputs ) ) { $value = array(); foreach ( $field->inputs as $input ) { $val = isset( $lead[ strval( $input['id'] ) ] ) ? $lead[ strval( $input['id'] ) ] : ''; if ( ! empty( $val ) ) { // replace commas in individual values to prevent individual value from being split into multiple values (checkboxes, multiselects) if ( in_array( RGFormsModel::get_input_type( $field ), array( 'checkbox', 'multiselect' ) ) ) { $val = str_replace( ',', ',', $val ); } $value[] = $val; } } $value = implode( ',', $value ); } else { $value = isset( $lead[ $field->id ] ) ? $lead[ $field->id ] : ''; } return $value; } private static function get_post_fields( $form, $lead ) { $post_data = array(); $post_data['post_custom_fields'] = array(); $post_data['tags_input'] = array(); $categories = array(); $images = array(); foreach ( $form['fields'] as $field ) { if ( $field->type == 'post_category' ) { $field = GFCommon::add_categories_as_choices( $field, '' ); } $value = self::get_post_field_value( $field, $lead ); switch ( $field->type ) { case 'post_title' : case 'post_excerpt' : case 'post_content' : $post_data[ $field->type ] = $value; break; case 'post_tags' : $tags = explode( ',', $value ); if ( is_array( $tags ) && sizeof( $tags ) > 0 ) { $post_data['tags_input'] = array_merge( $post_data['tags_input'], $tags ); } break; case 'post_custom_field' : $type = self::get_input_type( $field ); if ( 'fileupload' === $type && $field->multipleFiles ) { $value = json_decode( $value, true ); } $meta_name = $field->postCustomFieldName; if ( ! isset( $post_data['post_custom_fields'][ $meta_name ] ) ) { $post_data['post_custom_fields'][ $meta_name ] = $value; } else if ( ! is_array( $post_data['post_custom_fields'][ $meta_name ] ) ) { $post_data['post_custom_fields'][ $meta_name ] = array( $post_data['post_custom_fields'][ $meta_name ], $value ); } else { $post_data['post_custom_fields'][ $meta_name ][] = $value; } break; case 'post_category' : foreach ( explode( ',', $value ) as $cat_string ) { list( $cat_name, $cat_id ) = rgexplode( ':', $cat_string, 2 ); array_push( $categories, $cat_id ); } break; case 'post_image' : $ary = ! empty( $value ) ? explode( '|:|', $value ) : array(); $url = count( $ary ) > 0 ? $ary[0] : ''; $title = count( $ary ) > 1 ? $ary[1] : ''; $caption = count( $ary ) > 2 ? $ary[2] : ''; $description = count( $ary ) > 3 ? $ary[3] : ''; array_push( $images, array( 'field_id' => $field->id, 'url' => $url, 'title' => $title, 'description' => $description, 'caption' => $caption ) ); break; } } $post_data['post_status'] = rgar( $form, 'postStatus' ); $post_data['post_category'] = ! empty( $categories ) ? $categories : array( rgar( $form, 'postCategory' ) ); $post_data['images'] = $images; //setting current user as author depending on settings $post_data['post_author'] = $form['useCurrentUserAsAuthor'] && ! empty( $lead['created_by'] ) ? $lead['created_by'] : $form['postAuthor']; return $post_data; } public static function get_custom_field_names() { global $wpdb; $keys = $wpdb->get_col( " SELECT meta_key FROM $wpdb->postmeta WHERE meta_key NOT LIKE '\_%' GROUP BY meta_key ORDER BY meta_id DESC" ); if ( $keys ) { natcasesort( $keys ); } return $keys; } public static function get_input_masks() { $masks = array( 'US Phone' => '(999) 999-9999', 'US Phone + Ext' => '(999) 999-9999? x99999', 'Date' => '99/99/9999', 'Tax ID' => '99-9999999', 'SSN' => '999-99-9999', 'Zip Code' => '99999', 'Full Zip Code' => '99999?-9999', ); return apply_filters( 'gform_input_masks', $masks ); } private static function get_default_post_title() { global $wpdb; $title = 'Untitled'; $count = 1; $titles = $wpdb->get_col( "SELECT post_title FROM $wpdb->posts WHERE post_title like '%Untitled%'" ); $titles = array_values( $titles ); while ( in_array( $title, $titles ) ) { $title = "Untitled_$count"; $count ++; } return $title; } public static function prepare_date( $date_format, $value ) { $format = empty( $date_format ) ? 'mdy' : $date_format; $date_info = GFCommon::parse_date( $value, $format ); if ( ! empty( $date_info ) && ! GFCommon::is_empty_array( $date_info ) ) { $value = sprintf( '%s-%02d-%02d', $date_info['year'], $date_info['month'], $date_info['day'] ); } else { $value = ''; } return $value; } /** * Prepare the value before saving it to the lead. * * @param mixed $form * @param GF_Field $field * @param mixed $value * @param mixed $input_name * @param mixed $lead_id the current lead ID, used for fields that are processed after other fields have been saved (ie Total, Calculations) * @param mixed $lead passed by the RGFormsModel::create_lead() method, lead ID is not available for leads created by this function * * @return mixed */ public static function prepare_value( $form, $field, $value, $input_name, $lead_id, $lead = array() ) { $value = $field->get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ); // special format for Post Category fields if ( $field->type == 'post_category' ) { $full_values = array(); if ( ! is_array( $value ) ) { $value = explode( ',', $value ); } foreach ( $value as $cat_id ) { $cat = get_term( $cat_id, 'category' ); $full_values[] = ! is_wp_error( $cat ) && is_object( $cat ) ? $cat->name . ':' . $cat_id : ''; } $value = implode( ',', $full_values ); } //do not save price fields with blank price if ( $field->enablePrice ) { $ary = explode( '|', $value ); $label = count( $ary ) > 0 ? $ary[0] : ''; $price = count( $ary ) > 1 ? $ary[1] : ''; $is_empty = ( strlen( trim( $price ) ) <= 0 ); if ( $is_empty ) { $value = ''; } } 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 ( $field->enableChoiceValue || $field->enablePrice ) { foreach ( $field->choices as $choice ) { if ( $choice['value'] == $lead[ $field_id ] ) { return $choice['value']; } else if ( $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; } public static function get_fileupload_value( $form_id, $input_name ) { _deprecated_function( 'GFFormsModel::get_fileupload_value', '1.9', 'GF_Field_Fileupload::get_fileupload_value' ); global $_gf_uploaded_files; GFCommon::log_debug( 'GFFormsModel::get_fileupload_value(): Starting.' ); if ( empty( $_gf_uploaded_files ) ) { GFCommon::log_debug( 'GFFormsModel::get_fileupload_value(): No files uploaded. Exiting.' ); $_gf_uploaded_files = array(); } if ( ! isset( $_gf_uploaded_files[ $input_name ] ) ) { //check if file has already been uploaded by previous step $file_info = self::get_temp_filename( $form_id, $input_name ); $temp_filepath = self::get_upload_path( $form_id ) . '/tmp/' . $file_info['temp_filename']; GFCommon::log_debug( 'GFFormsModel::get_fileupload_value(): Temp file path: ' . $temp_filepath ); if ( $file_info && file_exists( $temp_filepath ) ) { GFCommon::log_debug( 'GFFormsModel::get_fileupload_value(): Moving temp file: ' . $temp_filepath ); $_gf_uploaded_files[ $input_name ] = self::move_temp_file( $form_id, $file_info ); } else if ( ! empty( $_FILES[ $input_name ]['name'] ) ) { GFCommon::log_debug( 'GFFormsModel::get_fileupload_value(): Uploading file: ' . $_FILES[ $input_name ]['name'] ); $_gf_uploaded_files[ $input_name ] = self::upload_file( $form_id, $_FILES[ $input_name ] ); } } return rgget( $input_name, $_gf_uploaded_files ); } public static function get_form_unique_id( $form_id ) { $unique_id = ''; if ( rgpost( 'gform_submit' ) == $form_id ) { $posted_uid = rgpost( 'gform_unique_id' ); if ( false === empty( $posted_uid ) && ctype_alnum( $posted_uid )) { $unique_id = $posted_uid; self::$unique_ids[ $form_id ] = $unique_id; } elseif ( isset( self::$unique_ids[ $form_id ] ) ) { $unique_id = self::$unique_ids[ $form_id ]; } else { $unique_id = uniqid(); self::$unique_ids[ $form_id ] = $unique_id; } } return $unique_id; } public static function get_temp_filename( $form_id, $input_name ) { $uploaded_filename = ! empty( $_FILES[ $input_name ]['name'] ) && $_FILES[ $input_name ]['error'] === 0 ? $_FILES[ $input_name ]['name'] : ''; if ( empty( $uploaded_filename ) && isset( self::$uploaded_files[ $form_id ] ) ) { $uploaded_filename = rgget( $input_name, self::$uploaded_files[ $form_id ] ); } if ( empty( $uploaded_filename ) ) { return false; } $form_unique_id = self::get_form_unique_id( $form_id ); $pathinfo = pathinfo( $uploaded_filename ); return array( 'uploaded_filename' => $uploaded_filename, 'temp_filename' => "{$form_unique_id}_{$input_name}.{$pathinfo['extension']}" ); } public static function get_choice_text( $field, $value, $input_id = 0 ) { if ( ! is_array( $field->choices ) ) { return $value; } foreach ( $field->choices as $choice ) { if ( is_array( $value ) && self::choice_value_match( $field, $choice, $value[ $input_id ] ) ) { return $choice['text']; } else if ( ! is_array( $value ) && self::choice_value_match( $field, $choice, $value ) ) { return $choice['text']; } } return is_array( $value ) ? '' : $value; } public static function choice_value_match( $field, $choice, $value ) { $choice_value = GFFormsModel::maybe_trim_input( $choice['value'], $field->formId, $field ); $value = GFFormsModel::maybe_trim_input( $value, $field->formId, $field ); if ( $choice_value == $value ) { return true; } else if ( $field->enablePrice ) { $ary = explode( '|', $value ); $val = count( $ary ) > 0 ? $ary[0] : ''; $price = count( $ary ) > 1 ? $ary[1] : ''; if ( $val == $choice['value'] ) { return true; } } // add support for prepopulating multiselects @alex else if ( RGFormsModel::get_input_type( $field ) == 'multiselect' ) { $values = explode( ',', $value ); if ( in_array( $choice_value, $values ) ) { return true; } } return false; } public static function choices_value_match( $field, $choices, $value ) { foreach ( $choices as $choice ) { if ( self::choice_value_match( $field, $choice, $value ) ) { return true; } } return false; } public static function create_post( $form, &$lead ) { GFCommon::log_debug( 'GFFormsModel::create_post(): Starting.' ); $has_post_field = false; foreach ( $form['fields'] as $field ) { $is_hidden = self::is_field_hidden( $form, $field, array(), $lead ); if ( ! $is_hidden && in_array( $field->type, array( 'post_category', 'post_title', 'post_content', 'post_excerpt', 'post_tags', 'post_custom_field', 'post_image' ) ) ) { $has_post_field = true; break; } } //if this form does not have any post fields, don't create a post if ( ! $has_post_field ) { GFCommon::log_debug( "GFFormsModel::create_post(): Stopping. The form doesn't have any post fields." ); return $lead; } //processing post fields GFCommon::log_debug( 'GFFormsModel::create_post(): Getting post fields.' ); $post_data = self::get_post_fields( $form, $lead ); //allowing users to change post fields before post gets created $post_data = apply_filters( "gform_post_data_{$form['id']}", apply_filters( 'gform_post_data', $post_data, $form, $lead ), $form, $lead ); //adding default title if none of the required post fields are in the form (will make sure wp_insert_post() inserts the post) if ( empty( $post_data['post_title'] ) && empty( $post_data['post_content'] ) && empty( $post_data['post_excerpt'] ) ) { $post_data['post_title'] = self::get_default_post_title(); } // remove original post status and save it for later $post_status = $post_data['post_status']; // replace original post status with 'draft' so other plugins know this post is not fully populated yet $post_data['post_status'] = 'draft'; // inserting post GFCommon::log_debug( 'GFFormsModel::create_post(): Inserting post via wp_insert_post().' ); $post_id = wp_insert_post( $post_data ); GFCommon::log_debug( "GFFormsModel::create_post(): Result from wp_insert_post(): {$post_id}." ); //adding form id and entry id hidden custom fields add_post_meta( $post_id, '_gform-form-id', $form['id'] ); add_post_meta( $post_id, '_gform-entry-id', $lead['id'] ); //creating post images GFCommon::log_debug( 'GFFormsModel::create_post(): Creating post images.' ); $post_images = array(); foreach ( $post_data['images'] as $image ) { $image_meta = array( 'post_excerpt' => $image['caption'], 'post_content' => $image['description'], ); //adding title only if it is not empty. It will default to the file name if it is not in the array if ( ! empty( $image['title'] ) ) { $image_meta['post_title'] = $image['title']; } if ( ! empty( $image['url'] ) ) { GFCommon::log_debug( 'GFFormsModel::create_post(): Adding image: ' . $image['url'] ); $media_id = self::media_handle_upload( $image['url'], $post_id, $image_meta ); if ( $media_id ) { //save media id for post body/title template variable replacement (below) $post_images[ $image['field_id'] ] = $media_id; $lead[ $image['field_id'] ] .= "|:|$media_id"; // set featured image $field = RGFormsModel::get_field( $form, $image['field_id'] ); if ( $field->postFeaturedImage ) { set_post_thumbnail( $post_id, $media_id ); } } } } //adding custom fields GFCommon::log_debug( 'GFFormsModel::create_post(): Adding custom fields.' ); foreach ( $post_data['post_custom_fields'] as $meta_name => $meta_value ) { if ( ! is_array( $meta_value ) ) { $meta_value = array( $meta_value ); } $meta_index = 0; foreach ( $meta_value as $value ) { GFCommon::log_debug( 'GFFormsModel::create_post(): Getting custom field: ' . $meta_name ); $custom_field = self::get_custom_field( $form, $meta_name, $meta_index ); //replacing template variables if template is enabled if ( $custom_field && rgget( 'customFieldTemplateEnabled', $custom_field ) ) { //replacing post image variables GFCommon::log_debug( 'GFFormsModel::create_post(): Replacing post image variables.' ); $value = GFCommon::replace_variables_post_image( $custom_field['customFieldTemplate'], $post_images, $lead ); //replacing all other variables $value = GFCommon::replace_variables( $value, $form, $lead, false, false, false ); // replace conditional shortcodes $value = do_shortcode( $value ); } switch ( RGFormsModel::get_input_type( $custom_field ) ) { case 'list' : $value = maybe_unserialize( $value ); if ( is_array( $value ) ) { foreach ( $value as $item ) { if ( is_array( $item ) ) { $item = implode( '|', $item ); } if ( ! rgblank( $item ) ) { add_post_meta( $post_id, $meta_name, $item ); } } } break; case 'multiselect' : case 'checkbox' : $value = explode( ',', $value ); if ( is_array( $value ) ) { foreach ( $value as $item ) { if ( ! rgblank( $item ) ) { // add post meta and replace HTML symbol in $item with real comma add_post_meta( $post_id, $meta_name, str_replace( ',', ',', $item ) ); } } } break; case 'date' : $value = GFCommon::date_display( $value, rgar( $custom_field, 'dateFormat' ) ); if ( ! rgblank( $value ) ) { add_post_meta( $post_id, $meta_name, $value ); } break; default : if ( ! rgblank( $value ) ) { add_post_meta( $post_id, $meta_name, $value ); } break; } $meta_index ++; } } $has_content_field = sizeof( GFCommon::get_fields_by_type( $form, array( 'post_content' ) ) ) > 0; $has_title_field = sizeof( GFCommon::get_fields_by_type( $form, array( 'post_title' ) ) ) > 0; $post = false; //if a post field was configured with a content or title template, process template if ( ( rgar( $form, 'postContentTemplateEnabled' ) && $has_content_field ) || ( rgar( $form, 'postTitleTemplateEnabled' ) && $has_title_field ) ) { GFCommon::log_debug( 'GFFormsModel::create_post(): Processing template.' ); $post = get_post( $post_id ); if ( rgar( $form, 'postContentTemplateEnabled' ) && $has_content_field ) { //replacing post image variables $post_content = GFCommon::replace_variables_post_image( $form['postContentTemplate'], $post_images, $lead ); //replacing all other variables $post_content = GFCommon::replace_variables( $post_content, $form, $lead, false, false, false ); //updating post content $post->post_content = $post_content; } if ( rgar( $form, 'postTitleTemplateEnabled' ) && $has_title_field ) { //replacing post image variables $post_title = GFCommon::replace_variables_post_image( $form['postTitleTemplate'], $post_images, $lead ); //replacing all other variables $post_title = GFCommon::replace_variables( $post_title, $form, $lead, false, false, false ); // replace conditional shortcodes $post_title = do_shortcode( $post_title ); //updating post $post->post_title = $post_title; $post->post_name = $post_title; } } // update post status back to original status (if not draft) if ( $post_status != 'draft' ) { $post = is_object( $post ) ? $post : get_post( $post_id ); $post->post_status = $post_status; } // if post has been modified since creation, save updates if ( is_object( $post ) ) { GFCommon::log_debug( 'GFFormsModel::create_post(): Updating post.' ); wp_update_post( $post ); } //adding post format if ( current_theme_supports( 'post-formats' ) && rgar( $form, 'postFormat' ) ) { $formats = get_theme_support( 'post-formats' ); $post_format = rgar( $form, 'postFormat' ); if ( is_array( $formats ) ) { $formats = $formats[0]; if ( in_array( $post_format, $formats ) ) { set_post_format( $post_id, $post_format ); } else if ( '0' == $post_format ) { set_post_format( $post_id, false ); } } } //update post_id field if a post was created $lead['post_id'] = $post_id; GFCommon::log_debug( 'GFFormsModel::create_post(): Updating entry with post id.' ); self::update_lead_property( $lead['id'], 'post_id', $post_id ); do_action( 'gform_after_create_post', $post_id ); return $post_id; } private static function get_custom_field( $form, $meta_name, $meta_index ) { $custom_fields = GFCommon::get_fields_by_type( $form, array( 'post_custom_field' ) ); $index = 0; foreach ( $custom_fields as $field ) { if ( $field->postCustomFieldName == $meta_name ) { if ( $meta_index == $index ) { return $field; } $index ++; } } return false; } private static function copy_post_image( $url, $post_id ) { $time = current_time( 'mysql' ); if ( $post = get_post( $post_id ) ) { if ( substr( $post->post_date, 0, 4 ) > 0 ) { $time = $post->post_date; } } //making sure there is a valid upload folder if ( ! ( ( $uploads = wp_upload_dir( $time ) ) && false === $uploads['error'] ) ) { return false; } $name = basename( $url ); $filename = wp_unique_filename( $uploads['path'], $name ); // Move the file to the uploads dir $new_file = $uploads['path'] . "/$filename"; $uploaddir = wp_upload_dir(); $path = str_replace( $uploaddir['baseurl'], $uploaddir['basedir'], $url ); if ( ! copy( $path, $new_file ) ) { return false; } // Set correct file permissions $stat = stat( dirname( $new_file ) ); $perms = $stat['mode'] & 0000666; @ chmod( $new_file, $perms ); // Compute the URL $url = $uploads['url'] . "/$filename"; if ( is_multisite() ) { delete_transient( 'dirsize_cache' ); } $type = wp_check_filetype( $new_file ); return array( 'file' => $new_file, 'url' => $url, 'type' => $type['type'] ); } private static function media_handle_upload( $url, $post_id, $post_data = array() ) { //WordPress Administration API required for the media_handle_upload() function require_once( ABSPATH . 'wp-admin/includes/image.php' ); $name = basename( $url ); $file = self::copy_post_image( $url, $post_id ); if ( ! $file ) { return false; } $name_parts = pathinfo( $name ); $name = trim( substr( $name, 0, - ( 1 + strlen( $name_parts['extension'] ) ) ) ); $url = $file['url']; $type = $file['type']; $file = $file['file']; $title = $name; $content = ''; // use image exif/iptc data for title and caption defaults if possible if ( $image_meta = @wp_read_image_metadata( $file ) ) { if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) { $title = $image_meta['title']; } if ( trim( $image_meta['caption'] ) ) { $content = $image_meta['caption']; } } // Construct the attachment array $attachment = array_merge( array( 'post_mime_type' => $type, 'guid' => $url, 'post_parent' => $post_id, 'post_title' => $title, 'post_content' => $content, ), $post_data ); // Save the data $id = wp_insert_attachment( $attachment, $file, $post_id ); if ( ! is_wp_error( $id ) ) { wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) ); } return $id; } public static function save_input( $form, $field, &$lead, $current_fields, $input_id ) { $input_name = 'input_' . str_replace( '.', '_', $input_id ); if ( $field->enableCopyValuesOption && rgpost( 'input_' . $field->id . '_copy_values_activated' ) ) { $source_field_id = $field->copyValuesOptionField; $source_input_name = str_replace( 'input_' . $field->id, 'input_' . $source_field_id, $input_name ); $value = rgpost( $source_input_name ); } else { $value = rgpost( $input_name ); } $value = self::maybe_trim_input( $value, $form['id'], $field ); //ignore file upload when nothing was sent in the admin //ignore post fields in the admin $type = self::get_input_type( $field ); $multiple_files = $field->multipleFiles; $uploaded_files = GFFormsModel::$uploaded_files; $form_id = $form['id']; if ( RG_CURRENT_VIEW == 'entry' && $type == 'fileupload' && ( ( ! $multiple_files && empty( $_FILES[ $input_name ]['name'] ) ) || ( $multiple_files && ! isset( $uploaded_files[ $form_id ][ $input_name ] ) ) ) ) { return; } else if ( RG_CURRENT_VIEW == 'entry' && in_array( $field->type, array( 'post_category', 'post_title', 'post_content', 'post_excerpt', 'post_tags', 'post_custom_field', 'post_image' ) ) ) { return; } $is_form_editor = GFCommon::is_form_editor(); $is_entry_detail = GFCommon::is_entry_detail(); $is_admin = $is_form_editor || $is_entry_detail; if ( empty( $value ) && $field->adminOnly && ! $is_admin ) { $value = self::get_default_value( $field, $input_id ); } //processing values so that they are in the correct format for each input type $value = self::prepare_value( $form, $field, $value, $input_name, rgar( $lead, 'id' ) ); //ignore fields that have not changed if( $lead != null && isset( $lead[ $input_id ] ) && $value === rgget( (string) $input_id, $lead ) ){ return; } $lead_detail_id = self::get_lead_detail_id( $current_fields, $input_id ); self::update_lead_field_value( $form, $lead, $field, $lead_detail_id, $input_id, $value ); } public static function update_lead_field_value( $form, $lead, $field, $lead_detail_id, $input_id, $value ) { global $wpdb; $lead_id = $lead['id']; $form_id = $form['id']; $lead_detail_table = self::get_lead_details_table_name(); $lead_detail_long_table = self::get_lead_details_long_table_name(); if ( ! rgblank( $value ) ) { $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 ) { $result = $wpdb->update( $lead_detail_table, array( 'value' => $truncated_value ), array( 'id' => $lead_detail_id ), array( '%s' ), array( '%d' ) ); if ( false === $result ) { return false; } //insert, update or delete long value $sql = $wpdb->prepare( "SELECT count(0) FROM $lead_detail_long_table WHERE lead_detail_id=%d", $lead_detail_id ); $has_long_field = intval( $wpdb->get_var( $sql ) ) > 0; //delete long field if value has been shortened if ( $has_long_field && GFCommon::safe_strlen( $value ) <= GFORMS_MAX_FIELD_LENGTH ) { $sql = $wpdb->prepare( "DELETE FROM $lead_detail_long_table WHERE lead_detail_id=%d", $lead_detail_id ); $result = $wpdb->query( $sql ); if ( false === $result ) { return false; } } //update long field else if ( $has_long_field ) { $result = $wpdb->update( $lead_detail_long_table, array( 'value' => $value ), array( 'lead_detail_id' => $lead_detail_id ), array( '%s' ), array( '%d' ) ); if ( false === $result ) { return false; } } //insert long field (value has been increased) else if ( GFCommon::safe_strlen( $value ) > GFORMS_MAX_FIELD_LENGTH ) { $result = $wpdb->insert( $lead_detail_long_table, array( 'lead_detail_id' => $lead_detail_id, 'value' => $value ), array( '%d', '%s' ) ); if ( false === $result ) { return false; } } } else { $result = $wpdb->insert( $lead_detail_table, array( 'lead_id' => $lead_id, 'form_id' => $form_id, 'field_number' => $input_id, 'value' => $truncated_value ), array( '%d', '%d', '%F', '%s' ) ); if ( false === $result ) { return false; } if ( GFCommon::safe_strlen( $value ) > GFORMS_MAX_FIELD_LENGTH ) { //read newly created lead detal id $lead_detail_id = $wpdb->insert_id; //insert long value $result = $wpdb->insert( $lead_detail_long_table, array( 'lead_detail_id' => $lead_detail_id, 'value' => $value ), array( '%d', '%s' ) ); if ( false === $result ) { return false; } } } } else { //Deleting long field if there is one $sql = $wpdb->prepare( "DELETE FROM $lead_detail_long_table WHERE lead_detail_id IN( SELECT id FROM $lead_detail_table WHERE lead_id=%d AND field_number BETWEEN %s AND %s )", $lead_id, doubleval( $input_id ) - 0.0001, doubleval( $input_id ) + 0.0001 ); $result = $wpdb->query( $sql ); if ( false === $result ) { return false; } //Deleting details for this field $sql = $wpdb->prepare( "DELETE FROM $lead_detail_table WHERE lead_id=%d AND field_number BETWEEN %s AND %s ", $lead_id, doubleval( $input_id ) - 0.0001, doubleval( $input_id ) + 0.0001 ); $result = $wpdb->query( $sql ); if ( false === $result ) { return false; } } return true; } private static function move_temp_file( $form_id, $tempfile_info ) { _deprecated_function( 'move_temp_file', '1.9', 'GF_Field_Fileupload::move_temp_file' ); $target = self::get_file_upload_path( $form_id, $tempfile_info['uploaded_filename'] ); $source = self::get_upload_path( $form_id ) . '/tmp/' . $tempfile_info['temp_filename']; if ( rename( $source, $target['path'] ) ) { self::set_permissions( $target['path'] ); return $target['url']; } else { return 'FAILED (Temporary file could not be moved.)'; } } public static function set_permissions( $path ) { $permission = apply_filters( 'gform_file_permission', 0644, $path ); if ( $permission ) { chmod( $path, $permission ); } } public static function upload_file( $form_id, $file ) { _deprecated_function( 'upload_file', '1.9', 'GF_Field_Fileupload::upload_file' ); $target = self::get_file_upload_path( $form_id, $file['name'] ); if ( ! $target ) { GFCommon::log_debug( 'GFFormsModel::upload_file(): FAILED (Upload folder could not be created.)' ); return 'FAILED (Upload folder could not be created.)'; } if ( move_uploaded_file( $file['tmp_name'], $target['path'] ) ) { GFCommon::log_debug( 'GFFormsModel::upload_file(): Setting permissions on ' . $target['path'] ); self::set_permissions( $target['path'] ); return $target['url']; } else { GFCommon::log_debug( 'GFFormsModel::upload_file(): FAILED (Temporary file could not be copied.)' ); return 'FAILED (Temporary file could not be copied.)'; } } public static function get_upload_root() { $dir = wp_upload_dir(); if ( $dir['error'] ) { return null; } return $dir['basedir'] . '/gravity_forms/'; } public static function get_upload_url_root() { $dir = wp_upload_dir(); if ( $dir['error'] ) { return null; } return $dir['baseurl'] . '/gravity_forms/'; } public static function get_upload_path( $form_id ) { $form_id = absint( $form_id ); return self::get_upload_root() . $form_id . '-' . wp_hash( $form_id ); } public static function get_upload_url( $form_id ) { $form_id = absint( $form_id ); $dir = wp_upload_dir(); return $dir['baseurl'] . "/gravity_forms/$form_id" . '-' . wp_hash( $form_id ); } public static function get_file_upload_path( $form_id, $file_name ) { if ( get_magic_quotes_gpc() ) { $file_name = stripslashes( $file_name ); } $form_id = absint( $form_id ); // Where the file is going to be placed // Generate the yearly and monthly dirs $time = current_time( 'mysql' ); $y = substr( $time, 0, 4 ); $m = substr( $time, 5, 2 ); $target_root = self::get_upload_path( $form_id ) . "/$y/$m/"; $target_root_url = self::get_upload_url( $form_id ) . "/$y/$m/"; //adding filter to upload root path and url $upload_root_info = array( 'path' => $target_root, 'url' => $target_root_url ); $upload_root_info = apply_filters( "gform_upload_path_{$form_id}", apply_filters( 'gform_upload_path', $upload_root_info, $form_id ), $form_id ); $target_root = $upload_root_info['path']; $target_root_url = $upload_root_info['url']; if ( ! is_dir( $target_root ) ) { if ( ! wp_mkdir_p( $target_root ) ) { return false; } //adding index.html files to all subfolders if ( ! file_exists( self::get_upload_root() . '/index.html' ) ) { GFCommon::recursive_add_index_file( self::get_upload_root() ); } else if ( ! file_exists( self::get_upload_path( $form_id ) . '/index.html' ) ) { GFCommon::recursive_add_index_file( self::get_upload_path( $form_id ) ); } else if ( ! file_exists( self::get_upload_path( $form_id ) . "/$y/index.html" ) ) { GFCommon::recursive_add_index_file( self::get_upload_path( $form_id ) . "/$y" ); } else { GFCommon::recursive_add_index_file( self::get_upload_path( $form_id ) . "/$y/$m" ); } } //Add the original filename to our target path. //Result is "uploads/filename.extension" $file_info = pathinfo( $file_name ); $extension = rgar( $file_info, 'extension' ); if ( ! empty( $extension ) ) { $extension = '.' . $extension; } $file_name = basename( $file_info['basename'], $extension ); $file_name = sanitize_file_name( $file_name ); $counter = 1; $target_path = $target_root . $file_name . $extension; while ( file_exists( $target_path ) ) { $target_path = $target_root . $file_name . "$counter" . $extension; $counter ++; } //Remove '.' from the end if file does not have a file extension $target_path = trim( $target_path, '.' ); //creating url $target_url = str_replace( $target_root, $target_root_url, $target_path ); return array( 'path' => $target_path, 'url' => $target_url ); } public static function get_tables() { return array( self::get_lead_details_long_table_name(), self::get_lead_notes_table_name(), self::get_lead_details_table_name(), self::get_lead_table_name(), self::get_form_view_table_name(), self::get_meta_table_name(), self::get_form_table_name(), self::get_lead_meta_table_name(), ); } public static function drop_tables() { global $wpdb; foreach ( self::get_tables() as $table ) { $wpdb->query( "DROP TABLE IF EXISTS $table" ); } } public static function mu_drop_tables( $drop_tables ) { return array_merge( $drop_tables, self::get_tables() ); } public static function insert_form_view( $form_id, $ip ) { global $wpdb; $table_name = self::get_form_view_table_name(); $sql = $wpdb->prepare( " SELECT id FROM $table_name WHERE form_id=%d AND year(date_created) = year(utc_timestamp()) AND month(date_created) = month(utc_timestamp()) AND day(date_created) = day(utc_timestamp()) AND hour(date_created) = hour(utc_timestamp())", $form_id ); $id = $wpdb->get_var( $sql, 0, 0 ); if ( empty( $id ) ) { $wpdb->query( $wpdb->prepare( "INSERT INTO $table_name(form_id, date_created, ip) values(%d, utc_timestamp(), %s)", $form_id, $ip ) ); } else { $wpdb->query( $wpdb->prepare( "UPDATE $table_name SET count = count+1 WHERE id=%d", $id ) ); } } public static function is_duplicate( $form_id, $field, $value ) { global $wpdb; $lead_detail_table_name = self::get_lead_details_table_name(); $lead_table_name = self::get_lead_table_name(); $lead_detail_long = self::get_lead_details_long_table_name(); $is_long = ! is_array( $value ) && strlen( $value ) > GFORMS_MAX_FIELD_LENGTH - 10; $sql_comparison = $is_long ? '( ld.value = %s OR ldl.value = %s )' : 'ld.value = %s'; switch ( GFFormsModel::get_input_type( $field ) ) { case 'time': $value = sprintf( "%02d:%02d %s", $value[0], $value[1], $value[2] ); break; case 'date': $value = self::prepare_date( $field->dateFormat, $value ); break; case 'number': $value = GFCommon::clean_number( $value, $field->numberFormat ); break; case 'phone': $value = str_replace( array( ')', '(', '-', ' ' ), '', $value ); $sql_comparison = 'replace( replace( replace( replace( ld.value, ")", "" ), "(", "" ), "-", "" ), " ", "" ) = %s'; break; case 'email': $value = is_array( $value ) ? rgar( $value, 0 ) : $value; break; } $inner_sql_template = "SELECT %s as input, ld.lead_id FROM {$lead_detail_table_name} ld INNER JOIN {$lead_table_name} l ON l.id = ld.lead_id\n"; if ( $is_long ) { $inner_sql_template .= "INNER JOIN {$lead_detail_long} ldl ON ldl.lead_detail_id = ld.id\n"; } $inner_sql_template .= "WHERE l.form_id=%d AND ld.form_id=%d AND ld.field_number between %s AND %s AND status='active' AND {$sql_comparison}"; $sql = "SELECT count(distinct input) as match_count FROM ( "; $input_count = 1; if ( is_array( $field->get_entry_inputs() ) ) { $input_count = sizeof( $field->inputs ); foreach ( $field->inputs as $input ) { $union = empty( $inner_sql ) ? '' : ' UNION ALL '; $inner_sql .= $union . $wpdb->prepare( $inner_sql_template, $input['id'], $form_id, $form_id, $input['id'] - 0.0001, $input['id'] + 0.0001, $value[ $input['id'] ], $value[ $input['id'] ] ); } } else { $inner_sql = $wpdb->prepare( $inner_sql_template, $field->id, $form_id, $form_id, doubleval( $field->id ) - 0.0001, doubleval( $field->id ) + 0.0001, $value, $value ); } $sql .= $inner_sql . " ) as count GROUP BY lead_id ORDER BY match_count DESC"; $count = apply_filters( "gform_is_duplicate_{$form_id}", apply_filters( 'gform_is_duplicate', $wpdb->get_var( $sql ), $form_id, $field, $value ), $form_id, $field, $value ); return $count != null && $count >= $input_count; } public static function get_lead( $lead_id ) { global $wpdb; $lead_detail_table_name = self::get_lead_details_table_name(); $lead_table_name = self::get_lead_table_name(); $results = $wpdb->get_results( $wpdb->prepare( " SELECT l.*, field_number, value FROM $lead_table_name l INNER JOIN $lead_detail_table_name ld ON l.id = ld.lead_id WHERE l.id=%d", $lead_id ) ); $leads = self::build_lead_array( $results, true ); return sizeof( $leads ) == 1 ? $leads[0] : false; } 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, 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 ) ); } public static function refresh_lead_field_value( $lead_id, $field_id ) { $cache_key = 'GFFormsModel::get_lead_field_value_' . $lead_id . '_' . $field_id; GFCache::delete( $cache_key ); } /** * @param $lead * @param $field GF_Field * * @return array|bool|mixed|string|void */ public static function get_lead_field_value( $lead, $field ) { if ( empty( $lead ) ) { return; } $field_id = $field instanceof GF_Field ? $field->id : $field['id']; //returning cache entry if available $cache_key = 'GFFormsModel::get_lead_field_value_' . $lead['id'] . '_' . $field_id; $cache_value = GFCache::get( $cache_key ); if ( $cache_value !== false ) { return $cache_value; } $max_length = GFORMS_MAX_FIELD_LENGTH; $value = array(); $inputs = $field instanceof GF_Field ? $field->get_entry_inputs() : rgar( $field, 'inputs' ); if ( is_array( $inputs ) ) { //making sure values submitted are sent in the value even if //there isn't an input associated with it $lead_field_keys = array_keys( $lead ); natsort( $lead_field_keys ); foreach ( $lead_field_keys as $input_id ) { if ( is_numeric( $input_id ) && absint( $input_id ) == absint( $field->id ) ) { $val = $lead[ $input_id ]; if ( strlen( $val ) >= ( $max_length - 10 ) ) { if ( empty( $form ) ) { $form = RGFormsModel::get_form_meta( $lead['form_id'] ); } $long_choice = self::get_field_value_long( $lead, $input_id, $form ); } else { $long_choice = $val; } $value[ $input_id ] = ! empty( $long_choice ) ? $long_choice : $val; } } } else { $val = rgget( $field_id, $lead ); //To save a database call to get long text, only getting long text if regular field is 'somewhat' large (i.e. max - 50) if ( strlen( $val ) >= ( $max_length - 50 ) ) { if ( empty( $form ) ) { $form = RGFormsModel::get_form_meta( $lead['form_id'] ); } $long_text = self::get_field_value_long( $lead, $field_id, $form ); } $value = ! empty( $long_text ) ? $long_text : $val; } //filtering lead value $value = apply_filters( 'gform_get_field_value', $value, $lead, $field ); //saving value in global variable to optimize performance GFCache::set( $cache_key, $value ); return $value; } public static function get_field_value_long( $lead, $field_number, $form, $apply_filter = true ) { global $wpdb; $detail_table_name = self::get_lead_details_table_name(); $long_table_name = self::get_lead_details_long_table_name(); $sql = $wpdb->prepare( " SELECT l.value FROM $detail_table_name d INNER JOIN $long_table_name l ON l.lead_detail_id = d.id WHERE lead_id=%d AND field_number BETWEEN %s AND %s", $lead['id'], doubleval( $field_number ) - 0.0001, doubleval( $field_number ) + 0.0001 ); $val = $wpdb->get_var( $sql ); //running aform_get_input_value when needed if ( $apply_filter ) { $field = RGFormsModel::get_field( $form, $field_number ); $input_id = (string) $field_number == (string) $field->id ? '' : $field_number; $val = apply_filters( 'gform_get_input_value', $val, $lead, $field, $input_id ); } return $val; } public static function get_leads_by_meta( $meta_key, $meta_value ) { global $wpdb; $sql = $wpdb->prepare( " SELECT l.*, d.field_number, d.value FROM {$wpdb->prefix}rg_lead l INNER JOIN {$wpdb->prefix}rg_lead_detail d ON l.id = d.lead_id INNER JOIN {$wpdb->prefix}rg_lead_meta m ON l.id = m.lead_id WHERE m.meta_key=%s AND m.meta_value=%s", $meta_key, $meta_value ); //getting results $results = $wpdb->get_results( $sql ); $leads = self::build_lead_array( $results ); return $leads; } public static function get_leads( $form_id, $sort_field_number = 0, $sort_direction = 'DESC', $search = '', $offset = 0, $page_size = 30, $star = null, $read = null, $is_numeric_sort = false, $start_date = null, $end_date = null, $status = 'active', $payment_status = false ) { global $wpdb; if ( empty( $sort_field_number ) ) { $sort_field_number = 'date_created'; } if ( is_numeric( $sort_field_number ) ) { $sql = self::sort_by_custom_field_query( $form_id, $sort_field_number, $sort_direction, $search, $offset, $page_size, $star, $read, $is_numeric_sort, $status, $payment_status ); } else { $sql = self::sort_by_default_field_query( $form_id, $sort_field_number, $sort_direction, $search, $offset, $page_size, $star, $read, $is_numeric_sort, $start_date, $end_date, $status, $payment_status ); } //initializing rownum $wpdb->query( 'select @rownum:=0' ); //getting results $results = $wpdb->get_results( $sql ); $leads = self::build_lead_array( $results ); return $leads; } public static function get_leads_count( $form_id ) { } private static function sort_by_custom_field_query( $form_id, $sort_field_number = 0, $sort_direction = 'DESC', $search = '', $offset = 0, $page_size = 30, $star = null, $read = null, $is_numeric_sort = false, $status = 'active', $payment_status = false ) { global $wpdb; if ( ! is_numeric( $form_id ) || ! is_numeric( $sort_field_number ) || ! is_numeric( $offset ) || ! is_numeric( $page_size ) ) { return ''; } $lead_detail_table_name = self::get_lead_details_table_name(); $lead_table_name = self::get_lead_table_name(); $orderby = $is_numeric_sort ? "ORDER BY query, (value+0) $sort_direction" : "ORDER BY query, value $sort_direction"; $is_default = false; $search_sql = self::get_leads_where_sql( compact( 'form_id', 'search', 'status', 'star', 'read', 'start_date', 'end_date', 'payment_status', 'is_default' ) ); $field_number_min = $sort_field_number - 0.0001; $field_number_max = $sort_field_number + 0.0001; $sql = " SELECT filtered.sort, l.*, d.field_number, d.value FROM $lead_table_name l INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id INNER JOIN ( SELECT distinct sorted.sort, l.id FROM $lead_table_name l INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id INNER JOIN ( SELECT @rownum:=@rownum+1 as sort, id FROM ( SELECT 0 as query, lead_id as id, value FROM $lead_detail_table_name WHERE form_id=$form_id AND field_number between $field_number_min AND $field_number_max UNION ALL SELECT 1 as query, l.id, d.value FROM $lead_table_name l LEFT OUTER JOIN $lead_detail_table_name d ON d.lead_id = l.id AND field_number between $field_number_min AND $field_number_max WHERE l.form_id=$form_id AND d.lead_id IS NULL ) sorted1 $orderby ) sorted ON d.lead_id = sorted.id $search_sql LIMIT $offset,$page_size ) filtered ON filtered.id = l.id ORDER BY filtered.sort"; return $sql; } private static function sort_by_default_field_query( $form_id, $sort_field, $sort_direction = 'DESC', $search = '', $offset = 0, $page_size = 30, $star = null, $read = null, $is_numeric_sort = false, $start_date = null, $end_date = null, $status = 'active', $payment_status = false ) { global $wpdb; if ( ! is_numeric( $form_id ) || ! is_numeric( $offset ) || ! is_numeric( $page_size ) ) { return ''; } $lead_detail_table_name = self::get_lead_details_table_name(); $lead_table_name = self::get_lead_table_name(); $lead_meta_table_name = self::get_lead_meta_table_name(); $where = self::get_leads_where_sql( compact( 'form_id', 'search', 'status', 'star', 'read', 'start_date', 'end_date', 'payment_status' ) ); $entry_meta = self::get_entry_meta( $form_id ); $entry_meta_sql_join = ''; 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 ); $is_numeric_sort = $entry_meta[ $sort_field ]['is_numeric']; } $grid_columns = RGFormsModel::get_grid_columns( $form_id ); if ( $sort_field != 'date_created' && false === array_key_exists( $sort_field, $grid_columns ) ) { $sort_field = 'date_created'; } $orderby = $is_numeric_sort ? "ORDER BY ($sort_field+0) $sort_direction" : "ORDER BY $sort_field $sort_direction"; $sql = " SELECT filtered.sort, l.*, d.field_number, d.value FROM $lead_table_name l INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id INNER JOIN ( SELECT @rownum:=@rownum + 1 as sort, id FROM ( SELECT distinct l.id FROM $lead_table_name l INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id $entry_meta_sql_join $where $orderby LIMIT $offset,$page_size ) page ) filtered ON filtered.id = l.id ORDER BY filtered.sort"; return $sql; } public static function get_leads_where_sql( $args ) { global $wpdb; extract( wp_parse_args( $args, array( 'form_id' => false, 'search' => '', 'status' => 'active', 'star' => null, 'read' => null, 'start_date' => null, 'end_date' => null, 'payment_status' => null, 'is_default' => true, ) ) ); $where = array(); if ( $is_default ) { $where[] = "l.form_id = $form_id"; } if ( $search && $is_default ) { $where[] = $wpdb->prepare( 'value LIKE %s', "%$search%" ); } else if ( $search ) { $where[] = $wpdb->prepare( 'd.value LIKE %s', "%$search%" ); } if ( $star !== null && $status == 'active' ) { $where[] = $wpdb->prepare( "is_starred = %d AND status = 'active'", $star ); } if ( $read !== null && $status == 'active' ) { $where[] = $wpdb->prepare( "is_read = %d AND status = 'active'", $read ); } if ( $payment_status ) { $where[] = $wpdb->prepare( "payment_status = '%s'", $payment_status ); } if ( $status !== null ) { $where[] = $wpdb->prepare( 'status = %s', $status ); } if ( ! empty( $start_date ) ) { $where[] = "timestampdiff(SECOND, '$start_date', date_created) >= 0"; } if ( ! empty( $end_date ) ) { $where[] = "timestampdiff(SECOND, '$end_date', date_created) <= 0"; } return 'WHERE ' . implode( ' AND ', $where ); } public static function build_lead_array( $results, $use_long_values = true ) { $leads = array(); $lead = array(); $form_id = 0; if ( is_array( $results ) && sizeof( $results ) > 0 ) { $form_id = $results[0]->form_id; $lead = array( 'id' => $results[0]->id, 'form_id' => $results[0]->form_id, 'date_created' => $results[0]->date_created, 'is_starred' => intval( $results[0]->is_starred ), 'is_read' => intval( $results[0]->is_read ), 'ip' => $results[0]->ip, 'source_url' => $results[0]->source_url, 'post_id' => $results[0]->post_id, 'currency' => $results[0]->currency, 'payment_status' => $results[0]->payment_status, 'payment_date' => $results[0]->payment_date, 'transaction_id' => $results[0]->transaction_id, 'payment_amount' => $results[0]->payment_amount, 'payment_method' => $results[0]->payment_method, 'is_fulfilled' => $results[0]->is_fulfilled, 'created_by' => $results[0]->created_by, 'transaction_type' => $results[0]->transaction_type, 'user_agent' => $results[0]->user_agent, 'status' => $results[0]->status ); $form = RGFormsModel::get_form_meta( $form_id ); $prev_lead_id = 0; foreach ( $results as $result ) { if ( $prev_lead_id <> $result->id && $prev_lead_id > 0 ) { array_push( $leads, $lead ); $lead = array( 'id' => $result->id, 'form_id' => $result->form_id, 'date_created' => $result->date_created, 'is_starred' => intval( $result->is_starred ), 'is_read' => intval( $result->is_read ), 'ip' => $result->ip, 'source_url' => $result->source_url, 'post_id' => $result->post_id, 'currency' => $result->currency, 'payment_status' => $result->payment_status, 'payment_date' => $result->payment_date, 'transaction_id' => $result->transaction_id, 'payment_amount' => $result->payment_amount, 'payment_method' => $result->payment_method, 'is_fulfilled' => $result->is_fulfilled, 'created_by' => $result->created_by, 'transaction_type' => $result->transaction_type, 'user_agent' => $result->user_agent, 'status' => $result->status ); } $field_value = $result->value; $field_number = (string)$result->field_number; //using long values if specified if ( $use_long_values && strlen( $field_value ) >= ( GFORMS_MAX_FIELD_LENGTH - 10 ) ) { $long_text = RGFormsModel::get_field_value_long( $lead, $field_number, $form, false ); $field_value = ! empty( $long_text ) ? $long_text : $field_value; } $lead[ $field_number ] = $field_value; $prev_lead_id = $result->id; } } //adding last lead. if ( sizeof( $lead ) > 0 ) { array_push( $leads, $lead ); } //running entry through gform_get_field_value filter foreach ( $leads as &$lead ) { foreach ( $form['fields'] as $field ) { /* @var GF_Field $field */ $inputs = $field->get_entry_inputs(); // skip types html, page and section? if ( is_array( $inputs ) ) { foreach ( $inputs as $input ) { $lead[ (string) $input['id'] ] = apply_filters( 'gform_get_input_value', rgar( $lead, (string) $input['id'] ), $lead, $field, $input['id'] ); } } else { $value = rgar( $lead, (string) $field->id ); if ( self::is_encrypted_field( $lead['id'], $field->id ) ) { $value = GFCommon::decrypt( $value ); } $lead[ $field->id ] = apply_filters( 'gform_get_input_value', $value, $lead, $field, '' ); } } } //add custom entry properties $entry_ids = array(); foreach ( $leads as $l ) { $entry_ids[] = $l['id']; } $entry_meta = GFFormsModel::get_entry_meta( $form_id ); $meta_keys = array_keys( $entry_meta ); $entry_meta_data_rows = gform_get_meta_values_for_entries( $entry_ids, $meta_keys ); foreach ( $leads as &$lead ) { foreach ( $entry_meta_data_rows as $entry_meta_data_row ) { if ( $entry_meta_data_row->lead_id == $lead['id'] ) { foreach ( $meta_keys as $meta_key ) { $lead[ $meta_key ] = $entry_meta_data_row->$meta_key; } } } } return $leads; } public static function save_key( $key ) { $current_key = get_option( 'rg_gforms_key' ); if ( empty( $key ) ) { delete_option( 'rg_gforms_key' ); } else if ( $current_key != $key ) { $key = trim( $key ); update_option( 'rg_gforms_key', md5( $key ) ); } } public static function get_lead_count( $form_id, $search, $star = null, $read = null, $start_date = null, $end_date = null, $status = null, $payment_status = null ) { global $wpdb; if ( ! is_numeric( $form_id ) ) { return ''; } $detail_table_name = self::get_lead_details_table_name(); $lead_table_name = self::get_lead_table_name(); $where = self::get_leads_where_sql( compact( 'form_id', 'search', 'status', 'star', 'read', 'start_date', 'end_date', 'payment_status', 'is_default' ) ); $sql = "SELECT count(distinct l.id) FROM $lead_table_name l INNER JOIN $detail_table_name ld ON l.id = ld.lead_id $where"; return $wpdb->get_var( $sql ); } public static function get_lead_ids( $form_id, $search, $star = null, $read = null, $start_date = null, $end_date = null, $status = null, $payment_status = null ) { global $wpdb; if ( ! is_numeric( $form_id ) ) { return ''; } $detail_table_name = self::get_lead_details_table_name(); $lead_table_name = self::get_lead_table_name(); $where = self::get_leads_where_sql( compact( 'form_id', 'search', 'status', 'star', 'read', 'start_date', 'end_date', 'payment_status', 'is_default' ) ); $sql = "SELECT distinct l.id FROM $lead_table_name l INNER JOIN $detail_table_name ld ON l.id = ld.lead_id $where"; $rows = $wpdb->get_results( $sql ); if ( empty( $rows ) ) { return array(); } foreach ( $rows as $row ) { $lead_ids[] = $row->id; } return $lead_ids; } public static function get_grid_columns( $form_id, $input_label_only = false ) { $form = self::get_form_meta( $form_id ); $field_ids = self::get_grid_column_meta( $form_id ); if ( ! is_array( $field_ids ) ) { $field_ids = array(); for ( $i = 0, $count = sizeof( $form['fields'] ); $i < $count && $i < 5; $i ++ ) { /* @var GF_Field $field */ $field = $form['fields'][ $i ]; //loading post category fields with choices and inputs if ( $field->type == 'post_category' ) { $field = GFCommon::add_categories_as_choices( $field, '' ); } if ( RGForms::get( 'displayOnly', $field ) || self::get_input_type( $field ) == 'list' ) { continue; } $inputs = $field->get_entry_inputs(); if ( is_array( $inputs ) ) { if ( $field->type == 'name' ) { $field_ids[] = $field->id . '.3'; //adding first name $field_ids[] = $field->id . '.6'; //adding last name } else { $field_ids[] = $field->inputs[0]['id']; //getting first input } } else { $field_ids[] = $field->id; } } //adding default entry meta columns $entry_metas = GFFormsModel::get_entry_meta( $form_id ); foreach ( $entry_metas as $key => $entry_meta ) { if ( rgar( $entry_meta, 'is_default_column' ) ) { $field_ids[] = $key; } } } $columns = array(); $entry_meta = self::get_entry_meta( $form_id ); foreach ( $field_ids as $field_id ) { switch ( $field_id ) { case 'id' : $columns[ $field_id ] = array( 'label' => 'Entry Id', 'type' => 'id' ); break; case 'ip' : $columns[ $field_id ] = array( 'label' => 'User IP', 'type' => 'ip' ); break; case 'date_created' : $columns[ $field_id ] = array( 'label' => 'Entry Date', 'type' => 'date_created' ); break; case 'source_url' : $columns[ $field_id ] = array( 'label' => 'Source Url', 'type' => 'source_url' ); break; case 'payment_status' : $columns[ $field_id ] = array( 'label' => 'Payment Status', 'type' => 'payment_status' ); break; case 'transaction_id' : $columns[ $field_id ] = array( 'label' => 'Transaction Id', 'type' => 'transaction_id' ); break; case 'payment_date' : $columns[ $field_id ] = array( 'label' => 'Payment Date', 'type' => 'payment_date' ); break; case 'payment_amount' : $columns[ $field_id ] = array( 'label' => 'Payment Amount', 'type' => 'payment_amount' ); break; case 'created_by' : $columns[ $field_id ] = array( 'label' => 'User', 'type' => 'created_by' ); break; case ( ( is_string( $field_id ) || is_int( $field_id ) ) && array_key_exists( $field_id, $entry_meta ) ) : $columns[ $field_id ] = array( 'label' => $entry_meta[ $field_id ]['label'], 'type' => $field_id ); break; default : $field = self::get_field( $form, $field_id ); if ( $field ) { $input_label_only = apply_filters( 'gform_entry_list_column_input_label_only', $input_label_only, $form, $field ); $columns[strval( $field_id )] = array( 'label' => self::get_label( $field, $field_id, $input_label_only ), 'type' => $field->type, 'inputType' => $field->inputType ); } } } return $columns; } /** * @param GF_Field $field * @param int $input_id * @param bool $input_only * * @return string */ public static function get_label( $field, $input_id = 0, $input_only = false ) { if ( ! $field instanceof GF_Field ) { $field = GF_Fields::create( $field ); } $field_label = ( IS_ADMIN || RG_CURRENT_PAGE == 'select_columns.php' || RG_CURRENT_PAGE == 'print-entry.php' || rgget( 'gf_page', $_GET ) == 'select_columns' || rgget( 'gf_page', $_GET ) == 'print-entry' ) && ! empty( $field->adminLabel ) ? $field->adminLabel : $field->label; $input = self::get_input( $field, $input_id ); if ( self::get_input_type($field) == 'checkbox' && $input != null ) { return $input['label']; } else if ( $input != null ) { return $input_only ? $input['label'] : $field_label . ' (' . $input['label'] . ')'; } else { return $field_label; } } /** * @param GF_Field $field * @param $id * * @return null */ public static function get_input( $field, $id ) { if ( is_array( $field->inputs ) ) { foreach ( $field->inputs as $input ) { if ( $input['id'] == $id ) { return $input; } } } return null; } public static function has_input( $field, $input_id ) { if ( ! is_array( $field->inputs ) ) { return false; } else { foreach ( $field->inputs as $input ) { if ( $input['id'] == $input_id ) { return true; } } return false; } } public static function get_current_page_url( $force_ssl = false ) { $pageURL = 'http'; if ( RGForms::get( 'HTTPS', $_SERVER ) == 'on' || $force_ssl ) { $pageURL .= 's'; } $pageURL .= '://'; $pageURL .= RGForms::get( 'HTTP_HOST', $_SERVER ) . rgget( 'REQUEST_URI', $_SERVER ); return $pageURL; } public static function get_submitted_fields( $form_id ) { global $wpdb; $lead_detail_table_name = self::get_lead_details_table_name(); $field_list = ''; $fields = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT field_number FROM $lead_detail_table_name WHERE form_id=%d", $form_id ) ); foreach ( $fields as $field ) { $field_list .= intval( $field->field_number ) . ','; } if ( ! empty( $field_list ) ) { $field_list = substr( $field_list, 0, strlen( $field_list ) - 1 ); } return $field_list; } /** * @param $form * @param $field_id * * @return GF_Field */ public static function get_field( $form, $field_id ) { if ( is_numeric( $field_id ) ) { $field_id = intval( $field_id ); } //removing floating part of field (i.e 1.3 -> 1) to return field by input id if ( ! is_array( $form['fields'] ) ) { return null; } global $_fields; $key = $form['id'] . '_' . $field_id; if ( ! isset( $_fields[ $key ] ) ) { $_fields[ $key ] = null; foreach ( $form['fields'] as $field ) { if ( $field->id == $field_id ) { $_fields[ $key ] = $field; break; } } } return $_fields[ $key ]; } public static function is_html5_enabled() { return get_option( 'rg_gforms_enable_html5' ); } /** * Return the current lead being processed. Should only be called when a form has been submitted. * If called before the "real" lead has been saved to the database, uses self::create_lead() to create * a temporary lead to work with. */ public static function get_current_lead() { // if a GF submission is not in process, always return false if ( ! rgpost( 'gform_submit' ) ) { return false; } if ( ! self::$_current_lead ) { $form_id = absint( rgpost( 'gform_submit' ) ); $form = self::get_form_meta( $form_id ); self::$_current_lead = self::create_lead( $form ); } return self::$_current_lead; } /** * Set RGFormsModel::$lead for use in hooks where $lead is not explicitly passed. * * @param mixed $lead */ public static function set_current_lead( $lead ) { GFCache::flush(); self::$_current_lead = $lead; } /** * v1.7 introduces conditional confirmations. If the form's "confirmations" key is empty, grab the existing confirmation * and populate it in the form's "confirmations" property. * * @param mixed $form * @return array */ public static function convert_confirmation( $form ) { $id = uniqid(); // convert confirmation to new confirmations format $confirmation = rgar( $form, 'confirmation' ); $confirmation['id'] = $id; $confirmation['name'] = __( 'Default Confirmation', 'gravityforms' ); $confirmation['isDefault'] = true; $form['confirmations'] = array( $id => $confirmation ); self::save_form_confirmations( $form['id'], $form['confirmations'] ); return $form; } public static function load_confirmations( $form ) { $confirmations = self::get_form_confirmations( $form['id'] ); // if there are no confirmations, convert existing (singular) confirmation (prior to 1.7) to new (plural) confirmations format if ( empty( $confirmations ) ) { $form = self::convert_confirmation( $form ); } else { $form['confirmations'] = $confirmations; } return $form; } public static function get_form_confirmations( $form_id ) { global $wpdb; if ( isset( $_confirmations[ $form_id ] ) ) { return $_confirmations[ $form_id ]; } $tablename = GFFormsModel::get_meta_table_name(); $sql = $wpdb->prepare( "SELECT confirmations FROM $tablename WHERE form_id = %d", $form_id ); $results = $wpdb->get_results( $sql, ARRAY_A ); $confirmations = rgars( $results, '0/confirmations' ); self::$_confirmations[ $form_id ] = $confirmations ? self::unserialize( $confirmations ) : array(); return self::$_confirmations[ $form_id ]; } public static function save_form_confirmations( $form_id, $confirmations ) { return self::update_form_meta( $form_id, $confirmations, 'confirmations' ); } public static function save_form_notifications( $form_id, $notifications ) { return self::update_form_meta( $form_id, $notifications, 'notifications' ); } public static function get_form_ids( $active = true, $trash = false ) { global $wpdb; $table = self::get_form_table_name(); $sql = $wpdb->prepare( "SELECT id from $table where is_active = %d and is_trash = %d", (bool) $active, (bool) $trash ); $results = $wpdb->get_col( $sql ); return $results; } public static function get_entry_meta( $form_ids ) { global $_entry_meta; if ( $form_ids == 0 ) { $form_ids = self::get_form_ids(); } if ( ! is_array( $form_ids ) ) { $form_ids = array( $form_ids ); } $meta = array(); foreach ( $form_ids as $form_id ) { if ( ! isset( $_entry_meta[ $form_id ] ) ) { $_entry_meta = array(); $_entry_meta[ $form_id ] = apply_filters( 'gform_entry_meta', array(), $form_id ); } $meta = array_merge( $meta, $_entry_meta[ $form_id ] ); } return $meta; } public static function set_entry_meta( $lead, $form ) { $entry_meta = self::get_entry_meta( $form['id'] ); $keys = array_keys( $entry_meta ); foreach ( $keys as $key ) { if ( isset( $entry_meta[ $key ]['update_entry_meta_callback'] ) ) { $callback = $entry_meta[ $key ]['update_entry_meta_callback']; $value = call_user_func_array( $callback, array( $key, $lead, $form ) ); gform_update_meta( $lead['id'], $key, $value ); $lead[ $key ] = $value; } } return $lead; } public static function search_leads( $form_id, $search_criteria = array(), $sorting = null, $paging = null ) { global $wpdb; $sort_field = isset( $sorting['key'] ) ? $sorting['key'] : 'date_created'; // column, field or entry meta if ( is_numeric( $sort_field ) ) { $sql = self::sort_by_field_query( $form_id, $search_criteria, $sorting, $paging ); } else { $sql = self::sort_by_column_query( $form_id, $search_criteria, $sorting, $paging ); } //initializing rownum $wpdb->query( 'select @rownum:=0' ); GFCommon::log_debug( $sql ); //getting results $results = $wpdb->get_results( $sql ); $leads = GFFormsModel::build_lead_array( $results ); return $leads; } public static function search_lead_ids( $form_id, $search_criteria = array() ) { global $wpdb; $detail_table_name = GFFormsModel::get_lead_details_table_name(); $lead_table_name = GFFormsModel::get_lead_table_name(); $where = self::get_search_where( $form_id, $search_criteria ); $sql = "SELECT distinct l.id FROM $lead_table_name l INNER JOIN $detail_table_name ld ON l.id = ld.lead_id $where "; $rows = $wpdb->get_results( $sql ); if ( empty( $rows ) ) { return array(); } foreach ( $rows as $row ) { $lead_ids[] = $row->id; } return $lead_ids; } private static function sort_by_field_query( $form_id, $search_criteria, $sorting, $paging ) { global $wpdb; $sort_field_number = rgar( $sorting, 'key' ); $sort_direction = isset( $sorting['direction'] ) ? $sorting['direction'] : 'DESC'; $is_numeric_sort = isset( $sorting['is_numeric'] ) ? $sorting['is_numeric'] : false; $offset = isset( $paging['offset'] ) ? $paging['offset'] : 0; $page_size = isset( $paging['page_size'] ) ? $paging['page_size'] : 20; if ( ! is_numeric( $sort_field_number ) || ! is_numeric( $offset ) || ! is_numeric( $page_size ) ) { return ''; } $lead_detail_table_name = GFFormsModel::get_lead_details_table_name(); $lead_table_name = GFFormsModel::get_lead_table_name(); $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 ); 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.0001; $field_number_max = $sort_field_number + 0.0001; $sql = " SELECT filtered.sort, l.*, d.field_number, d.value FROM $lead_table_name l INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id INNER JOIN ( SELECT distinct sorted.sort, l.id FROM $lead_table_name l INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id INNER JOIN ( SELECT @rownum:=@rownum+1 as sort, id FROM ( SELECT 0 as query, lead_id as id, value FROM $lead_detail_table_name l WHERE field_number between $field_number_min AND $field_number_max $form_id_where UNION ALL SELECT 1 as query, l.id, d.value FROM $lead_table_name l LEFT OUTER JOIN $lead_detail_table_name d ON d.lead_id = l.id AND field_number between $field_number_min AND $field_number_max WHERE d.lead_id IS NULL $form_id_where ) sorted1 $orderby ) sorted ON d.lead_id = sorted.id $where LIMIT $offset,$page_size ) filtered ON filtered.id = l.id ORDER BY filtered.sort"; return $sql; } private static function sort_by_column_query( $form_id, $search_criteria, $sorting, $paging ) { global $wpdb; $sort_field = isset( $sorting['key'] ) ? $sorting['key'] : 'date_created'; $sort_direction = isset( $sorting['direction'] ) ? $sorting['direction'] : 'DESC'; $is_numeric_sort = isset( $sorting['is_numeric'] ) ? $sorting['is_numeric'] : false; $offset = isset( $paging['offset'] ) ? $paging['offset'] : 0; $page_size = isset( $paging['page_size'] ) ? $paging['page_size'] : 20; if ( ! is_numeric( $offset ) || ! is_numeric( $page_size ) ) { return ''; } $lead_detail_table_name = GFFormsModel::get_lead_details_table_name(); $lead_table_name = GFFormsModel::get_lead_table_name(); $lead_meta_table_name = GFFormsModel::get_lead_meta_table_name(); $entry_meta = GFFormsModel::get_entry_meta( is_array( $form_id ) ? 0 : $form_id ); $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 ); $is_numeric_sort = $entry_meta[ $sort_field ]['is_numeric']; $sort_field_is_entry_meta = true; } else { $db_columns = self::get_lead_db_columns(); if ( $sort_field != 'date_created' && false === in_array( $sort_field, $db_columns ) ) { $sort_field = 'date_created'; } } if ( $sort_field_is_entry_meta ) { $orderby = $is_numeric_sort ? "ORDER BY ($sort_field+0) $sort_direction" : "ORDER BY $sort_field $sort_direction"; } else { $orderby = $is_numeric_sort ? "ORDER BY (l.$sort_field+0) $sort_direction" : "ORDER BY l.$sort_field $sort_direction"; } $where = self::get_search_where( $form_id, $search_criteria ); $sql = " SELECT filtered.sort, l.*, d.field_number, d.value FROM $lead_table_name l INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id INNER JOIN ( SELECT @rownum:=@rownum + 1 as sort, id FROM ( SELECT distinct l.id FROM $lead_table_name l INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id $entry_meta_sql_join $where $orderby LIMIT $offset,$page_size ) page ) filtered ON filtered.id = l.id ORDER BY filtered.sort"; 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 ), '%d' ); $in_str = 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 ); 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 ); $where_and_clause_arr = array(); 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; } $status_where = isset( $search_criteria['status'] ) ? $wpdb->prepare( 'l.status = %s', $search_criteria['status'] ) : ''; if ( ! empty( $status_where ) ) { $where_and_clause_arr[] = $status_where; } $where_and_clause = join( ' AND ', $where_and_clause_arr ); if ( ! empty( $where_and_clause ) ) { $where_and_clause = '(' . $where_and_clause . ')'; } $where_parts = array(); if ( ! empty( $where ) ) { $where_parts[] = $where; } if ( ! empty( $where_and_clause ) ) { $where_parts[] = $where_and_clause; } $where = join( ' AND ', $where_parts ); if ( ! empty( $where ) ) { $where = 'WHERE ' . $where; } return $where; } private static function get_field_filters_where( $form_id, $search_criteria ) { global $wpdb; $field_filters = rgar( $search_criteria, 'field_filters' ); $search_operator = self::get_search_operator( $search_criteria ); if ( empty( $field_filters ) ) { return false; } unset( $field_filters['mode'] ); $sql_array = array(); $lead_details_table_name = GFFormsModel::get_lead_details_table_name(); $lead_meta_table_name = GFFormsModel::get_lead_meta_table_name(); if ( is_array( $form_id ) ) { $in_str_arr = array_fill( 0, count( $form_id ), '%d' ); $in_str = 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 form_id=%d', $form_id ) : ''; } $info_column_keys = self::get_lead_db_columns(); $entry_meta = self::get_entry_meta( is_array( $form_id ) ? 0 : $form_id ); array_push( $info_column_keys, 'id' ); foreach ( $field_filters as $search ) { $key = rgar( $search, 'key' ); if ( 'entry_id' === $key ) { $key = 'id'; } if ( in_array( $key, $info_column_keys ) ) { continue; } $val = rgar( $search, 'value' ); $operator = isset( $search['operator'] ) ? strtolower( $search['operator'] ) : '='; if ( 'is' == $operator ) { $operator = '='; } if ( 'isnot' == $operator ) { $operator = '<>'; } if ( 'contains' == $operator ) { $operator = 'like'; } $search_term = 'like' == $operator ? "%$val%" : $val; $search_type = rgar( $search, 'type' ); if ( empty( $search_type ) ) { if ( empty( $key ) ) { $search_type = 'global'; } elseif ( is_numeric( $key ) ) { $search_type = 'field'; } else { $search_type = 'meta'; } } switch ( $search_type ) { case 'field': $is_number_field = false; if ( $operator != 'like' && ! is_array( $form_id ) && $form_id > 0 ) { $form = GFAPI::get_form( $form_id ); $field = self::get_field( $form, $key ); if ( self::get_input_type( $field ) == 'number' ){ $is_number_field = true; } } $search_term_placeholder = rgar( $search, 'is_numeric' ) || $is_number_field ? '%f' : '%s'; if ( is_array( $search_term ) ) { if ( in_array( $operator, array( '=', 'in' ) ) ) { $operator = 'IN'; // Override operator } elseif ( in_array( $operator, array( '!=', '<>', 'not in' ) ) ) { $operator = 'NOT IN'; // Override operator } // Format in SQL and sanitize the strings in the list $search_terms = array_fill( 0, count( $search_term ), '%s' ); $search_term_placeholder = $wpdb->prepare( '( ' . implode( ', ', $search_terms ) . ' )', $search_term ); $search_term = ''; // Set to blank, still gets passed to wpdb::prepare below but isn't used } $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} {$search_term_placeholder}) {$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 ); $field_query = '(' . $field_query . ' OR ' . $skipped_field_query . ')'; } $sql_array[] = $field_query; /* //supports '<>' for checkboxes but it doesn't scale $sql_array[] = $wpdb->prepare("l.id IN (SELECT lead_id FROM ( SELECT lead_id, value FROM $lead_details_table_name WHERE form_id = %d AND (field_number BETWEEN %s AND %s) GROUP BY lead_id HAVING value $operator %s ) ld ) ", $form_id, (float)$key - 0.0001, $upper_field_number_limit, $val ); */ break; case 'global': // include choice text $forms = array(); if ( $form_id == 0 ) { $forms = GFAPI::get_forms(); } elseif ( is_array( $form_id ) ) { foreach ( $form_id as $id ){ $forms[] = GFAPI::get_form( $id ); } } else { $forms[] = GFAPI::get_form( $form_id ); } $choice_texts_clauses = array(); foreach ( $forms as $form ) { if ( isset( $form['fields'] ) ) { $choice_texts_clauses_for_form = array(); foreach ( $form['fields'] as $field ) { /* @var GF_Field $field */ $choice_texts_clauses_for_field = array(); if ( is_array( $field->choices ) ) { foreach ( $field->choices as $choice ) { if ( ( $operator == '=' && strtolower( $choice['text'] ) == strtolower( $val ) ) || ( $operator == 'like' && ! empty( $val ) && strpos( strtolower( $choice['text'] ), strtolower( $val ) ) !== false ) ) { if ( $field->gsurveyLikertEnableMultipleRows ){ $choice_value = '%' . $choice['value'] . '%' ; $choice_search_operator = 'like'; } else { $choice_value = $choice['value']; $choice_search_operator = '='; } $choice_texts_clauses_for_field[] = $wpdb->prepare( "(field_number BETWEEN %s AND %s AND value {$choice_search_operator} %s)", (float) $field->id - 0.0001, (float) $field->id + 0.9999, $choice_value ); } } } if ( ! empty( $choice_texts_clauses_for_field ) ) { $choice_texts_clauses_for_form[] = join( ' OR ', $choice_texts_clauses_for_field ); } } } if ( ! empty( $choice_texts_clauses_for_form ) ) { $choice_texts_clauses[] = '(l.form_id = ' . $form['id'] . ' AND (' . join( ' OR ', $choice_texts_clauses_for_form ) . ' ))'; } } $choice_texts_clause = ''; if ( ! empty( $choice_texts_clauses) ){ $choice_texts_clause = join( ' OR ', $choice_texts_clauses ); $choice_texts_clause = " l.id IN ( SELECT lead_id FROM {$lead_details_table_name} WHERE {$choice_texts_clause} ) OR "; } $choice_value_clause = $wpdb->prepare( "value {$operator} %s", $search_term ); $sql_array[] = '(' . $choice_texts_clause . $choice_value_clause . ')'; break; case 'meta': /* doesn't support '<>' for multiple values of the same key */ $meta = rgar( $entry_meta, $key ); $placeholder = rgar( $meta, 'is_numeric' ) ? '%s' : '%s'; $search_term = 'like' == $operator ? "%$val%" : $val; if ( is_array( $search_term ) ) { if ( in_array( $operator, array( '=', 'in' ) ) ) { $operator = 'IN'; } elseif ( in_array( $operator, array( '!=', '<>', 'not in' ) ) ) { $operator = 'NOT IN'; } $search_terms = array_fill( 0, count( $search_term ), '%s' ); $placeholder = $wpdb->prepare( '( ' . implode( ', ', $search_terms ) . ' )', $search_term ); $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; } } $sql = empty( $sql_array ) ? '' : join( ' ' . $search_operator . ' ', $sql_array ); return $sql; } private static function get_date_range_where( $search_criteria ) { global $wpdb; 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 ) . ')'; return $sql; } private static function get_search_operator( $search_criteria ) { if ( ! isset( $search_criteria['field_filters'] ) ) { return ''; } $field_filters = $search_criteria['field_filters']; $search_mode = isset( $field_filters['mode'] ) ? strtolower( $field_filters['mode'] ) : 'all'; return strtolower( $search_mode ) == 'any' ? 'OR' : 'AND'; } private static function get_lead_db_columns() { return array( 'id', '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' ); } private static function get_info_search_where( $search_criteria ) { global $wpdb; $field_filters = rgar( $search_criteria, 'field_filters' ); $search_operator = self::get_search_operator( $search_criteria ); if ( empty( $field_filters ) ) { return; } unset( $field_filters['mode'] ); $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', 'entry_id' ); $where_array = array(); foreach ( $field_filters as $filter ) { $key = strtolower( rgar( $filter, 'key' ) ); if ( 'entry_id' === $key ) { $key = 'id'; } if ( ! in_array( $key, $info_column_keys ) ) { continue; } $operator = isset( $filter['operator'] ) ? strtolower( $filter['operator'] ) : '='; $value = rgar( $filter, 'value' ); if ( 'is' == $operator ) { $operator = '='; } if ( 'isnot' == $operator ) { $operator = '<>'; } if ( 'contains' == $operator ) { $operator = 'like'; } $search_term = 'like' == $operator ? '%value%' : $value; if ( 'date_created' == $key && '=' === $operator ) { $where_array[] = $wpdb->prepare( '(datediff(date_created, %s) >= 0 AND datediff(date_created, %s) <= 0)', $search_term, $search_term ); } else if ( in_array( $key, $int_columns ) ) { $where_array[] = $wpdb->prepare( "l.{$key} $operator %d", $search_term ); } else { $where_array[] = $wpdb->prepare( "l.{$key} $operator %s", $search_term ); } } $sql = empty( $where_array ) ? '' : join( " $search_operator ", $where_array ); return $sql; } public static function count_search_leads( $form_id, $search_criteria = array() ) { global $wpdb; $detail_table_name = GFFormsModel::get_lead_details_table_name(); $lead_table_name = GFFormsModel::get_lead_table_name(); $where = self::get_search_where( $form_id, $search_criteria ); $sql = "SELECT count(distinct l.id) FROM $lead_table_name l INNER JOIN $detail_table_name ld ON l.id = ld.lead_id $where "; return $wpdb->get_var( $sql ); } public static function get_lead_count_all_forms( $status = 'active' ) { global $wpdb; $detail_table_name = self::get_lead_details_table_name(); $lead_table_name = self::get_lead_table_name(); $sql = "SELECT count(id) FROM $lead_table_name WHERE status='{$status}'"; return $wpdb->get_var( $sql ); } public static function dbDelta( $sql ) { global $wpdb; require_once( ABSPATH . '/wp-admin/includes/upgrade.php' ); //Fixes issue with dbDelta lower-casing table names, which cause problems on case sensitive DB servers. add_filter( 'dbdelta_create_queries', array( 'GFForms', 'dbdelta_fix_case' ) ); dbDelta( $sql ); remove_filter( 'dbdelta_create_queries', array( 'GFForms', 'dbdelta_fix_case' ) ); } public static function get_db_charset() { global $wpdb; if ( ! empty( $wpdb->charset ) ) { $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset"; } if ( ! empty( $wpdb->collate ) ) { $charset_collate .= " COLLATE $wpdb->collate"; } 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( 'GFFormsModel::trim_form_meta_values(): Starting.' ); 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 ( 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 ( 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( 'GFFormsModel::trim_form_meta_values(): Form values trimmed.' ); } 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( 'GFFormsModel::trim_conditional_logic_values(): Starting.' ); 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( 'GFFormsModel::trim_conditional_logic_values(): Conditional logic values trimmed.' ); } 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 ( $element instanceof GF_Field ) { /* @var GF_Field $element */ if ( 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; } } } } } else { 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; } public static function get_encrypted_fields( $entry_id ) { $encrypted_fields = gform_get_meta( $entry_id, '_encrypted_fields' ); if ( empty( $encrypted_fields ) ) { $encrypted_fields = array(); } return $encrypted_fields; } public static function set_encrypted_fields( $entry_id, $field_ids ) { if ( ! is_array( $field_ids ) ) { $field_ids = array( $field_ids ); } $encrypted_fields = array_merge( self::get_encrypted_fields( $entry_id ), $field_ids ); gform_update_meta( $entry_id, '_encrypted_fields', $encrypted_fields ); return true; } public static function is_encrypted_field( $entry_id, $field_id ) { $encrypted_fields = self::get_encrypted_fields( $entry_id ); return in_array( $field_id, $encrypted_fields ); } public static function delete_password( $entry, $form ) { $password_fields = GFCommon::get_fields_by_type( $form, array( 'password' ) ); if ( is_array( $password_fields ) ) { foreach ( $password_fields as $password_field ) { $entry[ $password_field->id ] = ''; } } GFAPI::update_entry( $entry ); return $entry; } } class RGFormsModel extends GFFormsModel { } global $_gform_lead_meta; $_gform_lead_meta = array(); //functions to handle lead meta function gform_get_meta( $entry_id, $meta_key ) { global $wpdb, $_gform_lead_meta; //get from cache if available $cache_key = $entry_id . '_' . $meta_key; if ( array_key_exists( $cache_key, $_gform_lead_meta ) ) { return maybe_unserialize( $_gform_lead_meta[ $cache_key ] ); } $table_name = RGFormsModel::get_lead_meta_table_name(); $results = $wpdb->get_results( $wpdb->prepare( "SELECT meta_value FROM {$table_name} WHERE lead_id=%d AND meta_key=%s", $entry_id, $meta_key ) ); $value = isset( $results[0] ) ? $results[0]->meta_value : null; $meta_value = $value === null ? false : maybe_unserialize( $value ); $_gform_lead_meta[ $cache_key ] = $meta_value; return $meta_value; } function gform_get_meta_values_for_entries( $entry_ids, $meta_keys ) { global $wpdb; if ( empty( $meta_keys ) || empty( $entry_ids ) ) { return array(); } $table_name = RGFormsModel::get_lead_meta_table_name(); $meta_key_select_array = array(); foreach ( $meta_keys as $meta_key ) { $meta_key_select_array[] = "max(case when meta_key = '$meta_key' then meta_value end) as $meta_key"; } $entry_ids_str = join( ',', $entry_ids ); $meta_key_select = join( ',', $meta_key_select_array ); $sql_query = " SELECT lead_id, $meta_key_select FROM $table_name WHERE lead_id IN ($entry_ids_str) GROUP BY lead_id"; $results = $wpdb->get_results( $sql_query ); foreach ( $results as $result ) { foreach ( $meta_keys as $meta_key ) { $result->$meta_key = $result->$meta_key === null ? false : maybe_unserialize( $result->$meta_key ); } } $meta_value_array = $results; return $meta_value_array; } /** * Add or update metadata associated with an entry * * Data will be serialized; no sanitation is necessary. * * @param int $entry_id The ID of the entry to be updated * @param string $meta_key The key for the meta data to be stored * @param mixed $meta_value The data to be stored for the entry * @param int|null $form_id The form ID of the entry (optional, saves extra query if passed when creating the metadata) */ function gform_update_meta( $entry_id, $meta_key, $meta_value, $form_id = null ) { global $wpdb, $_gform_lead_meta; $table_name = RGFormsModel::get_lead_meta_table_name(); if ( false === $meta_value ) { $meta_value = '0'; } $serialized_meta_value = maybe_serialize( $meta_value ); $meta_exists = gform_get_meta( $entry_id, $meta_key ) !== false; if ( $meta_exists ) { $wpdb->update( $table_name, array( 'meta_value' => $serialized_meta_value ), array( 'lead_id' => $entry_id, 'meta_key' => $meta_key ), array( '%s' ), array( '%d', '%s' ) ); } else { if ( empty( $form_id ) ) { $lead_table_name = RGFormsModel::get_lead_table_name(); $form_id = $wpdb->get_var( $wpdb->prepare( "SELECT form_id from $lead_table_name WHERE id=%d", $entry_id ) ); } else { $form_id = intval( $form_id ); } $wpdb->insert( $table_name, array( 'form_id' => $form_id, 'lead_id' => $entry_id, 'meta_key' => $meta_key, 'meta_value' => $serialized_meta_value ), array( '%d', '%d', '%s', '%s' ) ); } //updates cache $cache_key = $entry_id . '_' . $meta_key; if ( array_key_exists( $cache_key, $_gform_lead_meta ) ) { $_gform_lead_meta[ $cache_key ] = $meta_value; } } /** * Add metadata associated with an entry * * Data will be serialized; no sanitation is necessary. * * @param int $entry_id The ID of the entry where metadata is to be added * @param string $meta_key The key for the meta data to be stored * @param mixed $meta_value The data to be stored for the entry * @param int|null $form_id The form ID of the entry (optional, saves extra query if passed when creating the metadata) */ function gform_add_meta( $entry_id, $meta_key, $meta_value, $form_id = null ) { global $wpdb, $_gform_lead_meta; $table_name = RGFormsModel::get_lead_meta_table_name(); if ( false === $meta_value ) { $meta_value = '0'; } $serialized_meta_value = maybe_serialize( $meta_value ); if ( empty( $form_id ) ) { $lead_table_name = RGFormsModel::get_lead_table_name(); $form_id = $wpdb->get_var( $wpdb->prepare( "SELECT form_id from $lead_table_name WHERE id=%d", $entry_id ) ); } else { $form_id = intval( $form_id ); } $wpdb->insert( $table_name, array( 'form_id' => $form_id, 'lead_id' => $entry_id, 'meta_key' => $meta_key, 'meta_value' => $serialized_meta_value ), array( '%d', '%d', '%s', '%s' ) ); } function gform_delete_meta( $entry_id, $meta_key = '' ) { global $wpdb, $_gform_lead_meta; $table_name = RGFormsModel::get_lead_meta_table_name(); $meta_filter = empty( $meta_key ) ? '' : $wpdb->prepare( 'AND meta_key=%s', $meta_key ); $wpdb->query( $wpdb->prepare( "DELETE FROM {$table_name} WHERE lead_id=%d {$meta_filter}", $entry_id ) ); //clears cache. $_gform_lead_meta = array(); }