Give_DB_Logs::get_logs()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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