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

Give_Donor_Reports_Table::column_default()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 28
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 20
nc 6
nop 2
dl 0
loc 28
rs 8.439
c 0
b 0
f 0
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 29 and the first side effect is on line 14.

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
 * Donor Reports Table Class
4
 *
5
 * @package     Give
6
 * @subpackage  Admin/Reports
7
 * @copyright   Copyright (c) 2016, WordImpress
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
// Load WP_List_Table if not loaded
18
if ( ! class_exists( 'WP_List_Table' ) ) {
19
	require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
20
}
21
22
/**
23
 * Give_Donor_Reports_Table Class
24
 *
25
 * Renders the Donor Reports table
26
 *
27
 * @since 1.0
28
 */
29
class Give_Donor_Reports_Table extends WP_List_Table {
30
31
	/**
32
	 * Number of items per page
33
	 *
34
	 * @var int
35
	 * @since 1.0
36
	 */
37
	public $per_page = 30;
38
39
	/**
40
	 * Number of donors found
41
	 *
42
	 * @var int
43
	 * @since 1.0
44
	 */
45
	public $count = 0;
46
47
	/**
48
	 * Total donors
49
	 *
50
	 * @var int
51
	 * @since 1.0
52
	 */
53
	public $total = 0;
54
55
	/**
56
	 * Get things started
57
	 *
58
	 * @since 1.0
59
	 * @see   WP_List_Table::__construct()
60
	 */
61
	public function __construct() {
62
		global $status, $page;
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...
63
64
		// Set parent defaults
65
		parent::__construct( array(
66
			'singular' => esc_html__( 'Donor', 'give' ),     // Singular name of the listed records
67
			'plural'   => esc_html__( 'Donors', 'give' ),    // Plural name of the listed records
68
			'ajax'     => false                        // Does this table support ajax?
69
		) );
70
71
	}
72
73
	/**
74
	 * Remove default search field in favor for repositioned location
75
	 *
76
	 * Reposition the search field
77
	 *
78
	 * @since       1.0
79
	 * @access      public
80
	 *
81
	 * @param string $text     Label for the search box
82
	 * @param string $input_id ID of the search box
83
	 *
84
	 * @return false
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean?

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...
85
	 */
86
	public function search_box( $text, $input_id ) {
87
		return false;
88
	}
89
90
	/**
91
	 * Show the search field
92
	 *
93
	 * @since  1.0
94
	 * @access public
95
	 *
96
	 * @param string $text     Label for the search box
97
	 * @param string $input_id ID of the search box
98
	 *
99
	 * @return void
100
	 */
101
	public function give_search_box( $text, $input_id ) {
102
		$input_id = $input_id . '-search-input';
103
104
		if ( ! empty( $_REQUEST['orderby'] ) ) {
105
			echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
106
		}
107
		if ( ! empty( $_REQUEST['order'] ) ) {
108
			echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
109
		}
110
		?>
111
		<p class="search-box donor-search" role="search">
112
			<label class="screen-reader-text" for="<?php echo $input_id ?>"><?php echo $text; ?>:</label>
113
			<input type="search" id="<?php echo $input_id ?>" name="s" value="<?php _admin_search_query(); ?>" />
114
			<?php submit_button( $text, 'button', false, false, array( 'ID' => 'search-submit' ) ); ?>
115
		</p>
116
	<?php
117
	}
118
119
	/**
120
	 * Generate the table navigation above or below the table
121
	 *
122
	 * @since  1.0
123
	 * @access protected
124
	 *
125
	 * @param string $which
126
	 */
127
	protected function display_tablenav( $which ) {
128
129
		if ( 'top' === $which ) {
130
			wp_nonce_field( 'bulk-' . $this->_args['plural'] );
131
		}
132
		?>
133
		<div class="tablenav give-clearfix <?php echo esc_attr( $which ); ?>">
134
135
			<?php if ( 'top' === $which ) { ?>
136
				<h3 class="alignleft reports-earnings-title">
137
					<span><?php esc_html_e( 'Donors Report', 'give' ); ?></span>
138
				</h3>
139
			<?php } ?>
140
141
			<div class="alignright tablenav-right">
142
				<div class="actions bulkactions">
143
					<?php
144
					if ( 'top' === $which ) {
145
						$this->give_search_box( esc_html__( 'Search Donors', 'give' ), 'give-donors-report-search' );
146
					}
147
148
					$this->bulk_actions( $which ); ?>
149
150
				</div>
151
				<?php
152
				$this->extra_tablenav( $which );
153
				$this->pagination( $which );
154
				?>
155
			</div>
156
157
158
			<br class="clear" />
159
160
		</div>
161
	<?php
162
	}
163
164
	/**
165
	 * This function renders most of the columns in the list table.
166
	 *
167
	 * @access public
168
	 * @since  1.0
169
	 *
170
	 * @param array  $item        Contains all the data of the donors
171
	 * @param string $column_name The name of the column
172
	 *
173
	 * @return string Column Name
174
	 */
175
	public function column_default( $item, $column_name ) {
176
	    
177
		switch ( $column_name ) {
178
179
			case 'name' :
180
				$name = '#' . $item['id'] . ' ';
181
				$name .= ! empty( $item['name'] ) ? $item['name'] : '<em>' . esc_html__( 'Unnamed Donor', 'give' ) . '</em>';
182
				$view_url = admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=overview&id=' . $item['id'] );
183
				$value = '<a href="' . esc_url( $view_url ) . '">' . $name . '</a>';
184
				break;
185
				
186
			case 'num_donations' :
187
				$value = '<a href="' .
188
				         admin_url( 'edit.php?post_type=give_forms&page=give-payment-history&user=' . urlencode( $item['email'] )
189
				         ) . '">' . esc_html( $item['num_donations'] ) . '</a>';
190
				break;
191
192
			case 'amount_spent' :
193
				$value = give_currency_filter( give_format_amount( $item[ $column_name ] ) );
194
				break;
195
196
			default:
197
				$value = isset( $item[ $column_name ] ) ? $item[ $column_name ] : null;
198
				break;
199
		}
200
201
		return apply_filters( "give_report_column_{$column_name}", $value, $item['id'] );
202
	}
203
204
	/**
205
	 * Retrieve the table columns
206
	 *
207
	 * @access public
208
	 * @since  1.0
209
	 * @return array $columns Array of all the list table columns
210
	 */
211
	public function get_columns() {
212
		$columns = array(
213
			'name'          => esc_html__( 'Name', 'give' ),
214
			'email'         => esc_html__( 'Email', 'give' ),
215
			'num_donations' => esc_html__( 'Donations', 'give' ),
216
			'amount_spent'  => esc_html__( 'Total Donated', 'give' )
217
		);
218
219
		return apply_filters( 'give_report_donor_columns', $columns );
220
221
	}
222
223
	/**
224
	 * Get the sortable columns
225
	 *
226
	 * @access public
227
	 * @since  1.0
228
	 * @return array Array of all the sortable columns
229
	 */
230
	public function get_sortable_columns() {
231
		return array(
232
			'id'            => array( 'id', true ),
233
			'name'          => array( 'name', true ),
234
			'num_donations' => array( 'purchase_count', false ),
235
			'amount_spent'  => array( 'purchase_value', false ),
236
		);
237
	}
238
239
	/**
240
	 * Outputs the reporting views
241
	 *
242
	 * @access public
243
	 * @since  1.0
244
	 * @return void
245
	 */
246
	public function bulk_actions( $which = '' ) {
247
248
	}
249
250
	/**
251
	 * Retrieve the current page number
252
	 *
253
	 * @access public
254
	 * @since  1.0
255
	 * @return int Current page number
256
	 */
257
	public function get_paged() {
258
		return isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1;
259
	}
260
261
	/**
262
	 * Retrieves the search query string
263
	 *
264
	 * @access public
265
	 * @since  1.0
266
	 * @return mixed string If search is present, false otherwise
267
	 */
268
	public function get_search() {
269
		return ! empty( $_GET['s'] ) ? urldecode( trim( $_GET['s'] ) ) : false;
270
	}
271
272
	/**
273
	 * Build all the reports data
274
	 *
275
	 * @access public
276
	 * @since  1.0
277
	 * @global object $wpdb Used to query the database using the WordPress
278
	 *                      Database API
279
	 * @return array $reports_data All the data for donor reports
280
	 */
281
	public function reports_data() {
282
		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...
283
284
		$data    = array();
285
		$paged   = $this->get_paged();
286
		$offset  = $this->per_page * ( $paged - 1 );
287
		$search  = $this->get_search();
288
		$order   = isset( $_GET['order'] ) ? sanitize_text_field( $_GET['order'] ) : 'DESC';
289
		$orderby = isset( $_GET['orderby'] ) ? sanitize_text_field( $_GET['orderby'] ) : 'id';
290
291
		$args = array(
292
			'number'  => $this->per_page,
293
			'offset'  => $offset,
294
			'order'   => $order,
295
			'orderby' => $orderby
296
		);
297
298
		if ( is_email( $search ) ) {
299
			$args['email'] = $search;
300
		} elseif ( is_numeric( $search ) ) {
301
			$args['id'] = $search;
302
		}
303
304
		$donors = Give()->customers->get_customers( $args );
305
306
		if ( $donors ) {
307
308
			$this->count = count( $donors );
309
310
			foreach ( $donors as $donor ) {
311
312
				$user_id = ! empty( $donor->user_id ) ? absint( $donor->user_id ) : 0;
313
314
				$data[] = array(
315
					'id'            => $donor->id,
316
					'user_id'       => $user_id,
317
					'name'          => $donor->name,
318
					'email'         => $donor->email,
319
					'num_donations' => $donor->purchase_count,
320
					'amount_spent'  => $donor->purchase_value
321
				);
322
			}
323
		}
324
325
		return $data;
326
	}
327
328
	/**
329
	 * Setup the final data for the table
330
	 *
331
	 * @access public
332
	 * @since  1.0
333
	 * @uses   Give_Donor_Reports_Table::get_columns()
334
	 * @uses   WP_List_Table::get_sortable_columns()
335
	 * @uses   Give_Donor_Reports_Table::get_pagenum()
336
	 * @uses   Give_Donor_Reports_Table::get_total_donors()
337
	 * @return void
338
	 */
339
	public function prepare_items() {
340
341
		$columns  = $this->get_columns();
342
		$hidden   = array(); // No hidden columns
343
		$sortable = $this->get_sortable_columns();
344
345
		$this->_column_headers = array( $columns, $hidden, $sortable );
346
347
		$this->items = $this->reports_data();
348
349
		$this->total = give_count_total_customers();
350
351
		$this->set_pagination_args( array(
352
			'total_items' => $this->total,
353
			'per_page'    => $this->per_page,
354
			'total_pages' => ceil( $this->total / $this->per_page )
355
		) );
356
	}
357
}