Completed
Push — issues/1132 ( b0ddd9...34d612 )
by Ravinder
22:33 queued 02:37
created

Give_DB_Logs::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 12
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
	 * @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;
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...
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(
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;
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...
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 );
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;
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...
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 );
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;
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...
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;
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...
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
		if ( ! empty( $args['ID'] ) ) {
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
		if ( ! empty( $args['log_parent'] ) ) {
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
		if ( ! empty( $args['log_type'] ) && ! is_array( $args['log_type'] ) ) {
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
	/**
396
	 * Check if current id is log or not
397
	 *
398
	 * @since 2.0
399
	 * @access public
400
	 * @param $id
401
	 *
402
	 * @return bool
403
	 */
404
	public function is_log( $id ) {
405
		$log = $this->get_log_by( $id );
406
		return ! empty( $log ) ? true : false;
407
	}
408
}
409