523 lines
11 KiB
PHP
523 lines
11 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Stats Base
|
||
|
*
|
||
|
* @package EDD
|
||
|
* @subpackage Classes/Stats
|
||
|
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||
|
* @since 1.8
|
||
|
*/
|
||
|
|
||
|
// Exit if accessed directly
|
||
|
defined( 'ABSPATH' ) || exit;
|
||
|
|
||
|
/**
|
||
|
* EDD_Stats Class
|
||
|
*
|
||
|
* Base class for other stats classes
|
||
|
*
|
||
|
* Primarily for setting up dates and ranges
|
||
|
*
|
||
|
* @since 1.8
|
||
|
*/
|
||
|
class EDD_Stats {
|
||
|
|
||
|
|
||
|
/**
|
||
|
* The start date for the period we're getting stats for
|
||
|
*
|
||
|
* Can be a timestamp, formatted date, date string (such as August 3, 2013),
|
||
|
* or a predefined date string, such as last_week or this_month
|
||
|
*
|
||
|
* Predefined date options are: today, yesterday, this_week, last_week, this_month, last_month
|
||
|
* this_quarter, last_quarter, this_year, last_year
|
||
|
*
|
||
|
* @since 1.8
|
||
|
*/
|
||
|
public $start_date;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* The end date for the period we're getting stats for
|
||
|
*
|
||
|
* Can be a timestamp, formatted date, date string (such as August 3, 2013),
|
||
|
* or a predefined date string, such as last_week or this_month
|
||
|
*
|
||
|
* Predefined date options are: today, yesterday, this_week, last_week, this_month, last_month
|
||
|
* this_quarter, last_quarter, this_year, last_year
|
||
|
*
|
||
|
* The end date is optional
|
||
|
*
|
||
|
* @since 1.8
|
||
|
*/
|
||
|
public $end_date;
|
||
|
|
||
|
/**
|
||
|
* Flag to determine if current query is based on timestamps
|
||
|
*
|
||
|
* @since 1.9
|
||
|
*/
|
||
|
public $timestamp;
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* @since 1.8
|
||
|
* @return void
|
||
|
*/
|
||
|
public function __construct() { /* nothing here. Call get_sales() and get_earnings() directly */ }
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Get the predefined date periods permitted
|
||
|
*
|
||
|
* @since 1.8
|
||
|
* @return array
|
||
|
*/
|
||
|
public function get_predefined_dates() {
|
||
|
return apply_filters( 'edd_stats_predefined_dates', array(
|
||
|
'today' => __( 'Today', 'easy-digital-downloads' ),
|
||
|
'yesterday' => __( 'Yesterday', 'easy-digital-downloads' ),
|
||
|
'this_week' => __( 'This Week', 'easy-digital-downloads' ),
|
||
|
'last_week' => __( 'Last Week', 'easy-digital-downloads' ),
|
||
|
'this_month' => __( 'This Month', 'easy-digital-downloads' ),
|
||
|
'last_month' => __( 'Last Month', 'easy-digital-downloads' ),
|
||
|
'this_quarter' => __( 'This Quarter', 'easy-digital-downloads' ),
|
||
|
'last_quarter' => __( 'Last Quarter', 'easy-digital-downloads' ),
|
||
|
'this_year' => __( 'This Year', 'easy-digital-downloads' ),
|
||
|
'last_year' => __( 'Last Year', 'easy-digital-downloads' )
|
||
|
) );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Setup the dates passed to our constructor.
|
||
|
*
|
||
|
* This calls the convert_date() member function to ensure the dates are formatted correctly
|
||
|
*
|
||
|
* @since 1.8
|
||
|
* @return void
|
||
|
*/
|
||
|
public function setup_dates( $_start_date = 'this_month', $_end_date = false ) {
|
||
|
|
||
|
if ( empty( $_start_date ) ) {
|
||
|
$_start_date = 'this_month';
|
||
|
}
|
||
|
|
||
|
if ( empty( $_end_date ) ) {
|
||
|
$_end_date = $_start_date;
|
||
|
}
|
||
|
|
||
|
$this->start_date = $this->convert_date( $_start_date );
|
||
|
$this->end_date = $this->convert_date( $_end_date, true );
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Converts a date to a timestamp
|
||
|
*
|
||
|
* @since 1.8
|
||
|
* @return array|WP_Error If the date is invalid, a WP_Error object will be returned
|
||
|
*/
|
||
|
public function convert_date( $date, $end_date = false ) {
|
||
|
|
||
|
$this->timestamp = false;
|
||
|
$second = $end_date ? 59 : 0;
|
||
|
$minute = $end_date ? 59 : 0;
|
||
|
$hour = $end_date ? 23 : 0;
|
||
|
$day = 1;
|
||
|
$month = date( 'n', current_time( 'timestamp' ) );
|
||
|
$year = date( 'Y', current_time( 'timestamp' ) );
|
||
|
|
||
|
if ( ( is_string( $date ) || is_int( $date ) ) && array_key_exists( $date, $this->get_predefined_dates() ) ) {
|
||
|
|
||
|
// This is a predefined date rate, such as last_week
|
||
|
switch( $date ) {
|
||
|
|
||
|
case 'this_month' :
|
||
|
|
||
|
if ( $end_date ) {
|
||
|
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'last_month' :
|
||
|
|
||
|
if ( $month == 1 ) {
|
||
|
|
||
|
$month = 12;
|
||
|
$year--;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
$month--;
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( $end_date ) {
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'today' :
|
||
|
|
||
|
$day = date( 'd', current_time( 'timestamp' ) );
|
||
|
|
||
|
if ( $end_date ) {
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'yesterday' :
|
||
|
|
||
|
$day = date( 'd', current_time( 'timestamp' ) ) - 1;
|
||
|
|
||
|
// Check if Today is the first day of the month (meaning subtracting one will get us 0)
|
||
|
if ( $day < 1 ) {
|
||
|
|
||
|
// If current month is 1
|
||
|
if ( 1 == $month ) {
|
||
|
|
||
|
$year -= 1; // Today is January 1, so skip back to last day of December
|
||
|
$month = 12;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
// Go back one month and get the last day of the month
|
||
|
$month -= 1;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'this_week' :
|
||
|
|
||
|
$days_to_week_start = ( date( 'w', current_time( 'timestamp' ) ) - 1 ) *60*60*24;
|
||
|
$today = date( 'd', current_time( 'timestamp' ) ) *60*60*24;
|
||
|
|
||
|
if ( $today < $days_to_week_start ) {
|
||
|
|
||
|
if ( $month > 1 ) {
|
||
|
$month -= 1;
|
||
|
} else {
|
||
|
$month = 12;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( ! $end_date ) {
|
||
|
|
||
|
// Getting the start day
|
||
|
|
||
|
$day = date( 'd', current_time( 'timestamp' ) - $days_to_week_start ) - 1;
|
||
|
$day += get_option( 'start_of_week' );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
// Getting the end day
|
||
|
|
||
|
$day = date( 'd', current_time( 'timestamp' ) - $days_to_week_start ) - 1;
|
||
|
$day += get_option( 'start_of_week' ) + 6;
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'last_week' :
|
||
|
|
||
|
$days_to_week_start = ( date( 'w', current_time( 'timestamp' ) ) - 1 ) *60*60*24;
|
||
|
$today = date( 'd', current_time( 'timestamp' ) ) *60*60*24;
|
||
|
|
||
|
if ( $today < $days_to_week_start ) {
|
||
|
|
||
|
if ( $month > 1 ) {
|
||
|
$month -= 1;
|
||
|
} else {
|
||
|
$month = 12;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( ! $end_date ) {
|
||
|
|
||
|
// Getting the start day
|
||
|
|
||
|
$day = date( 'd', current_time( 'timestamp' ) - $days_to_week_start ) - 8;
|
||
|
$day += get_option( 'start_of_week' );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
// Getting the end day
|
||
|
|
||
|
$day = date( 'd', current_time( 'timestamp' ) - $days_to_week_start ) - 8;
|
||
|
$day += get_option( 'start_of_week' ) + 6;
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'this_quarter' :
|
||
|
|
||
|
$month_now = date( 'n', current_time( 'timestamp' ) );
|
||
|
|
||
|
if ( $month_now <= 3 ) {
|
||
|
|
||
|
if ( ! $end_date ) {
|
||
|
$month = 1;
|
||
|
} else {
|
||
|
$month = 3;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
}
|
||
|
|
||
|
} else if ( $month_now <= 6 ) {
|
||
|
|
||
|
if ( ! $end_date ) {
|
||
|
$month = 4;
|
||
|
} else {
|
||
|
$month = 6;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
}
|
||
|
|
||
|
} else if ( $month_now <= 9 ) {
|
||
|
|
||
|
if ( ! $end_date ) {
|
||
|
$month = 7;
|
||
|
} else {
|
||
|
$month = 9;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
if ( ! $end_date ) {
|
||
|
$month = 10;
|
||
|
} else {
|
||
|
$month = 12;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'last_quarter' :
|
||
|
|
||
|
$month_now = date( 'n', current_time( 'timestamp' ) );
|
||
|
|
||
|
if ( $month_now <= 3 ) {
|
||
|
|
||
|
if ( ! $end_date ) {
|
||
|
$month = 10;
|
||
|
} else {
|
||
|
$year -= 1;
|
||
|
$month = 12;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
}
|
||
|
|
||
|
} else if ( $month_now <= 6 ) {
|
||
|
|
||
|
if ( ! $end_date ) {
|
||
|
$month = 1;
|
||
|
} else {
|
||
|
$month = 3;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
}
|
||
|
|
||
|
} else if ( $month_now <= 9 ) {
|
||
|
|
||
|
if ( ! $end_date ) {
|
||
|
$month = 4;
|
||
|
} else {
|
||
|
$month = 6;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
if ( ! $end_date ) {
|
||
|
$month = 7;
|
||
|
} else {
|
||
|
$month = 9;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'this_year' :
|
||
|
|
||
|
if ( ! $end_date ) {
|
||
|
$month = 1;
|
||
|
} else {
|
||
|
$month = 12;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'last_year' :
|
||
|
|
||
|
$year -= 1;
|
||
|
if ( ! $end_date ) {
|
||
|
$month = 1;
|
||
|
$day = 1;
|
||
|
} else {
|
||
|
$month = 12;
|
||
|
$day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
|
||
|
$hour = 23;
|
||
|
$minute = 59;
|
||
|
$second = 59;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
} else if ( is_numeric( $date ) ) {
|
||
|
|
||
|
// return $date unchanged since it is a timestamp
|
||
|
$this->timestamp = true;
|
||
|
|
||
|
} else if ( false !== strtotime( $date ) ) {
|
||
|
|
||
|
$date = strtotime( $date, current_time( 'timestamp' ) );
|
||
|
$year = date( 'Y', $date );
|
||
|
$month = date( 'm', $date );
|
||
|
$day = date( 'd', $date );
|
||
|
|
||
|
} else {
|
||
|
return new WP_Error( 'invalid_date', __( 'Improper date provided.', 'easy-digital-downloads' ) );
|
||
|
}
|
||
|
|
||
|
// Create an exact timestamp
|
||
|
if ( false === $this->timestamp ) {
|
||
|
$date = mktime( $hour, $minute, $second, $month, $day, $year );
|
||
|
}
|
||
|
|
||
|
return apply_filters( 'edd_stats_date', $date, $end_date, $this );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Modifies the WHERE flag for payment counts
|
||
|
*
|
||
|
* Only get payments in our date range
|
||
|
*
|
||
|
* @since 1.8
|
||
|
* @return string
|
||
|
*/
|
||
|
public function count_where( $where = '' ) {
|
||
|
|
||
|
$start_where = $end_where = '';
|
||
|
|
||
|
if ( $this->start_date ) {
|
||
|
|
||
|
if ( $this->timestamp ) {
|
||
|
$format = 'Y-m-d H:i:s';
|
||
|
} else {
|
||
|
$format = 'Y-m-d 00:00:00';
|
||
|
}
|
||
|
|
||
|
$start_date = date( $format, $this->start_date );
|
||
|
$start_where = " AND date_created >= '{$start_date}'";
|
||
|
}
|
||
|
|
||
|
if ( $this->end_date ) {
|
||
|
|
||
|
if ( $this->timestamp ) {
|
||
|
$format = 'Y-m-d H:i:s';
|
||
|
} else {
|
||
|
$format = 'Y-m-d 23:59:59';
|
||
|
}
|
||
|
|
||
|
$end_date = date( $format, $this->end_date );
|
||
|
|
||
|
$end_where = " AND date_created <= '{$end_date}'";
|
||
|
}
|
||
|
|
||
|
$where .= "{$start_where}{$end_where}";
|
||
|
|
||
|
return $where;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Modifies the WHERE flag for payment queries
|
||
|
*
|
||
|
* @since 1.8
|
||
|
* @return string
|
||
|
*/
|
||
|
public function payments_where( $where = '' ) {
|
||
|
global $wpdb;
|
||
|
|
||
|
$start_where = '';
|
||
|
$end_where = '';
|
||
|
|
||
|
if ( ! is_wp_error( $this->start_date ) ) {
|
||
|
|
||
|
if ( $this->timestamp ) {
|
||
|
$format = 'Y-m-d H:i:s';
|
||
|
} else {
|
||
|
$format = 'Y-m-d 00:00:00';
|
||
|
}
|
||
|
|
||
|
$start_date = date( $format, $this->start_date );
|
||
|
$start_where = " AND {$wpdb->posts}.post_date >= '{$start_date}'";
|
||
|
}
|
||
|
|
||
|
if ( ! is_wp_error( $this->end_date ) ) {
|
||
|
|
||
|
if ( $this->timestamp ) {
|
||
|
$format = 'Y-m-d H:i:s';
|
||
|
} else {
|
||
|
$format = 'Y-m-d 23:59:59';
|
||
|
}
|
||
|
|
||
|
$end_date = date( $format, $this->end_date );
|
||
|
|
||
|
$end_where = " AND {$wpdb->posts}.post_date <= '{$end_date}'";
|
||
|
}
|
||
|
|
||
|
$where .= "{$start_where}{$end_where}";
|
||
|
|
||
|
return $where;
|
||
|
}
|
||
|
}
|