<?php
if ( ! class_exists( 'GFForms' ) ) {
	die();
}

use  Gravity_Forms\Gravity_Forms\Orders\Summaries\GF_Order_Summary;
use  Gravity_Forms\Gravity_Forms\Orders\Factories\GF_Order_Factory;

class GFEntryDetail {

	/**
	 * The current entry array.
	 *
	 * @var null|array
	 */
	private static $_entry = null;

	/**
	 * The current form object.
	 *
	 * @var null|form
	 */
	private static $_form = null;

	/**
	 * The total number of entries in the current filter sent from the entry list.
	 *
	 * @var int
	 */
	private static $_total_count = 0;

	/**
	 * Prepare meta boxes and screen options.
	 */
	public static function add_meta_boxes() {

		$entry = self::get_current_entry();
		if ( is_wp_error( $entry ) || ! $entry ) {
			return;
		}

		$meta_boxes = array(
			'submitdiv'     => 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',
			);
		}

		$meta_boxes['print'] = array(
		    'title' => esc_html__( 'Print entry', 'gravityforms' ),
            'callback' => array( 'GFEntryDetail', 'meta_box_print_entry' ),
            '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_id = absint( rgget( 'id' ) );
		if ( empty( $form_id ) ) {
			self::set_current_form( array() );

			return array();
		}

		$form = GFFormsModel::get_form_meta( $form_id );
		if ( empty( $form ) ) {
			self::set_current_form( array() );

			return array();
		}

		$form = GFCommon::gform_admin_pre_render( $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( rgar( $form, 'id' ) );

		self::set_current_entry( false );
		if ( empty( $form_id ) ) {
			return false;
		}

		$entry        = false;
		$has_entry_id = false;
		if ( isset( $_POST['entry_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
			$has_entry_id = true;
			$entry_id     = absint( $_POST['entry_id'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
		} elseif ( isset( $_GET['lid'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			$has_entry_id = true;
			$entry_id     = absint( $_GET['lid'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		}

		if ( $has_entry_id ) {
			if ( empty( $entry_id ) ) {
				return false;
			}

			$entry = GFAPI::get_entry( $entry_id );
			if ( is_wp_error( $entry ) ) {
				return $entry;
			}

			$entry_form_id = absint( rgar( $entry, 'form_id' ) );
			if ( $entry_form_id !== $form_id ) {
				if ( wp_safe_redirect( add_query_arg( array(
					'id'       => $entry_form_id,
					'lid'      => $entry_id,
					'order'    => false,
					'filter'   => false,
					'paged'    => false,
					'pos'      => false,
					'field_id' => false,
					'operator' => false,
				) ) ) ) {
					exit;
				}
			}
		}

		$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 : sanitize_text_field( wp_unslash( $_GET['orderby'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$sort_field_meta = GFFormsModel::get_field( $form, $sort_field );
		$is_numeric      = $sort_field_meta && $sort_field_meta->get_input_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'] !== '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			$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' ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended
				'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();
		}

		if ( empty( $entry ) ) {
			$entries = GFAPI::get_entries( $form_id, $search_criteria, $sorting, $paging, self::$_total_count );
			$entry   = rgar( $entries, 0, false );
		} else {
			self::$_total_count = GFAPI::count_entries( $form_id, $search_criteria );
		}

		self::set_current_entry( $entry );

		return $entry;
	}

	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;
		}

		$form    = self::get_current_form();
		$form_id = absint( rgar( $form, 'id' ) );
		if ( empty( $form_id ) ) {
			GFCommon::add_error_message( esc_html__( "Oops! We couldn't find your form. Please try again.", 'gravityforms' ) );
			GFForms::admin_header();

			return;
		}

		$lead = self::get_current_entry();
		if ( is_wp_error( $lead ) || ! $lead ) {
			GFCommon::add_error_message( esc_html__( "Oops! We couldn't find your entry. Please try again.", 'gravityforms' ) );
			GFForms::admin_header();

			return;
		}

		$mode = rgpost( 'screen_mode' );
		if ( empty( $mode ) ) {
			$mode = rgget( 'screen_mode' ) === 'edit' ? 'edit' : 'view';
		} else {
			$mode = sanitize_key( $mode );
		}

		if ( $mode === 'edit' && ! GFCommon::current_user_can_any( 'gravityforms_edit_entries' ) ) {
			GFCommon::add_error_message( esc_html__( "You don't have adequate permission to edit entries.", 'gravityforms' ) );
			$mode = 'view';
		}

		GFForms::admin_header();

		$lead_id = rgar( $lead, '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;

				// Some field types won't access their submitted values if this is not set.
				$_POST[ 'is_submit_' . $form_id ] = '1';

				// 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, isset( $_POST['new_note'] ) ? wp_unslash( $_POST['new_note'] ) : '' ); //  phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

				//emailing notes if configured
				if ( rgpost( 'gentry_email_notes_to' ) ) {
					GFCommon::log_debug( 'GFEntryDetail::lead_detail_page(): Preparing to email entry notes.' );
					$email_to      = isset( $_POST['gentry_email_notes_to'] ) ? sanitize_email( wp_unslash( $_POST['gentry_email_notes_to'] ) ) : '';
					$email_from    = $current_user->user_email;
					$email_subject = isset( $_POST['gentry_email_subject'] ) ? sanitize_text_field( wp_unslash( $_POST['gentry_email_subject'] ) ) : '';
					$body          = isset( $_POST['new_note'] ) ? wp_unslash( $_POST['new_note'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

					$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, isset( $_POST['quick_note'] ) ? wp_unslash( $_POST['quick_note'] ) : '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
				break;

			case 'bulk' :
				check_admin_referer( 'gforms_update_note', 'gforms_update_note' );
				if ( rgpost( '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( rgpost( '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'] ) );
				?>
				<script type="text/javascript">
					document.location.href = <?php echo json_encode( $admin_url ); ?>;
				</script>
				<?php
				break;

			case 'restore' :
				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 restore entries.", 'gravityforms' ) );
				}
				GFFormsModel::update_entry_property( $lead['id'], 'status', 'active' );
				$lead = RGFormsModel::get_lead( $lead['id'] );
				self::set_current_entry( $lead );
				break;

			case 'unspam' :
				check_admin_referer( 'gforms_save_entry', 'gforms_save_entry' );
				GFFormsModel::update_entry_property( $lead['id'], 'status', 'active' );
				$lead = GFFormsModel::get_entry( $lead['id'] );
				self::set_current_entry( $lead );
				break;

			case 'spam' :
				check_admin_referer( 'gforms_save_entry', 'gforms_save_entry' );
				GFFormsModel::update_entry_property( $lead['id'], 'status', 'spam' );
				$lead = GFFormsModel::get_entry( $lead['id'] );
				self::set_current_entry( $lead );
				break;

			case 'delete' :
				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 delete entries.", 'gravityforms' ) );
				}
				GFFormsModel::delete_entry( $lead['id'] );
				$admin_url = admin_url( 'admin.php?page=gf_entries&view=entries&id=' . absint( $form['id'] ) . '&deleted=' . absint( $lead['id'] ) );
				?>
				<script type="text/javascript">
					document.location.href = <?php echo json_encode( $admin_url ); ?>;
				</script>
				<?php
				break;
		} // End switch().

		$screen = get_current_screen();

		?>
		<script type="text/javascript">
			var formId = <?php echo absint( $form_id ); ?>;

			jQuery(document).ready(function () {
				toggleNotificationOverride(true);
				jQuery('#gform_update_button').prop('disabled', false);
				if(typeof postboxes != 'undefined'){
					jQuery('.if-js-closed').removeClass('if-js-closed').addClass('closed');
					postboxes.add_postbox_toggles( <?php echo json_encode( $screen->id ); ?>);
				}
			});

			function DeleteFile(leadId, fieldId, deleteButton) {
				if (confirm(<?php echo json_encode( __( "Would you like to delete this file? 'Cancel' to stop. 'OK' to delete", 'gravityforms' ) ); ?>)) {
					var fileIndex = jQuery(deleteButton).parent().index();
					var mysack = new sack("<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>");
					mysack.execute = 1;
					mysack.method = 'POST';
					mysack.setVar("action", "rg_delete_file");
					mysack.setVar("rg_delete_file", "<?php echo esc_js( wp_create_nonce( 'rg_delete_file' ) ); ?>");
					mysack.setVar("lead_id", leadId);
					mysack.setVar("field_id", fieldId);
					mysack.setVar("file_index", fileIndex);
					mysack.onError = function () {
						alert(<?php echo json_encode( __( 'Ajax error while deleting field.', 'gravityforms' ) ); ?>)
					};
					mysack.runAJAX();

					return true;
				}
			}

			function EndDeleteFile(fieldId, fileIndex) {
				var previewFileSelector = "#preview_existing_files_" + fieldId + " .ginput_preview";
				var $previewFiles = jQuery(previewFileSelector);
				var rr = $previewFiles.eq(fileIndex);
				$previewFiles.eq(fileIndex).remove();
				var $visiblePreviewFields = jQuery(previewFileSelector);
				if ($visiblePreviewFields.length == 0) {
					jQuery('#preview_' + fieldId).hide();
					jQuery('#upload_' + fieldId).show('slow');
				}

				var $multiFileContainer = jQuery( '#gform_multifile_upload_' + formId + '_' + fieldId );
				if ( ! $multiFileContainer.hasClass( 'gform_fileupload_multifile' ) ) {
					return;
				}

				var $input = jQuery( 'input[name="input_' + fieldId + '"]' );
				var rawFiles  = JSON.parse( $input.val() );
				var files = rawFiles.filter( function( url ) { return url !== null; } );

				// remove file from array
				if ( fileIndex > -1 ) {
					files.splice( fileIndex, 1 );
				}

				$input.val( jQuery.toJSON( files ) );

			}

			function ToggleShowEmptyFields() {
				if (jQuery("#gentry_display_empty_fields").is(":checked")) {
					createCookie("gf_display_empty_fields", true, 10000);
					document.location = document.location.href;
				}
				else {
					eraseCookie("gf_display_empty_fields");
					document.location = document.location.href;
				}
			}

			function createCookie(name, value, days) {
				if (days) {
					var date = new Date();
					date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
					var expires = "; expires=" + date.toGMTString();
				}
				else var expires = "";
				document.cookie = name + "=" + value + expires + "; path=/";
			}

			function eraseCookie(name) {
				createCookie(name, "", -1);
			}

			function ResendNotifications() {
				var selectedNotifications = new Array();
				jQuery(".gform_notifications:checked").each(function () {
					selectedNotifications.push(jQuery(this).val());
				});

				var sendTo = jQuery('#notification_override_email').val();

				if (selectedNotifications.length <= 0) {
					displayMessage(<?php echo json_encode( __( 'You must select at least one type of notification to resend.', 'gravityforms' ) ); ?>, 'error', '#notifications');
					return;
				}

				jQuery('#please_wait_container').fadeIn();

				jQuery.post(ajaxurl, {
						action                 : "gf_resend_notifications",
						gf_resend_notifications: '<?php echo esc_js( wp_create_nonce( 'gf_resend_notifications' ) ); ?>',
						notifications          : jQuery.toJSON(selectedNotifications),
						sendTo                 : sendTo,
						leadIds                : '<?php echo absint( $lead['id'] ); ?>',
						formId                 : '<?php echo absint( $form['id'] ); ?>'
					},
					function (response) {
						response = response.trim();
						if (response) {
							displayMessage(response, "error", "#notifications");
						} else {
							displayMessage(<?php echo json_encode( esc_html__( 'Notifications were resent successfully.', 'gravityforms' ) ); ?>, "success", "#notifications" );

							// reset UI
							jQuery(".gform_notifications").attr( 'checked', false );
							jQuery('#notification_override_email').val('');

							toggleNotificationOverride();

						}

						jQuery('#please_wait_container').hide();
						setTimeout(function () {
							jQuery('#notifications_container').find('.message').slideUp();
						}, 5000);
					}
				);

			}

			function displayMessage( message, messageClass, container ) {
				jQuery( container ).find( '.message' ).hide().html( message ).attr( 'class', 'message alert ' + messageClass ).slideDown();
			}

			function toggleNotificationOverride(isInit) {

				if (isInit)
					jQuery('#notification_override_email').val('');

				if (jQuery(".gform_notifications:checked").length > 0) {
					jQuery('#notifications_override_settings').slideDown();
				}
				else {
					jQuery('#notifications_override_settings').slideUp(function () {
						jQuery('#notification_override_email').val('');
					});
				}
			}

		</script>
		<?php

		if ( rgpost( 'action' ) == 'update' ) {
			?>
            <div class="alert success">
                <p><?php esc_html_e( 'Entry Updated.', 'gravityforms' ); ?></p>
            </div>
			<?php
		}

		?>
		<form method="post" id="entry_form" enctype='multipart/form-data' action="<?php echo esc_url( remove_query_arg( 'screen_mode' ) ) ?>">
			<?php wp_nonce_field( 'gforms_save_entry', 'gforms_save_entry' ) ?>
			<input type="hidden" name="action" id="action" value="" />
			<input type="hidden" name="screen_mode" id="screen_mode" value="<?php echo esc_attr( $mode ) ?>" />

			<input type="hidden" name="entry_id" id="entry_id" value="<?php echo absint( $lead['id'] ) ?>" />

			<div class="wrap gf_entry_wrap">

					<?php
					$gf_entry_locking = new GFEntryLocking();
					$gf_entry_locking->lock_info( $lead_id ); ?>


				<?php if ( isset( $_GET['pos'] ) ) { ?>
				<div class="gf_entry_detail_pagination">
					<div class="gf_entry_count">
						<?php esc_html_e('Entry', 'gravityforms' );?>&nbsp;<strong><?php echo esc_html( $position + 1 ); ?></strong> of <strong><?php echo esc_html( $total_count ); ?></strong>
					</div>
					<div class="gf_entry_prev gf_entry_pagination"><?php echo GFEntryDetail::entry_detail_pagination_link( $prev_pos, 'Previous Entry', 'gf_entry_prev_link', 'dashicons-arrow-left-alt' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
					<div class="gf_entry_next gf_entry_pagination"><?php echo GFEntryDetail::entry_detail_pagination_link( $next_pos, 'Next Entry', 'gf_entry_next_link', 'dashicons-arrow-right-alt' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></div>
				</div>
				<?php } ?>
				<div id="poststuff">
					<?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
					<?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>


					<div id="post-body" class="metabox-holder columns-2 gform-settings-panel__content">
						<div id="post-body-content" >
							<?php
							/**
							 * Fires before the entry detail content is displayed
							 *
							 * @param array $form The Form object
							 * @param array $lead The Entry object
							 */
							do_action( 'gform_entry_detail_content_before', $form, $lead );

							if ( 'edit' === $mode && GFCommon::current_user_can_any( 'gravityforms_edit_entries' ) ) {
								self::lead_detail_edit( $form, $lead );
							} else {
								self::lead_detail_grid( $form, $lead, true );
							}

							/**
							 * Fires when entry details are displayed
							 *
							 * @param array $form The Form object
							 * @param array $lead The Entry object
							 */
							do_action( 'gform_entry_detail', $form, $lead );
							?>
						</div>

						<div id="postbox-container-1" class="postbox-container">

							<?php
							/**
							 * Fires before the entry detail sidebar is generated
							 *
							 * @param array $form The Form object
							 * @param array $lead The Entry object
							 */
							do_action( 'gform_entry_detail_sidebar_before', $form, $lead );
							?>
							<?php


							do_meta_boxes( $screen->id, 'side', array( 'form' => $form, 'entry' => $lead, 'mode' => $mode ) ); ?>

							<?php
							/**
							 * Inserts information into the middle of the entry detail sidebar
							 *
							 * @param array $form The Form object
							 * @param array $lead The Entry object
							 */
							do_action( 'gform_entry_detail_sidebar_middle', $form, $lead );

							/**
							 * Fires after the entry detail sidebar information.
							 *
							 * @param array $form The Form object
							 * @param array $lead The Entry object
							 */
							do_action( 'gform_entry_detail_sidebar_after', $form, $lead );
							?>
						</div>

						<div id="postbox-container-2" class="postbox-container">
							<?php do_meta_boxes( $screen->id, 'normal', array( 'form' => $form, 'entry' => $lead, 'mode' => $mode ) ); ?>
							<?php

							/**
							 * Fires after the entry detail content is displayed
							 *
							 * @param array $form The Form object
							 * @param array $lead The Entry object
							 */
							do_action( 'gform_entry_detail_content_after', $form, $lead );
							?>
						</div>
					</div>
				</div>
			</div>
		</form>
		<?php
	}

	public static function lead_detail_edit( $form, $lead ) {
		$form_id = absint( $form['id'] );

		if ( empty( $form_id ) ) {
			return;
		}
		?>
		<div class="postbox">
			<h3>
				<label for="name"><?php esc_html_e( 'Details', 'gravityforms' ); ?></label>
			</h3>

			<div class="inside gform_wrapper gravity-theme gform_wrapper_edit_form_entry">
				<table class="form-table entry-details">
					<tbody>
					<?php
					foreach ( $form['fields'] as $field ) {
						$field_id = $field->id;
						$content = $value = '';

						switch ( $field->get_input_type() ) {
							case 'section' :

								$content = '
								<tr valign="top">
									<td class="detail-view">
										<div style="margin-bottom:10px; border-bottom:1px dotted #ccc;">
											<h2 class="detail_gsection_title">' . esc_html( GFCommon::get_label( $field ) ) . '</h2>
										</div>
									</td>
								</tr>';

								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 = "<label class='detail-label'>" . esc_html( GFCommon::get_label( $field ) ) . '</label>';
								}

								$content = "<tr valign='top'><td class='detail-view' id='{$td_id}'>" .
								           $field_label .
								           GFCommon::get_field_input( $field, $value, $lead['id'], $form_id, $form ) .
								           '</td></tr>';

								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; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
					}
					?>
					</tbody>
				</table>
				<br />

				<div class="gform_footer">
					<input type="hidden" name="gform_unique_id" value="" />
					<input type="hidden" name="gform_uploaded_files" id='gform_uploaded_files_<?php echo absint( $form_id ); ?>' value="" />
				</div>
			</div>
		</div>
		<?php
	}

	public static function notes_grid( $notes, $is_editable, $emails = null, $subject = '' ) {
		if ( sizeof( $notes ) > 0 && $is_editable && GFCommon::current_user_can_any( 'gravityforms_edit_entry_notes' ) ) {
			?>
			<div class="actions" style="padding:3px 0;">
				<label class="hidden" for="bulk_action"><?php esc_html_e( ' Bulk action', 'gravityforms' ) ?></label>
				<select name="bulk_action" id="bulk_action">
					<option value=''><?php esc_html_e( ' Bulk action ', 'gravityforms' ) ?></option>
					<option value='delete'><?php esc_html_e( 'Delete', 'gravityforms' ) ?></option>
				</select>
				<?php
				$apply_button = '<input type="submit" class="button" value="' . esc_attr__( 'Apply', 'gravityforms' ) . '" onclick="jQuery(\'#action\').val(\'bulk\');" />';
				/**
				 * 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 ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				?>
			</div>
			<?php
		}
		?>

        <div class="entry-notes">
			<?php
			$count = 0;
			$notes_count = sizeof( $notes );
			if ( $notes_count > 0 ) {
				echo '<h3 class="entry-notes-print-header">' . esc_html__( 'Notes', 'gravityforms' ) . '</h3>';
			}
	        foreach ( $notes as $note ) {
		        $count ++;
		        $is_last = $count >= $notes_count ? true : false;

		        // Prepare note classes.
		        $classes = array();

		        // Add base note class.
		        if ( $note->note_type ) {
			        $classes[] = sprintf( 'gforms_note_%s', $note->note_type );
		        }

		        // Add sub type note class.
		        if ( rgobj( $note, 'sub_type' ) ) {
			        $classes[] = sprintf( 'alert gforms_note_%s', $note->sub_type );
		        }

		        // Escape note classes.
		        $classes = array_map( 'esc_attr', $classes );

		        ?>
	            <div class="note" data-id="<?php echo esc_attr( $note->id ); ?>" data-type="<?php echo esc_attr( $note->note_type ); ?>"<?php echo rgobj( $note, 'sub_type' ) ? ' data-sub-type="' . esc_attr( $note->sub_type ) . '"' : ''; ?>>
                    <div class="note-details">
	                    <?php if ( $is_editable && GFCommon::current_user_can_any( 'gravityforms_edit_entry_notes' ) ) { ?>
                        <div class="note-check" >
                            <input type="checkbox" value="<?php echo esc_attr( $note->id ); ?>" name="note[]" />
                        </div>
	                    <?php } ?>

                        <div class="author<?php echo $is_last ? ' lastrow' : '' ?>">
                            <div class="avatar">
                                <?php

                                if ( $note->user_id ) {
                                    $avatar = get_avatar( $note->user_id, 48 );
                                } else {
                                    $avatar = '<svg width="37" height="39" alt="' . esc_attr( $note->user_name ) . '" viewBox="0 0 43 47" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M42.8148 31.7793C42.8148 33.9193 41.2892 36.5422 39.421 37.6067L24.7956 45.9912C22.9274 47.0557 19.8763 47.0557 18.0081 45.9912L3.38273 37.6067C1.52555 36.5422 0 33.9193 0 31.7793V15.0103C0 12.8703 1.52555 10.2474 3.39379 9.18288L18.0081 0.798392C19.8763 -0.266131 22.9274 -0.266131 24.7956 0.798392L39.421 9.18288C41.2892 10.2474 42.8148 12.8703 42.8148 15.0103V31.7793Z" fill="#F15A29"/>
<path d="M17.2449 19.51H36.6238V14.0996H17.3002C14.5365 14.0996 12.2372 15.0434 10.4905 16.8981C6.26765 21.3537 6.1571 32.5916 6.1571 32.5916H36.4911V22.4292H31.0412V27.1812H11.9608C12.0824 25.4143 12.9005 22.2427 14.4481 20.6075C15.1556 19.8612 16.051 19.51 17.2449 19.51Z" fill="white"/></svg>';
                                }

                                /**
                                 * Allows filtering of the notes avatar
                                 *
                                 * @param array $note The Note object that is being filtered when modifying the avatar
                                 */
                                echo apply_filters( 'gform_notes_avatar', $avatar, $note );  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 
								?>
                            </div>
                            <div class="text">
                                <h6><?php echo esc_html( $note->user_name ) ?>&nbsp;<?php if ( $note->user_email ): ?><?php echo esc_html( $note->user_email ) ?><?php endif; ?></h6>
                                <time><?php esc_html_e( 'added', 'gravityforms' ); ?> <?php echo esc_html( GFCommon::format_date( $note->date_created, true ) ) ?></time>
                            </div>
                        </div>

                    </div>

                    <div class="note-content <?php echo esc_attr( implode( ' ', $classes ) ); ?>"><?php echo nl2br( wp_kses_post( $note->value ) ) ?></div>

                </div>
		        <?php
	        }
	        if ( $is_editable && GFCommon::current_user_can_any( 'gravityforms_edit_entry_notes' ) ) {
		        ?>
                <div class="add-note">
                    <textarea name="new_note" ></textarea>
                    <div class="add-note-actions">
	                    <?php
	                    $note_button = '<input type="submit" name="add_note" value="' . esc_attr__( 'Add Note', 'gravityforms' ) . '" class="button" onclick="jQuery(\'#action\').val(\'add_note\');"/>';

	                    /**
	                     * Allows for modification of the "Add Note" button for Entry Notes
	                     *
	                     * @param string $note_button The HTML for the "Add Note" Button
	                     */
	                    echo apply_filters( 'gform_addnote_button', $note_button );  // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

	                    if ( ! empty( $emails ) ) {
		                    ?>
                            &nbsp;&nbsp;
                            <span class="send-to">
                            <select name="gentry_email_notes_to" onchange="if(jQuery(this).val() != '') {jQuery('#gentry_email_subject_container').css('display', 'inline');} else{jQuery('#gentry_email_subject_container').css('display', 'none');}">
                                <option value=""><?php esc_html_e( 'Also email this note to', 'gravityforms' ) ?></option>
                                <?php foreach ( $emails as $email ) { ?>
                                    <option value="<?php echo esc_attr( $email ); ?>"><?php echo esc_html( $email ); ?></option>
                                <?php } ?>
                            </select>
                            &nbsp;&nbsp;

                            <span id='gentry_email_subject_container' style="display:none;">
                                <label for="gentry_email_subject"><?php esc_html_e( 'Subject:', 'gravityforms' ) ?></label>
                                <input type="text" name="gentry_email_subject" id="gentry_email_subject" value="" style="width:70%" />
                            </span>
                        </span>
	                    <?php } ?>
                    </div>
                </div>
		        <?php
	        }
	        ?>
        </div>
		<?php
	}

	public static function lead_detail_grid( $form, $lead, $allow_display_empty_fields = false ) {
		$form_id = absint( $form['id'] );

		if ( empty( $form_id ) ) {
			return;
		}

		$display_empty_fields = self::maybe_display_empty_fields( $allow_display_empty_fields, $form, $lead );


		?>
		<table cellspacing="0" class="entry-details-table ">
			<thead>
			<tr>
				<th id="details">
					<?php
					$title = sprintf( '%s : %s %s', esc_html( $form['title'] ), esc_html__( 'Entry # ', 'gravityforms' ), absint( $lead['id'] ) );
					/**
					 * Filters the title displayed on the entry detail page.
					 *
					 * @since 1.9
					 *
					 * @param string $title The title used.
					 * @param array  $form  The Form Object.
					 * @param array  $entry The Entry Object.
					 */
					echo apply_filters( 'gform_entry_detail_title', $title, $form, $lead ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
					?>
				</th>
				<th style="width:auto; font-size:10px; text-align: right;">
					<?php
					if ( $allow_display_empty_fields ) {
						?>
						<input type="checkbox" id="gentry_display_empty_fields" <?php echo $display_empty_fields ? "checked='checked'" : '' ?> onclick="ToggleShowEmptyFields();" />
						<label for="gentry_display_empty_fields"><?php esc_html_e( 'show empty fields', 'gravityforms' ) ?></label>
						<?php
					}
					?>
				</th>
			</tr>
			</thead>
			<tbody>
			<?php
			$count = 0;
			$field_count = sizeof( $form['fields'] );
			$has_product_fields = false;
			foreach ( $form['fields'] as $field ) {

				$content = $value = '';

				switch ( $field->get_input_type() ) {
					case 'section' :
						if ( ! GFCommon::is_section_empty( $field, $form, $lead ) || $display_empty_fields ) {
							$count ++;
							$is_last = $count >= $field_count ? ' lastrow' : '';

							$content = '
                                <tr>
                                    <td colspan="2" class="entry-view-section-break' . $is_last . '">' . esc_html( GFCommon::get_label( $field ) ) . '</td>
                                </tr>';
						}
						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 = $field->get_value_entry_detail( $value, $lead, false, 'html', 'screen' );

						/**
						 * 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' ? '&nbsp;' : $display_value;

							$content = '
                                <tr>
                                    <td colspan="2" class="entry-view-field-name">' . esc_html( GFCommon::get_label( $field ) ) . '</td>
                                </tr>
                                <tr>
                                    <td colspan="2" class="entry-view-field-value' . $last_row . '">' . $display_value . '</td>
                                </tr>';
						}
						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; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			}

			$products = array();
			if ( $has_product_fields ) {
				$products             = GFCommon::get_product_fields( $form, $lead, false, true );
				$order_summary_markup = GF_Order_Summary::render( $form, $lead, 'order-summary', false, true );
				if ( $order_summary_markup ) {
					/**
					 * Filter the markup of the order summary which appears on the Entry Detail, the {all_fields} merge tag and the {pricing_fields} merge tag.
					 *
					 * @since 2.1.2.5
					 * @see   https://docs.gravityforms.com/gform_order_summary/
					 *
					 * @var string $markup          The order summary markup.
					 * @var array  $form            Current form object.
					 * @var array  $lead            Current entry object.
					 * @var array  $products        Current order summary object.
					 * @var string $format          Format that should be used to display the summary ('html' or 'text').
					 */
					$order_summary_markup = gf_apply_filters( array( 'gform_order_summary', $form['id'] ), trim( $order_summary_markup ), $form, $lead, $products, 'html' );

					echo $order_summary_markup; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				}
			}
			?>
			</tbody>
		</table>
		<?php
	}

	public static function entry_detail_pagination_link( $pos, $label = '', $class = '', $icon = '' ) {
		$url = add_query_arg( array( 'pos' => $pos ), remove_query_arg( array( 'pos', 'lid', 'screen_mode' ) ) );

		$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 '<a ' . $href . ' class="' . $class . '" aria-label="' . esc_attr( $label ) . '"><i aria-hidden="true" class="dashicons ' . esc_attr( $icon ) . '" title="' . esc_attr( $label ) . '"></i></a>';
	}

	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.' );
		?>
		<!-- PAYMENT BOX -->
		<div id="submitdiv" class="stuffbox">

			<h3 class="hndle" style="cursor:default;">
				<span><?php echo $entry['transaction_type'] == 2 ? esc_html__( 'Subscription Details', 'gravityforms' ) : esc_html__( 'Payment Details', 'gravityforms' ); ?></span>
			</h3>

			<div class="inside">
				<?php self::meta_box_payment_details( compact( 'entry', 'form' ) ); ?>
			</div>

		</div>
		<?php
	}

	public static function meta_box_payment_details( $args ) {

		$entry = $args['entry'];
		$form  = $args['form'];

		?>

		<div id="submitcomment" class="submitbox">
			<div id="minor-publishing">
				<?php

				$payment_status = apply_filters( 'gform_payment_status', GFCommon::get_entry_payment_status_text( $entry['payment_status'] ), $form, $entry );
				if ( ! empty( $payment_status ) ) {
					?>
					<div id="gf_payment_status" class="gf_payment_detail">
						<?php esc_html_e( 'Status', 'gravityforms' ) ?>:
						<span id="gform_payment_status"><?php echo $payment_status; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- May contain HTML ?></span>
					</div>

					<?php

					/**
					 * Allows for modification on the form payment date format
					 *
					 * @param array $form The Form object to filter through
					 * @param array $entry The Lead object to filter through
					 */
					$payment_date = apply_filters( 'gform_payment_date', GFCommon::format_date( $entry['payment_date'], false, 'Y/m/d', $entry['transaction_type'] != 2 ), $form, $entry );
					if ( ! empty( $payment_date ) ) {
						?>
						<div id="gf_payment_date" class="gf_payment_detail">
							<?php echo $entry['transaction_type'] == 2 ? esc_html__( 'Start Date', 'gravityforms' ) : esc_html__( 'Date', 'gravityforms' ) ?>:
							<span id='gform_payment_date'><?php echo $payment_date; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- May contain HTML ?></span>
						</div>
						<?php
					}

					/**
					 * Allows filtering through a payment transaction ID
					 *
					 * @param int   $entry['transaction_id'] The transaction ID that can be modified
					 * @param array $form                   The Form object to be filtered when modifying the transaction ID
					 * @param array $entry                   The Lead object to be filtered when modifying the transaction ID
					 */
					$transaction_id = apply_filters( 'gform_payment_transaction_id', $entry['transaction_id'], $form, $entry );
					if ( ! empty( $transaction_id ) ) {
						?>
						<div id="gf_payment_transaction_id" class="gf_payment_detail">
							<?php echo $entry['transaction_type'] == 2 ? esc_html__( 'Subscription Id', 'gravityforms' ) : esc_html__( 'Transaction Id', 'gravityforms' ); ?>:
							<span id='gform_payment_transaction_id'><?php echo $transaction_id; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- May contain HTML ?></span>
						</div>
						<?php
					}

					/**
					 * Filter through the way the Payment Amount is rendered
					 *
					 * @param string $entry['payment_amount'] The payment amount taken from the lead object
					 * @param string $entry['currency']       The payment currency taken from the lead object
					 * @param array  $form                   The Form object to filter through
					 * @param array  $entry                   The lead object to filter through
					 */
					$payment_amount = apply_filters( 'gform_payment_amount', GFCommon::to_money( $entry['payment_amount'], $entry['currency'] ), $form, $entry );
					if ( ! rgblank( $payment_amount ) ) {
						?>
						<div id="gf_payment_amount" class="gf_payment_detail">
							<?php echo $entry['transaction_type'] == 2 ? esc_html__( 'Recurring Amount', 'gravityforms' ) : esc_html__( 'Amount', 'gravityforms' ); ?>:
							<span id='gform_payment_amount'><?php echo $payment_amount; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- May contain HTML ?></span>
						</div>
						<?php
					}



					$order      = GF_Order_Factory::create_from_entry( $form, $entry );
					$trial_item = $order->get_item_by_property( 'is_trial', true );
					if ( $trial_item && $trial_item->description ) {
						/**
						 * Filter through the way the trial description is rendered.
						 *
						 * @param string $trial_description The trial description.
						 * @param array  $form              The Form object to filter through
						 * @param array  $entry             The lead object to filter through
						 */
						$trial_description = apply_filters( 'gform_subscription_details_trial_description', $trial_item->description, $form, $entry );
						if ( ! rgblank( $trial_description ) ) {
							?>
							<div id="gf_trial_description" class="gf_payment_detail">
								<?php echo esc_html( $trial_description ); ?>
							</div>
							<?php
						}
					}
				}

				/**
				 * Fires after the Form Payment Details (The type of payment, the cost, the ID, etc)
				 *
				 * @param int   $form['id'] The current Form ID
				 * @param array $entry       The current Lead object
				 */
				do_action( 'gform_payment_details', $form['id'], $entry );

				?>
			</div>
		</div>

		<?php
	}

	/**
	 * Display the button to print an entry.
	 *
	 * @since 2.5
	 *
	 * @param array $args
	 */
	public static function meta_box_print_entry( $args ) {

		$lead = $args['entry'];
		$form = $args['form'];

		?>
		<!-- begin print button -->
		<div class="detail-view-print">
			<?php if ( GFCommon::current_user_can_any( 'gravityforms_view_entry_notes' ) ) { ?>

				<input type="checkbox" name="print_notes" value="print_notes" checked="checked" id="gform_print_notes" />
				<label for="print_notes"><?php esc_html_e( 'Include Notes', 'gravityforms' ); ?></label>

			<?php } ?>
			<br><br>
			<a href="javascript:;" onclick="var notes_qs = jQuery('#gform_print_notes').is(':checked') ? '&notes=1' : ''; var url='<?php echo esc_url( trailingslashit( site_url() ) ); ?>?gf_page=print-entry&fid=<?php echo absint( $form['id'] ); ?>&lid=<?php echo absint( $lead['id'] ); ?>' + notes_qs; window.open (url,'printwindow');" class="button"><?php esc_html_e( 'Print', 'gravityforms' ); ?></a>
		</div>
		<!-- end print button -->
		<?php
	}

	public static function meta_box_notes( $args, $metabox ) {
		$entry = $args['entry'];
		$form  = $args['form'];
		?>
		<form method="post">
			<?php wp_nonce_field( 'gforms_update_note', 'gforms_update_note' ) ?>
				<?php
				$notes = RGFormsModel::get_lead_notes( $entry['id'] );

				//getting email values
				$email_fields = GFCommon::get_email_fields( $form );
				$emails = array();

				foreach ( $email_fields as $email_field ) {
					if ( ! empty( $entry[ $email_field->id ] ) ) {
						$emails[] = $entry[ $email_field->id ];
					}
				}
				//displaying notes grid
				$subject = '';
				self::notes_grid( $notes, true, $emails, $subject );
				?>
		</form>
		<?php
	}

	public static function meta_box_entry_info( $args, $metabox ) {
		$form  = $args['form'];
		$entry = $args['entry'];
		$mode  = $args['mode'];
		?>
		<div id="submitcomment" class="submitbox">
			<div id="minor-publishing">
				<?php esc_html_e( 'Entry Id', 'gravityforms' ); ?>: <?php echo absint( $entry['id'] ) ?><br /><br />
				<?php esc_html_e( 'Submitted on', 'gravityforms' ); ?>: <?php echo esc_html( GFCommon::format_date( $entry['date_created'], false, 'Y/m/d' ) ) ?>
				<br /><br />
				<?php
				if ( ! empty( $entry['date_updated'] ) && $entry['date_updated'] != $entry['date_created'] ) {
					esc_html_e( 'Updated', 'gravityforms' ); ?>: <?php echo esc_html( GFCommon::format_date( $entry['date_updated'], false, 'Y/m/d' ) );
					echo '<br /><br />';
				}

				if ( ! empty( $entry['ip'] ) ) {
					esc_html_e( 'User IP', 'gravityforms' ); ?>: <?php echo esc_html( $entry['ip'] );
					echo '<br /><br />';
				}

				if ( ! empty( $entry['created_by'] ) && $usermeta = get_userdata( $entry['created_by'] ) ) {
					?>
					<?php esc_html_e( 'User', 'gravityforms' ); ?>:
					<a href="user-edit.php?user_id=<?php echo absint( $entry['created_by'] ) ?>"><?php echo esc_html( $usermeta->user_login ) ?></a>
					<br /><br />
					<?php
				}

				esc_html_e( 'Embed Url', 'gravityforms' ); ?>:
				<a href="<?php echo esc_url( $entry['source_url'] ) ?>" target="_blank">.../<?php echo esc_html( GFCommon::truncate_url( $entry['source_url'] ) ) ?><span class="screen-reader-text"><?php echo esc_html__('(opens in a new tab)', 'gravityforms'); ?></span>&nbsp;<span class="gform-icon gform-icon--external-link" aria-hidden="true"></span></a>
				<br /><br />
				<?php
				if ( ! empty( $entry['post_id'] ) ) {
					$post = get_post( $entry['post_id'] );
					?>
					<?php esc_html_e( 'Edit Post', 'gravityforms' ); ?>:
					<a href="post.php?action=edit&post=<?php echo absint( $post->ID ) ?>"><?php echo esc_html( $post->post_title ) ?></a>
					<br /><br />
					<?php
				}

				/**
				 * Adds additional information to the entry details
				 *
				 * @param int   $form['id'] The form ID
				 * @param array $lead       The Entry object
				 */
				do_action( 'gform_entry_info', $form['id'], $entry );

				?>
			</div>
			<div id="major-publishing-actions">
				<div id="delete-action">
					<?php
					switch ( $entry['status'] ) {
						case 'spam' :
							if ( GFCommon::current_user_can_any( 'gravityforms_edit_entries' ) ) {
								?>
								<a onclick="jQuery('#action').val('unspam'); jQuery('#entry_form').submit()" href="#"><?php esc_html_e( 'Not Spam', 'gravityforms' ) ?></a>
								<?php
								echo GFCommon::current_user_can_any( 'gravityforms_delete_entries' ) ? '|' : '';
							}
							if ( GFCommon::current_user_can_any( 'gravityforms_delete_entries' ) ) {
								?>
								<a class="submitdelete deletion" onclick="if ( confirm('<?php echo esc_js( __( "You are about to delete this entry. 'Cancel' to stop, 'OK' to delete.", 'gravityforms' ) ); ?>') ) {jQuery('#action').val('delete'); jQuery('#entry_form').submit(); return true;} return false;" href="#"><?php esc_html_e( 'Delete Permanently', 'gravityforms' ) ?></a>
								<?php
							}

							break;

						case 'trash' :
							if ( GFCommon::current_user_can_any( 'gravityforms_delete_entries' ) ) {
							?>
								<a onclick="jQuery('#action').val('restore'); jQuery('#entry_form').submit()" href="#"><?php esc_html_e( 'Restore', 'gravityforms' ) ?></a>
								|
								<a class="submitdelete deletion" onclick="if ( confirm('<?php echo esc_js( __( "You are about to delete this entry. 'Cancel' to stop, 'OK' to delete.", 'gravityforms' ) ); ?>') ) {jQuery('#action').val('delete'); jQuery('#entry_form').submit(); return true;} return false;" href="#"><?php esc_html_e( 'Delete Permanently', 'gravityforms' ) ?></a>
								<?php
							}

							break;

						default :
							if ( GFCommon::current_user_can_any( 'gravityforms_delete_entries' ) ) {
								?>
								<a class="submitdelete deletion" onclick="jQuery('#action').val('trash'); jQuery('#entry_form').submit()" href="#"><?php esc_html_e( 'Move to Trash', 'gravityforms' ) ?></a>
								<?php
								echo GFCommon::spam_enabled( $form['id'] ) && GFCommon::current_user_can_any( 'gravityforms_edit_entries' ) ? '|' : '';
							}
							if ( GFCommon::spam_enabled( $form['id'] ) && GFCommon::current_user_can_any( 'gravityforms_edit_entries' ) ) {
								?>
								<a class="submitdelete deletion" onclick="jQuery('#action').val('spam'); jQuery('#entry_form').submit()" href="#"><?php esc_html_e( 'Mark as Spam', 'gravityforms' ) ?></a>
								<?php
							}
					}

					?>
				</div>
				<div id="publishing-action">
					<?php
					if ( GFCommon::current_user_can_any( 'gravityforms_edit_entries' ) && $entry['status'] != 'trash' ) {
						$button_text      = $mode == 'view' ? __( 'Edit', 'gravityforms' ) : __( 'Update', 'gravityforms' );
						$button_classes   = $mode == 'view' ? 'button button-large' : 'button button-large primary';
						$disabled         = $mode == 'view' ? '' : ' disabled="disabled" ';
						$update_button_id = $mode == 'view' ? 'gform_edit_button' : 'gform_update_button';
						$button_click     = $mode == 'view' ? "jQuery('#screen_mode').val('edit');" : "jQuery('#action').val('update'); jQuery('#screen_mode').val('view');";
						$update_button    = '<input id="' . $update_button_id . '" ' . $disabled . ' class="' . esc_attr( $button_classes ) . '" type="submit" tabindex="4" value="' . esc_attr( $button_text ) . '" name="save" onclick="' . $button_click . '"/>';

						/**
						 * A filter to allow the modification of the button to update an entry detail
						 *
						 * @param string $update_button The HTML Rendered for the Entry Detail update button
						 */
						echo apply_filters( 'gform_entrydetail_update_button', $update_button ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
						if ( $mode == 'edit' ) {
							echo '&nbsp;&nbsp;<input class="button button-large" type="submit" tabindex="5" value="' . esc_attr__( 'Cancel', 'gravityforms' ) . '" name="cancel" onclick="jQuery(\'#screen_mode\').val(\'view\');"/>';
						}
					}
					?>
				</div>
				<div class="clear"></div>
			</div>
		</div>
		<?php
	}

	public static function meta_box_notifications( $args, $metabox ){
		$form    = $args['form'];
		$form_id = $form['id'];

		if ( ! GFCommon::current_user_can_any( 'gravityforms_edit_entry_notes' ) ) {
			return;
		}
		?>

		<div class="message" style="display:none;"></div>
		<div>
			<?php

			$notifications = GFCommon::get_notifications( 'resend_notifications', $form );

			if ( ! is_array( $notifications ) || count( $form['notifications'] ) <= 0 ) {
				?>
				<p class="description"><?php esc_html_e( 'You cannot resend notifications for this entry because this form does not currently have any notifications configured.', 'gravityforms' ); ?></p>

				<a href="<?php echo esc_url_raw( admin_url( "admin.php?page=gf_edit_forms&view=settings&subview=notification&id={$form_id}" ) ) ?>" class="button"><?php esc_html_e( 'Configure Notifications', 'gravityforms' ) ?></a>
				<?php
			} else {
				foreach ( $notifications as $notification ) {
					?>
					<input type="checkbox" class="gform_notifications" value="<?php echo esc_attr( $notification['id'] ); ?>" id="notification_<?php echo esc_attr( $notification['id'] ); ?>" onclick="toggleNotificationOverride();" />
					<label for="notification_<?php echo esc_attr( $notification['id'] ); ?>"><?php echo esc_html( $notification['name'] ); ?></label>
					<br /><br />
					<?php
				}
				?>

				<div id="notifications_override_settings" style="display:none;">

					<p class="description" style="padding-top:0; margin-top:0; width:99%;">You may override the default notification settings
						by entering a comma delimited list of emails to which the selected notifications should be sent.</p>
					<label for="notification_override_email"><?php esc_html_e( 'Send To', 'gravityforms' ); ?> <?php gform_tooltip( 'notification_override_email' ) ?></label>
					<input type="text" name="notification_override_email" id="notification_override_email" style="width:99%;" />
					<br /><br />

				</div>

				<input type="button" name="notification_resend" value="<?php esc_attr_e( 'Resend', 'gravityforms' ) ?>" class="button" style="" onclick="ResendNotifications();" />
				<span id="please_wait_container" style="display:none; margin-left: 5px;">
							<i class='gficon-gravityforms-spinner-icon gficon-spin'></i> <?php esc_html_e( 'Resending...', 'gravityforms' ); ?>
                        </span>
				<?php
			}
			?>

		</div>

		<?php
	}

	/**
	 * Helper to determine if empty fields should be displayed when the lead detail grid is processed.
	 *
	 * @param bool $allow_display_empty_fields Determines if the value of the 'show empty fields' checkbox should be used. True when viewing the entry and false when in edit mode.
	 * @param array $form The Form object for the current Entry.
	 * @param array|bool $lead The current Entry object or false.
	 *
	 * @return bool
	 */
	public static function maybe_display_empty_fields( $allow_display_empty_fields, $form, $lead = false ) {
		$display_empty_fields = false;
		if ( $allow_display_empty_fields ) {
			$display_empty_fields = (bool) rgget( 'gf_display_empty_fields', $_COOKIE );
		}

		if ( ! $lead ) {
			$lead = self::get_current_entry();
		}

		/**
		 * A filter to determine if empty fields should be displayed in the entry details.
		 *
		 * @param bool $display_empty_fields True or false to show the fields
		 * @param array $form The Form object to filter
		 * @param array $lead The Entry object to filter
		 */
		return apply_filters( 'gform_entry_detail_grid_display_empty_fields', $display_empty_fields, $form, $lead );
	}

}
