Give_Payment_Stats::get_earnings()   C
last analyzed

Complexity

Conditions 11
Paths 34

Size

Total Lines 112

Duplication

Lines 24
Ratio 21.43 %

Importance

Changes 0
Metric Value
cc 11
nc 34
nop 4
dl 24
loc 112
rs 5.8533
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Earnings / Sales Stats
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Stats
7
 * @copyright   Copyright (c) 2016, GiveWP
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Give_Stats Class
19
 *
20
 * This class is for retrieving stats for earnings and sales.
21
 *
22
 * Stats can be retrieved for date ranges and pre-defined periods.
23
 *
24
 * @since 1.0
25
 */
26
class Give_Payment_Stats extends Give_Stats {
27
28
	/**
29
	 * Retrieve sale stats
30
	 *
31
	 * @since  1.0
32
	 * @access public
33
	 *
34
	 * @param  $form_id    int          The donation form to retrieve stats for. If false, gets stats for all forms
35
	 * @param  $start_date string|bool  The starting date for which we'd like to filter our sale stats. If false, we'll use the default start date of `this_month`
36
	 * @param  $end_date   string|bool  The end date for which we'd like to filter our sale stats. If false, we'll use the default end date of `this_month`
37
	 * @param  $status     string|array The sale status(es) to count. Only valid when retrieving global stats
38
	 *
39
	 * @return float|int                Total amount of donations based on the passed arguments.
40
	 */
41
	public function get_sales( $form_id = 0, $start_date = false, $end_date = false, $status = 'publish' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $status is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
42
43
		$this->setup_dates( $start_date, $end_date );
0 ignored issues
show
Documentation introduced by
$start_date is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
44
45
		// Make sure start date is valid
46
		if ( is_wp_error( $this->start_date ) ) {
47
			return $this->start_date;
48
		}
49
50
		// Make sure end date is valid
51
		if ( is_wp_error( $this->end_date ) ) {
52
			return $this->end_date;
53
		}
54
55
		$args = array(
56
			'status'     => 'publish',
57
			'start_date' => $this->start_date,
58
			'end_date'   => $this->end_date,
59
			'fields'     => 'ids',
60
			'number'     => - 1,
61
			'output'     => ''
62
		);
63
64
		if ( ! empty( $form_id ) ) {
65
			$args['give_forms'] = $form_id;
66
		}
67
68
		/* @var Give_Payments_Query $payments */
69
		$payments = new Give_Payments_Query( $args );
70
		$payments = $payments->get_payments();
71
72
		return count( $payments );
73
	}
74
75
76
	/**
77
	 * Retrieve earning stats
78
	 *
79
	 * @since  1.0
80
	 * @access public
81
	 *
82
	 * @param  $form_id     int         The donation form to retrieve stats for. If false, gets stats for all forms.
83
	 * @param  $start_date  string|bool The starting date for which we'd like to filter our donation earnings stats. If false, method will use the default start date of `this_month`.
84
	 * @param  $end_date    string|bool The end date for which we'd like to filter the donations stats. If false, method will use the default end date of `this_month`.
85
	 * @param  $gateway_id  string|bool The gateway to get earnings for such as 'paypal' or 'stripe'.
86
	 *
87
	 * @return float|int                Total amount of donations based on the passed arguments.
88
	 */
89
	public function get_earnings( $form_id = 0, $start_date = false, $end_date = false, $gateway_id = false ) {
90
		global $wpdb;
91
		$this->setup_dates( $start_date, $end_date );
0 ignored issues
show
Documentation introduced by
$start_date is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
92
93
		// Make sure start date is valid
94
		if ( is_wp_error( $this->start_date ) ) {
95
			return $this->start_date;
96
		}
97
98
		// Make sure end date is valid
99
		if ( is_wp_error( $this->end_date ) ) {
100
			return $this->end_date;
101
		}
102
103
		$args = array(
104
			'status'     => 'publish',
105
			'give_forms' => $form_id,
106
			'start_date' => $this->start_date,
107
			'end_date'   => $this->end_date,
108
			'fields'     => 'ids',
109
			'number'     => - 1,
110
			'output'     => '',
111
		);
112
113
114
		// Filter by Gateway ID meta_key
115
		if ( $gateway_id ) {
116
			$args['meta_query'][] = array(
117
				'key'   => '_give_payment_gateway',
118
				'value' => $gateway_id,
119
			);
120
		}
121
122
		// Filter by Gateway ID meta_key
123
		if ( $form_id ) {
124
			$args['meta_query'][] = array(
125
				'key'   => '_give_payment_form_id',
126
				'value' => $form_id,
127
			);
128
		}
129
130 View Code Duplication
		if ( ! empty( $args['meta_query'] ) && 1 < count( $args['meta_query'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
			$args['meta_query']['relation'] = 'AND';
132
		}
133
134
		$args = apply_filters( 'give_stats_earnings_args', $args );
135
		$key  = Give_Cache::get_key( 'give_stats', $args );
136
137
		// Set transient for faster stats.
138
		$earnings = Give_Cache::get( $key );
139
140
		if ( false === $earnings ) {
141
142
			$this->timestamp = false;
0 ignored issues
show
Documentation Bug introduced by
The property $timestamp was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
143
			$payments        = new Give_Payments_Query( $args );
144
			$payments        = $payments->get_payments();
145
			$earnings        = 0;
146
147
			if ( ! empty( $payments ) ) {
148
				$donation_id_col = Give()->payment_meta->get_meta_type() . '_id';
149
				$query = "SELECT {$donation_id_col} as id, meta_value as total
150
					FROM {$wpdb->donationmeta}
151
					WHERE meta_key='_give_payment_total'
152
					AND {$donation_id_col} IN ('". implode( '\',\'', $payments ) ."')";
153
154
				$payments = $wpdb->get_results($query, ARRAY_A);
155
156 View Code Duplication
				if( ! empty( $payments ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
					foreach ( $payments as $payment ) {
158
						$currency_code = give_get_payment_currency_code( $payment['id'] );
159
160
						/**
161
						 * Filter the donation amount
162
						 * Note: this filter documented in payments/functions.php:give_donation_amount()
163
						 *
164
						 * @since 2.1
165
						 */
166
						$formatted_amount = apply_filters(
167
							'give_donation_amount',
168
							give_format_amount(  $payment['total'], array( 'donation_id' =>  $payment['id'] ) ),
169
							$payment['total'],
170
							$payment['id'],
171
							array( 'type' => 'stats', 'currency'=> false, 'amount' => false )
172
						);
173
174
						$earnings += (float) give_maybe_sanitize_amount( $formatted_amount, array( 'currency' => $currency_code  ) );
175
					}
176
				}
177
178
			}
179
180
			// Cache the results for one hour.
181
			Give_Cache::set( $key, give_sanitize_amount_for_db( $earnings ), 60 * 60 );
182
		}
183
184
		/**
185
		 * Filter the earnings.
186
		 *
187
		 * @since 1.8.17
188
		 *
189
		 * @param  float       $earnings   Earning amount.
190
		 * @param  int         $form_id    Donation Form ID.
191
		 * @param  string|bool $start_date Earning start date.
192
		 * @param  string|bool $end_date   Earning end date.
193
		 * @param  string|bool $gateway_id Payment gateway id.
194
		 */
195
		$earnings = apply_filters( 'give_get_earnings', $earnings, $form_id, $start_date, $end_date, $gateway_id );
196
197
		//return earnings
198
		return round( $earnings, give_get_price_decimals( $form_id ) );
199
200
	}
201
202
	/**
203
	 * Retrieve earning stat transient key
204
	 *
205
	 * @since  1.0
206
	 * @access public
207
	 *
208
	 * @param  $form_id     int         The donation form to retrieve stats for. If false, gets stats for all forms
209
	 * @param  $start_date  string|bool The starting date for which we'd like to filter our donation earnings stats. If false, we'll use the default start date of `this_month`
210
	 * @param  $end_date    string|bool The end date for which we'd like to filter our sale stats. If false, we'll use the default end date of `this_month`
211
	 * @param  $gateway_id  string|bool The gateway to get earnings for such as 'paypal' or 'stripe'
212
	 *
213
	 * @return float|int                Total amount of donations based on the passed arguments.
214
	 */
215
	public function get_earnings_cache_key( $form_id = 0, $start_date = false, $end_date = false, $gateway_id = false ) {
216
217
		$this->setup_dates( $start_date, $end_date );
0 ignored issues
show
Documentation introduced by
$start_date is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
218
219
		// Make sure start date is valid
220
		if ( is_wp_error( $this->start_date ) ) {
221
			return $this->start_date;
222
		}
223
224
		// Make sure end date is valid
225
		if ( is_wp_error( $this->end_date ) ) {
226
			return $this->end_date;
227
		}
228
229
		$args = array(
230
			'status'     => 'publish',
231
			'give_forms' => $form_id,
232
			'start_date' => $this->start_date,
233
			'end_date'   => $this->end_date,
234
			'fields'     => 'ids',
235
			'number'     => - 1,
236
		);
237
238
239
		// Filter by Gateway ID meta_key
240
		if ( $gateway_id ) {
241
			$args['meta_query'][] = array(
242
				'key'   => '_give_payment_gateway',
243
				'value' => $gateway_id,
244
			);
245
		}
246
247
		// Filter by Gateway ID meta_key
248
		if ( $form_id ) {
249
			$args['meta_query'][] = array(
250
				'key'   => '_give_payment_form_id',
251
				'value' => $form_id,
252
			);
253
		}
254
255 View Code Duplication
		if ( ! empty( $args['meta_query'] ) && 1 < count( $args['meta_query'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
256
			$args['meta_query']['relation'] = 'AND';
257
		}
258
259
		$args = apply_filters( 'give_stats_earnings_args', $args );
260
		$key  = Give_Cache::get_key( 'give_stats', $args );
261
262
		//return earnings
263
		return $key;
264
265
	}
266
267
	/**
268
	 * Get the best selling forms
269
	 *
270
	 * @since  1.0
271
	 * @access public
272
	 * @global wpdb $wpdb
273
	 *
274
	 * @param       $number int The number of results to retrieve with the default set to 10.
275
	 *
276
	 * @return array       Best selling forms
277
	 */
278
	public function get_best_selling( $number = 10 ) {
279
		global $wpdb;
280
281
		$meta_table = __give_v20_bc_table_details( 'form' );
282
283
		$give_forms = $wpdb->get_results( $wpdb->prepare(
284
			"SELECT {$meta_table['column']['id']} as form_id, max(meta_value) as sales
285
				FROM {$meta_table['name']} WHERE meta_key='_give_form_sales' AND meta_value > 0
286
				GROUP BY meta_value+0
287
				DESC LIMIT %d;", $number
288
		) );
289
290
		return $give_forms;
291
	}
292
293
}
294