PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / trunk
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar vtrunk
3.3.1 3.3.0 3.2.14 3.2.13 3.2.12 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 trunk 0.2.5.5 0.2.5.6 0.2.5.7 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 All 156 releases
notificationx / includes / Extensions / FluentForm / FluentForm.php

FluentForm.php in NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar trunk, at includes/Extensions/FluentForm/FluentForm.php

426 lines 17.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Fluent_Form Extension
5 *
6 * @package NotificationX\Extensions
7 */
8
9 namespace NotificationX\Extensions\FluentForm;
10
11 use NotificationX\Core\Helper;
12 use NotificationX\Core\Rules;
13 use NotificationX\GetInstance;
14 use NotificationX\Extensions\Extension;
15 use NotificationX\Extensions\GlobalFields;
16 use NotificationX\Admin\Entries;
17
18 /**
19 * Fluent_Form Extension
20 * @method static Fluent_Form get_instance($args = null)
21 */
22 class FluentForm extends Extension {
23 /**
24 * Instance of Fluent_Form
25 *
26 * @var FluentForm
27 */
28 use GetInstance;
29
30 public $priority = 20;
31 public $id = 'fluentform';
32 public $img = '';
33 public $doc_link = 'https://notificationx.com/docs/contact-form-submission-alert/';
34 public $types = 'form';
35 public $module = 'modules_fluentform';
36 public $module_priority = 10;
37 public $constant = 'FLUENTFORM_VERSION';
38 public $post_type = 'fluentform';
39 /**
40 * Initially Invoked when initialized.
41 */
42 public function __construct() {
43 parent::__construct();
44 }
45
46 public function init_extension()
47 {
48 $this->title = __('Fluent Forms', 'notificationx');
49 $this->module_title = __('Fluent Forms', 'notificationx');
50 }
51
52 public function init() {
53 parent::init();
54 add_action('fluentform_submission_inserted', array($this, 'save_new_records'),10,3);
55 }
56
57 public function init_fields(){
58 parent::init_fields();
59 add_filter('nx_form_list', [$this, 'nx_form_list'], 9);
60 }
61
62 /**
63 * This functions is hooked
64 *
65 * @return void
66 */
67 public function admin_actions() {
68 parent::admin_actions();
69
70 add_filter("nx_can_entry_{$this->id}", array($this, 'can_entry'), 10, 3);
71 }
72
73 /**
74 * This functions is hooked
75 *
76 * @hooked nx_public_action
77 * @return void
78 */
79 public function public_actions() {
80 parent::public_actions();
81
82 add_filter("nx_filtered_data_{$this->id}", array($this, 'filter_by_form'), 11, 3);
83 }
84
85 public function source_error_message($messages) {
86 if (!$this->class_exists()) {
87 $url = admin_url('plugin-install.php?s=fluent-forms&tab=search&type=term');
88 $messages[$this->id] = [
89 'message' => sprintf( '%s <a href="%s" target="_blank">%s</a> %s',
90 __( 'You have to install', 'notificationx' ),
91 $url,
92 __( 'Fluent Forms', 'notificationx' ),
93 __( 'plugin first.', 'notificationx' )
94 ),
95 'html' => true,
96 'type' => 'error',
97 'rules' => Rules::is('source', $this->id),
98 ];
99 }
100 return $messages;
101 }
102
103 public function nx_form_list($forms) {
104 $_forms = GlobalFields::get_instance()->normalize_fields($this->get_forms(), 'source', $this->id);
105 return array_merge($forms, $_forms);
106 }
107
108 public function get_forms() {
109 $forms = [];
110 if (!$this->class_exists()) {
111 return [];
112 }
113 global $wpdb;
114
115 $table_name = $wpdb->prefix . 'fluentform_forms';
116 $limit = 10;
117 // Prepare the query with a WHERE condition
118 $query = $wpdb->prepare(
119 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- False positive: the query is prepared via $this->wpdb->prepare(), which this sniff does not recognise, and only $wpdb->prefix table names are interpolated. Audited 2026-07-16.
120 "SELECT id, title FROM {$table_name} WHERE status = %s LIMIT %d",
121 'published', $limit
122 );
123 // Execute the query and retrieve the results
124 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- False positive: the query is prepared via $this->wpdb->prepare(), which this sniff does not recognise, and only $wpdb->prefix table names are interpolated. Audited 2026-07-16.
125 $form_result = $wpdb->get_results($query);
126
127 if (!empty($form_result)) {
128 foreach ($form_result as $form) {
129 $key = $this->key($form->id);
130 $forms[$key] = $form->title;
131 }
132 }
133 return $forms;
134 }
135
136 public function restResponse($args) {
137 $forms = [];
138 if (!$this->class_exists()) {
139 return [];
140 }
141
142 global $wpdb;
143 $table_name = $wpdb->prefix . 'fluentform_forms';
144 if (!empty($args['inputValue'])) {
145 $limit = 10;
146 // Prepare the query with a LIKE condition
147 $query = $wpdb->prepare(
148 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- False positive: the query is prepared via $this->wpdb->prepare(), which this sniff does not recognise, and only $wpdb->prefix table names are interpolated. Audited 2026-07-16.
149 "SELECT id, title FROM {$table_name} WHERE title LIKE %s AND status = %s LIMIT %d",
150 '%' . $wpdb->esc_like($args['inputValue']) . '%','published',$limit
151 );
152 // Execute the query and retrieve the results
153 // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- False positive: the query is prepared via $this->wpdb->prepare(), which this sniff does not recognise, and only $wpdb->prefix table names are interpolated. Audited 2026-07-16.
154 $form_result = $wpdb->get_results($query);
155 if (!empty($form_result)) {
156 foreach ($form_result as $form) {
157 $key = $this->key($form->id);
158 $forms[$key] = $form->title;
159 }
160 }
161 $result = array_values(GlobalFields::get_instance()->normalize_fields($forms, 'source', $this->id));
162 return $result;
163 }
164 if (isset($args['form_id'])) {
165 return $this->keys_generator($args['form_id']);
166 }
167
168 wp_send_json_error([]);
169 }
170
171 public function keys_generator($form_id) {
172 $formData = [];
173 $formApi = fluentFormApi('forms')->form($form_id);
174 $formFields = $formApi->inputs();
175 if( !empty( $formFields ) ) {
176 $formData = $this->extractVisibleFields($formFields);
177 };
178 return $formData;
179 }
180
181 function extractVisibleFields($inputArray , $recursive = false) {
182 $outputArray = [];
183 foreach ($inputArray as $field) {
184 if ( $recursive && isset($field['settings']['visible']) && $field['settings']['visible']) {
185 $label = $field['settings']['label'];
186 $value = $field['attributes']['name'];
187 if( $value == 'first_name' || $value == 'last_name' ) {
188 $outputArray[] = ['label' => $label, 'value' => 'tag__' . $value];
189 }else{
190 $outputArray[] = ['label' => $label, 'value' => 'tag_' . $value];
191 }
192
193 }
194 if (isset($field['raw']['fields']) && is_array($field['raw']['fields'])) {
195 $main_label = $field['admin_label'];
196 $main_value = $field['raw']['attributes']['name'];
197 $outputArray[] = [ 'label' => $main_label, 'value' => 'tag_'. $main_value ];
198 $outputArray = array_merge($outputArray, $this->extractVisibleFields($field['raw']['fields'], true ) );
199 }else if( !$recursive ) {
200 $label = $field['raw']['settings']['label'];
201 $value = $field['raw']['attributes']['name'];
202 $outputArray[] = [ 'label' => $label, 'value' => 'tag_'. $value ];
203 }
204 }
205 return $outputArray;
206 }
207
208
209 public function save_new_records($insertId,$formData,$form) {
210 $submission = wpFluent()->table('fluentform_submissions')
211 ->where('form_id', $form->id)
212 ->where('id', $insertId)
213 ->first();
214 $data = [];
215 if( !empty( $submission ) ) {
216 $data['ip'] = $submission->ip;
217 $data['timestamp'] = Helper::get_utc_time($submission->created_at);
218 $inputs = \FluentForm\App\Modules\Form\FormFieldsParser::getEntryInputs($form);
219 $submission = \FluentForm\App\Modules\Form\FormDataParser::parseFormEntry($submission, $form, $inputs, false);
220 foreach ($submission->user_inputs as $key => $field) {
221 $getFieldRow = wpFluent()->table('fluentform_entry_details')
222 ->where('submission_id', $submission->id)
223 ->where('field_name',$key)
224 ->get();
225 if( count( $getFieldRow ) > 1 ) {
226 foreach ($getFieldRow as $_key => $_value) {
227 if( !empty( $getFieldRow[$_key] ) ) {
228 if( $_value->sub_field_name == 'first_name' || $_value->sub_field_name == 'last_name' ) {
229 $data['_'.$_value->sub_field_name] = $_value->field_value;
230 }else{
231 $data[$_value->sub_field_name] = $_value->field_value;
232 }
233 }
234 }
235 $data[$key] = $field;
236 }else{
237 if( $key == 'first_name' || $key == 'last_name' ) {
238 $data['_'.$key] = $field;
239 }else{
240 $data[$key] = $field;
241 }
242 }
243 }
244 }
245 $data['title'] = $form->title ? $form->title : '';
246 $data['timestamp'] = isset($data['timestamp']) ? $data['timestamp'] : time();
247 $data['submission_id'] = $submission->id;
248
249 if (!empty($data)) {
250 $key = $this->key($form->id);
251 $this->save([
252 'source' => $this->id,
253 'entry_key' => $key,
254 'data' => $data,
255 ]);
256 return true;
257 }
258 return false;
259 }
260
261 public function key($key = '') {
262 $key = $this->id . '_' . $key;
263 return $key;
264 }
265
266 public function saved_post($post, $data, $nx_id) {
267 $this->get_notification_ready($data);
268 }
269
270 /**
271 * This function responsible for making ready the notifications for the first time
272 * we have made a notification.
273 *
274 * @param string $type
275 * @param array $data
276 * @return void
277 */
278 public function get_notification_ready($data = array()) {
279 if( !empty( $data['__form_list']['value'] ) ) {
280 $form_list = explode('_',$data['__form_list']['value']);
281 if( !empty( $form_list[1] ) ) {
282 $form = wpFluent()->table('fluentform_forms')->where('id', $form_list[1])->first();
283 // $valueFrom = date('Y-m-d',strtotime('-'.$data['display_from'].' days',time()));
284 $valueFrom = gmdate('Y-m-d H:i:s', Helper::generate_time_string($data));
285 $valueTo = gmdate('Y-m-d',strtotime('1 days',time()));
286 $query = wpFluent()->table('fluentform_submissions')
287 ->where('form_id', $form->id);
288 // define('FLUENTFORM_VERSION', '5.0.6')
289 if( version_compare(FLUENTFORM_VERSION, '5.0.0', '>=')){
290 $query = $query->whereBetween('created_at', [$valueFrom, $valueTo] );
291 }
292 else{
293 $query = $query->whereBetween('created_at', $valueFrom, $valueTo );
294 }
295
296 $query = $query->orderBy('id','DESC')
297 ->limit($data['display_last']);
298 $submissionArr = $query->get();
299 $entries = [];
300 foreach ($submissionArr as $sub) {
301 if( !empty( $sub ) ) {
302 $entry_data = [];
303 $inputs = \FluentForm\App\Modules\Form\FormFieldsParser::getEntryInputs($form);
304 $submission = \FluentForm\App\Modules\Form\FormDataParser::parseFormEntry($sub, $form, $inputs, false);
305 foreach ($submission->user_inputs as $key => $field) {
306 $getFieldRow = wpFluent()->table('fluentform_entry_details')
307 ->where('submission_id', $submission->id)
308 ->where('field_name',$key)
309 ->get();
310 if( count( $getFieldRow ) > 1 ) {
311 foreach ($getFieldRow as $__key => $_value) {
312 if( !empty( $getFieldRow[$__key] ) ) {
313 if( $_value->sub_field_name == 'first_name' || $_value->sub_field_name == 'last_name' ) {
314 $entry_data['_'.$_value->sub_field_name] = $_value->field_value;
315 }else{
316 $entry_data[$_value->sub_field_name] = $_value->field_value;
317 }
318 }
319 }
320 $entry_data[$key] = $field;
321 }else{
322 if( $key == 'first_name' || $key == 'last_name' ) {
323 $entry_data['_'.$key] = $field;
324 }else{
325 $entry_data[$key] = $field;
326 }
327 }
328 }
329 $entry_data['title'] = $form->title ? $form->title : '';
330 $entry_data['ip'] = $sub->ip;
331 $entry_data['timestamp'] = Helper::get_utc_time($sub->created_at);
332 $entry_data['submission_id'] = $submission->id;
333 if( $this->is_submission_exists((int) $data['nx_id'], $submission->id) ) {
334 continue;
335 }
336 $_key = $this->key($form->id);
337 if (!empty($data)) {
338 $entries[] = [
339 'nx_id' => $data['nx_id'],
340 'source' => $this->id,
341 'entry_key' => $_key,
342 'data' => $entry_data,
343 ];
344 }
345 }
346 }
347 $this->update_notifications($entries);
348 }
349 }
350 }
351
352 public function is_submission_exists( $nx_id, $submission_id ) {
353 $entries = Entries::get_instance()->get_entries($nx_id);
354 $filteredData = array_filter($entries, function ($item) use ($submission_id) {
355 return $item['submission_id'] == $submission_id;
356 });
357 return $filteredData ? true : false;
358 }
359
360 /**
361 * Limit entry by selected form in 'Select a Form';
362 *
363 * @param [type] $return
364 * @param [type] $entry
365 * @param [type] $settings
366 * @return boolean
367 */
368 public function can_entry($return, $entry, $settings){
369 if(!empty($settings['form_list']) && !empty($entry['entry_key'])){
370 $selected_form = $settings['form_list'];
371 $form_id = $entry['entry_key'];
372 if($selected_form != $form_id){
373 return false;
374 }
375
376 }
377 return $return;
378 }
379
380 /**
381 * Filter entries based on selected form
382 *
383 * @param [type] $data
384 * @param [type] $settings
385 * @return boolean
386 */
387 public function filter_by_form($data, $settings){
388 if( empty( $settings['form_list'] )) {
389 return $data;
390 }
391
392 $new_data = [];
393
394 if( ! empty( $data ) ) {
395 foreach( $data as $key => $entry ) {
396 $selected_form = $settings['form_list'];
397 $form_id = $entry['entry_key'];
398 if($selected_form == $form_id){
399 $new_data[] = $entry;
400 }
401 }
402 }
403 return $new_data;
404 }
405
406
407 public function doc() {
408 /* translators: %1$s: Fluent Forms installed and configured link URL, %2$s: documentation link URL, %3$s: video tutorial link URL, %4$s: Display Fluent Forms Submission Alert link URL */
409 return sprintf(__('
410 <p>To use the campaign & form subscription data, make sure that you have <a target="_blank" href="%1$s">Fluent Forms installed and configured</a> on your website. For detailed guidelines, follow this <a target="_blank" href="%2$s">documentation</a>.</p>
411
412 <p>🎥 Learn quickly from the <a target="_blank" href="%3$s">video tutorial</a>.</p>
413
414 <p>⚙️ NotificationX integration with Fluent Forms</p>
415
416 <p>📖 Recommended Reading: </p>
417 <p>🔥How To <a target="_blank" href="%4$s">Display Fluent Forms Submission Alert</a> Using NotificationX?</p>
418 ', 'notificationx'),
419 'https://wordpress.org/plugins/fluentform/',
420 'https://notificationx.com/docs/fluent-forms-submission-alert-notificationx',
421 'https://youtu.be/cl0WEazGflU',
422 'https://notificationx.com/blog/display-fluent-forms-submission-alert/'
423 );
424 }
425 }
426