Completed
Push — issues/1796 ( fe0f55...71eafd )
by Ravinder
17:33
created

Give_DB_Logs::validate_params()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 24 and the first side effect is on line 14.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
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
	 *
147
	 * @return bool|null|array
148
	 */
149
	public function get_log_by( $log_id = 0 ) {
150
		/* @var WPDB $wpdb */
151
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
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
		if ( ! $log = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE ID = %s LIMIT 1", $log_id ), ARRAY_A ) ) {
162
			return false;
163
		}
164
165
		return $log;
166
	}
167
168
	/**
169
	 * Retrieve logs from the database.
170
	 *
171
	 * @since  2.0
172
	 * @access public
173
	 *
174
	 * @param  array $args
175
	 *
176
	 * @return mixed
177
	 */
178
	public function get_logs( $args = array() ) {
179
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
180
		$sql_query = $this->get_sql( $args );
181
		
182
		// Get log.
183
		if ( ! ( $logs = Give_Cache::get( 'give_logs', true, $sql_query ) ) ) {
184
			$logs = $wpdb->get_results( $sql_query );
185
			Give_Cache::set( 'give_logs', $logs, 3600, true, $sql_query );
186
		}
187
188
		return $logs;
189
	}
190
191
192
	/**
193
	 * Count the total number of logs in the database
194
	 *
195
	 * @since  2.0
196
	 * @access public
197
	 *
198
	 * @param  array $args
199
	 *
200
	 * @return int
201
	 */
202
	public function count( $args = array() ) {
203
		/* @var WPDB $wpdb */
204
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
205
		$args['number'] = - 1;
206
		$args['fields'] = 'ID';
207
		$args['count']  = true;
208
209
		$sql_query = $this->get_sql( $args );
210
211
		if ( ! ( $count = Give_Cache::get( 'give_logs_count', true, $sql_query ) ) ) {
212
			$count = $wpdb->get_var( $sql_query );
213
			Give_Cache::set( 'give_logs_count', $count, 3600, true, $args );
214
		}
215
		
216
		return absint( $count );
217
	}
218
219
	/**
220
	 * Create the table
221
	 *
222
	 * @since  2.0
223
	 * @access public
224
	 *
225
	 * @return void
226
	 */
227
	public function create_table() {
228
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
229
		$charset_collate = $wpdb->get_charset_collate();
230
231
		$sql = "CREATE TABLE {$this->table_name} (
232
        ID bigint(20) NOT NULL AUTO_INCREMENT,
233
        log_title longtext NOT NULL,
234
        log_content longtext NOT NULL,
235
      	log_parent bigint(20) NOT NULL,
236
        log_type mediumtext NOT NULL,
237
        log_date datetime NOT NULL,
238
        log_date_gmt datetime NOT NULL,
239
        PRIMARY KEY  (ID)
240
        ) {$charset_collate};";
241
242
		require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
243
		dbDelta( $sql );
244
245
		update_option( $this->table_name . '_db_version', $this->version );
246
	}
247
248
249
	/**
250
	 * Get sql query from quaried array.
251
	 *
252
	 * @since  2.0
253
	 * @access public
254
	 *
255
	 * @param array $args
256
	 *
257
	 * @return string
258
	 */
259
	public function get_sql( $args = array() ) {
260
		/* @var WPDB $wpdb */
261
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
262
263
		$defaults = array(
264
			'number'  => 20,
265
			'offset'  => 0,
266
			'paged'   => 0,
267
			'orderby' => 'date',
268
			'order'   => 'DESC',
269
			'fields'  => 'all',
270
			'count'   => false,
271
		);
272
273
		$args = wp_parse_args( $args, $defaults );
274
275
		// validate params.
276
		$this->validate_params( $args );
277
278
		if ( $args['number'] < 1 ) {
279
			$args['number'] = 999999999999;
280
		}
281
282
		// Where clause for primary table.
283
		$where = '';
284
285
		// Get sql query for meta.
286
		if ( ! empty( $args['meta_query'] ) ) {
287
			$meta_query_object = new WP_Meta_Query( $args['meta_query'] );
288
			$meta_query        = $meta_query_object->get_sql( 'log', $this->table_name, 'id' );
289
			$where             = implode( '', $meta_query );
290
		}
291
292
		$where .= ' WHERE 1=1 ';
293
294
		// Set offset.
295
		if ( empty( $args['offset'] ) && ( 0 < $args['paged'] ) ) {
296
			$args['offset'] = $args['number'] * ( $args['paged'] - 1 );
297
		}
298
299
		// Set fields.
300
		$fields = "{$this->table_name}.*";
301
		if ( is_string( $args['fields'] ) && ( 'all' !== $args['fields'] ) ) {
302
			$fields = "{$this->table_name}.{$args['fields']}";
303
		}
304
305
		// Set count.
306
		if ( $args['count'] ) {
307
			$fields = "COUNT({$fields})";
308
		}
309
310
		// Specific logs.
311
		if ( ! empty( $args['ID'] ) ) {
312
313
			if ( ! is_array( $args['ID'] ) ) {
314
				$args['ID'] = explode( ',', $args['ID'] );
315
			}
316
			$log_ids = implode( ',', array_map( 'intval', $args['ID'] ) );
317
318
			$where .= " AND {$this->table_name}.ID IN( {$log_ids} ) ";
319
		}
320
321
		// Logs created for a specific date or in a date range
322
		if ( ! empty( $args['date_query'] ) ) {
323
			$date_query_object = new WP_Date_Query( $args['date_query'], "{$this->table_name}.date" );
324
			$where             .= $date_query_object->get_sql();
325
		}
326
327
		// Logs create for specific parent.
328
		if ( ! empty( $args['log_parent'] ) ) {
329
			if ( ! is_array( $args['log_parent'] ) ) {
330
				$args['log_parent'] = explode( ',', $args['log_parent'] );
331
			}
332
			$parent_ids = implode( ',', array_map( 'intval', $args['log_parent'] ) );
333
334
			$where .= " AND {$this->table_name}.log_parent IN( {$parent_ids} ) ";
335
		}
336
337
		// Logs create for specific type.
338
		if ( ! empty( $args['log_type'] ) ) {
339
			if ( ! is_array( $args['log_type'] ) ) {
340
				$args['log_type'] = explode( ',', $args['log_type'] );
341
			}
342
343
			$log_types = implode( '\',\'', array_map( 'trim', $args['log_type'] ) );
344
345
			$where .= " AND {$this->table_name}.log_type IN( '{$log_types}' ) ";
346
		}
347
348
		$args['orderby'] = ! array_key_exists( $args['orderby'], $this->get_columns() ) ? 'log_date' : $args['orderby'];
349
350
		$args['orderby'] = esc_sql( $args['orderby'] );
351
		$args['order']   = esc_sql( $args['order'] );
352
353
		return $wpdb->prepare(
354
			"SELECT {$fields} FROM {$this->table_name} {$where} ORDER BY {$this->table_name}.{$args['orderby']} {$args['order']} LIMIT %d,%d;",
355
			absint( $args['offset'] ),
356
			absint( $args['number'] )
357
		);
358
	}
359
360
361
	/**
362
	 * Validate query params.
363
	 *
364
	 * @since  2.0
365
	 * @access private
366
	 *
367
	 * @param $args
368
	 *
369
	 * @return mixed
370
	 */
371
	private function validate_params( &$args ) {
372
		$args['fields'] = array_key_exists( $args['fields'], $this->get_columns() ) ?
373
			$args['fields'] :
374
			'all';
375
	}
376
}
377