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, GiveWP |
||
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() ) { |
||
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 | * |
||
110 | * @param int $row_id Row ID. |
||
111 | * |
||
112 | * @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 | |||
123 | return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE $this->primary_key = %s LIMIT 1;", $row_id ) ); |
||
124 | } |
||
125 | |||
126 | /** |
||
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 | */ |
||
137 | View Code Duplication | public function get_by( $column, $row_id ) { |
|
0 ignored issues
–
show
|
|||
138 | /* @var WPDB $wpdb */ |
||
139 | global $wpdb; |
||
140 | |||
141 | // Bailout. |
||
142 | if ( empty( $column ) || empty( $row_id ) ) { |
||
143 | return null; |
||
144 | } |
||
145 | |||
146 | $column = esc_sql( $column ); |
||
147 | |||
148 | return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $this->table_name WHERE $column = %s LIMIT 1;", $row_id ) ); |
||
149 | } |
||
150 | |||
151 | /** |
||
152 | * Retrieve all rows by a specific column / value |
||
153 | * Note: currently support string comparision |
||
154 | * |
||
155 | * @since 2.2.4 |
||
156 | * @access public |
||
157 | * |
||
158 | * @param array $column_args Array contains column key and expected value. |
||
159 | * |
||
160 | * @return array |
||
161 | */ |
||
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 | $column_args = wp_parse_args( |
||
172 | $column_args, |
||
173 | array( |
||
174 | 'relation' => 'AND' |
||
175 | ) |
||
176 | ); |
||
177 | |||
178 | $relation = $column_args['relation']; |
||
179 | unset($column_args['relation']); |
||
180 | |||
181 | $where = array(); |
||
182 | foreach ( $column_args as $column_name => $column_value ) { |
||
183 | $where[] = esc_sql( $column_name ) . "='$column_value'"; |
||
184 | } |
||
185 | $where = implode( " {$relation} ", $where ); |
||
186 | |||
187 | return $wpdb->get_results( "SELECT * FROM {$this->table_name} WHERE {$where};" ); |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * Retrieve a specific column's value by the primary key |
||
192 | * |
||
193 | * @since 1.0 |
||
194 | * @access public |
||
195 | * |
||
196 | * @param int $column Column ID. |
||
197 | * @param int $row_id Row ID. |
||
198 | * |
||
199 | * @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 | 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 ) ); |
||
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 | |||
239 | return $wpdb->get_var( $wpdb->prepare( "SELECT $column FROM $this->table_name WHERE $column_where = %s LIMIT 1;", $column_value ) ); |
||
240 | } |
||
241 | |||
242 | /** |
||
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 ); |
||
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 ) ) { |
||
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 | public function delete( $row_id = 0 ) { |
||
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 ) ) ) { |
||
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; |
||
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( |
||
407 | "SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND COLUMN_NAME = %s ", |
||
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 | |||
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_Comment_Meta , 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 |
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.