PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/models/FrmUsage.php +238 -52 6.25 → trunk View file →
@@ -17,11 +17,14 @@
17 17 if ( ! $this->tracking_allowed() ) {
18 18 return;
19 19 }
20 20
21 + $snapshot = $this->snapshot();
22 + $this->clean_before_send( $snapshot );
23 +
21 24 $ep = 'aHR0cHM6Ly91c2FnZTIuZm9ybWlkYWJsZWZvcm1zLmNvbS9zbmFwc2hvdA==';
22 25 // $ep = base64_encode( 'http://localhost:4567/snapshot' ); // Uncomment for testing
23 - $body = json_encode( $this->snapshot() );
26 + $body = json_encode( $snapshot );
24 27
25 28 // Setup variable for wp_remote_request.
26 29 $post = array(
27 30 'method' => 'POST',
@@ -44,8 +47,11 @@
44 47 }
45 48
46 49 /**
47 50 * @since 3.06.04
51 + *
52 + * @param bool $regenerate
53 + *
48 54 * @return string
49 55 */
50 56 public function uuid( $regenerate = false ) {
51 57 $uuid_key = 'frm-usage-uuid';
@@ -50,13 +56,13 @@
50 56 public function uuid( $regenerate = false ) {
51 57 $uuid_key = 'frm-usage-uuid';
52 58 $uuid = get_option( $uuid_key );
53 59
54 - if ( $regenerate || empty( $uuid ) ) {
60 + if ( $regenerate || ! $uuid ) {
55 61 // Definitely not cryptographically secure but
56 - // close enough to provide an unique id
62 + // close enough to provide a unique id
57 63 $uuid = md5( uniqid() . site_url() );
58 - update_option( $uuid_key, $uuid, 'no' );
64 + update_option( $uuid_key, $uuid, false );
59 65 }
60 66
61 67 return $uuid;
62 68 }
@@ -62,8 +68,9 @@
62 68 }
63 69
64 70 /**
65 71 * @since 3.06.04
72 + *
66 73 * @return array
67 74 */
68 75 public function snapshot() {
69 76 global $wpdb, $wp_version;
@@ -72,10 +79,8 @@
72 79 $form_counts = FrmForm::get_count();
73 80
74 81 $snap = array(
75 82 'uuid' => $this->uuid(),
76 - // Let's keep it anonymous.
77 - 'admin_email' => '',
78 83 'wp_version' => $wp_version,
79 84 'php_version' => phpversion(),
80 85 'mysql_version' => $wpdb->db_version(),
81 86 'os' => FrmAppHelper::get_server_os(),
@@ -84,8 +89,9 @@
84 89 'active_license' => FrmAppHelper::pro_is_installed(),
85 90 'form_count' => $form_counts->published,
86 91 'entry_count' => FrmEntry::getRecordCount(),
87 92 'timestamp' => gmdate( 'c' ),
93 + 'misc' => array(),
88 94
89 95 'theme_name' => is_object( $theme_data ) ? $theme_data->Name : '', // phpcs:ignore WordPress.NamingConventions
90 96 'plugins' => $this->plugins(),
91 97 'settings' => array(
@@ -95,8 +101,9 @@
95 101 'fields' => $this->fields(),
96 102 'actions' => $this->actions(),
97 103
98 104 'onboarding-wizard' => $this->onboarding_wizard(),
105 + 'welcome-tour' => FrmWelcomeTourController::get_usage_data(),
99 106 'flows' => FrmUsageController::get_flows_data(),
100 107 'payments' => $this->payments(),
101 108 'subscriptions' => $this->payments( 'frm_subscriptions' ),
102 109 );
@@ -108,8 +115,125 @@
108 115 return apply_filters( 'frm_usage_snapshot', $snap );
109 116 }
110 117
111 118 /**
119 + * Cleans the snapshot data before sending.
120 + *
121 + * @param array $data Snapshot data.
122 + *
123 + * @return void
124 + */
125 + private function clean_before_send( &$data ) {
126 + $skip_keys = array(
127 + 'plan_id',
128 + 'paypal_item_name',
129 + 'account_num',
130 + 'routing_num',
131 + 'bank_name',
132 + 'business_email',
133 +
134 + // Form action settings.
135 + 'quiz',
136 + 'email_to',
137 + 'cc',
138 + 'bcc',
139 + 'from',
140 + 'email_subject',
141 + 'email_msg',
142 + 'email_message',
143 + 'success_msg',
144 + 'success_url',
145 + 'success_page_id',
146 + 'redirect_msg',
147 + 'conditions',
148 + 'list_id',
149 + 'api_key',
150 + 'url',
151 + 'data_fields',
152 + 'reg_email_msg',
153 +
154 + // Form settings.
155 + 'form_id',
156 + 'description',
157 + 'submit_conditions-hide_field',
158 + 'submit_conditions-hide_field_cond',
159 + 'submit_conditions-hide_opt',
160 + 'submit_conditions-show_hide',
161 + 'submit_conditions-any_all',
162 +
163 + // Field settings.
164 + 'show_hide',
165 + 'any_all',
166 + 'hide_field',
167 + 'hide_field_cond',
168 + 'hide_opt',
169 + 'custom_html',
170 + 'blank',
171 + 'required_indicator',
172 + 'invalid',
173 + 'unique_msg',
174 + 'edit_text',
175 + 'start_over_label',
176 + 'add_label',
177 + 'remove_label',
178 + 'draft',
179 + );
180 +
181 + /**
182 + * Filter the keys to skip when cleaning the snapshot data before sending.
183 + *
184 + * @since 6.28
185 + *
186 + * @param array $skip_keys Data keys.
187 + */
188 + $skip_keys = apply_filters( 'frm_usage_skip_keys', $skip_keys );
189 +
190 + $long_text_keys = array( 'description' );
191 +
192 + /**
193 + * Filter the keys to replace with a long text placeholder before sending.
194 + *
195 + * @since 6.28
196 + *
197 + * @paramm array $long_text_keys Data keys.
198 + */
199 + $long_text_keys = apply_filters( 'frm_usage_long_text_keys', $long_text_keys );
200 +
201 + foreach ( $data as $key => &$value ) {
202 + if ( ! $value ) {
203 + continue;
204 + }
205 +
206 + if ( in_array( $key, $skip_keys, true ) || str_ends_with( $key, '_url' ) ) {
207 + unset( $data[ $key ] );
208 + continue;
209 + }
210 +
211 + if ( is_object( $value ) ) {
212 + $value = '{{object}}';
213 + continue;
214 + }
215 +
216 + if ( is_array( $value ) ) {
217 + $this->clean_before_send( $value );
218 + continue;
219 + }
220 +
221 + if ( in_array( $key, $long_text_keys, true ) || str_ends_with( $key, '_msg' ) ) {
222 + // Replace it with a placeholder.
223 + $value = '{{long_text}}';
224 + continue;
225 + }
226 +
227 + // If key ends with `_email`, or value contains `@`, this might contain an email address.
228 + if ( str_ends_with( $key, '_email' ) || ( is_string( $value ) && str_contains( $value, '@' ) ) ) {
229 + // Replace it with a placeholder.
230 + $value = '{{contain_email}}';
231 + }
232 + }//end foreach
233 + }
234 +
235 + /**
112 236 * Gets onboarding wizard data.
113 237 *
114 238 * @since 6.16.1
115 239 *
@@ -137,29 +261,21 @@
137 261 *
138 262 * @since 6.16.1
139 263 *
140 264 * @param string $table Database table name.
265 + *
141 266 * @return array
142 267 */
143 268 private function payments( $table = 'frm_payments' ) {
144 269 $allowed_tables = array( 'frm_payments', 'frm_subscriptions' );
145 - if ( ! in_array( $table, $allowed_tables, true ) ) {
146 - return array();
147 - }
148 270
149 - if ( ! FrmTransLiteAppHelper::payments_table_exists() ) {
271 + if ( ! in_array( $table, $allowed_tables, true ) || ! FrmTransLiteAppHelper::payments_table_exists() ) {
150 272 return array();
151 273 }
152 274
153 - global $wpdb;
154 - $rows = $wpdb->get_results(
155 - $wpdb->prepare(
156 - 'SELECT amount, status, paysys, created_at FROM %1$s',
157 - $wpdb->prefix . $table
158 - )
159 - );
275 + $rows = $this->get_payment_db_rows( $table );
276 + $payments = array();
160 277
161 - $payments = array();
162 278 foreach ( $rows as $row ) {
163 279 $payments[] = array(
164 280 'amount' => (float) $row->amount,
165 281 'status' => $row->status,
@@ -171,15 +287,44 @@
171 287 return $payments;
172 288 }
173 289
174 290 /**
291 + * @since 6.30
292 + *
293 + * @param string $table
294 + *
295 + * @return array
296 + */
297 + private function get_payment_db_rows( $table ) {
298 + global $wpdb;
299 +
300 + if ( FrmDb::db_column_exists( $table, 'test' ) ) {
301 + return $wpdb->get_results(
302 + $wpdb->prepare(
303 + 'SELECT amount, status, paysys, created_at FROM %i WHERE test IS NULL OR test != 1',
304 + $wpdb->prefix . $table
305 + )
306 + );
307 + }
308 +
309 + // Fallback for PayPal add-on where this column does not exist.
310 + return $wpdb->get_results(
311 + $wpdb->prepare(
312 + 'SELECT amount, status, paysys, created_at FROM %i',
313 + $wpdb->prefix . $table
314 + )
315 + );
316 + }
317 +
318 + /**
175 319 * @since 3.06.04
320 + *
176 321 * @return array
177 322 */
178 323 private function plugins() {
179 324 $plugin_list = FrmAppHelper::get_plugins();
325 + $plugins = array();
180 326
181 - $plugins = array();
182 327 foreach ( $plugin_list as $slug => $info ) {
183 328 $plugins[] = array(
184 329 'name' => $info['Name'],
185 330 'slug' => $slug,
@@ -194,8 +339,9 @@
194 339 /**
195 340 * Add global settings to tracking data.
196 341 *
197 342 * @since 3.06.04
343 + *
198 344 * @return array
199 345 */
200 346 private function settings() {
201 347 $settings_list = FrmAppHelper::get_settings();
@@ -245,8 +391,9 @@
245 391 *
246 392 * @since 3.06.04
247 393 *
248 394 * @param FrmSettings $settings_list
395 + *
249 396 * @return array
250 397 */
251 398 private function messages( $settings_list ) {
252 399 $messages = array(
@@ -259,11 +406,11 @@
259 406 'login_msg',
260 407 'admin_permission',
261 408 );
262 409
263 - $default = $settings_list->default_options();
410 + $default = $settings_list->default_options();
411 + $message_settings = array();
264 412
265 - $message_settings = array();
266 413 foreach ( $messages as $message ) {
267 414 $message_settings[ 'changed-' . $message ] = $settings_list->$message === $default[ $message ] ? 0 : 1;
268 415 }
269 416
@@ -275,8 +422,9 @@
275 422 *
276 423 * @since 3.06.04
277 424 *
278 425 * @param FrmSettings $settings_list
426 + *
279 427 * @return array
280 428 */
281 429 private function permissions( $settings_list ) {
282 430 $permissions = array();
@@ -292,8 +440,9 @@
292 440 }
293 441
294 442 /**
295 443 * @since 3.06.04
444 + *
296 445 * @return array
297 446 */
298 447 private function forms() {
299 448 $s_query = array(
@@ -341,8 +490,9 @@
341 490 'submit_conditions',
342 491 );
343 492
344 493 $style = new FrmStyle();
494 +
345 495 foreach ( $saved_forms as $form ) {
346 496 $new_form = array(
347 497 'form_id' => $form->id,
348 498 'description' => $form->description,
@@ -354,28 +504,31 @@
354 504 'form_action_count' => $this->form_action_count( $form->id ),
355 505 );
356 506
357 507 foreach ( $settings as $setting ) {
358 - if ( isset( $form->options[ $setting ] ) ) {
359 - if ( 'custom_style' === $setting ) {
360 - $style->id = $form->options[ $setting ];
508 + if ( ! isset( $form->options[ $setting ] ) ) {
509 + continue;
510 + }
361 511
362 - if ( ! $style->id ) {
363 - $style_name = 0;
364 - } elseif ( 1 === intval( $style->id ) ) {
365 - $style_name = 'formidable-style';
366 - } else {
367 - $style_post = $style->get_one();
368 - $style_name = $style_post ? $style_post->post_name : 'formidable-style';
369 - }
512 + if ( 'custom_style' !== $setting ) {
513 + $new_form[ $setting ] = $this->maybe_json( $form->options[ $setting ] );
514 + continue;
515 + }
370 516
371 - $new_form[ $setting ] = $style_name;
372 - } else {
373 - $new_form[ $setting ] = $this->maybe_json( $form->options[ $setting ] );
374 - }
517 + $style->id = $form->options[ $setting ];
518 +
519 + if ( ! $style->id ) {
520 + $style_name = 0;
521 + } elseif ( 1 === intval( $style->id ) ) {
522 + $style_name = 'formidable-style';
523 + } else {
524 + $style_post = $style->get_one();
525 + $style_name = $style_post ? $style_post->post_name : 'formidable-style';
375 526 }
376 - }
377 527
528 + $new_form[ $setting ] = $style_name;
529 + }//end foreach
530 +
378 531 $forms[] = apply_filters( 'frm_usage_form', $new_form, compact( 'form' ) );
379 532 }//end foreach
380 533
381 534 // If the array uses numeric keys, reset them.
@@ -383,8 +536,11 @@
383 536 }
384 537
385 538 /**
386 539 * @since 3.06.04
540 + *
541 + * @param int|string $form_id Form ID.
542 + *
387 543 * @return int
388 544 */
389 545 private function form_field_count( $form_id ) {
390 546 global $wpdb;
@@ -401,8 +557,11 @@
401 557 }
402 558
403 559 /**
404 560 * @since 3.06.04
561 + *
562 + * @param int|string $form_id Form ID.
563 + *
405 564 * @return int
406 565 */
407 566 private function form_action_count( $form_id ) {
408 567 $args = array(
@@ -418,8 +577,9 @@
418 577 /**
419 578 * Get the last 100 fields created.
420 579 *
421 580 * @since 3.06.04
581 + *
422 582 * @return array
423 583 */
424 584 private function fields() {
425 585 $args = array(
@@ -427,42 +587,65 @@
427 587 'order_by' => 'id DESC',
428 588 );
429 589
430 590 $fields = FrmDb::get_results( 'frm_fields', array(), 'id, form_id, name, type, field_options', $args );
591 +
431 592 foreach ( $fields as $k => $field ) {
432 593 FrmAppHelper::unserialize_or_decode( $field->field_options );
433 - $fields[ $k ]->field_options = json_encode( $field->field_options );
594 + $fields[ $k ]->field_options = $field->field_options;
434 595 }
596 +
435 597 return $fields;
436 598 }
437 599
438 600 /**
439 601 * @since 3.06.04
602 + *
440 603 * @return array
441 604 */
442 605 private function actions() {
443 - $args = array(
444 - 'post_type' => FrmFormActionsController::$action_post_type,
445 - 'numberposts' => 100,
446 - );
606 + $actions = array();
607 + $offset = 0;
608 + $limit = 100;
609 + $limit_plus_one = $limit + 1;
447 610
448 - $actions = array();
611 + do {
612 + $args = array(
613 + 'post_type' => FrmFormActionsController::$action_post_type,
614 + 'numberposts' => $limit_plus_one,
615 + 'offset' => $offset,
616 + );
617 + $saved_actions = get_posts( $args );
618 + $has_more = count( $saved_actions ) === $limit_plus_one;
449 619
450 - $saved_actions = FrmDb::check_cache( json_encode( $args ), 'frm_actions', $args, 'get_posts' );
451 - foreach ( $saved_actions as $action ) {
452 - $actions[] = array(
453 - 'form_id' => $action->menu_order,
454 - 'type' => $action->post_excerpt,
455 - 'status' => $action->post_status,
456 - 'settings' => $action->post_content,
457 - );
458 - }
620 + if ( $has_more ) {
621 + // Pop off the last item as it is only queried to determine if there are more results.
622 + array_pop( $saved_actions );
623 + }
459 624
625 + foreach ( $saved_actions as $action ) {
626 + $actions[] = array(
627 + 'form_id' => $action->menu_order,
628 + 'type' => $action->post_excerpt,
629 + 'status' => $action->post_status,
630 + 'settings' => FrmAppHelper::maybe_json_decode( $action->post_content ),
631 + );
632 + unset( $action );
633 + }
634 +
635 + $offset += $limit;
636 +
637 + unset( $saved_actions );
638 +
639 + gc_collect_cycles();
640 + } while ( $has_more );
641 +
460 642 return $actions;
461 643 }
462 644
463 645 /**
464 646 * @since 3.06.04
647 + *
465 648 * @return bool
466 649 */
467 650 private function tracking_allowed() {
468 651 return FrmUsageController::tracking_allowed();
@@ -469,8 +652,11 @@
469 652 }
470 653
471 654 /**
472 655 * @since 3.06.04
656 + *
657 + * @param mixed $value Value.
658 + *
473 659 * @return string
474 660 */
475 661 private function maybe_json( $value ) {
476 662 return is_array( $value ) ? json_encode( $value ) : $value;