Completed
Push — issue/3613v2 ( 6db57d )
by Ravinder
1303:17 queued 1297:33
created

Give_Donor_Wall::parse_atts()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 55
rs 8.9818
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
2
/**
3
 * Donors Gravatars
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Give_Donors_Gravatars
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
18
/**
19
 * Give_Donor_Wall Class
20
 *
21
 * This class handles donors.
22
 *
23
 * @since 2.2.0
24
 */
25
class Give_Donor_Wall {
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
26
	/**
27
	 * Instance.
28
	 *
29
	 * @since  2.2.0
30
	 * @access private
31
	 * @var Give_Donor_Wall
32
	 */
33
	static private $instance;
34
35
	/**
36
	 * Singleton pattern.
37
	 *
38
	 * @since  2.2.0
39
	 * @access private
40
	 */
41
	private function __construct() {
42
	}
43
44
45
	/**
46
	 * Get instance.
47
	 *
48
	 * @since  2.2.0
49
	 * @access public
50
	 * @return Give_Donor_Wall
51
	 */
52
	public static function get_instance() {
53
		if ( null === static::$instance ) {
54
			self::$instance = new static();
55
56
			self::$instance->setup_actions();
57
		}
58
59
		return self::$instance;
60
	}
61
62
	/**
63
	 * Setup the default hooks and actions
64
	 *
65
	 * @since  2.2.0
66
	 *
67
	 * @return void
68
	 */
69
	public function setup_actions() {
70
71
		add_shortcode( 'give_donor_wall', array( $this, 'render_shortcode' ) );
72
73
		add_action( 'wp_ajax_give_get_donor_comments', array( $this, 'ajax_handler' ) );
74
		add_action( 'wp_ajax_nopriv_give_get_donor_comments', array( $this, 'ajax_handler' ) );
75
76
	}
77
78
79
	/**
80
	 * Displays donors in a grid layout.
81
	 *
82
	 * @since  2.2.0
83
	 *
84
	 * @param array $atts                {
85
	 *                                   Optional. Attributes of the donor wall shortcode.
86
	 *
87
	 * @type int    $donors_per_page     Number of donors per page. Default '20'.
88
	 * @type int    $form_id             The donation form to filter donors by. Default is all forms (no filter).
89
	 * @type bool   $paged               Whether to paginate donors. Default 'true'.
90
	 * @type string $ids                 A comma-separated list of donor IDs to display. Default empty.
91
	 * @type string $columns             Maximum columns to display. Default 'best-fit'.
92
	 *                                   Accepts 'best-fit', '1', '2', '3', '4'.
93
	 * @type bool   $show_avatar         Whether to display the donor's gravatar image if available. Default 'true'.
94
	 * @type bool   $show_name           Whether to display the donor's full name, first and last. Default 'true'.
95
	 * @type bool   $show_total          Whether to display the donor's donation amount. Default 'true'.
96
	 * @type bool   $show_time           Whether to display date of the last donation. Default 'true'.
97
	 * @type bool   $show_comments       Whether to display the donor's comment if they left one. Default 'true'.
98
	 * @type int    $comment_length      The number of words to display for the comments before a "Read more" field
99
	 *                                   displays. Default '20'.
100
	 * @type string $readmore_text       Link label for modal in which donor can read full comment.
101
	 * @type string $loadmore_text       Button label which will load more donor comments.
102
	 * @type int    $avatar_size         Avatar image size in pixels without the "px". Default "60"
103
	 * @type string $orderby             The order in which you want the donors to appear. Accepts "donation_amount", "donation_count",
104
	 *                                   if donor donated same value for orderby attribute then they will short by created date (fallback)
105
	 * @type string $order               The order in which you want the donors to appear. Accepts "ASC". "DESC".
106
	 *
107
	 * }
108
	 * @return string|bool The markup of the form grid or false.
109
	 */
110
	public function render_shortcode( $atts ) {
111
112
		$give_settings = give_get_settings();
113
114
		$atts        = $this->parse_atts( $atts );
115
		$donor_query = $this->get_donor_query_atts( $atts );
116
		$donors      = $this->get_donors( $donor_query );
117
		$html        = '';
118
119
		if ( $donors ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $donors 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...
120
121
			ob_start();
122
123
			foreach ( $donors as $donor ) {
124
				// Give/templates/shortcode-donor-wall.php.
125
				give_get_template( 'shortcode-donor-wall', array( $donor, $give_settings, $atts ) );
126
			}
127
128
			$html = ob_get_clean();
129
130
			// Return only donor html.
131
			if (
132
				isset( $atts['only_donor_html'] )
133
				&& wp_doing_ajax()
134
				&& $atts['only_donor_html']
135
			) {
136
				return $html;
137
			}
138
		}
139
140
		$next_donor_query           = $donor_query;
141
		$next_donor_query['paged']  = $next_donor_query['paged'] + 1;
142
		$next_donor_query['fields'] = 'id';
143
144
		$more_btn_html = '';
145
		if ( $this->get_donors( $next_donor_query ) ) {
146
			$more_btn_html = sprintf(
147
				'<button class="give-donor__load_more give-button-with-loader" data-shortcode="%1$s"><span class="give-loading-animation"></span>%2$s</button>',
148
				rawurlencode( http_build_query( $atts ) ),
149
				$atts['loadmore_text']
150
			);
151
		}
152
153
		$html = $html
154
			? sprintf(
155
				'<div class="give-wrap give-grid-ie-utility"><div class="give-grid give-grid--%1$s">%2$s</div>%3$s</div>',
156
				esc_attr( $atts['columns'] ),
157
				$html,
158
				$more_btn_html
159
			)
160
			: '';
161
162
		return $html;
163
	}
164
165
	/**
166
	 * Parse shortcode attributes
167
	 *
168
	 * @since  2.2.0
169
	 * @access public
170
	 *
171
	 * @param array $atts Shortcode attributes.
172
	 *
173
	 * @return array
174
	 */
175
	public function parse_atts( $atts ) {
176
		$atts = shortcode_atts(
177
			array(
178
				'donors_per_page' => 20,
179
				'form_id'         => 0,
180
				'paged'           => 1,
181
				'ids'             => '',
182
				'columns'         => 'best-fit',
183
				'show_avatar'     => true,
184
				'show_name'       => true,
185
				'show_total'      => true,
186
				'show_time'       => true,
187
				'show_comments'   => true,
188
				'show_anonymous'  => false,
189
				'comment_length'  => 20,
190
				'only_comments'   => false,
191
				'readmore_text'   => esc_html__( 'Read More', 'give' ),
192
				'loadmore_text'   => esc_html__( 'Load More', 'give' ),
193
				'avatar_size'     => 60,
194
				'orderby'         => 'donation_count',
195
				'order'           => 'DESC',
196
				'hide_empty'      => true,
197
				'only_donor_html' => false, // Only for internal use.
198
			), $atts
199
		);
200
201
		// Validate integer attributes.
202
		$atts['donors_per_page'] = absint( $atts['donors_per_page'] );
203
204
		// Validate boolean attributes.
205
		$boolean_attributes = array(
206
			'show_avatar',
207
			'show_name',
208
			'show_total',
209
			'show_time',
210
			'show_comments',
211
			'show_comments',
212
			'show_anonymous',
213
			'hide_empty',
214
			'only_comments',
215
			'only_donor_html',
216
		);
217
218
		foreach ( $boolean_attributes as $att ) {
219
			// Convert numeric to boolean.
220
			// It will prevent condition check against boolean value.
221
			if ( is_numeric( $atts[ $att ] ) ) {
222
				$atts[ $att ] = (bool) $atts[ $att ];
223
			}
224
225
			$atts[ $att ] = filter_var( $atts[ $att ], FILTER_VALIDATE_BOOLEAN );
226
		}
227
228
		return $atts;
229
	}
230
231
	/**
232
	 * Get donor query from shortcode attribiutes
233
	 *
234
	 * @since  2.2.0
235
	 * @access public
236
	 *
237
	 * @param array $atts Shortcode attributes.
238
	 *
239
	 * @return array
240
	 */
241
	public function get_donor_query_atts( $atts ) {
242
		// Set default form query args.
243
		$donor_args = array(
244
			'number'     => $atts['donors_per_page'],
245
			'paged'      => $atts['paged'],
246
			'orderby'    => $atts['orderby'],
247
			'order'      => $atts['order'],
248
		);
249
250
		if ( ! $atts['show_anonymous'] ) {
251
			$donor_args['meta_query'] = array(
0 ignored issues
show
introduced by
Detected usage of meta_query, possible slow query.
Loading history...
252
				// Hide anonymous donor.
253
				array(
254
					'key'     => '_give_anonymous_donor',
255
					'value'   => '1',
256
					'compare' => '!='
257
				)
258
			);
259
		}
260
261
		// Hide donors with zero donation amount.
262
		if ( $atts['hide_empty'] ) {
263
			$donor_args['donation_amount'] = array(
264
				'compare' => '>=',
265
				'amount'  => 1,
266
			);
267
		}
268
269
		// Show donor who donated to specific form.
270
		if ( $atts['form_id'] ) {
271
			$donor_args['give_forms'] = $atts['form_id'];
272
		}
273
274
		// Show donor by id.
275
		if ( $atts['ids'] ) {
276
			$donor_args['donor'] = $atts['ids'];
277
		}
278
279
		// Replace donation with purchase because donor table has that prefix in column name.
280
		$donor_args['orderby'] = str_replace(
281
			array( 'donation', 'amount' ), array(
282
				'purchase',
283
				'value',
284
			), $atts['orderby']
285
		);
286
287
		// Add fallback orderby.
288
		$donor_args['orderby'] = array(
289
			$donor_args['orderby'] => $donor_args['order'],
290
			'date_created'         => 'DESC',
291
		);
292
293
		unset( $donor_args['order'] );
294
295
		// Set payment query.
296
		// @codingStandardsIgnoreStart
297
		if ( true === $atts['only_comments'] ) {
298
			$donor_args['meta_query']['relation'] = 'AND';
299
			$donor_args['meta_query'][] = array(
300
				array(
301
					'key'   => '_give_has_comment',
302
					'value' => '1',
303
				),
304
			);
305
		}
306
		// @codingStandardsIgnoreEnd
307
308
		return $donor_args;
309
	}
310
311
	/**
312
	 * Get donors
313
	 *
314
	 * @since  2.2.0
315
	 * @access public
316
	 *
317
	 * @param array $donor_query Dorno query.
318
	 *
319
	 * @return array
320
	 */
321
	public function get_donors( $donor_query ) {
322
		$donor_query = new Give_Donors_Query( $donor_query );
323
		$donors      = $donor_query->get_donors();
324
325
		return $donors;
326
	}
327
328
329
	/**
330
	 * Ajax handler
331
	 *
332
	 * @since  2.2.0
333
	 * @access public
334
	 */
335
	public function ajax_handler() {
336
		$shortcode_atts = wp_parse_args( give_clean( rawurldecode( $_POST['data'] ) ) ); // @codingStandardsIgnoreLine
337
338
		// Get next page donor comments.
339
		$shortcode_atts['paged']           = $shortcode_atts['paged'] + 1;
340
		$shortcode_atts['only_donor_html'] = true;
341
342
		$donors_comment_html = $this->render_shortcode( $shortcode_atts );
343
344
		// Check if donor comment remaining.
345
		$donor_query           = $this->get_donor_query_atts( $shortcode_atts );
346
		$donor_query['paged']  = $donor_query['paged'] + 1;
347
		$donor_query['fields'] = 'id';
348
		$has_donors            = $this->get_donors( $donor_query ) ? 1 : 0;
349
350
		// Remove internal shortcode param.
351
		unset( $shortcode_atts['only_donor_html'] );
352
353
		wp_send_json(
354
			array(
355
				'shortcode' => rawurlencode( http_build_query( $shortcode_atts ) ),
356
				'html'      => $donors_comment_html,
357
				'remaining' => $has_donors,
358
			)
359
		);
360
	}
361
}
362
363
// Initialize shortcode.
364
Give_Donor_Wall::get_instance();
365