0 && $previous > 0 ) { return round( ( $current - $previous ) / $previous * 100 ); } return 0; } /** * Determines a sane date range interval based on the date range type. * * E.g. if the date range type is '3months', the interval will be 'W' (week). * This prevents the chart from displaying too many datapoints. * * @since 4.7.3 * * @param \SimplePay\Core\Report\DateRange $range The date range to use for the report. * @return string The DatePeriod interval to use for the report. */ protected function get_date_range_interval( $range ) { $range_diff = $range->start->diff( $range->end ); switch ( $range->type ) { case 'today': return 'H'; case '3months': return 'W'; case '12months': return 'M'; case 'yeartodate': if ( $range_diff->m > 1 ) { return 'M'; } elseif ( 1 === $range_diff->m ) { return 'W'; } else { return 'D'; } case 'custom': if ( $range_diff->days <= 2 ) { return 'H'; } elseif ( $range_diff->days <= 30 ) { return 'D'; } elseif ( $range_diff->days <= 90 ) { return 'W'; } else { return 'M'; } // last7. // 4weeks. default: return 'D'; } } /** * Determines the SQL date format to use for the given interval. * * @since 4.7.3 * * @param string $interval The DatePeriod interval to use for the report. * @return string The SQL date format to use for the report. */ protected function get_sql_select_date_format( $interval ) { switch ( $interval ) { case 'H': return '%%Y-%%m-%%d %%H:00:00'; case 'D': return '%%Y-%%m-%%d'; case 'W': /** @var mixed $start_of_week */ $start_of_week = get_option( 'start_of_week', '0' ); $first_day_of_week = absint( is_scalar( $start_of_week ) ? (string) $start_of_week : '0' ); // Week begins on Monday, ISO 8601. if ( 1 === $first_day_of_week ) { return '%%x-%%v'; } // Week begins on day other than specified by ISO 8601. return '%%X-%%V'; case 'M': return '%%Y-%%m'; default: return '%%Y'; } } /** * Determines the PHP date format to use for the given interval. * * @since 4.7.3 * * @param string $interval The DatePeriod interval to use for the report. * @return string The PHP date format to use for the report. */ protected function get_php_date_format( $interval ) { switch ( $interval ) { case 'H': return 'Y-m-d H:i:s'; case 'D': return 'Y-m-d'; case 'W': return 'Y-W'; case 'M': return 'Y-m'; default: return 'Y'; } } /** * Determines the SQL date SELECT string to use for the given interval. * * This ensures the query groups the results by the correct date interval. * * @since 4.7.3 * * @param string $interval The DatePeriod interval to use for the report. * @return string The SQL date SELECT string to use for the report. */ protected function get_sql_select_date_as( $interval ) { $date_format = $this->get_sql_select_date_format( $interval ); $column = 'date_created'; switch ( $interval ) { case 'H': case 'D': return "DATE_FORMAT($column, '$date_format')"; case 'W': /** @var mixed $start_of_week */ $start_of_week = get_option( 'start_of_week', '0' ); $first_day_of_week = absint( is_scalar( $start_of_week ) ? (string) $start_of_week : '0' ); // Week begins on Monday, ISO 8601. if ( 1 === $first_day_of_week ) { return "DATE_FORMAT($column, '$date_format')"; } // Week begins on day other than specified by ISO 8601. return "CONCAT(YEAR($column), '-', LPAD( FLOOR( ( DAYOFYEAR($column) + ( ( DATE_FORMAT(MAKEDATE(YEAR($column),1), '%%w') - $first_day_of_week + 7 ) %% 7 ) - 1 ) / 7 ) + 1 , 2, '0'))"; case 'M': return "DATE_FORMAT($column, '$date_format')"; default: return "YEAR($column)"; } } /** * Returns the timezone offset for the current site. * * @since 4.7.3 * * @return string The timezone offset for the current site. */ protected function get_timezone_offset() { /** @var string $offset */ $offset = get_option( 'gmt_offset', '0' ); /** @var float $offset */ $offset = (float) $offset; $hours = (int) $offset; $minutes = ( $offset - $hours ); $sign = ( $offset < 0 ) ? '-' : '+'; $abs_hour = abs( $hours ); $abs_mins = abs( $minutes * 60 ); $tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins ); return $tz_offset; } }