Give_DB_Comments::get_sql()   F
last analyzed

Complexity

Conditions 17
Paths 3456

Size

Total Lines 101

Duplication

Lines 101
Ratio 100 %

Importance

Changes 0
Metric Value
cc 17
nc 3456
nop 1
dl 101
loc 101
rs 0.8399
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
 * Custom Comments & Notes
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Give_DB_Comments
7
 * @copyright   Copyright (c) 2018, GiveWP
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       2.3.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Give_DB_Comments Class
19
 *
20
 * This class is for interacting with the comment database table.
21
 *
22
 * @since 2.3.0
23
 */
24
class Give_DB_Comments extends Give_DB {
25
26
	/**
27
	 * Give_DB_Comments constructor.
28
	 *
29
	 * Set up the Give DB Donor class.
30
	 *
31
	 * @since  2.3.0
32
	 * @access public
33
	 */
34
	public function __construct() {
35
		/* @var WPDB $wpdb */
36
		global $wpdb;
37
38
		$wpdb->give_comments = $this->table_name = $wpdb->prefix . 'give_comments';
39
		$this->primary_key   = 'comment_ID';
40
		$this->version       = '1.0';
41
42
		parent::__construct();
43
	}
44
45
	/**
46
	 * Get columns and formats
47
	 *
48
	 * @since  2.3.0
49
	 * @access public
50
	 *
51
	 * @return array  Columns and formats.
52
	 */
53
	public function get_columns() {
54
		return array(
55
			'comment_ID'       => '%d',
56
			'user_id'          => '%d',
57
			'comment_content'  => '%s',
58
			'comment_parent'   => '%s',
59
			'comment_type'     => '%s',
60
			'comment_date'     => '%s',
61
			'comment_date_gmt' => '%s',
62
		);
63
	}
64
65
	/**
66
	 * Get default column values
67
	 *
68
	 * @since  2.3.0
69
	 * @access public
70
	 *
71
	 * @return array  Default column values.
72
	 */
73
	public function get_column_defaults() {
74
		$comment_create_date     = current_time( 'mysql', 0 );
75
		$comment_create_date_gmt = get_gmt_from_date( $comment_create_date );
76
77
		return array(
78
			'comment_ID'       => 0,
79
			'user_id'          => 0,
80
			'comment_content'  => '',
81
			'comment_parent'   => 0,
82
			'comment_type'     => '',
83
			'comment_date'     => $comment_create_date,
84
			'comment_date_gmt' => $comment_create_date_gmt,
85
		);
86
	}
87
88
	/**
89
	 * Add a comment
90
	 *
91
	 * @since  2.3.0
92
	 * @access public
93
	 *
94
	 * @param  array $data
95
	 *
96
	 * @return bool|int
97
	 */
98
	public function add( $data = array() ) {
99
		// Valid table columns.
100
		$table_columns = array_keys( $this->get_columns() );
101
102
		// Filter data.
103
		foreach ( $data as $table_column => $column_data ) {
104
			if ( ! in_array( $table_column, $table_columns ) ) {
105
				unset( $data[ $table_column ] );
106
			}
107
		}
108
109
		// Set default values.
110
		$current_comment_data = wp_parse_args( $data, $this->get_column_defaults() );
111
112
		// Filter comment content. Filter documented in /wp-includes/comment.php
113
		$current_comment_data['comment_content'] = apply_filters( 'pre_comment_content', $current_comment_data['comment_content'] );
114
115
		// Strip out backslash for apostrophe and sanitize comment using give_clean.
116
		$current_comment_data['comment_content'] = isset( $current_comment_data['comment_content'] )
117
			? wp_unslash( wp_strip_all_tags( $current_comment_data['comment_content'] ) )
118
			: $current_comment_data['comment_content'];
119
120
		// Comment parent should be an int.
121
		$current_comment_data['comment_parent'] = is_numeric( $current_comment_data['comment_parent'] )
122
			? absint( $current_comment_data['comment_parent'] )
123
			: $current_comment_data['comment_parent'];
124
125
		// Get comment.
126
		$existing_comment = $this->get_comment_by( $current_comment_data['comment_ID'] );
127
128
		// Update an existing comment.
129
		if ( $existing_comment ) {
130
131
			// Create new comment data from existing and new comment data.
132
			$current_comment_data = wp_parse_args( $current_comment_data, $existing_comment );
133
134
			// Update comment data.
135
			$this->update( $current_comment_data['comment_ID'], $current_comment_data );
136
137
			$comment_id = $current_comment_data['comment_ID'];
138
139
		} else {
140
			$comment_id = $this->insert( $current_comment_data, 'comment' );
141
		}
142
143
		return $comment_id;
144
	}
145
146
147
	/**
148
	 * Retrieves a single comment from the database
149
	 *
150
	 * @since  2.3.0
151
	 * @access public
152
	 *
153
	 * @param int    $comment_id
154
	 * @param string $by
155
	 *
156
	 * @return bool|null|array
157
	 */
158 View Code Duplication
	public function get_comment_by( $comment_id = 0, $by = 'id' ) {
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...
159
		/* @var WPDB $wpdb */
160
		global $wpdb;
161
		$comment = null;
162
163
		// Make sure $comment_id is int.
164
		$comment_id = absint( $comment_id );
165
166
		// Bailout.
167
		if ( empty( $comment_id ) ) {
168
			return null;
169
		}
170
171
		switch ( $by ) {
172
			case 'id':
173
				$comment = $wpdb->get_row(
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
174
					$wpdb->prepare(
175
						"SELECT * FROM $this->table_name WHERE comment_ID = %s LIMIT 1",
176
						$comment_id
177
					),
178
					ARRAY_A
179
				);
180
				break;
181
182
			default:
183
				$comment = apply_filters( "give_get_comment_by_{$by}", $comment, $comment_id );
184
		}
185
186
		return $comment;
187
	}
188
189
	/**
190
	 * Retrieve comments from the database.
191
	 *
192
	 * @since  2.3.0
193
	 * @access public
194
	 *
195
	 * @param  array $args
196
	 *
197
	 * @return mixed
198
	 */
199
	public function get_comments( $args = array() ) {
200
		global $wpdb;
201
		$sql_query = $this->get_sql( $args );
202
203
		// Get comment.
204
		$comments = $wpdb->get_results( $sql_query );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
205
206
		return $comments;
207
	}
208
209
210
	/**
211
	 * Count the total number of comments in the database
212
	 *
213
	 * @since  2.3.0
214
	 * @access public
215
	 *
216
	 * @param  array $args
217
	 *
218
	 * @return int
219
	 */
220
	public function count( $args = array() ) {
221
		/* @var WPDB $wpdb */
222
		global $wpdb;
223
		$args['number'] = - 1;
224
		$args['fields'] = 'comment_ID';
225
		$args['count']  = true;
226
227
		$sql_query = $this->get_sql( $args );
228
229
		$count = $wpdb->get_var( $sql_query );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
230
231
		return absint( $count );
232
	}
233
234
	/**
235
	 * Create the table
236
	 *
237
	 * @since  2.3.0
238
	 * @access public
239
	 *
240
	 * @return void
241
	 */
242 View Code Duplication
	public function create_table() {
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...
243
		global $wpdb;
244
		$charset_collate = $wpdb->get_charset_collate();
245
246
		$sql = "CREATE TABLE {$this->table_name} (
247
        comment_ID bigint(20) NOT NULL AUTO_INCREMENT,
248
        user_id bigint(20) NOT NULL,
249
        comment_content longtext NOT NULL,
250
      	comment_parent mediumtext NOT NULL,
251
        comment_type mediumtext NOT NULL,
252
        comment_date datetime NOT NULL,
253
        comment_date_gmt datetime NOT NULL,
254
        PRIMARY KEY  (comment_ID)
255
        ) {$charset_collate};";
256
257
		require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
258
		dbDelta( $sql );
259
260
		update_option( $this->table_name . '_db_version', $this->version, false );
261
	}
262
263
264
	/**
265
	 * Get sql query from quaried array.
266
	 *
267
	 * @since  2.3.0
268
	 * @access public
269
	 *
270
	 * @param array $args
271
	 *
272
	 * @return string
273
	 */
274 View Code Duplication
	public function get_sql( $args = array() ) {
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...
275
		/* @var WPDB $wpdb */
276
		global $wpdb;
277
278
		$defaults = array(
279
			'number'  => 20,
280
			'offset'  => 0,
281
			'paged'   => 0,
282
			'orderby' => 'date',
283
			'order'   => 'DESC',
284
			'fields'  => 'all',
285
			'count'   => false,
286
		);
287
288
		$args = wp_parse_args( $args, $defaults );
289
290
		// validate params.
291
		$this->validate_params( $args );
292
293
		if ( $args['number'] < 1 ) {
294
			$args['number'] = 99999999999;
295
		}
296
297
		// Where clause for primary table.
298
		$where = '';
299
300
		// Get sql query for meta.
301
		if ( ! empty( $args['meta_query'] ) ) {
302
			$meta_query_object = new WP_Meta_Query( $args['meta_query'] );
303
			$meta_query        = $meta_query_object->get_sql( 'give_comment', $this->table_name, 'comment_ID' );
304
			$where             = implode( '', $meta_query );
305
		}
306
307
		$where .= ' WHERE 1=1 ';
308
309
		// Set offset.
310
		if ( empty( $args['offset'] ) && ( 0 < $args['paged'] ) ) {
311
			$args['offset'] = $args['number'] * ( $args['paged'] - 1 );
312
		}
313
314
		// Set fields.
315
		$fields = "{$this->table_name}.*";
316
		if ( is_string( $args['fields'] ) && ( 'all' !== $args['fields'] ) ) {
317
			$fields = "{$this->table_name}.{$args['fields']}";
318
		}
319
320
		// Set count.
321
		if ( $args['count'] ) {
322
			$fields = "COUNT({$fields})";
323
		}
324
325
		// Specific comments.
326
		if ( ! empty( $args['comment_ID'] ) ) {
327
328
			if ( ! is_array( $args['comment_ID'] ) ) {
329
				$args['comment_ID'] = explode( ',', $args['comment_ID'] );
330
			}
331
			$comment_ids = implode( ',', array_map( 'intval', $args['comment_ID'] ) );
332
333
			$where .= " AND {$this->table_name}.comment_ID IN( {$comment_ids} ) ";
334
		}
335
336
		// Comments created for a specific date or in a date range
337
		if ( ! empty( $args['date_query'] ) ) {
338
			$date_query_object = new WP_Date_Query( $args['date_query'], "{$this->table_name}.comment_date" );
339
			$where             .= $date_query_object->get_sql();
340
		}
341
342
		// Comments create for specific parent.
343
		if ( ! empty( $args['comment_parent'] ) ) {
344
			if ( ! is_array( $args['comment_parent'] ) ) {
345
				$args['comment_parent'] = explode( ',', $args['comment_parent'] );
346
			}
347
			$parent_ids = implode( ',', array_map( 'intval', $args['comment_parent'] ) );
348
349
			$where .= " AND {$this->table_name}.comment_parent IN( {$parent_ids} ) ";
350
		}
351
352
		// Comments create for specific type.
353
		// is_array check is for backward compatibility.
354
		if ( ! empty( $args['comment_type'] ) && ! is_array( $args['comment_type'] ) ) {
355
			if ( ! is_array( $args['comment_type'] ) ) {
356
				$args['comment_type'] = explode( ',', $args['comment_type'] );
357
			}
358
359
			$comment_types = implode( '\',\'', array_map( 'trim', $args['comment_type'] ) );
360
361
			$where .= " AND {$this->table_name}.comment_type IN( '{$comment_types}' ) ";
362
		}
363
364
		$args['orderby'] = ! array_key_exists( $args['orderby'], $this->get_columns() ) ? 'comment_date' : $args['orderby'];
365
366
		$args['orderby'] = esc_sql( $args['orderby'] );
367
		$args['order']   = esc_sql( $args['order'] );
368
369
		return $wpdb->prepare(
370
			"SELECT {$fields} FROM {$this->table_name} {$where} ORDER BY {$this->table_name}.{$args['orderby']} {$args['order']} LIMIT %d,%d;",
371
			absint( $args['offset'] ),
372
			absint( $args['number'] )
373
		);
374
	}
375
376
377
	/**
378
	 * Validate query params.
379
	 *
380
	 * @since  2.3.0
381
	 * @access private
382
	 *
383
	 * @param $args
384
	 *
385
	 * @return mixed
386
	 */
387 View Code Duplication
	private function validate_params( &$args ) {
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...
388
		// fields params
389
		$args['fields'] = 'ids' === $args['fields']
390
			? 'comment_ID'
391
			: $args['fields'];
392
		$args['fields'] = array_key_exists( $args['fields'], $this->get_columns() )
393
			? $args['fields']
394
			: 'all';
395
	}
396
}
397
398
// @todo: update cache logic.
399
// @todo: create issue for log cache logic.
400