__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
<?php

namespace WPForms\Pro\Admin;

use DateInterval;
use DatePeriod;
use DateTime;
use Exception;
use WP_Post;
use WPForms\Admin\Blocks\Links;
use WPForms\Admin\Dashboard\Widget;
use WPForms\Admin\Helpers\Datepicker;
use WPForms\Pro\Reports\EntriesCount;

/**
 * Dashboard Widget shows a chart and the form entries stats in WP Dashboard.
 *
 * @since 1.5.0
 */
class DashboardWidget extends Widget {

	/**
	 * Widget settings.
	 *
	 * @since 1.5.0
	 *
	 * @var array
	 */
	public $settings;

	/**
	 * Runtime values.
	 *
	 * @since 1.5.5
	 * @deprecated 1.8.6
	 *
	 * @var array
	 */
	public $runtime_data = [];

	/**
	 * Entries count.
	 *
	 * @since 1.7.6
	 *
	 * @var EntriesCount
	 */
	private $entries_count;

	/**
	 * Constructor.
	 *
	 * @since 1.5.0
	 */
	public function __construct() {

		$this->entries_count = new EntriesCount();
	}

	/**
	 * Init class.
	 *
	 * @since 1.5.5
	 * @since 1.8.3 Added cache clean hooks.
	 */
	public function init() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks

		// phpcs:disable WPForms.PHP.ValidateHooks.InvalidHookName
		/** This filter is documented in the wpforms/src/Lite/Admin/DashboardWidget.php file. */
		if ( ! apply_filters( 'wpforms_admin_dashboardwidget', true ) ) {
			return;
		}
		// phpcs:enable WPForms.PHP.ValidateHooks.InvalidHookName

		// This widget should be displayed for certain high-level users only.
		if ( ! wpforms_current_user_can( 'view_entries' ) ) {
			return;
		}

		add_action( 'wpforms_create_form', [ static::class, 'clear_widget_cache' ] );
		add_action( 'wpforms_save_form', [ static::class, 'clear_widget_cache' ] );
		add_action( 'wpforms_delete_form', [ static::class, 'clear_widget_cache' ] );

		/**
		 * Clear cache after PRO plugin deactivation.
		 *
		 * If a user wants to switch to the Lite version, it needs to deactivate PRO plugin first.
		 * After activation of the Lite version, the cache will be cleared.
		 */
		add_action( 'deactivate_wpforms/wpforms.php', [ static::class, 'clear_widget_cache' ] );

		// Continue only if we are on the dashboard page.
		if ( ! $this->is_dashboard_page() && ! $this->is_dashboard_widget_ajax_request() ) {
			return;
		}

		$this->settings();
		$this->hooks();
	}

	/**
	 * Filterable widget settings.
	 *
	 * @since 1.5.0
	 */
	public function settings() {

		$widget_slug = static::SLUG;

		// phpcs:disable WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName

		$this->settings = [

			// Number of forms to display in the forms' list before the "Show More" button appears.
			'forms_list_number_to_display'     => apply_filters( "wpforms_{$widget_slug}_forms_list_number_to_display", 5 ),

			// Allow results caching to reduce a DB load.
			'allow_data_caching'               => apply_filters( "wpforms_{$widget_slug}_allow_data_caching", true ),

			// PHP DateTime supported string (http://php.net/manual/en/datetime.formats.php).
			'date_end_str'                     => apply_filters( "wpforms_{$widget_slug}_date_end_str", 'today' ),

			// Transient lifetime in seconds. Defaults to one hour in seconds.
			'transient_lifetime'               => apply_filters( "wpforms_{$widget_slug}_transient_lifetime", HOUR_IN_SECONDS ),

			// Determine if the days with no entries should appear on a chart. Once switched, the effect applies after cache expiration.
			'display_chart_empty_entries'      => apply_filters( "wpforms_{$widget_slug}_display_chart_empty_entries", true ),

			// Determine if the forms with no entries should appear in a forms' list.
			// Once switched, the effect applies after cache expiration.
			'display_forms_list_empty_entries' => apply_filters( "wpforms_{$widget_slug}_display_forms_list_empty_entries", true ),
		];

		// phpcs:enable WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName
	}

	/**
	 * Widget hooks.
	 *
	 * @since 1.5.0
	 */
	public function hooks() {

		$widget_slug = static::SLUG;

		add_action( 'admin_enqueue_scripts', [ $this, 'widget_scripts' ] );

		if ( $widget_slug === 'dash_widget' ) {
			add_action( 'wp_dashboard_setup', [ $this, 'widget_register' ] );
		}

		add_action( "wp_ajax_wpforms_{$widget_slug}_get_chart_data", [ $this, 'get_chart_data_ajax' ] );
		add_action( "wp_ajax_wpforms_{$widget_slug}_get_forms_list", [ $this, 'get_forms_list_ajax' ] );
		add_action( "wp_ajax_wpforms_{$widget_slug}_save_widget_meta", [ $this, 'save_widget_meta_ajax' ] );
	}

	/**
	 * Load widget-specific scripts.
	 *
	 * @since 1.5.0
	 *
	 * @param string $hook_suffix The current admin page.
	 *
	 * @throws Exception Exception.
	 */
	public function widget_scripts( $hook_suffix ) {

		if ( ! in_array( $hook_suffix, [ 'index.php', 'wpforms_page_wpforms-entries' ], true ) ) {
			return;
		}

		$min = wpforms_get_min_suffix();

		wp_enqueue_style(
			'wpforms-dashboard-widget',
			WPFORMS_PLUGIN_URL . "assets/css/dashboard-widget$min.css",
			[],
			WPFORMS_VERSION
		);

		wp_enqueue_script(
			'wpforms-chart',
			WPFORMS_PLUGIN_URL . 'assets/lib/chart.min.js',
			[ 'moment' ],
			'4.4.4',
			true
		);

		wp_enqueue_script(
			'wpforms-chart-adapter-moment',
			WPFORMS_PLUGIN_URL . 'assets/lib/chartjs-adapter-moment.min.js',
			[ 'moment', 'wpforms-chart' ],
			'1.0.1',
			true
		);

		wp_enqueue_script(
			'wpforms-dashboard-widget',
			WPFORMS_PLUGIN_URL . "assets/pro/js/admin/dashboard-widget$min.js",
			[ 'jquery', 'wpforms-chart' ],
			WPFORMS_VERSION,
			true
		);

		wp_localize_script(
			'wpforms-dashboard-widget',
			'wpforms_dashboard_widget',
			[
				'nonce'            => wp_create_nonce( 'wpforms_' . static::SLUG . '_nonce' ),
				'slug'             => static::SLUG,
				'date_format'      => sanitize_text_field( Datepicker::get_wp_date_format_for_momentjs() ),
				'empty_chart_html' => $this->get_empty_chart_html(),
				'chart_data'       => $this->get_entries_count_by(
					'date',
					$this->widget_meta( 'get', 'timespan' ),
					$this->widget_meta( 'get', 'active_form_id' )
				),
				'chart_type'       => (int) $this->widget_meta( 'get', 'graph_style' ) === 2 ? 'line' : 'bar',
				'color_scheme'     => (int) $this->widget_meta( 'get', 'color_scheme' ) === 2 ? 'wp' : 'wpforms',
				'show_more_html'   => esc_html__( 'Show More', 'wpforms' ) . '<span class="dashicons dashicons-arrow-down"></span>',
				'show_less_html'   => esc_html__( 'Show Less', 'wpforms' ) . '<span class="dashicons dashicons-arrow-up"></span>',
				'i18n'             => [
					'total_entries' => esc_html__( 'Total Entries', 'wpforms' ),
					'entries'       => esc_html__( 'Entries', 'wpforms' ),
					'form_entries'  => esc_html__( 'Form Entries', 'wpforms' ),
				],
			]
		);
	}

	/**
	 * Register the widget.
	 *
	 * @since 1.5.0
	 */
	public function widget_register() {

		global $wp_meta_boxes;

		$widget_key = 'wpforms_reports_widget_pro';

		wp_add_dashboard_widget(
			$widget_key,
			esc_html__( 'WPForms', 'wpforms' ),
			[ $this, 'widget_content' ]
		);

		// Attempt to place the widget at the top.
		$normal_dashboard = $wp_meta_boxes['dashboard']['normal']['core'];
		$widget_instance  = [ $widget_key => $normal_dashboard[ $widget_key ] ];

		unset( $normal_dashboard[ $widget_key ] );

		$sorted_dashboard = array_merge( $widget_instance, $normal_dashboard );

		// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
		$wp_meta_boxes['dashboard']['normal']['core'] = $sorted_dashboard;
	}

	/**
	 * Load widget content.
	 *
	 * @since 1.5.0
	 *
	 * @throws Exception Exception.
	 */
	public function widget_content(): void {

		$form_obj = wpforms()->obj( 'form' );
		$forms    = $form_obj ? $form_obj->get( '', [ 'fields' => 'ids' ] ) : [];

		echo '<div class="wpforms-dash-widget wpforms-pro">';

		echo '<div class="wpforms-dash-widget-content">';

		if ( empty( $forms ) ) {
			$this->widget_content_no_forms_html();
		} else {
			$this->widget_content_html();
		}

		echo '</div><!-- .wpforms-dash-widget-content -->';

		Links::render(
			[
				'docs'    => [
					'medium'  => 'dashboard-widget',
					'content' => 'docs',
				],
				'support' => [
					'medium'  => 'dashboard-widget',
					'content' => 'support',
				],
			]
		);

		$plugin           = $this->get_recommended_plugin();
		$hide_recommended = $this->widget_meta( 'get', 'hide_recommended_block' );

		if (
			! empty( $plugin ) &&
			! empty( $forms ) &&
			! $hide_recommended
		) {
			$this->recommended_plugin_block_html( $plugin );
		}

		echo '</div><!-- .wpforms-dash-widget -->';
	}

	/**
	 * Widget content HTML if a user has no forms.
	 *
	 * @since 1.5.0
	 */
	public function widget_content_no_forms_html() {

		$create_form_url = add_query_arg( 'page', 'wpforms-builder', admin_url( 'admin.php' ) );
		$learn_more_url  = 'https://wpforms.com/docs/creating-first-form/?utm_source=WordPress&utm_medium=link&utm_campaign=plugin&utm_content=dashboardwidget';

		?>
		<div class="wpforms-dash-widget-block wpforms-dash-widget-block-no-forms">
			<img class="wpforms-dash-widget-block-sullie-logo" src="<?php echo esc_url( WPFORMS_PLUGIN_URL . 'assets/images/sullie.png' ); ?>" alt="<?php esc_attr_e( 'Sullie the WPForms mascot', 'wpforms' ); ?>">
			<h2><?php esc_html_e( 'Create Your First Form to Start Collecting Leads', 'wpforms' ); ?></h2>
			<p><?php esc_html_e( 'You can use WPForms to build contact forms, surveys, payment forms, and more with just a few clicks.', 'wpforms' ); ?></p>

			<?php if ( wpforms_current_user_can( 'create_forms' ) ) : ?>
				<a href="<?php echo esc_url( $create_form_url ); ?>" class="button button-primary">
					<?php esc_html_e( 'Create Your Form', 'wpforms' ); ?>
				</a>
			<?php endif; ?>

			<a href="<?php echo esc_url( $learn_more_url ); ?>" class="button" target="_blank" rel="noopener noreferrer">
				<?php esc_html_e( 'Learn More', 'wpforms' ); ?>
			</a>
		</div>
		<?php
	}

	/**
	 * Widget content HTML.
	 *
	 * @since 1.5.0
	 *
	 * @throws Exception Exception.
	 */
	public function widget_content_html() {

		$widget_slug    = static::SLUG;
		$timespan       = $this->widget_meta( 'get', 'timespan' );
		$active_form_id = $this->widget_meta( 'get', 'active_form_id' );

		// phpcs:disable WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName
		$title           = empty( $active_form_id ) ? apply_filters( "wpforms_{$widget_slug}_total_entries_title", esc_html__( 'Total Entries', 'wpforms' ) ) : get_the_title( $active_form_id );
		$timespan_at_top = (bool) apply_filters( "wpforms_{$widget_slug}_timespan_at_top", false );
		// phpcs:enable WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName

		// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
		/**
		 * Filters the content before the Dashboard Widget Chart block container (for Pro).
		 *
		 * @since 1.7.4
		 *
		 * @param string $chart_block_before Chart block before markup.
		 */
		echo apply_filters( 'wpforms_pro_admin_dashboard_widget_content_html_chart_block_before', '' );
		// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
		?>

		<div class="wpforms-dash-widget-chart-block-container">

			<div class="wpforms-dash-widget-block">
				<?php if ( empty( $active_form_id ) ) : ?>
				<button type="button" id="wpforms-dash-widget-reset-chart" class="wpforms-dash-widget-reset-chart" title="<?php esc_html_e( 'Reset chart to display all forms', 'wpforms' ); ?>"
					style="display: none;" >
					<span class="dashicons dashicons-dismiss"></span>
				</button>
				<?php endif; ?>
				<h3 id="wpforms-dash-widget-chart-title">
					<?php echo esc_html( $title ); ?>
				</h3>
				<div class="wpforms-dash-widget-settings">
				<?php
				if ( $timespan_at_top ) {
					$this->timespan_select_html( $active_form_id );
					$this->widget_settings_html();
				}
				?>
				</div>
			</div>

			<div class="wpforms-dash-widget-block wpforms-dash-widget-chart-block">
				<canvas id="wpforms-dash-widget-chart" width="400" height="300"></canvas>
				<div class="wpforms-dash-widget-overlay"></div>
			</div>

		</div>

		<?php if ( ! $timespan_at_top ) : ?>
			<div class="wpforms-dash-widget-block wpforms-dash-widget-block-title">
				<h3>
					<span id="entry-count-text"><?php esc_html_e( 'Total Entries', 'wpforms' ); ?></span>:
					<span id="entry-count-value" data-total-count="<?php echo esc_attr( $this->get_total_entries() ); ?>"><?php echo esc_html( $this->get_total_entries() ); ?></span>
				</h3>
				<div class="wpforms-dash-widget-settings">
				<?php
				$this->timespan_select_html( $active_form_id );
				$this->widget_settings_html();
				?>
				</div>
			</div>
		<?php endif; ?>

		<div id="wpforms-dash-widget-forms-list-block" class="wpforms-dash-widget-block wpforms-dash-widget-forms-list-block">
			<?php $this->forms_list_block( $timespan ); ?>
		</div>
		<?php
	}

	/**
	 * Forms list block.
	 *
	 * @since 1.5.0
	 *
	 * @param int $days Timespan (in days) to fetch the data for.
	 *
	 * @throws Exception When date is failing.
	 */
	public function forms_list_block( $days ) {

		$forms = $this->get_entries_count_by( 'form', $days );

		if ( empty( $forms ) ) {
			$this->forms_list_block_empty_html();
		} else {
			$this->forms_list_block_html( $forms );
		}
	}

	/**
	 * Empty forms list block HTML.
	 *
	 * @since 1.5.0
	 */
	public function forms_list_block_empty_html() {

		?>
		<p class="wpforms-error wpforms-error-no-data-forms-list">
			<?php esc_html_e( 'No entries for selected period.', 'wpforms' ); ?>
		</p>
		<?php
	}

	/**
	 * Forms list block HTML.
	 *
	 * @since 1.5.0
	 *
	 * @param array $forms Forms to display in the list.
	 *
	 * @noinspection HtmlUnknownTarget
	 */
	public function forms_list_block_html( $forms ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh

		// Number of forms to display in the forms' list before the "Show More" button appears.
		$show_forms     = $this->settings['forms_list_number_to_display'];
		$active_form_id = $this->widget_meta( 'get', 'active_form_id' );
		$widget_slug    = static::SLUG;
		?>

		<table id="wpforms-dash-widget-forms-list-table" cellspacing="0">
			<?php
			echo wp_kses(
				/**
				 * Allow modifying a forms' list table header.
				 *
				 * @since 1.5.4
				 *
				 * @param string $header Forms list table header.
				 * @param array  $forms  Forms list data.
				 *
				 * @return string
				 */
				apply_filters( "wpforms_{$widget_slug}_forms_list_columns", '', $forms ), // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
				[
					'tr' => [
						'class' => [],
					],
					'td' => [
						'class' => [],
					],
				]
			);

			foreach ( array_values( $forms ) as $key => $form ) :

				$is_active_form = $form['form_id'] === $active_form_id;

				if ( ! is_array( $form ) ) {
					continue;
				}
				if ( ! isset( $form['form_id'], $form['title'], $form['count'], $form['edit_url'] ) ) {
					continue;
				}

				$form_data = $form['form_id'] ? wpforms()->obj( 'form' )->get( $form['form_id'], [ 'content_only' => true ] ) : [];

				$classes = [
					$key >= $show_forms && $show_forms > 0 ? 'wpforms-dash-widget-forms-list-hidden-el' : '',
					$is_active_form ? 'wpforms-dash-widget-form-active' : '',
				];
				?>

				<tr data-form-id="<?php echo absint( $form['form_id'] ); ?>"
					data-entry-count="<?php echo absint( $form['count'] ); ?>"
					class="<?php echo esc_attr( implode( ' ', array_unique( $classes ) ) ); ?>"
				>
					<td>
						<span class="wpforms-dash-widget-form-title">
							<?php
							echo wp_kses(
								/**
								 * Allow modifying a widget title.
								 *
								 * @since 1.5.5
								 *
								 * @param string $form_title Widget title.
								 * @param array  $form       Form data and settings.
								 *
								 * @return string
								 */
								apply_filters( // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
									"wpforms_{$widget_slug}_forms_list_form_title",
									$form['title'],
									$form
								),
								[
									'a' => [
										'href'  => [],
										'class' => [],
									],
								]
							);
							?>
						</span>
					</td>
					<?php
					echo wp_kses(
						/**
						 * Allow adding additional cells for a widget table.
						 *
						 * @since 1.5.5
						 *
						 * @param string $form_title Widget title.
						 * @param array  $form       Form data and settings.
						 *
						 * @return string
						 */
						apply_filters( // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
							"wpforms_{$widget_slug}_forms_list_additional_cells",
							'',
							$form
						),
						[
							'td' => [],
							'a'  => [
								'href' => [],
							],
						]
					);
					?>
					<td>
						<?php

						if ( $form['count'] === 0 && ! empty( $form_data['settings']['disable_entries'] ) ) {
							echo '&mdash;';
						} elseif ( wpforms_current_user_can( 'view_entries_form_single', $form['form_id'] ) ) {
							// Ensure the current user has enough permission to view entries of this form.
							printf(
								'<a href="%s" class="entry-list-link">%d</a>',
								esc_url( $form['edit_url'] ),
								absint( $form['count'] )
							);
						} else {
							echo absint( $form['count'] );
						}
						?>
					</td>
					<td class="graph">
						<?php if ( absint( $form['count'] ) > 0 ) : ?>
							<button type="button" class="wpforms-dash-widget-single-chart-btn chart dashicons dashicons-chart-bar" title="<?php esc_attr_e( 'Display only this form data in the graph', 'wpforms' ); ?>"></button>
							<?php
								if ( $is_active_form ) {
									?>
									<button type="button" id="wpforms-dash-widget-reset-chart" class="wpforms-dash-widget-reset-chart" title="<?php esc_html_e( 'Reset graph to display all forms', 'wpforms' ); ?>" >
										<span class="dashicons dashicons-dismiss"></span>
									</button>
									<?php
								}
							?>
							<?php
							echo wp_kses(
								/**
								 * Allow adding additional buttons for a widget table.
								 *
								 * @since 1.5.5
								 *
								 * @param string $form_title Widget title.
								 * @param array  $form       Form data and settings.
								 *
								 * @return string
								 */
								apply_filters( // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
									"wpforms_{$widget_slug}_forms_list_additional_buttons",
									'',
									$form
								),
								[
									'button' => [
										'type'  => [],
										'class' => [],
										'title' => [],
									],
									'span'   => [
										'class' => [],
									],
								]
							);
							?>
						<?php endif; ?>
					</td>
				</tr>
			<?php endforeach; ?>
		</table>

		<?php if ( $show_forms > 0 && count( $forms ) > $show_forms ) : ?>
			<button type="button" id="wpforms-dash-widget-forms-more" class="wpforms-dash-widget-forms-more" title="<?php esc_attr_e( 'Show all forms', 'wpforms' ); ?>">
				<?php esc_html_e( 'Show More', 'wpforms' ); ?> <span class="dashicons dashicons-arrow-down"></span>
			</button>
		<?php endif; ?>

		<?php
	}

	/**
	 * Recommended plugin block HTML.
	 *
	 * @since 1.5.0
	 * @since 1.7.3 Added plugin parameter.
	 *
	 * @param array $plugin Plugin data.
	 */
	public function recommended_plugin_block_html( $plugin = [] ) {

		if ( ! $plugin ) {
			return;
		}

		$install_url = wp_nonce_url(
			self_admin_url( 'update.php?action=install-plugin&plugin=' . rawurlencode( $plugin['slug'] ) ),
			'install-plugin_' . $plugin['slug']
		);
		?>

		<div class="wpforms-dash-widget-block wpforms-dash-widget-recommended-plugin-block">
			<span class="wpforms-dash-widget-recommended-plugin">
				<span class="recommended"><?php esc_html_e( 'Recommended Plugin:', 'wpforms' ); ?></span>
				<strong><?php echo esc_html( $plugin['name'] ); ?></strong>
				<span class="sep">-</span>
				<span class="action-links">
					<?php if ( wpforms_can_install( 'plugin' ) ) { ?>
						<a href="<?php echo esc_url( $install_url ); ?>"><?php esc_html_e( 'Install', 'wpforms' ); ?></a>
						<span class="sep sep-vertical">&vert;</span>
					<?php } ?>
					<a href="<?php echo esc_url( $plugin['more'] ); ?>?utm_source=wpformsplugin&utm_medium=link&utm_campaign=wpformsdashboardwidget"><?php esc_html_e( 'Learn More', 'wpforms' ); ?></a>
				</span>
			</span>
			<button type="button" id="wpforms-dash-widget-dismiss-recommended-plugin-block" class="wpforms-dash-widget-dismiss-icon" title="<?php esc_html_e( 'Dismiss', 'wpforms' ); ?>" data-field="hide_recommended_block">
				<span class="dashicons dashicons-no-alt"></span>
			</button>
		</div>
		<?php
	}

	/**
	 * The welcome block HTML.
	 *
	 * @since 1.8.7
	 * @deprecated 1.9.7
	 */
	public function welcome_block_html() {

		return '';
	}

	/**
	 * Get empty chart HTML.
	 *
	 * @since 1.5.0
	 */
	public function get_empty_chart_html() {

		ob_start();
		?>

		<div class="wpforms-error wpforms-error-no-data-chart">
			<div class="wpforms-dash-widget-modal">
				<h2><?php esc_html_e( 'No entries for selected period', 'wpforms' ); ?></h2>
				<p><?php esc_html_e( 'Please select a different period or check back later.', 'wpforms' ); ?></p>
			</div>
		</div>

		<?php

		return ob_get_clean();
	}

	/**
	 * Converts number of days to day start and day end values.
	 *
	 * @since 1.5.5
	 *
	 * @param integer $days Timespan days.
	 *
	 * @return array|false
	 */
	public function get_days_interval( $days = 0 ) {

		// PHP DateTime supported string (http://php.net/manual/en/datetime.formats.php).
		$date_end_str  = $this->settings['date_end_str'];
		$modify_offset = (float) get_option( 'gmt_offset' ) * 60 . ' minutes';

		try {
			$now               = new DateTime();
			$interval['start'] = new DateTime( $date_end_str );
			$interval['end']   = new DateTime( $date_end_str );

			$interval['end']
				->setTime( $now->format( 'H' ), $now->format( 'i' ), $now->format( 's' ) )
				->modify( $modify_offset )
				->setTime( 23, 59, 59 );
			$interval['start']
				->setTime( $now->format( 'H' ), $now->format( 'i' ), $now->format( 's' ) )
				->modify( $modify_offset )
				->modify( '-' . ( absint( $days ) - 1 ) . 'days' )
				->setTime( 0, 0 );
		} catch ( Exception $e ) {
			return false;
		}

		return $interval;
	}


	/**
	 * Get entries count grouped by $param.
	 * Main point of entry to fetch form entry count data from DB.
	 * Caches the result.
	 *
	 * @since 1.5.0
	 *
	 * @param string $param   Possible value: 'date' or 'form'.
	 * @param int    $days    Timespan (in days) to fetch the data for.
	 * @param int    $form_id Form ID to fetch the data for.
	 *
	 * @return array
	 * @throws Exception When dates management fails.
	 */
	public function get_entries_count_by( $param, $days = 0, $form_id = 0 ): array {

		// Allow only 'date' and 'form' params.
		if ( ! in_array( $param, [ 'date', 'form' ], true ) ) {
			return [];
		}

		// Allow results caching to reduce a DB load.
		$allow_caching = $this->settings['allow_data_caching'];

		if ( $allow_caching ) {
			$widget_slug    = static::SLUG;
			$transient_name = $this->get_entries_transient_name( $param, $days, $form_id );

			$cache = get_transient( $transient_name );

			// Filter the cache to clear or alter its data.
			// phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName
			$cache = apply_filters( "wpforms_{$widget_slug}_cached_data", $cache, $param, $days, $form_id );

			if ( is_array( $cache ) && count( $cache ) > 0 ) {
				return $cache;
			}
		}

		$dates = $this->get_days_interval( $days );

		switch ( $param ) {
			case 'date':
				$result = $this->get_entries_count_by_date_sql( $form_id, $dates['start'], $dates['end'] );
				break;

			case 'form':
				$result = $this->get_entries_count_by_form_sql( $form_id, $dates['start'], $dates['end'] );
				break;

			default:
				$result = [];
		}

		if ( $allow_caching ) {
			// Transient lifetime in seconds. Defaults to the end of a current day.
			$transient_lifetime = $this->settings['transient_lifetime'];

			set_transient( $transient_name, $result, $transient_lifetime );
		}

		return $result;
	}

	/**
	 * Get the total number of form entries.
	 *
	 * @since 1.7.4
	 *
	 * @return int
	 * @throws Exception When dates management fails.
	 */
	private function get_total_entries(): int {

		$total = 0;
		$forms = $this->get_entries_count_by( 'form' );

		if ( ! empty( $forms ) ) {
			foreach ( $forms as $form ) {
				$total += (int) $form['count'];
			}
		}

		return $total;
	}

	/**
	 * Get entries count grouped by date.
	 * In most cases, it's better to use `get_entries_count_by( 'date' )` instead.
	 * Doesn't cache the result.
	 *
	 * @since 1.5.0
	 * @since 1.7.5 Filter the forms where entries are fetched by allowed
	 *                  access of the current user.
	 *
	 * @param int      $form_id    Form ID to fetch the data for.
	 * @param DateTime $date_start Start date for the search.
	 * @param DateTime $date_end   End date for the search.
	 *
	 * @return array
	 * @throws Exception When dates are failing.
	 */
	public function get_entries_count_by_date_sql( $form_id = 0, $date_start = null, $date_end = null ): array {

		if ( ! empty( $form_id ) && ! wpforms_current_user_can( 'view_entries_form_single', $form_id ) ) {
			return [];
		}

		$results = $this->entries_count->get_by_date_sql( $form_id, $date_start, $date_end );

		if ( ! $this->settings['display_chart_empty_entries'] ) {
			return $results;
		}

		return $this->fill_chart_empty_entries( $results, $date_start, $date_end );
	}

	/**
	 * Get entries count grouped by form.
	 * In most cases, it's better to use `get_entries_count_by( 'form' )` instead.
	 * Doesn't cache the result.
	 *
	 * @since 1.5.0
	 * @since 1.7.5 Filter the results by allowed access of the current user.
	 *
	 * @param int      $form_id    Form ID to fetch the data for.
	 * @param DateTime $date_start Start date for the search.
	 * @param DateTime $date_end   End date for the search.
	 *
	 * @return array
	 */
	public function get_entries_count_by_form_sql( $form_id = 0, $date_start = null, $date_end = null ): array {

		if ( ! empty( $form_id ) && ! wpforms_current_user_can( 'view_entries_form_single', $form_id ) ) {
			return [];
		}

		$results = $this->entries_count->get_by_form_sql( $form_id, $date_start, $date_end );

		// Keep backward compatibility converting an array to object.
		foreach ( $results as $key => $form ) {
			$results[ $key ] = (object) $form;
		}

		// Determine if the forms with no entries should appear in a forms' list.
		// Once switched, the effect applies after cache expiration.
		if ( $this->settings['display_forms_list_empty_entries'] ) {
			$forms = $this->fill_forms_list_empty_entries_form_data( $results );
		} else {
			$forms = $this->fill_forms_list_form_data( $results );
		}

		$access_obj = wpforms()->obj( 'access' );

		return (
		$access_obj ?
			$access_obj->filter_forms_by_current_user_capability( $forms, 'view_entries_form_single' ) :
			[]
		);
	}

	/**
	 * Fill DB results with empty entries where there's no data.
	 * Needed to correctly distribute labels and data on a chart.
	 *
	 * @since 1.5.0
	 *
	 * @param array    $results    DB results from `$wpdb->prepare()`.
	 * @param DateTime $date_start Start date for the search.
	 * @param DateTime $date_end   End date for the search.
	 *
	 * @return array
	 * @throws Exception DatePeriod may throw an exception.
	 */
	public function fill_chart_empty_entries( $results, $date_start, $date_end ): array {

		if ( ! is_array( $results ) ) {
			return [];
		}

		$period = new DatePeriod(
			$date_start,
			new DateInterval( 'P1D' ),
			$date_end
		);

		foreach ( $period as $value ) {
			/**
			 * Period value.
			 *
			 * @var DateTime $value
			 */
			$date = $value->format( 'Y-m-d' );

			if ( ! array_key_exists( $date, $results ) ) {
				$results[ $date ] = [
					'day'   => $date,
					'count' => 0,
				];

				continue;
			}

			// Mold an object to array to stay uniform.
			$results[ $date ] = (array) $results[ $date ];
		}

		ksort( $results );

		return $results;
	}

	/**
	 * Fill a forms' list with the data needed for a frontend display.
	 *
	 * @since 1.5.0
	 *
	 * @param array $results DB results from `$wpdb->prepare()`.
	 *
	 * @return array
	 */
	public function fill_forms_list_form_data( $results ): array {

		if ( ! is_array( $results ) ) {
			return [];
		}

		$processed = [];

		foreach ( $results as $form_id => $result ) {

			$form_obj = wpforms()->obj( 'form' );
			$form     = $form_obj ? $form_obj->get( $form_id ) : null;

			if ( empty( $form ) ) {
				continue;
			}

			$data = $this->get_formatted_forms_list_form_data( $form, $results );

			if ( $data ) {
				$processed[ $form->ID ] = $data;
			}
		}

		return $processed;
	}

	/**
	 * Fill a forms' list with the data needed for a frontend display.
	 * Includes forms with zero entries.
	 *
	 * @since 1.5.0
	 *
	 * @param array $results DB results from `$wpdb->prepare()`.
	 *
	 * @return array
	 */
	public function fill_forms_list_empty_entries_form_data( $results ): array {

		if ( ! is_array( $results ) ) {
			return [];
		}

		$form_obj = wpforms()->obj( 'form' );
		$forms    = $form_obj ? $form_obj->get() : null;

		if ( empty( $forms ) ) {
			return [];
		}

		$processed = [];

		foreach ( $forms as $form ) {

			$data = $this->get_formatted_forms_list_form_data( $form, $results );

			if ( $data ) {
				$processed[ $form->ID ] = $data;
			}
		}

		return wp_list_sort( $processed, 'count', 'DESC' );
	}

	/**
	 * Get formatted form data for a forms list frontend display.
	 *
	 * @since 1.5.4
	 *
	 * @param WP_Post $form    Form object.
	 * @param array   $results DB results from `$wpdb->prepare()`.
	 *
	 * @return array
	 */
	public function get_formatted_forms_list_form_data( $form, $results ): array {

		if ( ! ( $form instanceof WP_Post ) ) {
			return [];
		}

		$widget_slug = static::SLUG;

		$edit_url = add_query_arg(
			[
				'page'    => 'wpforms-entries',
				'view'    => 'list',
				'form_id' => absint( $form->ID ),
			],
			admin_url( 'admin.php' )
		);

		$form_data = [
			'form_id'  => $form->ID,
			'count'    => isset( $results[ $form->ID ]->count ) ? absint( $results[ $form->ID ]->count ) : 0,
			'title'    => $form->post_title,
			'edit_url' => $edit_url,
		];

		// phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName
		return (array) apply_filters( "wpforms_{$widget_slug}_form_item_fields", $form_data, $form );
	}

	/**
	 * Get the data for a chart using AJAX.
	 *
	 * @since 1.5.0
	 *
	 * @throws Exception Exception.
	 */
	public function get_chart_data_ajax() {

		check_admin_referer( 'wpforms_' . static::SLUG . '_nonce' );

		$days    = ! empty( $_POST['days'] ) ? absint( $_POST['days'] ) : 0;
		$form_id = ! empty( $_POST['form_id'] ) ? absint( $_POST['form_id'] ) : 0;

		$data = $this->get_entries_count_by( 'date', $days, $form_id );

		wp_send_json( $data );
	}

	/**
	 * Get the data for a forms' list using AJAX.
	 *
	 * @since 1.5.0
	 *
	 * @throws Exception Exception.
	 */
	public function get_forms_list_ajax() {

		check_admin_referer( 'wpforms_' . static::SLUG . '_nonce' );

		$days = ! empty( $_POST['days'] ) ? absint( $_POST['days'] ) : 0;

		ob_start();
		$this->forms_list_block( $days );
		wp_send_json( ob_get_clean() );
	}

	/**
	 * Clear dashboard widget cached data.
	 *
	 * @since 1.5.2
	 */
	public static function clear_widget_cache() {

		global $wpdb;

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$wpdb->query(
			$wpdb->prepare(
				"DELETE FROM $wpdb->options WHERE option_name LIKE %s",
				'%wpforms_' . $wpdb->esc_like( static::SLUG ) . '_pro_entries_by_%'
			)
		);
	}

	/**
	 * Get transient name for entries count by $param.
	 *
	 * @since 1.8.6
	 *
	 * @param string $param   Possible value: 'date' or 'form'.
	 * @param int    $days    Timespan (in days) to fetch the data for.
	 * @param int    $form_id Form ID to fetch the data for.
	 *
	 * @return string
	 */
	private function get_entries_transient_name( $param, $days, $form_id ): string {

		$widget_slug = static::SLUG;
		$user_id     = get_current_user_id();

		return "wpforms_{$widget_slug}_pro_entries_by_{$param}_{$days}_user_{$user_id}_form_{$form_id}";
	}
}

Filemanager

Name Type Size Permission Actions
Addons Folder 0750
Builder Folder 0750
Education Folder 0750
Entries Folder 0750
Pages Folder 0750
Settings Folder 0750
AdminBarMenu.php File 2.26 KB 0640
CoreInfoCache.php File 2.04 KB 0640
DashboardWidget.php File 31.6 KB 0640
PluginList.php File 26.46 KB 0640
PluginListDisabler.php File 1.83 KB 0640
SiteHealth.php File 4.31 KB 0640
Filemanager