PluginProbe ʕ •ᴥ•ʔ
WPForms – Easy Form Builder for WordPress – Contact Forms, Payment Forms, Surveys, & More / 1.7.9.1
WPForms – Easy Form Builder for WordPress – Contact Forms, Payment Forms, Surveys, & More v1.7.9.1
1.10.1.1 1.10.1 1.10.0.5 trunk 1.1.4 1.1.4.2 1.1.5 1.1.5.1 1.1.6 1.1.6.1 1.1.7 1.1.7.1 1.1.7.2 1.1.8 1.1.8.1 1.1.8.2 1.1.8.3 1.1.8.4 1.10.0.1 1.10.0.2 1.10.0.3 1.10.0.4 1.2.0 1.2.0.1 1.2.1 1.2.2 1.2.2.1 1.2.2.2 1.2.3 1.2.3.1 1.2.3.2 1.2.4 1.2.4.1 1.2.5 1.2.5.1 1.2.6 1.2.7 1.2.8 1.2.8.1 1.2.9 1.3.0 1.3.1 1.3.1.1 1.3.1.2 1.3.2 1.3.3 1.3.5 1.3.6 1.3.6.1 1.3.6.2 1.3.7.2 1.3.7.3 1.3.7.4 1.3.8 1.3.9.1 1.4.0.1 1.4.1.1 1.4.2 1.4.2.1 1.4.2.2 1.4.3 1.4.4 1.4.4.1 1.4.5 1.4.5.1 1.4.5.2 1.4.5.3 1.4.6 1.4.7.1 1.4.7.2 1.4.8.1 1.4.9 1.5.0.1 1.5.0.3 1.5.0.4 1.5.1 1.5.1.1 1.5.1.3 1.5.2.1 1.5.2.2 1.5.2.3 1.5.3 1.5.3.1 1.5.4.1 1.5.4.2 1.5.5 1.5.5.1 1.5.6 1.5.6.2 1.5.7 1.5.8.2 1.5.9.1 1.5.9.4 1.5.9.5 1.6.0.1 1.6.0.2 1.6.1 1.6.2.2 1.6.2.3 1.6.3.1 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.7 1.6.7.1 1.6.7.2 1.6.7.3 1.6.8 1.6.8.1 1.6.9 1.7.0 1.7.1.1 1.7.1.2 1.7.2 1.7.2.1 1.7.3 1.7.4 1.7.4.1 1.7.4.2 1.7.5.1 1.7.5.2 1.7.5.3 1.7.5.5 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.7.9.1 1.8.0.1 1.8.0.2 1.8.1.1 1.8.1.2 1.8.1.3 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.3.1 1.8.4 1.8.4.1 1.8.5.2 1.8.5.3 1.8.5.4 1.8.6.2 1.8.6.3 1.8.6.4 1.8.7.2 1.8.8.2 1.8.8.3 1.8.9.1 1.8.9.2 1.8.9.4 1.8.9.5 1.8.9.6 1.9.0.1 1.9.0.2 1.9.0.3 1.9.0.4 1.9.1.1 1.9.1.2 1.9.1.3 1.9.1.4 1.9.1.5 1.9.1.6 1.9.2.1 1.9.2.2 1.9.2.3 1.9.3.1 1.9.3.2 1.9.4.1 1.9.4.2 1.9.5 1.9.5.1 1.9.5.2 1.9.6 1.9.6.1 1.9.6.2 1.9.7.1 1.9.7.2 1.9.7.3 1.9.8.1 1.9.8.2 1.9.8.4 1.9.8.7 1.9.9.2 1.9.9.3 1.9.9.4
wpforms-lite / includes / class-db.php
wpforms-lite / includes Last commit date
admin 3 years ago emails 3 years ago fields 3 years ago providers 3 years ago templates 3 years ago class-db.php 3 years ago class-fields.php 3 years ago class-form.php 3 years ago class-frontend.php 3 years ago class-install.php 3 years ago class-process.php 3 years ago class-providers.php 3 years ago class-templates.php 3 years ago class-widget.php 3 years ago compat.php 3 years ago deprecated.php 3 years ago functions-list.php 3 years ago functions.php 3 years ago integrations.php 3 years ago
class-db.php
466 lines
1 <?php
2
3 /**
4 * DB class.
5 *
6 * This handy class originated from Pippin's Easy Digital Downloads.
7 * https://github.com/easydigitaldownloads/easy-digital-downloads/blob/master/includes/class-edd-db.php
8 *
9 * Sub-classes should define $table_name, $version, and $primary_key in __construct() method.
10 *
11 * @since 1.1.6
12 */
13 abstract class WPForms_DB {
14
15 /**
16 * Database table name.
17 *
18 * @since 1.1.6
19 *
20 * @var string
21 */
22 public $table_name;
23
24 /**
25 * Database version.
26 *
27 * @since 1.1.6
28 *
29 * @var string
30 */
31 public $version;
32
33 /**
34 * Primary key (unique field) for the database table.
35 *
36 * @since 1.1.6
37 *
38 * @var string
39 */
40 public $primary_key;
41
42 /**
43 * Database type identifier.
44 *
45 * @since 1.5.1
46 *
47 * @var string
48 */
49 public $type;
50
51 /**
52 * Retrieve the list of columns for the database table.
53 * Sub-classes should define an array of columns here.
54 *
55 * @since 1.1.6
56 *
57 * @return array List of columns.
58 */
59 public function get_columns() {
60
61 return [];
62 }
63
64 /**
65 * Retrieve column defaults.
66 * Sub-classes can define default for any/all of columns defined in the get_columns() method.
67 *
68 * @since 1.1.6
69 *
70 * @return array All defined column defaults.
71 */
72 public function get_column_defaults() {
73
74 return [];
75 }
76
77 /**
78 * Retrieve a row from the database based on a given row ID.
79 *
80 * @since 1.1.6
81 *
82 * @param int $row_id Row ID.
83 *
84 * @return null|object
85 */
86 public function get( $row_id ) {
87
88 global $wpdb;
89
90 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
91 return $wpdb->get_row(
92 $wpdb->prepare(
93 "SELECT * FROM $this->table_name WHERE $this->primary_key = %d LIMIT 1;", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
94 (int) $row_id
95 )
96 );
97 }
98
99 /**
100 * Retrieve a row based on column and row ID.
101 *
102 * @since 1.1.6
103 *
104 * @param string $column Column name.
105 * @param int|string $value Column value.
106 *
107 * @return object|null Database query result, object or null on failure.
108 */
109 public function get_by( $column, $value ) {
110
111 global $wpdb;
112
113 if (
114 empty( $value ) ||
115 ! array_key_exists( $column, $this->get_columns() )
116 ) {
117 return null;
118 }
119
120 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
121 return $wpdb->get_row(
122 $wpdb->prepare(
123 "SELECT * FROM $this->table_name WHERE $column = %s LIMIT 1;", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
124 $value
125 )
126 );
127 }
128
129 /**
130 * Retrieve a value based on column name and row ID.
131 *
132 * @since 1.1.6
133 *
134 * @param string $column Column name.
135 * @param int|string $row_id Row ID.
136 *
137 * @return string|null Database query result (as string), or null on failure.
138 */
139 public function get_column( $column, $row_id ) {
140
141 global $wpdb;
142
143 if ( empty( $row_id ) || ! array_key_exists( $column, $this->get_columns() ) ) {
144 return null;
145 }
146
147 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
148 return $wpdb->get_var(
149 $wpdb->prepare(
150 "SELECT $column FROM $this->table_name WHERE $this->primary_key = %d LIMIT 1;", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
151 (int) $row_id
152 )
153 );
154 }
155
156 /**
157 * Retrieve one column value based on another given column and matching value.
158 *
159 * @since 1.1.6
160 *
161 * @param string $column Column name.
162 * @param string $column_where Column to match against in the WHERE clause.
163 * @param string $column_value Value to match to the column in the WHERE clause.
164 *
165 * @return string|null Database query result (as string), or null on failure.
166 */
167 public function get_column_by( $column, $column_where, $column_value ) {
168
169 global $wpdb;
170
171 if (
172 empty( $column ) ||
173 empty( $column_where ) ||
174 empty( $column_value ) ||
175 ! array_key_exists( $column_where, $this->get_columns() ) ||
176 ! array_key_exists( $column, $this->get_columns() )
177 ) {
178 return null;
179 }
180
181 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
182 return $wpdb->get_var(
183 $wpdb->prepare(
184 "SELECT $column FROM $this->table_name WHERE $column_where = %s LIMIT 1;", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
185 $column_value
186 )
187 );
188 }
189
190 /**
191 * Insert a new record into the database.
192 *
193 * @since 1.1.6
194 *
195 * @param array $data Column data.
196 * @param string $type Optional. Data type context.
197 *
198 * @return int ID for the newly inserted record. 0 otherwise.
199 */
200 public function add( $data, $type = '' ) {
201
202 global $wpdb;
203
204 // Set default values.
205 $data = (array) wp_parse_args( $data, $this->get_column_defaults() );
206
207 do_action( 'wpforms_pre_insert_' . $type, $data );
208
209 // Initialise column format array.
210 $column_formats = $this->get_columns();
211
212 // Force fields to lower case.
213 $data = array_change_key_case( $data );
214
215 // White list columns.
216 $data = array_intersect_key( $data, $column_formats );
217
218 // Reorder $column_formats to match the order of columns given in $data.
219 $data_keys = array_keys( $data );
220 $column_formats = array_merge( array_flip( $data_keys ), $column_formats );
221
222 $wpdb->insert( $this->table_name, $data, $column_formats );
223
224 do_action( 'wpforms_post_insert_' . $type, $wpdb->insert_id, $data );
225
226 return $wpdb->insert_id;
227 }
228
229 /**
230 * Insert a new record into the database. This runs the add() method.
231 *
232 * @see add()
233 *
234 * @since 1.1.6
235 *
236 * @param array $data Column data.
237 *
238 * @return int ID for the newly inserted record.
239 */
240 public function insert( $data ) {
241
242 return $this->add( $data );
243 }
244
245 /**
246 * Update an existing record in the database.
247 *
248 * @since 1.1.6
249 *
250 * @param int|string $row_id Row ID for the record being updated.
251 * @param array $data Optional. Array of columns and associated data to update. Default empty array.
252 * @param string $where Optional. Column to match against in the WHERE clause. If empty, $primary_key
253 * will be used. Default empty.
254 * @param string $type Optional. Data type context, e.g. 'affiliate', 'creative', etc. Default empty.
255 *
256 * @return bool False if the record could not be updated, true otherwise.
257 */
258 public function update( $row_id, $data = [], $where = '', $type = '' ) {
259
260 global $wpdb;
261
262 // Row ID must be a positive integer.
263 $row_id = absint( $row_id );
264
265 if ( empty( $row_id ) ) {
266 return false;
267 }
268
269 if ( empty( $where ) ) {
270 $where = $this->primary_key;
271 }
272
273 do_action( 'wpforms_pre_update_' . $type, $data );
274
275 // Initialise column format array.
276 $column_formats = $this->get_columns();
277
278 // Force fields to lower case.
279 $data = array_change_key_case( $data );
280
281 // White list columns.
282 $data = array_intersect_key( $data, $column_formats );
283
284 // Reorder $column_formats to match the order of columns given in $data.
285 $data_keys = array_keys( $data );
286 $column_formats = array_merge( array_flip( $data_keys ), $column_formats );
287
288 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
289 if ( $wpdb->update( $this->table_name, $data, [ $where => $row_id ], $column_formats ) === false ) {
290 return false;
291 }
292
293 do_action( 'wpforms_post_update_' . $type, $data );
294
295 return true;
296 }
297
298 /**
299 * Delete a record from the database.
300 *
301 * @since 1.1.6
302 *
303 * @param int|string $row_id Row ID.
304 *
305 * @return bool False if the record could not be deleted, true otherwise.
306 */
307 public function delete( $row_id = 0 ) {
308
309 global $wpdb;
310
311 // Row ID must be positive integer.
312 $row_id = absint( $row_id );
313
314 if ( empty( $row_id ) ) {
315 return false;
316 }
317
318 do_action( 'wpforms_pre_delete', $row_id );
319 do_action( 'wpforms_pre_delete_' . $this->type, $row_id );
320
321 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
322 if ( $wpdb->query( $wpdb->prepare( "DELETE FROM $this->table_name WHERE $this->primary_key = %d", $row_id ) ) === false ) {
323 return false;
324 }
325
326 do_action( 'wpforms_post_delete', $row_id );
327 do_action( 'wpforms_post_delete_' . $this->type, $row_id );
328
329 return true;
330 }
331
332 /**
333 * Delete a record from the database by column.
334 *
335 * @since 1.1.6
336 *
337 * @param string $column Column name.
338 * @param int|string $column_value Column value.
339 *
340 * @return bool False if the record could not be deleted, true otherwise.
341 */
342 public function delete_by( $column, $column_value ) {
343
344 global $wpdb;
345
346 if (
347 empty( $column ) ||
348 empty( $column_value ) ||
349 ! array_key_exists( $column, $this->get_columns() )
350 ) {
351 return false;
352 }
353
354 do_action( 'wpforms_pre_delete', $column_value );
355 do_action( 'wpforms_pre_delete_' . $this->type, $column_value );
356
357 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
358 if ( $wpdb->query( $wpdb->prepare( "DELETE FROM $this->table_name WHERE $column = %s", $column_value ) ) === false ) {
359 return false;
360 }
361
362 do_action( 'wpforms_post_delete', $column_value );
363 do_action( 'wpforms_post_delete_' . $this->type, $column_value );
364
365 return true;
366 }
367
368 /**
369 * Delete record(s) from the database using WHERE IN syntax.
370 *
371 * @since 1.6.4
372 *
373 * @param string $column Column name.
374 * @param mixed $column_values Column values.
375 *
376 * @return int|bool Number of deleted records, false otherwise.
377 */
378 public function delete_where_in( $column, $column_values ) {
379
380 global $wpdb;
381
382 if ( empty( $column ) || empty( $column_values ) ) {
383 return false;
384 }
385
386 if ( ! array_key_exists( $column, $this->get_columns() ) ) {
387 return false;
388 }
389
390 $values = is_array( $column_values ) ? $column_values : [ $column_values ];
391
392 foreach ( $values as $key => $value ) {
393 // Check if a string contains an integer and sanitize accordingly.
394 if ( (string) (int) $value === $value ) {
395 $values[ $key ] = (int) $value;
396 $placeholders[ $key ] = '%d';
397 } else {
398 $values[ $key ] = sanitize_text_field( $value );
399 $placeholders[ $key ] = '%s';
400 }
401 }
402
403 $placeholders = isset( $placeholders ) ? implode( ',', $placeholders ) : '';
404 $sql = "DELETE FROM $this->table_name WHERE $column IN ( $placeholders )";
405
406 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.NotPrepared
407 return $wpdb->query( $wpdb->prepare( $sql, $values ) );
408 }
409
410 /**
411 * Check if the given table exists.
412 *
413 * @since 1.1.6
414 * @since 1.5.9 Default value is now the current child class table name.
415 *
416 * @param string $table The table name. Defaults to the child class table name.
417 *
418 * @return bool If the table name exists.
419 */
420 public function table_exists( $table = '' ) {
421
422 global $wpdb;
423
424 if ( ! empty( $table ) ) {
425 $table = sanitize_text_field( $table );
426 } else {
427 $table = $this->table_name;
428 }
429
430 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching
431 return $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ) === $table;
432 }
433
434 /**
435 * Build WHERE for a query.
436 *
437 * @since 1.7.2.2
438 *
439 * @param array $args Optional args.
440 * @param array $keys Allowed arg items.
441 * @param string|string[] $formats Formats of arg items.
442 *
443 * @return string
444 */
445 protected function build_where( $args, $keys = [], $formats = [] ) {
446
447 $formats = array_pad( $formats, count( $keys ), '%d' );
448 $where = '';
449
450 foreach ( $keys as $index => $key ) {
451 // Value `$args[ $key ]` can be a natural number and a numeric string.
452 // We should skip empty string values, but continue working with '0'.
453 if ( empty( $args[ $key ] ) && $args[ $key ] !== '0' ) {
454 continue;
455 }
456
457 $ids = wpforms_wpdb_prepare_in( $args[ $key ], $formats[ $index ] );
458
459 $where .= empty( $where ) ? 'WHERE' : 'AND';
460 $where .= " `{$key}` IN ( {$ids} ) ";
461 }
462
463 return $where;
464 }
465 }
466