IP : 3.133.100.195Hostname : server86.web-hosting.comKernel : Linux server86.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64Disable Function : None :) OS : Linux
PATH:
/
home/
servlmvm/
public_html/
wp-content/
plugins/
gravityforms/
fonts/
../
forms_model.php/
/
<?php
if ( ! class_exists( 'GFForms' ) ) { die(); }
use Gravity_Forms\Gravity_Forms\License; use Gravity_Forms\Gravity_Forms\Query\Batch_Processing\GF_Entry_Meta_Batch_Processor; use Gravity_Forms\Gravity_Forms\Query\Batch_Processing\GF_Batch_Operations_Service_Provider;
/** * Class GFFormsModel * * Handles database calls and formatting of stored data regarding forms */ class GFFormsModel {
/** * Stores the values containing and uploaded files for later access * * @since Unknwon * @access public * * @var array Defaults to an empty array. */ public static $uploaded_files = array(); /** * Stores unique form IDs found. * * @since Unknown * @access public * * @var array Defaults to an empty array. */ public static $unique_ids = array();
/** * An in-memory cache for the form meta for the current blog. * * Use "{Blog ID}_{Form ID}" as the key. * * @since Unknown * @access private * @example $_current_forms['1_2'] * * @var array $_current_forms */ private static $_current_forms = array();
/** * An in-memory cache of form properties using "{Blog ID}_{Form ID}" as the key. * * @since 2.7 * * @var array $_current_forms_props */ private static $_current_forms_props = array();
/** * The entry data for the current site. *. * @access private * * @var null Defaults to null. */ private static $_current_lead = null; private static $_batch_field_updates = array(); private static $_batch_field_inserts = array(); private static $_batch_field_deletes = array();
/** * Returns the current database version. * * @since 2.2 * * @return string */ public static function get_database_version() { static $db_version = array(); $blog_id = get_current_blog_id(); if ( empty( $db_version[ $blog_id ] ) ) { $db_version[ $blog_id ] = get_option( 'gf_db_version' ); }
return $db_version[ $blog_id ]; }
/** * Flushes the data stored within GFFormsModel::$_current_forms. * * @since Unknown * @access public * * @uses GFFormsModel::$_current_forms * * @return void */ public static function flush_current_forms() { self::$_current_forms = array(); self::$_current_forms_props = array(); self::flush_confirmations(); }
/** * Flushes the data stored within GFFormsModel::$_current_lead. * * @since Unknown * @access public * * @uses GFFormsModel::$_current_lead * * @return void */ public static function flush_current_lead() { self::$_current_lead = null; }
/** * Removes the cached properties, meta, and confirmations for a specific form. * * @since 2.6 * * @var string $key The cache key. * * @return void */ public static function flush_current_form( $key ) { unset( self::$_current_forms[ $key ], self::$_current_forms_props[ $key ], self::$_confirmations[ $key ] ); }
/** * Flushes the data stored within GFFormsModel::$_confirmations * * @since Unknown * @access public * * @uses GFFormsModel::$_confirmations * * @return void */ public static function flush_confirmations() { self::$_confirmations = array(); }
/** * Gets the form table name, including the site's database prefix. * * @since Unknown * @access public * @global $wpdb * * @return string The form table name. */ public static function get_form_table_name() { global $wpdb;
/** * Gets the form meta table, including the site's database prefix. * * @since Unknown * @access public * @global $wpdb * * @return string The form meta table. */ public static function get_meta_table_name() { global $wpdb;
/** * Gets the form view table name, including the site's database prefix. * * @since Unknown * @access public * @global $wpdb * * @return string The form view table name. */ public static function get_form_view_table_name() { global $wpdb;
/** * Gets the form revisions table name, including the site's database prefix. * * @since 2.4-dev * * @return string The form revisions table name. */ public static function get_form_revisions_table_name() { global $wpdb;
return $wpdb->prefix . 'gf_form_revisions'; }
/** * Gets the lead (entries) table name, including the site's database prefix. * * @since Unknown * @access public * @global $wpdb * * @return string The lead (entry) table name. */ public static function get_lead_table_name() { return GF_Forms_Model_Legacy::get_lead_table_name(); }
/** * Gets the lead (entry) meta table name, including the site's database prefix. * * @since Unknown * @access public * @global $wpdb * * @return string The lead (entry) meta table name. */ public static function get_lead_meta_table_name() { return GF_Forms_Model_Legacy::get_lead_meta_table_name(); }
/** * Gets the lead (entry) notes table name, including the site's database prefix. * * @since Unknown * @access public * @global $wpdb * * @return string The lead (entry) notes table name. */ public static function get_lead_notes_table_name() { return GF_Forms_Model_Legacy::get_lead_notes_table_name(); }
/** * Gets the lead (entry) details table name, including the site's database prefix. * * @since Unknown * @access public * @global $wpdb * * @return string The lead (entry) details table name. */ public static function get_lead_details_table_name() { return GF_Forms_Model_Legacy::get_lead_details_table_name(); }
/** * Gets the lead (entry) details long table name, including the site's database prefix. * * @since Unknown * @access public * @global $wpdb * * @return string The lead (entry) details long table name. */ public static function get_lead_details_long_table_name() { return GF_Forms_Model_Legacy::get_lead_details_long_table_name(); }
/** * Gets the lead (entry) view table name, including the site's database prefix. * * @since Unknown * @access public * @global $wpdb * * @return string The lead (entry) view table name. */ public static function get_lead_view_name() { return GF_Forms_Model_Legacy::get_lead_view_name(); }
/** * Gets the incomplete submissions table name, including the site's database prefix. * * @since Unknown * @access public * @global $wpdb * * @return string he incomplete submissions table name. */ public static function get_incomplete_submissions_table_name() { return GF_Forms_Model_Legacy::get_incomplete_submissions_table_name(); }
/** * Gets the entry table name, including the site's database prefix * * @access public * @static * @global $wpdb * * @return string The entry table name */ public static function get_entry_table_name() { global $wpdb;
return $wpdb->prefix . 'gf_entry'; }
/** * Gets the entry meta table name, including the site's database prefix * * @access public * @static * @global $wpdb * * @return string The entry meta table name */ public static function get_entry_meta_table_name() { global $wpdb;
return $wpdb->prefix . 'gf_entry_meta'; }
/** * Gets the lead (entry) notes table name, including the site's database prefix * * @access public * @static * @global $wpdb * * @return string The lead (entry) notes table name */ public static function get_entry_notes_table_name() { global $wpdb;
return $wpdb->prefix . 'gf_entry_notes'; }
/** * Gets the draft submissions table name, including the site's database prefix * * @access public * @static * @global $wpdb * * @return string The draft submissions table name */ public static function get_draft_submissions_table_name() { global $wpdb;
return $wpdb->prefix . 'gf_draft_submissions'; }
/** * Gets the REST API Key table name, including the site's database prefix * * @access public * @static * @global $wpdb * * @return string The REST API Keys submissions table name */ public static function get_rest_api_keys_table_name() { global $wpdb;
return $wpdb->prefix . 'gf_rest_api_keys'; }
/** * Returns the name of the table where add-on feeds are stored, including the site's database prefix. * * @since 2.4.24 * * @return string */ public static function get_addon_feed_table_name() { global $wpdb;
return $wpdb->prefix . 'gf_addon_feed'; }
/** * Gets all forms. * * @since Unknown * @access public * @global $wpdb * * @uses GFFormsModel::get_form_table_name() * @uses GFFormsModel::get_form_db_columns() * @uses GFFormsModel::get_entry_count_per_form() * @uses GFFormsModel::get_view_count_per_form() * * @param bool $is_active Optional. Defines if inactive forms should be displayed. Defaults to null. * @param string $sort_column Optional. The column to be used for sorting the forms. Defaults to 'title'. * @param string $sort_dir Optional. Defines the direction that sorting should occur. Defaults to 'ASC' (ascending). Use 'DESC' for descending. * @param bool $is_trash Optional. Defines if forms within the trash should be displayed. Defaults to false. * * @return array $forms All forms found. */ public static function get_forms( $is_active = null, $sort_column = 'title', $sort_dir = 'ASC', $is_trash = false ) { global $wpdb; $form_table_name = esc_sql( self::get_form_table_name() );
/** * Searches form titles based on query. * * @access public * @static * @global $wpdb * @see GFFormsModel::get_form_table_name * @see GFFormsModel::get_form_db_columns * @see GFFormsModel::get_entry_count_per_form * @see GFFormsModel::get_view_count_per_form * * @param string $query Optional. The query to search. * @param bool $is_active Optional. Defines if inactive forms should be displayed. Defaults to null. * @param string $sort_column Optional. The column to be used for sorting the forms. Defaults to 'title'. * @param string $sort_dir Optional. Defines the direction that sorting should occur. Defaults to 'ASC' (ascending). Use 'DESC' for descending. * @param bool $is_trash Optional. Defines if forms within the trash should be displayed. Defaults to false. * * @return array $forms All forms found. */ public static function search_forms( $query = '', $is_active = null, $sort_column = 'title', $sort_dir = 'ASC', $is_trash = false ) { global $wpdb; $form_table_name = esc_sql( self::get_form_table_name() );
// All of the pieces of this SQL statement have already gone through $wpdb->prepare, so we don't prepare it again here. $sql = "SELECT f.id, f.title, f.date_created, f.is_active, 0 as entry_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 $entry_count = self::get_entry_count_per_form();
//Getting view count per form $view_count = self::get_view_count_per_form();
//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; } }
/** * Gets the number of entries per form. * * First attempts to read from cache. If unavailable, gets the entry count, caches it, and returns it. * * @since Unknown * @access public * @global $wpdb * * @uses GFFormsModel::get_lead_table_name() * @uses GFCache::get() * @uses GFCache::set() * * @return array $entry_count Array of forms, containing the form ID and the entry count */ public static function get_entry_count_per_form() {
global $wpdb; $entry_table_name = esc_sql( self::get_entry_table_name() );
$entry_count = GFCache::get( 'get_entry_count_per_form' ); if ( empty( $entry_count ) ) { //Getting entry count per form $sql = $wpdb->prepare( "SELECT form_id, count(id) as entry_count FROM $entry_table_name l WHERE status=%s GROUP BY form_id", 'active' ); $entry_count = $wpdb->get_results( $sql );
/** * Gets the number of views per form * * Checks the cache first. If not there, gets the count from the database, stores it in the cache, and returns it. * * @since Unknown * @access public * @global $wpdb * * @uses GFFormsModel::get_form_view_table_name() * @uses GFCache::get() * @uses GFCache::set() * * @return array $view_count Array of forms, containing the form ID and the view count */ public static function get_view_count_per_form() { global $wpdb; $view_table_name = esc_sql( self::get_form_view_table_name() );
$view_count = GFCache::get( 'get_view_count_per_form' ); if ( empty( $view_count ) ){ $sql = "SELECT form_id, sum(count) as view_count FROM $view_table_name GROUP BY form_id"; $view_count = $wpdb->get_results( $sql );
/** * Returns the form database columns. * * @since Unknown * @access public * * @return array The column IDs */ public static function get_form_db_columns() { return array( 'id', 'title', 'date_created', 'date_updated', 'is_active', 'is_trash' ); }
/** * Gets the payment totals for a particular form ID. * * @since Unknown * @access public * @global $wpdb * * @uses GFFormsModel::get_lead_table_name() * * @param int $form_id The form ID to get payment totals for. * * @return array $totals The payment totals found. */ public static function get_form_payment_totals( $form_id ) { global $wpdb; $entry_table_name = version_compare( self::get_database_version(), '2.3-dev-1', '<' ) ? self::get_lead_table_name() : self::get_entry_table_name();
$sql = $wpdb->prepare( " SELECT sum(payment_amount) revenue, count(l.id) orders FROM $entry_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 $entry_table_name WHERE form_id=%d AND payment_status='Active'", $form_id ) );
if ( empty( $active ) ) { $active = 0; }
$totals['active'] = $active;
return $totals; }
/** * Gets the total, unread, starred, spam, and trashed entry counts. * * @since Unknown * @access public * @global $wpdb * * @uses GFFormsModel::get_lead_table_name() * @uses GFFormsModel::get_lead_details_table_name() * * @param int $form_id The ID of the form to check. * * @return array $results[0] The form counts. */ public static function get_form_counts( $form_id ) {
$sql = $wpdb->prepare( "SELECT (SELECT count(DISTINCT(l.id)) FROM $entry_table_name l WHERE l.form_id=%d AND l.status='active') as total, (SELECT count(DISTINCT(l.id)) FROM $entry_table_name l WHERE l.is_read=0 AND l.status='active' AND l.form_id=%d) as unread, (SELECT count(DISTINCT(l.id)) FROM $entry_table_name l WHERE l.is_starred=1 AND l.status='active' AND l.form_id=%d) as starred, (SELECT count(DISTINCT(l.id)) FROM $entry_table_name l WHERE l.status='spam' AND l.form_id=%d) as spam, (SELECT count(DISTINCT(l.id)) FROM $entry_table_name l WHERE l.status='trash' AND l.form_id=%d) as trash", $form_id, $form_id, $form_id, $form_id, $form_id );
/** * Gets the form summary for all forms. * * @since Unknown * @access public * @global $wpdb * * @uses GFFormsModel::get_form_table_name() * @uses GFFormsModel::get_lead_table_name() * * @return array $forms Contains the form summary for all forms. */ public static function get_form_summary() { global $wpdb; $form_table_name = esc_sql( self::get_form_table_name() ); $entry_table_name = version_compare( self::get_database_version(), '2.3-dev-1', '<' ) ? esc_sql( self::get_lead_table_name() ) : esc_sql( self::get_entry_table_name() );
$sql = $wpdb->prepare( "SELECT l.form_id, count(l.id) as unread_count FROM $entry_table_name l WHERE is_read=%d AND status=%s GROUP BY form_id", 0, 'active' );
// Getting number of unread and total leads for all forms $unread_results = $wpdb->get_results( $sql, ARRAY_A );
$sql = $wpdb->prepare( "SELECT l.form_id, max(l.date_created) as last_entry_date, count(l.id) as total_entries FROM $entry_table_name l WHERE status=%s GROUP BY form_id", 'active' );
$sql = $wpdb->prepare( "SELECT id, title, is_trash, '' as last_entry_date, 0 as unread_count FROM $form_table_name WHERE is_active=%d ORDER BY title", 1 );
/** * Modifies the summary of all forms, includes unread and total entry counts. * * @since 2.4.16 * * @param array $forms Form summary. */ $forms = apply_filters( 'gform_form_summary', $forms );
return $forms; }
/** * Gets the total, active, inactive, and trashed form counts. * * @since Unknown * @access public * @global $wpdb * * @uses GFFormsModel::get_form_table_name() * * @return array The form counts. */ 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 " );
/** * Gets the form ID based on the form title. * * @since Unknown * @access public * * @uses GFFormsModel::get_forms() * * @param string $form_title The form title to search for. * * @return int The form ID. Returns 0 if not found. */ 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 absint( $form->id ); } }
return 0; }
/** * Returns the cache key for the specified form. * * @since 2.7 * * @param int $form_id The form ID. * * @return string */ public static function get_form_cache_key( $form_id ) { return get_current_blog_id() . '_' . $form_id; }
/** * Returns an object containing the properties of the specified form or false if the form doesn't exist. * * @since Unknown * @since 2.7 Updated to cache the result. * * @param int $form_id The ID of the form to get. * @param bool $allow_trash Optional. Set to true to allow trashed results. Defaults to false. * * @return bool|object */ public static function get_form( $form_id, $allow_trash = false ) { $form_id = absint( $form_id ); if ( empty( $form_id ) ) { return false; }
if ( is_object( $form_props ) ) { if ( ! $allow_trash && $form_props->is_trash ) { return false; }
return $form_props; }
global $wpdb; $table_name = self::get_form_table_name(); $trash_clause = $allow_trash ? '' : 'AND is_trash = 0'; $result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id=%d {$trash_clause}", $form_id ) );
if ( empty( $result ) ) { return false; }
self::$_current_forms_props[ $key ] = $result;
return $result; }
/** * Converts a serialized string or JSON for access in PHP. * * @since Unknown * @access public * * @param string $string The string to convert. * * @return mixed */ public static function unserialize( $string ) { if ( empty( $string ) ) { return null; } elseif ( is_serialized( $string ) ) { $obj = @unserialize( $string ); } else { $obj = json_decode( $string, true ); }
return $obj; }
/** * Gets the form meta based on the form ID. * * @since Unknown * @access public * @global $wpdb * * @uses GFFormsModel::get_meta_table_name() * @uses GFFormsModel::unserialize() * @uses GFFormsModel::convert_field_objects() * @uses GFFormsModel::load_notifications_from_legacy() * @uses GFFormsModel::$_current_forms * * @param int $form_id The form ID. * * @return array|null $form Form object if found. Null if not found. */ public static function get_form_meta( $form_id ) { global $wpdb;
$key = self::get_form_cache_key( $form_id ); // Return cached version if form meta has been previously retrieved for this form if ( isset( self::$_current_forms[ $key ] ) ) { return self::$_current_forms[ $key ]; }
$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( rgar( $form_row, 'display_meta' ) );
if ( ! $form ) { return null; }
// Ensure the fields property is in the correct format, an associative array will cause warnings and js errors in the form editor. $form['fields'] = is_array( rgar( $form, 'fields' ) ) ? array_values( $form['fields'] ) : array();
// 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 );
// Ensure the next field ID is set correctly. $form['nextFieldId'] = self::get_next_field_id( $form['fields'] );
/** * Filters the Form object after the form meta is obtained * * @param array $form The Form object */ $form = gf_apply_filters( array( 'gform_form_post_get_meta', $form_id ), $form );
// Cached form meta for cheaper retrieval on subsequent requests self::$_current_forms[ $key ] = $form;
return $form; }
/** * Recursively checks the highest ID for all the fields in the form and then returns the highest ID + 1. * * @since 2.4.6.12 * * @param GF_Field[] $fields * @param int $next_field_id * * @return int */ public static function get_next_field_id( $fields, $next_field_id = 1 ) {
/** * Converts all field objects in a form, based on field type. * * @since Unknown * @access public * * @uses GF_Field_CreditCard::maybe_upgrade_inputs() * * @param array $form The Form object. * * @return array $form The Form object after the field objects are converted. */ public static function convert_field_objects( $form ) { $page_number = 1; $form['fields'] = is_array( rgar( $form, 'fields' ) ) ? array_values( $form['fields'] ) : array();
// Populate required cssClass property with empty string if not set to avoid JS errors when rendering. if ( ! isset( $field->cssClass ) ) { $field->cssClass = ''; }
$field->post_convert_field(); }
return $form; }
/** * Converts the sub fields to field objects. * * @since 2.4 * * @param GF_Field $field The repeater field to be converted to objects. * @param int $form_id The current form ID. * @param int $page_number The page number the parent field is located on. * @param int $nesting_level The level at which a repeater field is nested. */ private static function convert_sub_field_objects( &$field, $form_id, $page_number, $nesting_level = 0 ) { $field->nestingLevel = $nesting_level; foreach ( $field->fields as &$field ) { $field = GF_Fields::create( $field ); $field->formId = $form_id; $field->pageNumber = $page_number; $field->post_convert_field(); if ( is_array( $field['fields'] ) ) { $new_nesting_level = $nesting_level + 1; self::convert_sub_field_objects( $field, $form_id, $page_number, $new_nesting_level ); } } }
/** * Gets the form meta for multiple forms based on an array for form IDs. * * @since Unknown * @access public * @global $wpdb * * @uses GFFormsModel::get_form_table_name() * @uses GFFormsModel::get_meta_table_name() * @uses GFFormsModel::unserialize() * @uses GFFormsModel::convert_field_objects() * * @param array $ids Array of form IDs. * * @return array $results */ 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();
$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;
}
/** * Converts current notification structure to legacy. * * @since Unknown * @access private * * @param array $form The Form object. * * @return array $form The Form object. */ private static function load_notifications_to_legacy( $form ) { if ( ! is_array( rgar( $form, 'notifications' ) ) ) { return $form; }
//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'] = esc_html__( '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'] = esc_html__( '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; }
/** * Converts a form property to the merge tag format. * * @since Unknown * @access private * * @uses GFFormsModel::get_field_merge_tag() * * @param array $form The Form object. * @param array $array Array of properties to search through. * @param string $target_property The property to move the value to. * @param string $source_property The property to search for. * * @return array $array The array that was searched through. */ 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; }
/** * Gets a formatted merge tag for a field. * * @since Unknown * @access private * * @uses GFFormsModel::get_field() * @uses GFCommon::get_label() * * @param array $form The Form object. * @param int $field_id The field ID. * * @return string|false The merge tag if found. False if not found. */ private static function get_field_merge_tag( $form, $field_id ) { $field = self::get_field( $form, $field_id ); if ( ! $field ) { return false; }
/** * Gets the column info for the entry listing page. * * @since Unknown * @access public * @global $wpdb * * @uses GFFormsModel::get_meta_table_name() * * @param int $form_id The ID of the form that entries are coming from. * * @return mixed */ 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;
/** * Updates the form is_active property in the database. * * @since unknown * @since 2.7 Updated to clear the form from the cache. * * @param int $form_id The ID of the form to be updated. * @param int|bool $is_active Indicates if the form is being set as active. * * @return void */ 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 ) {
/** * Fires after an inactive form gets marked as active * * @since 1.9 * * @param int $form_id The Form ID used to specify which form to activate */ do_action( 'gform_post_form_activated', $form_id ); } else {
/** * Fires after an active form gets marked as inactive * * @since 1.9 * * @param int $form_id The Form ID used to specify which form to activate */ do_action( 'gform_post_form_deactivated', $form_id ); }
if ( (bool) $is_active ) { /** * Fires before a notification is activated * * @param int $form['notifications'][ $notification_id ] The ID of the notification that was activated * @param array $form The Form object */ do_action( 'gform_pre_notification_activated', $form['notifications'][ $notification_id ], $form ); } else { /** * Fires before a notification is deactivated * * @param int $form['notifications'][ $notification_id ] The ID of the notification that was deactivated * @param array $form The Form object */ do_action( 'gform_pre_notification_deactivated', $form['notifications'][ $notification_id ], $form ); }
//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' ) ) ) {
// If property is trash, log user login if ( $property_name == 'status' && $property_value == 'trash' && ! empty( $current_user->user_login ) ) { GFCommon::log_debug( __METHOD__ . "(): User ID {$current_user->ID} requested moving of entry #{$lead_id} to trash." ); }
// 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( isset( $form ) ? $form : GFAPI::get_form( $lead['form_id'] ), $lead ); }
/** * Fired after an entry property is updated * * @param string $property_name Used within the action string. Defines the property that fires the action. * * @param int $lead_id The Entry ID * @param string $property_value The new value of the property that was updated * @param string $previous_value The previous property value before the update */ do_action( "gform_update_{$property_name}", $lead_id, $property_value, $previous_value );
/** * Fired after an entry property is updated. * * @param int $lead_id The Entry ID. * @param string $property_name The property that was updated. * @param string $property_value The new value of the property that was updated. * @param string $previous_value The previous property value before the update. * * @since 2.3.3.9 */ do_action( "gform_post_update_entry_property", $lead_id, $property_name, $property_value, $previous_value ); gf_feed_processor()->save()->dispatch(); } }
GFCommon::log_debug( __METHOD__ . "(): Deleting entries for form #{$form_id}." );
/** * Fires when you delete entries for a specific form * * @param int $form_id The form ID to specify from which form to delete entries * @param string $status Allows you to set the form entries to a deleted status */ do_action( 'gform_delete_entries', $form_id, $status );
// Get status filter. $status_filter = empty( $status ) ? '' : $wpdb->prepare( 'AND status=%s', $status );
// Get entry IDs. $entry_ids = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM $entry_table WHERE form_id=%d {$status_filter}", $form_id ) );
// If entries were found, loop through them and run action. if ( ! empty( $entry_ids ) ) {
// Log user login for user requesting the deletion of entries if ( ! empty( $current_user->user_login ) ) { GFCommon::log_debug( __METHOD__ . "(): User ID {$current_user->ID} requested deletion of entries: " . json_encode( $entry_ids ) ); }
foreach ( $entry_ids as $entry_id ) {
/** * Fires before an entry is deleted. * * @param int $entry_id Entry ID to be deleted. */ do_action( 'gform_delete_entry', $entry_id );
/** * Fires before a lead is deleted * @param $lead_id * @deprecated Use gform_delete_entry instead * @see gform_delete_entry */ do_action( 'gform_delete_lead', $entry_id );
}
}
// Deleting uploaded files self::delete_files_by_form( $form_id, $status ); // Delete from entry notes $sql = $wpdb->prepare( " DELETE FROM $entry_notes_table WHERE entry_id IN ( SELECT id FROM $entry_table WHERE form_id=%d {$status_filter} )", $form_id ); $wpdb->query( $sql );
// Delete from entry meta $sql = $wpdb->prepare( " DELETE FROM $entry_meta_table WHERE entry_id IN ( SELECT id FROM $entry_table WHERE form_id=%d {$status_filter} )", $form_id ); $wpdb->query( $sql );
// Delete from entry $sql = $wpdb->prepare( "DELETE FROM $entry_table WHERE form_id=%d {$status_filter}", $form_id ); $wpdb->query( $sql ); }
/** * Delete the views for the specified form. * * @param int $form_id The form ID. */ public static function delete_views( $form_id ) {
if ( gf_upgrade()->get_submissions_block() ) { return new WP_Error( 'submissions_blocked', __( 'Submissions are currently blocked due to an upgrade in progress', 'gravityforms' ) ); }
global $wpdb, $current_user;
// Log user login for user requesting deletion of views if ( ! empty( $current_user->user_login ) ) { GFCommon::log_debug( __METHOD__ . "(): User ID {$current_user->ID} requested deletion of views for form #{$form_id}." ); }
//Delete form view $sql = $wpdb->prepare( "DELETE FROM $form_view_table WHERE form_id=%d", $form_id ); $wpdb->query( $sql );
/** * Fires after form views are deleted * * @param int $form_id The ID of the form that views were deleted from */ do_action( 'gform_post_form_views_deleted', $form_id ); }
public static function delete_form( $form_id ) {
if ( gf_upgrade()->get_submissions_block() ) { return new WP_Error( 'submissions_blocked', __( 'Submissions are currently blocked due to an upgrade in progress', 'gravityforms' ) ); }
global $wpdb, $current_user;
// Log user login for user requesting deletion of form if ( ! empty( $current_user->user_login ) ) { GFCommon::log_debug( __METHOD__ . "(): User ID {$current_user->ID} requested deletion of form #{$form_id}." ); }
/** * Fires before a form is deleted * * @param int $form_id The ID of the form being deleted */ do_action( 'gform_before_delete_form', $form_id );
/** * Fires after a form is deleted * * @param int $form_id The ID of the form that was deleted */ do_action( 'gform_after_delete_form', $form_id ); }
public static function trash_form( $form_id ) {
if ( gf_upgrade()->get_submissions_block() ) { return new WP_Error( 'submissions_blocked', __( 'Submissions are currently blocked due to an upgrade in progress', 'gravityforms' ) ); }
global $wpdb, $current_user; // Log user login for user moving the form to trash if ( ! empty( $current_user->user_login ) ) { GFCommon::log_debug( __METHOD__ . "(): User ID {$current_user->ID} requested moving of form #{$form_id} to trash." ); } $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 );
/** * Fires after a form is trashed * * @since 1.9 * * @param int $form_id The ID of the form that was trashed */ do_action( 'gform_post_form_trashed', $form_id );
self::update_recent_forms( $form_id, true );
return $success; }
public static function restore_form( $form_id ) {
if ( gf_upgrade()->get_submissions_block() ) { return new WP_Error( 'submissions_blocked', __( 'Submissions are currently blocked due to an upgrade in progress', 'gravityforms' ) ); }
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 );
/** * Fires after a form is restored from trash * * @since 1.9 * * @param int $form_id The ID of the form that was restored */ do_action( 'gform_post_form_restored', $form_id );
return $success; }
/** * Duplicate form. * * @access public * @static * @param int $form_id Form ID to duplicate. * * @return int|WP_Error */ public static function duplicate_form( $form_id ) {
if ( gf_upgrade()->get_submissions_block() ) { return new WP_Error( 'submissions_blocked', __( 'Submissions are currently blocked due to an upgrade in progress', 'gravityforms' ) ); }
// Get form to be duplicated. $form = self::get_form( $form_id );
// Set initial form title. $new_title = self::maybe_increment_title( $form->title );
// Create new form. $new_id = self::insert_form( $new_title );
// Copying form meta to new form. $meta = self::get_form_meta( $form_id ); $meta['title'] = $new_title; $meta['id'] = $new_id;
// Add notifications to new form. self::update_form_meta( $new_id, $meta['notifications'], 'notifications' ); unset( $meta['notifications'] );
// Add confirmations to new form. self::update_form_meta( $new_id, $meta['confirmations'], 'confirmations' ); unset( $meta['confirmations'] );
// Save form meta. self::update_form_meta( $new_id, $meta );
// Set active state. self::update_form_active( $new_id, $form->is_active );
// The gform_after_duplicate_form action is deprecated since version 1.9. Please use gform_post_form_duplicated instead
/** * Fires after a form is duplicated * * @param int $form_id The original form's ID * @param int $new_id The ID of the new, duplicated form */ do_action( 'gform_post_form_duplicated', $form_id, $new_id );
return $new_id;
}
public static function is_unique_title( $title, $form_id=0 ) { $forms = self::get_forms(); foreach ( $forms as $form ) { if ( strtolower( $form->title ) === strtolower( $title ) && (int) $form->id !== (int) $form_id ) { return false; } }
return true; }
/** * If a form title isn't unique, add a number to it to make it unique. * * @since 2.5 * * @param string $title * @param int|string $form_id * * @return string */ public static function maybe_increment_title( $title, $form_id = '' ) { // Title is unique, so we don't need to do anything to it. if ( self::is_unique_title( $title, $form_id ) ) { return $title; }
// Check for form count in form title. preg_match_all( '/(\\(([0-9])*\\))$/mi', $title, $count_exists_in_title );
// If count does not exist, set count to 1. if ( empty( $count_exists_in_title[0] ) ) {
// Set initial count. $count = 1;
} else {
// Set existing count to current count plus one. $count = (int) $count_exists_in_title[2][0] + 1;
// Add copy count to form title. $new_title = $title . " ($count)";
// If new form title is not unique, increment the count until a unique form title is created. while ( ! self::is_unique_title( $new_title, $form_id ) ) { $count++; $new_title = $title . " ($count)"; }
return $new_title; }
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.' ); gf_upgrade()->upgrade_schema(); } }
public static function insert_form( $form_title ) { global $wpdb; $form_table_name = self::get_form_table_name();
//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;
}
/** * Update form meta. * * @since 2.4 Added the form revision creation functionality. * * @param int $form_id Form id. * @param array $form_meta Form meta. * @param string $meta_name Meta name. * * @return false|int Number of rows affected/selected or false on error. */ public static function update_form_meta( $form_id, $form_meta, $meta_name = 'display_meta' ) { global $wpdb;
/** * Fires after form meta has been updated for any form * * @param mixed $form_meta The Form Meta object from the database * @param int $form_id The ID of the form data was updated * @param string $meta_name The name of the meta updated */ gf_do_action( array( 'gform_post_update_form_meta', $form_id ), $form_meta, $form_id, $meta_name );
return $result; }
/** * Create form revision if conditions met. * * @since 2.4 * * @param array $new_display_meta Form meta. * @param int $form_id Form ID. */ public static function maybe_create_form_revision( $new_display_meta, $form_id ) { global $wpdb;
// Make sure the form isn't in the cache before calling get_form_meta(). self::flush_current_form( self::get_form_cache_key( $form_id ) ); $form = self::get_form_meta( $form_id ); // check if form has consent field. if ( GFCommon::has_consent_field( $new_display_meta ) ) { $revisions_table_name = self::get_form_revisions_table_name();
// create the first revision. if ( intval( $wpdb->get_var( $wpdb->prepare( "SELECT count(0) FROM $revisions_table_name WHERE form_id=%d", $form_id ) ) ) === 0 ) { $wpdb->query( $wpdb->prepare( "INSERT INTO $revisions_table_name(form_id, display_meta, date_created) VALUES(%d, %s, utc_timestamp())", $form_id, json_encode( $new_display_meta ) ) );
/** * Get the latest revision ID from form revisions. * * @since 2.4 * * @param int $form_id Form ID. * * @return int Revision ID. */ public static function get_latest_form_revisions_id( $form_id ) { global $wpdb; $revisions_table_name = GFFormsModel::get_form_revisions_table_name(); $value = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $revisions_table_name WHERE form_id=%d ORDER BY date_created DESC, id DESC LIMIT 1", $form_id ) );
return $value; }
public static function delete_files( $lead_id, $form = null ) { $lead = self::get_lead( $lead_id );
/** * Returns an array of field types for which can uploaded files can be deleted. * * @since 2.4.6.1 * * @param array $form The current form. * * @return array */ public static function get_delete_file_field_types( $form ) { $field_types = array( 'fileupload', 'post_image' );
/** * Allows more files to be deleted * * @since 1.9.10 * * @param array $field_types Field types which contain file uploads * @param array $form The Form Object */ return gf_apply_filters( array( 'gform_field_types_delete_files', $form['id'] ), $field_types, $form ); }
/** * Deletes the uploaded files for the specified form and field. * * Note: Does not delete the file URLs from the entries, that is done by GFFormsModel::delete_field_values(). * * @since 2.4.6.1 * * @since 2.5.16 changed the query to return entry ID as well. * * @param int $form_id The current form ID. * @param int $field_id The ID of field being deleted. */ public static function delete_field_files( $form_id, $field_id ) { if ( version_compare( self::get_database_version(), '2.3-dev-1', '<' ) ) { return; }
// Update entry field value - simulate form submission. $entry_meta_table_name = self::get_entry_meta_table_name(); $sql = $wpdb->prepare( "SELECT id FROM {$entry_meta_table_name} WHERE entry_id=%d AND meta_key = %s", $entry_id, $field_id ); $entry_meta_id = $wpdb->get_var( $sql );
/** * Allow the file path to be overridden so files stored outside the /wp-content/uploads/gravity_forms/ directory can be deleted. * * @since 2.2.3.1 * * @param string $file_path The path of the file to be deleted. * @param string $url The URL of the file to be deleted. */ $file_path = apply_filters( 'gform_file_path_pre_delete_file', $file_path, $url );
/** * Fires before a field is deleted * * @param int $form_id The ID of the form that the field is being deleted from * @param int $field_id The ID of the field being deleted */ do_action( 'gform_before_delete_field', $form_id, $field_id );
// Deleting field from form meta. if ( $field->id == $field_id ) { $field_type = $field->type; unset( $form['fields'][ $i ] ); } }
// The field has already been removed from the form passed by GFFormDetail::save_form_info(), get the field from the db. if ( empty( $field_type ) && $deleted_field = self::get_field( $form_id, $field_id ) ) { $field_type = $deleted_field->type; }
// 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'] = ''; }
// Notifications/confirmations are not present in the form passed by GFFormDetail::save_form_info() but they could be present in other scenarios. $form = GFFormsModel::delete_field_from_confirmations( $form, $field_id ); $form = GFFormsModel::delete_field_from_notifications( $form, $field_id );
/** * Fires after a field is deleted * * @param int $form_id The form ID where the form was deleted * @param int $field_id The ID of the field that was deleted * */ do_action( 'gform_after_delete_field', $form_id, $field_id );
return $form; }
/** * Deletes confirmation conditional logic rules based on the deleted field. * * @since 2.4.6.1 * * @param array $form The form containing the confirmations to be processed. * @param int $field_id The ID of the field being deleted. * * @return array */ public static function delete_field_from_confirmations( $form, $field_id ) { if ( empty( $form['confirmations'] ) ) { return $form; }
/** * Deletes notification routing and conditional logic rules based on the deleted field. * * @since 2.4.6.1 * * @param array $form The form containing the notifications to be processed. * @param int $field_id The ID of the field being deleted. * * @return array */ public static function delete_field_from_notifications( $form, $field_id ) { if ( empty( $form['notifications'] ) ) { return $form; }
$save = false;
foreach ( $form['notifications'] as &$notification ) { if ( ! empty( $notification['routing'] ) ) { $dirty = false;
/** * Deletes conditional logic rules based on the deleted field. * * If no rules remain following the deletion conditional logic is disabled. * * @since 2.4.6.1 * * @param array $logic The conditional logic object to be processed. * @param int $field_id The ID of the field being deleted. * * @return null|array */ public static function delete_field_from_conditional_logic( $logic, $field_id ) { if ( empty( $logic['rules'] ) ) { return null; }
// Delete from entry meta $sql = $wpdb->prepare( "DELETE FROM $entry_meta_table WHERE form_id=%d AND meta_key = %s", $form_id, $field_id ); if ( is_numeric( $field_id ) ) { $sql .= $wpdb->prepare( " OR form_id=%d AND meta_key LIKE %s", $form_id, sprintf( '%d.%%', $field_id ) ); } $wpdb->query( $sql );
// Delete leads with no details $sql = $wpdb->prepare( " DELETE FROM $entry_table WHERE form_id=%d AND id NOT IN( SELECT DISTINCT(entry_id) FROM $entry_meta_table WHERE form_id=%d )", $form_id, $form_id ); $wpdb->query( $sql ); }
/** * Deletes a lead. * * @param $lead_id */ public static function delete_lead( $lead_id ) { self::delete_entry( $lead_id ); }
public static function delete_entry( $entry_id ) { global $wpdb, $current_user;
// Log if user requested deletion of entries if ( ! empty( $current_user->user_login ) ) { GFCommon::log_debug( __METHOD__ . "(): User ID {$current_user->ID} requested deletion of entry #{$entry_id}" ); }
/** * Fires before an entry is deleted. * * @param $entry_id */ do_action( 'gform_delete_entry', $entry_id );
/** * Fires before a lead is deleted * @param $lead_id * @deprecated Use gform_delete_entry instead * @see gform_delete_entry */ do_action( 'gform_delete_lead', $entry_id );
// Delete from entry meta $sql = $wpdb->prepare( "DELETE FROM $entry_meta_table_name WHERE entry_id=%d", $entry_id ); $wpdb->query( $sql );
// Delete from lead notes $sql = $wpdb->prepare( "DELETE FROM $entry_notes_table WHERE entry_id=%d", $entry_id ); $wpdb->query( $sql );
// Delete from entry table $sql = $wpdb->prepare( "DELETE FROM $entry_table WHERE id=%d", $entry_id ); $wpdb->query( $sql ); }
/** * Adds a note. * * @since 2.4.18 Return statement added. * @since unknown * * @param int $entry_id ID of the entry to add the note to. * @param int $user_id ID of the user who created the note. * @param string $user_name Name of the user who created the note. * @param string $note Text of the note. * @param string $note_type Note type. * @param null $sub_type Note sub-type. * @return int ID of the new note. */ public static function add_note( $entry_id, $user_id, $user_name, $note, $note_type = 'user', $sub_type = null ) { global $wpdb;
/** * Fires after a note has been added to an entry * * @since 2.4.13 Added sub_type parameter. * @since Unknown * * @param int $wpdb->insert_id The row ID of this note in the database * @param int $entry_id The ID of the entry that the note was added to * @param int $user_id The ID of the current user adding the note * @param string $user_name The user name of the current user * @param string $note The content of the note being added * @param string $note_type The type of note being added. Defaults to 'note' * @param string $sub_type The sub-type of note being added. * */ do_action( 'gform_post_note_added', $wpdb->insert_id, $entry_id, $user_id, $user_name, $note, $note_type, $sub_type );
return $wpdb->insert_id; }
/** * Updates a note. * * @since 2.4.18 * * @param int $note_id ID of the note to update. * @param int $entry_id ID of the entry to add the note to. * @param int $user_id ID of the user who created the note. * @param string $user_name Name of the user who created the note. * @param string $date_created Date and time the note was created in SQL datetime format. * @param string $note Text of the note. * @param string $note_type Note type. * @param null $sub_type Note sub-type. * @return string */ public static function update_note( $note_id, $entry_id, $user_id, $user_name, $date_created, $note, $note_type = 'user', $sub_type = null ) { global $wpdb;
/** * Deletes a note. * * @since 2.4.18 Return statement added. * @since unknown * * @param $note_id int ID of the note to delete. * @return bool|int Success or failure. */ public static function delete_note( $note_id ) { global $wpdb;
$lead_id = $wpdb->get_var( $wpdb->prepare( "SELECT entry_id FROM $table_name WHERE id = %d", $note_id ) );
/** * Fires before a note is deleted * * @param int $note_id The current note ID * @param int $lead_id The current lead ID */ do_action( 'gform_pre_note_deleted', $note_id, $lead_id );
$sql = $wpdb->prepare( "DELETE FROM $table_name WHERE id=%d", $note_id ); $result = $wpdb->query( $sql );
return $result; }
public static function delete_notes( $notes ) { if ( ! is_array( $notes ) ) { return; }
/** * Add note to entry containing the notification sending result * * @since 2.4.14 * * @param integer $entry_id Id number for entry being processed. * @param string|boolean $result The result returned by wp_mail(). * @param array $notification The notification properties. * @param string $error_info Additional details for notifications with error. * @param array $email Array containing email details. * @param array $note_args Array containing text, type and subtype for the note. */ public static function add_notification_note( $entry_id, $result, $notification, $error_info = '', $email = array(), $note_args = array() ) {
// Skip if no entry id (e.g. Save and Continue notifications). if ( empty( $entry_id ) ) { return; }
// If $note_args is empty, use default arguments for Gravity Forms core notifications. if ( empty( $note_args ) ) { if ( $result === true ) {
$note_args['type'] = 'notification'; $note_args['subtype'] = 'success'; $note_args['text'] = esc_html__( 'WordPress successfully passed the notification email to the sending server.', 'gravityforms' );
} elseif ( $result === false ) {
$note_args['type'] = 'notification'; $note_args['subtype'] = 'error'; $note_args['text'] = esc_html__( 'WordPress was unable to send the notification email.', 'gravityforms' );
/** * Allow customization of the Sending Result Note. * * @param array $note_args Array containing text, type and subtype for the note. * @param int $entry_id Id number for entry being processed. * @param bool $result The result returned by wp_mail(). * @param array $notification The notification properties. * @param string $error_info Additional details for notifications with error. * @param array $email Array containing email details. */ $note_args = apply_filters( 'gform_notification_note', $note_args, $entry_id, $result, $notification, $error_info, $email );
if ( ! empty( $note_args['text'] ) ) { // translators: Notification name followed by its ID. e.g. Admin Notification (ID: 5d4c0a2a37204). self::add_note( $entry_id, 0, sprintf( esc_html__( '%1$s (ID: %2$s)', 'gravityforms' ), $notification['name'], $notification['id'] ), $note_args['text'], $note_args['type'], $note_args['subtype'] ); }
}
/** * Gets the IP to be used within the entry. * * @since 2.2 Using $_SERVER['REMOTE_ADDR']. * * @return string The IP to be stored in the entry. */ public static function get_ip() {
$ip = rgar( $_SERVER, 'REMOTE_ADDR' );
/** * Allows the IP address of the client to be modified. * * Use this filter if the server is behind a proxy. * * @since 2.2 * @example https://docs.gravityforms.com/gform_ip_address/ * * @param string $ip The IP being used. */ $ip = apply_filters( 'gform_ip_address', $ip );
// HTTP_X_FORWARDED_FOR can return a comma separated list of IPs; use the first one $ips = explode( ',', $ip );
return $ips[0]; }
public static function save_lead( $form, &$entry ) { self::save_entry( $form, $entry ); }
/** * Save Entry to database. * * @since 2.4.8.13 Updated created_by property to save as an empty value when undefined. * @since Unknown * * @param array $form Form object. * @param array $entry Entry object. */ public static function save_entry( $form, &$entry ) { global $wpdb, $current_user;
// Log user login for user updating the entry if ( ! $is_new_lead && ! empty( $entry['id'] ) && ! empty( $current_user->ID ) ) { GFCommon::log_debug( __METHOD__ . "(): User ID {$current_user->ID} requested update of entry #{$entry['id']}." ); }
if ( ! $is_new_lead && ! self::entry_exists( rgar( $entry, 'id' ) ) ) { // Force a new entry to be saved when an entry does not exist for the supplied id. $entry = array(); $is_new_lead = true; GFCommon::log_debug( __METHOD__ . '(): Existing entry not found. Saving new entry instead.' ); }
$die_message = esc_html__( 'An error prevented the entry for this form submission being saved. Please contact support.', 'gravityforms' );
/** * Allow the currency code to be overridden. * * @param string $currency The three character ISO currency code to be stored in the entry. Default is value returned by GFCommon::get_currency() * @param array $form The form currently being processed. * */ $currency = gf_apply_filters( array( 'gform_currency_pre_save_entry', $form['id'] ), GFCommon::get_currency(), $form );
GFCommon::log_debug( __METHOD__ . "(): Entry record created in the database. ID: {$lead_id}." ); } else { GFCommon::log_debug( __METHOD__ . "(): Updating existing entry. ID: {$entry['id']}." );
// Ensures the entry being updated contains all the current properties and registered meta. self::add_properties_to_entry( $entry ); self::add_meta_to_entry( $entry );
// ignore the honeypot field if ( $field->type == 'honeypot' ) { continue; }
//Ignore fields that are marked as display only if ( $field->displayOnly ) { continue; }
// Ignore pricing fields in the entry detail if ( $is_entry_detail && GFCommon::is_pricing_field( $field->type ) ) { continue; }
// Process total field after all fields have been saved if ( $field->type == 'total' ) { $total_fields[] = $field; continue; }
/** * Specify whether to fetch values from the $_POST when evaluating a field's conditional logic. Defaults to true * for new entries and false for existing entries. * * @since 2.3.1.11 * * @param bool $read_value_from_post Should value be fetched from $_POST? * @param array $form The current form object. * @param array $entry The current entry object. */ $read_value_from_post = gf_apply_filters( array( 'gform_use_post_value_for_conditional_logic_save_entry', $form['id'] ), $is_new_lead || ! isset( $entry[ 'date_created' ] ), $form, $entry );
// Only save fields that are not hidden (except when updating an entry) if ( $is_entry_detail || ! GFFormsModel::is_field_hidden( $form, $field, array(), $read_value_from_post ? null : $entry ) ) {
// process calculation fields after all fields have been saved (moved after the is hidden check) if ( $field->has_calculation() ) { $calculation_fields[] = $field; continue; }
if ( $is_new_lead && is_wp_error( $results['inserts'] ) ) { /* @var WP_Error $error */ $error = $results['inserts']; GFCommon::log_error( __METHOD__ . '(): Error while saving calculation field values for new entry. ' . $error->get_error_message() ); self::add_note( $entry['id'], 0, 'Gravity Forms', sprintf( esc_html__( 'Error while saving calculation field values: %s', 'gravityforms' ), $error->get_error_message() ), 'save_entry', 'error' ); wp_die( $die_message ); }
self::refresh_product_cache( $form, $entry ); }
//saving total field as the last field of the form. if ( ! empty( $total_fields ) ) { GFFormsModel::begin_batch_field_operations(); foreach ( $total_fields as $total_field ) { self::save_input( $form, $total_field, $entry, $current_fields, $total_field->id ); } $results = GFFormsModel::commit_batch_field_operations();
if ( $is_new_lead && is_wp_error( $results['inserts'] ) ) { /* @var WP_Error $error */ $error = $results['inserts']; GFCommon::log_error( __METHOD__ . '(): Error while saving total field values for new entry. ' . $error->get_error_message() ); self::add_note( $entry['id'], 0, 'Gravity Forms', sprintf( esc_html__( 'Error while saving total field values: %s', 'gravityforms' ), $error->get_error_message() ), 'save_entry', 'error' ); wp_die( $die_message ); } }
/** * Gets the extra meta data a field wants to save to the entry and updates the entry meta with the retrieved data. * * This method depends on batch operations, so begin_batch_entry_meta_operations should be called before this method is called * and commit_batch_entry_meta_operations should be called after. * * @since 2.5.16 * * @param $field * @param $form * @param $entry */ public static function save_extra_field_meta( $field, $form, $entry ) {
/** * Creates a new instance of the entry meta batch operations handler if required and returns it. * * @since 2.5.16 * * @return GF_Entry_Meta_Batch_Processor */ public static function get_entry_meta_batch_processor() { if ( is_null( self::$entry_meta_batch_processor ) ) { $processor = GFForms::get_service_container()->get( GF_Batch_Operations_Service_Provider::ENTRY_META_BATCH_PROCESSOR ); self::$entry_meta_batch_processor = $processor; }
return self::$entry_meta_batch_processor; }
/** * Populates the supplied entry with missing properties. * * @since 2.4.5.8 * * @param array $entry The partial or complete entry currently being updated. */ public static function add_properties_to_entry( &$entry ) { if ( empty( $entry['id'] ) ) { return; }
global $wpdb; $entry_table = GFFormsModel::get_entry_table_name(); $sql = $wpdb->prepare( "SELECT * FROM $entry_table WHERE id=%d", $entry['id'] ); $properties = $wpdb->get_row( $sql, ARRAY_A );
/** * Allow the currency code to be overridden. * * @param string $currency The three character ISO currency code to be stored in the entry. Default is value returned by GFCommon::get_currency() * @param array $form The form currently being processed. * */ $lead['currency'] = gf_apply_filters( array( 'gform_currency_pre_save_entry', $form_id ), GFCommon::get_currency(), $form );
// 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 ); } }
GFCommon::log_debug( __METHOD__ . sprintf( '(): Draft entry created for form (#%d) in %F seconds.', $form_id, GFCommon::timer_end( __METHOD__ ) ) );
return $lead; }
public static function get_prepared_input_value( $form, $field, $lead, $input_id ) {
if ( ! empty( $value ) ) { $value = json_encode( $value ); // Encode the array of temp URLs as JSON string } else { // If no files were uploaded, set the value to an empty string for backwards compatibility $value = ''; }
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 );
/** * 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( $lead ) && isset( $lead['id'] ) ) { // Make sure that we cache field visiblity on a per-entry basis // https://github.com/gravityview/GravityView/issues/1307 $cache_key = $cache_key . '_' . $lead['id']; }
//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'; }
/*** * Determines if the submit button was supposed to be hidden by conditional logic. This function helps ensure that * the form doesn't get submitted when the submit button is hidden by conditional logic. * * @param $form The Form object * * @return bool Returns true if the submit button is hidden by conditional logic, false otherwise. */ public static function is_submit_button_hidden( $form ) {
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; }
/** * Determines if the field value matches the conditional logic rule value. * * @param mixed $field_value The field value to be checked. * @param mixed $target_value The conditional logic rule value. * @param string $operation The conditional logic rule operator. * @param null|GF_Field $source_field The field the rule is based on. * @param null|array $rule The conditional logic rule properties. * @param null|array $form The current form. * * @return bool */ 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' ) ) { if ( $source_field->type == 'post_category' ) { $field_value = GFCommon::prepare_post_category_value( $field_value, $source_field, 'conditional_logic' ); } elseif ( $source_field instanceof GF_Field_MultiSelect && ! empty( $field_value ) && ! is_array( $field_value ) ) { // Convert the comma-delimited string into an array. $field_value = $source_field->to_array( $field_value ); } elseif ( $source_field->get_input_type() != 'checkbox' && is_array( $field_value ) && $source_field->id != $rule['fieldId'] && is_array( $source_field->get_entry_inputs() ) ) { // Get the specific input value from the full field value. $field_value = rgar( $field_value, $rule['fieldId'] ); } }
// If operation is Is Not, none of the values in the array can match the target value. // Except when operation is Is Not Empty. In that case, one non-empty value is enough $must_match_all = ( $operation == 'isnot' && ! rgblank( $target_value ) ) || ( $operation == 'is' && rgblank( $target_value ) ); $is_match = $must_match_all ? $match_count == count( $field_value ) : $match_count > 0;
case 'ends_with' : // If target value is a 0 set $val2 to 0 rather than the empty string it currently is to prevent false positives. if ( empty( $val2 ) ) { $val2 = '0'; }
/** * Returns the value for a field. * * @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 */ public static function get_field_value( &$field, $field_values = array(), $get_from_post = true ) {
/** * Purges expired draft submissions. * * @since 2.4 * * @param int $expiration_days * * @return false|int */ public static function purge_expired_draft_submissions( $expiration_days = 30 ) { global $wpdb;
/** * Overrides the number of days until draft submissions are purged. * * @since 1.9 * * @param int $expiration_days The number of days until expiration. Defaults to 30. */ $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 ) );
/** * Allows the query used to purge expired draft (save and continue) submissions to be overridden. * * @since 2.1.1.20 * * @param array $query The delete, from, and where arguments to be used when the query is performed. */ $query = apply_filters( 'gform_purge_expired_incomplete_submissions_query', $query );
/** * Fires after an draft submission is saved * * @since 1.9 * * @param array $submission Contains the partially submitted entry, fields, values, and files. * @param string $resume_token The unique resume token that was generated for this partial submission * @param array $form The Form object * @param array $entry The Entry object */ do_action( 'gform_incomplete_submission_post_save', $submission, $resume_token, $form, $entry );
return $result ? $resume_token : $result; }
/** * Filters the submission json string before saving. * * @since 2.4 * * @param $submission_json * @param $resume_token * @param $form * * @return string */ private static function filter_draft_submission_pre_save( $submission_json, $resume_token, $form ) { /** * Allows the draft submission to be overridden before it is saved to the database. * * @since 2.3.3.1 * * @param string $submission_json { * JSON encoded associative array containing this incomplete submission. * * @type array $submitted_values The submitted values. * @type array $partial_entry The draft entry created from the submitted values. * @type null|array $field_values The dynamic population field values. * @type int $page_number The forms current page number. * @type array $files The uploaded file properties. * @type string $gform_unique_id The unique id for this submission. * } * @param string $resume_token The unique token which can be used to resume this incomplete submission at a later date/time. * @param array $form The form which this incomplete submission was created for. */ $submission_json = apply_filters( 'gform_incomplete_submission_pre_save', $submission_json, $resume_token, $form );
return $submission_json; }
/** * Updates a draft submission. * * @since 2.4 * * @param string $resume_token The uuid of the draft submission to be updated. * @param array $form * @param string $date_created * @param string $ip * @param string $source_url * @param string $submission_json * * @return bool|false|int|string */ public static function update_draft_submission( $resume_token, $form, $date_created, $ip, $source_url, $submission_json ) { global $wpdb;
/** * 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 = '' ) {
// 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,
/** * Filters the draft submission after reading it from the database. * * @since 2.4 * * @param $submission_json * @param $resume_token * @param $form * * @return string */ private static function filter_draft_submission_post_get( $submission_json, $resume_token, $form ) {
/** * Allows the draft submission to be overridden after it is retrieved from the database but before it used to populate the form. * * @since 2.3.3.1 * * @param string $submission_json { * JSON encoded associative array containing the draft submission being resumed. * * @type array $submitted_values The submitted values. * @type array $partial_entry The draft entry created from the submitted values. * @type null|array $field_values The dynamic population field values. * @type int $page_number The forms current page number. * @type array $files The uploaded file properties. * @type string $gform_unique_id The unique id for this submission. * } * @param string $resume_token The unique token which was used to resume this incomplete submission. * @param array $form The form which this incomplete submission was created for. */ $submission_json = apply_filters( 'gform_incomplete_submission_post_get', $submission_json, $resume_token, $form ); return $submission_json; }
foreach ( $rows as $row ) { /** * Allow modification of the delimiter used to parse List field URL parameters. * * @since 2.0.0 * * @param string $delimiter Defaults to '|'; * @param array $field GF_Field object for the current field. * @param string $name Name of the current dynamic population parameter. * @param array $field_values Array of values provided for pre-population into the form. */ $delimiter = apply_filters( 'gform_list_field_parameter_delimiter', '|', $field, $name, $field_values ); $ary_rows = array_merge( $ary_rows, rgexplode( $delimiter, $row, $column_count ) ); }
// replace commas in individual values to prevent individual value from being split into multiple values (checkboxes, multiselects) if ( $field->get_input_type() === 'checkbox' ) { $val = str_replace( ',', ',', $val ); }
case 'post_category' : foreach ( explode( ',', $value ) as $cat_string ) { $cat_array = explode( ':', $cat_string ); // the category id is the last item in the array, access it using end() in case the category name includes colons. array_push( $categories, end( $cat_array ) ); } break;
//setting current user as author depending on settings $post_data['post_author'] = $form['useCurrentUserAsAuthor'] && ! empty( $lead['created_by'] ) ? $lead['created_by'] : rgar( $form, 'postAuthor' );
return $post_data; }
/** * Retrieves the custom field names (meta keys) for the custom field select in the form editor. * * @since unknown * * @return array */ public static function get_custom_field_names() { $form_id = absint( rgget( 'id' ) );
/** * Allow the postmeta query which retrieves the custom field names (meta keys) to be disabled. * * @since 2.3.4.1 * * @param bool $disable_query Indicates if the custom field names query should be disabled. Default is false. */ $disable_query = gf_apply_filters( array( 'gform_disable_custom_field_names_query', $form_id ), false );
if ( $disable_query ) { return array(); }
global $wpdb; $sql = "SELECT DISTINCT meta_key FROM $wpdb->postmeta WHERE meta_key NOT BETWEEN '_' AND '_z' HAVING meta_key NOT LIKE %s ORDER BY meta_key"; $keys = $wpdb->get_col( $wpdb->prepare( $sql, $wpdb->esc_like( '_' ) . '%' ) );
/** * Prepare the value before saving it to the lead. For multi-input fields this will be called for each input. * * @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() ) {
// special format for Post Category fields if ( $field->type == 'post_category' ) { $is_multiselect = $field->inputType === 'multiselect'; $full_values = array();
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;
//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 = gf_apply_filters( array( 'gform_post_data', $form['id'] ), $post_data, $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, true ); GFCommon::log_debug( 'GFFormsModel::create_post(): Result from wp_insert_post(): ' . print_r( $post_id, 1 ) );
// Add the post id to the entry so it is available during merge tag replacement. $lead['post_id'] = $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'] );
$post_images = array(); if ( ! empty( $post_data['images'] ) ) { // Creating post images. GFCommon::log_debug( 'GFFormsModel::create_post(): Processing post images.' );
foreach ( $post_data['images'] as $image ) { if ( empty( $image['url'] ) ) { GFCommon::log_debug( __METHOD__ . '(): No image to process for field #' . $image['field_id'] ); continue; }
// 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']; }
// Save media id for post body/title template variable replacement (below). $post_images[ $image['field_id'] ] = $media_id; $lead[ $image['field_id'] ] .= "|:|$media_id";
// Update the alt text. update_post_meta( $media_id, '_wp_attachment_image_alt', $image['alt'] );
// Setting the featured image. $field = RGFormsModel::get_field( $form, $image['field_id'] ); if ( $field->postFeaturedImage ) { $result = set_post_thumbnail( $post_id, $media_id ); GFCommon::log_debug( __METHOD__ . '(): Setting the featured image. Result from set_post_thumbnail(): ' . var_export( $result, 1 ) ); } } } }
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;
//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 ) ) {
//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' ) ) {
// Update the post_id in the database for this entry. GFCommon::log_debug( 'GFFormsModel::create_post(): Updating entry with post id.' ); self::update_lead_property( $lead['id'], 'post_id', $post_id );
$gform_after_create_post_args = array( 'gform_after_create_post', $form['id'] ); if ( gf_has_action( $gform_after_create_post_args ) ) { GFCommon::log_debug( __METHOD__ . '(): Executing functions hooked to gform_after_create_post.' ); /** * Fires after a post, from a form with post fields, is created * * @param int $form ['id'] The ID of the form where the new post was created * @param int $post_id The new Post ID created after submission * @param array $lead The Lead Object * @param array $form The Form Object for the form used to create the post */ gf_do_action( $gform_after_create_post_args, $post_id, $lead, $form ); GFCommon::log_debug( __METHOD__ . '(): Completed gform_after_create_post.' ); }
GFCommon::log_debug( __METHOD__ . sprintf( '(): Post creation completed in %F seconds.', GFCommon::timer_end( __METHOD__ ) ) );
return $post_id; }
/** * Process any merge tags and shortcodes found in the template. * * @param string $template The template. * @param string $field_type The field type currently being processed. Possible values: post_custom_field, post_content, or post_title. * @param array $post_images The uploaded post images. * @param array $post_data The post data prepared from the current entry. * @param array $form The form currently being processed. * @param array $entry The entry currently being processed. * * @return string */ public static function process_post_template( $template, $field_type, $post_images, $post_data, $form, $entry ) { GFCommon::log_debug( __METHOD__ . "(): Processing {$field_type} template." );
//replacing all other variables $template = GFCommon::replace_variables( $template, $form, $entry, false, false, false );
if ( $field_type != 'post_content' ) { $process_template_shortcodes = true;
/** * Allow shortcode processing of custom field and post title templates to be disabled. * * @param boolean $process_template_shortcodes Should the shortcodes be processed? Default is true. * @param string $field_type The field type currently being processed. Possible values: post_custom_field, post_content, or post_title. * @param array $post_data The post data prepared from the current entry. * @param array $form The form currently being processed. * @param array $entry The entry currently being processed. * * @since 2.0.0.4 */ $process_template_shortcodes = apply_filters( 'gform_process_template_shortcodes_pre_create_post', $process_template_shortcodes, $field_type, $post_data, $form, $entry ); $process_template_shortcodes = apply_filters( 'gform_process_template_shortcodes_pre_create_post_' . $form['id'], $process_template_shortcodes, $field_type, $post_data, $form, $entry );
/** * Filter the media upload location. * * @param array $upload_dir The current upload directory’s path and url. * @param int $form_id The ID of the form currently being processed. * @param int $post_id The ID of the post created from the entry currently being processed. */ $upload_dir = gf_apply_filters( 'gform_media_upload_path', $form_id, $upload_dir, $form_id, $post_id );
if ( ! file_exists( $upload_dir['path'] ) ) { if ( ! wp_mkdir_p( $upload_dir['path'] ) ) { return false; } }
} else { //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 );
//ignore fields that have not changed if ( $lead != null && isset( $lead[ $input_id ] ) && $value === rgget( (string) $input_id, $lead ) ) { return; }
/** * Filter the value before it's saved to the database. * * @since 1.5.0 * @since 1.8.6 Added the $input_id parameter. * @since 1.9.14 Added form and field specific versions. * * @param string|array $value The fields input value. * @param array $entry The current entry object. * @param GF_Field $field The current field object. * @param array $form The current form object. * @param string $input_id The ID of the input being saved or the field ID for single input field types. */ $value = apply_filters( 'gform_save_field_value', $value, $entry, $field, $form, $input_id ); $value = apply_filters( "gform_save_field_value_{$form['id']}", $value, $entry, $field, $form, $input_id );
} else { // when the value is empty and no $entry_meta_id was set, check if it's a repeater field. if ( empty( $entry_meta_id ) && $field instanceof GF_Field_Repeater && isset( $field->fields ) && is_array( $field->fields ) ) { foreach ( $field->fields as $subfield ) { self::update_entry_field_value( $form, $entry, $subfield, 0, $subfield->id, '' ); } } else { // Deleting details for this field if ( is_a( $field, 'GF_Field' ) && is_array( $field->get_entry_inputs() ) ) { $_input_id = ( false === strpos( $input_id, '.' ) ) ? sprintf( '%d.%%', $input_id ) : $input_id; $sql = $wpdb->prepare( "DELETE FROM $entry_meta_table_name WHERE entry_id=%d AND meta_key LIKE %s ", $entry_id, $_input_id ); } else { $sql = $wpdb->prepare( "DELETE FROM $entry_meta_table_name WHERE entry_id=%d AND meta_key = %s ", $entry_id, $input_id ); } if ( $item_index ) { $sql .= $wpdb->prepare( ' AND item_index=%s', $item_index ); } $result = $wpdb->query( $sql ); if ( false === $result ) { return false; } } }
return true; }
/** * Returns the SQL to update or insert field values.. * * @param array $form * @param array $entry * @param GF_Field $field * @param int $entry_meta_id * @param string $input_id * @param string $value * @param string $item_index * * @return bool */ public static function queue_batch_field_operation( $form, &$entry, $field, $entry_meta_id, $input_id, $value, $item_index = '' ) { /** * Filter the value before it's saved to the database. * * @since 1.5.0 * @since 1.8.6 Added the $input_id parameter. * @since 1.9.14 Added form and field specific versions. * * @param string|array $value The fields input value. * @param array $entry The current entry object. * @param GF_Field $field The current field object. * @param array $form The current form object. * @param string $input_id The ID of the input being saved or the field ID for single input field types. */ $value = apply_filters( 'gform_save_field_value', $value, $entry, $field, $form, $input_id ); $value = apply_filters( "gform_save_field_value_{$form['id']}", $value, $entry, $field, $form, $input_id );
/** * Checks if any field updates, inserts, or deletions have been registered for batch processing. * * @since 2.4.17 * * @return bool */ public static function has_batch_field_operations() { return ! empty( self::$_batch_field_updates ) || ! empty( self::$_batch_field_inserts ) || ! empty( self::$_batch_field_deletes ); }
public static function flush_batch_field_operations() { self::$_batch_field_updates = array(); self::$_batch_field_inserts = array(); self::$_batch_field_deletes = array(); }
public static function begin_batch_field_operations() { self::flush_batch_field_operations(); }
/** * Performs the update, inserts and deletes registered by queue_batch_field_operation() * * @return array An array of results. */ public static function commit_batch_field_operations() { global $wpdb;
public static function get_tables() { return array( self::get_form_view_table_name(), self::get_meta_table_name(), self::get_form_table_name(), self::get_form_revisions_table_name(), self::get_entry_table_name(), self::get_entry_meta_table_name(), self::get_entry_notes_table_name(), self::get_draft_submissions_table_name(), self::get_rest_api_keys_table_name(), ); }
public static function drop_tables() { global $wpdb; foreach ( GF_Forms_Model_Legacy::get_legacy_tables() as $table ) { $wpdb->query( "DROP TABLE IF EXISTS $table" ); } foreach ( self::get_tables() as $table ) { $wpdb->query( "DROP TABLE IF EXISTS $table" ); } }
/** * Target for the wpmu_drop_tables filter. Adds all tables for Gravity Forms and the Add-On Framework to list * of tables to drop when a site is deleted. * * @param $drop_tables * * @return array */ public static function mu_drop_tables( $drop_tables ) { global $wpdb;
public static function insert_form_view( $form_id, $deprecated = null ) { global $wpdb; $table_name = self::get_form_view_table_name();
$sql = $wpdb->prepare( " SELECT id FROM $table_name WHERE form_id=%d AND date_created BETWEEN DATE_SUB(utc_timestamp(), INTERVAL 1 DAY) AND 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, '' ) ); } 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;
return $wpdb->get_results( $wpdb->prepare( " SELECT n.id, n.user_id, n.date_created, n.value, n.note_type, n.sub_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 entry_id=%d ORDER BY id", $lead_id ) ); }
/** * Get a collection of notes. * * @since 2.4.18 * * @param array $search_criteria { * Array of search criteria. * * @type int $id Get the note with this ID. * @type int $entry_id Get notes associated with this entry ID. * @type int $user_id Get notes with this user ID. * @type string $user_name Get notes with this user name. * @type string $note_type Get notes with this note type. * @type string $sub_type Get notes with this sub type. * @type string $start_date Get notes on or after this date. Expects SQL datetime format. * @type string $end_date Get notes on or before this date. Expects SQL datetime format. * } * @param null|array $sorting { * Array of sort key and direction. * * @type string $key Key to sort on. Options: id, entry_id, user_id, user_name, note_type, sub_type, date. * @type string $direction Sort direction. Options: ASC, DESC. * } * @return array|null|object */ public static function get_notes( $search_criteria = array(), $sorting = null ) { global $wpdb;
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 );
/*** * Saves the Gravity Forms license key to the database and registers the site and license key with the Gravity Forms licensing server. * * @since 1.0 * * @param string $new_key Gravity Forms license key to be saved. */ public static function save_key( $new_key ) {
// Updating site registration with Gravity Server. $result = $license_connector->update_site_registration( $new_key_md5, true );
// New key is invalid, revert to old key. if ( ! $result->can_be_used() ) { self::update_license_key( $previous_key ); } } else { // Updating site registration with Gravity Server. $license_connector->update_site_registration( $new_key_md5, true ); }
$sql = "SELECT count(distinct l.id) FROM $entry_table_name l INNER JOIN $entry_meta_table_name ld ON l.id = ld.entry_id $where";
return $wpdb->get_var( $sql ); }
/** * Returns the WHERE clause for an entry search. * * This function is not used and is only included for backwards compatibility. Use GFAPI::count_entries() instead. * * @deprecated 2.3.0.1 * * @since 2.3.0.1 * * @param $args * * @return string */ public static function get_entries_where_sql( $args ) {
/** * Get the text that tells the user that the field is required. * * @since 2.5 * * @param $form_id * * @return string HTML required indicator. */ public static function get_required_indicator( $form_id ) { $meta = self::get_form_meta( $form_id ); $required_indicator = rgar( $meta, 'requiredIndicator' );
/** * Returns the field object for the requested field or input ID from the supplied or specified form. * * @since 2.3 Updated to support being passed the form id or form object as the first parameter. * @since unknown. * @access public * * @param array|int $form_or_id The Form Object or ID. * @param string|int $field_id The field or input ID. * * @return GF_Field|null */ public static function get_field( $form_or_id, $field_id ) { $form = is_numeric( $form_or_id ) ? self::get_form_meta( $form_or_id ) : $form_or_id;
if ( is_numeric( $field_id ) || preg_match( '/^\d+\.\w+$/', $field_id ) ) { // Removing the input-specific segment from the field ID (i.e 1.3 or 1.something -> 1). $field_id = intval( $field_id ); }
/** * Returns the field inside a repeater field with the specified ID. * * @since 2.4 * * @param GF_Field_Repeater $repeater_field The repeater field. * @param int $field_id The field ID. * * @return null|GF_Field */ public static function get_sub_field( $repeater_field, $field_id ) { if ( is_array( $repeater_field->fields ) ) { foreach ( $repeater_field->fields as $field ) { if ( $field->id == $field_id ) { return $field; } elseif ( is_array( $field->fields ) ) { $f = self::get_sub_field( $field, $field_id ); if ( $f ) { return $f; } } } } return null; }
/** * @deprecated 2.8 HTML5 setting was removed, and HTML5 is now always enabled. * @return true */ public static function is_html5_enabled() { return true; }
/** * 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. * * @since Unknown * @since 2.7.1 Added the optional $form arg. * * @param array $form The form being processed or an empty array to get the form based on the ID from the gform_submit input. * * @return false|array */ public static function get_current_lead( $form = array() ) { $form_id = absint( rgpost( 'gform_submit' ) );
// If a GF submission is not in process, always return false. if ( empty( $form_id ) ) { return false; }
/** * 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; }
/** * Converts the legacy confirmation from forms created prior to v1.7 to the current format or adds the default confirmation. * * @since 1.7 * @since 2.4.15 Fixed corrupt confirmation being created when form doesn't have one to convert. * * @param array $form The form being processed. * * @return array */ public static function convert_confirmation( $form ) { $confirmation = rgar( $form, 'confirmation' );
if ( ! empty( $confirmation['type'] ) ) { // Complete converting legacy confirmation by adding missing properties. $confirmation['id'] = uniqid(); $confirmation['name'] = esc_html__( 'Default Confirmation', 'gravityforms' ); $confirmation['isDefault'] = true; } else { // Form does not have a valid legacy confirmation add the default confirmation instead. $confirmation = self::get_default_confirmation(); }
/** * Returns a default confirmation. * * @since 2.4.15 * * @param string $event The confirmation event. form_saved, form_save_email_sent, or an empty string for the default form submission event. * * @return array */ public static function get_default_confirmation( $event = '' ) { switch ( $event ) { case 'form_saved': return array( 'id' => uniqid( 'sc1' ), 'event' => 'form_saved', 'name' => __( 'Save and Continue Confirmation', 'gravityforms' ), 'isDefault' => true, 'type' => 'message', 'message' => sprintf( '<h2>%s</h2><p role="alert">%s</p><p class="resume_form_link_wrapper">{save_link}</p><p>%s<br />%s</p>{save_email_input}', __( 'Link to continue editing later', 'gravityforms' ), __( 'Please use the following link to return and complete this form from any computer.', 'gravityforms' ), __( 'Note: This link will expire after 30 days.', 'gravityforms' ), __( 'Enter your email address if you would like to receive the link via email.', 'gravityforms' ) ), 'url' => '', 'pageId' => '', 'queryString' => '', );
case 'form_save_email_sent': return array( 'id' => uniqid( 'sc2' ), 'event' => 'form_save_email_sent', 'name' => __( 'Save and Continue Email Sent Confirmation', 'gravityforms' ), 'isDefault' => true, 'type' => 'message', 'message' => sprintf( '<h2 class="saved_message_success">%s</h2><p>%s <span class="saved_message_email">{save_email}</span></p>', __( 'Success!', 'gravityforms' ), __( 'The link was sent to the following email address:', 'gravityforms' ) ), 'url' => '', 'pageId' => '', 'queryString' => '', );
default: return array( 'id' => uniqid(), 'name' => __( 'Default Confirmation', 'gravityforms' ), 'isDefault' => true, 'type' => 'message', 'message' => __( 'Thanks for contacting us! We will get in touch with you shortly.', 'gravityforms' ), 'url' => '', 'pageId' => '', 'queryString' => '', ); } }
public static function load_confirmations( $form ) {
// If there are no confirmations convert the legacy confirmation or add the default. if ( empty( $confirmations ) ) { $form = self::convert_confirmation( $form ); } else { $form['confirmations'] = $confirmations; }
return $form; }
public static function get_form_confirmations( $form_id ) { global $wpdb;
/** * Delete a form confirmation by ID. * * @since 2.5 * * @param string $confirmation_id The confirmation to be deleted. * @param int|array $form_id The form ID or Form Object form the confirmation being deleted. * * @return false|int The result of the database operation. */ public static function delete_form_confirmation( $confirmation_id, $form_id ) {
// If no Form ID or object was provided, exit. if ( ! $form_id ) { return false; }
// Get Form object if only ID was provided. $form = ! is_array( $form_id ) ? self::get_form_meta( $form_id ) : $form_id;
/** * Fires right before a confirmation is deleted. * * @since 1.9 * * @param int $form ['confirmations'][$confirmation_id] The ID of the confirmation being deleted. * @param array $form The Form object. */ do_action( 'gform_pre_confirmation_deleted', $form['confirmations'][ $confirmation_id ], $form );
// Clear form cache so next retrieval of form meta will reflect deleted confirmation. self::flush_current_form( self::get_form_cache_key( $form_id ) );
/** * Remove corrupt confirmations created by old versions of GFFormsModel::convert_confirmation(). * * @since 2.4.15 * * @param mixed $confirmations The confirmations to be processed. * * @return array */ public static function remove_corrupt_confirmations( $confirmations ) { if ( ! is_array( $confirmations ) ) { return array(); }
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' ); }
/** * Returns the ids of the specified forms. * * @since unknown * @since 2.5 Added $sort_column and $sort_dir parameters. * @since 2.5.8 Added support for passing null for the $active and $trash args. * * @param bool|null $active True if active forms are returned. False to get inactive forms. Null to ignore the is_active property. Defaults to true. * @param bool|null $trash True if trashed forms are returned. False to exclude trash. Null to ignore the is_trash property. Defaults to false. * @param string $sort_column The column to sort the results on. * @param string $sort_dir The sort direction, ASC or DESC. * * @return array of form IDs. */ public static function get_form_ids( $active = true, $trash = false, $sort_column = 'id', $sort_dir = 'ASC' ) { global $wpdb;
$sql = 'SELECT id FROM ' . self::get_form_table_name(); $where = array();
if ( ! empty( $sort_column ) ) { $sql .= " ORDER BY $sort_column " . ( $sort_dir == 'ASC' ? 'ASC' : 'DESC' ); }
return $wpdb->get_col( $sql ); }
/** * Get forms and return any form column(s). * * @see GFFormsModel::get_form_ids() * @since 2.7.5 * * @param bool $active True if active forms are returned. False to get inactive forms. Defaults to true. * @param bool $trash True if trashed forms are returned. False to exclude trash. Defaults to false. * @param string $sort_column The column to sort the results on. * @param string $sort_dir The sort direction, ASC or DESC. * @param array $columns The columns to return. Defaults to ['id']. Other options are 'title', 'date_created', 'is_active', 'is_trash'. 'date_updated' may be supported, depending on the Gravity Forms version. * * @return array Forms indexed from 0 by SQL result row number. Each row is an associative array (column => value). */ public static function get_forms_columns( $active = true, $trash = false, $sort_column = 'id', $sort_dir = 'ASC', $columns = array( 'id' ) ) { global $wpdb;
/** * Returns the lead (entry) count for all forms. * * @param string $status * * @return null|string */ public static function get_lead_count_all_forms( $status = 'active' ) { return self::get_entry_count_all_forms( $status ); }
/** * Returns the entry count for all forms. * * @param string $status * * @return null|string */ public static function get_entry_count_all_forms( $status = 'active' ) { global $wpdb;
/** * Returns an array of field IDs that have been encrypted using GFCommon::encrypt() * * @deprecated * * @since unknown * * @param $entry_id * * @return array|bool|mixed */ public static function get_encrypted_fields( $entry_id ) {
/** * Stores the field IDs that have been encrypted using GFCommon::encrypt() * * @deprecated * * @since unknown * * @param $entry_id * @param $field_ids * * @return bool */ public static function set_encrypted_fields( $entry_id, $field_ids ) {
/** * Checks whether the given field was encrypted using GFCommon::encrpyt() and registered using GFCommon::set_encrypted_fields() * * @deprecated * * @since unknown * * @param $entry_id * @param $field_id * * @return bool|mixed|void */ public static function is_encrypted_field( $entry_id, $field_id ) {
/** * Determines if an entry field is stored encrypted. Use this hook to change the default behavior of decrypting fields that have been encrypted or to completely disable the * process if checking for encrypted fields. * * @param int $entry_id The current Entry ID * @param int $field_id The current Field ID. */ $is_encrypted = apply_filters('gform_is_encrypted_field', '', $entry_id, $field_id ); if ( $is_encrypted !== '' ){ return $is_encrypted; }
/** * Returns an array of field IDs that have been encrypted using GFCommon::openssl_encrypt() * * @since 2.3 * * @param $entry_id * * @return array|bool|mixed */ public static function get_openssl_encrypted_fields( $entry_id ) {
/** * Returns the encrypted field IDs for each entry_id specified in the $entry_ids array. * * @since 2.6 * * @param array $entry_ids An array of entry IDs. * * @return array Returns an array with entry_id as the key and an array of field IDs (that have been encrypted using GFCommon::openssl_encrypt()) as the value. */ public static function get_openssl_encrypted_fields_by_entries( $entry_ids ) { global $wpdb;
/** * Adds the field IDs that have been encrypted using GFCommon::encrypt(). Merges the new IDs with the existing IDs. * * @since 2.3 * * @param $entry_id * @param $field_ids * * @return bool */ public static function set_openssl_encrypted_fields( $entry_id, $field_ids ) {
/** * Checks whether the given field was encrypted using GFCommon::encrpyt() and registered using GFCommon::set_encrypted_fields() * * @since 2.3 * * @param $entry_id * @param $field_id * * @return bool|mixed|void */ public static function is_openssl_encrypted_field( $entry_id, $field_id ) {
/** * Determines if an entry field is stored encrypted. Use this hook to change the default behavior of decrypting fields that have been encrypted or to completely disable the * process if checking for encrypted fields. * * @param int $entry_id The current Entry ID * @param int $field_id The current Field ID. */ $is_encrypted = apply_filters('gform_is_encrypted_field', '', $entry_id, $field_id ); if ( $is_encrypted !== '' ){ return $is_encrypted; }
/** * Checks whether the conditional logic operator passed in is valid. * * @since 2.0.7.20 Refactored and added filter gform_is_valid_conditional_logic_operator. * @access public * * @param string $operator Conditional logic operator. * * @return bool true if a valid operator, false if not. */ public static function is_valid_operator( $operator ) { $operators = array( 'is', 'isnot', '<>', 'not in', 'in', '>', '<', 'contains', 'starts_with', 'ends_with', 'like', '>=', '<=' ); $is_valid = in_array( strtolower( $operator ), $operators ); /** * Filter which checks whether the operator is valid. * * Allows custom operators to be validated. * * @since 2.0.7.20 * * @param bool $is_valid Whether the operator is valid or not. * @param string $operator The conditional logic operator. */ return apply_filters( 'gform_is_valid_conditional_logic_operator', $is_valid, $operator ); }
/** * Update the recent forms list for the current user when a form is edited or trashed. * * @since 2.0.7.14 * * @param int $form_id The ID of the current form. * @param bool $trashed Indicates if the form was trashed. Default is false, form was opened for editing. */ public static function update_recent_forms( $form_id, $trashed = false ) { if ( ! get_option( 'gform_enable_toolbar_menu' ) ) { return; }
/** * Get the recent forms list for the current user. * * @since 2.2.1.14 * * @param int $current_user_id The ID of the currently logged in user. * * @return array */ public static function get_recent_forms( $current_user_id = 0 ) { if ( ! $current_user_id ) { $current_user_id = get_current_user_id(); }
/** * Evaluates the conditional logic based on the specified $logic variable. This method is used when evaluating field conditional logic. * NOTE: There is a future refactoring opportunity to reduce code duplication by merging this method with GFCommon::evaluate_conditional_logic(), which currently handles non-field conditional logic (i.e. notification, confirmation and feed). A possible solution is for this method to call GFCommon::evaluate_conditional_logic(). * * @param array $form The current Form object. * @param array $logic The conditional logic configuration array with all the specified rules. * @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 $entry Optional, default is null. If entry object is available, pass the entry. * * @return bool Returns true if the conditional logic passes (i.e. field/button is supposed to be displayed), false otherwise. */ private static function evaluate_conditional_logic( $form, $logic, $field_values, $entry = null ) {
if ( empty( $logic ) ){ return true; }
$match_count = 0; foreach ( $logic['rules'] as $rule ) { try { /** * Filter the conditional logic rule before it is evaluated. * * @since 2.4.22 * * @param array $rule The conditional logic rule about to be evaluated. * @param array $form The current form meta. * @param array $logic All details required to evaluate an objects conditional logic. * @param array $field_values The default field values for this form. * @param array $entry The current entry object (if available). */ $rule = apply_filters( 'gform_rule_pre_evaluation', $rule, $form, $logic, $field_values, $entry ); } catch ( Error $e ) { GFCommon::log_error( __METHOD__ . '(): Error from function hooked to gform_rule_pre_evaluation. ' . $e->getMessage() ); } $source_field = RGFormsModel::get_field( $form, $rule['fieldId'] ); $source_value = empty( $entry ) ? self::get_field_value( $source_field, $field_values ) : self::get_lead_field_value( $entry, $source_field );
/** * Filter the source value of a conditional logic rule before it is compared with the target value. * * @since 2.6.2 * * @param int|string $source_value The value of the rule's configured field ID, entry meta, or custom property. * @param array $rule The conditional logic rule that is being evaluated. * @param array $form The current form meta. * @param array $logic All details required to evaluate an objects conditional logic. * @param array $entry The current entry object (if available). */ $source_value = apply_filters( 'gform_rule_source_value', $source_value, $rule, $form, $logic, $entry );
/** * Returns all the draft submissions. * * @since 2.4 * * @return array|null|object The query result. */ public static function get_draft_submissions() { global $wpdb;
/** * Sanitizes the names of the files that have been uploaded to the tmp directory and sent in * $_POST['gform_uploaded_files'] and caches them in GFFormsModel::$uploaded_files. * * @since 2.4.3.5 * * @param $form_id * * @return array */ public static function set_uploaded_files( $form_id ) { $files = GFCommon::json_decode( stripslashes( GFForms::post( 'gform_uploaded_files' ) ) ); if ( ! is_array( $files ) ) { $files = array(); }
/** * Checks if an entry exists for the supplied ID. * * @since 2.4.6 * @since 2.4.24 Updated to use GFFormsModel::id_exists_in_table(). * * @param int $entry_id The ID to be checked. * * @return bool */ public static function entry_exists( $entry_id ) { return self::id_exists_in_table( $entry_id, GFFormsModel::get_entry_table_name() ); }
/** * Checks if an id exists in the specified table. * * @since 2.4.24 * * @param int $id The ID to be checked. * @param string $table The table name, including the site's database prefix. * * @return bool */ public static function id_exists_in_table( $id, $table ) { $id = intval( $id ); if ( $id <= 0 ) { return false; }
global $wpdb; $sql = $wpdb->prepare( "SELECT count(id) FROM {$table} WHERE id = %d", $id ); $result = intval( $wpdb->get_var( $sql ) );
return $result > 0; }
/** * Returns an array of column names used by the gf_addon_feed table. * * @since 2.4.24 * * @return string[] */ public static function get_addon_feed_db_columns() { return array( 'id', 'form_id', 'is_active', 'feed_order', 'meta', 'addon_slug', 'event_type' ); }
/** * Updates the specified feed with the given property value. * * @since 2.4.24 * * @param int $feed_id The ID of the feed being updated. * @param string $property_name The name of the property (column) being updated. * @param mixed $property_value The new value of the specified property. * * @return bool|WP_Error */ public static function update_feed_property( $feed_id, $property_name, $property_value ) { if ( $property_name === 'id' ) { return new WP_Error( 'invalid_property', __( 'Updating the id property is not supported', 'gravityforms' ) ); }
if ( ! in_array( $property_name, self::get_addon_feed_db_columns() ) ) { return new WP_Error( 'invalid_property', sprintf( __( '%s is not a valid feed property', 'gravityforms' ), $property_name ) ); }
if ( gf_upgrade()->get_submissions_block() ) { return new WP_Error( 'submissions_blocked', __( 'Submissions are currently blocked due to an upgrade in progress', 'gravityforms' ) ); }
if ( $property_name === 'meta' ) { if ( is_array( $property_value ) ) { $property_value = json_encode( $property_value ); }
if ( empty( $property_value ) || ! is_string( $property_value ) || $property_value[0] !== '{' ) { return new WP_Error( 'invalid_meta', __( 'Feed meta should be an associative array or JSON', 'gravityforms' ) ); } }
if ( $result === false ) { return new WP_Error( 'error_updating', sprintf( __( 'There was an error while updating feed id %s', 'gravityforms' ), $feed_id ) ); }
if ( $result === 0 && ! self::id_exists_in_table( $feed_id, $table ) ) { return new WP_Error( 'not_found', sprintf( __( 'Feed id %s not found', 'gravityforms' ), $feed_id ) ); }
return (bool) $result; }
/** * Updates the license key, If multisite, it updates the license key for all sites in the network. * * @since 2.7 * @since 2.8.17 Updated to also store the key as a network option. * * @param string $license The license key MD5. * * @return void */ public static function update_license_key( $license ) { if ( is_main_site() && GFCommon::is_network_active() ) { if ( $license ) { update_network_option( null, GFForms::LICENSE_KEY_OPT, $license ); } else { delete_network_option( null, GFForms::LICENSE_KEY_OPT ); }
/** * In-memory cache of entry meta using "{blog_id}_{entry_id}_{meta_key}" as the key. * * @since 2.3 Prefixed cache key with the blog id. * @since unknown * * @global array $_gform_lead_meta */ global $_gform_lead_meta; $_gform_lead_meta = array();
// Functions to handle lead meta function gform_get_meta( $entry_id, $meta_key ) {
/** * Add or update metadata associated with an entry. * * Data will be serialized. Don't forget to sanitize user input. * * @since Unknown * @since 2.5 Return the result of the query. * * @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). * * @return int|false Returns the number of affected rows, or false if the operation fails. */ function gform_update_meta( $entry_id, $meta_key, $meta_value, $form_id = null ) { global $wpdb, $_gform_lead_meta;
if ( gf_upgrade()->get_submissions_block() ) { return; }
/** * Add metadata associated with an entry. * * Data will be serialized; Don't forget to sanitize user input. * * @since Unknown * @since 2.5 Return the result of the query. * * @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). * * @return int|false Returns the number of affected rows, or false if the operation fails. */ function gform_add_meta( $entry_id, $meta_key, $meta_value, $form_id = null ) { global $wpdb, $_gform_lead_meta;
if ( gf_upgrade()->get_submissions_block() ) { return; }
/** * Delete metadata associated with an entry. * * @since Unknown * @since 2.5 Return the result of the query. * * @param int $entry_id The ID of the entry to be deleted. * @param string $meta_key The key for the meta data to be deleted. * * @return int|bool Returns true or the number of rows affected, or false if the operation fails. */ function gform_delete_meta( $entry_id, $meta_key = '' ) { global $wpdb, $_gform_lead_meta;
if ( gf_upgrade()->get_submissions_block() ) { return; }