This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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 | * Set Minimum Index Length |
||
38 | * |
||
39 | * @since 2.0.1 |
||
40 | * @access public |
||
41 | * |
||
42 | * @var int |
||
43 | */ |
||
44 | public $min_index_length = 191; |
||
45 | |||
46 | /** |
||
47 | * The version of our database table |
||
48 | * |
||
49 | * @since 1.0 |
||
50 | * @access public |
||
51 | * |
||
52 | * @var string |
||
53 | */ |
||
54 | public $version; |
||
55 | |||
56 | /** |
||
57 | * The name of the primary column |
||
58 | * |
||
59 | * @since 1.0 |
||
60 | * @access public |
||
61 | * |
||
62 | * @var string |
||
63 | */ |
||
64 | public $primary_key; |
||
65 | |||
66 | /** |
||
67 | * Class Constructor |
||
68 | * |
||
69 | * Set up the Give DB Class. |
||
70 | * |
||
71 | * @since 1.0 |
||
72 | * @access public |
||
73 | */ |
||
74 | public function __construct() { |
||
75 | if( is_multisite() ) { |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
76 | add_action( 'switch_blog', array( $this, 'handle_switch_blog' ), 10, 2 ); |
||
77 | } |
||
78 | } |
||
79 | |||
80 | /** |
||
81 | * Whitelist of columns |
||
82 | * |
||
83 | * @since 1.0 |
||
84 | * @access public |
||
85 | * |
||
86 | * @return array Columns and formats. |
||
87 | */ |
||
88 | public function get_columns() { |
||
89 | return array(); |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * Default column values |
||
94 | * |
||
95 | * @since 1.0 |
||
96 | * @access public |
||
97 | * |
||
98 | * @return array Default column values. |
||
99 | */ |
||
100 | public function get_column_defaults() { |
||
101 | return array(); |
||
102 | } |
||
103 | |||
104 | /** |
||
105 | * Retrieve a row by the primary key |
||
106 | * |
||
107 | * @since 1.0 |
||
108 | * @access public |
||
109 | 52 | * |
|
110 | 52 | * @param int $row_id Row ID. |
|
111 | 52 | * |
|
112 | 52 | * @return object |
|
113 | */ |
||
114 | public function get( $row_id ) { |
||
115 | /* @var WPDB $wpdb */ |
||
116 | global $wpdb; |
||
117 | |||
118 | // Bailout. |
||
119 | if ( empty( $row_id ) ) { |
||
120 | return null; |
||
121 | } |
||
122 | 2 | ||
123 | 2 | return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE $this->primary_key = %s LIMIT 1;", $row_id ) ); |
|
0 ignored issues
–
show
|
|||
124 | 2 | } |
|
125 | 2 | ||
126 | 2 | /** |
|
127 | * Retrieve a row by a specific column / value |
||
128 | * |
||
129 | * @since 1.0 |
||
130 | * @access public |
||
131 | * |
||
132 | * @param int $column Column ID. |
||
133 | * @param int $row_id Row ID. |
||
134 | * |
||
135 | * @return object |
||
136 | 52 | */ |
|
137 | 52 | View Code Duplication | public function get_by( $column, $row_id ) { |
0 ignored issues
–
show
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. ![]() |
|||
138 | /* @var WPDB $wpdb */ |
||
139 | global $wpdb; |
||
140 | 52 | ||
141 | // Bailout. |
||
142 | 52 | if ( empty( $column ) || empty( $row_id ) ) { |
|
143 | return null; |
||
144 | } |
||
145 | 52 | ||
146 | $column = esc_sql( $column ); |
||
147 | |||
148 | 52 | return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE $column = %s LIMIT 1;", $row_id ) ); |
|
0 ignored issues
–
show
|
|||
149 | } |
||
150 | |||
151 | 52 | /** |
|
152 | * Retrieve all rows by a specific column / value |
||
153 | * Note: currently support string comparision |
||
154 | 52 | * |
|
155 | 52 | * @since 2.2.4 |
|
156 | * @access public |
||
157 | 52 | * |
|
158 | * @param array $column_args Array contains column key and expected value. |
||
159 | 52 | * |
|
160 | * @return array |
||
161 | 52 | */ |
|
162 | public function get_results_by( $column_args ) { |
||
163 | /* @var WPDB $wpdb */ |
||
164 | global $wpdb; |
||
165 | |||
166 | // Bailout. |
||
167 | if ( empty( $column_args ) ) { |
||
168 | return null; |
||
169 | } |
||
170 | |||
171 | 52 | $column_args = wp_parse_args( |
|
172 | $column_args, |
||
173 | 52 | array( |
|
174 | 'relation' => 'AND' |
||
175 | ) |
||
176 | 52 | ); |
|
177 | |||
178 | 52 | $relation = $column_args['relation']; |
|
179 | 1 | unset($column_args['relation']); |
|
0 ignored issues
–
show
|
|||
180 | |||
181 | $where = array(); |
||
182 | 52 | foreach ( $column_args as $column_name => $column_value ) { |
|
183 | 52 | $where[] = esc_sql( $column_name ) . "='$column_value'"; |
|
184 | 52 | } |
|
185 | $where = implode( " {$relation} ", $where ); |
||
186 | |||
187 | 52 | return $wpdb->get_results( "SELECT * FROM {$this->table_name} WHERE {$where};" ); |
|
0 ignored issues
–
show
|
|||
188 | } |
||
189 | |||
190 | 52 | /** |
|
191 | * Retrieve a specific column's value by the primary key |
||
192 | * |
||
193 | 52 | * @since 1.0 |
|
194 | * @access public |
||
195 | * |
||
196 | 52 | * @param int $column Column ID. |
|
197 | 52 | * @param int $row_id Row ID. |
|
198 | * |
||
199 | 52 | * @return string Column value. |
|
200 | */ |
||
201 | View Code Duplication | public function get_column( $column, $row_id ) { |
|
0 ignored issues
–
show
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. ![]() |
|||
202 | /* @var WPDB $wpdb */ |
||
203 | 52 | global $wpdb; |
|
204 | |||
205 | // Bailout. |
||
206 | if ( empty( $column ) || empty( $row_id ) ) { |
||
207 | return null; |
||
208 | } |
||
209 | |||
210 | $column = esc_sql( $column ); |
||
211 | |||
212 | 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
|
|||
213 | } |
||
214 | |||
215 | /** |
||
216 | * Retrieve a specific column's value by the the specified column / value |
||
217 | * |
||
218 | * @since 1.0 |
||
219 | * @access public |
||
220 | * |
||
221 | * @param int $column Column ID. |
||
222 | * @param string $column_where Column name. |
||
223 | * @param string $column_value Column value. |
||
224 | * |
||
225 | * @return string |
||
226 | */ |
||
227 | public function get_column_by( $column, $column_where, $column_value ) { |
||
228 | /* @var WPDB $wpdb */ |
||
229 | global $wpdb; |
||
230 | |||
231 | // Bailout. |
||
232 | if ( empty( $column ) || empty( $column_where ) || empty( $column_value ) ) { |
||
233 | return null; |
||
234 | } |
||
235 | |||
236 | $column_where = esc_sql( $column_where ); |
||
237 | $column = esc_sql( $column ); |
||
238 | 2 | ||
239 | 2 | return $wpdb->get_var( $wpdb->prepare( "SELECT $column FROM $this->table_name WHERE $column_where = %s LIMIT 1;", $column_value ) ); |
|
0 ignored issues
–
show
|
|||
240 | 2 | } |
|
241 | |||
242 | 2 | /** |
|
243 | * Insert a new row |
||
244 | * |
||
245 | * @since 1.0 |
||
246 | * @access public |
||
247 | * |
||
248 | * @param array $data |
||
249 | * @param string $type |
||
250 | * |
||
251 | * @return int |
||
252 | */ |
||
253 | public function insert( $data, $type = '' ) { |
||
254 | /* @var WPDB $wpdb */ |
||
255 | global $wpdb; |
||
256 | |||
257 | // Set default values. |
||
258 | $data = wp_parse_args( $data, $this->get_column_defaults() ); |
||
259 | |||
260 | /** |
||
261 | * Fires before inserting data to the database. |
||
262 | * |
||
263 | * @since 1.0 |
||
264 | * |
||
265 | * @param array $data |
||
266 | */ |
||
267 | do_action( "give_pre_insert_{$type}", $data ); |
||
268 | |||
269 | // Initialise column format array |
||
270 | $column_formats = $this->get_columns(); |
||
271 | |||
272 | // Force fields to lower case |
||
273 | // $data = array_change_key_case( $data ); |
||
274 | |||
275 | // White list columns |
||
276 | $data = array_intersect_key( $data, $column_formats ); |
||
277 | |||
278 | // Reorder $column_formats to match the order of columns given in $data |
||
279 | $data_keys = array_keys( $data ); |
||
280 | $column_formats = array_merge( array_flip( $data_keys ), $column_formats ); |
||
281 | |||
282 | $wpdb->insert( $this->table_name, $data, $column_formats ); |
||
0 ignored issues
–
show
|
|||
283 | |||
284 | /** |
||
285 | * Fires after inserting data to the database. |
||
286 | * |
||
287 | * @since 1.0 |
||
288 | * |
||
289 | * @param int $insert_id |
||
290 | * @param array $data |
||
291 | */ |
||
292 | do_action( "give_post_insert_{$type}", $wpdb->insert_id, $data ); |
||
293 | |||
294 | return $wpdb->insert_id; |
||
295 | } |
||
296 | |||
297 | /** |
||
298 | * Update a row |
||
299 | * |
||
300 | * @since 1.0 |
||
301 | * @access public |
||
302 | * |
||
303 | * @param int $row_id Column ID |
||
304 | * @param array $data |
||
305 | * @param string $where Column value |
||
306 | * |
||
307 | * @return bool |
||
308 | */ |
||
309 | public function update( $row_id, $data = array(), $where = '' ) { |
||
310 | /* @var WPDB $wpdb */ |
||
311 | global $wpdb; |
||
312 | |||
313 | // Row ID must be positive integer |
||
314 | $row_id = absint( $row_id ); |
||
315 | |||
316 | if ( empty( $row_id ) ) { |
||
317 | return false; |
||
318 | } |
||
319 | |||
320 | if ( empty( $where ) ) { |
||
321 | $where = $this->primary_key; |
||
322 | } |
||
323 | |||
324 | // Initialise column format array |
||
325 | $column_formats = $this->get_columns(); |
||
326 | |||
327 | // Force fields to lower case |
||
328 | $data = array_change_key_case( $data ); |
||
329 | |||
330 | // White list columns |
||
331 | $data = array_intersect_key( $data, $column_formats ); |
||
332 | |||
333 | // Reorder $column_formats to match the order of columns given in $data |
||
334 | $data_keys = array_keys( $data ); |
||
335 | $column_formats = array_merge( array_flip( $data_keys ), $column_formats ); |
||
336 | |||
337 | if ( false === $wpdb->update( $this->table_name, $data, array( $where => $row_id ), $column_formats ) ) { |
||
0 ignored issues
–
show
|
|||
338 | return false; |
||
339 | } |
||
340 | |||
341 | return true; |
||
342 | } |
||
343 | |||
344 | /** |
||
345 | * Delete a row identified by the primary key |
||
346 | * |
||
347 | * @since 1.0 |
||
348 | * @access public |
||
349 | * |
||
350 | * @param int $row_id Column ID. |
||
351 | * |
||
352 | * @return bool |
||
353 | */ |
||
354 | View Code Duplication | public function delete( $row_id = 0 ) { |
|
0 ignored issues
–
show
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. ![]() |
|||
355 | /* @var WPDB $wpdb */ |
||
356 | global $wpdb; |
||
357 | |||
358 | // Row ID must be positive integer |
||
359 | $row_id = absint( $row_id ); |
||
360 | |||
361 | if ( empty( $row_id ) ) { |
||
362 | return false; |
||
363 | } |
||
364 | |||
365 | if ( false === $wpdb->query( $wpdb->prepare( "DELETE FROM $this->table_name WHERE $this->primary_key = %d", $row_id ) ) ) { |
||
0 ignored issues
–
show
|
|||
366 | return false; |
||
367 | } |
||
368 | |||
369 | return true; |
||
370 | } |
||
371 | |||
372 | /** |
||
373 | * Check if the given table exists |
||
374 | * |
||
375 | * @since 1.3.2 |
||
376 | * @access public |
||
377 | * |
||
378 | * @param string $table The table name. |
||
379 | * |
||
380 | * @return bool If the table name exists. |
||
381 | */ |
||
382 | public function table_exists( $table ) { |
||
383 | /* @var WPDB $wpdb */ |
||
384 | global $wpdb; |
||
385 | |||
386 | $table = sanitize_text_field( $table ); |
||
387 | |||
388 | return $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE '%s'", $table ) ) === $table; |
||
0 ignored issues
–
show
|
|||
389 | } |
||
390 | |||
391 | /** |
||
392 | * Checks whether column exists in a table or not. |
||
393 | * |
||
394 | * @param string $column_name Name of the Column in Database Table. |
||
395 | * |
||
396 | * @since 1.8.18 |
||
397 | * |
||
398 | * @see https://gist.github.com/datafeedr/54e89e07f87232fb055121bb766743fe |
||
399 | * |
||
400 | * @return bool |
||
401 | */ |
||
402 | public function does_column_exist( $column_name ) { |
||
403 | |||
404 | global $wpdb; |
||
405 | |||
406 | $column = $wpdb->get_results( $wpdb->prepare( |
||
0 ignored issues
–
show
|
|||
407 | "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 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 ( 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: 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. ![]() |
|||
408 | DB_NAME, $this->table_name, $column_name |
||
409 | ) ); |
||
410 | |||
411 | if ( ! empty( $column ) ) { |
||
412 | return true; |
||
413 | } |
||
414 | |||
415 | return false; |
||
416 | } |
||
417 | |||
418 | /** |
||
419 | * Check if the table was ever installed |
||
420 | * |
||
421 | * @since 1.6 |
||
422 | * @access public |
||
423 | * |
||
424 | * @return bool Returns if the customers table was installed and upgrade routine run. |
||
425 | */ |
||
426 | public function installed() { |
||
427 | return $this->table_exists( $this->table_name ); |
||
428 | } |
||
429 | |||
430 | /** |
||
431 | * Register tables |
||
432 | * |
||
433 | * @since 1.8.9 |
||
434 | * @access public |
||
435 | */ |
||
436 | public function register_table() { |
||
437 | $current_version = get_option( $this->table_name . '_db_version' ); |
||
438 | if ( ! $current_version || version_compare( $current_version, $this->version, '<' ) ) { |
||
439 | $this->create_table(); |
||
440 | } |
||
441 | } |
||
442 | |||
443 | /** |
||
444 | * Create table |
||
445 | * |
||
446 | * @since 1.8.9 |
||
447 | * @access public |
||
448 | */ |
||
449 | public function create_table() { |
||
450 | } |
||
451 | |||
452 | |||
453 | /** |
||
454 | * Given a ID, make sure it's a positive number, greater than zero before inserting or adding. |
||
455 | * |
||
456 | * @access private |
||
457 | * @since 2.0 |
||
458 | * |
||
459 | * @param int $id A passed ID. |
||
460 | * |
||
461 | * @return int|bool The normalized log ID or false if it's found to not be valid. |
||
462 | */ |
||
463 | public function sanitize_id( $id ) { |
||
464 | if ( ! is_numeric( $id ) ) { |
||
465 | return false; |
||
466 | } |
||
467 | |||
468 | $id = (int) $id; |
||
469 | |||
470 | // We were given a non positive number. |
||
471 | if ( absint( $id ) !== $id ) { |
||
472 | return false; |
||
473 | } |
||
474 | |||
475 | if ( empty( $id ) ) { |
||
476 | return false; |
||
477 | } |
||
478 | |||
479 | return absint( $id ); |
||
480 | |||
481 | } |
||
482 | |||
483 | /** |
||
484 | * Handle switch blog on multi-site |
||
485 | * |
||
486 | * @since 2.0.4 |
||
487 | * |
||
488 | * @access public |
||
489 | * |
||
490 | * @param $new_blog_id |
||
491 | * @param $prev_blog_id |
||
492 | */ |
||
493 | public function handle_switch_blog( $new_blog_id, $prev_blog_id ) { |
||
494 | global $wpdb; |
||
495 | |||
496 | // Bailout. |
||
497 | if ( $new_blog_id === $prev_blog_id ) { |
||
498 | return; |
||
499 | } |
||
500 | |||
0 ignored issues
–
show
|
|||
501 | |||
502 | $this->table_name = str_replace( |
||
503 | 1 != $prev_blog_id ? $wpdb->get_blog_prefix( $prev_blog_id ) : $wpdb->base_prefix, |
||
504 | 1 != $new_blog_id ? $wpdb->get_blog_prefix( $new_blog_id ) : $wpdb->base_prefix, |
||
505 | $this->table_name |
||
506 | ); |
||
507 | |||
508 | if ( $this instanceof Give_DB_Meta ) { |
||
509 | $wpdb->{$this->get_meta_type() . 'meta'} = $this->table_name; |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Give_DB as the method get_meta_type() does only exist in the following sub-classes of Give_DB : Give_DB_Donor_Meta , Give_DB_Form_Meta , Give_DB_Log_Meta , Give_DB_Meta , Give_DB_Payment_Meta . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
510 | } |
||
511 | |||
512 | } |
||
513 | } |
||
514 |