Passed
Push — master ( c9620c...0d5a04 )
by Brian
04:05
created

get_date_range()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 11
rs 10
1
<?php
2
/**
3
 * Helper for the date based controllers.
4
 *
5
 * @package GetPaid
6
 * @subpackage REST API
7
 * @since   2.0.0
8
 */
9
10
defined( 'ABSPATH' ) || exit;
11
12
/**
13
 * GetPaid REST date based controller class.
14
 *
15
 * @package Invoicing
16
 */
17
class GetPaid_REST_Date_Based_Controller extends GetPaid_REST_Controller {
18
19
	/**
20
	 * Group response items by day or month.
21
	 *
22
	 * @var string
23
	 */
24
	public $groupby = 'day';
25
26
	/**
27
	 * The period interval.
28
	 *
29
	 * @var int
30
	 */
31
	public $interval;
32
33
	/**
34
	 * Retrieves the before and after dates.
35
	 *
36
	 * @param WP_REST_Request $request Request object.
37
	 * @return array The appropriate date range.
38
	 */
39
	public function get_date_range( $request ) {
40
41
		// If not supported, assume all time.
42
		if ( ! in_array( $request['period'], array( 'custom', 'today', 'yesterday', '7_days', '30_days', '60_days', '90_days', '180_days', 'month', 'last_month', 'year', 'last_year' ) ) ) {
43
			$request['period'] = '7_days';
44
		}
45
46
		$date_range = call_user_func( array( $this, 'get_' . $request['period'] . '_date_range' ), $request );
47
		$this->prepare_interval( $date_range );
48
49
		return $date_range;
50
51
	}
52
53
	/**
54
	 * Groups by month or days.
55
	 *
56
	 * @param array $range Date range.
57
	 * @return array The appropriate date range.
58
	 */
59
	public function prepare_interval( $range ) {
60
61
		$before = strtotime( $range['before'] ) - DAY_IN_SECONDS;
62
		$after  = strtotime( $range['after'] ) + DAY_IN_SECONDS;
63
		if ( 'day' === $this->groupby ) {
64
			$difference     = max( DAY_IN_SECONDS, ( DAY_IN_SECONDS + $before - $after ) ); // Prevent division by 0;
65
			$this->interval = absint( ceil( max( 1, $difference / DAY_IN_SECONDS ) ) );
66
			return;
67
		}
68
69
		$this->interval = 0;
70
		$min_date       = strtotime( date( 'Y-m-01', $after ) );
71
72
		while ( $min_date <= $before ) {
73
			$this->interval ++;
74
			$min_date = strtotime( '+1 MONTH', $min_date );
75
		}
76
77
		$this->interval = max( 1, $this->interval );
78
79
	}
80
81
	/**
82
	 * Retrieves a custom date range.
83
	 *
84
	 * @param WP_REST_Request $request Request object.
85
	 * @return array The appropriate date range.
86
	 */
87
	public function get_custom_date_range( $request ) {
88
89
		$after  = max( strtotime( '-20 years' ), strtotime( sanitize_text_field( $request['after'] ) ) );
90
		$before = strtotime( '+1 day', current_time( 'timestamp' ) );
91
92
		if ( ! empty( $request['before'] ) ) {
93
			$before  = min( $before, strtotime( sanitize_text_field( $request['before'] ) ) );
94
		}
95
96
		// 3 months max for day view
97
		if ( ( $before - $after ) / MONTH_IN_SECONDS > 3 ) {
98
			$this->groupby = 'month';
99
		}
100
101
		return array(
102
			'before' => date( 'Y-m-d', $before ),
103
			'after' => date( 'Y-m-d', $after ),
104
		);
105
106
	}
107
108
	/**
109
	 * Retrieves todays date range.
110
	 *
111
	 * @return array The appropriate date range.
112
	 */
113
	public function get_today_date_range() {
114
115
		return array(
116
			'before' => date( 'Y-m-d', strtotime( '+1 day', current_time( 'timestamp' ) ) ),
117
			'after'  => date( 'Y-m-d', strtotime( '-1 day', current_time( 'timestamp' ) ) ),
118
		);
119
120
	}
121
122
	/**
123
	 * Retrieves yesterdays date range.
124
	 *
125
	 * @return array The appropriate date range.
126
	 */
127
	public function get_yesterday_date_range() {
128
129
		return array(
130
			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
131
			'after'  => date( 'Y-m-d', strtotime( '-2 days', current_time( 'timestamp' ) ) ),
132
		);
133
134
	}
135
136
	/**
137
	 * Retrieves last 7 days date range.
138
	 *
139
	 * @return array The appropriate date range.
140
	 */
141
	public function get_7_days_date_range() {
142
143
		return array(
144
			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
145
			'after'  => date( 'Y-m-d', strtotime( '-8 days', current_time( 'timestamp' ) ) ),
146
		);
147
148
	}
149
150
	/**
151
	 * Retrieves last 30 days date range.
152
	 *
153
	 * @return array The appropriate date range.
154
	 */
155
	public function get_30_days_date_range() {
156
157
		return array(
158
			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
159
			'after'  => date( 'Y-m-d', strtotime( '-31 days', current_time( 'timestamp' ) ) ),
160
		);
161
162
	}
163
164
	/**
165
	 * Retrieves last 90 days date range.
166
	 *
167
	 * @return array The appropriate date range.
168
	 */
169
	public function get_90_days_date_range() {
170
171
		$this->groupby = 'month';
172
		return array(
173
			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
174
			'after'  => date( 'Y-m-d', strtotime( '-91 days', current_time( 'timestamp' ) ) ),
175
		);
176
177
	}
178
179
	/**
180
	 * Retrieves last 180 days date range.
181
	 *
182
	 * @return array The appropriate date range.
183
	 */
184
	public function get_180_days_date_range() {
185
186
		$this->groupby = 'month';
187
		return array(
188
			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
189
			'after'  => date( 'Y-m-d', strtotime( '-181 days', current_time( 'timestamp' ) ) ),
190
		);
191
192
	}
193
194
	/**
195
	 * Retrieves last 60 days date range.
196
	 *
197
	 * @return array The appropriate date range.
198
	 */
199
	public function get_60_days_date_range() {
200
201
		return array(
202
			'before' => date( 'Y-m-d', current_time( 'timestamp' ) ),
203
			'after'  => date( 'Y-m-d', strtotime( '-61 days', current_time( 'timestamp' ) ) ),
204
		);
205
206
	}
207
208
	/**
209
	 * Retrieves this month date range.
210
	 *
211
	 * @return array The appropriate date range.
212
	 */
213
	public function get_month_date_range() {
214
215
		return array(
216
			'before' => date( 'Y-m-d', strtotime( '+1 day', current_time( 'timestamp' ) ) ),
217
			'after'  => date( 'Y-m-t', strtotime( 'last month', current_time( 'timestamp' ) ) ),
218
		);
219
220
	}
221
222
	/**
223
	 * Retrieves last month's date range.
224
	 *
225
	 * @return array The appropriate date range.
226
	 */
227
	public function get_last_month_date_range() {
228
229
		return array(
230
			'before' => date( 'Y-m-1', current_time( 'timestamp' ) ),
231
			'after'  => date( 'Y-m-t', strtotime( "-2 months", current_time( 'timestamp' ) ) ),
232
		);
233
234
	}
235
236
	/**
237
	 * Retrieves this year date range.
238
	 *
239
	 * @return array The appropriate date range.
240
	 */
241
	public function get_year_date_range() {
242
243
		$this->groupby = 'month';
244
		return array(
245
			'before' => date( 'Y-m-d', strtotime( '+1 day', current_time( 'timestamp' ) ) ),
246
			'after'  => date( 'Y-m-d', strtotime( 'last year December 31st', current_time( 'timestamp' ) ) ),
247
		);
248
249
	}
250
251
	/**
252
	 * Retrieves last year date range.
253
	 *
254
	 * @return array The appropriate date range.
255
	 */
256
	public function get_last_year_date_range() {
257
258
		$this->groupby = 'month';
259
		$year          = (int) date('Y') - 2;
260
		return array(
261
			'after'  => "$year-12-31",
262
			'before' => date( 'Y-m-d', strtotime( 'first day of january this year', current_time( 'timestamp' ) ) ),
263
		);
264
265
	}
266
267
	/**
268
	 * Prepare a the request date for SQL usage.
269
	 *
270
	 * @param WP_REST_Request $request Request object.
271
	 * @param string $date_field The date field.
272
	 * @return string The appropriate SQL.
273
	 */
274
	public function get_date_range_sql( $request, $date_field ) {
275
		global $wpdb;
276
277
		$sql = '1=1';
278
		$range = $this->get_date_range( $request );
279
280
		if ( ! empty( $range['after'] ) ) {
281
			$sql .= ' AND ' .  $wpdb->prepare(
282
				"$date_field > %s",
283
				$range['after']
284
			);
285
		}
286
287
		if ( ! empty( $range['before'] ) ) {
288
			$sql .= ' AND ' .  $wpdb->prepare(
289
				"$date_field < %s",
290
				$range['before']
291
			);
292
		}
293
294
		return $sql;
295
296
	}
297
298
	/**
299
	 * Prepares a group by query.
300
	 *
301
	 * @param string $date_field The date field.
302
	 * @return string The appropriate SQL.
303
	 */
304
	public function get_group_by_sql( $date_field ) {
305
306
		if ( 'day' === $this->groupby ) {
307
			return "YEAR($date_field), MONTH($date_field), DAY($date_field)";
308
		}
309
310
		return "YEAR($date_field), MONTH($date_field)";
311
	}
312
313
	/**
314
	 * Get the query params for collections.
315
	 *
316
	 * @return array
317
	 */
318
	public function get_collection_params() {
319
		return array(
320
			'context' => $this->get_context_param( array( 'default' => 'view' ) ),
321
			'period' => array(
322
				'description'       => __( 'Limit to results of a specific period.', 'invoicing' ),
323
				'type'              => 'string',
324
				'enum'              => array( 'custom', 'today', 'yesterday', '7_days', '30_days', '60_days' , '90_days', '180_days', 'month', 'last_month', 'year', 'last_year' ),
325
				'validate_callback' => 'rest_validate_request_arg',
326
				'sanitize_callback' => 'sanitize_text_field',
327
				'default'           => '7_days',
328
			),
329
			'after' => array(
330
				/* translators: %s: date format */
331
				'description'       => sprintf( __( 'Limit to results after a specific date, the date needs to be in the %s format.', 'invoicing' ), 'YYYY-MM-DD' ),
332
				'type'              => 'string',
333
				'format'            => 'date',
334
				'validate_callback' => 'rest_validate_request_arg',
335
				'sanitize_callback' => 'sanitize_text_field',
336
				'default'           => date( 'Y-m-d', strtotime( '-8 days', current_time( 'timestamp' ) ) ),
337
			),
338
			'before' => array(
339
				/* translators: %s: date format */
340
				'description'       => sprintf( __( 'Limit to results before a specific date, the date needs to be in the %s format.', 'invoicing' ), 'YYYY-MM-DD' ),
341
				'type'              => 'string',
342
				'format'            => 'date',
343
				'validate_callback' => 'rest_validate_request_arg',
344
				'sanitize_callback' => 'sanitize_text_field',
345
				'default'           => date( 'Y-m-d', current_time( 'timestamp' ) ),
346
			),
347
		);
348
	}
349
}
350