array(
'title' => esc_html__( 'Entry', 'gravityforms' ),
'callback' => array( 'GFEntryDetail', 'meta_box_entry_info' ),
'context' => 'side',
),
);
if ( GFCommon::current_user_can_any( 'gravityforms_edit_entry_notes' ) ) {
$meta_boxes['notifications'] = array(
'title' => esc_html__( 'Notifications', 'gravityforms' ),
'callback' => array( 'GFEntryDetail', 'meta_box_notifications' ),
'context' => 'side',
);
}
if ( GFCommon::current_user_can_any( 'gravityforms_view_entry_notes' ) ) {
$meta_boxes['notes'] = array(
'title' => esc_html__( 'Notes', 'gravityforms' ),
'callback' => array( 'GFEntryDetail', 'meta_box_notes' ),
'context' => 'normal',
);
}
if ( ! empty( $entry['payment_status'] ) ) {
$meta_boxes['payment'] = array(
'title' => $entry['transaction_type'] == 2 ? esc_html__( 'Subscription Details', 'gravityforms' ) : esc_html__( 'Payment Details', 'gravityforms' ),
'callback' => array( 'GFEntryDetail', 'meta_box_payment_details' ),
'context' => 'side',
);
}
$form = self::get_current_form();
/**
* Allow custom meta boxes to be added to the entry detail page.
*
* @since 2.0-beta-3
*
* @param array $meta_boxes The properties for the meta boxes.
* @param array $entry The entry currently being viewed/edited.
* @param array $form The form object used to process the current entry.
*/
$meta_boxes = apply_filters( 'gform_entry_detail_meta_boxes', $meta_boxes, $entry, $form );
foreach ( $meta_boxes as $id => $meta_box ) {
$screen = get_current_screen();
add_meta_box(
$id,
$meta_box['title'],
$meta_box['callback'],
$screen->id,
$meta_box['context'],
isset( $meta_box['priority'] ) ? $meta_box['priority'] : 'default',
isset( $meta_box['callback_args'] ) ? $meta_box['callback_args'] : null
);
}
}
public static function get_current_form() {
if ( isset( self::$_form ) ) {
return self::$_form;
}
$form = GFFormsModel::get_form_meta( absint( $_GET['id'] ) );
$form_id = absint( $form['id'] );
$form = apply_filters( 'gform_admin_pre_render', $form );
$form = apply_filters( 'gform_admin_pre_render_' . $form_id, $form );
self::set_current_form( $form );
return $form;
}
/**
* Caches the current form.
*
* @since 2.4.4.1
*
* @param array $form The form to be cached.
*/
public static function set_current_form( $form ) {
self::$_form = $form;
}
public static function get_current_entry() {
if ( isset( self::$_entry ) ) {
return self::$_entry;
}
$form = self::get_current_form();
$form_id = absint( $form['id'] );
$lead_id = rgpost( 'entry_id' ) ? absint( rgpost( 'entry_id' ) ) : absint( rgget( 'lid' ) );
$filter = rgget( 'filter' );
$status = in_array( $filter, array( 'trash', 'spam' ) ) ? $filter : 'active';
$position = rgget( 'pos' ) ? rgget( 'pos' ) : 0;
$sort_direction = rgget( 'order' ) ? rgget( 'order' ) : 'DESC';
$sort_field = empty( $_GET['orderby'] ) ? 0 : $_GET['orderby'];
$sort_field_meta = RGFormsModel::get_field( $form, $sort_field );
$is_numeric = rgar( $sort_field_meta, 'type' ) == 'number';
$search_criteria['status'] = $status;
require_once( 'entry_list.php' );
$filter_links = GFEntryList::get_filter_links( $form, false );
foreach ( $filter_links as $filter_link ) {
if ( $filter == $filter_link['id'] ) {
$search_criteria['field_filters'] = $filter_link['field_filters'];
break;
}
}
$search_field_id = rgget( 'field_id' );
if ( isset( $_GET['field_id'] ) && $_GET['field_id'] !== '' ) {
$key = $search_field_id;
$val = rgget( 's' );
$strpos_row_key = strpos( $search_field_id, '|' );
if ( $strpos_row_key !== false ) { //multi-row likert
$key_array = explode( '|', $search_field_id );
$key = $key_array[0];
$val = $key_array[1] . ':' . $val;
}
$search_criteria['field_filters'][] = array(
'key' => $key,
'operator' => rgempty( 'operator', $_GET ) ? 'is' : rgget( 'operator' ),
'value' => $val,
);
$type = rgget( 'type' );
if ( empty( $type ) ) {
if ( rgget( 'field_id' ) == '0' ) {
$search_criteria['type'] = 'global';
}
}
}
/**
* Allow the entry list search criteria to be overridden.
*
* @since 1.9.14.30
*
* @param array $search_criteria An array containing the search criteria.
* @param int $form_id The ID of the current form.
*/
$search_criteria = gf_apply_filters( array( 'gform_search_criteria_entry_list', $form_id ), $search_criteria, $form_id );
$paging = array( 'offset' => $position, 'page_size' => 1 );
if ( ! empty( $sort_field ) ) {
$sorting = array( 'key' => $sort_field, 'direction' => $sort_direction, 'is_numeric' => $is_numeric );
} else {
$sorting = array();
}
$leads = GFAPI::get_entries( $form['id'], $search_criteria, $sorting, $paging, self::$_total_count );
if ( ! $lead_id ) {
$lead = ! empty( $leads ) ? $leads[0] : false;
} else {
$lead = GFAPI::get_entry( $lead_id );
}
self::set_current_entry( $lead );
return $lead;
}
public static function set_current_entry( $entry ) {
self::$_entry = $entry;
}
public static function get_total_count() {
return self::$_total_count;
}
public static function lead_detail_page() {
global $current_user;
if ( ! GFCommon::ensure_wp_version() ) {
return;
}
echo GFCommon::get_remote_message();
$requested_form_id = absint( $_GET['id'] );
if ( empty( $requested_form_id ) ) {
return;
}
$lead = self::get_current_entry();
if ( is_wp_error( $lead ) || ! $lead ) {
esc_html_e( "Oops! We couldn't find your entry. Please try again", 'gravityforms' );
return;
}
$lead_id = $lead['id'];
$form = self::get_current_form();
$form_id = absint( $form['id'] );
/**
* Fires before the entry detail page is shown or any processing is handled.
*
* @param array $form The form object for the entry.
* @param array $lead The entry object.
*
* @since 2.3.3.9
*/
gf_do_action( array( 'gform_pre_entry_detail', $form['id'] ), $form, $lead );
$total_count = self::get_total_count();
$position = rgget( 'pos' ) ? rgget( 'pos' ) : 0;
$prev_pos = ! rgblank( $position ) && $position > 0 ? $position - 1 : false;
$next_pos = ! rgblank( $position ) && $position < self::$_total_count - 1 ? $position + 1 : false;
$filter = rgget( 'filter' );
// unread filter requires special handling for pagination since entries are filter out of the query as they are read
if ( $filter == 'unread' ) {
$next_pos = $position;
if ( $next_pos + 1 == $total_count ) {
$next_pos = false;
}
}
GFFormsModel::update_entry_property( $lead['id'], 'is_read', 1 );
switch ( RGForms::post( 'action' ) ) {
case 'update' :
check_admin_referer( 'gforms_save_entry', 'gforms_save_entry' );
$original_entry = $lead;
// Set files that have been uploaded to temp folder
GFFormsModel::set_uploaded_files( $form_id );
GFFormsModel::save_lead( $form, $lead );
/**
* Fires after the Entry is updated from the entry detail page.
*
* @param array $form The form object for the entry.
* @param integer $lead['id'] The entry ID.
* @param array $original_entry The entry object before being updated.
*/
gf_do_action( array( 'gform_after_update_entry', $form['id'] ), $form, $lead['id'], $original_entry );
$lead = GFFormsModel::get_entry( $lead['id'] );
$lead = GFFormsModel::set_entry_meta( $lead, $form );
self::set_current_entry( $lead );
// Check if there's consent field, and values updated.
if ( GFCommon::has_consent_field( $form ) ) {
$user_data = get_userdata( $current_user->ID );
$consent_update_note = '';
foreach ( $form['fields'] as $field ) {
if ( $field['type'] === 'consent' ) {
$field_obj = GFFormsModel::get_field( $form, $field['id'] );
$revision_id = GFFormsModel::get_latest_form_revisions_id( $form['id'] );
$current_description = $field_obj->get_field_description_from_revision( $revision_id );
$submitted_description = $field_obj->get_field_description_from_revision( $original_entry[ $field['id'] . '.3' ] );
if ( $lead[ $field['id'] . '.1' ] !== $original_entry[ $field['id'] . '.1' ] || $field['checkboxLabel'] !== $original_entry[ $field['id'] . '.2' ] || $current_description !== $submitted_description ) {
if ( ! empty( $consent_update_note ) ) {
$consent_update_note .= "\n";
}
$consent_update_note .= empty( $lead[ $field['id'] . '.1' ] ) ? sprintf( esc_html__( '%s: Unchecked "%s"', 'gravityforms' ), GFCommon::get_label( $field ), wp_strip_all_tags( $original_entry[ $field['id'] . '.2' ] ) ) : sprintf( esc_html__( '%s: Checked "%s"', 'gravityforms' ), GFCommon::get_label( $field ), wp_strip_all_tags( $lead[ $field['id'] . '.2' ] ) );
}
}
}
if ( ! empty( $consent_update_note ) ) {
GFFormsModel::add_note( $lead['id'], $current_user->ID, $user_data->display_name, $consent_update_note );
}
}
break;
case 'add_note' :
check_admin_referer( 'gforms_update_note', 'gforms_update_note' );
$user_data = get_userdata( $current_user->ID );
GFFormsModel::add_note( $lead['id'], $current_user->ID, $user_data->display_name, stripslashes( $_POST['new_note'] ) );
//emailing notes if configured
if ( rgpost( 'gentry_email_notes_to' ) ) {
GFCommon::log_debug( 'GFEntryDetail::lead_detail_page(): Preparing to email entry notes.' );
$email_to = $_POST['gentry_email_notes_to'];
$email_from = $current_user->user_email;
$email_subject = stripslashes( $_POST['gentry_email_subject'] );
$body = stripslashes( $_POST['new_note'] );
$headers = "From: \"$email_from\" <$email_from> \r\n";
GFCommon::log_debug( "GFEntryDetail::lead_detail_page(): Emailing notes - TO: $email_to SUBJECT: $email_subject BODY: $body HEADERS: $headers" );
$is_success = wp_mail( $email_to, $email_subject, $body, $headers );
$result = is_wp_error( $is_success ) ? $is_success->get_error_message() : $is_success;
GFCommon::log_debug( "GFEntryDetail::lead_detail_page(): Result from wp_mail(): {$result}" );
if ( ! is_wp_error( $is_success ) && $is_success ) {
GFCommon::log_debug( 'GFEntryDetail::lead_detail_page(): Mail was passed from WordPress to the mail server.' );
} else {
GFCommon::log_error( 'GFEntryDetail::lead_detail_page(): The mail message was passed off to WordPress for processing, but WordPress was unable to send the message.' );
}
if ( has_filter( 'phpmailer_init' ) ) {
GFCommon::log_debug( __METHOD__ . '(): The WordPress phpmailer_init hook has been detected, usually used by SMTP plugins, it can impact mail delivery.' );
}
/**
* Fires after a note is attached to an entry and sent as an email
*
* @param string $result The Error message or success message when the entry note is sent
* @param string $email_to The email address to send the entry note to
* @param string $email_from The email address from which the email is sent from
* @param string $email_subject The subject of the email that is sent
* @param mixed $body The Full body of the email containing the message after the note is sent
* @param array $form The current form object
* @param array $lead The Current lead object
*/
do_action( 'gform_post_send_entry_note', $result, $email_to, $email_from, $email_subject, $body, $form, $lead );
}
break;
case 'add_quick_note' :
check_admin_referer( 'gforms_save_entry', 'gforms_save_entry' );
$user_data = get_userdata( $current_user->ID );
GFFormsModel::add_note( $lead['id'], $current_user->ID, $user_data->display_name, stripslashes( $_POST['quick_note'] ) );
break;
case 'bulk' :
check_admin_referer( 'gforms_update_note', 'gforms_update_note' );
if ( $_POST['bulk_action'] == 'delete' ) {
if ( ! GFCommon::current_user_can_any( 'gravityforms_edit_entry_notes' ) ) {
wp_die( esc_html__( "You don't have adequate permission to delete notes.", 'gravityforms' ) );
}
GFFormsModel::delete_notes( $_POST['note'] );
}
break;
case 'trash' :
check_admin_referer( 'gforms_save_entry', 'gforms_save_entry' );
if ( ! GFCommon::current_user_can_any( 'gravityforms_delete_entries' ) ) {
wp_die( esc_html__( "You don't have adequate permission to trash entries.", 'gravityforms' ) );
}
GFFormsModel::update_entry_property( $lead['id'], 'status', 'trash' );
$admin_url = admin_url( 'admin.php?page=gf_entries&view=entries&id=' . absint( $form['id'] ) . '&trashed_entry=' . absint( $lead['id'] ) );
?>
id;
$content = $value = '';
switch ( $field->get_input_type() ) {
case 'section' :
$content = '
' . esc_html( GFCommon::get_label( $field ) ) . '
';
break;
case 'captcha':
case 'html':
case 'password':
//ignore certain fields
break;
default :
$value = RGFormsModel::get_lead_field_value( $lead, $field );
$td_id = 'field_' . $form_id . '_' . $field_id;
$td_id = esc_attr( $td_id );
if ( is_array( $field->fields ) ) {
// Ensure the top level repeater has the right nesting level so the label is not duplicated.
$field->nestingLevel = 0;
$field_label = '';
} else {
$field_label = "" . esc_html( GFCommon::get_label( $field ) ) . ' ';
}
$content = "" .
$field_label .
GFCommon::get_field_input( $field, $value, $lead['id'], $form_id, $form ) .
' ';
break;
}
/**
* Filters the field content.
*
* @since 2.1.2.14 Added form and field ID modifiers.
*
* @param string $content The field content.
* @param array $field The Field Object.
* @param string $value The field value.
* @param int $lead['id'] The entry ID.
* @param int $form['id'] The form ID.
*/
$content = gf_apply_filters( array( 'gform_field_content', $form['id'], $field->id ), $content, $field, $value, $lead['id'], $form['id'] );
echo $content;
}
?>
0 && $is_editable && GFCommon::current_user_can_any( 'gravityforms_edit_entry_notes' ) ) {
?>
';
/**
* A filter to allow you to modify the note apply button
*
* @param string $apply_button The Apply Button HTML
*/
echo apply_filters( 'gform_notes_apply_button', $apply_button );
?>
onclick="ToggleShowEmptyFields();" />
get_input_type() ) {
case 'section' :
if ( ! GFCommon::is_section_empty( $field, $form, $lead ) || $display_empty_fields ) {
$count ++;
$is_last = $count >= $field_count ? ' lastrow' : '';
$content = '
' . esc_html( GFCommon::get_label( $field ) ) . '
';
}
break;
case 'captcha':
case 'html':
case 'password':
case 'page':
// Ignore captcha, html, password, page field.
break;
default :
// Ignore product fields as they will be grouped together at the end of the grid.
if ( GFCommon::is_product_field( $field->type ) ) {
$has_product_fields = true;
break;
}
$value = RGFormsModel::get_lead_field_value( $lead, $field );
if ( is_array( $field->fields ) ) {
// Ensure the top level repeater has the right nesting level so the label is not duplicated.
$field->nestingLevel = 0;
}
$display_value = GFCommon::get_lead_field_display( $field, $value, $lead['currency'] );
/**
* Filters a field value displayed within an entry.
*
* @since 1.5
*
* @param string $display_value The value to be displayed.
* @param GF_Field $field The Field Object.
* @param array $lead The Entry Object.
* @param array $form The Form Object.
*/
$display_value = apply_filters( 'gform_entry_field_value', $display_value, $field, $lead, $form );
if ( $display_empty_fields || ! empty( $display_value ) || $display_value === '0' ) {
$count ++;
$is_last = $count >= $field_count && ! $has_product_fields ? true : false;
$last_row = $is_last ? ' lastrow' : '';
$display_value = empty( $display_value ) && $display_value !== '0' ? ' ' : $display_value;
$content = '
' . esc_html( GFCommon::get_label( $field ) ) . '
' . $display_value . '
';
}
break;
}
/**
* Filters the field content.
*
* @since 2.1.2.14 Added form and field ID modifiers.
*
* @param string $content The field content.
* @param array $field The Field Object.
* @param string $value The field value.
* @param int $lead['id'] The entry ID.
* @param int $form['id'] The form ID.
*/
$content = gf_apply_filters( array( 'gform_field_content', $form['id'], $field->id ), $content, $field, $value, $lead['id'], $form['id'] );
echo $content;
}
$products = array();
if ( $has_product_fields ) {
$products = GFCommon::get_product_fields( $form, $lead, false, true );
if ( ! empty( $products['products'] ) ) {
ob_start();
?>
$pos ), remove_query_arg( array( 'pos', 'lid' ) ) );
$href = ! rgblank( $pos ) ? 'href="' . esc_url( $url ) . '"' : '';
$class .= ' gf_entry_pagination_link';
$class .= $pos !== false ? ' gf_entry_pagination_link_active' : ' gf_entry_pagination_link_inactive';
return ' ';
}
public static function payment_details_box( $entry, $form ) {
_deprecated_function( __function__, '2.0', 'Use add_meta_box() with GFEntryDetail::meta_box_payment_details as the "callback" parameter.' );
?>