1755 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			1755 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Reports API - Functions
 | |
|  *
 | |
|  * @package     EDD
 | |
|  * @subpackage  Reports
 | |
|  * @copyright   Copyright (c) 2018, Easy Digital Downloads, LLC
 | |
|  * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 | |
|  * @since       3.0
 | |
|  */
 | |
| namespace EDD\Reports;
 | |
| 
 | |
| //
 | |
| // Endpoint and report helpers.
 | |
| //
 | |
| 
 | |
| /**
 | |
|  * Registers a new endpoint to the master registry.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @see \EDD\Reports\Data\Endpoint_Registry::register_endpoint()
 | |
|  *
 | |
|  * @param string $endpoint_id Reports data endpoint ID.
 | |
|  * @param array  $attributes  {
 | |
|  *     Endpoint attributes. All arguments are required unless otherwise noted.
 | |
|  *
 | |
|  *     @type string $label    Endpoint label.
 | |
|  *     @type int    $priority Optional. Priority by which to retrieve the endpoint. Default 10.
 | |
|  *     @type array  $views {
 | |
|  *         Array of view handlers by type.
 | |
|  *
 | |
|  *         @type array $view_type {
 | |
|  *             View type slug, with array beneath it.
 | |
|  *
 | |
|  *             @type callable $data_callback    Callback used to retrieve data for the view.
 | |
|  *             @type callable $display_callback Callback used to render the view.
 | |
|  *             @type array    $display_args     Optional. Array of arguments to pass to the
 | |
|  *                                              display_callback (if any). Default empty array.
 | |
|  *         }
 | |
|  *     }
 | |
|  * }
 | |
|  * @return bool True if the endpoint was successfully registered, otherwise false.
 | |
|  */
 | |
| function register_endpoint( $endpoint_id, $attributes ) {
 | |
| 
 | |
| 	/** @var Data\Endpoint_Registry|\WP_Error $registry */
 | |
| 	$registry = EDD()->utils->get_registry( 'reports:endpoints' );
 | |
| 
 | |
| 	if ( empty( $registry ) || is_wp_error( $registry ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	try {
 | |
| 		$added = $registry->register_endpoint( $endpoint_id, $attributes );
 | |
| 
 | |
| 	} catch ( \EDD_Exception $exception ) {
 | |
| 		edd_debug_log_exception( $exception );
 | |
| 
 | |
| 		$added = false;
 | |
| 	}
 | |
| 
 | |
| 	return $added;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves and builds an endpoint object.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @see \EDD\Reports\Data\Endpoint_Registry::build_endpoint()
 | |
|  *
 | |
|  * @param string $endpoint_id Endpoint ID.
 | |
|  * @param string $view_type   View type to use when building the object.
 | |
|  * @return Data\Endpoint|\WP_Error Endpoint object on success, otherwise a WP_Error object.
 | |
|  */
 | |
| function get_endpoint( $endpoint_id, $view_type ) {
 | |
| 
 | |
| 	/** @var Data\Endpoint_Registry|\WP_Error $registry */
 | |
| 	$registry = EDD()->utils->get_registry( 'reports:endpoints' );
 | |
| 
 | |
| 	if ( empty( $registry ) || is_wp_error( $registry ) ) {
 | |
| 		return $registry;
 | |
| 	}
 | |
| 
 | |
| 	return $registry->build_endpoint( $endpoint_id, $view_type );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Registers a new report.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @see \EDD\Reports\Data\Report_Registry::add_report()
 | |
|  *
 | |
|  * @param string $report_id   Report ID.
 | |
|  * @param array  $attributes {
 | |
|  *     Reports attributes. All arguments are required unless otherwise noted.
 | |
|  *
 | |
|  *     @type string $label     Report label.
 | |
|  *     @type int    $priority  Optional. Priority by which to register the report. Default 10.
 | |
|  *     @type array  $filters   Filters available to the report.
 | |
|  *     @type array  $endpoints Endpoints to associate with the report.
 | |
|  * }
 | |
|  * @return bool True if the report was successfully registered, otherwise false.
 | |
|  */
 | |
| function add_report( $report_id, $attributes ) {
 | |
| 
 | |
| 	/** @var Data\Report_Registry|\WP_Error $registry */
 | |
| 	$registry = EDD()->utils->get_registry( 'reports' );
 | |
| 
 | |
| 	if ( empty( $registry ) || is_wp_error( $registry ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	try {
 | |
| 		$added = $registry->add_report( $report_id, $attributes );
 | |
| 
 | |
| 	} catch ( \EDD_Exception $exception ) {
 | |
| 		edd_debug_log_exception( $exception );
 | |
| 
 | |
| 		$added = false;
 | |
| 	}
 | |
| 
 | |
| 	return $added;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves and builds a report object.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @see \EDD\Reports\Data\Report_Registry::build_report()
 | |
|  *
 | |
|  * @param string $report_id       Report ID.
 | |
|  * @param bool   $build_endpoints Optional. Whether to build the endpoints (includes registering
 | |
|  *                                any endpoint dependencies, such as registering meta boxes).
 | |
|  *                                Default true.
 | |
|  * @return Data\Report|\WP_Error Report object on success, otherwise a WP_Error object.
 | |
|  */
 | |
| function get_report( $report_id = false, $build_endpoints = true ) {
 | |
| 
 | |
| 	/** @var Data\Report_Registry|\WP_Error $registry */
 | |
| 	$registry = EDD()->utils->get_registry( 'reports' );
 | |
| 
 | |
| 	if ( empty( $registry ) || is_wp_error( $registry ) ) {
 | |
| 		return $registry;
 | |
| 	}
 | |
| 
 | |
| 	return $registry->build_report( $report_id, $build_endpoints );
 | |
| }
 | |
| 
 | |
| /** Sections ******************************************************************/
 | |
| 
 | |
| /**
 | |
|  * Retrieves the list of slug/label report pairs.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @return array List of reports, otherwise an empty array.
 | |
|  */
 | |
| function get_reports() {
 | |
| 
 | |
| 	/** @var Data\Report_Registry|\WP_Error $registry */
 | |
| 	$registry = EDD()->utils->get_registry( 'reports' );
 | |
| 
 | |
| 	if ( empty( $registry ) || is_wp_error( $registry ) ) {
 | |
| 		return array();
 | |
| 	} else {
 | |
| 		$reports = $registry->get_reports( 'priority', 'core' );
 | |
| 	}
 | |
| 
 | |
| 	// Re-sort by priority.
 | |
| 	uasort( $reports, array( $registry, 'priority_sort' ) );
 | |
| 
 | |
| 	/**
 | |
| 	 * Filters the list of report slug/label pairs.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @param array $reports List of slug/label pairs as representative of reports.
 | |
| 	 */
 | |
| 	return apply_filters( 'edd_get_reports', $reports );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves the slug for the active report.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @return string The active report, or the 'overview' report if no view defined
 | |
|  */
 | |
| function get_current_report() {
 | |
| 	return isset( $_REQUEST['view'] )
 | |
| 		? sanitize_key( $_REQUEST['view'] )
 | |
| 		: 'overview'; // Hardcoded default
 | |
| }
 | |
| 
 | |
| /** Endpoints *****************************************************************/
 | |
| 
 | |
| /**
 | |
|  * Retrieves the list of supported endpoint view types and their attributes.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @return array List of supported endpoint types.
 | |
|  */
 | |
| function get_endpoint_views() {
 | |
| 	if ( ! did_action( 'edd_reports_init' ) ) {
 | |
| 		_doing_it_wrong( __FUNCTION__, 'Endpoint views cannot be retrieved prior to the firing of the edd_reports_init hook.', 'EDD 3.0' );
 | |
| 
 | |
| 		return array();
 | |
| 	}
 | |
| 
 | |
| 	/** @var Data\Endpoint_View_Registry|\WP_Error $registry */
 | |
| 	$registry = EDD()->utils->get_registry( 'reports:endpoints:views' );
 | |
| 
 | |
| 	if ( empty( $registry ) || is_wp_error( $registry ) ) {
 | |
| 		return array();
 | |
| 	} else {
 | |
| 		$views = $registry->get_endpoint_views();
 | |
| 	}
 | |
| 
 | |
| 	return $views;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves the name of the handler class for a given endpoint view.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param string $view Endpoint view.
 | |
|  * @return string Handler class name if set and the view exists, otherwise an empty string.
 | |
|  */
 | |
| function get_endpoint_handler( $view ) {
 | |
| 	$views = get_endpoint_views();
 | |
| 
 | |
| 	return isset( $views[ $view ]['handler'] )
 | |
| 		? $views[ $view ]['handler']
 | |
| 		: '';
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves the group display callback for a given endpoint view.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param string $view Endpoint view.
 | |
|  * @return string Group callback if set, otherwise an empty string.
 | |
|  */
 | |
| function get_endpoint_group_callback( $view ) {
 | |
| 	$views = get_endpoint_views();
 | |
| 
 | |
| 	return isset( $views[ $view ]['group_callback'] )
 | |
| 		? $views[ $view ]['group_callback']
 | |
| 		: '';
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Determines whether an endpoint view is valid.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param string $view Endpoint view slug.
 | |
|  * @return bool True if the view is valid, otherwise false.
 | |
|  */
 | |
| function validate_endpoint_view( $view ) {
 | |
| 	return array_key_exists( $view, get_endpoint_views() );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Parses views for an incoming endpoint.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @see get_endpoint_views()
 | |
|  *
 | |
|  * @param array  $views View slugs and attributes as dictated by get_endpoint_views().
 | |
|  *
 | |
|  * @return array (Maybe) adjusted views slugs and attributes array.
 | |
|  */
 | |
| function parse_endpoint_views( $views ) {
 | |
| 	$valid_views = get_endpoint_views();
 | |
| 
 | |
| 	foreach ( $views as $view => $attributes ) {
 | |
| 		if ( ! empty( $valid_views[ $view ]['fields'] ) ) {
 | |
| 			$fields = $valid_views[ $view ]['fields'];
 | |
| 
 | |
| 			// Merge the incoming args with the field defaults.
 | |
| 			$view_args = wp_parse_args( $attributes, $fields );
 | |
| 
 | |
| 			// Overwrite the view attributes, keeping only the valid fields.
 | |
| 			$views[ $view ] = array_intersect_key( $view_args, $fields );
 | |
| 
 | |
| 			if ( $views[ $view ]['display_callback'] === $fields['display_callback'] ) {
 | |
| 				$views[ $view ]['display_args'] = wp_parse_args( $views[ $view ]['display_args'], $fields['display_args'] );
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return $views;
 | |
| }
 | |
| 
 | |
| /** Filters *******************************************************************/
 | |
| 
 | |
| /**
 | |
|  * Retrieves the list of registered reports filters and their attributes.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @return array List of supported endpoint filters.
 | |
|  */
 | |
| function get_filters() {
 | |
| 	$filters = array(
 | |
| 		'dates'              => array(
 | |
| 			'label'            => __( 'Date', 'easy-digital-downloads' ),
 | |
| 			'display_callback' => __NAMESPACE__ . '\\display_dates_filter'
 | |
| 		),
 | |
| 		'products'           => array(
 | |
| 			'label'            => __( 'Products', 'easy-digital-downloads' ),
 | |
| 			'display_callback' => __NAMESPACE__ . '\\display_products_filter'
 | |
| 		),
 | |
| 		'product_categories' => array(
 | |
| 			'label'            => __( 'Product Categories', 'easy-digital-downloads' ),
 | |
| 			'display_callback' => __NAMESPACE__ . '\\display_product_categories_filter'
 | |
| 		),
 | |
| 		'taxes'              => array(
 | |
| 			'label'            => __( 'Exclude Taxes', 'easy-digital-downloads' ),
 | |
| 			'display_callback' => __NAMESPACE__ . '\\display_taxes_filter'
 | |
| 		),
 | |
| 		'gateways'           => array(
 | |
| 			'label'            => __( 'Gateways', 'easy-digital-downloads' ),
 | |
| 			'display_callback' => __NAMESPACE__ . '\\display_gateways_filter'
 | |
| 		),
 | |
| 		'discounts'          => array(
 | |
| 			'label'            => __( 'Discounts', 'easy-digital-downloads' ),
 | |
| 			'display_callback' => __NAMESPACE__ . '\\display_discounts_filter'
 | |
| 		),
 | |
| 		'regions'            => array(
 | |
| 			'label'            => __( 'Regions', 'easy-digital-downloads' ),
 | |
| 			'display_callback' => __NAMESPACE__ . '\\display_region_filter'
 | |
| 		),
 | |
| 		'countries'          => array(
 | |
| 			'label'            => __( 'Countries', 'easy-digital-downloads' ),
 | |
| 			'display_callback' => __NAMESPACE__ . '\\display_country_filter'
 | |
| 		),
 | |
| 		'currencies'          => array(
 | |
| 			'label'            => __( 'Currencies', 'easy-digital-downloads' ),
 | |
| 			'display_callback' => __NAMESPACE__ . '\\display_currency_filter'
 | |
| 		)
 | |
| 	);
 | |
| 
 | |
| 	/**
 | |
| 	 * Filters the list of available report filters.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @param array[] $filters
 | |
| 	 */
 | |
| 	return apply_filters( 'edd_report_filters', $filters );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Determines whether the given filter is valid.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param string $filter Filter key.
 | |
|  * @return bool True if the filter is valid, otherwise false.
 | |
|  */
 | |
| function validate_filter( $filter ) {
 | |
| 	return array_key_exists( $filter, get_filters() );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves the value of an endpoint filter for the current session and report.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param string $filter Filter key to retrieve the value for.
 | |
|  * @return mixed|string Value of the filter if it exists, otherwise an empty string.
 | |
|  */
 | |
| function get_filter_value( $filter ) {
 | |
| 	$value = '';
 | |
| 
 | |
| 	// Bail if filter does not validate
 | |
| 	if ( ! validate_filter( $filter ) ) {
 | |
| 		return $value;
 | |
| 	}
 | |
| 
 | |
| 	switch ( $filter ) {
 | |
| 		// Handle dates.
 | |
| 		case 'dates':
 | |
| 			$default_range          = 'this_month';
 | |
| 			$default_relative_range = 'previous_period';
 | |
| 
 | |
| 			if ( ! isset( $_GET['range'] ) ) {
 | |
| 				$dates   = parse_dates_for_range( $default_range );
 | |
| 				$value   = array(
 | |
| 					'range'          => $default_range,
 | |
| 					'relative_range' => $default_relative_range,
 | |
| 					'from'           => $dates['start']->format( 'Y-m-d' ),
 | |
| 					'to'             => $dates['end']->format( 'Y-m-d' ),
 | |
| 				);
 | |
| 			} else {
 | |
| 				$value = array(
 | |
| 					'range' => isset( $_GET['range'] )
 | |
| 						? sanitize_text_field( $_GET['range'] )
 | |
| 						: $default_range,
 | |
| 					'relative_range' => isset( $_GET['relative_range'] )
 | |
| 						? sanitize_text_field( $_GET['relative_range'] )
 | |
| 						: $default_relative_range,
 | |
| 					'from' => isset( $_GET['filter_from'] )
 | |
| 						? sanitize_text_field( $_GET['filter_from'] )
 | |
| 						: '',
 | |
| 					'to'   => isset( $_GET['filter_to'] )
 | |
| 						? sanitize_text_field( $_GET['filter_to'] )
 | |
| 						: ''
 | |
| 				);
 | |
| 			}
 | |
| 
 | |
| 			break;
 | |
| 
 | |
| 		// Handle taxes.
 | |
| 		case 'taxes':
 | |
| 			$value = array();
 | |
| 
 | |
| 			if ( isset( $_GET['exclude_taxes'] ) ) {
 | |
| 				$value['exclude_taxes'] = true;
 | |
| 			}
 | |
| 
 | |
| 			break;
 | |
| 
 | |
| 		// Handle default (direct from URL).
 | |
| 		default:
 | |
| 			$value = isset( $_GET[ $filter ] )
 | |
| 				? sanitize_text_field( $_GET[ $filter ] )
 | |
| 				: '';
 | |
| 
 | |
| 			/**
 | |
| 			 * Filters the value of a report filter.
 | |
| 			 *
 | |
| 			 * @since 3.0
 | |
| 			 *
 | |
| 			 * @param string $value Report filter value.
 | |
| 			 * @param string $filter Report filter.
 | |
| 			 */
 | |
| 			$value = apply_filters( 'edd_reports_get_filter_value', $value, $filter );
 | |
| 	}
 | |
| 
 | |
| 	return $value;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Returns a list of registered report filters that should be persisted across views.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @return array
 | |
|  */
 | |
| function get_persisted_filters() {
 | |
| 	$filters = array(
 | |
| 		'range',
 | |
| 		'relative_range',
 | |
| 		'filter_from',
 | |
| 		'filter_to',
 | |
| 		'exclude_taxes',
 | |
| 	);
 | |
| 
 | |
| 	/**
 | |
| 	 * Filters registered report filters that should be persisted across views.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @param array $filters List of registered filters to persist.
 | |
| 	 */
 | |
| 	$filters = apply_filters( 'edd_reports_get_persisted_filters', $filters );
 | |
| 
 | |
| 	return $filters;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves key/label pairs of date filter options for use in a drop-down.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @return array Key/label pairs of date filter options.
 | |
|  */
 | |
| function get_dates_filter_options() {
 | |
| 	static $options = null;
 | |
| 
 | |
| 	if ( is_null( $options ) ) {
 | |
| 		$options = array(
 | |
| 			'other'        => __( 'Custom', 'easy-digital-downloads' ),
 | |
| 			'today'        => __( 'Today', 'easy-digital-downloads' ),
 | |
| 			'yesterday'    => __( 'Yesterday', 'easy-digital-downloads' ),
 | |
| 			'this_week'    => __( 'This Week', 'easy-digital-downloads' ),
 | |
| 			'last_week'    => __( 'Last Week', 'easy-digital-downloads' ),
 | |
| 			'last_30_days' => __( 'Last 30 Days', 'easy-digital-downloads' ),
 | |
| 			'this_month'   => __( 'Month to Date', 'easy-digital-downloads' ),
 | |
| 			'last_month'   => __( 'Last Month', 'easy-digital-downloads' ),
 | |
| 			'this_quarter' => __( 'Quarter to Date', 'easy-digital-downloads' ),
 | |
| 			'last_quarter' => __( 'Last Quarter', 'easy-digital-downloads' ),
 | |
| 			'this_year'    => __( 'Year to Date', 'easy-digital-downloads' ),
 | |
| 			'last_year'    => __( 'Last Year', 'easy-digital-downloads' ),
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Filters the list of key/label pairs of date filter options.
 | |
| 	 *
 | |
| 	 * @since 1.3
 | |
| 	 *
 | |
| 	 * @param array $date_options Date filter options.
 | |
| 	 */
 | |
| 	return apply_filters( 'edd_report_date_options', $options );
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Retrieves the default relative range key for a specific range.
 | |
|  *
 | |
|  * @since 3.1
 | |
|  *
 | |
|  * @return string Relative date range key.
 | |
|  */
 | |
| function get_default_relative_range( $range ) {
 | |
| 
 | |
| 	switch ( $range ) {
 | |
| 		case 'this_month':
 | |
| 		case 'last_month':
 | |
| 			$relative_range = 'previous_month';
 | |
| 			break;
 | |
| 
 | |
| 		case 'this_quarter':
 | |
| 		case 'last_quarter':
 | |
| 			$relative_range = 'previous_quarter';
 | |
| 			break;
 | |
| 
 | |
| 		case 'this_year':
 | |
| 		case 'last_year':
 | |
| 			$relative_range = 'previous_year';
 | |
| 			break;
 | |
| 
 | |
| 		default:
 | |
| 			$relative_range = 'previous_period';
 | |
| 			break;
 | |
| 	}
 | |
| 
 | |
| 	return $relative_range;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Retrieves key/label pairs of relative date filter options for use in a drop-down.
 | |
|  *
 | |
|  * @since 3.1
 | |
|  *
 | |
|  * @return array Key/label pairs of relative date filter options.
 | |
|  */
 | |
| function get_relative_dates_filter_options() {
 | |
| 	static $options = null;
 | |
| 
 | |
| 	if ( is_null( $options ) ) {
 | |
| 		$options = array(
 | |
| 			'previous_period'  => __( 'Previous period', 'easy-digital-downloads' ),
 | |
| 			'previous_month'   => __( 'Previous month', 'easy-digital-downloads' ),
 | |
| 			'previous_quarter' => __( 'Previous quarter', 'easy-digital-downloads' ),
 | |
| 			'previous_year'    => __( 'Previous year', 'easy-digital-downloads' ),
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	return $options;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves the start and end date filters for use with the Reports API.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param string $values   Optional. What format to retrieve dates in the resulting array in.
 | |
|  *                         Accepts 'strings' or 'objects'. Default 'strings'.
 | |
|  * @param string $timezone Optional. Timezone to force for filter dates. Primarily used for
 | |
|  *                         legacy testing purposes. Default empty.
 | |
|  * @return array|\EDD\Utils\Date[] {
 | |
|  *     Query date range for the current graph filter request.
 | |
|  *
 | |
|  *     @type string|\EDD\Utils\Date $start Start day and time (based on the beginning of the given day).
 | |
|  *                                         If `$values` is 'objects', a Carbon object, otherwise a date
 | |
|  *                                         time string.
 | |
|  *     @type string|\EDD\Utils\Date $end   End day and time (based on the end of the given day). If `$values`
 | |
|  *                                         is 'objects', a Carbon object, otherwise a date time string.
 | |
|  * }
 | |
|  */
 | |
| function get_dates_filter( $values = 'strings', $timezone = null ) {
 | |
| 	$dates = parse_dates_for_range();
 | |
| 
 | |
| 	if ( 'strings' === $values ) {
 | |
| 		if ( ! empty( $dates['start'] ) ) {
 | |
| 			$dates['start'] = $dates['start']->toDateTimeString();
 | |
| 		}
 | |
| 		if ( ! empty( $dates['end'] ) ) {
 | |
| 			$dates['end'] = $dates['end']->toDateTimeString();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Filters the start and end date filters for use with the Graphs API.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @param array|\EDD\Utils\Date[] $dates {
 | |
| 	 *     Query date range for the current graph filter request.
 | |
| 	 *
 | |
| 	 *     @type string|\EDD\Utils\Date $start Start day and time (based on the beginning of the given day).
 | |
| 	 *                                         If `$values` is 'objects', a Date object, otherwise a date
 | |
| 	 *                                         time string.
 | |
| 	 *     @type string|\EDD\Utils\Date $end   End day and time (based on the end of the given day). If `$values`
 | |
| 	 *                                         is 'objects', a Date object, otherwise a date time string.
 | |
| 	 * }
 | |
| 	 */
 | |
| 	return apply_filters( 'edd_get_dates_filter', $dates );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Parses start and end dates for the given range.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param string          $range          Optional. Range value to generate start and end dates for against `$date`.
 | |
|  *                                        Default is the current range as derived from the session.
 | |
|  * @param string          $date           Date string converted to `\EDD\Utils\Date` to anchor calculations to.
 | |
|  * @param bool            $convert_to_utc Optional. If we should convert the results to UTC for Database Queries
 | |
|  * @return \EDD\Utils\Date[] Array of start and end date objects.
 | |
|  */
 | |
| function parse_dates_for_range( $range = null, $date = 'now', $convert_to_utc = true ) {
 | |
| 
 | |
| 	// Set the time ranges in the user's timezone, so they ultimately see them in their own timezone.
 | |
| 	$date = EDD()->utils->date( $date, edd_get_timezone_id(), false );
 | |
| 
 | |
| 	if ( null === $range || ! array_key_exists( $range, get_dates_filter_options() ) ) {
 | |
| 		$range = get_dates_filter_range();
 | |
| 	}
 | |
| 
 | |
| 	switch ( $range ) {
 | |
| 
 | |
| 		case 'this_month':
 | |
| 			$dates = array(
 | |
| 				'start' => $date->copy()->startOfMonth(),
 | |
| 				'end'   => $date->copy()->endOfDay(),
 | |
| 			);
 | |
| 			break;
 | |
| 
 | |
| 		case 'last_month':
 | |
| 			$dates = array(
 | |
| 				'start' => $date->copy()->subMonthNoOverflow( 1 )->startOfMonth(),
 | |
| 				'end'   => $date->copy()->subMonthNoOverflow( 1 )->endOfMonth(),
 | |
| 			);
 | |
| 			break;
 | |
| 
 | |
| 		case 'today':
 | |
| 			$dates = array(
 | |
| 				'start' => $date->copy()->startOfDay(),
 | |
| 				'end'   => $date->copy()->endOfDay(),
 | |
| 			);
 | |
| 			break;
 | |
| 
 | |
| 		case 'yesterday':
 | |
| 			$dates = array(
 | |
| 				'start' => $date->copy()->subDay( 1 )->startOfDay(),
 | |
| 				'end'   => $date->copy()->subDay( 1 )->endOfDay(),
 | |
| 			);
 | |
| 			break;
 | |
| 
 | |
| 		case 'this_week':
 | |
| 			$dates = array(
 | |
| 				'start' => $date->copy()->startOfWeek(),
 | |
| 				'end'   => $date->copy()->endOfDay(),
 | |
| 			);
 | |
| 			break;
 | |
| 
 | |
| 		case 'last_week':
 | |
| 			$dates = array(
 | |
| 				'start' => $date->copy()->subWeek( 1 )->startOfWeek(),
 | |
| 				'end'   => $date->copy()->subWeek( 1 )->endOfWeek(),
 | |
| 			);
 | |
| 			break;
 | |
| 
 | |
| 		case 'last_30_days':
 | |
| 			$dates = array(
 | |
| 				'start' => $date->copy()->subDay( 30 )->startOfDay(),
 | |
| 				'end'   => $date->copy()->endOfDay(),
 | |
| 			);
 | |
| 			break;
 | |
| 
 | |
| 		case 'this_quarter':
 | |
| 			$dates = array(
 | |
| 				'start' => $date->copy()->startOfQuarter(),
 | |
| 				'end'   => $date->copy()->endOfDay(),
 | |
| 			);
 | |
| 			break;
 | |
| 
 | |
| 		case 'last_quarter':
 | |
| 			$dates = array(
 | |
| 				'start' => $date->copy()->subQuarter( 1 )->startOfQuarter(),
 | |
| 				'end'   => $date->copy()->subQuarter( 1 )->endOfQuarter(),
 | |
| 			);
 | |
| 			break;
 | |
| 
 | |
| 		case 'this_year':
 | |
| 			$dates = array(
 | |
| 				'start' => $date->copy()->startOfYear(),
 | |
| 				'end'   => $date->copy()->endOfDay(),
 | |
| 			);
 | |
| 			break;
 | |
| 
 | |
| 		case 'last_year':
 | |
| 			$dates = array(
 | |
| 				'start' => $date->copy()->subYear( 1 )->startOfYear(),
 | |
| 				'end'   => $date->copy()->subYear( 1 )->endOfYear(),
 | |
| 			);
 | |
| 			break;
 | |
| 
 | |
| 		case 'other':
 | |
| 		default:
 | |
| 			$dates_from_report = get_filter_value( 'dates' );
 | |
| 
 | |
| 			if ( ! empty( $dates_from_report ) ) {
 | |
| 				$start = $dates_from_report['from'];
 | |
| 				$end   = $dates_from_report['to'];
 | |
| 			} else {
 | |
| 				$start = $end = 'now';
 | |
| 			}
 | |
| 
 | |
| 			$dates = array(
 | |
| 				'start' => EDD()->utils->date( $start, edd_get_timezone_id(), false )->startOfDay(),
 | |
| 				'end'   => EDD()->utils->date( $end, edd_get_timezone_id(), false )->endOfDay(),
 | |
| 			);
 | |
| 			break;
 | |
| 	}
 | |
| 
 | |
| 	if ( $convert_to_utc ) {
 | |
| 		// Convert the values to the UTC equivalent so that we can query the database using UTC.
 | |
| 		$dates['start'] = edd_get_utc_equivalent_date( $dates['start'] );
 | |
| 		$dates['end']   = edd_get_utc_equivalent_date( $dates['end'] );
 | |
| 	}
 | |
| 
 | |
| 	$dates['range'] = $range;
 | |
| 
 | |
| 	return $dates;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Parses relative start and end dates for the given range.
 | |
|  *
 | |
|  * @since 3.1
 | |
|  *
 | |
|  * @param string          $range          Optional. Range value to generate start and end dates for against `$date`.
 | |
|  * @param string          $relative_range Optional. Range value to generate relative start and end dates for against `$date`.
 | |
|  *                                        Default is the current range as derived from the session.
 | |
|  * @param string          $date           Date string converted to `\EDD\Utils\Date` to anchor calculations to.
 | |
|  * @param bool            $convert_to_utc Optional. If we should convert the results to UTC for Database Queries
 | |
|  * @return \EDD\Utils\Date[] Array of start and end date objects.
 | |
|  */
 | |
| function parse_relative_dates_for_range( $range = null, $relative_range = null, $date = 'now', $convert_to_utc = true ) {
 | |
| 
 | |
| 	// Set the time ranges in the user's timezone, so they ultimately see them in their own timezone.
 | |
| 	$date = EDD()->utils->date( $date, edd_get_timezone_id(), false );
 | |
| 
 | |
| 	if ( null === $range || ! array_key_exists( $range, get_dates_filter_options() ) ) {
 | |
| 		$range = get_dates_filter_range();
 | |
| 	}
 | |
| 
 | |
| 	if ( null === $relative_range || ! array_key_exists( $relative_range, get_relative_dates_filter_options() ) ) {
 | |
| 		$relative_range = get_relative_dates_filter_range();
 | |
| 	}
 | |
| 
 | |
| 	$dates = parse_dates_for_range( $range, $date, false );
 | |
| 
 | |
| 	switch ( $relative_range ) {
 | |
| 		case 'previous_period':
 | |
| 			$days_diff = $dates['start']->copy()->diffInDays( $dates['end'], true ) + 1;
 | |
| 			$dates     = array(
 | |
| 				'start' => $dates['start']->copy()->subDays( $days_diff ),
 | |
| 				'end'   => $dates['end']->copy()->subDays( $days_diff ),
 | |
| 			);
 | |
| 			break;
 | |
| 		case 'previous_month':
 | |
| 			$dates = array(
 | |
| 				'start' => $dates['start']->copy()->subMonth( 1 ),
 | |
| 				'end'   => $dates['end']->copy()->subMonth( 1 ),
 | |
| 			);
 | |
| 			break;
 | |
| 		case 'previous_quarter':
 | |
| 			$dates = array(
 | |
| 				'start' => $dates['start']->copy()->subQuarter( 1 ),
 | |
| 				'end'   => $dates['end']->copy()->subQuarter( 1 ),
 | |
| 			);
 | |
| 			break;
 | |
| 		case 'previous_year':
 | |
| 			$dates = array(
 | |
| 				'start' => $dates['start']->copy()->subYear( 1 ),
 | |
| 				'end'   => $dates['end']->copy()->subYear( 1 ),
 | |
| 			);
 | |
| 			break;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	if ( $convert_to_utc ) {
 | |
| 		// Convert the values to the UTC equivalent so that we can query the database using UTC.
 | |
| 		$dates['start'] = edd_get_utc_equivalent_date( $dates['start'] );
 | |
| 		$dates['end']   = edd_get_utc_equivalent_date( $dates['end'] );
 | |
| 	}
 | |
| 
 | |
| 	$dates['range'] = $range;
 | |
| 
 | |
| 	return $dates;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves the date filter range.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @return string Date filter range.
 | |
|  */
 | |
| function get_dates_filter_range() {
 | |
| 
 | |
| 	$dates = get_filter_value( 'dates' );
 | |
| 
 | |
| 	if ( isset( $dates['range'] ) ) {
 | |
| 		$range = sanitize_key( $dates['range'] );
 | |
| 
 | |
| 	} else {
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters the report dates default range.
 | |
| 		 *
 | |
| 		 * @since 1.3
 | |
| 		 *
 | |
| 		 * @param string $range Date range as derived from the session. Default 'last_30_days'
 | |
| 		 * @param array  $dates Dates filter data array.
 | |
| 		 */
 | |
| 		$range = apply_filters( 'edd_get_report_dates_default_range', 'this_month', $dates );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Filters the dates filter range.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @param string $range Dates filter range.
 | |
| 	 * @param array  $dates Dates filter data array.
 | |
| 	 */
 | |
| 	return apply_filters( 'edd_get_dates_filter_range', $range, $dates );
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Retrieves the date filter for relative range.
 | |
|  *
 | |
|  * @since 3.1
 | |
|  *
 | |
|  * @return string Date filter range.
 | |
|  */
 | |
| function get_relative_dates_filter_range() {
 | |
| 
 | |
| 	$dates = get_filter_value( 'dates' );
 | |
| 
 | |
| 	if ( isset( $dates['relative_range'] ) ) {
 | |
| 		$relative_range = sanitize_key( $dates['relative_range'] );
 | |
| 	} else {
 | |
| 
 | |
| 		/**
 | |
| 		 * Filters the report dates default range.
 | |
| 		 *
 | |
| 		 * @since 3.1
 | |
| 		 *
 | |
| 		 * @param string $range Relative daate range as derived from the session. Default 'previous_period'
 | |
| 		 * @param array  $dates Dates filter data array.
 | |
| 		 */
 | |
| 		$relative_range = apply_filters( 'edd_get_report_dates_default_relative_range', 'previous_period', $dates );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Filters the dates filter range.
 | |
| 	 *
 | |
| 	 * @since 3.1
 | |
| 	 *
 | |
| 	 * @param string $range Dates filter relative range.
 | |
| 	 * @param array  $dates Dates filter data array.
 | |
| 	 */
 | |
| 	return apply_filters( 'edd_get_dates_filter_relative_range', $relative_range, $dates );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Determines whether results should be displayed hour by hour, or not.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @return bool True if results should use hour by hour, otherwise false.
 | |
|  */
 | |
| function get_dates_filter_hour_by_hour() {
 | |
| 	$hour_by_hour = false;
 | |
| 
 | |
| 	// Retrieve the queried dates.
 | |
| 	$dates = get_dates_filter( 'objects' );
 | |
| 
 | |
| 	// Determine graph options.
 | |
| 	switch ( $dates['range'] ) {
 | |
| 		case 'today':
 | |
| 		case 'yesterday':
 | |
| 			$hour_by_hour = true;
 | |
| 			break;
 | |
| 		case 'this_week':
 | |
| 		case 'this_month':
 | |
| 		case 'this_quarter':
 | |
| 		case 'this_year':
 | |
| 		case 'other':
 | |
| 			$difference = ( $dates['end']->getTimestamp() - $dates['start']->getTimestamp() );
 | |
| 			if ( $difference <= ( DAY_IN_SECONDS * 2 ) ) {
 | |
| 				$hour_by_hour = true;
 | |
| 			}
 | |
| 			break;
 | |
| 		default:
 | |
| 			$hour_by_hour = false;
 | |
| 			break;
 | |
| 	}
 | |
| 
 | |
| 	return $hour_by_hour;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Determines whether results should be displayed day by day or not.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @return bool True if results should use day by day, otherwise false.
 | |
|  */
 | |
| function get_dates_filter_day_by_day() {
 | |
| 	// Retrieve the queried dates
 | |
| 	$dates = get_dates_filter( 'objects' );
 | |
| 
 | |
| 	// Determine graph options
 | |
| 	switch ( $dates['range'] ) {
 | |
| 		case 'today':
 | |
| 		case 'yesterday':
 | |
| 		case 'this_year':
 | |
| 		case 'last_year':
 | |
| 			$day_by_day = false;
 | |
| 			break;
 | |
| 		case 'other':
 | |
| 			$difference = ( $dates['end']->getTimestamp() - $dates['start']->getTimestamp() );
 | |
| 
 | |
| 			if ( $difference >= ( YEAR_IN_SECONDS / 4 ) ) {
 | |
| 				$day_by_day = false;
 | |
| 			} else {
 | |
| 				$day_by_day = true;
 | |
| 			}
 | |
| 			break;
 | |
| 		default:
 | |
| 			$day_by_day = true;
 | |
| 			break;
 | |
| 	}
 | |
| 
 | |
| 	return $day_by_day;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Given a function and column, make a timezone converted groupby query.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  * @since 3.0.4 If MONTH is passed as the function, always add YEAR and MONTH
 | |
|  *              to avoid issues with spanning multiple years.
 | |
|  *
 | |
|  * @param string $function The function to run the value through, like DATE, HOUR, MONTH.
 | |
|  * @param string $column   The column to group by.
 | |
|  *
 | |
|  * @return string
 | |
|  */
 | |
| function get_groupby_date_string( $function = 'DATE', $column = 'date_created' ) {
 | |
| 	$function   = strtoupper( $function );
 | |
| 	$date       = EDD()->utils->date( 'now', edd_get_timezone_id(), false );
 | |
| 	$gmt_offset = $date->getOffset();
 | |
| 
 | |
| 	if ( empty( $gmt_offset ) ) {
 | |
| 
 | |
| 		switch ( $function ) {
 | |
| 			case 'HOUR':
 | |
| 				$group_by_string = "DAY({$column}), HOUR({$column})";
 | |
| 				break;
 | |
| 			case 'MONTH':
 | |
| 				$group_by_string = "YEAR({$column}), MONTH({$column})";
 | |
| 				break;
 | |
| 			default:
 | |
| 				$group_by_string = "{$function}({$column})";
 | |
| 				break;
 | |
| 		}
 | |
| 
 | |
| 		return $group_by_string;
 | |
| 	}
 | |
| 
 | |
| 	// Output the offset in the proper format.
 | |
| 	$hours   = abs( floor( $gmt_offset / HOUR_IN_SECONDS ) );
 | |
| 	$minutes = abs( floor( ( $gmt_offset / MINUTE_IN_SECONDS ) % MINUTE_IN_SECONDS ) );
 | |
| 	$math    = ( $gmt_offset >= 0 ) ? '+' : '-';
 | |
| 
 | |
| 	$formatted_offset = ! empty( $minutes ) ? "{$hours}:{$minutes}" : $hours . ':00';
 | |
| 
 | |
| 	/**
 | |
| 	 * There is a limitation here that we cannot get past due to MySQL not having timezone information.
 | |
| 	 *
 | |
| 	 * When a requested date group spans the DST change. For instance, a 6 month graph will have slightly
 | |
| 	 * different results for each month than if you pulled each of those 6 months individually. This is because
 | |
| 	 * our 'grouping' can only convert the timezone based on the current offset and that can change if the
 | |
| 	 * range spans the DST break, which would have some dates be in a +/- 1 hour state.
 | |
| 	 *
 | |
| 	 * @see https://github.com/awesomemotive/easy-digital-downloads/pull/9449
 | |
| 	 */
 | |
| 	$column_conversion = "CONVERT_TZ({$column}, '+0:00', '{$math}{$formatted_offset}')";
 | |
| 	switch ( $function ) {
 | |
| 		case 'HOUR':
 | |
| 			$group_by_string = "DAY({$column_conversion}), HOUR({$column_conversion})";
 | |
| 			break;
 | |
| 		case 'MONTH':
 | |
| 			$group_by_string = "YEAR({$column_conversion}), MONTH({$column_conversion})";
 | |
| 			break;
 | |
| 		default:
 | |
| 			$group_by_string = "{$function}({$column_conversion})";
 | |
| 			break;
 | |
| 	}
 | |
| 
 | |
| 	return $group_by_string;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Retrieves the tax exclusion filter.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @return bool True if taxes should be excluded from calculations.
 | |
|  */
 | |
| function get_taxes_excluded_filter() {
 | |
| 	$taxes = get_filter_value( 'taxes' );
 | |
| 
 | |
| 	if ( ! isset( $taxes['exclude_taxes'] ) ) {
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	return (bool) $taxes['exclude_taxes'];
 | |
| }
 | |
| 
 | |
| /** Display *******************************************************************/
 | |
| 
 | |
| /**
 | |
|  * Handles display of a report.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param Data\Report $report Report object.
 | |
|  */
 | |
| function default_display_report( $report ) {
 | |
| 
 | |
| 	// Bail if erroneous report
 | |
| 	if ( empty( $report ) || is_wp_error( $report ) ) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	// Try to output: tiles, tables, and charts
 | |
| 	$report->display_endpoint_group( 'tiles'  );
 | |
| 	$report->display_endpoint_group( 'tables' );
 | |
| 	$report->display_endpoint_group( 'charts' );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Displays the default content for a tile endpoint.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param Data\Report $report Report object the tile endpoint is being rendered in.
 | |
|  *                            Not always set.
 | |
|  * @param array       $tile   {
 | |
|  *     Tile display arguments.
 | |
|  *
 | |
|  *     @type Data\Tile_Endpoint $endpoint     Endpoint object.
 | |
|  *     @type mixed|array        $data         Date for display. By default, will be an array,
 | |
|  *                                            but can be of other types.
 | |
|  *     @type array              $display_args Array of any display arguments.
 | |
|  * }
 | |
|  * @return void Meta box display callbacks only echo output.
 | |
|  */
 | |
| function default_display_tile( $endpoint, $data, $args ) {
 | |
| 	echo '<div class="tile-label">' . esc_html( $endpoint->get_label() ) . '</div>';
 | |
| 
 | |
| 	if ( empty( $data ) ) {
 | |
| 		echo '<div class="tile-no-data tile-value">—</div>';
 | |
| 	} else {
 | |
| 		switch ( $args['type'] ) {
 | |
| 			case 'number':
 | |
| 				echo '<div class="tile-number tile-value">' . edd_format_amount( $data ) . '</div>';
 | |
| 				break;
 | |
| 
 | |
| 			case 'split-number':
 | |
| 				printf( '<div class="tile-amount tile-value">%1$d / %2$d</div>',
 | |
| 					edd_format_amount( $data['first_value'] ),
 | |
| 					edd_format_amount( $data['second_value'] )
 | |
| 				);
 | |
| 				break;
 | |
| 
 | |
| 			case 'split-amount':
 | |
| 				printf( '<div class="tile-amount tile-value">%1$d / %2$d</div>',
 | |
| 					edd_currency_filter( edd_format_amount( $data['first_value'] ) ),
 | |
| 					edd_currency_filter( edd_format_amount( $data['second_value'] ) )
 | |
| 				);
 | |
| 				break;
 | |
| 
 | |
| 			case 'relative':
 | |
| 				$direction = ( ! empty( $data['direction'] ) && in_array( $data['direction'], array( 'up', 'down' ), true ) )
 | |
| 					? '-' . sanitize_key( $data['direction'] )
 | |
| 					: '';
 | |
| 				echo '<div class="tile-change' . esc_attr( $direction ) . ' tile-value">' . edd_format_amount( $data['value'] ) . '</div>';
 | |
| 				break;
 | |
| 
 | |
| 			case 'amount':
 | |
| 				echo '<div class="tile-amount tile-value">' . edd_currency_filter( edd_format_amount( $data ) ) . '</div>';
 | |
| 				break;
 | |
| 
 | |
| 			case 'url':
 | |
| 				echo '<div class="tile-url tile-value">' . esc_url( $data ) . '</div>';
 | |
| 				break;
 | |
| 
 | |
| 			default:
 | |
| 				$tags = wp_kses_allowed_html( 'post' );
 | |
| 				echo '<div class="tile-value tile-default">' . wp_kses( $data, $tags ) . '</div>';
 | |
| 				break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if ( ! empty( $args['comparison_label'] ) ) {
 | |
| 		echo '<div class="tile-compare">' . esc_attr( $args['comparison_label'] ) . '</div>';
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles default display of all tile endpoints registered against a report.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param Data\Report $report Report object.
 | |
|  */
 | |
| function default_display_tiles_group( $report ) {
 | |
| 	if ( ! $report->has_endpoints( 'tiles' ) ) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	$tiles = $report->get_endpoints( 'tiles' );
 | |
| ?>
 | |
| 
 | |
| 	<div id="edd-reports-tiles-wrap" class="edd-report-wrap">
 | |
| 		<?php
 | |
| 		foreach ( $tiles as $endpoint_id => $tile ) :
 | |
| 			$tile->display();
 | |
| 		endforeach;
 | |
| 		?>
 | |
| 	</div>
 | |
| 
 | |
| 	<?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles default display of all table endpoints registered against a report.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param Data\Report $report Report object.
 | |
|  */
 | |
| function default_display_tables_group( $report ) {
 | |
| 	if ( ! $report->has_endpoints( 'tables' ) ) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	$tables = $report->get_endpoints( 'tables' ); ?>
 | |
| 
 | |
| 	<div id="edd-reports-tables-wrap" class="edd-report-wrap"><?php
 | |
| 
 | |
| 		foreach ( $tables as $endpoint_id => $table ) :
 | |
| 
 | |
| 			?><div class="edd-reports-table" id="edd-reports-table-<?php echo esc_attr( $endpoint_id ); ?>">
 | |
| 				<h3><?php echo esc_html( $table->get_label() ); ?></h3><?php
 | |
| 
 | |
| 				$table->display();
 | |
| 
 | |
| 			?></div><?php
 | |
| 
 | |
| 		endforeach;
 | |
| 
 | |
| 	?><div class="clear"></div></div><?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles default display of all chart endpoints registered against a report.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param Data\Report $report Report object.
 | |
|  */
 | |
| function default_display_charts_group( $report ) {
 | |
| 	if ( ! $report->has_endpoints( 'charts' ) ) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	?>
 | |
| 	<div id="edd-reports-charts-wrap" class="edd-report-wrap">
 | |
| 	<?php
 | |
| 
 | |
| 	$charts = $report->get_endpoints( 'charts' );
 | |
| 
 | |
| 	foreach ( $charts as $endpoint_id => $chart ) {
 | |
| 		?>
 | |
| 		<div class="edd-reports-chart edd-reports-chart-<?php echo esc_attr( $chart->get_type() ); ?>" id="edd-reports-table-<?php echo esc_attr( $endpoint_id ); ?>">
 | |
| 			<h3><?php echo esc_html( $chart->get_label() ); ?></h3>
 | |
| 
 | |
| 			<?php $chart->display(); ?>
 | |
| 		</div>
 | |
| 		<?php
 | |
| 	}
 | |
| 	?>
 | |
| 		<div class="chart-timezone">
 | |
| 			<?php printf( esc_html__( 'Chart time zone: %s', 'easy-digital-downloads' ), esc_html( edd_get_timezone_id() ) ); ?>
 | |
| 		</div>
 | |
| 	</div>
 | |
| 	<?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles display of the 'Date' filter for reports.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  */
 | |
| function display_dates_filter() {
 | |
| 	$date_format            = get_option( 'date_format' );
 | |
| 	$range_options          = get_dates_filter_options();
 | |
| 	$relative_range_options = get_relative_dates_filter_options();
 | |
| 	$dates                  = get_filter_value( 'dates' );
 | |
| 	$selected_range         = isset( $dates['range'] )
 | |
| 		? $dates['range']
 | |
| 		: get_dates_filter_range();
 | |
| 
 | |
| 	$selected_relative_range = isset( $dates['relative_range'] )
 | |
| 		? $dates['relative_range']
 | |
| 		: get_relative_dates_filter_range();
 | |
| 
 | |
| 	$class = ( 'other' !== $selected_range )
 | |
| 		? ' screen-reader-text'
 | |
| 		: '';
 | |
| 
 | |
| 	$range_select = EDD()->html->select(
 | |
| 		array(
 | |
| 			'name'             => 'range',
 | |
| 			'class'            => 'edd-graphs-date-options',
 | |
| 			'options'          => $range_options,
 | |
| 			'variations'       => false,
 | |
| 			'show_option_all'  => false,
 | |
| 			'show_option_none' => false,
 | |
| 			'selected'         => $selected_range,
 | |
| 		)
 | |
| 	);
 | |
| 
 | |
| 	$relative_range_select = EDD()->html->select(
 | |
| 		array(
 | |
| 			'name'             => 'relative_range',
 | |
| 			'class'            => 'edd-graphs-relative-date-options',
 | |
| 			'options'          => $relative_range_options,
 | |
| 			'variations'       => false,
 | |
| 			'show_option_all'  => false,
 | |
| 			'show_option_none' => false,
 | |
| 			'selected'         => $selected_relative_range,
 | |
| 		)
 | |
| 	);
 | |
| 
 | |
| 	// From.
 | |
| 	$from = EDD()->html->date_field(
 | |
| 		array(
 | |
| 			'id'          => 'filter_from',
 | |
| 			'name'        => 'filter_from',
 | |
| 			'value'       => ( empty( $dates['from'] ) || ( 'other' !== $dates['range'] ) ) ? '' : $dates['from'],
 | |
| 			'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' ),
 | |
| 		)
 | |
| 	);
 | |
| 
 | |
| 	// To.
 | |
| 	$to = EDD()->html->date_field(
 | |
| 		array(
 | |
| 			'id'          => 'filter_to',
 | |
| 			'name'        => 'filter_to',
 | |
| 			'value'       => ( empty( $dates['to'] ) || ( 'other' !== $dates['range'] ) ) ? '' : $dates['to'],
 | |
| 			'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' ),
 | |
| 		)
 | |
| 	);
 | |
| 
 | |
| 	// Output fields
 | |
| 	?>
 | |
| 	<div class="edd-date-range-picker graph-option-section" data-range="<?php echo esc_attr( $selected_range ); ?>">
 | |
| 		<?php echo $range_select; ?>
 | |
| 		<!-- DATE RANGES -->
 | |
| 		<div class="edd-date-range-dates">
 | |
| 			<span class="dashicons dashicons-calendar edd-date-main-icon"></span>
 | |
| 			<div class="edd-date-range-selected-date">
 | |
| 				<?php
 | |
| 				foreach ( $range_options as $range_key => $range_name ) :
 | |
| 					$range_dates          = \EDD\Reports\parse_dates_for_range( $range_key );
 | |
| 					$selected_range_class = ( $selected_range !== $range_key ) ? 'hidden' : '';
 | |
| 					$start_date           = edd_get_edd_timezone_equivalent_date_from_utc( $range_dates['start'] )->format( $date_format );
 | |
| 					$end_date             = edd_get_edd_timezone_equivalent_date_from_utc( $range_dates['end'] )->format( $date_format );
 | |
| 					$label                = $start_date;
 | |
| 					if ( $start_date !== $end_date ) {
 | |
| 						$label = $start_date . ' - ' . $end_date;
 | |
| 					}
 | |
| 					?>
 | |
| 					<span class="<?php echo esc_attr( $selected_range_class ); ?>" data-range="<?php echo esc_attr( $range_key ); ?>" data-default-relative-range="<?php echo \EDD\Reports\get_default_relative_range( $range_key ); ?>"><?php echo esc_html( $label ); ?></span>
 | |
| 					<?php
 | |
| 				endforeach;
 | |
| 				?>
 | |
| 			</div>
 | |
| 		</div>
 | |
| 		<!-- RELATIVE DATE RANGES -->
 | |
| 		<div class="edd-date-range-relative-dates">
 | |
| 			<div class="hidden"><?php echo $relative_range_select; ?></div>
 | |
| 
 | |
| 			<?php echo esc_html__( 'compared to', 'easy-digital-downloads' ); ?>
 | |
| 
 | |
| 			<div class="edd-date-range-selected-relative-date">
 | |
| 				<span class="edd-date-range-selected-relative-range-name"><?php echo esc_html( $relative_range_options[ $selected_relative_range ] ); ?></span>
 | |
| 				<img src="<?php echo esc_url( EDD_PLUGIN_URL . '/assets/images/icons/icon-chevron-down.svg' ); ?>" class="arrow-down">
 | |
| 
 | |
| 				<!-- RELATIVE DATE RANGES DROPDOWN -->
 | |
| 				<div class="edd-date-range-relative-dropdown">
 | |
| 					<?php echo \EDD\Reports\display_relative_dates_dropdown_options( $selected_range, $selected_relative_range ); ?>
 | |
| 				</div>
 | |
| 			</div>
 | |
| 		</div>
 | |
| 	</div>
 | |
| 	<span class="edd-date-range-options graph-option-section edd-from-to-wrapper<?php echo esc_attr( $class ); ?>">
 | |
| 		<?php echo $from . $to; ?>
 | |
| 	</span>
 | |
| 	<?php
 | |
| }
 | |
| /**
 | |
|  * Handles display of the relative dates dropdown options.
 | |
|  *
 | |
|  * @since 3.1
 | |
|  */
 | |
| function display_relative_dates_dropdown_options( $range, $selected_relative_range ) {
 | |
| 	$date_format            = get_option( 'date_format' );
 | |
| 	$relative_range_options = get_relative_dates_filter_options();
 | |
| 	?>
 | |
| 	<ul data-range="<?php echo esc_attr( $range ); ?>">
 | |
| 		<?php
 | |
| 		foreach ( $relative_range_options as $relative_range_key => $relative_range_name ) :
 | |
| 			$relative_range_dates = \EDD\Reports\parse_relative_dates_for_range( $range, $relative_range_key );
 | |
| 			$selected_range_class = ( $selected_relative_range === $relative_range_key ) ? 'active' : '';
 | |
| 			?>
 | |
| 			<li class="<?php echo esc_attr( $selected_range_class ); ?>" data-range="<?php echo esc_attr( $relative_range_key ); ?>">
 | |
| 				<span class="date-range-name"><?php echo esc_html( $relative_range_options[ $relative_range_key ] ); ?></span>
 | |
| 				<span class="date-range-dates"><?php echo esc_html( edd_get_edd_timezone_equivalent_date_from_utc( $relative_range_dates['start'] )->format( $date_format ) ); ?> - <?php echo esc_html( edd_get_edd_timezone_equivalent_date_from_utc( $relative_range_dates['end'] )->format( $date_format ) ); ?></span>
 | |
| 			</li>
 | |
| 			<?php
 | |
| 		endforeach;
 | |
| 		?>
 | |
| 	</ul>
 | |
| 	<?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles display of the 'Products' filter for reports.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  */
 | |
| function display_products_filter() {
 | |
| 	$products = get_filter_value( 'products' );
 | |
| 
 | |
| 	$select   = EDD()->html->product_dropdown( array(
 | |
| 		'chosen'           => true,
 | |
| 		'variations'       => true,
 | |
| 		'selected'         => empty( $products ) ? 0 : $products,
 | |
| 		'show_option_none' => false,
 | |
| 		'show_option_all'  => sprintf( __( 'All %s', 'easy-digital-downloads' ), edd_get_label_plural() ),
 | |
| 	) ); ?>
 | |
| 
 | |
| 	<span class="edd-graph-filter-options graph-option-section"><?php
 | |
| 		echo $select;
 | |
| 	?></span><?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles display of the 'Products Dropdown' filter for reports.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  */
 | |
| function display_product_categories_filter() {
 | |
| 	?>
 | |
| 	<span class="edd-graph-filter-options graph-option-selection">
 | |
| 		<?php echo EDD()->html->category_dropdown( 'product_categories', get_filter_value( 'product_categories' ) ); ?>
 | |
| 	</span>
 | |
| 	<?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles display of the 'Exclude Taxes' filter for reports.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  */
 | |
| function display_taxes_filter() {
 | |
| 	if ( false === edd_use_taxes() ) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	$taxes         = get_filter_value( 'taxes' );
 | |
| 	$exclude_taxes = isset( $taxes['exclude_taxes'] ) && true == $taxes['exclude_taxes'];
 | |
| ?>
 | |
| 	<span class="edd-graph-filter-options graph-option-section">
 | |
| 		<label for="exclude_taxes">
 | |
| 			<input type="checkbox" id="exclude_taxes" <?php checked( true, $exclude_taxes, true ); ?> value="1" name="exclude_taxes"/>
 | |
| 			<?php esc_html_e( 'Exclude Taxes', 'easy-digital-downloads' ); ?>
 | |
| 		</label>
 | |
| 	</span>
 | |
| <?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles display of the 'Discounts' filter for reports.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  */
 | |
| function display_discounts_filter() {
 | |
| 	$discount = get_filter_value( 'discounts' );
 | |
| 
 | |
| 	$d = edd_get_discounts( array(
 | |
| 		'fields' => array( 'code', 'name' ),
 | |
| 		'number' => 100,
 | |
| 	) );
 | |
| 
 | |
| 	$discounts = array();
 | |
| 
 | |
| 	foreach ( $d as $discount_data ) {
 | |
| 		$discounts[ $discount_data->code ] = esc_html( $discount_data->name );
 | |
| 	}
 | |
| 
 | |
| 	// Get the select
 | |
| 	$select = EDD()->html->discount_dropdown( array(
 | |
| 		'name'     => 'discounts',
 | |
| 		'chosen'   => true,
 | |
| 		'selected' => empty( $discount ) ? 0 : $discount,
 | |
| 	) ); ?>
 | |
| 
 | |
|     <span class="edd-graph-filter-options graph-option-section"><?php
 | |
| 		echo $select;
 | |
| 	?></span><?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles display of the 'Gateways' filter for reports.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  */
 | |
| function display_gateways_filter() {
 | |
| 	$gateway = get_filter_value( 'gateways' );
 | |
| 
 | |
| 	$known_gateways = edd_get_payment_gateways();
 | |
| 
 | |
| 	$gateways = array();
 | |
| 
 | |
| 	foreach ( $known_gateways as $id => $data ) {
 | |
| 		$gateways[ $id ] = esc_html( $data['admin_label'] );
 | |
| 	}
 | |
| 
 | |
| 	// Get the select
 | |
| 	$select = EDD()->html->select( array(
 | |
| 		'name'             => 'gateways',
 | |
| 		'options'          => $gateways,
 | |
| 		'selected'         => empty( $gateway ) ? 0 : $gateway,
 | |
| 		'show_option_none' => false,
 | |
| 	) ); ?>
 | |
| 
 | |
|     <span class="edd-graph-filter-options graph-option-section"><?php
 | |
| 		echo $select;
 | |
| 	?></span><?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles display of the 'Country' filter for reports.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  */
 | |
| function display_region_filter() {
 | |
| 	$region  = get_filter_value( 'regions' );
 | |
| 	$country = get_filter_value( 'countries' );
 | |
| 
 | |
| 	if ( empty( $region ) ) {
 | |
| 		$region = '';
 | |
| 	}
 | |
| 	if ( empty( $country ) ) {
 | |
| 		$country = '';
 | |
| 	}
 | |
| 
 | |
| 	$regions = edd_get_shop_states( $country );
 | |
| 
 | |
| 	// Remove empty values.
 | |
| 	$regions = array_filter( $regions );
 | |
| 
 | |
| 	// Get the select
 | |
| 	$select = EDD()->html->region_select(
 | |
| 		array(
 | |
| 			'name'    => 'regions',
 | |
| 			'id'      => 'edd_reports_filter_regions',
 | |
| 			'options' => $regions,
 | |
| 		),
 | |
| 		$country,
 | |
| 		$region
 | |
| 	);
 | |
| 	?>
 | |
| 
 | |
| 	<span class="edd-graph-filter-options graph-option-section"><?php
 | |
| 	echo $select;
 | |
| 	?></span><?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles display of the 'Country' filter for reports.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  */
 | |
| function display_country_filter() {
 | |
| 	$country = get_filter_value( 'countries' );
 | |
| 	if ( empty( $country ) ) {
 | |
| 		$country = '';
 | |
| 	}
 | |
| 
 | |
| 	$countries = edd_get_country_list();
 | |
| 
 | |
| 	// Remove empty values.
 | |
| 	$countries = array_filter( $countries );
 | |
| 
 | |
| 	// Get the select
 | |
| 	$select = EDD()->html->country_select(
 | |
| 		array(
 | |
| 			'name'    => 'countries',
 | |
| 			'id'      => 'edd_reports_filter_countries',
 | |
| 			'options' => $countries,
 | |
| 		),
 | |
| 		$country
 | |
| 	);
 | |
| 	?>
 | |
| 
 | |
| 	<span class="edd-graph-filter-options graph-option-section"><?php
 | |
| 	echo $select;
 | |
| 	?></span><?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Handles the display of the 'Currency' filter for reports.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  */
 | |
| function display_currency_filter() {
 | |
| 	$currency = get_filter_value( 'currencies' );
 | |
| 	if ( empty( $currency ) ) {
 | |
| 		$currency = 'all';
 | |
| 	}
 | |
| 
 | |
| 	$order_currencies = get_transient( 'edd_distinct_order_currencies' );
 | |
| 	if ( false === $order_currencies ) {
 | |
| 		global $wpdb;
 | |
| 
 | |
| 		$order_currencies = $wpdb->get_col(
 | |
| 			"SELECT distinct currency FROM {$wpdb->edd_orders}"
 | |
| 		);
 | |
| 
 | |
| 		if ( is_array( $order_currencies ) ) {
 | |
| 			$order_currencies = array_filter( $order_currencies );
 | |
| 		}
 | |
| 
 | |
| 		set_transient( 'edd_distinct_order_currencies', $order_currencies, 3 * HOUR_IN_SECONDS );
 | |
| 	}
 | |
| 
 | |
| 	if ( ! is_array( $order_currencies ) || count( $order_currencies ) <= 1 ) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	$all_currencies = array_intersect_key( edd_get_currencies(), array_flip( $order_currencies ) );
 | |
| 	if ( array_key_exists( edd_get_currency(), $all_currencies ) ) {
 | |
| 		$all_currencies = array_merge( array(
 | |
| 			'convert' => sprintf( __( '%s - Converted', 'easy-digital-downloads' ), $all_currencies[ edd_get_currency() ] )
 | |
| 		), $all_currencies );
 | |
| 	}
 | |
| 	?>
 | |
| 	<span class="edd-graph-filter-options graph-option-section">
 | |
| 		<?php
 | |
| 		echo EDD()->html->select( array(
 | |
| 			'name'             => 'currencies',
 | |
| 			'id'               => 'edd_reports_filter_currencies',
 | |
| 			'options'          => $all_currencies,
 | |
| 			'selected'         => $currency,
 | |
| 			'show_option_all'  => false,
 | |
| 			'show_option_none' => false
 | |
| 		) );
 | |
| 		?>
 | |
| 	</span>
 | |
| 	<?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Displays the filters UI for a report.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param Data\Report $report Report object.
 | |
|  */
 | |
| function display_filters( $report ) {
 | |
| 	$action = edd_get_admin_url( array(
 | |
| 		'page' => 'edd-reports',
 | |
| 	) );
 | |
| 	?>
 | |
| 
 | |
| 	<form action="<?php echo esc_url( $action ); ?>" method="GET">
 | |
| 		<?php edd_admin_filter_bar( 'reports', $report ); ?>
 | |
| 	</form>
 | |
| 
 | |
| 	<?php
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Output filter items
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param object $report
 | |
|  */
 | |
| function filter_items( $report = false ) {
 | |
| 
 | |
| 	// Get the report ID
 | |
| 	$report_id = $report->get_id();
 | |
| 
 | |
| 	// Bail if no report
 | |
| 	if ( empty( $report_id ) ) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	$redirect_url = edd_get_admin_url( array(
 | |
| 		'page' => 'edd-reports',
 | |
| 		'view' => sanitize_key( $report_id ),
 | |
| 	) );
 | |
| 
 | |
| 	// Bail if no filters
 | |
| 	$filters  = $report->get_filters();
 | |
| 	if ( empty( $filters ) ) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	// Bail if no manifest
 | |
| 	$manifest = get_filters();
 | |
| 	if ( empty( $manifest ) ) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	// Setup callables
 | |
| 	$callables = array();
 | |
| 
 | |
| 	// Loop through filters and find the callables
 | |
| 	foreach ( $filters as $filter ) {
 | |
| 
 | |
| 		// Skip if empty
 | |
| 		if ( empty( $manifest[ $filter ]['display_callback'] ) ) {
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		// Skip if not callable
 | |
| 		$callback = $manifest[ $filter ]['display_callback'];
 | |
| 		if ( ! is_callable( $callback ) ) {
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		// Add callable to callables
 | |
| 		$callables[] = $callback;
 | |
| 	}
 | |
| 
 | |
| 	// Bail if no callables
 | |
| 	if ( empty( $callables ) ) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	// Start an output buffer
 | |
| 	ob_start();
 | |
| 
 | |
| 	// Call the callables in the buffer
 | |
| 	foreach ( $callables as $to_call ) {
 | |
| 		call_user_func( $to_call, $report );
 | |
| 	} ?>
 | |
| 
 | |
| 	<span class="edd-graph-filter-submit graph-option-section">
 | |
| 		<input type="submit" class="button button-secondary" value="<?php esc_html_e( 'Filter', 'easy-digital-downloads' ); ?>"/>
 | |
| 		<input type="hidden" name="edd_action" value="filter_reports">
 | |
| 		<input type="hidden" name="edd_redirect" value="<?php echo esc_url_raw( $redirect_url ); ?>">
 | |
| 	</span>
 | |
| 
 | |
| 	<?php
 | |
| 
 | |
| 	// Output the current buffer
 | |
| 	echo ob_get_clean();
 | |
| }
 | |
| add_action( 'edd_admin_filter_bar_reports', 'EDD\Reports\filter_items' );
 | |
| 
 | |
| /**
 | |
|  * Renders the mobile link at the bottom of the payment history page
 | |
|  *
 | |
|  * @since 1.8.4
 | |
|  * @since 3.0 Updated filter to display link next to the reports filters.
 | |
| */
 | |
| function mobile_link() {
 | |
| 	$url = edd_link_helper(
 | |
| 		'https://easydigitaldownloads.com/downloads/ios-app/',
 | |
| 		array(
 | |
| 			'utm_medium'  => 'reports',
 | |
| 			'utm_content' => 'ios-app',
 | |
| 		)
 | |
| 	);
 | |
| 	?>
 | |
| 	<span class="edd-mobile-link">
 | |
| 		<a href="<?php echo $url; ?>" target="_blank">
 | |
| 			<?php esc_html_e( 'Try the Sales/Earnings iOS App!', 'easy-digital-downloads' ); ?>
 | |
| 		</a>
 | |
| 	</span>
 | |
| 	<?php
 | |
| }
 | |
| add_action( 'edd_after_admin_filter_bar_reports', 'EDD\Reports\mobile_link', 100 );
 | |
| 
 | |
| /** Compat ********************************************************************/
 | |
| 
 | |
| /**
 | |
|  * Private: Injects the value of $_REQUEST['range'] into the Reports\get_dates_filter_range() if set.
 | |
|  *
 | |
|  * To be used only for backward-compatibility with anything relying on the `$_REQUEST['range']` value.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  * @access private
 | |
|  *
 | |
|  * @param string $range Currently resolved dates range.
 | |
|  * @return string (Maybe) modified range based on the value of `$_REQUEST['range']`.
 | |
|  */
 | |
| function compat_filter_date_range( $range ) {
 | |
| 	return isset( $_REQUEST['range'] )
 | |
| 		? sanitize_key( $_REQUEST['range'] )
 | |
| 		: $range;
 | |
| }
 |