Test Failed
Push — issues/1944 ( f13954...e5d7bc )
by Ravinder
05:26
created

Give_DB::is_column_exists()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 1
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Give DB
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Give_DB
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Give_DB Class
19
 *
20
 * This class is for interacting with the database table.
21
 *
22
 * @since 1.0
23
 */
24
abstract class Give_DB {
25
26
	/**
27
	 * The name of our database table
28
	 *
29
	 * @since  1.0
30
	 * @access public
31
	 *
32
	 * @var    string
33
	 */
34
	public $table_name;
35
36
	/**
37
	 * The version of our database table
38
	 *
39
	 * @since  1.0
40
	 * @access public
41
	 *
42
	 * @var    string
43
	 */
44
	public $version;
45
46
	/**
47
	 * The name of the primary column
48
	 *
49
	 * @since  1.0
50
	 * @access public
51
	 *
52
	 * @var    string
53
	 */
54
	public $primary_key;
55
56
	/**
57
	 * Class Constructor
58
	 *
59
	 * Set up the Give DB Class.
60
	 *
61
	 * @since  1.0
62
	 * @access public
63
	 */
64
	public function __construct() {
65
	}
66
67
	/**
68
	 * Whitelist of columns
69
	 *
70
	 * @since  1.0
71
	 * @access public
72
	 *
73
	 * @return array  Columns and formats.
74
	 */
75
	public function get_columns() {
76
		return array();
77
	}
78
79
	/**
80
	 * Default column values
81
	 *
82
	 * @since  1.0
83
	 * @access public
84
	 *
85
	 * @return array  Default column values.
86
	 */
87
	public function get_column_defaults() {
88
		return array();
89
	}
90
91
	/**
92
	 * Retrieve a row by the primary key
93
	 *
94
	 * @since  1.0
95
	 * @access public
96
	 *
97
	 * @param  int $row_id Row ID.
98
	 *
99
	 * @return object
100
	 */
101
	public function get( $row_id ) {
102
		/* @var WPDB $wpdb */
103
		global $wpdb;
104
105
		// Bailout.
106
		if ( empty( $row_id ) ) {
107
			return null;
108
		}
109
110
		return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE $this->primary_key = %s LIMIT 1;", $row_id ) );
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...
111
	}
112
113
	/**
114
	 * Retrieve a row by a specific column / value
115
	 *
116
	 * @since  1.0
117
	 * @access public
118
	 *
119
	 * @param  int $column Column ID.
120
	 * @param  int $row_id Row ID.
121
	 *
122
	 * @return object
123
	 */
124 View Code Duplication
	public function get_by( $column, $row_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...
125
		/* @var WPDB $wpdb */
126
		global $wpdb;
127
128
		// Bailout.
129
		if ( empty( $column ) || empty( $row_id ) ) {
130
			return null;
131
		}
132
133
		$column = esc_sql( $column );
134
135
		return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE $column = %s LIMIT 1;", $row_id ) );
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...
136
	}
137
138
	/**
139
	 * Retrieve a specific column's value by the primary key
140
	 *
141
	 * @since  1.0
142
	 * @access public
143
	 *
144
	 * @param  int $column Column ID.
145
	 * @param  int $row_id Row ID.
146
	 *
147
	 * @return string      Column value.
148
	 */
149 View Code Duplication
	public function get_column( $column, $row_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...
150
		/* @var WPDB $wpdb */
151
		global $wpdb;
152
153
		// Bailout.
154
		if ( empty( $column ) || empty( $row_id ) ) {
155
			return null;
156
		}
157
158
		$column = esc_sql( $column );
159
160
		return $wpdb->get_var( $wpdb->prepare( "SELECT $column FROM $this->table_name WHERE $this->primary_key = %s LIMIT 1;", $row_id ) );
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...
161
	}
162
163
	/**
164
	 * Retrieve a specific column's value by the the specified column / value
165
	 *
166
	 * @since  1.0
167
	 * @access public
168
	 *
169
	 * @param  int    $column       Column ID.
170
	 * @param  string $column_where Column name.
171
	 * @param  string $column_value Column value.
172
	 *
173
	 * @return string
174
	 */
175
	public function get_column_by( $column, $column_where, $column_value ) {
176
		/* @var WPDB $wpdb */
177
		global $wpdb;
178
179
		// Bailout.
180
		if ( empty( $column ) || empty( $column_where ) || empty( $column_value ) ) {
181
			return null;
182
		}
183
184
		$column_where = esc_sql( $column_where );
185
		$column       = esc_sql( $column );
186
187
		return $wpdb->get_var( $wpdb->prepare( "SELECT $column FROM $this->table_name WHERE $column_where = %s LIMIT 1;", $column_value ) );
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...
188
	}
189
190
	/**
191
	 * Insert a new row
192
	 *
193
	 * @since  1.0
194
	 * @access public
195
	 *
196
	 * @param  array  $data
197
	 * @param  string $type
198
	 *
199
	 * @return int
200
	 */
201
	public function insert( $data, $type = '' ) {
202
		/* @var WPDB $wpdb */
203
		global $wpdb;
204
205
		// Set default values.
206
		$data = wp_parse_args( $data, $this->get_column_defaults() );
207
208
		/**
209
		 * Fires before inserting data to the database.
210
		 *
211
		 * @since 1.0
212
		 *
213
		 * @param array $data
214
		 */
215
		do_action( "give_pre_insert_{$type}", $data );
216
217
		// Initialise column format array
218
		$column_formats = $this->get_columns();
219
220
		// Force fields to lower case
221
		// $data = array_change_key_case( $data );
222
223
		// White list columns
224
		$data = array_intersect_key( $data, $column_formats );
225
226
		// Reorder $column_formats to match the order of columns given in $data
227
		$data_keys      = array_keys( $data );
228
		$column_formats = array_merge( array_flip( $data_keys ), $column_formats );
229
230
		$wpdb->insert( $this->table_name, $data, $column_formats );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
231
232
		/**
233
		 * Fires after inserting data to the database.
234
		 *
235
		 * @since 1.0
236
		 *
237
		 * @param int   $insert_id
238
		 * @param array $data
239
		 */
240
		do_action( "give_post_insert_{$type}", $wpdb->insert_id, $data );
241
242
		return $wpdb->insert_id;
243
	}
244
245
	/**
246
	 * Update a row
247
	 *
248
	 * @since  1.0
249
	 * @access public
250
	 *
251
	 * @param  int    $row_id Column ID
252
	 * @param  array  $data
253
	 * @param  string $where  Column value
254
	 *
255
	 * @return bool
256
	 */
257
	public function update( $row_id, $data = array(), $where = '' ) {
258
		/* @var WPDB $wpdb */
259
		global $wpdb;
260
261
		// Row ID must be positive integer
262
		$row_id = absint( $row_id );
263
264
		if ( empty( $row_id ) ) {
265
			return false;
266
		}
267
268
		if ( empty( $where ) ) {
269
			$where = $this->primary_key;
270
		}
271
272
		// Initialise column format array
273
		$column_formats = $this->get_columns();
274
275
		// Force fields to lower case
276
		$data = array_change_key_case( $data );
277
278
		// White list columns
279
		$data = array_intersect_key( $data, $column_formats );
280
281
		// Reorder $column_formats to match the order of columns given in $data
282
		$data_keys      = array_keys( $data );
283
		$column_formats = array_merge( array_flip( $data_keys ), $column_formats );
284
285
		if ( false === $wpdb->update( $this->table_name, $data, array( $where => $row_id ), $column_formats ) ) {
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
286
			return false;
287
		}
288
289
		return true;
290
	}
291
292
	/**
293
	 * Delete a row identified by the primary key
294
	 *
295
	 * @since  1.0
296
	 * @access public
297
	 *
298
	 * @param  int $row_id Column ID.
299
	 *
300
	 * @return bool
301
	 */
302 View Code Duplication
	public function delete( $row_id = 0 ) {
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...
303
		/* @var WPDB $wpdb */
304
		global $wpdb;
305
306
		// Row ID must be positive integer
307
		$row_id = absint( $row_id );
308
309
		if ( empty( $row_id ) ) {
310
			return false;
311
		}
312
313
		if ( false === $wpdb->query( $wpdb->prepare( "DELETE FROM $this->table_name WHERE $this->primary_key = %d", $row_id ) ) ) {
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...
314
			return false;
315
		}
316
317
		return true;
318
	}
319
320
	/**
321
	 * Check if the given table exists
322
	 *
323
	 * @since  1.3.2
324
	 * @access public
325
	 *
326
	 * @param  string $table The table name.
327
	 *
328
	 * @return bool          If the table name exists.
329
	 */
330
	public function table_exists( $table ) {
331
		/* @var WPDB $wpdb */
332
		global $wpdb;
333
334
		$table = sanitize_text_field( $table );
335
336
		return $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE '%s'", $table ) ) === $table;
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...
337
	}
338
339
	/**
340
	 * Checks whether column exists in a table or not.
341
	 *
342
	 * @param string $column_name Name of the Column in Database Table.
343
	 *
344
	 * @since 1.8.18
345
	 *
346
	 * @see https://gist.github.com/datafeedr/54e89e07f87232fb055121bb766743fe
347
	 *
348
	 * @return bool
349
	 */
350
	public function is_column_exists( $column_name ) {
351
352
		global $wpdb;
353
354
		$column = $wpdb->get_results( $wpdb->prepare(
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...
355
			"SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND COLUMN_NAME = %s ",
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal SELECT * FROM INFORMATIO...s AND COLUMN_NAME = %s does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
356
			DB_NAME, $this->table_name, $column_name
357
		) );
358
359
		if ( ! empty( $column ) ) {
360
			return true;
361
		}
362
363
		return false;
364
	}
365
366
	/**
367
	 * Check if the table was ever installed
368
	 *
369
	 * @since  1.6
370
	 * @access public
371
	 *
372
	 * @return bool Returns if the customers table was installed and upgrade routine run.
373
	 */
374
	public function installed() {
375
		return $this->table_exists( $this->table_name );
376
	}
377
378
	/**
379
	 * Register tables
380
	 *
381
	 * @since  1.8.9
382
	 * @access public
383
	 */
384
	public function register_table() {
385
		$current_version = get_option( $this->table_name . '_db_version' );
386
		if ( ! $current_version || version_compare( $current_version, $this->version, '<' ) ) {
387
			$this->create_table();
388
		}
389
	}
390
391
	/**
392
	 * Create table
393
	 *
394
	 * @since  1.8.9
395
	 * @access public
396
	 */
397
	public function create_table() {
398
	}
399
400
401
	/**
402
	 * Given a ID, make sure it's a positive number, greater than zero before inserting or adding.
403
	 *
404
	 * @access private
405
	 * @since  2.0
406
	 *
407
	 * @param  int $id A passed ID.
408
	 *
409
	 * @return int|bool                The normalized log ID or false if it's found to not be valid.
410
	 */
411
	public function sanitize_id( $id ) {
412
		if ( ! is_numeric( $id ) ) {
413
			return false;
414
		}
415
416
		$id = (int) $id;
417
418
		// We were given a non positive number.
419
		if ( absint( $id ) !== $id ) {
420
			return false;
421
		}
422
423
		if ( empty( $id ) ) {
424
			return false;
425
		}
426
427
		return absint( $id );
428
429
	}
430
}
431