status ) ? $source->status : ( $this->is_spam ? 'spam' : ( ! empty( $this->draft_id ) ? 'draft' : 'active' ) );
}
/**
* Date created in sql format 0000-00-00 00:00:00
*
* @var string
*/
public $date_created_sql;
/**
* Date created in sql format D M Y
*
* @var string
*/
public $date_created;
/**
* Time created in sql format M D Y @ g:i A
*
* @var string
*/
public $time_created;
/**
* Meta data
*
* @var array
*/
public $meta_data = array();
/**
* The table name
*
* @var string
*/
protected $table_name;
/**
* The table meta name
*
* @var string
*/
protected $table_meta_name;
/**
* Hold information about connected addons
*
* @since 1.1
* @var array
*/
private static $connected_addons = array();
/**
* Initialize the Model
*
* @param int $entry_id Entry Id.
*
* @since 1.0
* @since 1.1 Add instantiate connected addons
* @since 1.2 Limit initiate addon only on custom-forms by default
*/
public function __construct( $entry_id = 0 ) {
$this->table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$this->table_meta_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
/*
* @since 1.17.0
* draft_id could be used in place of the entry_id in the argument
* but we still need to get the entry_id which is used as the key for object cache
*/
if ( ! is_numeric( $entry_id ) && is_string( $entry_id ) && ctype_alnum( $entry_id ) ) {
$entry_id = $this->get_entry_id_by_draft_id( $entry_id );
}
if ( is_numeric( $entry_id ) && $entry_id > 0 ) {
$this->get( $entry_id );
// get connected addons.
if ( ! empty( $this->form_id ) ) {
$entry_types = array(
'custom-forms',
);
/**
* Filter Entry Types that can be connected with addons
*
* @param array $entry_types
*
* @since 1.2
*/
$entry_types = apply_filters( 'forminator_addon_entry_types', $entry_types );
if ( ! empty( $this->entry_type ) && in_array( $this->entry_type, $entry_types, true ) ) {
self::get_connected_addons( $this->form_id );
}
}
}
}
/**
* Load entry by id
* After load set entry to cache
*
* @param int $entry_id - the entry id.
*
* @return bool|mixed
* @since 1.0
*/
public function get( $entry_id ) {
global $wpdb;
$cache_key = self::FORM_ENTRY_CACHE_GROUP;
$entry_object_cache = wp_cache_get( $entry_id, $cache_key );
if ( $entry_object_cache ) {
$this->entry_id = $entry_object_cache->entry_id;
$this->entry_type = $entry_object_cache->entry_type;
$this->form_id = $entry_object_cache->form_id;
$this->is_spam = $entry_object_cache->is_spam;
$this->date_created_sql = $entry_object_cache->date_created_sql;
$this->date_created = $entry_object_cache->date_created;
$this->time_created = $entry_object_cache->time_created;
$this->meta_data = $entry_object_cache->meta_data;
$this->draft_id = $entry_object_cache->draft_id;
$this->status = $this->get_entry_status( $entry_object_cache );
return $entry_object_cache;
} else {
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$sql = "SELECT `entry_type`, `form_id`, `is_spam`, `date_created`, `draft_id`, `status` FROM {$table_name} WHERE `entry_id` = %d";
$entry = $wpdb->get_row( $wpdb->prepare( $sql, $entry_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
if ( $entry ) {
$this->entry_id = $entry_id;
$this->entry_type = $entry->entry_type;
$this->form_id = $entry->form_id;
$this->is_spam = $entry->is_spam;
$this->date_created_sql = $entry->date_created;
$this->date_created = date_i18n( 'j M Y', strtotime( $entry->date_created ) );
$this->time_created = date_i18n( 'M j, Y @ g:i A', strtotime( $entry->date_created ) );
$this->draft_id = $entry->draft_id;
$this->status = $this->get_entry_status( $entry );
$this->load_meta();
wp_cache_set( $entry_id, $this, $cache_key );
}
}
}
/**
* Set fields
*
* @param array $meta_array Array of data to be saved.
* @param string $entry_date Entry date.
*
* @type key - string the meta key
* @type value - string the meta value
* }
*
* @return bool - true or false
* @since 1.5 set meta_data values even entry_id is null for object reference in the future usage
* entry_id has null value is the outcome of failed to save or prevent_store is enabled
*
* @since 1.0
*/
public function set_fields( $meta_array, $entry_date = '' ) {
global $wpdb;
if ( $meta_array && ! is_array( $meta_array ) && ! empty( $meta_array ) ) {
return false;
}
// probably prevent_store enabled.
$prevent_store = ! $this->entry_id;
if ( ! $prevent_store ) {
// clear cache first.
wp_cache_delete( $this->entry_id, self::FORM_ENTRY_CACHE_GROUP );
wp_cache_delete( 'poll_entries_' . $this->form_id, self::FORM_ENTRY_CACHE_GROUP );
}
if ( $this->updating_entry ) {
// Delete all meta data for abandoned entry.
$wpdb->delete( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$this->table_meta_name,
array(
'entry_id' => $this->entry_id,
)
);
}
foreach ( $meta_array as $meta ) {
if ( ! isset( $meta['name'] ) || ! isset( $meta['value'] ) ) {
continue;
}
$key = wp_unslash( $meta['name'] );
$value = wp_unslash( $meta['value'] );
if ( ! $prevent_store ) {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$meta_id = $wpdb->insert(
esc_sql( $this->table_meta_name ),
array(
'entry_id' => $this->entry_id,
'meta_key' => $key, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
'meta_value' => maybe_serialize( $value ), // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
'date_created' => ! empty( $entry_date ) ? $entry_date : date_i18n( 'Y-m-d H:i:s' ),
)
);
} else {
$meta_id = $key;
}
/**
* Set Meta data for later usage
*
* @since 1.0.3
*/
if ( $meta_id ) {
$this->meta_data[ $key ] = array(
'id' => $meta_id,
'value' => $value,
);
}
}
if ( 'abandoned' === $this->status ) {
$form_uid = filter_input( INPUT_POST, 'form_uid' );
if ( $form_uid ) {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$meta_id = $wpdb->insert(
esc_sql( $this->table_meta_name ),
array(
'entry_id' => $this->entry_id,
'meta_key' => 'form_uid', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
'meta_value' => $form_uid, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
'date_created' => ! empty( $entry_date ) ? $entry_date : date_i18n( 'Y-m-d H:i:s' ),
)
);
}
}
return ! $prevent_store;
}
/**
* Load all meta data for entry
*
* @param object|bool $db - the WP_Db object.
*
* @since 1.0
*/
public function load_meta( $db = false ) {
if ( ! $db ) {
global $wpdb;
$db = $wpdb;
}
$this->meta_data = array();
$table_meta_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$sql = "SELECT `meta_id`, `meta_key`, `meta_value` FROM {$table_meta_name} WHERE `entry_id` = %d";
$results = $db->get_results( $db->prepare( $sql, $this->entry_id ) );
foreach ( $results as $result ) {
$this->meta_data[ $result->meta_key ] = array(
'id' => $result->meta_id,
'value' => is_array( $result->meta_value ) ? array_map( 'maybe_unserialize', $result->meta_value ) : maybe_unserialize( $result->meta_value ),
);
}
// Allow new field to get data of old field for old submissions.
if ( in_array( 'stripe-1', array_keys( $this->meta_data ), true ) && ! isset( $this->meta_data['stripe-ocs-1'] ) ) {
$this->meta_data['stripe-ocs-1'] = $this->meta_data['stripe-1'];
}
}
/**
* Get Meta
*
* @param string $meta_key - the meta key.
* @param mixed $default_value - the default value.
*
* @return mixed
* @since 1.0
*/
public function get_meta( $meta_key, $default_value = false ) {
if ( ! empty( $this->meta_data ) && isset( $this->meta_data[ $meta_key ] ) ) {
return $this->meta_data[ $meta_key ]['value'];
}
return $this->get_grouped_meta( $meta_key, $default_value );
}
/**
* Get Grouped Meta
* Sometimes the meta prefix is same
*
* @param string $meta_key - the meta key.
* @param mixed $default_value - the default value.
*
* @return mixed
* @since 1.0
*/
public function get_grouped_meta( $meta_key, $default_value = false ) {
if ( ! empty( $this->meta_data ) ) {
$response = '';
$field_suffix = self::field_suffix();
foreach ( $field_suffix as $suffix ) {
if ( isset( $this->meta_data[ $meta_key . '-' . $suffix ] ) ) {
$response .= $this->meta_data[ $meta_key . '-' . $suffix ]['value'] . ' ' . $suffix . ' , ';
}
}
if ( ! empty( $response ) ) {
return substr( trim( $response ), 0, - 1 );
}
}
return $default_value;
}
/**
* Save entry
*
* @param string|null $data_created Optional custom date created.
* @param int|null $entry_id Entry Id.
* @param int|null $previous_draft Draft Id.
*
* @return bool
* @since 1.6.1 add $data_created arg
*
* @since 1.0
*/
public function save( $data_created = null, $entry_id = null, $previous_draft = null ) {
global $wpdb;
$this->delete_previous_draft( $previous_draft );
// Check if abandonment feature is disabled and prevent saving abandoned entries.
if ( 'abandoned' === $this->status && forminator_form_abandonment_disabled() ) {
return false;
}
if ( ! empty( $entry_id ) ) {
$this->entry_id = $entry_id;
return true;
}
if ( empty( $data_created ) ) {
$data_created = date_i18n( 'Y-m-d H:i:s' );
}
// Derive status if not explicitly set.
$status = $this->get_entry_status( $this );
$saved_entry_id = $this->get_saved_entry_id();
if ( ! $saved_entry_id ) {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$result = $wpdb->insert(
$this->table_name,
array(
'entry_type' => $this->entry_type,
'form_id' => $this->form_id,
'is_spam' => $this->is_spam,
'date_created' => $data_created,
'draft_id' => $this->draft_id,
'status' => $status,
)
);
$this->entry_id = (int) $wpdb->insert_id;
} else {
$this->entry_id = $saved_entry_id;
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$result = $wpdb->update(
$this->table_name,
array(
'is_spam' => $this->is_spam,
'date_created' => $data_created,
'draft_id' => $this->draft_id,
'status' => $status,
),
array( 'entry_id' => $saved_entry_id )
);
}
if ( ! $result ) {
return false;
}
self::delete_form_entry_cache( $this->form_id );
wp_cache_delete( 'all_form_types', self::FORM_COUNT_CACHE_GROUP );
wp_cache_delete( $this->entry_type . '_form_type', self::FORM_COUNT_CACHE_GROUP );
return true;
}
/**
* Get saved entry id
*
* @return int
*/
private function get_saved_entry_id() {
$form_uid = filter_input( INPUT_POST, 'form_uid' );
if ( ! $form_uid ) {
return 0;
}
global $wpdb;
$sql = "SELECT m.entry_id FROM {$this->table_meta_name} m JOIN {$this->table_name} e ON (m.entry_id = e.entry_id)" .
" WHERE e.form_id = %d AND e.status = 'abandoned' AND m.meta_key = 'form_uid' AND m.meta_value = %s";
$entry_id = $wpdb->get_var( $wpdb->prepare( $sql, $this->form_id, $form_uid ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared
$this->updating_entry = ! empty( $entry_id );
return (int) $entry_id;
}
/**
* Delete entry with meta
*
* @since 1.0
*/
public function delete() {
self::delete_by_entry( $this->entry_id );
}
/**
* Field suffix
* Some fields are grouped and have the same suffix
*
* @return array
* @since 1.0
*/
public static function field_suffix() {
return apply_filters(
'forminator_field_suffix',
array(
'hours',
'minutes',
'ampm',
'street_address',
'address_line',
'city',
'state',
'zip',
'country',
'year',
'day',
'month',
'prefix',
'first-name',
'middle-name',
'last-name',
'post-title',
'post-content',
'post-excerpt',
'post-image',
'post-category',
'post-tags',
'product-id',
'product-quantity',
'min',
'max',
)
);
}
/**
* Field suffix label
* Displayable label for suffix
*
* @param string $suffix Suffix.
*
* @return string
* @since 1.0.5
*/
public static function translate_suffix( $suffix ) {
$translated_suffix = $suffix;
$field_suffixes = self::field_suffix();
$default_label_map = array(
'hours' => esc_html__( 'Hour', 'forminator' ),
'minutes' => esc_html__( 'Minute', 'forminator' ),
'ampm' => esc_html__( 'AM/PM', 'forminator' ),
'country' => esc_html__( 'Country', 'forminator' ),
'city' => esc_html__( 'City', 'forminator' ),
'state' => esc_html__( 'State', 'forminator' ),
'zip' => esc_html__( 'Zip', 'forminator' ),
'street_address' => esc_html__( 'Street Address', 'forminator' ),
'address_line' => esc_html__( 'Address Line 2', 'forminator' ),
'year' => esc_html__( 'Year', 'forminator' ),
'day' => esc_html__( 'Day', 'forminator' ),
'month' => esc_html__( 'Month', 'forminator' ),
'prefix' => esc_html__( 'Prefix', 'forminator' ),
'first-name' => esc_html__( 'First Name', 'forminator' ),
'middle-name' => esc_html__( 'Middle Name', 'forminator' ),
'last-name' => esc_html__( 'Last Name', 'forminator' ),
'post-title' => esc_html__( 'Post Title', 'forminator' ),
'post-content' => esc_html__( 'Post Content', 'forminator' ),
'post-excerpt' => esc_html__( 'Post Excerpt', 'forminator' ),
'post-image' => esc_html__( 'Post Image', 'forminator' ),
'post-category' => esc_html__( 'Post Category', 'forminator' ),
'post-tags' => esc_html__( 'Post Tags', 'forminator' ),
'product-id' => esc_html__( 'Product ID', 'forminator' ),
'product-quantity' => esc_html__( 'Product Quantity', 'forminator' ),
);
// could be filtered out field_suffix.
if ( in_array( $suffix, $field_suffixes, true ) && isset( $default_label_map[ $suffix ] ) ) {
$translated_suffix = $default_label_map[ $suffix ];
}
/**
* Translatable suffix
*
* @param string $translated_suffix
* @param string $suffix original suffix.
* @param array $default_label_map default translated suffix.
*
* @since 1.0.5
*/
return apply_filters( 'forminator_translate_suffix', $translated_suffix, $suffix, $default_label_map );
}
/**
* Ignored fields
* Fields not saved or shown
*
* @return array
* @since 1.0
*/
public static function ignored_fields() {
$ignored_fields = array(
'html',
'page-break',
'captcha',
'section',
);
if ( forminator_payments_disabled() ) {
$ignored_fields[] = 'stripe';
$ignored_fields[] = 'paypal';
$ignored_fields[] = 'stripe-ocs';
}
return apply_filters( 'forminator_entry_ignored_fields', $ignored_fields );
}
/**
* Return if form has live payment entry
*
* @param int $form_id - the form id.
*
* @return mixed
* @since 1.10
*/
public static function has_live_payment( $form_id ) {
global $wpdb;
$cached_count = wp_cache_get( 'live_payment_count_' . $form_id, self::FORM_COUNT_CACHE_GROUP );
if ( false !== $cached_count ) {
return $cached_count;
}
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$sql = "SELECT count(1) > 0
FROM {$table_name} m
LEFT JOIN {$entry_table_name} e
ON (m.entry_id = e.entry_id)
WHERE e.form_id = %d
AND ( m.meta_key = 'stripe-1' || m.meta_key = 'stripe-ocs-1' || m.meta_key = 'paypal-1' )
AND m.meta_value LIKE '%4:\"mode\";s:4:\"live\"%'
LIMIT 1";
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery -- unprepared SQL ok. false positive.
$count = $wpdb->get_var( $wpdb->prepare( $sql, $form_id ) );
wp_cache_set( 'live_payment_count_' . $form_id, $count, self::FORM_COUNT_CACHE_GROUP );
return $count;
}
/**
* Get all entries
*
* @param int $form_id - the form id.
* @param array $filters Filters.
*
* @return Forminator_Form_Entry_Model[]
* @since 1.40
*/
public static function get_all_entries( $form_id, $filters = array() ) {
$per_page = apply_filters( 'forminator_get_all_entries_limit', 100, $form_id );
$offset = 0;
$args = array(
'form_id' => $form_id,
'is_spam' => 0,
'per_page' => $per_page,
'offset' => $offset,
);
if ( ! empty( $filters ) && is_array( $filters ) ) {
$args = array_merge( $filters, $args );
}
$all_entries = array();
$page = 1;
do {
$entries = self::query_entries( $args );
if ( ! empty( $entries ) ) {
$all_entries = array_merge( $all_entries, $entries );
}
$args['offset'] = $page * $per_page;
$total_items = count( $entries );
++$page;
} while ( $total_items === $per_page );
return $all_entries;
}
/**
* Group count of Entries with extra selected
*
* @param int $form_id Form id.
* @param array $fields_element_id_with_extra Fields element Id.
*
* @return array|null|object
* @example = [
* 'FIELDS_WITH_EXTRA_ELEMENT_ID' => [
* 'META_VALUE-1' => COUNT
* 'META_VALUE-2' => COUNT
* ],
* 'answer-3' => [
* 'javascript is the best' => 8
* 'php is the best' => 7
* ],
* ]
*
* @since 1.0.5
*/
public static function count_polls_with_extra( $form_id, $fields_element_id_with_extra ) {
global $wpdb;
$polls_with_extras = array();
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
// Cached key.
$cache_key = 'forminator_count_polls_with_extra_' . $form_id;
// Check if cached data exists.
$cached_data = wp_cache_get( $cache_key, self::FORM_ENTRY_CACHE_GROUP );
if ( ! is_array( $cached_data ) ) {
$cached_data = array();
}
foreach ( $fields_element_id_with_extra as $field_element_id_with_extra ) {
$votes = array();
if ( isset( $cached_data[ $field_element_id_with_extra ] ) ) {
$votes = $cached_data[ $field_element_id_with_extra ];
} else {
$sql = "SELECT m.entry_id AS entry_id
FROM {$table_name} m
LEFT JOIN {$entry_table_name} e
ON (m.entry_id = e.entry_id)
WHERE e.form_id = %d
AND m.meta_key = %s
GROUP BY m.entry_id";
$sql = $wpdb->prepare( $sql, $form_id, esc_sql( $field_element_id_with_extra ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$entry_ids = $wpdb->get_col( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
if ( ! empty( $entry_ids ) ) {
$entry_id_placeholders = implode( ', ', array_fill( 0, count( $entry_ids ), '%d' ) );
$sql = "SELECT m.meta_value AS meta_value, COUNT(1) votes
FROM {$table_name} m
WHERE m.entry_id IN ({$entry_id_placeholders})
AND m.meta_key = 'extra'
GROUP BY m.meta_value ORDER BY votes DESC";
$sql = $wpdb->prepare( $sql, $entry_ids ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$votes = $wpdb->get_results( $sql, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
$cached_data[ $field_element_id_with_extra ] = $votes;
// Store the result in the cache.
wp_cache_set( $cache_key, $cached_data, self::FORM_ENTRY_CACHE_GROUP );
}
}
if ( ! empty( $votes ) ) {
$polls_with_extras[ $field_element_id_with_extra ] = array();
foreach ( $votes as $vote ) {
$polls_with_extras[ $field_element_id_with_extra ][ $vote['meta_value'] ] = $vote['votes'];
}
}
}
return $polls_with_extras;
}
/**
* Count entries by form
*
* @param int $form_id - the form id.
* @param mixed $db DB.
* @param bool $all_types Include draft, abandoned, etc.
*
* @return int - total entries
* @since 1.0
*/
public static function count_entries( $form_id, $db = false, $all_types = false ) {
if ( ! $db ) {
global $wpdb;
$db = $wpdb;
}
// Cached key.
$cache_key = 'forminator_count_entries_of_active_status_' . $form_id;
if ( $all_types ) {
$cache_key = 'forminator_count_entries_of_all_status_' . $form_id;
}
$entries_cache = wp_cache_get( $cache_key, self::FORM_COUNT_CACHE_GROUP );
$where = '';
if ( $entries_cache ) {
return $entries_cache;
} else {
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$where = $all_types ? " AND `status` != 'spam'" : " AND `status` = 'active'";
$sql = "SELECT count(`entry_id`) FROM {$table_name} WHERE `form_id` = %d {$where}";
$entries = $db->get_var( $db->prepare( $sql, $form_id ) );
if ( $entries ) {
wp_cache_set( $cache_key, $entries, self::FORM_COUNT_CACHE_GROUP );
return $entries;
}
}
return 0;
}
/**
* Count lead entries by form
*
* @param int $form_id Form Id.
* @param string $start_date Start date.
* @param string $end_date End date.
*
* @return int|string
*/
public static function count_leads( $form_id, $start_date = '', $end_date = '' ) {
global $wpdb;
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
// Cached key.
$cache_key = 'forminator_count_leads_' . $form_id;
$unique_id = md5( wp_json_encode( array( $start_date, $end_date ) ) );
// Get cached data.
$cached_data = wp_cache_get( $cache_key, self::FORM_ENTRY_CACHE_GROUP );
if ( ! is_array( $cached_data ) ) {
$cached_data = array();
}
if ( isset( $cached_data[ $unique_id ] ) ) {
return $cached_data[ $unique_id ];
} else {
$where = '';
if ( ! empty( $start_date ) && ! empty( $end_date ) ) {
$end_date = $end_date . ' 23:59:00';
$where .= $wpdb->prepare( ' AND ( e.date_created >= %s AND e.date_created <= %s )', esc_sql( $start_date ), esc_sql( $end_date ) );
}
$sql =
"SELECT count(DISTINCT e.`entry_id`) FROM {$table_name} m
LEFT JOIN {$entry_table_name} e ON(e.`entry_id` = m.`entry_id`)
WHERE e.`form_id` = %d AND m.meta_key = 'skip_form'
{$where}
AND m.meta_value = '0' AND e.`status` = 'active'";
$entries = $wpdb->get_var( $wpdb->prepare( $sql, $form_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery -- false positive
if ( ! $entries ) {
$entries = 0;
}
$cached_data[ $unique_id ] = $entries;
// Store the result in the cache.
wp_cache_set( $cache_key, $cached_data, self::FORM_ENTRY_CACHE_GROUP );
return $entries;
}
}
/**
* Count entries by form
*
* @param int $form_id - the form id.
*
* @return int - total entries
* @since 1.0
* @deprecated
*/
public static function count_entries_by_form_and_field( $form_id ) {
_deprecated_function( 'count_entries_by_form_and_field', '1.0.5' );
global $wpdb;
$field = '';
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$sql =
"SELECT count(m.`meta_id`) FROM {$table_name} m LEFT JOIN {$entry_table_name} e ON(e.`entry_id` = m.`entry_id`) WHERE e.`form_id` = %d AND m.`meta_key` = %s AND e.`status` = 'active'";
$entries = $wpdb->get_var( $wpdb->prepare( $sql, $form_id, $field ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
if ( $entries ) {
return $entries;
}
return 0;
}
/**
* Map Polls Entries with its votes
*
* @param int $form_id Form id.
* @param array $fields Fields.
*
* @return array
* @example {
* 'ELEMENT_ID' => 'NUMBER'
* 'answer-1' = 9
* }
*
* @since 1.0.5
*/
public static function map_polls_entries( $form_id, $fields ) {
$cache_key = 'poll_entries_' . $form_id;
$cached_entries = wp_cache_get( $cache_key, self::FORM_ENTRY_CACHE_GROUP );
if ( false !== $cached_entries ) {
return $cached_entries;
}
global $wpdb;
$map_entries = array();
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
// Make sure $form_id is always number.
if ( ! is_numeric( $form_id ) ) {
$form_id = 0;
}
$element_ids = array();
foreach ( $fields as $field ) {
$element_id = (string) $field['element_id'];
$element_ids[] = $element_id;
$title = sanitize_title( $field['title'] );
// First, escape the link for use in a LIKE statement.
$new_element_id_format = $wpdb->esc_like( 'answer-' );
// Add wildcards.
$new_element_id_format = $new_element_id_format . '%';
// find old format entries of this field.
$sql = "SELECT count(1) FROM {$table_name} m LEFT JOIN {$entry_table_name} e
ON (e.`entry_id` = m.`entry_id`)
WHERE e.form_id = %d AND m.meta_key NOT LIKE %s AND m.meta_value = '1' AND m.meta_key = %s LIMIT 1";
$old_format_entries = $wpdb->get_var( $wpdb->prepare( $sql, $form_id, esc_sql( $new_element_id_format ), esc_sql( $title ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
// old format exist.
if ( $old_format_entries ) {
// update old format entries if avail.
self::maybe_update_poll_entries_meta_key_to_element_id( $form_id, $title, $element_id );
}
}
if ( ! empty( $element_ids ) ) {
$element_ids_placeholders = implode( ', ', array_fill( 0, count( $element_ids ), '%s' ) );
$sql
= "SELECT m.meta_key as element_id, count(1) as votes
FROM {$table_name} m LEFT JOIN {$entry_table_name} e
ON (e.`entry_id` = m.`entry_id`)
WHERE e.form_id = {$form_id} AND m.meta_key IN ({$element_ids_placeholders}) GROUP BY m.meta_key";
$sql = $wpdb->prepare( $sql, $element_ids ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$results = $wpdb->get_results( $sql, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
foreach ( $results as $result ) {
$map_entries[ $result['element_id'] ] = $result['votes'];
}
}
wp_cache_set( $cache_key, $map_entries, self::FORM_ENTRY_CACHE_GROUP );
return $map_entries;
}
/**
* Map Polls Entries to be used for export
* Pretty much @see Form_Entry_Model::map_polls_entries(), but returning what's required for the export.
*
* @since 1.6
*
* @example {
* 'meta_id' => 'values'
* '2' = [
* 'date_created' = '1999-12-31 23:59:59',
* 'meta_key' = 'answer-1',
* 'is_spam' = '0',
* ]
* }
*
* @param int $form_id Form Id.
* @param array $fields Fields.
*
* @return array
*/
public static function map_polls_entries_for_export( $form_id, $fields ) {
global $wpdb;
$map_entries = array();
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
// Make sure $form_id is always number.
if ( ! is_numeric( $form_id ) ) {
$form_id = 0;
}
$element_ids = array();
foreach ( $fields as $field ) {
$element_id = (string) $field['element_id'];
$element_ids[] = $element_id;
$title = sanitize_title( $field['title'] );
// First, escape the link for use in a LIKE statement.
$new_element_id_format = $wpdb->esc_like( 'answer-' );
// Add wildcards.
$new_element_id_format = $new_element_id_format . '%';
// find old format entries of this field.
$sql = "SELECT count(1) FROM {$table_name} m LEFT JOIN {$entry_table_name} e
ON (e.`entry_id` = m.`entry_id`)
WHERE e.form_id = %d AND m.meta_key NOT LIKE %s AND m.meta_value = '1' AND m.meta_key = %s LIMIT 1";
$old_format_entries = $wpdb->get_var( $wpdb->prepare( $sql, $form_id, esc_sql( $new_element_id_format ), esc_sql( $title ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
// old format exist.
if ( $old_format_entries ) {
// update old format entries if avail.
self::maybe_update_poll_entries_meta_key_to_element_id( $form_id, $title, $element_id );
}
}
if ( ! empty( $element_ids ) ) {
$element_ids_placeholders = implode( ', ', array_fill( 0, count( $element_ids ), '%s' ) );
$sql
= "SELECT m.meta_id, m.meta_key, m.meta_value, m.date_created, e.status, m.entry_id
FROM {$table_name} m LEFT JOIN {$entry_table_name} e
ON (e.`entry_id` = m.`entry_id`)
WHERE e.form_id = {$form_id} AND m.meta_key IN ({$element_ids_placeholders})";
$sql = $wpdb->prepare( $sql, $element_ids ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$results = $wpdb->get_results( $sql, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
foreach ( $results as $result ) {
$map_entries[ $result['meta_id'] ]['entry_id'] = $result['entry_id'];
$map_entries[ $result['meta_id'] ]['status'] = $result['status'];
$map_entries[ $result['meta_id'] ]['date_created'] = $result['date_created'];
$map_entries[ $result['meta_id'] ]['meta_key'] = $result['meta_key']; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
$map_entries[ $result['meta_id'] ]['meta_value'] = $result['meta_value']; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
}
}
return $map_entries;
}
/**
* Update poll entries meta_key to its element_id
*
* @param int $form_id Form id.
* @param string $old_meta_key Old meta key.
* @param string $element_id Element Id.
*
* @since 1.0.5
*/
public static function maybe_update_poll_entries_meta_key_to_element_id( $form_id, $old_meta_key, $element_id ) {
global $wpdb;
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
// find entries that using old format.
$sql = "SELECT entry_id FROM {$entry_table_name} where form_id = %d";
$sql = $wpdb->prepare( $sql, $form_id ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$entry_ids = $wpdb->get_col( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
if ( ! empty( $entry_ids ) && count( $entry_ids ) > 0 ) {
$entry_ids = implode( ', ', $entry_ids );
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$wpdb->query(
$wpdb->prepare(
"UPDATE %s SET meta_key = %s, meta_value = %s WHERE entry_id IN (%s) AND meta_key = %s AND meta_value = '1'",
$table_name,
$element_id,
$entry_ids,
$old_meta_key,
$old_meta_key
)
);
}
}
/**
* Get entry date by ip and form
*
* @param int $form_id - the form id.
* @param string $ip - the user ip.
*
* @return string|bool
* @since 1.0
*/
public static function get_entry_date_by_ip_and_form( $form_id, $ip ) {
global $wpdb;
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$sql =
"SELECT m.`date_created` FROM {$table_name} m LEFT JOIN {$entry_table_name} e ON(e.`entry_id` = m.`entry_id`) WHERE e.`form_id` = %d AND m.`meta_key` = %s AND m.`meta_value` = %s order by m.`meta_id` desc limit 0,1";
$entry_date = $wpdb->get_var( $wpdb->prepare( $sql, $form_id, '_forminator_user_ip', $ip ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
if ( $entry_date ) {
return $entry_date;
}
return false;
}
/**
* Get amount submissions by current user
*
* @param int $form_id Form ID.
* @return int
*/
public static function count_user_entries( $form_id ) {
global $wpdb;
$user_id = get_current_user_id();
// Cached key.
$cache_key = 'forminator_count_user_entries_' . $form_id;
// Get cached data.
$cached_data = wp_cache_get( $cache_key, self::FORM_ENTRY_CACHE_GROUP );
if ( ! is_array( $cached_data ) ) {
$cached_data = array();
}
if ( isset( $cached_data[ $user_id ] ) ) {
return $cached_data[ $user_id ];
} else {
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$sql =
"SELECT COUNT(*) FROM {$table_name} m LEFT JOIN {$entry_table_name} e ON(e.`entry_id` = m.`entry_id`) WHERE e.`form_id` = %d AND m.`meta_key` = '_user_id' AND m.`meta_value` = %s";
$amount = $wpdb->get_var( $wpdb->prepare( $sql, $form_id, $user_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
$amount = intval( $amount );
$cached_data[ $user_id ] = $amount;
// Store the result in the cache.
wp_cache_set( $cache_key, $cached_data, self::FORM_ENTRY_CACHE_GROUP );
return $amount;
}
}
/**
* Get last entry by IP and form
*
* @param int $form_id - the form id.
* @param string $ip - the user ip.
*
* @return string|bool
* @since 1.0
*/
public static function get_last_entry_by_ip_and_form( $form_id, $ip ) {
$cache_key = 'last_entry_by_ip_' . $form_id . '_' . md5( $ip );
$cache_group = self::FORM_ENTRY_CACHE_GROUP . '_' . $form_id;
$cached_entry = wp_cache_get( $cache_key, $cache_group );
if ( false !== $cached_entry ) {
return $cached_entry;
}
global $wpdb;
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$sql =
"SELECT m.`entry_id` FROM {$table_name} m LEFT JOIN {$entry_table_name} e ON(e.`entry_id` = m.`entry_id`) WHERE e.`form_id` = %d AND m.`meta_key` = %s AND m.`meta_value` = %s order by m.`meta_id` desc limit 0,1";
$entry_id = $wpdb->get_var( $wpdb->prepare( $sql, $form_id, '_forminator_user_ip', $ip ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
if ( $entry_id ) {
wp_cache_set( $cache_key, $entry_id, $cache_group );
return $entry_id;
}
return false;
}
/**
* Get entry date by ip and form
*
* @param int $form_id - the form id.
* @param string $ip - the user ip.
* @param int $entry_id - the entry id.
* @param string $interval - the mysql interval. Eg (INTERVAL 1 HOUR).
*
* @return string|bool
* @since 1.0
*/
public static function check_entry_date_by_ip_and_form( $form_id, $ip, $entry_id, $interval = '' ) {
global $wpdb;
$current_date = date_i18n( 'Y-m-d H:i:s' );
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$interval = esc_sql( $interval );
$sql =
"SELECT m.`meta_id` FROM {$table_name} m LEFT JOIN {$entry_table_name} e ON(e.`entry_id` = m.`entry_id`) WHERE e.`form_id` = %d AND m.`meta_key` = %s AND m.`meta_value` = %s AND m.`entry_id` = %d AND DATE_ADD(m.`date_created`, {$interval}) < %s order by m.`meta_id` desc limit 0,1";
$entry = $wpdb->get_var( $wpdb->prepare( $sql, $form_id, '_forminator_user_ip', $ip, $entry_id, $current_date ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
if ( $entry ) {
return $entry;
}
return false;
}
/**
* Get active entry ID by payment identifier.
*
* @since 1.56
*
* @param int $form_id Form ID.
* @param string $meta_key Payment field meta key.
* @param string $identifier_key Payment identifier key.
* @param string $identifier_value Payment identifier value.
* @param int $excluded_entry_id Entry ID to exclude from lookup.
* @return int
*/
public static function get_active_entry_id_by_payment_identifier( $form_id, $meta_key, $identifier_key, $identifier_value, $excluded_entry_id = 0 ) {
if ( empty( $form_id ) || empty( $meta_key ) || empty( $identifier_key ) || empty( $identifier_value ) ) {
return 0;
}
global $wpdb;
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
// Payment fields are stored as serialized meta arrays, so match the exact identifier key/value pair.
$identifier_like = '%' . $wpdb->esc_like( ':"' . $identifier_key . '";s:' ) . '%' . $wpdb->esc_like( ':"' . $identifier_value . '"' ) . '%';
$sql = "SELECT m.`entry_id`
FROM {$table_name} m
LEFT JOIN {$entry_table_name} e
ON ( e.`entry_id` = m.`entry_id` )
WHERE e.`form_id` = %d
AND e.`status` = 'active'
AND e.`entry_id` != %d
AND m.`meta_key` = %s
AND m.`meta_value` LIKE %s
LIMIT 1";
$entry_id = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$wpdb->prepare(
$sql, // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$form_id,
$excluded_entry_id,
$meta_key,
$identifier_like
)
);
return (int) $entry_id;
}
/**
* Bulk delete form entries
*
* @param int $form_id - the form id.
* @param mixed $db - DB.
*
* @since 1.0
*/
public static function delete_by_form( $form_id, $db = false ) {
if ( ! $db ) {
global $wpdb;
$db = $wpdb;
}
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$sql = "SELECT GROUP_CONCAT(`entry_id`) FROM {$table_name} WHERE `form_id` = %d";
$entries = $db->get_var( $db->prepare( $sql, $form_id ) );
if ( $entries ) {
self::delete_by_entrys( $form_id, $entries, $db );
}
}
/**
* Delete by string of comma separated entry ids
*
* @param int $form_id Form id.
* @param string $entries Entries.
* @param bool|wpdb $db DB.
*
* @return bool
* @since 1.0
* @since 1.1 Add init addons and Add hooks `forminator_before_delete_entry`
*/
public static function delete_by_entrys( $form_id, $entries, $db = false ) {
if ( ! $db ) {
global $wpdb;
$db = $wpdb;
}
if ( empty( $form_id ) || empty( $entries ) ) {
return false;
}
$form_id = (int) $form_id;
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$table_meta_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
forminator_maybe_log( 'delete_by_entrys', $form_id, $entries );
$entries_to_array = explode( ',', $entries );
forminator_maybe_log( 'delete_by_entrys', $form_id, $entries_to_array );
$valid_entries_to_delete = array();
if ( ! empty( $entries_to_array ) && is_array( $entries_to_array ) ) {
foreach ( $entries_to_array as $entry_id ) {
$entry_id = (int) $entry_id;
$entry_model = new Forminator_Form_Entry_Model( $entry_id );
// validate : entry must be exist on requested $form_id.
if ( $form_id === (int) $entry_model->form_id ) {
$valid_entries_to_delete[] = $entry_id;
self::attach_addons_on_before_delete_entry( $form_id, $entry_model );
self::entry_delete_upload_files( $form_id, $entry_model );
}
}
}
if ( empty( $valid_entries_to_delete ) ) {
return false;
}
// modify $entries with $valid_entries_to_delete.
$entries = implode( ', ', $valid_entries_to_delete );
/**
* Fires just before an entry getting deleted
*
* @param int $form_id Current Form ID.
* @param int $entry_id Current Entry ID to be deleted.
*
* @since 1.1
*/
do_action_ref_array( 'forminator_before_delete_entries', array( $form_id, $entries ) );
$sql = "DELETE FROM {$table_meta_name} WHERE `entry_id` IN ($entries)";
$db->query( $sql );
$sql = "DELETE FROM {$table_name} WHERE `entry_id` IN ($entries)";
$db->query( $sql );
self::delete_form_entry_cache( $form_id );
wp_cache_delete( 'all_form_types', self::FORM_COUNT_CACHE_GROUP );
$model = forminator_get_model_from_id( $form_id );
if ( is_object( $model ) ) {
wp_cache_delete( $model->get_entry_type() . '_form_type', self::FORM_COUNT_CACHE_GROUP );
}
}
/**
* Delete by entry
*
* @param int $entry_id - the entry id.
*
* @since 1.0
* @since 1.1 Add init addons and Add hooks `forminator_before_delete_entry`
*/
public static function delete_by_entry( $entry_id ) {
global $wpdb;
$table_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY );
$table_meta_name = Forminator_Database_Tables::get_table_name( Forminator_Database_Tables::FORM_ENTRY_META );
$entry_model = new Forminator_Form_Entry_Model( $entry_id );
if ( empty( $entry_model->entry_id ) ) {
return;
}
$form_id = (int) $entry_model->form_id;
$entry_id = (int) $entry_id;
forminator_maybe_log( 'forminator_before_delete_entry', $form_id, $entry_id );
/**
* Fires just before an entry getting deleted
*
* @param int $form_id Current Form ID.
* @param int $entry_id Current Entry ID to be deleted.
*
* @since 1.1
*/
do_action_ref_array( 'forminator_before_delete_entry', array( $form_id, $entry_id ) );
self::attach_addons_on_before_delete_entry( $form_id, $entry_model );
self::entry_delete_upload_files( $form_id, $entry_model );
$wpdb->query( $wpdb->prepare( 'DELETE FROM ' . esc_sql( $table_meta_name ) . ' WHERE `entry_id` = %d', $entry_id ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$wpdb->query( $wpdb->prepare( 'DELETE FROM ' . esc_sql( $table_name ) . ' WHERE `entry_id` = %d', $entry_id ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
wp_cache_delete( $entry_id, self::FORM_ENTRY_CACHE_GROUP );
self::delete_form_entry_cache( $form_id );
wp_cache_delete( 'all_form_types', self::FORM_COUNT_CACHE_GROUP );
wp_cache_delete( $entry_model->entry_type . '_form_type', self::FORM_COUNT_CACHE_GROUP );
}
/**
* Delete files from upload folder
*
* @param int $form_id Form Id.
* @param Forminator_Form_Entry_Model $entry_model Form Entry model.
*
* @since 1.7
*/
public static function entry_delete_upload_files( $form_id, $entry_model ) {
$custom_form = Forminator_Base_Form_Model::get_model( $form_id );
$submission_file = 'delete';
if ( is_object( $custom_form ) ) {
$settings = $custom_form->settings;
$submission_file = isset( $settings['submission-file'] ) ? $settings['submission-file'] : 'delete';
}
if ( 'delete' === $submission_file ) {
$upload_root = wp_upload_dir();
if ( empty( $upload_root['basedir'] ) ) {
return;
}
$upload_root = $upload_root['basedir'];
foreach ( $entry_model->meta_data as $slug => $meta_data ) {
$meta_value = $meta_data['value'];
$field_type = Forminator_Core::get_field_type( $slug );
if ( in_array( $field_type, array( 'upload', 'signature' ), true )
&& is_array( $meta_value ) && isset( $meta_value['file'] ) ) {
$file_path = is_array( $meta_value['file']['file_path'] ) ? $meta_value['file']['file_path'] : array( $meta_value['file']['file_path'] );
if ( ! empty( $file_path ) ) {
foreach ( $file_path as $key => $path ) {
if ( ! is_string( $path ) || '' === $path ) {
continue;
}
$basename = wp_basename( $path );
$sanitized = sanitize_file_name( $basename );
if ( $basename !== $sanitized ) {
continue;
}
if ( ! forminator_attachment_path_is_allowed( $path ) ) {
continue;
}
$delete_attachment = false;
if ( isset( $meta_value['file']['file_url'][ $key ] ) ) {
$attachment_id = attachment_url_to_postid( $meta_value['file']['file_url'][ $key ] );
if ( $attachment_id ) {
$delete_attachment = wp_delete_attachment( $attachment_id );
}
}
if ( ! $delete_attachment ) {
wp_delete_file_from_directory( $path, $upload_root );
}
}
}
}
}
}
}
/**
* Convert meta value to string
* Useful on displaying metadata without PHP warning on conversion
*
* @param string $field_type Field type.
* @param mixed $meta_value Meta value.
* @param bool $allow_html Allow HTML.
* @param int $truncate truncate returned string (usefull if display container is limited).
* @param mixed $field Field data (optional).
*
* @return string
* @since 1.0.5
*/
public static function meta_value_to_string( $field_type, $meta_value, $allow_html = false, $truncate = PHP_INT_MAX, $field = null ) {
switch ( $field_type ) {
case 'postdata':
$string_value = self::postdata_to_string( $meta_value, $allow_html, $truncate );
break;
case 'time':
if ( ! isset( $meta_value['hours'] ) || ! isset( $meta_value['minutes'] ) ) {
$string_value = '';
} else {
$string_value = sprintf( '%02d', $meta_value['hours'] ) . ':' . sprintf( '%02d', $meta_value['minutes'] ) . ' ' . ( isset( $meta_value ['ampm'] ) ? $meta_value['ampm'] : '' );
}
// truncate.
if ( strlen( $string_value ) > $truncate ) {
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
break;
case 'date':
if ( ! isset( $meta_value['year'] ) || ! isset( $meta_value['month'] ) || ! isset( $meta_value['day'] ) ) {
// is it date picker?
if ( ! empty( $meta_value ) && is_string( $meta_value ) ) {
$string_value = $meta_value;
} else {
$string_value = '';
}
} elseif ( empty( $meta_value['year'] ) || empty( $meta_value['month'] ) || empty( $meta_value['day'] ) ) {
$string_value = '';
} else {
$date_value = $meta_value['year'] . '/' . sprintf( '%02d', $meta_value['month'] ) . '/' . sprintf( '%02d', $meta_value['day'] );
if ( isset( $meta_value['format'] ) && ! empty( $meta_value['format'] ) ) {
$string_value = date_i18n( $meta_value['format'], strtotime( $date_value ) );
} else {
$string_value = date_i18n( get_option( 'date_format' ), strtotime( $date_value ) );
}
}
// truncate.
if ( strlen( $string_value ) > $truncate ) {
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
break;
case 'email':
if ( ! empty( $meta_value ) ) {
$string_value = $meta_value;
// truncate.
if ( $allow_html ) {
// make link.
$email = $string_value;
// truncate.
if ( strlen( $email ) > $truncate ) {
$email = substr( $email, 0, $truncate ) . '...';
}
$string_value = '' . $email . '';
} elseif ( strlen( $string_value ) > $truncate ) {
// truncate url.
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
} else {
$string_value = '';
}
break;
case 'url':
if ( ! empty( $meta_value ) ) {
$string_value = $meta_value;
// truncate.
if ( $allow_html ) {
// make link.
$website = esc_url( $string_value );
// truncate.
if ( strlen( $website ) > $truncate ) {
$website = substr( $website, 0, $truncate ) . '...';
}
$string_value = '' . $website . '';
} elseif ( strlen( $string_value ) > $truncate ) {
// truncate url.
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
} else {
$string_value = '';
}
break;
case 'upload':
$file = '';
if ( isset( $meta_value['file'] ) ) {
$file = $meta_value['file'];
}
if ( ! empty( $file ) && is_array( $file ) && isset( $file['file_url'] ) && ! empty( $file['file_url'] ) ) {
if ( $allow_html ) {
// make link.
$string_value = '';
$upload_count = 0;
$file_values = is_array( $file['file_url'] ) ? $file['file_url'] : array( $file['file_url'] );
foreach ( $file_values as $file_value ) {
$url = $file_value;
$file_name = basename( $url );
$file_name = ! empty( $file_name ) ? $file_name : esc_html__( '(no filename)', 'forminator' );
// truncate.
if ( strlen( $file_name ) > $truncate ) {
$file_name = substr( $file_name, 0, $truncate ) . '...';
}
++$upload_count;
if ( $upload_count > 1 ) {
$string_value .= '
';
}
$string_value .= '' . $file_name . '';
}
} else {
// truncate url.
$string_value = is_array( $file['file_url'] ) ? implode( ', ', $file['file_url'] ) : $file['file_url'];
if ( strlen( $string_value ) > $truncate ) {
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
}
} else {
$string_value = '';
}
break;
case 'checkbox':
if ( is_array( $meta_value ) ) {
$string_value = implode( ', ', $meta_value );
} elseif ( is_string( $meta_value ) ) {
$string_value = $meta_value;
} else {
$string_value = '';
}
// truncate.
if ( strlen( $string_value ) > $truncate ) {
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
break;
case 'calculation':
if ( ! is_array( $meta_value ) ) {
if ( '' === (string) $meta_value ) {
$string_value = '0.0';
} elseif ( is_array( $field ) && ! empty( $field ) ) {
// Apply number formatting for scalar calculation values.
$string_value = Forminator_Field::forminator_number_formatting( $field, $meta_value );
} else {
$string_value = (string) $meta_value;
}
} elseif ( ! empty( $meta_value['error'] ) ) {
$string_value = $meta_value['error'];
} else {
$result = null;
if ( isset( $meta_value['result'] ) && is_array( $field ) && ! empty( $field ) ) {
$result = Forminator_Field::forminator_number_formatting( $field, $meta_value['result'] );
} elseif ( isset( $meta_value['formatting_result'] ) ) {
$result = $meta_value['formatting_result'];
} elseif ( isset( $meta_value['result'] ) ) {
$result = $meta_value['result'];
}
if ( null === $result ) {
$string_value = '0.0';
} elseif ( is_infinite( floatval( $result ) ) ) {
$string_value = 'INF';
} else {
$string_value = (string) $result;
}
}
// truncate.
if ( strlen( $string_value ) > $truncate ) {
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
break;
case 'stripe':
case 'stripe-ocs':
// In case stripe requested without mapper, we return transaction_id.
$string_value = '';
if ( is_array( $meta_value ) && isset( $meta_value['transaction_id'] ) ) {
if ( ! empty( $meta_value['transaction_id'] ) ) {
$string_value = $meta_value['transaction_id'];
}
}
// truncate.
if ( strlen( $string_value ) > $truncate ) {
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
/**
* Filter string value of Stripe meta entry
*
* @param string $string_value
* @param array $meta_value
* @param boolean $allow_html
* @param int $truncate
*
* @return string
* @since 1.7
*/
$string_value = apply_filters( 'forminator_entry_stripe_meta_value_to_string', $string_value, $meta_value, $allow_html, $truncate );
break;
case 'password':
// Hide value for login/template forms.
$string_value = '*****';
break;
case 'name':
if ( is_array( $meta_value ) ) {
$string_value = implode( ' ', array_filter( array_values( $meta_value ) ) );
} else {
$string_value = (string) $meta_value;
}
if ( strlen( $string_value ) > $truncate ) {
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
break;
case 'slider':
// Change behavior for range slider.
if ( is_array( $meta_value ) && isset( $meta_value['min'] ) && isset( $meta_value['max'] ) ) {
$string_value = $meta_value['min'] . ' - ' . $meta_value['max'];
break;
}
// fall-through.
case 'currency':
case 'number':
$raw = isset( $meta_value['result'] ) ? $meta_value['result'] : $meta_value;
if ( is_array( $field ) && ! empty( $field ) ) {
$string_value = Forminator_Field::forminator_number_formatting( $field, (string) $raw );
} else {
$string_value = (string) $raw;
}
// truncate.
if ( strlen( $string_value ) > $truncate ) {
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
break;
default:
// base flattener.
// implode on array.
if ( is_array( $meta_value ) ) {
$string_value = wp_json_encode( $meta_value );
} else {
// or juggling to string.
$string_value = (string) $meta_value;
}
// truncate.
if ( strlen( $string_value ) > $truncate ) {
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
break;
}
/**
* Filter string value of meta entry
*
* @param string $string_value
* @param string $field_type
* @param array $meta_value
* @param boolean $allow_html
* @param int $truncate
*
* @return string
* @since 1.7
*/
$string_value = apply_filters( 'forminator_entry_meta_value_to_string', $string_value, $field_type, $meta_value, $allow_html, $truncate );
return $string_value;
}
/**
* Process postdata meta value
*
* @param array $meta_value Meta value.
* @param bool $allow_html Allow HTML.
* @param int $truncate Truncate.
*
* @return string
* @since 1.17.0
*/
public static function postdata_to_string( $meta_value, $allow_html = false, $truncate = PHP_INT_MAX ) {
if ( empty( $meta_value ) ) {
$string_value = '';
} elseif ( is_string( $meta_value ) ) {
$string_value = $meta_value;
} elseif ( ! empty( $meta_value['postdata'] ) ) {
$post_id = $meta_value['postdata'];
// Title.
if ( current_user_can( 'edit_post', $post_id ) ) {
$url = get_edit_post_link( $post_id, 'link' );
} else {
// is not logged in.
$url = get_home_url();
}
// Title make link.
$title = get_the_title( $post_id );
$post_content = isset( $meta_value['value']['post-content'] ) ? $meta_value['value']['post-content'] : '';
$post_excerpt = isset( $meta_value['value']['post-excerpt'] ) ? $meta_value['value']['post-excerpt'] : '';
$category = isset( $meta_value['value']['category'] ) ? $meta_value['value']['category'] : array();
$tags = isset( $meta_value['value']['post_tag'] ) ? $meta_value['value']['post_tag'] : array();
$post_custom = isset( $meta_value['value']['post-custom'] ) ? $meta_value['value']['post-custom'] : '';
$tax_keys = forminator_list_custom_taxonomies( $meta_value['value'] );
if ( $allow_html ) {
$post_image = ! empty( $meta_value['value']['post-image'] ) && ! empty( $meta_value['value']['post-image']['attachment_id'] )
? $meta_value['value']['post-image']['attachment_id']
: '';
$string_value = self::get_postdata_title( $title, 'allow_html', $truncate, $url );
$string_value .= self::get_postdata_content( $post_content, true, $truncate );
$string_value .= self::get_postdata_excerpt( $post_excerpt, true, $truncate );
$string_value .= self::get_postdata_categories( $category, true );
$string_value .= self::get_postdata_tags( $tags, true );
$string_value .= self::get_postdata_image( $post_image, true );
$string_value .= self::get_postdata_customfields( $post_custom, true );
if ( ! empty( $tax_keys ) ) {
foreach ( $tax_keys as $tax_key => $tax_name ) {
$taxonomy_val = isset( $meta_value['value'][ $tax_name ] ) ? $meta_value['value'][ $tax_name ] : array();
$string_value .= self::get_postdata_taxonomies( $tax_name, $taxonomy_val );
}
}
} else {
$post_image = ! empty( $meta_value['value']['post-image'] ) && ! empty( $meta_value['value']['post-image']['uploaded_file'] )
? $meta_value['value']['post-image']['uploaded_file'][0]
: '';
$string_value = self::get_postdata_title( $title, 'no_html', $truncate );
$string_value .= self::get_postdata_content( $post_content, false, $truncate );
$string_value .= self::get_postdata_excerpt( $post_excerpt, false, $truncate );
$string_value .= self::get_postdata_categories( $category, false );
$string_value .= self::get_postdata_tags( $tags, false );
$string_value .= self::get_postdata_image( $post_image, false );
$string_value .= self::get_postdata_customfields( $post_custom, false, $truncate );
if ( ! empty( $tax_keys ) ) {
foreach ( $tax_keys as $tax_key => $tax_name ) {
$taxonomy_val = isset( $meta_value['value'][ $tax_name ] ) ? $meta_value['value'][ $tax_name ] : array();
$string_value .= self::get_postdata_taxonomies( $tax_name, $taxonomy_val, false );
}
}
// truncate.
if ( strlen( $string_value ) > $truncate ) {
$string_value = substr( $string_value, 0, $truncate ) . '...';
}
}
} else {
// Draft postdata values.
$title = isset( $meta_value['post-title'] ) ? $meta_value['post-title'] : '';
$post_content = isset( $meta_value['post-content'] ) ? $meta_value['post-content'] : '';
$post_excerpt = isset( $meta_value['post-excerpt'] ) ? $meta_value['post-excerpt'] : '';
$category = isset( $meta_value['category'] ) ? $meta_value['category'] : array();
$tags = isset( $meta_value['post_tag'] ) ? $meta_value['post_tag'] : array();
$tax_keys = forminator_list_custom_taxonomies( $meta_value );
$string_value = self::get_postdata_title( $title, 'draft', $truncate );
$string_value .= self::get_postdata_content( $post_content, true, $truncate );
$string_value .= self::get_postdata_excerpt( $post_excerpt, true, $truncate );
$string_value .= self::get_postdata_categories( $category, true );
$string_value .= self::get_postdata_tags( $tags, true );
if ( ! empty( $tax_keys ) ) {
foreach ( $tax_keys as $tax_key => $tax_name ) {
$taxonomy_val = isset( $meta_value[ $tax_name ] ) ? $meta_value[ $tax_name ] : array();
$string_value .= self::get_postdata_taxonomies( $tax_name, $taxonomy_val );
}
}
// Custom fields are not being saved in drafts but automatically created after full submission.
}
return $string_value;
}
/**
* Get the postdata title depending on context
*
* @param string $value Value.
* @param string $type allow_html, no_html, draft.
* @param int $truncate Truncate, Default: PHP_INT_MAX.
* @param string $url URL.
*
* @since 1.17.0
*/
public static function get_postdata_title( $value, $type = 'allow_html', $truncate = PHP_INT_MAX, $url = '' ) {
if ( empty( $value ) ) {
return;
}
$title = ! empty( $value ) ? $value : esc_html__( '(no title)', 'forminator' );
$title = forminator_truncate_text( wp_kses_post( $title ), $truncate );
$label = esc_html__( 'Title', 'forminator' );
if ( 'no_html' !== $type ) {
$value = '' . $label . ': ';
}
if ( 'allow_html' === $type ) {
$value .= '' . $title . '';
} elseif ( 'draft' === $type ) {
$value .= $title;
} else {
$value = $label . ': ';
$value .= $title . ' | ';
}
return $value;
}
/**
* Get the postdata content depending on context
*
* @param string $value Value.
* @param bool $allow_html Allow HTML.
* @param int $truncate Truncate.
*
* @since 1.17.0
*/
public static function get_postdata_content( $value = '', $allow_html = true, $truncate = PHP_INT_MAX ) {
if ( empty( $value ) ) {
return '';
}
$post_content = forminator_truncate_text( $value, $truncate );
$label = esc_html__( 'Content', 'forminator' );
if ( $allow_html ) {
$value = '