Test Failed
Push — master ( f5256c...25a383 )
by Devin
07:02
created

Give_Donor_Wall::parse_atts()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 53
rs 9.0254
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 View Code Duplication
	public static function get_instance() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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"><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
				'comment_length'  => 20,
189
				'only_comments'   => true,
190
				'readmore_text'   => esc_html__( 'Read More', 'give' ),
191
				'loadmore_text'   => esc_html__( 'Load More', 'give' ),
192
				'avatar_size'     => 60,
193
				'orderby'         => 'donation_count',
194
				'order'           => 'DESC',
195
				'hide_empty'      => true,
196
				'only_donor_html' => false, // Only for internal use.
197
			), $atts
198
		);
199
200
		// Validate integer attributes.
201
		$atts['donors_per_page'] = absint( $atts['donors_per_page'] );
202
203
		// Validate boolean attributes.
204
		$boolean_attributes = array(
205
			'show_avatar',
206
			'show_name',
207
			'show_total',
208
			'show_time',
209
			'show_comments',
210
			'show_comments',
211
			'hide_empty',
212
			'only_comments',
213
			'only_donor_html',
214
		);
215
216
		foreach ( $boolean_attributes as $att ) {
217
			// Convert numeric to boolean.
218
			// It will prevent condition check against boolean value.
219
			if ( is_numeric( $atts[ $att ] ) ) {
220
				$atts[ $att ] = (bool) $atts[ $att ];
221
			}
222
223
			$atts[ $att ] = filter_var( $atts[ $att ], FILTER_VALIDATE_BOOLEAN );
224
		}
225
226
		return $atts;
227
	}
228
229
	/**
230
	 * Get donor query from shortcode attribiutes
231
	 *
232
	 * @since  2.2.0
233
	 * @access public
234
	 *
235
	 * @param array $atts Shortcode attributes.
236
	 *
237
	 * @return array
238
	 */
239
	public function get_donor_query_atts( $atts ) {
240
		// Set default form query args.
241
		$donor_args = array(
242
			'number'  => $atts['donors_per_page'],
243
			'paged'   => $atts['paged'],
244
			'orderby' => $atts['orderby'],
245
			'order'   => $atts['order'],
246
		);
247
248
		// Hide donors with zero donation amount.
249
		if ( $atts['hide_empty'] ) {
250
			$donor_args['donation_amount'] = array(
251
				'compare' => '>=',
252
				'amount'  => 1,
253
			);
254
		}
255
256
		// Show donor who donated to specific form.
257
		if ( $atts['form_id'] ) {
258
			$donor_args['give_forms'] = $atts['form_id'];
259
		}
260
261
		// Show donor by id.
262
		if ( $atts['ids'] ) {
263
			$donor_args['donor'] = $atts['ids'];
264
		}
265
266
		// Replace donation with purchase because donor table has that prefix in column name.
267
		$donor_args['orderby'] = str_replace(
268
			array( 'donation', 'amount' ), array(
269
				'purchase',
270
				'value',
271
			), $atts['orderby']
272
		);
273
274
		// Add fallback orderby.
275
		$donor_args['orderby'] = array(
276
			$donor_args['orderby'] => $donor_args['order'],
277
			'date_created'         => 'DESC',
278
		);
279
280
		unset( $donor_args['order'] );
281
282
		// Set payment query.
283
		// @codingStandardsIgnoreStart
284
		if ( true === $atts['only_comments'] ) {
285
			$donor_args['meta_query'] = array(
286
				array(
287
					'key'   => '_give_has_comment',
288
					'value' => '1',
289
				),
290
			);
291
		}
292
		// @codingStandardsIgnoreEnd
293
294
		return $donor_args;
295
	}
296
297
	/**
298
	 * Get donors
299
	 *
300
	 * @since  2.2.0
301
	 * @access public
302
	 *
303
	 * @param array $donor_query Dorno query.
304
	 *
305
	 * @return array
306
	 */
307
	public function get_donors( $donor_query ) {
308
		$donor_query = new Give_Donors_Query( $donor_query );
309
		$donors      = $donor_query->get_donors();
310
311
		return $donors;
312
	}
313
314
315
	/**
316
	 * Ajax handler
317
	 *
318
	 * @since  2.2.0
319
	 * @access public
320
	 */
321
	public function ajax_handler() {
322
		$shortcode_atts = wp_parse_args( give_clean( rawurldecode( $_POST['data'] ) ) ); // @codingStandardsIgnoreLine
323
324
		// Get next page donor comments.
325
		$shortcode_atts['paged']           = $shortcode_atts['paged'] + 1;
326
		$shortcode_atts['only_donor_html'] = true;
327
328
		$donors_comment_html = $this->render_shortcode( $shortcode_atts );
329
330
		// Check if donor comment remaining.
331
		$donor_query           = $this->get_donor_query_atts( $shortcode_atts );
332
		$donor_query['paged']  = $donor_query['paged'] + 1;
333
		$donor_query['fields'] = 'id';
334
		$has_donors            = $this->get_donors( $donor_query ) ? 1 : 0;
335
336
		// Remove internal shortcode param.
337
		unset( $shortcode_atts['only_donor_html'] );
338
339
		wp_send_json(
340
			array(
341
				'shortcode' => rawurlencode( http_build_query( $shortcode_atts ) ),
342
				'html'      => $donors_comment_html,
343
				'remaining' => $has_donors,
344
			)
345
		);
346
	}
347
}
348
349
// Initialize shortcode.
350
Give_Donor_Wall::get_instance();
351