File "FrmProEntriesController.php"
Full path: /home/bud/public_html/swamp/wp-admin/wp-content/plugins/formidable-pro/classes/controllers/FrmProEntriesController.php
File size: 115.56 KB
MIME-type: text/x-php
Charset: utf-8
<?php
if ( ! defined( 'ABSPATH' ) ) {
die( 'You are not allowed to call this page directly.' );
}
class FrmProEntriesController {
public static function remove_fullscreen( $init ) {
if ( isset( $init['plugins'] ) ) {
$init['plugins'] = str_replace('wpfullscreen,', '', $init['plugins']);
$init['plugins'] = str_replace('fullscreen,', '', $init['plugins']);
}
return $init;
}
public static function data_sort( $options ) {
natcasesort($options); //TODO: add sorting options
return $options;
}
/* Back End CRUD */
public static function show_comments( $entry ) {
$id = $entry->id;
$user_ID = get_current_user_id();
if ( $_POST && isset($_POST['frm_comment']) && ! empty($_POST['frm_comment']) ) {
$meta_key = '';
$meta_value = array(
'comment' => $_POST['frm_comment'],
'user_id' => $user_ID,
);
FrmEntryMeta::add_entry_meta( $_POST['item_id'], 0, $meta_key, $meta_value );
//send email notifications
}
$comments = FrmEntryMeta::getAll( array( 'item_id' => $id, 'field_id' => 0), ' ORDER BY it.created_at ASC', '', true);
$date_format = get_option( 'date_format' );
$time_format = get_option( 'time_format' );
include FrmProAppHelper::plugin_path() . '/classes/views/frmpro-entries/show.php';
}
public static function add_new_entry_link( $form ) {
FrmProEntriesHelper::show_new_entry_button($form);
}
public static function new_entry() {
$form_id = FrmAppHelper::get_param( 'form', '', 'get', 'absint' );
if ( $form_id ) {
$form = FrmForm::getOne($form_id);
self::get_new_vars('', $form);
} else {
include(FrmProAppHelper::plugin_path() . '/classes/views/frmpro-entries/new-selection.php');
}
}
public static function create() {
if ( ! current_user_can('frm_create_entries') ) {
return FrmEntriesController::display_list();
}
$params = FrmForm::get_admin_params();
$record = false;
$form = false;
if ( $params['form'] ) {
$form = FrmForm::getOne( $params['form'] );
}
if ( ! $form ) {
return;
}
$errors = FrmEntryValidate::validate( wp_unslash( $_POST ) );
if ( count($errors) > 0 ) {
self::get_new_vars($errors, $form);
return;
}
if ( ( isset( $_POST[ 'frm_page_order_' . $form->id ] ) || FrmProFormsHelper::going_to_prev( $form->id ) ) && ! FrmProFormsHelper::saving_draft() ) {
self::get_new_vars('', $form);
return;
}
$_SERVER['REQUEST_URI'] = str_replace( '&frm_action=new', '', FrmAppHelper::get_server_value( 'REQUEST_URI' ) );
global $frm_vars;
if ( empty( $frm_vars['created_entries'][ $form->id ] ) ) {
$frm_vars['created_entries'][ $form->id ] = array();
}
if ( ! isset( $frm_vars['created_entries'][ $_POST['form_id'] ]['entry_id'] ) ) {
$record = FrmEntry::create( $_POST );
$frm_vars['created_entries'][ $form->id ]['entry_id'] = $record;
}
if ( $record ) {
if ( FrmProFormsHelper::saving_draft() ) {
$message = __( 'Draft was Successfully Created', 'formidable-pro' );
} else {
$message = __( 'Entry was Successfully Created', 'formidable-pro' );
}
self::get_edit_vars($record, $errors, $message);
} else {
self::get_new_vars($errors, $form);
}
}
public static function edit() {
$id = FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
if ( ! current_user_can('frm_edit_entries') ) {
return FrmEntriesController::show($id);
}
return self::get_edit_vars($id);
}
public static function update() {
$id = FrmAppHelper::get_param( 'id', '', 'get', 'absint' );
if ( ! current_user_can('frm_edit_entries') ) {
return FrmEntriesController::show($id);
}
$message = '';
$errors = FrmEntryValidate::validate( wp_unslash( $_POST ) );
if ( empty( $errors ) ) {
if ( isset( $_POST['form_id'] ) && ( isset( $_POST[ 'frm_page_order_' . $_POST['form_id'] ] ) || FrmProFormsHelper::going_to_prev( $_POST['form_id'] ) ) && ! FrmProFormsHelper::saving_draft() ) {
return self::get_edit_vars($id);
} else {
FrmEntry::update( $id, $_POST );
if ( isset($_POST['form_id']) && FrmProFormsHelper::saving_draft() ) {
$message = __( 'Draft was Successfully Updated', 'formidable-pro' );
} else {
$message = __( 'Entry was Successfully Updated', 'formidable-pro' );
}
$message .= ' <a href="?page=formidable-entries&form=' . absint( $_POST['form_id'] ) . '"> ' . __( 'Go Back to Entries', 'formidable-pro' ) . '</a>';
}
}
return self::get_edit_vars($id, $errors, $message);
}
public static function duplicate() {
$params = FrmForm::get_admin_params();
if ( ! current_user_can('frm_create_entries') ) {
return FrmEntriesController::show($params['id']);
}
$message = '';
$errors = '';
$record = FrmEntry::duplicate( $params['id'] );
if ( $record ) {
$message = __( 'Entry was Successfully Duplicated', 'formidable-pro' );
} else {
$errors = __( 'There was a problem duplicating that entry', 'formidable-pro' );
}
if ( ! empty( $errors ) ) {
return FrmEntriesController::display_list( $message, $errors );
} else {
return self::get_edit_vars( $record, array(), $message );
}
}
/**
* Delete all entries in a form when the 'delete all' button is clicked.
*
* @since 4.02.04
*/
public static function destroy_all() {
if ( ! current_user_can( 'frm_delete_entries' ) || ! wp_verify_nonce( FrmAppHelper::simple_get( '_wpnonce', '', 'sanitize_text_field' ), '-1' ) ) {
$frm_settings = FrmAppHelper::get_settings();
wp_die( esc_html( $frm_settings->admin_permission ) );
}
$params = FrmForm::get_admin_params();
$message = '';
$form_id = (int) $params['form'];
if ( $form_id ) {
$entry_ids = FrmDb::get_col( 'frm_items', array( 'form_id' => $form_id ) );
$action = FrmFormAction::get_action_for_form( $form_id, 'wppost', 1 );
if ( $action ) {
// This action takes a while, so only trigger it if there are posts to delete.
foreach ( $entry_ids as $entry_id ) {
do_action( 'frm_before_destroy_entry', $entry_id );
unset( $entry_id );
}
}
$results = self::delete_form_entries( $form_id );
if ( $results ) {
$message = 'destroy_all';
FrmEntry::clear_cache();
}
} else {
$message = 'no_entries_selected';
}
$url = admin_url( 'admin.php?page=formidable-entries&frm-full=1&frm_action=list&form=' . absint( $form_id ) );
if ( $message ) {
$url .= '&message=' . $message;
}
wp_safe_redirect( $url );
die();
}
/**
* @since 4.02.04
*
* @param int $form_id
*/
private static function delete_form_entries( $form_id ) {
global $wpdb;
$form_ids = self::get_child_form_ids( $form_id );
$meta_query = $wpdb->prepare( "DELETE em.* FROM {$wpdb->prefix}frm_item_metas as em INNER JOIN {$wpdb->prefix}frm_items as e on (em.item_id=e.id) WHERE form_id=%d", $form_id );
$entry_query = $wpdb->prepare( "DELETE FROM {$wpdb->prefix}frm_items WHERE form_id=%d", $form_id );
if ( ! empty( $form_ids ) ) {
$form_query = ' OR form_id in (' . $form_ids . ')';
$meta_query .= $form_query;
$entry_query .= $form_query;
}
$wpdb->query( $meta_query ); // WPCS: unprepared SQL ok.
return $wpdb->query( $entry_query ); // WPCS: unprepared SQL ok.
}
/**
* @since 4.02.04
*
* @param int $form_id
* @param bool|string $implode
*/
private static function get_child_form_ids( $form_id, $implode = ',' ) {
$form_ids = FrmProForm::get_child_form_ids( $form_id );
if ( $implode ) {
$form_ids = implode( $implode, $form_ids );
}
return $form_ids;
}
public static function bulk_actions( $action = 'list-form' ) {
$params = FrmForm::get_admin_params();
$errors = array();
$bulkaction = '-1';
if ( $action == 'list-form' ) {
if ( $_REQUEST['bulkaction'] != '-1' ) {
$bulkaction = sanitize_text_field( $_REQUEST['bulkaction'] );
} else if ( $_POST['bulkaction2'] != '-1' ) {
$bulkaction = sanitize_text_field( $_REQUEST['bulkaction2'] );
}
} else {
$bulkaction = str_replace('bulk_', '', $action);
}
$items = FrmAppHelper::get_param( 'item-action', '', 'get', 'sanitize_text_field' );
if ( empty( $items ) ) {
$errors[] = __( 'No entries were specified', 'formidable-pro' );
} else {
$frm_settings = FrmAppHelper::get_settings();
if ( ! is_array($items) ) {
$items = explode(',', $items);
}
if ( $bulkaction == 'delete' ) {
if ( ! current_user_can( 'frm_delete_entries' ) ) {
$errors[] = $frm_settings->admin_permission;
} else {
if ( is_array($items) ) {
foreach ( $items as $item_id ) {
FrmEntry::destroy($item_id);
}
}
}
} else if ( $bulkaction == 'csv' ) {
FrmAppHelper::permission_check('frm_view_entries');
$form_id = $params['form'];
if ( ! $form_id ) {
$form = FrmForm::get_published_forms( array(), 1 );
if ( ! empty($form) ) {
$form_id = $form->id;
} else {
$errors[] = __( 'No form was found', 'formidable-pro' );
}
}
if ( $form_id && is_array($items) ) {
echo '<script type="text/javascript">window.onload=function(){location.href="' . esc_url_raw( admin_url( 'admin-ajax.php?form=' . $form_id . '&action=frm_entries_csv&item_id=' . implode( ',', $items ) ) ) . '";}</script>';
}
}
}
FrmEntriesController::display_list( '', $errors );
}
/* Front End CRUD */
/*
* Determine if this is a new entry or if we're editing an old one
*/
public static function maybe_editing( $continue, $form_id, $action = 'new' ) {
$form_submitted = FrmAppHelper::get_param( 'form_id', '', 'get', 'absint' );
if ( $action == 'new' || $action == 'preview' ) {
$continue = true;
} else {
$continue = ( $form_submitted && (int) $form_id != $form_submitted );
}
return $continue;
}
public static function check_draft_status( $values, $id ) {
if ( ! FrmProEntriesHelper::get_field( 'is_draft', $id ) || $values['is_draft'] ) {
// if entry draft status is unchanged
return $values;
}
//add the create hooks since the entry is switching draft status
add_action('frm_after_update_entry', 'FrmProEntriesController::add_published_hooks', 2, 2);
/**
* Do something when a draft entry is officially saved
*
* @since 3.0.08
*/
do_action(
'frm_after_complete_entry_processed',
array(
'entry_id' => $id,
'form' => $values['form_id'],
)
);
//change created timestamp
$values['created_at'] = $values['updated_at'];
return $values;
}
public static function remove_draft_hooks( $entry_id ) {
if ( ! FrmProEntriesHelper::get_field('is_draft', $entry_id) ) {
return;
}
// don't let sub entries remove these hooks
$entry = FrmEntry::getOne($entry_id);
if ( $entry->parent_item_id ) {
return;
}
//remove hooks if saving as draft
remove_action('frm_after_create_entry', 'FrmProEntriesController::set_cookie', 20);
remove_action('frm_after_create_entry', 'FrmFormActionsController::trigger_create_actions', 20);
add_action( 'frm_after_create_entry', 'FrmProFormActionsController::trigger_draft_actions', 10, 2 );
// trigger after draft save hook
do_action( 'frm_after_draft_entry_processed', array( 'entry_id' => $entry_id, 'form' => $entry->form_id ) );
}
//add the create hooks since the entry is switching draft status
public static function add_published_hooks( $entry_id, $form_id ) {
do_action( 'frm_after_create_entry', $entry_id, $form_id );
do_action( 'frm_after_create_entry_' . $form_id, $entry_id );
remove_action( 'frm_after_update_entry', 'FrmProEntriesController::add_published_hooks', 2 );
remove_action( 'frm_after_update_entry', 'FrmProFormActionsController::trigger_update_actions', 10, 2 );
}
public static function process_update_entry( $params, $errors, $form, $args ) {
self::maybe_autosave_on_page_turn( $errors, $form );
if ( $params['action'] === 'create' && FrmFormsController::just_created_entry( $form->id ) ) {
self::success_after_create( $params, $form, $args );
} elseif ( $params['action'] === 'update' && empty( $errors ) ) {
if ( self::entry_previously_saved( $params ) ) {
return;
}
//check if user is allowed to update
if ( ! FrmProEntriesHelper::user_can_edit( (int) $params['id'], $form ) ) {
$frm_settings = FrmAppHelper::get_settings();
wp_die(do_shortcode($frm_settings->login_msg));
}
//update, but don't check for confirmation if saving draft
if ( FrmProFormsHelper::saving_draft() ) {
FrmEntry::update( $params['id'], $_POST );
do_action( 'frm_after_draft_entry_processed', array( 'entry_id' => $params['id'], 'form' => $form ) );
return;
}
//don't update if going back
if ( isset( $_POST[ 'frm_page_order_' . $form->id ] ) || FrmProFormsHelper::going_to_prev( $form->id ) ) {
return;
}
FrmEntry::update( $params['id'], $_POST );
$success_args = array( 'action' => $params['action'], 'id' => $params['id'] );
if ( $params['action'] != 'create' && FrmProEntriesHelper::is_new_entry($params['id']) ) {
$success_args['action'] = 'create';
}
self::trigger_redirect( $form, $success_args, $args );
} elseif ( $params['action'] === 'destroy' ) {
//if the user who created the entry is deleting it
self::ajax_destroy($form->id, false, false);
}
}
private static function success_after_create( $params, $form, $args ) {
global $frm_vars;
$entry_id = $frm_vars['created_entries'][ $form->id ]['entry_id'];
$params['id'] = $entry_id;
self::set_cookie( $entry_id, $form->id );
}
private static function trigger_redirect( $form, $params, $args ) {
$is_autosave = FrmAppHelper::get_post_param( 'frm_autosaving', '', 'sanitize_text_field' );
if ( $is_autosave == 1 ) {
return;
}
$conf_method = self::get_conf_method_after_save( $form, $params );
if ( $conf_method == 'redirect' ) {
FrmFormsController::trigger_redirect( $form, $params, $args );
}
}
private static function &entry_previously_saved( $params ) {
global $frm_vars;
$saved = ( isset( $frm_vars['saved_entries'] ) && in_array( (int) $params['id'], (array) $frm_vars['saved_entries'] ) );
return $saved;
}
/**
* @since 2.3
*/
private static function maybe_autosave_on_page_turn( $errors, $form ) {
if ( ! empty( $errors ) || ! is_user_logged_in() ) {
return;
}
// the entry is already getting saved
$last_page = ! isset( $_POST[ 'frm_page_order_' . $form->id ] );
if ( $last_page || FrmProFormsHelper::saving_draft() ) {
return;
}
$drafts_allowed = FrmForm::get_option( array( 'form' => $form, 'option' => 'save_draft' ) );
if ( $drafts_allowed ) {
self::autosave_on_page_turn( $form );
}
}
/**
* @since 2.3
*/
private static function autosave_on_page_turn( $form ) {
$params = $_POST;
$params['frm_saving_draft'] = true;
$params['is_draft'] = 1;
if ( ! isset( $params['action'] ) ) {
$params['action'] = $params['frm_action'];
}
if ( $params['action'] == 'create' || $params['action'] == 'frm_entries_create' ) {
global $frm_vars;
$_POST['frm_autosaving'] = 1;
if ( empty( $frm_vars['created_entries'][ $form->id ] ) ) {
$frm_vars['created_entries'][ $form->id ] = array( 'errors' => array() );
}
$frm_vars['created_entries'][ $form->id ]['entry_id'] = FrmEntry::create( $params );
} else if ( $params['action'] == 'update' || $params['action'] == 'frm_entries_update' ) {
if ( ! FrmProEntriesHelper::user_can_edit( absint( $params['id'] ), $form ) ) {
return;
}
$entry = FrmEntry::getOne( $params['id'] );
if ( $entry->is_draft ) {
$_POST['frm_autosaving'] = 1;
FrmEntry::update( $entry->id, $params );
}
}
}
public static function edit_update_form( $params, $fields, $form, $title, $description ) {
global $frm_vars;
FrmProFormState::set_initial_value( 'title', $title );
FrmProFormState::set_initial_value( 'description', $description );
self::load_wp_editor_assets( $fields, $form );
$continue = true;
$args = array(
'form' => $form,
'fields' => $fields,
'show_title' => $title,
'show_description' => $description,
'params' => $params,
);
if ( 'edit' === $params['action'] ) {
// For initial form load when editing
self::maybe_show_front_end_editable_entry_on_first_load( $args, $continue );
} elseif ( 'update' === $params['action'] && $params['posted_form_id'] == $form->id ) {
// For next/submit/previous/save draft clicks
self::show_front_end_editable_entry_after_submit_click( $args, $continue );
} elseif ( 'destroy' === $params['action'] ) {
self::front_destroy_entry($form);
} elseif ( isset( $frm_vars['editing_entry'] ) && $frm_vars['editing_entry'] ) {
// For entry_id=x, initial load only
self::maybe_show_front_end_editable_entry_with_entry_id_param( $args, $continue);
} else {
self::allow_front_create_entry($form, $continue);
}
self::check_form_status_options( $form, $continue );
self::remove_opposite_continue_to_new_filter( $continue );
}
/**
* Loads necessary WP Editor assets for Rich Text fields with
* AJAX-enabled forms.
*
* @since 4.06.02
*
* @param array $fields Array of fields and its properties.
* @param object $form Object representing the current Form.
*/
private static function load_wp_editor_assets( $fields, $form ) {
// This is only needed when AJAX submission is enabled for the form.
if ( ! FrmProForm::is_ajax_on( $form ) || FrmAppHelper::is_admin() ) {
return;
}
foreach ( $fields as $field ) {
// Check for an `rte` (Rich-text) field.
$field_type = FrmField::get_option( $field, 'original_type' );
if ( 'rte' === $field_type ) {
$field_obj = FrmFieldFactory::get_field_type( 'rte' );
$field_obj->load_default_rte_script();
break;
}
}
}
/**
* @since 3.04
*
* @param object $form
*/
private static function check_form_status_options( $form, &$continue ) {
if ( $continue && ! FrmProForm::is_open( $form ) ) {
$continue = false;
if ( isset( $form->options['closed_msg'] ) ) {
$message = $form->options['closed_msg'];
} else {
$default_opts = FrmProFormsHelper::get_default_opts();
$message = $default_opts['closed_msg'];
}
$message = do_shortcode( $message );
echo wp_kses_post( $message );
}
}
private static function remove_opposite_continue_to_new_filter( $continue ) {
if ( $continue === true ) {
remove_filter('frm_continue_to_new', '__return_false', 15);
add_filter('frm_continue_to_new', '__return_true', 15);
} else {
remove_filter('frm_continue_to_new', '__return_true', 15);
add_filter('frm_continue_to_new', '__return_false', 15);
}
}
/**
* Load form and entry for editing if user has permission and entry exists
* Used on initial load only, not on page turns
*
* @since 2.01.0
*
* @param array $args (always contains 'form', 'fields' , 'show_title', and 'show_description')
* @param boolean $continue
*/
private static function maybe_show_front_end_editable_entry_on_first_load( $args, &$continue ) {
global $wpdb, $frm_vars;
$entry_id = ( isset( $frm_vars['editing_entry'] ) && $frm_vars['editing_entry'] ) ? $frm_vars['editing_entry'] : '';
$entry_key = FrmAppHelper::get_param( 'entry', $entry_id, 'get', 'sanitize_title' );
$query = array( 'it.form_id' => $args['form']->id );
if ( $entry_key ) {
$query[1] = array( 'or' => 1, 'it.id' => $entry_key, 'it.item_key' => $entry_key );
$in_form = FrmDb::get_var( $wpdb->prefix . 'frm_items it', $query );
if ( ! $in_form ) {
$entry_key = false;
unset( $query[1] );
}
unset($in_form);
}
$entry = FrmProEntriesHelper::user_can_edit( $entry_key, $args['form'] );
if ( ! $entry ) {
return;
}
if ( ! is_array( $entry ) ) {
$entry = FrmEntry::getAll( $query, '', 1, true );
}
if ( ! empty( $entry ) ) {
global $frm_vars;
$entry = reset($entry);
$frm_vars['editing_entry'] = $entry->id;
self::show_entry_on_first_load_for_editing( $entry, $args );
$continue = false;
}
}
/**
* Load the form for editing when entry_id=x shortcode is used
*
* @param array $args (contains form, fields, show_title, and show_description)
* @param boolean $continue
*/
private static function maybe_show_front_end_editable_entry_with_entry_id_param( $args, &$continue ) {
global $frm_vars;
$entry_id = false;
if ( is_numeric( $frm_vars['editing_entry'] ) ) {
// For entry_id=x in shortcode
$entry_id = $frm_vars['editing_entry'];
} elseif ( $frm_vars['editing_entry'] == 'last' ) {
// For entry_id="last" in shortcode
// Get the last entry submitted by the current user
$user_ID = get_current_user_id();
$where = array(
'user_id' => $user_ID,
'form_id' => $args['form']->id,
);
$entry_id = FrmDb::get_col( 'frm_items', $where, 'id', array(), ' LIMIT 1' );
}
if ( ! $entry_id ) {
return;
}
if ( ! FrmProEntriesHelper::user_can_edit( $entry_id, $args['form'] ) ) {
return;
}
$frm_vars['editing_entry'] = $entry_id;
$entry = FrmEntry::getOne( $entry_id, true );
self::show_entry_on_first_load_for_editing( $entry, $args );
$continue = false;
}
private static function front_destroy_entry( $form ) {
//if the user who created the entry is deleting it
self::ajax_destroy($form->id, false);
}
/**
* Show the form/entry after clicking Next, Previous, Update, Submit, or Save Draft
*
* @since 2.01.0
*
* @param array $args (always contains 'form', 'fields' , 'show_title', 'show_description', and 'params')
* @param boolean $continue
*/
private static function show_front_end_editable_entry_after_submit_click( $args, &$continue ) {
global $frm_vars;
// Initialize basic entry info
$entry_id = $args['params']['id'];
$entry = FrmEntry::getOne( $entry_id, true );
$frm_vars['editing_entry'] = $entry_id;
// Add to args
$args['errors'] = self::get_posted_form_errors( $frm_vars, $args['form'] );
$field_args = array(
'parent_form_id' => $args['form']->id,
'fields' => $args['fields'],
'save_draft_click' => FrmProFormsHelper::saving_draft(),
);
$args['values'] = self::setup_entry_values_for_editing( $entry, $field_args );
self::add_submit_value_to_values( $args['form'], $args['values'] );
$args['submit_text'] = self::get_submit_button_text_for_editing_entry( $entry, $args['values'], $args['form'] );
if ( self::update_button_was_clicked( $args ) ) {
// If Update/Submit was clicked
if ( FrmProEntriesHelper::user_can_edit( $entry_id, $args['form'] ) ) {
self::do_on_update_settings( $entry, $args );
} else {
// entry is no longer editable after draft is saved
self::do_on_create_settings( $entry, $args );
}
} else {
// If Save Draft, Next, or Previous was clicked
$args['show_form'] = true;
$args['jump_to_form'] = true;
$args['conf_message'] = self::maybe_get_save_draft_message( $args['form'], $entry_id );
self::show_front_end_form_with_entry( $entry, $args );
}
$continue = false;
}
/**
* Adds submit value in $form object to $values array.
*
* @since 4.06.02
*
* @param object $form Form object.
* @param array $values Array of values, used to set submit button text, among other things.
*/
private static function add_submit_value_to_values( $form, &$values ) {
if ( isset( $form->submit_value ) ) {
$values['submit_value'] = $form->submit_value;
return;
}
if ( isset( $form->options['submit_value'] ) ) {
$values['submit_value'] = $form->options['submit_value'];
}
}
/**
* Show the message + form after the first Save Draft click (on front-end only)
* Replaces FrmProEntriesController::show_responses
*
* @since 2.01.0
*
* @param int $entry_id
* @param array $args
*/
public static function show_form_after_first_save_draft_click( $entry_id, $args ) {
global $frm_vars;
$frm_vars['editing_entry'] = $entry_id;
$entry = FrmEntry::getOne( $entry_id );
$field_args = array(
'parent_form_id' => $args['form']->id,
'fields' => $args['fields'],
'save_draft_click' => true,
);
$args['values'] = self::setup_entry_values_for_editing( $entry, $field_args );
$args['submit_text'] = self::get_submit_button_text_for_editing_entry( $entry, $args['values'], $args['form'] );
$args['show_form'] = true;
$args['jump_to_form'] = true;
$args['errors'] = array();
self::show_front_end_form_with_entry( $entry, $args );
}
/**
* Display a success message and possibly the form after single editable entry is submitted
* Replaces FrmProEntriesController::show_responses
*
* @since 2.01.0
* @param int $entry_id
* @param array $args (always contains 'form', 'fields', 'show_title', and 'show_description')
*/
public static function show_form_after_single_editable_entry_submission( $entry_id, $args ) {
self::show_form_after_first_save_draft_click( $entry_id, $args );
}
/**
* Get errors when validating server-side
*
* @since 2.01.0
*
* @param array $frm_vars
* @param object $form
* @return array
*/
private static function get_posted_form_errors( $frm_vars, $form ) {
if ( isset( $frm_vars['created_entries'][ $form->id ] ) ) {
$errors = $frm_vars['created_entries'][ $form->id ]['errors'];
} else {
$errors = false;
}
return $errors;
}
/**
* If a draft is being saved, get the save draft message
*
* @since 2.01.0
*
* @param object $form
* @param int $entry_id
* @return string $message
*/
private static function maybe_get_save_draft_message( $form, $entry_id ) {
$message = '';
if ( FrmProFormsHelper::saving_draft() ) {
$success_args = array( 'action' => self::get_current_entry_action( $entry_id ) );
$message = self::confirmation( 'message', $form, $form->options, $entry_id, $success_args );
}
return $message;
}
/**
* Check to see if user is allowed to create another entry
*/
private static function allow_front_create_entry( $form, &$continue ) {
$errors = array();
if ( FrmProFormsHelper::visitor_already_submitted( $form, $errors ) ) {
echo do_shortcode( reset( $errors ) );
$continue = false;
}
}
/**
* This function should only be used when editing an entry (on front-end only)
* Replaces FrmProEntriesController::show_responses
*
* @since 2.01.0
* @param object $entry
* @param array $args (always contains 'form', 'fields', 'show_title', and 'show_description')
*/
private static function show_entry_on_first_load_for_editing( $entry, $args ) {
$field_args = array(
'parent_form_id' => $args['form']->id,
'fields' => $args['fields'],
);
$args['values'] = self::setup_entry_values_for_editing( $entry, $field_args );
$args['submit_text'] = self::get_submit_button_text_for_editing_entry( $entry, $args['values'], $args['form'] );
$args['errors'] = array();
$args['show_form'] = true;
self::show_front_end_form_with_entry( $entry, $args );
}
/**
* Update the global $frm_vars so CSS and JavaScript gets loaded correctly
*
* @since 2.01.0
*
* @param array $args always contains 'form', 'fields', 'show_title', 'show_description', 'values', 'errors',
* 'submit_text', and 'show_form'
*/
private static function update_global_vars_for_entry_editing( &$args ) {
if ( isset( $args['form']->options['show_form'] ) && $args['form']->options['show_form'] ) {
//Do nothing because JavaScript is already loaded
// Make sure Formidable CSS is loaded
global $frm_vars;
if ( $args['values']['custom_style'] ) {
$frm_vars['load_css'] = true;
}
} else {
self::load_form_scripts(
array(
'style' => $args['values']['custom_style'],
)
);
}
}
/**
* Set up all the necessary data for editing an entry
* This is now used in place of FrmAppHelper::setup_edit_vars when editing entries
*
* @since 2.01.0
*
* @param object $entry
* @param array $args (always contains 'parent_form_id' and 'fields'; if repeating, will contain 'parent_field_id',
* 'key_pointer' and 'repeating'; if embedded, will contain in_embed_form)
* @return array $values
*/
public static function setup_entry_values_for_editing( $entry, $args ) {
$values = array(
'id' => $entry->id,
'fields' => array(),
);
foreach ( array( 'name', 'description' ) as $var ) {
$default_val = isset( $entry->{$var} ) ? $entry->{$var} : '';
$values[ $var ] = FrmAppHelper::get_param( $var, $default_val, 'get', 'wp_kses_post' );
FrmAppHelper::sanitize_value( 'wp_specialchars_decode', $values[ $var ] );
unset($var, $default_val);
}
$values['description'] = FrmAppHelper::use_wpautop( $values['description'] );
$fields = $args['fields'];
unset( $args['fields'] );
$values['fields'] = FrmProFieldsController::setup_field_data_for_editing_entry( $entry, $fields, $args );
FrmProFormsController::setup_form_data_for_editing_entry( $entry, $values );
$values = FrmEntriesHelper::setup_edit_vars( $values, $entry );
return $values;
}
/**
* Get the text on the Submit button when editing an entry
* Remember the Submit button may be the Next, Update, or Submit button
*
* @since 2.01.0
*
* @param object $entry
* @param array $values
* @param object $form
* @return string $submit_text
*/
private static function get_submit_button_text_for_editing_entry( $entry, $values, $form ) {
global $frm_vars;
if ( isset( $frm_vars['next_page'][ $form->id ] ) ) {
// If there is a "Next" page, get the Next button text
$submit_text = $frm_vars['next_page'][ $form->id ];
$submit_text = $submit_text->name;
} else {
if ( $entry->is_draft ) {
// If entry is a draft, get the create button text
if ( isset( $values['submit_value'] ) ) {
$submit_text = $values['submit_value'];
} else {
$frmpro_settings = FrmProAppHelper::get_settings();
$submit_text = $frmpro_settings->submit_value;
}
} else {
// If entry is not a draft, get the edit button text
if ( isset( $values['edit_value'] ) ) {
$submit_text = $values['edit_value'];
} else {
$frmpro_settings = FrmProAppHelper::get_settings();
$submit_text = $frmpro_settings->update_value;
}
}
}
return $submit_text;
}
/**
* Determine whether the "Update" button was clicked
*
* @since 2.01.0
*
* @param array $args (always contains 'form', 'fields' , 'show_title', 'show_description', 'params', 'values',
* 'errors', and 'submit_text')
* @return boolean $update_button_was_clicked
*/
private static function update_button_was_clicked( &$args ) {
global $frm_vars;
$update_button_was_clicked = false;
$form = $args['form'];
if ( ! isset( $_POST['item_meta'] ) || $args['errors'] ) {
// There is no item meta or there are errors, so don't update entry
} else if ( isset( $frm_vars['prev_page'][ $form->id ] ) || FrmProFormsHelper::going_to_prev( $form->id ) ) {
// Back or Next was clicked
} else if ( $form->id != FrmAppHelper::get_param( 'form_id', '', 'get', 'absint' ) ) {
// This form is NOT the one being submitted/updated
} else if ( FrmProFormsHelper::saving_draft() ) {
// Save Draft was clicked
} else {
$update_button_was_clicked = true;
}
return $update_button_was_clicked;
}
/**
* Determine whether the form is displayed after edit
*
* @since 2.01.0
*
* @param object $form
* @return boolean $show_form
*/
private static function is_form_displayed_after_edit( $form ) {
$show_form = ( isset( $form->options['show_form'] ) ) ? $form->options['show_form'] : true;
$show_form = apply_filters( 'frm_show_form_after_edit', $show_form, $form );
return $show_form;
}
/**
* Determine whether the current entry is being created or updated
*
* @since 2.01.0
*
* @param int $entry_id
* @return boolean
*/
private static function get_current_entry_action( $entry_id ) {
return FrmProEntriesHelper::is_new_entry( $entry_id ) ? 'create' : 'update';
}
/**
* Get the confirmation method selected for "On Update"
*
* @since 2.01.0
*
* @param object $form
* @param array $success_args (always includes 'action' )
* @return string
*/
private static function get_conf_method_after_save( $form, $success_args ) {
return apply_filters( 'frm_success_filter', 'message', $form, $success_args['action'] );
}
/**
* Do the "On Update" settings (redirect to URL, show a message, or show content from another page)
*
* @since 2.01.0
*
* @param object $entry
* @param array $args
* $args always contains 'form', 'fields' , 'show_title', 'show_description', 'params', 'values', 'errors', and
* 'submit_text'
*/
private static function do_on_update_settings( $entry, $args ) {
$success_args = array( 'action' => self::get_current_entry_action( $entry->id ) );
$conf_method = self::get_conf_method_after_save( $args['form'], $success_args );
if ( $conf_method == 'message' ) {
$args['conf_message'] = self::confirmation( 'message', $args['form'], $args['form']->options, $entry->id, $success_args );
$args['show_form'] = self::is_form_displayed_after_edit( $args['form'] );
self::show_front_end_form_with_entry( $entry, $args );
} else {
do_action('frm_success_action', $conf_method, $args['form'], $args['form']->options, $entry->id, $success_args );
}
}
/**
* Show the editable form/entry on the front-end
*
* @since 2.01.0
*
* @param object $entry
* @param array $args
* $args always contains 'form', 'fields', 'show_title', 'show_description', 'values', 'errors', 'submit_text', and
* 'show_form'
*/
private static function show_front_end_form_with_entry( $entry, $args ) {
self::update_global_vars_for_entry_editing( $args );
// Setup variables for view (maybe do away with this and create a new view)
$values = $args['values'];
$user_ID = get_current_user_id();
$frm_settings = FrmAppHelper::get_settings();
$title = $args['show_title'];
$description = $args['show_description'];
$id = $entry->id;
$errors = $args['errors'];
$form = $args['form'];
$submit = $args['submit_text'];
$show_form = $args['show_form'];
$jump_to_form = isset( $args['jump_to_form'] ) ? $args['jump_to_form'] : false;
$message = isset( $args['conf_message'] ) ? $args['conf_message'] : false;
if ( $message ) {
$message = apply_filters( 'frm_main_feedback', $message, $form, $id );
}
if ( is_callable( 'FrmFormsController::maybe_load_css' ) ) {
global $frm_vars;
FrmFormsController::maybe_load_css( $form, $values['custom_style'], $frm_vars['load_css'] );
}
require( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-entries/edit-front.php');
add_filter('frm_continue_to_new', 'FrmProEntriesController::maybe_editing', 10, 3);
}
private static function do_on_create_settings( $entry, $args ) {
$conf_method = apply_filters( 'frm_success_filter', 'message', $args['form'], 'create' );
$args['entry_id'] = $entry->id;
$args['title'] = $args['show_title'];
$args['description'] = $args['show_description'];
$args['conf_method'] = $conf_method;
FrmFormsController::run_success_action( $args );
}
public static function ajax_submit_button() {
global $frm_vars;
if ( isset($frm_vars['novalidate']) && $frm_vars['novalidate'] ) {
echo ' formnovalidate="formnovalidate"';
}
}
public static function get_confirmation_method( $method, $form, $action = 'create' ) {
$opt = ( $action == 'update' ) ? 'edit_action' : 'success_action';
$method = ( isset( $form->options[ $opt ] ) && ! empty( $form->options[ $opt ] ) ) ? $form->options[ $opt ] : $method;
if ( $method != 'message' && FrmProFormsHelper::saving_draft() ) {
$method = 'message';
}
return $method;
}
public static function confirmation( $method, $form, $form_options, $entry_id, $args = array() ) {
$opt = ( ! isset( $args['action'] ) || $args['action'] == 'create' ) ? 'success' : 'edit';
if ( ( $method == 'page' && is_numeric( $form_options[ $opt . '_page_id' ] ) ) || $method == 'redirect' ) {
$pass_args = $args;
$pass_args['conf_method'] = $method;
$pass_args['form'] = $form;
$pass_args['entry_id'] = $entry_id;
FrmFormsController::run_success_action( $pass_args );
} else {
$frm_settings = FrmAppHelper::get_settings();
$frmpro_settings = FrmProAppHelper::get_settings();
$msg = ( $opt == 'edit' ) ? $frmpro_settings->edit_msg : $frm_settings->success_msg;
$message = isset( $form->options[ $opt . '_msg' ] ) ? $form->options[ $opt . '_msg' ] : $msg;
// Replace $message with save draft message if we are saving a draft
FrmProFormsHelper::save_draft_msg( $message, $form );
$class = 'frm_message';
return FrmFormsHelper::get_success_message( compact( 'message', 'form', 'entry_id', 'class' ) );
}
}
public static function delete_entry( $post_id ) {
// Check that installation has occurred
$db_version = get_option('frm_db_version');
if ( ! $db_version ) {
return;
}
$entry = FrmDb::get_row( 'frm_items', array( 'post_id' => $post_id ), 'id' );
self::maybe_delete_entry( $entry );
}
public static function trashed_post( $post_id ) {
$form_id = get_post_meta( $post_id, 'frm_form_id', true );
if ( ! $form_id ) {
return;
}
$display = FrmProDisplay::get_auto_custom_display( array( 'form_id' => $form_id ) );
if ( $display ) {
update_post_meta( $post_id, 'frm_display_id', $display->ID );
} else {
delete_post_meta( $post_id, 'frm_display_id' );
}
}
/**
* Allow extra parameters in the frm-show-entry shortcode
*
* @since 3.01.01
*/
public static function show_entry_defaults( $atts ) {
$atts['date_format'] = '';
$atts['show_image'] = false;
$atts['size'] = 'full';
$atts['image_option_size'] = 'thumbnail';
$atts['show_image_options'] = true;
$atts['show_filename'] = false;
$atts['add_link'] = false;
$atts['summary'] = false; // whether we're trying to display the summary field
return $atts;
}
public static function create_entry_from_post_box( $post_type, $post = false ) {
if ( ! $post || ! isset($post->ID) || $post_type == 'attachment' || $post_type == 'link' ) {
return;
}
global $wpdb, $frm_vars;
//don't show the meta box if there is already an entry for this post
$post_entry = FrmDb::get_var( $wpdb->prefix . 'frm_items', array( 'post_id' => $post->ID ) );
if ( $post_entry ) {
return;
}
//don't show meta box if no forms are set up to create this post type
$actions = FrmFormAction::get_action_for_form( 0, 'wppost' );
if ( ! $actions ) {
return;
}
$form_ids = array();
foreach ( $actions as $action ) {
if ( $action->post_content['post_type'] == $post_type && $action->menu_order ) {
$form_ids[] = $action->menu_order;
}
}
if ( empty($form_ids) ) {
return;
}
$forms = FrmDb::get_results( 'frm_forms', array( 'id' => $form_ids ), 'id, name' );
$frm_vars['post_forms'] = $forms;
if ( current_user_can('frm_create_entries') ) {
add_meta_box( 'frm_create_entry', __( 'Create Entry in Form', 'formidable-pro' ), 'FrmProEntriesController::render_meta_box_content', null, 'side' );
}
}
public static function render_meta_box_content( $post ) {
global $frm_vars;
$i = 1;
echo '<p>';
foreach ( (array) $frm_vars['post_forms'] as $form ) {
if ( $i != 1 ) {
echo ' | ';
}
$i++;
echo '<a href="javascript:frmCreatePostEntry(' . (int) $form->id . ',' . (int) $post->ID . ')">' . esc_html( FrmAppHelper::truncate( $form->name, 15 ) ) . '</a>';
unset($form);
}
echo '</p>';
}
public static function create_post_entry( $id = false, $post_id = false ) {
if ( FrmAppHelper::doing_ajax() ) {
check_ajax_referer( 'frm_ajax', 'nonce' );
}
if ( ! $id ) {
$id = absint( $_POST['id'] );
}
if ( ! $post_id ) {
$post_id = absint( $_POST['post_id'] );
}
if ( ! is_numeric($id) || ! is_numeric($post_id) ) {
return;
}
$post = get_post($post_id);
global $wpdb;
$values = array(
'description' => __( 'Copied from Post', 'formidable-pro' ),
'form_id' => $id,
'created_at' => $post->post_date_gmt,
'name' => $post->post_title,
'item_key' => FrmAppHelper::get_unique_key( $post->post_name, $wpdb->prefix . 'frm_items', 'item_key' ),
'user_id' => $post->post_author,
'post_id' => $post->ID,
);
$results = $wpdb->insert( $wpdb->prefix . 'frm_items', $values );
unset( $values );
if ( ! $results ) {
wp_die();
}
$entry_id = $wpdb->insert_id;
$user_id_field = FrmField::get_all_types_in_form($id, 'user_id', 1);
if ( $user_id_field ) {
$new_values = array(
'meta_value' => $post->post_author,
'item_id' => $entry_id,
'field_id' => $user_id_field->id,
'created_at' => current_time( 'mysql', 1 ),
);
$wpdb->insert( $wpdb->prefix . 'frm_item_metas', $new_values );
}
$display = FrmProDisplay::get_auto_custom_display( array( 'form_id' => $id, 'entry_id' => $entry_id ) );
if ( $display ) {
update_post_meta( $post->ID, 'frm_display_id', $display->ID );
}
wp_die();
}
public static function get_new_vars( $errors = array(), $form = false, $message = '' ) {
$description = true;
$title = false;
$form = apply_filters('frm_pre_display_form', $form);
if ( ! $form ) {
wp_die( esc_html__( 'You are trying to access an entry that does not exist.', 'formidable-pro' ) );
return;
}
$fields = FrmFieldsHelper::get_form_fields( $form->id, $errors );
$values = $fields ? FrmEntriesHelper::setup_new_vars($fields, $form) : array();
$submit = self::submit_label( compact( 'form', 'values' ) );
require( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-entries/new.php' );
}
/**
* @since 4.0
*/
public static function save_new_entry_button( $atts ) {
echo FrmProFormsHelper::get_draft_button( $atts['form'], 'button-secondary' );
$submit = self::submit_label( $atts );
submit_button( $submit, 'primary', '', false );
}
/**
* @since 4.0
*/
private static function submit_label( $atts ) {
global $frm_vars;
$form = $atts['form'];
$values = $atts['values'];
$frm_settings = FrmAppHelper::get_settings();
if ( FrmProFormsHelper::is_final_page( $form->id ) ) {
$submit = ( isset( $values['submit_value'] ) ? $values['submit_value'] : $frm_settings->submit_value );
if ( isset( $atts['entry'] ) ) {
if ( isset( $values['edit_value'] ) ) {
$edit_label = $values['edit_value'];
} else {
$frmpro_settings = FrmProAppHelper::get_settings();
$edit_label = $frmpro_settings->update_value;
}
$submit = $atts['entry']->is_draft ? $submit : $edit_label;
}
} else {
$submit = $frm_vars['next_page'][ $form->id ];
}
if ( is_object( $submit ) ) {
$submit = $submit->name;
}
return $submit;
}
/**
* @since 4.0
*/
public static function edit_entry_button( $atts ) {
if ( $atts['entry']->is_draft ) {
echo FrmProFormsHelper::get_draft_button( $atts['form'], 'button-secondary' );
}
$submit = self::submit_label( $atts );
echo '<button type="submit" class="button button-primary frm-button-secondary">' . esc_html( $submit ) . '</button>';
if ( ! FrmProFormsHelper::is_final_page( $atts['form']->id ) ) {
echo '<button type="submit" class="frm-button-secondary frm_page_skip hide-no-js" data-page="">' . esc_html__( 'Save', 'formidable-pro' ) . '</button>';
}
}
private static function get_edit_vars( $id, $errors = array(), $message = '' ) {
$description = true;
$title = false;
$entry = FrmEntry::getOne( $id, true );
if ( ! $entry ) {
wp_die( esc_html__( 'You are trying to access an entry that does not exist.', 'formidable-pro' ) );
return;
}
global $frm_vars;
$frm_vars['editing_entry'] = $id;
$form = FrmForm::getOne( $entry->form_id );
$form = apply_filters( 'frm_pre_display_form', $form );
$fields = FrmFieldsHelper::get_form_fields( $form->id, $errors );
$values = FrmAppHelper::setup_edit_vars( $entry, 'entries', $fields );
/**
* Allows modifying the list of fields in the form.
*
* @since 5.0
*
* @param array $fields Array of fields.
* @param array $args The arguments. Contains `$args`.
*/
$values['fields'] = apply_filters( 'frm_fields_in_form_edit', $values['fields'], compact( 'form' ) );
$submit = self::submit_label( compact( 'form', 'values', 'entry' ) );
FrmFormsController::maybe_load_css( $form, $values['custom_style'], $frm_vars['load_css'] );
require( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-entries/edit.php' );
}
public static function filter_shortcode_value( $value, $tag, $atts, $field ) {
if ( isset( $atts['striphtml'] ) && $atts['striphtml'] ) {
self::kses_deep( $atts, $value );
} elseif ( ! isset( $atts['keepjs'] ) || ! $atts['keepjs'] ) {
FrmAppHelper::sanitize_value( 'wp_kses_post', $value );
}
return self::get_option_label_for_saved_value( $value, $field, $atts );
}
/**
* @since 2.05.03
*/
private static function kses_deep( $atts, &$value ) {
$allowed_tags = apply_filters( 'frm_striphtml_allowed_tags', array(), $atts );
if ( is_array( $value ) ) {
foreach ( $value as $k => $v ) {
$value[ $k ] = wp_kses( $v, $allowed_tags );
unset( $k, $v );
}
} else {
$value = wp_kses( $value, $allowed_tags );
}
}
/**
* Get the option label from a saved value, if a field has separate values and saved_value="1" is not set
*
* @since 2.02.14
*
* @param mixed $value
* @param object $field
* @param array $atts
*
* @return array|mixed
*/
public static function get_option_label_for_saved_value( $value, $field, $atts = array() ) {
$show_value = ( isset( $atts['show'] ) && $atts['show'] == 'value' );
$saved_value = ( isset( $atts['saved_value'] ) && $atts['saved_value'] );
if ( $saved_value || $value === false || $show_value ) {
return $value;
}
if ( FrmProImages::showing_images( $field, $atts ) ) {
return FrmProImages::display( $field, $value, $atts );
}
$has_separate_option = in_array( $field->type, array( 'radio', 'checkbox', 'select', 'product' ) ) && FrmField::is_option_true( $field, 'separate_value' );
if ( ! $has_separate_option ) {
return $value;
}
$f_values = array();
$f_labels = array();
$show = ( isset( $atts['show'] ) && $atts['show'] === 'price' ) ? 'price' : 'label';
foreach ( $field->options as $opt_key => $opt ) {
if ( ! is_array( $opt ) ) {
continue;
}
$f_labels[ $opt_key ] = isset( $opt[ $show ] ) ? $opt[ $show ] : reset( $opt );
$f_values[ $opt_key ] = isset( $opt['value'] ) ? $opt['value'] : $f_labels[ $opt_key ];
if ( $f_labels[ $opt_key ] == $f_values[ $opt_key ] ) {
unset( $f_values[ $opt_key ], $f_labels[ $opt_key ] );
}
unset( $opt_key, $opt );
}
if ( ! empty( $f_values ) ) {
if ( is_array( $value ) ) {
$value = FrmAppHelper::array_flatten( $value, 'reset' );
}
foreach ( (array) $value as $v_key => $val ) {
if ( in_array( $val, $f_values ) ) {
$opt = array_search( $val, $f_values );
if ( is_array( $value ) ) {
$value[ $v_key ] = $f_labels[ $opt ];
} else {
$value = $f_labels[ $opt ];
}
}
unset( $v_key, $val );
}
}
return $value;
}
/**
* Trigger from the frm_display_value_atts hook
*
* @since 2.0
*/
public static function display_value_atts( $atts, $field ) {
if ( $field->type == 'file' ) {
$atts['truncate'] = false;
$atts['html'] = true;
} elseif ( FrmProImages::has_image_options( $field ) ) {
$atts['truncate'] = false;
$atts['show_filename'] = false;
if ( isset( $atts['show_icon'] ) && ! $atts['show_icon'] ) {
// For the CSV export.
$atts['show_image'] = false;
$atts['sep'] = ', ';
} elseif ( ! isset( $atts['saved_value'] ) || ! $atts['saved_value'] ) {
$atts['sep'] = ' ';
}
}
return $atts;
}
public static function filter_display_value( $value, $field, $atts = array() ) {
self::set_display_atts( $field, $atts );
if ( $atts['type'] === 'return_raw' ) {
return $value;
} elseif ( $atts['type'] == 'data' ) {
self::get_dynamic_value_for_display( $field, $atts, $value );
} else {
$atts['return_array'] = true;
$value = FrmFieldsHelper::get_unfiltered_display_value( compact( 'value', 'field', 'atts' ) );
$value = self::get_option_label_for_saved_value( $value, $field, $atts );
if ( is_array( $value ) ) {
$sep = isset( $atts['sep'] ) ? $atts['sep'] : ', ';
$value = implode( $sep, $value );
}
}
if ( ! $atts['keepjs'] ) {
FrmAppHelper::sanitize_value( 'wp_kses_post', $value );
}
return $value;
}
/**
* Set a value after all other field-specific formating has been set.
*
* @since 4.06.01
*/
public static function display_value( $value, $field, $atts ) {
$value = FrmProCurrencyHelper::maybe_format_currency( $value, $field, $atts );
return $value;
}
private static function set_display_atts( $field, &$atts ) {
$defaults = array( 'html' => 0, 'type' => $field->type, 'keepjs' => 0 );
$atts = array_merge( $defaults, $atts );
if ( FrmField::is_image( $field ) ) {
$atts['html'] = true;
$atts['sep'] = '';
} elseif ( isset( $atts['show'] ) && empty( $atts['show'] ) ) {
unset( $atts['show'] );
}
if ( $atts['type'] == 'file' && $atts['html'] && $atts['sep'] == ', ' ) {
$atts['sep'] = '';
$atts['show_image'] = true;
if ( ! isset( $atts['add_link'] ) ) {
$atts['add_link'] = true;
}
}
}
private static function get_dynamic_value_for_display( $field, $atts, &$value ) {
if ( ! is_numeric( $value ) ) {
if ( ! is_array( $value ) ) {
$value = explode( $atts['sep'], $value );
}
if ( is_array( $value ) ) {
$new_value = '';
foreach ( $value as $entry_id ) {
if ( ! empty( $new_value ) ) {
$new_value .= $atts['sep'];
}
if ( is_numeric( $entry_id ) ) {
$new_value .= FrmProFieldsHelper::get_data_value( $entry_id, $field, $atts );
} else {
$new_value .= $entry_id;
}
}
$value = $new_value;
}
} else {
//replace item id with specified field
$new_value = FrmProFieldsHelper::get_data_value( $value, $field, $atts );
if ( FrmProField::is_list_field( $field ) ) {
$linked_field = FrmField::getOne( $field->field_options['form_select'] );
if ( $linked_field && $linked_field->type == 'file' ) {
$old_value = explode( ', ', $new_value );
$new_value = '';
foreach ( $old_value as $v ) {
$new_value .= '<img src="' . esc_url( $v ) . '" class="frm_image_from_url" alt="" />';
if ( $atts['show_filename'] ) {
$new_value .= '<br/>' . $v;
}
unset( $v );
}
} else {
$new_value = $value;
}
}
$value = $new_value;
}
}
public static function route( $action ) {
add_filter( 'frm_entry_stop_action_route', '__return_true' );
add_action( 'frm_load_form_hooks', 'FrmHooksController::trigger_load_form_hooks' );
FrmAppHelper::trigger_hook_load( 'form' );
if ( in_array( $action, array( 'create', 'edit', 'update', 'duplicate', 'new' ) ) ) {
wp_enqueue_style( 'formidable' );
}
switch ( $action ) {
case 'create':
case 'edit':
case 'update':
case 'duplicate':
return self::$action();
case 'new':
return self::new_entry();
default:
$action = FrmAppHelper::get_param( 'action', '', 'get', 'sanitize_text_field' );
if ( $action == -1 ) {
$action = FrmAppHelper::get_param( 'action2', '', 'get', 'sanitize_title' );
}
if ( strpos($action, 'bulk_') === 0 ) {
FrmAppHelper::remove_get_action();
return self::bulk_actions($action);
}
$message = '';
$errors = array();
switch ( FrmAppHelper::get_param( 'message' ) ) {
case 'destroy_all':
$message = __( 'Entries Successfully Deleted', 'formidable-pro' );
break;
case 'no_entries_selected':
$errors[] = __( 'No Entries Selected', 'formidable-pro' );
break;
}
return FrmEntriesController::display_list( $message, $errors );
}
}
/**
* @return string The name of the entry listing class
*/
public static function list_class() {
return 'FrmProEntriesListHelper';
}
public static function manage_columns( $columns ) {
global $frm_vars;
$form_id = FrmForm::get_current_form_id();
$cb_item = array( 'cb' => '<input type="checkbox" />' );
$columns = $cb_item + (array) $columns;
$columns[ $form_id . '_post_id' ] = __( 'Post', 'formidable-pro' );
$columns[ $form_id . '_is_draft' ] = __( 'Draft', 'formidable-pro' );
$columns[ $form_id . '_parent_item_id' ] = __( 'Parent Entry ID', 'formidable-pro' );
$frm_vars['cols'] = $columns;
return $columns;
}
public static function row_actions( $actions, $item ) {
$edit_link = FrmProEntry::admin_edit_link( $item->id );
if ( current_user_can('frm_edit_entries') ) {
$actions['edit'] = '<a href="' . esc_url( $edit_link ) . '">' . __( 'Edit' ) . '</a>';
}
if ( current_user_can('frm_create_entries') ) {
$duplicate_link = '?page=formidable-entries&frm_action=duplicate&id=' . $item->id . '&form=' . $item->form_id;
$actions['duplicate'] = '<a href="' . esc_url( wp_nonce_url( $duplicate_link ) ) . '">' . __( 'Duplicate', 'formidable-pro' ) . '</a>';
}
// move delete link to the end of the links
if ( isset($actions['delete']) ) {
$delete_link = $actions['delete'];
unset($actions['delete']);
$actions['delete'] = $delete_link;
}
return $actions;
}
public static function get_form_results( $atts ) {
FrmAppHelper::sanitize_value( 'wp_kses_post', $atts );
$atts = shortcode_atts(
array(
'id' => false, 'cols' => 99, 'style' => true,
'fields' => false, 'clickable' => false, 'user_id' => false,
'google' => false, 'pagesize' => 20, 'sort' => true,
'edit_link' => false, 'delete_link' => false, 'page_id' => false,
'no_entries' => __( 'No Entries Found', 'formidable-pro' ),
'confirm' => __( 'Are you sure you want to delete that entry?', 'formidable-pro' ),
'drafts' => '0',
),
$atts
);
$atts['form'] = self::get_form( $atts );
if ( ! $atts['form'] ) {
return;
}
if ( $atts['fields'] ) {
$atts['fields'] = explode( ',', $atts['fields'] );
}
self::get_table_values( $atts );
if ( empty( $atts['form_cols'] ) ) {
$contents = '<div class="frm_no_entries">' . __( 'There are no matching fields. Please check your formresults shortcode to make sure you are using the correct form and field IDs.', 'formidable-pro' ) . '</div>';
return $contents;
}
$contents = '';
self::add_delete_entry_message( $atts, $contents );
self::setup_edit_link( $atts );
self::setup_delete_link( $atts );
$filename = self::set_formresults_filename( $atts );
self::load_form_scripts( $atts );
ob_start();
include( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-entries/' . $filename . '.php' );
$contents .= ob_get_contents();
ob_end_clean();
if ( ! $atts['google'] && $atts['clickable'] ) {
$contents = make_clickable( $contents );
}
return $contents;
}
/**
* Get the form for the formresults table
*
* @since 2.0.09
* @param array $atts
* @return object
*/
private static function get_form( $atts ) {
if ( ! $atts['id'] ) {
return false;
}
return FrmForm::getOne( $atts['id'] );
}
/**
* Get entries and fields for formresults
*
* @since 2.0.09
* @param array $atts
*/
private static function get_table_values( &$atts ) {
// Get all fields in the form
$atts['form_cols'] = FrmField::get_all_for_form( $atts['form']->id, '', 'include' );
// Get all entries for the form
$atts['entries'] = self::get_entries_for_table( $atts );
$subforms_to_include = array();
$field_count = 0;
foreach ( $atts['form_cols'] as $k => $f ) {
if ( $field_count < $atts['cols'] && self::is_field_needed( $f, $atts, $subforms_to_include ) ) {
$field_count++;
self::get_sub_field_values( $f, $atts );
} else {
unset( $atts['form_cols'][ $k ] );
}
}
}
private static function get_entries_for_table( $atts ) {
$where = array( 'it.form_id' => $atts['form']->id );
if ( $atts['drafts'] != 'both' ) {
$where['it.is_draft'] = (int) $atts['drafts'];
}
if ( $atts['user_id'] ) {
$where['user_id'] = (int) FrmAppHelper::get_user_id_param( $atts['user_id'] );
}
$s = FrmAppHelper::get_param( 'frm_search', false, 'get', 'sanitize_text_field' );
if ( $s ) {
$new_ids = FrmProEntriesHelper::get_search_ids( $s, $atts['form']->id, array( 'is_draft' => $atts['drafts'] ) );
$where['it.id'] = $new_ids;
}
if ( isset( $new_ids ) && empty( $new_ids ) ) {
$entries = false;
} else {
$entries = FrmEntry::getAll( $where, '', '', true, false );
}
return $entries;
}
/**
* Check if each field is needed in the formresults table
*
* @since 2.0.09
* @param object $f - field
* @param array $atts
* @param array $subforms_to_include
* @return boolean
*/
private static function is_field_needed( $f, $atts, &$subforms_to_include ) {
if ( ! empty( $atts['fields'] ) ) {
if ( FrmField::is_no_save_field( $f->type ) ) {
if ( FrmField::is_option_true( $f, 'form_select' ) && ( in_array( $f->id, $atts['fields'] ) || in_array( $f->field_key, $atts['fields'] ) ) ) {
$subforms_to_include[] = $f->field_options['form_select'];
}
return false;
}
if ( ! in_array( $f->form_id, $subforms_to_include ) && ! in_array( $f->id, $atts['fields'] ) && ! in_array( $f->field_key, $atts['fields'] ) ) {
return false;
}
} else {
if ( FrmField::is_no_save_field( $f->type ) ) {
return false;
}
}
return true;
}
/**
* Get values in nested forms (repeating sections and embed form)
*
* @since 2.0.09
* @param object $field
* @param array $atts
*/
private static function get_sub_field_values( $field, &$atts ) {
if ( empty( $atts['entries'] ) ) {
return;
}
foreach ( $atts['entries'] as $key => $entry ) {
if ( ! isset( $entry->metas[ $field->id ] ) || $entry->metas[ $field->id ] == '' ) {
FrmProEntryMeta::add_repeating_value_to_entry( $field, $atts['entries'][ $key ] );
}
}
}
/**
* If delete_link is set in formresults and frm_action is set to destroy,
* check if entry should be deleted when page is loaded
*/
private static function add_delete_entry_message( $atts, &$contents ) {
$action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
if ( $atts['delete_link'] && $action == 'destroy' ) {
$delete_message = self::ajax_destroy( false, false, false );
$delete_message = '<div class="' . esc_attr( $atts['style'] ? FrmFormsHelper::get_form_style_class() : '' ) . '"><div class="frm_message">' . $delete_message . '</div></div>';
$contents = $delete_message;
}
}
/**
* If edit link is set in formresults, set up values for the edit link
*
* @since 2.0.09
* @param array $atts
*/
private static function setup_edit_link( &$atts ) {
if ( $atts['edit_link'] ) {
$atts['anchor'] = '';
if ( ! $atts['page_id'] ) {
global $post;
$atts['page_id'] = $post ? $post->ID : 0;
$atts['anchor'] = '#form_' . $atts['form']->form_key;
}
if ( $atts['edit_link'] === '1' ) {
$atts['edit_link'] = __( 'Edit', 'formidable-pro' );
}
$atts['permalink'] = get_permalink( $atts['page_id'] );
}
}
/**
* If delete_link is set to true in formresults, set the delete link text
*
* @since 2.0.09
* @param array $atts
*/
private static function setup_delete_link( &$atts ) {
if ( $atts['delete_link'] === '1' ) {
$atts['delete_link'] = __( 'Delete', 'formidable-pro' );
}
}
/**
* Get the filename for the formresults table
*
* @since 2.0.09
* @param array $atts
* @return string $filename
*/
private static function set_formresults_filename( &$atts ) {
if ( $atts['google'] ) {
$filename = 'google_table';
self::prepare_google_table( $atts );
} else {
$atts['fields'] = (array) $atts['fields'];
$filename = 'table';
}
return $filename;
}
private static function prepare_google_table( $atts ) {
global $frm_vars;
$options = array(
'allowHtml' => true,
'sort' => $atts['sort'] ? 'enable' : 'disable',
);
if ( $atts['pagesize'] ) {
$options['page'] = 'enable';
$options['pageSize'] = (int) $atts['pagesize'];
}
if ( $atts['style'] ) {
$options['cssClassNames'] = array( 'oddTableRow' => 'frm_even' );
}
$shortcode_options = $atts;
$shortcode_options['form_id'] = $atts['form']->id;
unset( $shortcode_options['entries'], $shortcode_options['form_cols'], $shortcode_options['form'] );
unset( $shortcode_options['permalink'], $shortcode_options['anchor'] );
$graph_vals = array(
'fields' => array(),
'entries' => array(),
'options' => $shortcode_options,
'graphOpts' => $options,
);
if ( $atts['clickable'] ) {
$graph_vals['options']['no_entries'] = make_clickable( $graph_vals['options']['no_entries'] );
}
if ( ! isset( $atts['entries'] ) || empty( $atts['entries'] ) ) {
$atts['entries'] = array();
}
$first_loop = true;
foreach ( $atts['entries'] as $k => $entry ) {
$this_entry = array(
'id' => $entry->id,
'metas' => array(),
);
foreach ( $atts['form_cols'] as $col ) {
$field_value = isset( $entry->metas[ $col->id ] ) ? $entry->metas[ $col->id ] : false;
$type = $col->type;
$val = FrmEntriesHelper::display_value(
$field_value,
$col,
array(
'type' => $type,
'post_id' => $entry->post_id,
'entry_id' => $entry->id,
'show_filename' => false,
)
);
if ( $col->type == 'number' ) {
$val = empty( $val ) ? '0' : $val;
if ( ! is_numeric( $val ) ) {
// Repeaters my not be numeric.
$type = 'text';
}
} elseif ( $col->type == 'checkbox' && count( $col->options ) == 1 ) {
// force boolean values
$val = empty( $val ) ? false : true;
} else if ( empty( $val ) ) {
$val = '';
} else {
$val = ( $atts['clickable'] && $col->type != 'file' ) ? make_clickable( $val ) : $val;
}
$this_entry['metas'][ $col->id ] = $val;
if ( $first_loop ) {
// add the fields to graphs on first loop only
$graph_vals['fields'][] = array(
'id' => $col->id,
'type' => $type,
'name' => $col->name,
'options' => $col->options,
'field_options' => array( 'post_field' => isset( $col->field_options['post_field'] ) ? $col->field_options['post_field'] : '' ),
);
}
unset( $col );
}
if ( $atts['edit_link'] && FrmProEntriesHelper::user_can_edit( $entry, $atts['form'] ) ) {
$this_entry['editLink'] = esc_url_raw( add_query_arg( array( 'frm_action' => 'edit', 'entry' => $entry->id ), $atts['permalink'] ) ) . $atts['anchor'];
}
if ( $atts['delete_link'] && FrmProEntriesHelper::user_can_delete( $entry ) ) {
$this_entry['deleteLink'] = esc_url_raw( add_query_arg( array( 'frm_action' => 'destroy', 'entry' => $entry->id ) ) );
}
$graph_vals['entries'][] = $this_entry;
$first_loop = false;
unset( $k, $entry, $this_entry );
}
if ( ! isset( $frm_vars['google_graphs'] ) ) {
$frm_vars['google_graphs'] = array();
}
if ( ! isset( $frm_vars['google_graphs']['table'] ) ) {
$frm_vars['google_graphs']['table'] = array();
}
$frm_vars['google_graphs']['table'][] = $graph_vals;
}
/**
* Load JS and CSS for a shortcode
*/
private static function load_form_scripts( $atts = array() ) {
global $frm_vars;
// Trigger CSS loading
if ( isset( $atts['style'] ) && $atts['style'] ) {
$frm_vars['load_css'] = true;
}
// Trigger the js load
$frm_vars['forms_loaded'][] = true;
}
public static function get_search( $atts ) {
$atts = shortcode_atts(
array(
'post_id' => '',
'label' => __( 'Search', 'formidable-pro' ),
'style' => false,
'views' => '',
),
$atts
);
if ( $atts['post_id'] == '' ) {
global $post;
if ( $post ) {
$atts['post_id'] = $post->ID;
}
}
if ( $atts['post_id'] != '' ) {
$action_link = get_permalink($atts['post_id']);
} else {
$action_link = '';
}
if ( ! empty($atts['style']) ) {
self::load_form_scripts();
if ( $atts['style'] == 1 || 'true' == $atts['style'] ) {
$atts['style'] = FrmStylesController::get_form_style_class('with_frm_style', 'default');
} else {
$atts['style'] .= ' with_frm_style';
}
}
ob_start();
include(FrmProAppHelper::plugin_path() . '/classes/views/frmpro-entries/search.php');
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
public static function entry_link_shortcode( $atts ) {
$atts = shortcode_atts(
array(
'id' => false,
'field_key' => 'created_at',
'type' => 'list',
'logged_in' => true,
'edit' => true,
'class' => '',
'link_type' => 'page',
'blank_label' => '',
'param_name' => 'entry',
'param_value' => 'key',
'page_id' => false,
'show_delete' => false,
'confirm' => __( 'Are you sure you want to delete that entry?', 'formidable-pro' ),
'drafts' => false,
'order' => '',
'user_id' => 'current',
),
$atts
);
// Keep logged_in for reverse compatibility
if ( $atts['logged_in'] == false ) {
$atts['user_id'] = false;
}
$user_ID = get_current_user_id();
if ( ! $atts['id'] || ( $atts['user_id'] && ! $user_ID ) ) {
return;
}
$atts = self::fill_entry_links_atts($atts);
$action = ( isset($_GET) && isset($_GET['frm_action']) ) ? 'frm_action' : 'action';
$entry_action = FrmAppHelper::simple_get( $action, 'sanitize_title' );
$entry_key = FrmAppHelper::simple_get( 'entry', 'sanitize_title' );
if ( $entry_action == 'destroy' ) {
self::maybe_delete_entry($entry_key);
}
$entries = self::get_entry_link_entries( $atts );
if ( empty($entries) ) {
return;
}
$extra_args = array(
'entry_action' => $entry_action,
'entry_key' => $entry_key,
'current_user' => $user_ID,
);
self::maybe_remove_entries_from_list( $extra_args, $atts, $entries );
$content = array();
switch ( $atts['type'] ) {
case 'list':
self::entry_link_list( $entries, $atts, $content );
break;
case 'select':
self::entry_link_select( $entries, $atts, $content );
break;
case 'collapse':
self::entry_link_collapse( $entries, $atts, $content );
}
$content = implode('', $content);
return $content;
}
private static function fill_entry_links_atts( $atts ) {
$atts['id'] = (int) $atts['id'];
if ( $atts['show_delete'] === 1 ) {
$atts['show_delete'] = __( 'Delete', 'formidable-pro' );
}
$atts['label'] = $atts['show_delete'];
$atts['field'] = false;
if ( $atts['field_key'] != 'created_at' ) {
$atts['field'] = FrmField::getOne($atts['field_key']);
if ( ! $atts['field'] ) {
$atts['field_key'] = 'created_at';
}
}
if ( ! in_array( $atts['type'], array( 'list', 'collapse', 'select' ) ) ) {
$atts['type'] = 'select';
}
if ( empty( $atts['confirm'] ) ) {
$atts['confirm'] = __( 'Are you sure you want to delete that entry?', 'formidable-pro' );
}
if ( $atts['user_id'] == 'current' ) {
$atts['user_id'] = get_current_user_id();
}
global $post;
$atts['permalink'] = get_permalink( $atts['page_id'] ? $atts['page_id'] : $post->ID );
return $atts;
}
private static function get_entry_link_entries( $atts ) {
$s = FrmAppHelper::get_param( 'frm_search', false, 'get', 'sanitize_text_field' );
if ( $s ) {
$entry_ids = FrmProEntriesHelper::get_search_ids( $s, $atts['id'], array( 'is_draft' => $atts['drafts'], 'user_id' => $atts['user_id'] ) );
} else {
$entry_ids = FrmEntryMeta::getEntryIds( array( 'fi.form_id' => (int) $atts['id'] ), '', '', true, array( 'is_draft' => $atts['drafts'], 'user_id' => $atts['user_id'] ) );
}
if ( empty($entry_ids) ) {
return;
}
$order = strpos( strtolower( trim( $atts['order'] ) ), 'order ' ) === 0 ? $atts['order'] : '';
$order = ( $atts['type'] == 'collapse' || $atts['order'] == 'DESC' ) ? ' ORDER BY it.created_at DESC' : $order;
$entries = FrmEntry::getAll( array( 'it.id' => $entry_ids ), $order, '', true);
return $entries;
}
/**
* Remove deleted entries from the list.
* Also remove private, draft, and pending posts if the current user is not the creator or an administrator.
*
* @since 2.0.18
* @param array $extra_args
* @param array $atts
* @param array $entries
*/
private static function maybe_remove_entries_from_list( $extra_args, $atts, &$entries ) {
$public_entries = array();
$post_status_check = array();
foreach ( $entries as $k => $entry ) {
// If entry was just deleted, don't show it in list
if ( $extra_args['entry_action'] == 'destroy' && in_array( $extra_args['entry_key'], array( $entry->item_key, $entry->id ) ) ) {
continue;
}
// If entry has a post, check the post status
if ( $entry->post_id ) {
$post_status_check[ $entry->post_id ] = $entry->id;
}
$public_entries[ $entry->id ] = $entry;
}
$current_user_is_creator_of_all_listed_entries = ( $extra_args['current_user'] && $atts['user_id'] == $extra_args['current_user'] );
if ( current_user_can( 'administrator' ) || $current_user_is_creator_of_all_listed_entries ) {
// If the current user is an administrator or the creator of the entry, don't remove private, draft, or pending posts
} else if ( ! empty( $post_status_check ) ) {
global $wpdb;
$query = array( 'post_status !' => 'publish', 'ID' => array_keys( $post_status_check ) );
$remove_entries = FrmDb::get_col( $wpdb->posts, $query, 'ID' );
unset($query);
foreach ( $remove_entries as $entry_post_id ) {
unset( $public_entries[ $post_status_check[ $entry_post_id ] ] );
}
unset( $remove_entries );
}
$entries = $public_entries;
}
private static function entry_link_list( $entries, $atts, array &$content ) {
$content[] = '<ul class="frm_entry_ul ' . $atts['class'] . '">' . "\n";
foreach ( $entries as $entry ) {
$value = self::entry_link_meta_value($entry, $atts);
$link = self::entry_link_href($entry, $atts);
$content[] = '<li><a href="' . esc_url( $link ) . '">' . $value . '</a>';
if ( ! empty( $atts['show_delete'] ) && FrmProEntriesHelper::user_can_delete( $entry ) ) {
$content[] = ' <a href="' . esc_url( add_query_arg( array( 'frm_action' => 'destroy', 'entry' => $entry->id ), $atts['permalink'] ) ) . '" class="frm_delete_list" data-frmconfirm="' . esc_attr( $atts['confirm'] ) . '">' . $atts['show_delete'] . '</a>' . "\n";
}
$content[] = "</li>\n";
}
$content[] = "</ul>\n";
}
private static function entry_link_collapse( $entries, $atts, array &$content ) {
FrmProStylesController::enqueue_jquery_css();
wp_enqueue_script('jquery-ui-core');
wp_enqueue_script('formidable' );
wp_enqueue_script('formidablepro');
$content[] = '<div class="frm_collapse">';
$year = '';
$month = '';
$prev_year = false;
$prev_month = false;
foreach ( $entries as $entry ) {
$value = self::entry_link_meta_value($entry, $atts);
$link = self::entry_link_href($entry, $atts);
$timestamp = strtotime( $entry->created_at );
$new_year = date_i18n( 'Y', $timestamp );
$new_month = date_i18n( 'F', $timestamp );
if ( $new_year != $year ) {
if ( $prev_year ) {
if ( $prev_month ) {
$content[] = '</ul></div>';
}
$content[] = '</div>';
$prev_month = false;
}
$class = $prev_year ? ' frm_hidden' : '';
$triangle = $prev_year ? 'e' : 's';
$content[] = "\n" . '<div class="frm_year_heading frm_year_heading_' . esc_attr( $atts['id'] ) . '">
<span class="ui-icon ui-icon-triangle-1-' . esc_attr( $triangle ) . '"></span>' . "\n" .
'<a>' . sanitize_text_field( $new_year ) . '</a></div>' . "\n" .
'<div class="frm_toggle_container' . esc_attr( $class ) . '">' . "\n";
$prev_year = true;
}
if ( $new_month != $month ) {
if ( $prev_month ) {
$content[] = '</ul></div>';
}
$class = $prev_month ? ' frm_hidden' : '';
$triangle = $prev_month ? 'e' : 's';
$content[] = '<div class="frm_month_heading frm_month_heading_' . esc_attr( $atts['id'] ) . '">
<span class="ui-icon ui-icon-triangle-1-' . esc_attr( $triangle ) . '"></span>' . "\n" .
'<a>' . sanitize_text_field( $new_month ) . '</a>' . "\n" . '</div>' . "\n" .
'<div class="frm_toggle_container frm_month_listing' . esc_attr( $class ) . '"><ul>' . "\n";
$prev_month = true;
}
$content[] = '<li><a href="' . esc_url( $link ) . '">' . $value . '</a>';
if ( $atts['show_delete'] && FrmProEntriesHelper::user_can_delete($entry) ) {
$content[] = ' <a href="' . esc_url( add_query_arg( array( 'frm_action' => 'destroy', 'entry' => $entry->id ), $atts['permalink'] ) ) . '" class="frm_delete_list" data-frmconfirm="' . esc_attr( $atts['confirm'] ) . '">' . $atts['show_delete'] . '</a>' . "\n";
}
$content[] = "</li>\n";
$year = $new_year;
$month = $new_month;
}
if ( $prev_year ) {
$content[] = '</div>';
}
if ( $prev_month ) {
$content[] = '</ul></div>';
}
$content[] = '</div>';
}
private static function entry_link_select( $entries, $atts, array &$content ) {
global $post;
$content[] = '<select id="frm_select_form_' . esc_attr( $atts['id'] ) . '" name="frm_select_form_' . esc_attr( $atts['id'] ) . '" class="' . esc_attr( $atts['class'] ) . '" onchange="location=this.options[this.selectedIndex].value;">' . "\n";
$content[] = '<option value="' . esc_attr( get_permalink( $post->ID ) ) . '">' . $atts['blank_label'] . '</option>' . "\n";
$entry_param = FrmAppHelper::simple_get( 'entry', 'sanitize_title' );
foreach ( $entries as $entry ) {
$value = self::entry_link_meta_value($entry, $atts);
$link = self::entry_link_href($entry, $atts);
$content[] = '<option value="' . esc_url( $link ) . '" ' . selected( $entry_param, $entry->item_key, false ) . '>' . esc_attr($value) . "</option>\n";
}
$content[] = "</select>\n";
if ( $atts['show_delete'] && $entry_param ) {
$content[] = " <a href='" . esc_url( add_query_arg( array( 'frm_action' => 'destroy', 'entry' => $entry_param ), $atts['permalink'] ) ) . "' class='frm_delete_list' data-frmconfirm='" . esc_attr( $atts['confirm'] ) . "'>" . $atts['show_delete'] . "</a>\n";
}
}
private static function entry_link_meta_value( $entry, $atts ) {
$value = '';
if ( $atts['field_key'] && $atts['field_key'] != 'created_at' ) {
if ( $entry->post_id && ( ( $atts['field'] && $atts['field']->field_options['post_field'] ) || $atts['field']->type == 'tag' ) ) {
$meta = false;
$value = FrmProEntryMetaHelper::get_post_value(
$entry->post_id,
$atts['field']->field_options['post_field'],
$atts['field']->field_options['custom_field'],
array(
'type' => $atts['field']->type, 'form_id' => $atts['field']->form_id, 'field' => $atts['field'],
)
);
} else {
$meta = isset( $entry->metas[ $atts['field']->id ] ) ? $entry->metas[ $atts['field']->id ] : '';
}
} else {
$meta = reset($entry->metas);
}
self::entry_link_value($entry, $atts, $meta, $value);
return $value;
}
private static function entry_link_value( $entry, $atts, $meta, &$value ) {
if ( 'created_at' != $atts['field_key'] && $meta ) {
if ( is_object($meta) ) {
$value = $meta->meta_value;
} else {
$value = $meta;
}
}
if ( '' == $value ) {
$value = date_i18n(get_option('date_format'), strtotime($entry->created_at));
return;
}
$new_atts = array(
'type' => $atts['field']->type,
'display_type' => $atts['type'],
'show_filename' => false,
);
$value = FrmEntriesHelper::display_value( $value, $atts['field'], $new_atts );
}
private static function entry_link_href( $entry, $atts ) {
$args = array(
$atts['param_name'] => ( 'key' == $atts['param_value'] ) ? $entry->item_key : $entry->id,
);
if ( $atts['edit'] ) {
$args['frm_action'] = 'edit';
}
if ( $atts['link_type'] === 'scroll' ) {
$link = '#' . $entry->item_key;
} elseif ( $atts['link_type'] === 'admin' ) {
$link = add_query_arg( $args, FrmAppHelper::get_server_value( 'REQUEST_URI' ) );
} else {
$link = add_query_arg($args, $atts['permalink']);
}
return $link;
}
public static function entry_edit_link( $atts ) {
global $post, $frm_vars, $wpdb;
$atts = shortcode_atts(
array(
'id' => ( isset( $frm_vars['editing_entry'] ) ? $frm_vars['editing_entry'] : false ),
'label' => __( 'Edit', 'formidable-pro' ),
'cancel' => __( 'Cancel', 'formidable-pro' ),
'class' => '',
'page_id' => ( $post ? $post->ID : 0 ),
'html_id' => false,
'prefix' => '',
'form_id' => false,
'title' => '',
'fields' => array(),
'exclude_fields' => array(),
'start_page' => 1,
),
$atts
);
$link = '';
$entry_id = ( $atts['id'] && is_numeric( $atts['id'] ) ) ? $atts['id'] : FrmAppHelper::get_param( 'entry', false, 'get', 'sanitize_text_field' );
if ( ! $entry_id && $atts['id'] === 'current' ) {
if ( ! empty( $frm_vars['editing_entry'] ) && is_numeric( $frm_vars['editing_entry'] ) ) {
$entry_id = $frm_vars['editing_entry'];
} elseif ( $post ) {
$entry_id = FrmDb::get_var( $wpdb->prefix . 'frm_items', array( 'post_id' => $post->ID ) );
}
}
if ( ! $entry_id ) {
return '';
}
if ( ! $atts['form_id'] ) {
$atts['form_id'] = (int) FrmDb::get_var( $wpdb->prefix . 'frm_items', array( 'id' => $entry_id ), 'form_id' );
}
//if user is not allowed to edit, then don't show the link
if ( ! FrmProEntriesHelper::user_can_edit($entry_id, $atts['form_id']) ) {
return $link;
}
if ( empty($atts['prefix']) ) {
$link = add_query_arg( array( 'frm_action' => 'edit', 'entry' => $entry_id ), get_permalink( $atts['page_id'] ) );
if ( $atts['label'] ) {
$link = '<a href="' . esc_url( $link ) . '" class="' . esc_attr( $atts['class'] ) . '">' . $atts['label'] . '</a>';
}
return $link;
}
$action = ( $_POST && isset( $_POST['frm_action'] ) ) ? 'frm_action' : 'action';
$form_action = FrmAppHelper::get_post_param( $action, '', 'sanitize_title' );
$posted_form_id = FrmAppHelper::get_post_param( 'form_id', '', 'sanitize_title' );
$posted_entry_id = FrmAppHelper::get_post_param( 'id', '', 'sanitize_title' );
if ( $form_action == 'update' && $posted_form_id == $atts['form_id'] && $posted_entry_id == $entry_id ) {
$errors = ( isset( $frm_vars['created_entries'][ $atts['form_id'] ] ) && isset( $frm_vars['created_entries'][ $atts['form_id'] ]['errors'] ) ) ? $frm_vars['created_entries'][ $atts['form_id'] ]['errors'] : array();
if ( ! empty($errors) ) {
return FrmFormsController::get_form_shortcode( array( 'id' => $atts['form_id'], 'entry_id' => $entry_id, 'fields' => $atts['fields'], 'exclude_fields' => $atts['exclude_fields'] ) );
}
$link .= "<script type='text/javascript'>document.addEventListener('DOMContentLoaded',function(){frmFrontForm.scrollToID('" . esc_js( $atts['prefix'] . $entry_id ) . "');});</script>";
}
if ( empty($atts['title']) ) {
$atts['title'] = $atts['label'];
}
if ( ! $atts['html_id'] ) {
$atts['html_id'] = 'frm_edit_' . $entry_id;
}
self::load_form_scripts();
$data = array(
'entryid' => $entry_id,
'prefix' => $atts['prefix'],
'pageid' => $atts['page_id'],
'formid' => $atts['form_id'],
'cancel' => $atts['cancel'],
'edit' => $atts['label'],
'startpage' => $atts['start_page'],
);
if ( ! empty( $atts['fields'] ) ) {
$data['fields'] = implode( ',', (array) $atts['fields'] );
}
if ( ! empty( $atts['exclude_fields'] ) ) {
$data['exclude_fields'] = implode( ',', (array) $atts['exclude_fields'] );
}
$link .= '<span class="frm_edit_link_container">';
$link .= '<a href="#" class="frm_inplace_edit frm_edit_link ' . esc_attr( $atts['class'] ) . '" id="' . esc_attr( $atts['html_id'] ) . '" title="' . esc_attr( $atts['title'] ) . '"';
foreach ( $data as $name => $label ) {
$link .= ' data-' . str_replace( '_', '', sanitize_title( $name ) ) . '="' . esc_attr( $label ) . '"';
}
$link .= '>' . wp_kses_post( $atts['label'] ) . "</a>\n";
$link .= '</span>';
return $link;
}
public static function entry_update_field( $atts ) {
global $frm_vars, $frm_update_link_count;
$atts = shortcode_atts(
array(
'id' => ( isset( $frm_vars['editing_entry'] ) ? $frm_vars['editing_entry'] : false ),
'field_id' => false,
'label' => __( 'Update', 'formidable-pro' ),
'class' => '',
'value' => '',
'message' => '',
'title' => '',
),
$atts
);
if ( ! $atts['field_id'] ) {
return __( 'You are missing options in your shortcode. A field_id is required.', 'formidable-pro' );
}
$entry_id = ( $atts['id'] && is_numeric( $atts['id'] ) ) ? absint( $atts['id'] ) : FrmAppHelper::get_param( 'entry', false, 'get', 'absint' );
if ( ! $entry_id ) {
return '';
}
$field = FrmField::getOne( $atts['field_id'] );
if ( ! $field || ! FrmProEntriesHelper::user_can_edit( $entry_id, $field->form_id ) ) {
return '';
}
// Check if current value is equal to new value
$current_val = FrmProEntryMetaHelper::get_post_or_meta_value( $entry_id, $field );
if ( $current_val == $atts['value'] ) {
return '';
}
self::load_form_scripts();
if ( ! $frm_update_link_count ) {
$frm_update_link_count = 0;
}
$frm_update_link_count++;
if ( empty( $atts['title'] ) ) {
$atts['title'] = $atts['label'];
}
$value = htmlspecialchars( addslashes( $atts['value'] ) );
$message = htmlspecialchars( addslashes( $atts['message'] ) );
$onclick = "frmUpdateField({$entry_id},{$field->id},'{$value}','{$message}',{$frm_update_link_count});return false;";
$html_id = "frm_update_field_{$entry_id}_{$field->id}_{$frm_update_link_count}";
$class = esc_attr( 'frm_update_field_link ' . $atts['class'] );
$title = esc_attr( $atts['title'] );
$link = "<a href=\"#\" onclick=\"{$onclick}\" id=\"{$html_id}\" class=\"{$class}\" title=\"{$title}\">{$atts['label']}</a>";
return $link;
}
public static function entry_delete_link( $atts ) {
global $post, $frm_vars;
$atts = shortcode_atts(
array(
'id' => ( isset( $frm_vars['editing_entry'] ) ? $frm_vars['editing_entry'] : false ),
'label' => __( 'Delete' ),
'confirm' => __( 'Are you sure you want to delete that entry?', 'formidable-pro' ),
'class' => '',
'page_id' => $post ? $post->ID : 0,
'html_id' => false,
'prefix' => '',
'title' => '',
),
$atts
);
$entry_id = FrmAppHelper::get_param( 'id', false, 'get', 'sanitize_text_field' );
$entry_id = ( $atts['id'] && is_numeric( $atts['id'] ) ) ? $atts['id'] : ( FrmAppHelper::is_admin() ? $entry_id : FrmAppHelper::get_param( 'entry', false, 'get', 'sanitize_text_field' ) );
if ( empty( $entry_id ) || ! FrmProEntriesHelper::user_can_delete( $entry_id ) ) {
// User doesn't have permission to delete this entry
return '';
}
self::load_form_scripts();
if ( ! empty($atts['prefix']) ) {
if ( ! $atts['html_id'] ) {
$atts['html_id'] = 'frm_delete_' . $entry_id;
}
$link = '<a href="#" class="frm_ajax_delete frm_delete_link ' . esc_attr( $atts['class'] ) . '" id="' . esc_attr( $atts['html_id'] ) . '" data-deleteconfirm="' . esc_attr( $atts['confirm'] ) . '" data-entryid="' . esc_attr( $entry_id ) . '" data-prefix="' . esc_attr( $atts['prefix'] ) . '">' . $atts['label'] . "</a>\n";
return $link;
}
$link = '';
// Delete entry now
$action = FrmAppHelper::get_param( 'frm_action', '', 'get', 'sanitize_title' );
if ( $action == 'destroy' ) {
$entry_key = FrmAppHelper::get_param( 'entry', '', 'get', 'absint' );
if ( $entry_key && $entry_key == $entry_id ) {
$link = self::ajax_destroy(false, false, false);
if ( ! empty($link) ) {
$new_link = '<div class="frm_message">' . $link . '</div>';
if ( empty($atts['label']) ) {
return;
}
if ( $link == __( 'Your entry was successfully deleted', 'formidable-pro' ) ) {
return $new_link;
} else {
$link = $new_link;
}
unset($new_link);
}
}
}
$delete_link = wp_nonce_url( admin_url( 'admin-ajax.php?action=frm_entries_destroy&entry=' . $entry_id . '&redirect=' . $atts['page_id'] ), 'frm_ajax', 'nonce' );
if ( empty($atts['label']) ) {
$link .= $delete_link;
} else {
if ( empty($atts['title']) ) {
$atts['title'] = $atts['label'];
}
$link .= '<a href="' . esc_url( $delete_link ) . '" class="' . esc_attr( $atts['class'] ) . '" data-frmconfirm="' . esc_attr( $atts['confirm'] ) . '" title="' . esc_attr( $atts['title'] ) . '">' . $atts['label'] . '</a>' . "\n";
}
return $link;
}
public static function get_field_value_shortcode( $sc_atts ) {
$atts = shortcode_atts(
array(
'entry' => false,
'field_id' => false,
'user_id' => false,
'ip' => false,
'show' => '',
'format' => '',
'return_array' => false,
'default' => '',
'truncate' => false,
),
$sc_atts
);
// Include all user-defined atts as well
$atts = (array) $atts + (array) $sc_atts;
// For reverse compatibility
if ( isset( $atts['entry_id'] ) && ! $atts['entry'] ) {
$atts['entry'] = $atts['entry_id'];
}
if ( ! $atts['field_id'] ) {
return __( 'You are missing options in your shortcode. field_id is required.', 'formidable-pro' );
}
$field = FrmField::getOne($atts['field_id']);
if ( ! $field ) {
return $atts['default'];
}
$entries = self::get_frm_field_value_entry( $field, $atts );
if ( empty( $entries ) ) {
return $atts['default'];
}
$truncate = $atts['truncate'] && is_numeric( $atts['truncate'] ) && 1 !== (int) $atts['truncate'] ? $atts['truncate'] : false;
if ( $truncate ) {
// unset the attribute to avoid double truncating from FrmEntriesHelper::display_value
unset( $atts['truncate'] );
}
$values = array();
foreach ( $entries as $entry ) {
$value = self::get_single_field_value( $entry, $field, $atts );
if ( $value != '' ) {
$values[] = $value;
}
}
$value = implode( ', ', $values );
if ( $value == '' ) {
$value = $atts['default'];
}
if ( $truncate ) {
$more_text = isset( $atts['more_text'] ) ? sanitize_text_field( $atts['more_text'] ) : '...';
$value = FrmAppHelper::truncate( $value, $truncate, 3, $more_text );
}
return $value;
}
private static function get_single_field_value( $entry, $field, $atts ) {
$value = FrmProEntryMetaHelper::get_post_or_meta_value( $entry, $field, $atts );
$atts['type'] = $field->type;
$atts['post_id'] = $entry->post_id;
$atts['entry_id'] = $entry->id;
self::add_frm_field_value_atts_for_file_upload_field( $field, $atts );
$tested_field_types = array( 'time', 'file' );
if ( in_array( $field->type, $tested_field_types ) || ! empty( $atts['format'] ) || ( isset( $atts['show'] ) && ! empty( $atts['show'] ) ) ) {
if ( empty( $atts['format'] ) ) {
unset( $atts['format'] );
}
$value = FrmFieldsHelper::get_display_value( $value, $field, $atts );
} else {
$value = FrmEntriesHelper::display_value( $value, $field, $atts);
}
return $value;
}
/**
* Add some default attributes for a file upload field in the frm-field-value shortcode
*
* @since 2.02.11
*
* @param object $field
* @param array $atts
*/
private static function add_frm_field_value_atts_for_file_upload_field( $field, &$atts ) {
if ( $field->type != 'file' ) {
return;
}
if ( ! isset( $atts['show_filename'] ) ) {
$atts['show_filename'] = false;
}
if ( ! isset( $atts['size'] ) ) {
$atts['size'] = 'thumbnail';
}
// Show the image by default, for reverse compatibility
if ( ! isset( $atts['html'] ) ) {
if ( ! isset( $atts['show_image'] ) ) {
$atts['show_image'] = 1;
}
if ( ! isset( $atts['add_link'] ) ) {
$atts['add_link'] = 1;
}
}
}
/**
* Get entry object for frm_field_value shortcode
* Uses user_id, entry, or ip atts to fetch the entry
*
* @since 2.0.13
* @param object $field
* @param array $atts
* @return array $entry
*/
private static function get_frm_field_value_entry( $field, &$atts ) {
$query = array( 'form_id' => $field->form_id );
$order = array( 'order_by' => 'created_at DESC' );
if ( $atts['user_id'] ) {
// make sure we are not getting entries for logged-out users
$query['user_id'] = (int) FrmAppHelper::get_user_id_param( $atts['user_id'] );
$query['user_id !'] = 0;
}
if ( $atts['entry'] ) {
if ( ! is_numeric($atts['entry']) ) {
$atts['entry'] = FrmAppHelper::simple_get( $atts['entry'], 'sanitize_title', $atts['entry'] );
}
if ( empty( $atts['entry'] ) ) {
return array();
}
if ( is_numeric( $atts['entry'] ) ) {
$query[] = array( 'or' => 1, 'id' => $atts['entry'], 'parent_item_id' => $atts['entry'] );
} else {
$query[] = array( 'item_key' => $atts['entry'] );
}
} else {
// get the latest entry
$order['limit'] = 1;
}
if ( $atts['ip'] ) {
$use_current = $atts['ip'] === true || $atts['ip'] === '1' || $atts['ip'] === 'current';
$query['ip'] = $use_current ? FrmAppHelper::get_ip_address() : $atts['ip'];
}
$entry = FrmDb::get_results( 'frm_items', $query, 'post_id, id', $order );
return $entry;
}
public static function show_entry_shortcode( $atts ) {
return FrmEntriesController::show_entry_shortcode( $atts );
}
/**
* Alternate Row Color for Default HTML
*
* @return string
*/
public static function change_row_color() {
global $frm_email_col;
$bg_color = 'bg_color';
if ( $frm_email_col ) {
$bg_color .= '_active';
$frm_email_col = false;
} else {
$frm_email_col = true;
}
$bg_color = FrmStylesController::get_style_val($bg_color);
$alt_color = 'background-color:#' . $bg_color . ';';
return $alt_color;
}
public static function maybe_set_cookie( $entry_id, $form_id ) {
if ( defined('WP_IMPORTING') || defined('DOING_AJAX') || defined('REST_REQUEST') ) {
return;
}
if ( isset($_POST) && isset($_POST['frm_skip_cookie']) ) {
self::set_cookie($entry_id, $form_id);
return;
}
include(FrmProAppHelper::plugin_path() . '/classes/views/frmpro-entries/set_cookie.php');
}
/* AJAX */
public static function wp_ajax_destroy() {
check_ajax_referer( 'frm_ajax', 'nonce' );
$echo = true;
if ( isset($_REQUEST['redirect']) ) {
// don't echo if redirecting
$echo = false;
}
self::ajax_destroy(false, true, $echo);
if ( ! $echo ) {
// redirect instead of loading a blank page
wp_redirect( esc_url_raw( get_permalink( $_REQUEST['redirect'] ) ) );
die();
}
wp_die();
}
public static function ajax_destroy( $form_id = false, $ajax = true, $echo = true ) {
global $wpdb, $frm_vars;
$entry_key = FrmAppHelper::get_param( 'entry', '', 'get', 'sanitize_title' );
if ( ! $form_id ) {
$form_id = FrmAppHelper::get_param( 'form_id', '', 'get', 'absint' );
}
if ( ! $entry_key ) {
return;
}
if ( isset( $frm_vars['deleted_entries'] ) && is_array( $frm_vars['deleted_entries'] ) && in_array( $entry_key, $frm_vars['deleted_entries'] ) ) {
return;
}
if ( is_numeric( $entry_key ) ) {
$where = array( 'id' => $entry_key );
} else {
$where = array( 'item_key' => $entry_key );
}
$entry = FrmDb::get_row( $wpdb->prefix . 'frm_items', $where, 'id, form_id, is_draft, user_id' );
unset( $where );
if ( ! $entry || ( $form_id && $entry->form_id != (int) $form_id ) ) {
return;
}
$message = self::maybe_delete_entry($entry);
if ( $message && ! is_numeric($message) ) {
if ( $echo ) {
echo '<div class="frm_message">' . $message . '</div>';
}
return;
}
if ( ! isset( $frm_vars['deleted_entries'] ) || empty( $frm_vars['deleted_entries'] ) ) {
$frm_vars['deleted_entries'] = array();
}
$frm_vars['deleted_entries'][] = $entry->id;
if ( $ajax && $echo ) {
$message = 'success';
echo 'success';
} else if ( ! $ajax ) {
$message = apply_filters( 'frm_delete_message', esc_html__( 'Your entry was successfully deleted', 'formidable-pro' ), $entry );
if ( $echo ) {
echo '<div class="frm_message">' . $message . '</div>';
}
} else {
$message = '';
}
return $message;
}
public static function maybe_delete_entry( $entry ) {
FrmEntry::maybe_get_entry( $entry );
if ( ! $entry || ! FrmProEntriesHelper::user_can_delete($entry) ) {
return __( 'There was an error deleting that entry', 'formidable-pro' );
}
return FrmEntry::destroy( $entry->id );
}
public static function send_email() {
if ( current_user_can('frm_view_forms') || current_user_can('frm_edit_forms') || current_user_can('frm_edit_entries') ) {
if ( FrmAppHelper::doing_ajax() ) {
check_ajax_referer( 'frm_ajax', 'nonce' );
}
$entry_id = FrmAppHelper::get_param( 'entry_id', '', 'get', 'absint' );
$form_id = FrmAppHelper::get_param( 'form_id', '', 'get', 'absint' );
add_filter( 'frm_echo_emails', '__return_true' );
ob_start();
FrmFormActionsController::trigger_actions( 'create', $form_id, $entry_id, 'email' );
$emails = ob_get_contents();
ob_end_clean();
if ( empty( $emails ) ) {
$emails = __( 'no one', 'formidable-pro' );
}
printf( esc_html__( 'Resent to %s', 'formidable-pro' ), esc_html( $emails ) );
self::suggest_smtp();
} else {
esc_html_e( 'Resent to No one! You do not have permission', 'formidable-pro' );
}
wp_die();
}
/**
* Include a link to the SMTP page after an email is resent.
*
* @since 4.04.04
*/
private static function suggest_smtp() {
$suggest_smtp = class_exists( 'FrmSMTPController' ) && current_user_can( 'activate_plugins' ) && ! function_exists( 'wp_mail_smtp' );
if ( ! $suggest_smtp ) {
return;
}
$link = admin_url( 'admin.php?page=formidable-smtp' );
?>
<p>
<a href="<?php echo esc_url( $link ); ?>" class="frm_pro_tip">
<?php FrmAppHelper::icon_by_class( 'frmfont frm_star_full_icon', array( 'aria-hidden' => 'true' ) ); ?>
<?php esc_html_e( 'Not receiving emails?', 'formidable-pro' ); ?>
<span class="frm-tip-cta">
<?php esc_html_e( 'Setup SMTP.', 'formidable-pro' ); ?>
</span>
</a>
</p>
<?php
}
public static function ajax_set_cookie() {
check_ajax_referer( 'frm_ajax', 'nonce' );
self::set_cookie();
wp_die();
}
public static function set_cookie( $entry_id = false, $form_id = false ) {
if ( headers_sent() ) {
return;
}
if ( ! apply_filters('frm_create_cookies', true) ) {
return;
}
if ( ! $entry_id ) {
$entry_id = FrmAppHelper::get_param( 'entry_id', '', 'get', 'absint' );
}
if ( ! $form_id ) {
$form_id = FrmAppHelper::get_param( 'form_id', '', 'get', 'absint' );
}
$form = FrmForm::getOne($form_id);
if ( ! isset( $form->options['single_entry_type'] ) || $form->options['single_entry_type'] !== 'cookie' ) {
return;
}
$expiration = isset( $form->options['cookie_expiration'] ) ? ( (float) $form->options['cookie_expiration'] * 60 * 60 ) : 30000000;
$expiration = apply_filters('frm_cookie_expiration', $expiration, $form_id, $entry_id);
setcookie( 'frm_form' . $form_id . '_' . COOKIEHASH, current_time('mysql', 1), time() + $expiration, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
}
public static function ajax_create() {
if ( ! FrmAppHelper::doing_ajax() || ! isset( $_POST['form_id'] ) ) {
// normally, this function would be triggered with the wp_ajax hook, but we need it fired sooner
return;
}
$allowed_actions = array( 'frm_entries_create', 'frm_entries_update' );
if ( ! in_array( FrmAppHelper::get_post_param( 'action', '', 'sanitize_title' ), $allowed_actions ) ) {
// allow ajax creating and updating
return;
}
$response = array( 'errors' => array(), 'content' => '', 'pass' => false );
$form = FrmForm::getOne( FrmAppHelper::get_post_param( 'form_id', 0, 'absint' ) );
if ( ! $form ) {
echo json_encode( $response );
wp_die();
}
$is_ajax_on = FrmProForm::is_ajax_on( $form );
$no_ajax_fields = $is_ajax_on ? false : array( 'file' );
$errors = FrmEntryValidate::validate( wp_unslash( $_POST ), $no_ajax_fields );
if ( empty( $errors ) ) {
if ( $is_ajax_on ) {
global $frm_vars;
$frm_vars['ajax'] = true;
$frm_vars['css_loaded'] = true;
self::maybe_include_exclude_fields( $form->id );
// don't load scripts if we are going backwards in the form
$going_backwards = FrmProFormsHelper::going_to_prev( $form->id );
// save the entry if there is not another page or when saving a draft
if ( ( ! isset( $_POST[ 'frm_page_order_' . $form->id ] ) && ! $going_backwards ) || FrmProFormsHelper::saving_draft() ) {
$processed = true;
FrmEntriesController::process_entry( $errors, true );
} else {
self::maybe_autosave_on_page_turn( $errors, $form );
$response['page'] = FrmProFormsHelper::get_the_page_number( $form->id );
}
$get = FrmProFormState::get_from_request( 'get', array() );
if ( $get ) {
FrmProAppController::set_get( $get );
}
self::maybe_include_exclude_fields( $form->id );
$title = FrmProFormState::get_from_request( 'title', false );
$description = FrmProFormState::get_from_request( 'description', false );
$response['content'] .= FrmFormsController::show_form( $form->id, '', $title, $description );
// trigger the footer scripts if there is a form to show
if ( $errors || ! isset( $processed ) || ! empty( $frm_vars['forms_loaded'] ) ) {
ob_start();
FrmProFormsController::print_ajax_scripts( $going_backwards ? 'none' : '' );
FrmProFormsController::footer_js();
$response['content'] .= ob_get_contents();
ob_end_clean();
// Mark the end of added footer content
$response['content'] .= '<span class="frm_end_ajax_' . $form->id . '"></span>';
}
}
} else {
$obj = array();
foreach ( $errors as $field => $error ) {
$field_id = str_replace( 'field', '', $field );
$error = self::maybe_modify_ajax_error( $error, $field_id, $form, $errors );
$obj[ $field_id ] = $error;
}
$response['errors'] = $obj;
$invalid_msg = FrmFormsHelper::get_invalid_error_message( array( 'form' => $form ) );
$response['error_message'] = FrmFormsHelper::get_success_message(
array(
'message' => $invalid_msg, 'form' => $form,
'entry_id' => 0,
'class' => FrmFormsHelper::form_error_class(),
)
);
}
if ( FrmProFieldCaptcha::posting_captcha_data() ) {
$checked = FrmProFieldCaptcha::checked();
if ( $checked ) {
$response['recaptcha'] = $checked;
}
}
echo json_encode( $response );
wp_die();
}
/**
* If a field has custom HTML for errors, apply it around the message.
*
* @since 5.0.03
*
* @param string $error
* @param string $field_id
* @param stdClass $form the form being submitted (not necessarily the field's form when embedded/repeated).
* @param array $errors all errors that were caught in this form submission, passed into the frm_before_replace_shortcodes filter for reference.
* @return string
*/
private static function maybe_modify_ajax_error( $error, $field_id, $form, $errors ) {
if ( ! is_callable( 'FrmFieldsController::pull_custom_error_body_from_custom_html' ) ) {
// this function only exists since formidable lite 5.0.03
// if the lite version has not been updated, leave the error unmodified.
return $error;
}
if ( false !== strpos( $field_id, '-' ) ) {
// repeated fields look like field_id-repeater_id-iteration, so pull the first value for the field id.
list( $use_field_id ) = explode( '-', $field_id );
} else {
$use_field_id = $field_id;
}
if ( ! is_numeric( $use_field_id ) ) {
return $error;
}
$use_field = FrmField::getOne( $use_field_id );
if ( ! $use_field ) {
return $error;
}
$use_field = FrmFieldsHelper::setup_edit_vars( $use_field );
$error_body = FrmFieldsController::pull_custom_error_body_from_custom_html( $form, $use_field, $errors );
if ( false !== $error_body ) {
$error = str_replace( '[error]', $error, $error_body );
$error = str_replace( '[key]', $field_id, $error );
}
return $error;
}
/**
* @param int $form_id
* @return void
*/
public static function maybe_include_exclude_fields( $form_id ) {
$include_fields = FrmProFormState::get_from_request( 'include_fields', array() );
if ( $include_fields ) {
global $frm_vars;
$frm_vars['show_fields'] = $include_fields;
}
}
public static function setup_edit_vars( $values ) {
if ( ! isset( $values['edit_value'] ) ) {
$values['edit_value'] = ( $_POST && isset( $_POST['options']['edit_value'] ) ) ? wp_kses_post( $_POST['options']['edit_value'] ) : __( 'Update', 'formidable-pro' );
}
if ( ! isset($values['edit_msg']) ) {
if ( $_POST && isset( $_POST['options']['edit_msg'] ) ) {
$values['edit_msg'] = wp_kses_post( $_POST['options']['edit_msg'] );
} else {
$frmpro_settings = FrmProAppHelper::get_settings();
$values['edit_msg'] = $frmpro_settings->edit_msg;
}
}
return $values;
}
public static function edit_entry_ajax() {
$id = FrmAppHelper::get_param( 'id', '', 'post', 'absint' );
$entry_id = FrmAppHelper::get_param( 'entry_id', 0, 'post', 'absint' );
$post_id = FrmAppHelper::get_param( 'post_id', 0, 'post', 'sanitize_title' );
$fields = FrmAppHelper::get_param( 'fields', array(), 'post', 'sanitize_text_field' );
$exclude_fields = FrmAppHelper::get_param( 'exclude_fields', array(), 'post', 'sanitize_text_field' );
$start_page = FrmAppHelper::get_param( 'start_page', 1, 'post', 'absint' );
global $frm_vars;
$frm_vars['footer_loaded'] = true;
$frm_vars['inplace_edit'] = true;
if ( $entry_id ) {
$_GET['entry'] = $entry_id;
}
if ( $post_id && is_numeric( $post_id ) ) {
global $post;
if ( ! $post ) {
$post = get_post( $post_id );
}
}
FrmProFormsController::mark_jquery_as_loaded();
$atts = compact( 'id', 'entry_id', 'fields', 'exclude_fields' );
if ( 1 !== $start_page ) {
self::maybe_set_page_from_attribute( $id, $start_page );
} else {
self::maybe_set_page( $atts );
}
echo FrmFormsController::get_form_shortcode( $atts );
FrmProFormsController::print_ajax_scripts( 'all' );
wp_die();
}
/**
* @param int $form_id
* @param int $start_page
*/
private static function maybe_set_page_from_attribute( $form_id, $start_page ) {
$start_page_order = self::get_order_of_start_page_attribute( $form_id, $start_page );
if ( $start_page_order > 1 ) {
self::set_page( $form_id, $start_page_order );
}
}
/**
* @param int $form_id
* @param int $page
* @return int
*/
private static function get_order_of_start_page_attribute( $form_id, $page ) {
$page_break_orders = self::get_page_break_orders( $form_id );
$index = $page - 2; // offset by 2 because the first page break is not a real field and arrays are 0 indexed.
return array_key_exists( $index, $page_break_orders ) ? $page_break_orders[ $index ] : 1;
}
/**
* @param int $form_id
* @param int $page_break_order
*/
private static function set_page( $form_id, $page_break_order ) {
$_POST[ 'frm_page_order_' . $form_id ] = $page_break_order;
}
/**
* @param array $atts including keys id (form id), entry_id, fields, exclude_fields.
*/
private static function maybe_set_page( $atts ) {
$page = self::get_page_from_attributes( $atts );
if ( 1 !== $page ) {
self::set_page( $atts['id'], $page );
}
}
/**
* @param array $atts including keys id (form id), entry_id, fields, exclude_fields.
* @return int the page break field order to start on.
*/
private static function get_page_from_attributes( $atts ) {
$page = 1;
if ( empty( $atts['id'] ) || ( empty( $atts['fields'] ) && empty( $atts['exclude_fields'] ) ) ) {
// return the first page if information is missing or all fields are present.
return $page;
}
$form_id = $atts['id'];
$page_break_orders = self::get_page_break_orders( $form_id );
if ( ! $page_break_orders ) {
// stop if there are no page breaks for this form.
return $page;
}
$first_field_order = self::get_order_of_first_field( $atts );
foreach ( $page_break_orders as $page_break_order ) {
if ( $page_break_order > $first_field_order ) {
break;
}
$page = $page_break_order;
}
return $page;
}
/**
* @param int $form_id
* @return array<int> field orders for all page break fields.
*/
private static function get_page_break_orders( $form_id ) {
return FrmDb::get_col(
'frm_fields',
array(
'type' => 'break',
'form_id' => $form_id,
),
'field_order',
array(
'order_by' => 'field_order',
)
);
}
/**
* Get the field_order of the first field based off of what is included and excluded with field attributes.
*
* @param array $atts including keys id (form id), entry_id, fields, exclude_fields.
* @return int the lowest field_order value from the set of fields.
*/
private static function get_order_of_first_field( $atts ) {
$includes = ! empty( $atts['fields'] ) ? self::create_id_key_condition_pair( $atts['fields'] ) : array();
$excludes = ! empty( $atts['exclude_fields'] ) ? self::create_id_key_condition_pair( $atts['exclude_fields'], false ) : array();
$where = self::build_where_for_first_field_check( $atts['id'], $includes, $excludes );
$args = array( 'order_by' => 'field_order' );
return FrmDb::get_var( 'frm_fields', $where, 'field_order', $args );
}
/**
* @param array|string $fields
* @param bool $include
* @return array
*/
private static function create_id_key_condition_pair( $fields, $include = true ) {
$fields = self::maybe_explode( $fields );
$ids = self::pull_ids( $fields );
$keys = self::pull_keys( $fields );
$pair = array();
$suffix = $include ? '' : ' not';
if ( $ids ) {
$pair[ 'id' . $suffix ] = $ids;
}
if ( $keys ) {
$pair[ 'field_key' . $suffix ] = $keys;
if ( $ids ) {
$pair['or'] = 1;
}
}
return $pair;
}
/**
* @param int $form_id
* @param array $includes
* @param array $excludes
* @return array
*/
private static function build_where_for_first_field_check( $form_id, $includes, $excludes ) {
$where = array();
if ( $includes ) {
$where[] = $includes;
}
if ( $excludes ) {
$where[] = $excludes;
}
$where[] = array(
'form_id' => $form_id,
'type !' => 'break',
);
return $where;
}
/**
* @param array|string $ids
*/
private static function maybe_explode( $ids ) {
return is_array( $ids ) ? $ids : explode( ',', $ids );
}
/**
* @param array $values
* @return array<int> ids
*/
private static function pull_ids( $values ) {
return array_filter( $values, 'is_numeric' );
}
/**
* @param array $values
* @return array<string> keys
*/
private static function pull_keys( $values ) {
return array_filter(
$values,
function( $value ) {
return ! is_numeric( $value );
}
);
}
public static function update_field_ajax() {
//check_ajax_referer( 'frm_ajax', 'nonce' );
$entry_id = FrmAppHelper::get_param( 'entry_id', 0, 'post', 'absint' );
$field_id = FrmAppHelper::get_param( 'field_id', 0, 'post', 'sanitize_title' );
$value = FrmAppHelper::get_param( 'value', '', 'post', 'wp_kses_post' );
FrmAppHelper::sanitize_value( 'wp_specialchars_decode', $value );
FrmField::maybe_get_field( $field_id );
if ( $field_id && FrmProEntriesHelper::user_can_edit( $entry_id, $field_id->form_id ) ) {
$updated = FrmProEntryMeta::update_single_field( compact( 'entry_id', 'field_id', 'value' ) );
echo $updated;
}
wp_die();
}
public static function redirect_url( $url ) {
$url = str_replace( array( ' ', '[', ']', '|', '@' ), array( '%20', '%5B', '%5D', '%7C', '%40' ), $url );
return $url;
}
/**
* @param stdClass $field
* @return bool
*/
public static function field_column_is_sortable( $sortable, $field ) {
if ( ! $sortable && ! empty( $field->field_options['post_field'] ) ) {
$sortable_options = array( 'post_title', 'post_content', 'post_excerpt', 'post_name', 'post_date', 'post_custom', 'post_status' );
$sortable = in_array( $field->field_options['post_field'], $sortable_options, true );
}
return $sortable;
}
/**
* @param string $sort
* @param int $field_id
* @param array $field_options
* @return string
*/
public static function handle_field_column_sort( $sort, $field_id, $field_options ) {
if ( '' !== $sort || empty( $field_options['post_field'] ) ) {
return $sort;
}
global $wpdb;
if ( 'post_custom' === $field_options['post_field'] ) {
if ( empty( $field_options['custom_field'] ) ) {
return '';
}
$meta_key = sanitize_key( $field_options['custom_field'] );
return ', (SELECT m.meta_value FROM ' . $wpdb->prefix . 'postmeta m INNER JOIN ' . $wpdb->prefix . 'frm_items i ON i.post_id=m.post_id WHERE m.meta_key = "' . esc_sql( $meta_key ) . '" AND i.id = it.id) as meta_' . $field_id;
}
$column = sanitize_key( $field_options['post_field'] );
return ', (SELECT p.' . $column . ' FROM ' . $wpdb->prefix . 'posts p INNER JOIN ' . $wpdb->prefix . 'frm_items i ON i.post_id=p.ID WHERE i.id = it.id) as meta_' . $field_id;
}
/**
* AJAX handler for deleting draft entry.
*
* @since 5.4
*/
public static function delete_draft_entry_ajax() {
check_ajax_referer( 'frm_ajax' );
$form_id = FrmAppHelper::get_post_param( 'form', 0, 'intval' );
if ( ! $form_id ) {
wp_send_json_error();
}
$user_id = get_current_user_id();
global $wpdb;
$wpdb->delete(
$wpdb->prefix . 'frm_items',
array(
'is_draft' => 1,
'form_id' => $form_id,
'user_id' => $user_id,
),
array( '%d', '%d', '%d' )
);
wp_send_json_success();
}
/**
* @since 3.0
* @deprecated 4.0
*/
public static function add_edit_link( $entry = array() ) {
_deprecated_function( __METHOD__, '4.0' );
FrmProEntriesHelper::edit_button( $entry );
}
/**
* @deprecated 4.0
*/
public static function add_sidebar_links( $entry ) {
_deprecated_function( __METHOD__, '4.0' );
}
/**
* @codeCoverageIgnore
*/
public static function admin_js() {
_deprecated_function( __METHOD__, '3.0', 'FrmProFormsController::admin_js' );
FrmProFormsController::admin_js();
}
/**
* @codeCoverageIgnore
*/
public static function add_js() {
_deprecated_function( __METHOD__, '3.0', 'FrmProFormsController::add_js' );
FrmProFormsController::add_js();
}
/**
* @codeCoverageIgnore
*/
public static function print_ajax_scripts( $keep = '' ) {
_deprecated_function( __METHOD__, '3.0', 'FrmProFormsController::print_ajax_scripts' );
FrmProFormsController::print_ajax_scripts();
}
/**
* @codeCoverageIgnore
*/
public static function after_footer_loaded() {
_deprecated_function( __METHOD__, '3.0', 'FrmProFormsController::after_footer_loaded' );
FrmProFormsController::after_footer_loaded();
}
/**
* @codeCoverageIgnore
*/
public static function enqueue_footer_js() {
_deprecated_function( __METHOD__, '3.0', 'FrmProFormsController::enqueue_footer_js' );
FrmProFormsController::enqueue_footer_js();
}
/**
* @codeCoverageIgnore
*/
public static function footer_js() {
_deprecated_function( __METHOD__, '3.0', 'FrmProFormsController::footer_js' );
FrmProFormsController::footer_js();
}
/**
* @codeCoverageIgnore
*/
public static function add_duplicate_link( $entry ) {
_deprecated_function( __METHOD__, '3.0' );
FrmProEntriesHelper::show_duplicate_link( $entry );
}
/**
* @codeCoverageIgnore
*/
public static function register_scripts() {
_deprecated_function( __METHOD__, '3.0', 'FrmProAppController::register_scripts' );
FrmProAppController::register_scripts();
}
/**
* @deprecated 2.04
* @codeCoverageIgnore
*/
public static function filter_value_in_single_entry_table( $value, $meta, $entry, $atts = array() ) {
_deprecated_function( __FUNCTION__, '2.04', 'FrmProEntriesController::get_option_label_for_saved_value');
if ( isset( $atts['field'] ) ) {
$field = $atts['field'];
} else {
$field = FrmField::getOne( $meta->field_id );
}
if ( ! $field ) {
return $value;
}
return self::get_option_label_for_saved_value( $value, $field, $atts );
}
/**
* @deprecated 4.09
*/
public static function register_widgets() {
return FrmProDisplaysController::deprecated_function( __METHOD__, 'FrmViewsDisplaysController::register_widgets' );
}
}