Completed
Pull Request — master (#664)
by Devin
19:01
created

Give_Tools_Recount_Customer_Stats::headers()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 7
rs 9.4285
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 23 and the first side effect is on line 15.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Recount all customer stats
4
 *
5
 * This class handles batch processing of recounting all customer stats
6
 *
7
 * @subpackage  Admin/Tools/Give_Tools_Recount_Customer_Stats
8
 * @copyright   Copyright (c) 2016, Chris Klosowski
9
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
10
 * @since       1.5
11
 */
12
13
// Exit if accessed directly
14
if ( ! defined( 'ABSPATH' ) ) {
15
	exit;
16
}
17
18
/**
19
 * Give_Tools_Recount_Customer_Stats Class
20
 *
21
 * @since 1.5
22
 */
23
class Give_Tools_Recount_Customer_Stats extends Give_Batch_Export {
24
25
	/**
26
	 * Our export type. Used for export-type specific filters/actions
27
	 * @var string
28
	 * @since 1.5
29
	 */
30
	public $export_type = '';
31
32
	/**
33
	 * Allows for a non-form batch processing to be run.
34
	 * @since  1.5
35
	 * @var boolean
36
	 */
37
	public $is_void = true;
38
39
	/**
40
	 * Sets the number of items to pull on each step
41
	 * @since  1.5
42
	 * @var integer
43
	 */
44
	public $per_step = 5;
45
46
	/**
47
	 * Get the Export Data
48
	 *
49
	 * @access public
50
	 * @since 1.5
51
	 * @global object $wpdb Used to query the database using the WordPress
52
	 *   Database API
53
	 * @return array $data The data for the CSV file
54
	 */
55
	public function get_data() {
56
57
		$args = array(
58
			'number'  => $this->per_step,
59
			'offset'  => $this->per_step * ( $this->step - 1 ),
60
			'orderby' => 'id',
61
			'order'   => 'DESC',
62
		);
63
64
		$customers = Give()->customers->get_customers( $args );
65
66
		if ( $customers ) {
67
68
			$allowed_payment_status = apply_filters( 'give_recount_customer_payment_statuses', give_get_payment_status_keys() );
69
70
			foreach ( $customers as $customer ) {
71
72
				$attached_payment_ids = explode( ',', $customer->payment_ids );
73
74
				$attached_args = array(
75
					'post__in' => $attached_payment_ids,
76
					'number'   => - 1,
77
					'status'   => $allowed_payment_status,
78
				);
79
80
				$attached_payments = (array) give_get_payments( $attached_args );
81
82
				$unattached_args = array(
83
					'post__not_in' => $attached_payment_ids,
84
					'number'       => - 1,
85
					'status'       => $allowed_payment_status,
86
					'meta_query'   => array(
87
						array(
88
							'key'     => '_give_payment_user_email',
89
							'value'   => $customer->email,
90
							'compare' => '=',
91
						)
92
					),
93
				);
94
95
				$unattached_payments = give_get_payments( $unattached_args );
96
97
				$payments = array_merge( $attached_payments, $unattached_payments );
98
99
				$purchase_value = 0.00;
100
				$purchase_count = 0;
101
				$payment_ids    = array();
102
103
				if ( $payments ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $payments of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
104
105
					foreach ( $payments as $payment ) {
106
107
						$should_process_payment = 'publish' == $payment->post_status || 'revoked' == $payment->post_status ? true : false;
108
						$should_process_payment = apply_filters( 'give_customer_recount_should_process_payment', $should_process_payment, $payment );
109
110
						if ( true === $should_process_payment ) {
111
112
							if ( apply_filters( 'give_customer_recount_should_increase_value', true, $payment ) ) {
113
								$purchase_value += give_get_payment_amount( $payment->ID );
114
							}
115
116
							if ( apply_filters( 'give_customer_recount_should_increase_count', true, $payment ) ) {
117
								$purchase_count ++;
118
							}
119
120
						}
121
122
						$payment_ids[] = $payment->ID;
123
					}
124
125
				}
126
127
				$payment_ids = implode( ',', $payment_ids );
128
129
				$customer_update_data = array(
130
					'purchase_count' => $purchase_count,
131
					'purchase_value' => $purchase_value,
132
					'payment_ids'    => $payment_ids,
133
				);
134
135
				$customer_instance = new Give_Customer( $customer->id );
136
				$customer_instance->update( $customer_update_data );
137
138
			}
139
140
			return true;
141
		}
142
143
		return false;
144
145
	}
146
147
	/**
148
	 * Return the calculated completion percentage
149
	 *
150
	 * @since 1.5
151
	 * @return int
152
	 */
153
	public function get_percentage_complete() {
154
155
		$args = array(
156
			'number'  => - 1,
157
			'orderby' => 'id',
158
			'order'   => 'DESC',
159
		);
160
161
		$customers = Give()->customers->get_customers( $args );
162
		$total     = count( $customers );
163
164
		$percentage = 100;
165
166
		if ( $total > 0 ) {
167
			$percentage = ( ( $this->per_step * $this->step ) / $total ) * 100;
168
		}
169
170
		if ( $percentage > 100 ) {
171
			$percentage = 100;
172
		}
173
174
		return $percentage;
175
	}
176
177
	/**
178
	 * Set the properties specific to the payments export
179
	 *
180
	 * @since 1.5
181
	 *
182
	 * @param array $request The Form Data passed into the batch processing
183
	 */
184
	public function set_properties( $request ) {
185
	}
186
187
	/**
188
	 * Process a step
189
	 *
190
	 * @since 1.5
191
	 * @return bool
192
	 */
193
	public function process_step() {
194
195
		if ( ! $this->can_export() ) {
196
			wp_die( __( 'You do not have permission to export data.', 'give' ), __( 'Error', 'give' ), array( 'response' => 403 ) );
197
		}
198
199
		$had_data = $this->get_data();
200
201
		if ( $had_data ) {
202
			$this->done = false;
0 ignored issues
show
Bug introduced by
The property done does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
203
204
			return true;
205
		} else {
206
			$this->done    = true;
207
			$this->message = __( 'Donor stats successfully recounted.', 'give' );
0 ignored issues
show
Bug introduced by
The property message does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
208
209
			return false;
210
		}
211
	}
212
213
	/**
214
	 * Headers
215
	 */
216
	public function headers() {
217
		ignore_user_abort( true );
218
219
		if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
220
			set_time_limit( 0 );
221
		}
222
	}
223
224
	/**
225
	 * Perform the export
226
	 *
227
	 * @access public
228
	 * @since 1.5
229
	 * @return void
230
	 */
231
	public function export() {
232
233
		// Set headers
234
		$this->headers();
235
236
		give_die();
237
	}
238
239
}
240