Completed
Push — issues/1413 ( d54dbe...6f1da6 )
by Ravinder
38:15 queued 18:12
created

Give_Batch_Customers_Export::get_data()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 69
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 36
nc 5
nop 0
dl 0
loc 69
rs 6.9081
c 0
b 0
f 0

How to fix   Long Method   

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
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 24 and the first side effect is on line 16.

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
 * Batch Customers Export Class
4
 *
5
 * This class handles customer export
6
 *
7
 * @package     Give
8
 * @subpackage  Admin/Reports
9
 * @copyright   Copyright (c) 2016, WordImpress
10
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
11
 * @since       1.5
12
 */
13
14
// Exit if accessed directly.
15
if ( ! defined( 'ABSPATH' ) ) {
16
	exit;
17
}
18
19
/**
20
 * Give_Batch_Customers_Export Class
21
 *
22
 * @since 1.5
23
 */
24
class Give_Batch_Customers_Export extends Give_Batch_Export {
25
26
	/**
27
	 * Our export type. Used for export-type specific filters/actions
28
	 *
29
	 * @var string
30
	 * @since 1.5
31
	 */
32
	public $export_type = 'customers';
33
34
	/**
35
	 * Form submission data
36
	 *
37
	 * @var array
38
	 * @since 1.5
39
	 */
40
	private $data = array();
41
42
	/**
43
	 * Array of donor ids which is already included in csv file.
44
	 *
45
	 * @since 1.8
46
	 * @var array
47
	 */
48
	private $donor_ids = array();
49
50
	/**
51
	 * Export query id.
52
	 *
53
	 * @since 1.8
54
	 * @var array
55
	 */
56
	private $query_id = '';
57
58
	/**
59
	 * Set the properties specific to the Customers export
60
	 *
61
	 * @since 1.5
62
	 *
63
	 * @param array $request The Form Data passed into the batch processing
64
	 */
65
	public function set_properties( $request ) {
66
67
		// Set data from form submission
68
		if ( isset( $_POST['form'] ) ) {
69
			parse_str( $_POST['form'], $this->data );
70
		}
71
72
		$this->form = $this->data['forms'];
73
74
		// Setup donor ids cache.
75
		if( ! empty( $this->form ) ) {
76
			// Cache donor ids to output unique list of donor.
77
			$this->query_id = give_clean( $_REQUEST['give_export_option']['query_id'] );
78
			if( ! ( $this->donor_ids = get_transient( $this->query_id ) ) ) {
79
				$this->donor_ids = array();
80
				set_transient( $this->query_id, $this->donor_ids, HOUR_IN_SECONDS );
81
			}
82
		}
83
84
		$this->price_id = ! empty( $request['give_price_option'] ) && 0 !== $request['give_price_option'] ? absint( $request['give_price_option'] ) : null;
85
86
	}
87
88
	/**
89
	 * Set the CSV columns.
90
	 *
91
	 * @access public
92
	 * @since  1.5
93
	 * @return array|bool $cols All the columns.
94
	 */
95
	public function csv_cols() {
96
97
		$cols = array();
98
99
		$columns = isset( $this->data['give_export_option'] ) ? $this->data['give_export_option'] : array();
100
101
		// We need columns.
102
		if ( empty( $columns ) ) {
103
			return false;
104
		}
105
106
		$cols = $this->get_cols( $columns );
107
108
		return $cols;
109
	}
110
111
	/**
112
	 * CSV file columns.
113
	 *
114
	 * @param array $columns
115
	 *
116
	 * @return array
117
	 */
118
	private function get_cols( $columns ) {
119
120
		$cols = array();
121
122
		foreach ( $columns as $key => $value ) {
123
124
			switch ( $key ) {
125
				case 'full_name' :
126
					$cols['full_name'] = esc_html__( 'Full Name', 'give' );
127
					break;
128
				case 'email' :
129
					$cols['email'] = esc_html__( 'Email Address', 'give' );
130
					break;
131
				case 'address' :
132
					$cols['address_line1']   = esc_html__( 'Address', 'give' );
133
					$cols['address_line2']   = esc_html__( 'Address 2', 'give' );
134
					$cols['address_city']    = esc_html__( 'City', 'give' );
135
					$cols['address_state']   = esc_html__( 'State', 'give' );
136
					$cols['address_zip']     = esc_html__( 'Zip', 'give' );
137
					$cols['address_country'] = esc_html__( 'Country', 'give' );
138
					break;
139
				case 'userid' :
140
					$cols['userid'] = esc_html__( 'User ID', 'give' );
141
					break;
142
				case 'date_first_donated' :
143
					$cols['date_first_donated'] = esc_html__( 'First Donation Date', 'give' );
144
					break;
145
				case 'donations' :
146
					$cols['donations'] = esc_html__( 'Number of Donations', 'give' );
147
					break;
148
				case 'donation_sum' :
149
					$cols['donation_sum'] = esc_html__( 'Sum of Donations', 'give' );
150
					break;
151
			}
152
		}
153
154
		return $cols;
155
156
	}
157
158
	/**
159
	 * Get the Export Data
160
	 *
161
	 * @access public
162
	 * @since  1.0
163
	 * @global object $give_logs Give Logs Object
164
	 * @return array $data The data for the CSV file
165
	 */
166
	public function get_data() {
167
168
		$data = array();
169
170
		$i = 0;
171
172
		if ( ! empty( $this->form ) ) {
173
174
			// Export donors of a specific product
175
			global $give_logs;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
176
177
			$args = array(
178
				'post_parent'    => absint( $this->form ),
179
				'log_type'       => 'sale',
180
				'posts_per_page' => 30,
181
				'paged'          => $this->step,
182
			);
183
184
			// Check for price option
185
			if ( null !== $this->price_id ) {
186
				$args['meta_query'] = array(
187
					array(
188
						'key'   => '_give_log_price_id',
189
						'value' => (int) $this->price_id,
190
					),
191
				);
192
			}
193
194
			$logs = $give_logs->get_connected_logs( $args );
195
196
			if ( $logs ) {
197
				foreach ( $logs as $log ) {
198
					$payment_id = get_post_meta( $log->ID, '_give_log_payment_id', true );
199
					$payment    = new Give_Payment( $payment_id );
200
201
					// Continue if donor already included.
202
					if( in_array( $payment->customer_id , $this->donor_ids ) ) {
203
						continue;
204
					}
205
206
					$this->donor_ids[] = $payment->customer_id;
207
208
					$donor      = Give()->customers->get_customer_by( 'id', $payment->customer_id );
209
					$data[]     = $this->set_donor_data( $i, $data, $donor );
210
					$i ++;
211
				}
212
213
				// Cache donor ids only if admin export donor for specific form.
214
				set_transient( $this->query_id, array_unique( $this->donor_ids ), HOUR_IN_SECONDS );
215
			}
216
		} else {
217
218
			// Export all customers
219
			$offset = 30 * ( $this->step - 1 );
220
			$donors = Give()->customers->get_customers( array( 'number' => 30, 'offset' => $offset ) );
221
222
			foreach ( $donors as $donor ) {
0 ignored issues
show
Bug introduced by
The expression $donors of type array|object|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
223
224
				$data[] = $this->set_donor_data( $i, $data, $donor );
225
				$i ++;
226
			}
227
		}
228
229
230
		$data = apply_filters( 'give_export_get_data', $data );
231
		$data = apply_filters( "give_export_get_data_{$this->export_type}", $data );
232
233
		return $data;
234
	}
235
236
	/**
237
	 * Return the calculated completion percentage
238
	 *
239
	 * @since 1.5
240
	 * @return int
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|double?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
241
	 */
242
	public function get_percentage_complete() {
243
244
		$percentage = 0;
245
246
		// We can't count the number when getting them for a specific form
247
		if ( empty( $this->form ) ) {
248
249
			$total = Give()->customers->count();
250
251
			if ( $total > 0 ) {
252
253
				$percentage = ( ( 30 * $this->step ) / $total ) * 100;
254
255
			}
256
		}
257
258
		if ( $percentage > 100 ) {
259
			$percentage = 100;
260
		}
261
262
		return $percentage;
263
	}
264
265
	/**
266
	 * Set Donor Data
267
	 *
268
	 * @param int           $i
269
	 * @param array         $data
270
	 * @param Give_Customer $donor
271
	 *
272
	 * @return mixed
273
	 */
274
	private function set_donor_data( $i, $data, $donor ) {
275
276
		$columns = $this->csv_cols();
277
278
		// Set address variable
279
		$address = '';
280
		if ( isset( $donor->user_id ) && $donor->user_id > 0 ) {
281
			$address = give_get_donor_address( $donor->user_id );
282
		}
283
284
		// Set columns
285
		if ( ! empty( $columns['full_name'] ) ) {
286
			$data[ $i ]['full_name'] = $donor->name;
287
		}
288
		if ( ! empty( $columns['email'] ) ) {
289
			$data[ $i ]['email'] = $donor->email;
290
		}
291
		if ( ! empty( $columns['address_line1'] ) ) {
292
293
			$data[ $i ]['address_line1']   = isset( $address['line1'] ) ? $address['line1'] : '';
294
			$data[ $i ]['address_line2']   = isset( $address['line2'] ) ? $address['line2'] : '';
295
			$data[ $i ]['address_city']    = isset( $address['city'] ) ? $address['city'] : '';
296
			$data[ $i ]['address_state']   = isset( $address['state'] ) ? $address['state'] : '';
297
			$data[ $i ]['address_zip']     = isset( $address['zip'] ) ? $address['zip'] : '';
298
			$data[ $i ]['address_country'] = isset( $address['country'] ) ? $address['country'] : '';
299
		}
300
		if ( ! empty( $columns['userid'] ) ) {
301
			$data[ $i ]['userid'] = ! empty( $donor->user_id ) ? $donor->user_id : '';
302
		}
303
		if ( ! empty( $columns['date_first_donated'] ) ) {
304
			$data[ $i ]['date_first_donated'] = date_i18n( give_date_format(), strtotime( $donor->date_created ) );
305
		}
306
		if ( ! empty( $columns['donations'] ) ) {
307
			$data[ $i ]['donations'] = $donor->purchase_count;
308
		}
309
		if ( ! empty( $columns['donation_sum'] ) ) {
310
			$data[ $i ]['donation_sum'] = give_format_amount( $donor->purchase_value );
311
		}
312
313
		return $data[ $i ];
314
315
	}
316
317
}
318