PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.3.9
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.3.9
3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.3.1 2.3.2 2.3.3 All 194 releases
convertkit / includes / class-convertkit-form-entries.php

class-convertkit-form-entries.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 3.3.9, at includes/class-convertkit-form-entries.php

462 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Kit Admin Form Builder Entries class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * Stores entries submitted via Form Builder blocks that have
11 * the 'Store Entries' option enabled.
12 *
13 * @package ConvertKit
14 * @author ConvertKit
15 */
16 class ConvertKit_Form_Entries {
17
18 /**
19 * Holds the DB table name
20 *
21 * @since 3.0.0
22 *
23 * @var string
24 */
25 private $table = 'kit_form_entries';
26
27 /**
28 * Create database table.
29 *
30 * @since 3.0.0
31 *
32 * @global $wpdb WordPress DB Object
33 */
34 public function create_database_table() {
35
36 global $wpdb;
37
38 // Create database table.
39 $query = $wpdb->prepare(
40 "CREATE TABLE IF NOT EXISTS %i (
41 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
42 `post_id` int(11) NOT NULL,
43 `first_name` varchar(191) NOT NULL DEFAULT '',
44 `email` varchar(191) NOT NULL DEFAULT '',
45 `custom_fields` text,
46 `form_id` int(11) NOT NULL,
47 `tag_id` int(11) NOT NULL,
48 `sequence_id` int(11) NOT NULL,
49 `created_at` datetime NOT NULL,
50 `updated_at` datetime NOT NULL,
51 `api_result` varchar(191) NOT NULL DEFAULT 'success',
52 `api_error` text,
53 PRIMARY KEY (`id`),
54 KEY `post_id` (`post_id`),
55 KEY `first_name` (`first_name`),
56 KEY `email` (`email`),
57 KEY `form_id` (`form_id`),
58 KEY `tag_id` (`tag_id`),
59 KEY `sequence_id` (`sequence_id`),
60 KEY `api_result` (`api_result`)
61 )",
62 $wpdb->prefix . $this->table
63 );
64 $query .= ' ' . $wpdb->get_charset_collate() . ' AUTO_INCREMENT=1';
65 $wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
66
67 }
68
69 /**
70 * Adds an entry
71 *
72 * @since 3.0.0
73 *
74 * @param array $entry Entry.
75 * int $post_id Post ID.
76 * string $first_name First Name.
77 * string $email Email.
78 * array $custom_fields Custom Fields.
79 * int $form_id Form ID.
80 * int $tag_id Tag ID.
81 * int $sequence_id Sequence ID.
82 * string $api_result Result (success,error).
83 * string $api_error API Response (when $api_result is 'error').
84 * @return int|bool|WP_Error
85 */
86 public function add( $entry ) {
87
88 global $wpdb;
89
90 // If no email is provided, return an error.
91 if ( ! array_key_exists( 'email', $entry ) ) {
92 return new \WP_Error( 'convertkit_form_entries_no_email', __( 'No email address provided', 'convertkit' ) );
93 }
94
95 // If no post ID is provided, return an error.
96 if ( ! array_key_exists( 'post_id', $entry ) ) {
97 return new \WP_Error( 'convertkit_form_entries_no_post_id', __( 'No post ID provided', 'convertkit' ) );
98 }
99
100 // JSON encode custom fields, if supplied as an array.
101 if ( array_key_exists( 'custom_fields', $entry ) && is_array( $entry['custom_fields'] ) ) {
102 $entry['custom_fields'] = wp_json_encode( $entry['custom_fields'] );
103 }
104
105 // Add created_at and updated_at timestamps.
106 $entry['created_at'] = gmdate( 'Y-m-d H:i:s' );
107 $entry['updated_at'] = gmdate( 'Y-m-d H:i:s' );
108
109 $wpdb->insert(
110 $wpdb->prefix . $this->table,
111 $entry
112 );
113
114 // Return the entry ID.
115 return $wpdb->insert_id;
116
117 }
118
119 /**
120 * Updates an entry
121 *
122 * @since 3.0.0
123 *
124 * @param int $id Entry ID.
125 * @param array $entry Entry.
126 * int $post_id Post ID.
127 * string $first_name First Name.
128 * string $email Email.
129 * array $custom_fields Custom Fields.
130 * int $form_id Form ID.
131 * int $tag_id Tag ID.
132 * int $sequence_id Sequence ID.
133 * string $api_result Result (success,error).
134 * string $api_error API Response (when $api_result is 'error').
135 * @return int|bool|WP_Error
136 */
137 public function update( $id, $entry ) {
138
139 global $wpdb;
140
141 // If no email is provided, return an error.
142 if ( ! array_key_exists( 'email', $entry ) ) {
143 return new \WP_Error( 'convertkit_form_entries_no_email', __( 'No email address provided', 'convertkit' ) );
144 }
145
146 // JSON encode custom fields, if supplied as an array.
147 if ( array_key_exists( 'custom_fields', $entry ) && is_array( $entry['custom_fields'] ) ) {
148 $entry['custom_fields'] = wp_json_encode( $entry['custom_fields'] );
149 }
150
151 // Add updated_at timestamp.
152 $entry['updated_at'] = gmdate( 'Y-m-d H:i:s' );
153
154 $wpdb->update(
155 $wpdb->prefix . $this->table,
156 $entry,
157 array( 'id' => $id )
158 );
159
160 // Return the entry ID.
161 return $wpdb->insert_id;
162
163 }
164
165 /**
166 * Upserts an entry
167 *
168 * @since 3.0.0
169 *
170 * @param array $entry Entry.
171 * int $post_id Post ID.
172 * string $first_name First Name.
173 * string $email Email.
174 * array $custom_fields Custom Fields.
175 * int $form_id Form ID.
176 * int $tag_id Tag ID.
177 * int $sequence_id Sequence ID.
178 * datetime $created_at Created At.
179 * datetime $api_request_sent Request Sent to API.
180 * string $api_result Result (success,test_mode,pending,error).
181 * string $api_response API Response.
182 * @return int|bool|WP_Error
183 */
184 public function upsert( $entry ) {
185
186 global $wpdb;
187
188 // If no email is provided, return an error.
189 if ( ! array_key_exists( 'email', $entry ) ) {
190 return new \WP_Error( 'convertkit_form_entries_no_email', __( 'No email address provided', 'convertkit' ) );
191 }
192
193 // If no post ID is provided, return an error.
194 if ( ! array_key_exists( 'post_id', $entry ) ) {
195 return new \WP_Error( 'convertkit_form_entries_no_post_id', __( 'No post ID provided', 'convertkit' ) );
196 }
197
198 // Check if an entry already exists for the given Post ID and Email.
199 $id = $wpdb->get_var(
200 $wpdb->prepare(
201 'SELECT id FROM %i WHERE post_id = %d AND email = %s',
202 $wpdb->prefix . $this->table,
203 $entry['post_id'],
204 $entry['email']
205 )
206 );
207
208 // If an entry already exists, update it.
209 if ( $id ) {
210 return $this->update( $id, $entry );
211 }
212
213 // Insert new entry.
214 return $this->add( $entry );
215
216 }
217
218 /**
219 * Gets entries by IDs
220 *
221 * @since 3.0.0
222 *
223 * @param array $ids Entry IDs.
224 * @return array
225 */
226 public function get_by_ids( $ids ) {
227
228 global $wpdb;
229
230 // Map IDs as integers.
231 $ids = array_map( 'absint', $ids );
232
233 // Return empty array if no IDs are provided.
234 if ( empty( $ids ) ) {
235 return array();
236 }
237
238 // Create IN clause.
239 $in_clause = implode( ',', array_fill( 0, count( $ids ), '%d' ) );
240
241 // Create SQL query.
242 $sql = "SELECT * FROM {$wpdb->prefix}{$this->table} WHERE id IN ($in_clause)";
243
244 return $wpdb->get_results(
245 $wpdb->prepare( $sql, $ids ), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
246 ARRAY_A
247 );
248
249 }
250
251 /**
252 * Returns a CSV string for the given entries
253 *
254 * @since 3.0.0
255 *
256 * @param array $entries Entries.
257 * @return string
258 */
259 public function get_csv_string( $entries ) {
260
261 // Bail if no entries are provided.
262 if ( empty( $entries ) ) {
263 return '';
264 }
265
266 $csv = array(
267 '"' . implode( '","', array_keys( $entries[0] ) ) . '"',
268 );
269 foreach ( $entries as $entry ) {
270 $csv[] = '"' . implode( '","', $entry ) . '"';
271 }
272
273 return implode( "\n", $csv );
274
275 }
276
277 /**
278 * Searches entries by the given key/value pairs
279 *
280 * @since 3.0.0
281 *
282 * @param bool|string $search Search Query.
283 * @param bool|string $api_result API Result.
284 * @param string $order_by Order Results By.
285 * @param string $order Order (asc|desc).
286 * @param int $page Pagination Offset (default: 1).
287 * @param int $per_page Number of Results to Return (default: 25).
288 * @return array
289 */
290 public function search( $search = false, $api_result = false, $order_by = 'created_at', $order = 'desc', $page = 1, $per_page = 25 ) {
291
292 global $wpdb;
293
294 // Prepare query.
295 $query = $wpdb->prepare(
296 'SELECT * FROM %i',
297 $wpdb->prefix . $this->table
298 );
299
300 // Build where clauses.
301 $where_clauses = $this->build_where_clauses( $search, $api_result );
302
303 // If where clauses are provided, add them to the query.
304 if ( count( $where_clauses ) ) {
305 $query .= ' WHERE ' . implode( ' AND ', $where_clauses );
306 }
307
308 // Order.
309 $query .= $wpdb->prepare(
310 ' ORDER BY %i.%i',
311 $wpdb->prefix . $this->table,
312 $order_by
313 );
314 $query .= ' ' . ( strtolower( $order ) === 'asc' ? 'ASC' : 'DESC' );
315
316 // Limit.
317 if ( $page > 0 && $per_page > 0 ) {
318 $query .= $wpdb->prepare( ' LIMIT %d, %d', ( ( $page - 1 ) * $per_page ), $per_page );
319 }
320
321 // Run and return query results.
322 return $wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
323
324 }
325
326 /**
327 * Gets the number of entry records found for the given query parameters
328 *
329 * @since 3.0.0
330 *
331 * @param bool|string $search Search Query.
332 * @param bool|string $api_result API Result.
333 * @return int
334 */
335 public function total( $search = false, $api_result = false ) {
336
337 global $wpdb;
338
339 // Prepare query.
340 $query = $wpdb->prepare(
341 'SELECT COUNT(%i.id) FROM %i',
342 $wpdb->prefix . $this->table,
343 $wpdb->prefix . $this->table
344 );
345
346 // Build where clauses.
347 $where_clauses = $this->build_where_clauses( $search, $api_result );
348
349 // If where clauses are provided, add them to the query.
350 if ( count( $where_clauses ) ) {
351 $query .= ' WHERE ' . implode( ' AND ', $where_clauses );
352 }
353
354 // Run and return total records found.
355 return (int) $wpdb->get_var( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
356
357 }
358
359 /**
360 * Builds the where clauses for the given query parameters
361 *
362 * @since 3.0.1
363 *
364 * @param bool|string $search Search Query.
365 * @param bool|string $api_result API Result.
366 * @return array
367 */
368 private function build_where_clauses( $search = false, $api_result = false ) {
369
370 global $wpdb;
371
372 $where_clauses = array();
373
374 // Add search clause.
375 if ( $search ) {
376 $where_clauses[] = $wpdb->prepare(
377 '(first_name LIKE %s OR email LIKE %s)',
378 '%' . $search . '%',
379 '%' . $search . '%'
380 );
381 }
382
383 // Add API result clause.
384 if ( $api_result ) {
385 $where_clauses[] = $wpdb->prepare(
386 'api_result = %s',
387 $api_result
388 );
389 }
390
391 return $where_clauses;
392
393 }
394
395 /**
396 * Deletes a single entry for the given ID
397 *
398 * @since 3.0.0
399 *
400 * @param array $id Entry ID.
401 * @return bool
402 */
403 public function delete_by_id( $id ) {
404
405 global $wpdb;
406
407 return $wpdb->delete(
408 $wpdb->prefix . $this->table,
409 array(
410 'id' => absint( $id ),
411 )
412 );
413
414 }
415
416 /**
417 * Deletes multiple entries for the given Entry IDs
418 *
419 * @since 3.0.0
420 *
421 * @param array $ids Entry IDs.
422 * @return bool Success
423 */
424 public function delete_by_ids( $ids ) {
425
426 global $wpdb;
427
428 return $wpdb->query(
429 $wpdb->prepare(
430 sprintf(
431 'DELETE FROM %s WHERE id IN (%s)',
432 $wpdb->prefix . $this->table, // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
433 implode( ',', array_fill( 0, count( $ids ), '%d' ) )
434 ),
435 $ids
436 )
437 );
438
439 }
440
441 /**
442 * Deletes all entries
443 *
444 * @since 3.0.0
445 *
446 * @return bool
447 */
448 public function delete_all() {
449
450 global $wpdb;
451
452 return $wpdb->query(
453 $wpdb->prepare(
454 'TRUNCATE TABLE %i',
455 $wpdb->prefix . $this->table
456 )
457 );
458
459 }
460
461 }
462