PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 3.3.1
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v3.3.1
3.3.1 V-3.3.0 3.2.2 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 V3.0.3 V3.0.2 -3.0.1 V_3.0.0 1.1.1 1.1.8 1.2 1.3 1.4 1.4.18 1.5.2 1.9 2.0 2.10.0 2.10.1 All 138 releases
← All changes | includes/Core/Database/FormEntryLogModel.php +151 -68 1.5.23.3.1 View file →
@@ -7,88 +7,171 @@
7 7 /**
8 8 * Undocumented class
9 9 */
10 10
11 -use BitCode\BitForm\Core\Database\Model;
12 -
13 11 class FormEntryLogModel extends Model
14 12 {
15 - protected static $table = 'bitforms_form_log_details';
13 + protected static $table = 'bitforms_form_log_details';
16 14
17 - public function geLogHistory($form_id, $entry_id)
18 - {
19 - $sql = "SELECT * FROM `{$this->app_db->prefix}bitforms_form_entry_log` where form_entry_id=$entry_id AND form_id=$form_id order By created_at DESC";
15 + public function geLogHistory($form_id, $entry_id)
16 + {
17 + $sql = "SELECT * FROM `{$this->app_db->prefix}bitforms_form_entry_log` where form_entry_id=%d AND form_id=%d order By created_at DESC";
18 + $logs = $this->execute($sql, [$entry_id, $form_id])->getResult();
19 + $response = ['success' => true, 'data' => [], 'integrations' => []];
20 + $ids = [];
21 + foreach ($logs as $log) {
22 + $ids[] = (int) $log->id;
23 + }
24 + if (isset($logs->errors['result_empty'])) {
25 + wp_send_json($response);
26 + } else {
27 + $allLogId = preg_replace('/"/', '', implode(',', $ids));
28 + $sql2 = "SELECT * FROM `{$this->app_db->prefix}bitforms_form_log_details` WHERE `log_id` IN ($allLogId)";
29 + $integrations = $this->execute($sql2)->getResult();
20 30
21 - $logs = $this->execute($sql)->getResult();
22 - $response = ['success' => true, 'data' => [], 'integrations' => []];
23 - $ids = [];
24 - foreach ($logs as $log) {
25 - $ids[] = $log->id;
26 - }
27 - if (isset($logs->errors['result_empty'])) {
28 - wp_send_json($response);
29 - } else {
30 - $allLogId = preg_replace('/"/', '', implode(',', $ids));
31 - $sql2 = "SELECT * FROM `{$this->app_db->prefix}bitforms_form_log_details` WHERE `log_id` IN ($allLogId)";
32 - $integrations = $this->execute($sql2)->getResult();
33 - foreach ($logs as $key => $log) {
34 - foreach ($integrations as $integration) {
35 - if ($integration->log_id == $log->id) {
36 - $logs[$key]->integration = true;
37 - }
38 - }
31 + if (isset($integrations->errors['result_empty'])) {
32 + $integrations = [];
33 + } else {
34 + foreach ($logs as $key => $log) {
35 + foreach ($integrations as $integration) {
36 + if ($integration->log_id === $log->id) {
37 + $logs[$key]->integration = true;
39 38 }
40 - if (isset($integrations->errors['result_empty'])) {
41 - $integrations = [];
42 - }
43 - wp_send_json(['success' => true, 'data' => $logs, 'integrations' => $integrations]);
39 + }
44 40 }
41 + }
42 +
43 + wp_send_json(['success' => true, 'data' => $logs, 'integrations' => $integrations]);
45 44 }
45 + }
46 46
47 - public function entryLogCheck($entry_id, $integ_id)
48 - {
49 - if (is_null($entry_id)) {
50 - return new WP_Error('empty_data', __('Form data is empty', 'bit-form'));
51 - }
52 - $sql = "SELECT api_type, response_obj FROM `{$this->app_db->prefix}bitforms_form_entry_log` as el JOIN `{$this->app_db->prefix}bitforms_form_log_details` as ld ON ld.log_id = el.id WHERE form_entry_id = {$entry_id} AND integration_id = {$integ_id} AND ld.response_type = 'success' ORDER BY el.id DESC LIMIT 1";
47 + public function entryLogCheck($entry_id, $integ_id)
48 + {
49 + if (is_null($entry_id)) {
50 + return new WP_Error('empty_data', __('Form data is empty', 'bit-form'));
51 + }
52 + $sql = $this->app_db->prepare(
53 + "SELECT api_type, response_obj FROM `{$this->app_db->prefix}bitforms_form_entry_log` as el JOIN `{$this->app_db->prefix}bitforms_form_log_details` as ld ON ld.log_id = el.id WHERE form_entry_id = %d AND integration_id = %d AND ld.response_type = 'success' ORDER BY el.id DESC LIMIT 1",
54 + $entry_id,
55 + $integ_id
56 + );
53 57
54 - return $this->app_db->get_results($sql);
58 + return $this->app_db->get_results($sql);
59 + }
60 +
61 + public function form_log_insert($data = [])
62 + {
63 + if (is_null($data)) {
64 + return new WP_Error('empty_data', __('Form data is empty', 'bit-form'));
55 65 }
66 + $result = $this->app_db->insert(
67 + "{$this->app_db->prefix}bitforms_form_entry_log",
68 + $data
69 + );
70 + return $this->getResult($result);
71 + }
56 72
57 - public function form_log_insert($data = array())
58 - {
59 - if (is_null($data)) {
60 - return new WP_Error('empty_data', __('Form data is empty', 'bit-form'));
61 - }
62 - $result = $this->app_db->insert(
63 - "{$this->app_db->prefix}bitforms_form_entry_log",
64 - $data
65 - );
66 - return $this->getResult($result);
73 + public function log_history_insert($data = [])
74 + {
75 + if (is_null($data)) {
76 + return new WP_Error('empty_data', __('Form data is empty', 'bit-form'));
67 77 }
78 + $result = $this->app_db->insert(
79 + "{$this->app_db->prefix}bitforms_form_log_details",
80 + $data
81 + );
82 + return $this->getResult($result);
83 + }
68 84
69 - public function log_history_insert($data = array())
70 - {
71 - if (is_null($data)) {
72 - return new WP_Error('empty_data', __('Form data is empty', 'bit-form'));
73 - }
74 - $result = $this->app_db->insert(
75 - "{$this->app_db->prefix}bitforms_form_log_details",
76 - $data
77 - );
78 - return $this->getResult($result);
79 - }
85 + public function get_form_value($form_id = '')
86 + {
87 + $sql = $this->app_db->prepare(
88 + "SELECT `meta_key`,`meta_value` FROM `{$this->app_db->prefix}bitforms_form_entrymeta` WHERE bitforms_form_entry_id=%d",
89 + $form_id
90 + );
91 + return $this->execute($sql)->getResult();
92 + }
80 93
81 - public function get_form_value($form_id = "")
82 - {
83 - $sql = "SELECT `meta_key`,`meta_value` FROM `{$this->app_db->prefix}bitforms_form_entrymeta` where bitforms_form_entry_id=$form_id";
84 - return $this->execute($sql)->getResult();
94 + /**
95 + * Queued workflow-trigger rows (response_type 'queued', integration_id 0)
96 + * whose browser trigger and per-entry reclaim event were both lost, joined
97 + * to the entry log for the form/entry ids the executor needs.
98 + */
99 + public function getStaleQueuedWorkflows($minAgeMinutes, $maxAgeHours, $limit)
100 + {
101 + $sql = "SELECT ld.id AS queue_log_id, ld.log_id, el.form_id, el.form_entry_id
102 + FROM `{$this->app_db->prefix}bitforms_form_log_details` ld
103 + JOIN `{$this->app_db->prefix}bitforms_form_entry_log` el ON el.id = ld.log_id
104 + WHERE ld.integration_id = 0
105 + AND ld.response_type = 'queued'
106 + AND ld.created_at < DATE_SUB(%s, INTERVAL %d MINUTE)
107 + AND ld.created_at > DATE_SUB(%s, INTERVAL %d HOUR)
108 + ORDER BY ld.id ASC
109 + LIMIT %d";
110 + $now = current_time('mysql');
111 + return $this->execute($sql, [$now, absint($minAgeMinutes), $now, absint($maxAgeHours), absint($limit)])->getResult();
112 + }
113 +
114 + /**
115 + * Newest still-queued workflow row of an entry, for callers that hold the
116 + * entry id but not the queue log id (the payment endpoints).
117 + *
118 + * @return object|null row with id and response_obj
119 + */
120 + public function latestQueuedWorkflowByEntry($entryID)
121 + {
122 + $sql = "SELECT ld.id, ld.response_obj
123 + FROM `{$this->app_db->prefix}bitforms_form_log_details` ld
124 + JOIN `{$this->app_db->prefix}bitforms_form_entry_log` el ON el.id = ld.log_id
125 + WHERE el.form_entry_id = %d
126 + AND ld.integration_id = 0
127 + AND ld.response_type = 'queued'
128 + ORDER BY ld.id DESC
129 + LIMIT 1";
130 + $rows = $this->execute($sql, [absint($entryID)])->getResult();
131 +
132 + return is_wp_error($rows) || empty($rows) ? null : $rows[0];
133 + }
134 +
135 + /**
136 + * Patch a queued row's payload. The 'queued' condition keeps it off rows a
137 + * trigger or the reclaim cron has already claimed.
138 + *
139 + * @return mixed rows affected, or WP_Error
140 + */
141 + public function updateQueuedWorkflowResponse($queueLogId, array $responseObj)
142 + {
143 + return $this->update(
144 + ['response_obj' => wp_json_encode($responseObj)],
145 + ['id' => absint($queueLogId), 'response_type' => 'queued']
146 + );
147 + }
148 +
149 + /**
150 + * Latest execution per integration of a form: last run time plus the
151 + * response_type of that newest log row. integration_id 0 (workflow queue) excluded.
152 + */
153 + public function getIntegrationLastRuns($formId)
154 + {
155 + $sql = "SELECT ld.integration_id,
156 + MAX(ld.created_at) AS lastRun,
157 + SUBSTRING_INDEX(GROUP_CONCAT(ld.response_type ORDER BY ld.created_at DESC, ld.id DESC), ',', 1) AS lastStatus
158 + FROM `{$this->app_db->prefix}bitforms_form_log_details` ld
159 + JOIN `{$this->app_db->prefix}bitforms_form_entry_log` el ON el.id = ld.log_id
160 + WHERE el.form_id = %d AND ld.integration_id > 0
161 + GROUP BY ld.integration_id";
162 + return $this->execute($sql, [absint($formId)])->getResult();
163 + }
164 +
165 + public function logUpdate($updateValue, $logID)
166 + {
167 + if (empty($logID)) {
168 + return false;
85 169 }
86 - public function logUpdate($updateValue, $logID)
87 - {
88 - if (empty($logID)) {
89 - return false;
90 - }
91 - $sql = "UPDATE `{$this->app_db->prefix}bitforms_form_entry_log` SET content='$updateValue' WHERE id=$logID";
92 - return $this->execute($sql)->getResult();
93 - }
170 + $sql = $this->app_db->prepare(
171 + "UPDATE `{$this->app_db->prefix}bitforms_form_entry_log` SET content=%s WHERE id=%d",
172 + $updateValue,
173 + $logID
174 + );
175 + return $this->execute($sql)->getResult();
176 + }
94 177 }