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

Give_Batch_Payments_Export   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 237
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 237
rs 8.2857
wmc 39
lcom 1
cbo 1

4 Methods

Rating   Name   Duplication   Size   Complexity  
B csv_cols() 0 29 2
F get_data() 0 131 29
B get_percentage_complete() 0 30 4
A set_properties() 0 5 4
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
 * Payments Export Class
4
 *
5
 * This class handles payment export in batches
6
 *
7
 * @package     Give
8
 * @subpackage  Admin/Reports
9
 * @copyright   Copyright (c) 2016, WordImpress
10
 * @license     http://opensource.org/licenses/gpl-2.0.php 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_Payments_Export Class
21
 *
22
 * @since 1.5
23
 */
24
class Give_Batch_Payments_Export extends Give_Batch_Export {
25
26
	/**
27
	 * Our export type. Used for export-type specific filters/actions
28
	 * @var string
29
	 * @since 1.5
30
	 */
31
	public $export_type = 'payments';
32
33
	/**
34
	 * Set the CSV columns
35
	 *
36
	 * @access public
37
	 * @since 1.5
38
	 * @return array $cols All the columns
39
	 */
40
	public function csv_cols() {
41
		$cols = array(
42
			'id'       => __( 'ID', 'give' ), // unaltered payment ID (use for querying)
43
			'seq_id'   => __( 'Payment Number', 'give' ), // sequential payment ID
44
			'email'    => __( 'Email', 'give' ),
45
			'first'    => __( 'First Name', 'give' ),
46
			'last'     => __( 'Last Name', 'give' ),
47
			'address1' => __( 'Address', 'give' ),
48
			'address2' => __( 'Address (Line 2)', 'give' ),
49
			'city'     => __( 'City', 'give' ),
50
			'state'    => __( 'State', 'give' ),
51
			'country'  => __( 'Country', 'give' ),
52
			'zip'      => __( 'Zip / Postal Code', 'give' ),
53
			'products' => __( 'Products', 'give' ),
54
			'amount'   => __( 'Amount', 'give' ) . ' (' . html_entity_decode( give_currency_filter( '' ) ) . ')',
55
			'gateway'  => __( 'Payment Method', 'give' ),
56
			'trans_id' => __( 'Transaction ID', 'give' ),
57
			'key'      => __( 'Purchase Key', 'give' ),
58
			'date'     => __( 'Date', 'give' ),
59
			'user'     => __( 'User', 'give' ),
60
			'status'   => __( 'Status', 'give' )
61
		);
62
63
		if ( ! give_get_option( 'enable_sequential' ) ) {
64
			unset( $cols['seq_id'] );
65
		}
66
67
		return $cols;
68
	}
69
70
	/**
71
	 * Get the Export Data
72
	 *
73
	 * @access public
74
	 * @since 1.5
75
	 * @global object $wpdb Used to query the database using the WordPress
76
	 *   Database API
77
	 * @return array $data The data for the CSV file
78
	 */
79
	public function get_data() {
80
		global $wpdb;
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...
81
82
		$data = array();
83
84
		$args = array(
85
			'number' => 30,
86
			'page'   => $this->step,
87
			'status' => $this->status
88
		);
89
90
		if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
91
92
			$args['date_query'] = array(
93
				array(
94
					'after'     => date( 'Y-n-d 00:00:00', strtotime( $this->start ) ),
95
					'before'    => date( 'Y-n-d 23:59:59', strtotime( $this->end ) ),
96
					'inclusive' => true
97
				)
98
			);
99
100
		}
101
102
		//echo json_encode($args ); exit;
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
103
104
		$payments = give_get_payments( $args );
105
106
		if ( $payments ) {
107
108
			foreach ( $payments as $payment ) {
109
				$payment_meta = give_get_payment_meta( $payment->ID );
110
				$user_info    = give_get_payment_meta_user_info( $payment->ID );
111
				$total        = give_get_payment_amount( $payment->ID );
112
				$user_id      = isset( $user_info['id'] ) && $user_info['id'] != - 1 ? $user_info['id'] : $user_info['email'];
113
				$products     = '';
114
				$skus         = '';
115
116
				if ( $downloads ) {
117
					foreach ( $downloads as $key => $download ) {
118
119
						// Form ID
120
						$id  = isset( $payment_meta['cart_details'] ) ? $download['id'] : $download;
121
						$qty = isset( $download['quantity'] ) ? $download['quantity'] : 1;
122
123
						if ( isset( $download['price'] ) ) {
124
							$price = $download['price'];
125
						} else {
126
							// If the download has variable prices, override the default price
127
							$price_override = isset( $payment_meta['cart_details'] ) ? $download['price'] : null;
128
							$price          = give_get_download_final_price( $id, $user_info, $price_override );
129
						}
130
131
132
						// Display the Downoad Name
133
						$products .= html_entity_decode( get_the_title( $id ) );
134
135
						if ( $qty > 1 ) {
136
							$products .= html_entity_decode( ' (' . $qty . ')' );
137
						}
138
139
						$products .= ' - ';
140
141
						if ( give_use_skus() ) {
142
							$sku = give_get_download_sku( $id );
143
144
							if ( ! empty( $sku ) ) {
145
								$skus .= $sku;
146
							}
147
						}
148
149
						if ( isset( $downloads[ $key ]['item_number'] ) && isset( $downloads[ $key ]['item_number']['options'] ) ) {
150
							$price_options = $downloads[ $key ]['item_number']['options'];
151
152
							if ( isset( $price_options['price_id'] ) ) {
153
								$products .= html_entity_decode( give_get_price_option_name( $id, $price_options['price_id'], $payment->ID ) ) . ' - ';
154
							}
155
						}
156
157
						$products .= html_entity_decode( give_currency_filter( give_format_amount( $price ) ) );
158
159
						if ( $key != ( count( $downloads ) - 1 ) ) {
0 ignored issues
show
Bug introduced by
The variable $downloads does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
160
							$products .= ' / ';
161
162
							if ( give_use_skus() ) {
163
								$skus .= ' / ';
164
							}
165
						}
166
					}
167
				}
168
169
				if ( is_numeric( $user_id ) ) {
170
					$user = get_userdata( $user_id );
171
				} else {
172
					$user = false;
173
				}
174
175
				$data[] = array(
176
					'id'       => $payment->ID,
177
					'seq_id'   => give_get_payment_number( $payment->ID ),
178
					'email'    => $payment_meta['email'],
179
					'first'    => $user_info['first_name'],
180
					'last'     => $user_info['last_name'],
181
					'address1' => isset( $user_info['address']['line1'] ) ? $user_info['address']['line1'] : '',
182
					'address2' => isset( $user_info['address']['line2'] ) ? $user_info['address']['line2'] : '',
183
					'city'     => isset( $user_info['address']['city'] ) ? $user_info['address']['city'] : '',
184
					'state'    => isset( $user_info['address']['state'] ) ? $user_info['address']['state'] : '',
185
					'country'  => isset( $user_info['address']['country'] ) ? $user_info['address']['country'] : '',
186
					'zip'      => isset( $user_info['address']['zip'] ) ? $user_info['address']['zip'] : '',
187
					'products' => $products,
188
					'skus'     => $skus,
189
					'amount'   => html_entity_decode( give_format_amount( $total ) ),
190
					'gateway'  => give_get_gateway_admin_label( get_post_meta( $payment->ID, '_give_payment_gateway', true ) ),
191
					'trans_id' => give_get_payment_transaction_id( $payment->ID ),
192
					'key'      => $payment_meta['key'],
193
					'date'     => $payment->post_date,
194
					'user'     => $user ? $user->display_name : __( 'guest', 'give' ),
195
					'status'   => give_get_payment_status( $payment, true )
196
				);
197
198
			}
199
200
			$data = apply_filters( 'give_export_get_data', $data );
201
			$data = apply_filters( 'give_export_get_data_' . $this->export_type, $data );
202
203
			return $data;
204
205
		}
206
207
		return false;
208
209
	}
210
211
	/**
212
	 * Return the calculated completion percentage
213
	 *
214
	 * @since 1.5
215
	 * @return int
216
	 */
217
	public function get_percentage_complete() {
218
219
		$status = $this->status;
220
		$args   = array(
221
			'start-date' => date( 'n/d/Y', strtotime( $this->start ) ),
222
			'end-date'   => date( 'n/d/Y', strtotime( $this->end ) ),
223
		);
224
225
		if ( 'any' == $status ) {
226
227
			$total = array_sum( (array) give_count_payments( $args ) );
228
229
		} else {
230
231
			$total = give_count_payments( $args )->$status;
232
233
		}
234
235
		$percentage = 100;
236
237
		if ( $total > 0 ) {
238
			$percentage = ( ( 30 * $this->step ) / $total ) * 100;
239
		}
240
241
		if ( $percentage > 100 ) {
242
			$percentage = 100;
243
		}
244
245
		return $percentage;
246
	}
247
248
	/**
249
	 * Set the properties specific to the payments export
250
	 *
251
	 * @since 1.5
252
	 *
253
	 * @param array $request The Form Data passed into the batch processing
254
	 */
255
	public function set_properties( $request ) {
256
		$this->start  = isset( $request['start'] ) ? sanitize_text_field( $request['start'] ) : '';
257
		$this->end    = isset( $request['end'] ) ? sanitize_text_field( $request['end'] ) : '';
258
		$this->status = isset( $request['status'] ) ? sanitize_text_field( $request['status'] ) : 'complete';
259
	}
260
}
261