Test Failed
Push — master ( 966cf3...fe1ced )
by Devin
13:57 queued 06:53
created

Give_DB_Logs::get_sql()   F

Complexity

Conditions 17
Paths 3456

Size

Total Lines 101
Code Lines 52

Duplication

Lines 26
Ratio 25.74 %

Importance

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