PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.4.0
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.4.0
2.12.6 2.12.5 2.12.4 2.12.3 2.12.2 2.12.1 2.12.0 2.11.1 2.11.0 2.10.1 2.10.0 2.9.1 2.9.0 2.8.2 2.8.1 2.7.0 2.7.1 2.8.0 trunk 0.0.10 0.0.11 0.0.12 0.0.13 0.0.2 0.0.3 All 96 releases
sureforms / admin / admin.php

admin.php in SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz 2.4.0, at admin/admin.php

1,578 lines 52.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Admin Class.
4 *
5 * @package sureforms.
6 */
7
8 namespace SRFM\Admin;
9
10 use SRFM\Inc\AI_Form_Builder\AI_Helper;
11 use SRFM\Inc\Database\Tables\Entries;
12 use SRFM\Inc\Helper;
13 use SRFM\Inc\Onboarding;
14 use SRFM\Inc\Payments\Payment_Helper;
15 use SRFM\Inc\Payments\Stripe\Stripe_Helper;
16 use SRFM\Inc\Traits\Get_Instance;
17
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit; // Exit if accessed directly.
20 }
21 /**
22 * Admin handler class.
23 *
24 * @since 0.0.1
25 */
26 class Admin {
27 use Get_Instance;
28
29 /**
30 * Dashboard widget entries data.
31 *
32 * @var array
33 * @since 1.9.1
34 */
35 private $dashboard_widget_data = [];
36
37 /**
38 * SureForms Page Default permission.
39 *
40 * @var string
41 * @since 1.12.2
42 */
43 private static $sureforms_page_default_capability = 'manage_options';
44
45 /**
46 * Class constructor.
47 *
48 * @return void
49 * @since 0.0.1
50 */
51 public function __construct() {
52 add_action( 'admin_menu', [ $this, 'add_menu_page' ], 9 );
53 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
54 add_action( 'admin_menu', [ $this, 'settings_page' ] );
55 add_action( 'admin_menu', [ $this, 'add_new_form' ] );
56 add_action( 'admin_menu', [ $this, 'add_suremail_page' ] );
57 if ( ! Helper::has_pro() ) {
58 add_action( 'admin_menu', [ $this, 'add_upgrade_to_pro' ] );
59 add_action( 'admin_footer', [ $this, 'add_upgrade_to_pro_target_attr' ] );
60 }
61
62 add_filter( 'plugin_action_links', [ $this, 'add_settings_link' ], 10, 2 );
63 add_action( 'enqueue_block_assets', [ $this, 'enqueue_styles' ] );
64 add_action( 'admin_head', [ $this, 'enqueue_header_styles' ] );
65 add_filter( 'admin_body_class', [ $this, 'admin_template_picker_body_class' ] );
66
67 // this action is used to restrict Spectra's quick action bar on SureForms CPTS.
68 add_action( 'uag_enable_quick_action_sidebar', [ $this, 'restrict_spectra_quick_action_bar' ] );
69
70 add_action( 'current_screen', [ $this, 'enable_gutenberg_for_sureforms' ], 100 );
71 add_action( 'admin_notices', [ $this, 'srfm_pro_version_compatibility' ] );
72
73 // This action enqueues translations for NPS Survey library.
74 // A better solution will be required from library to resolve plugin conflict.
75 add_action(
76 'admin_footer',
77 static function() {
78 Helper::register_script_translations( 'nps-survey-script' );
79 },
80 1000
81 );
82 // Enfold theme compatibility to enable block editor for SureForms post type.
83 add_filter( 'avf_use_block_editor_for_post', [ $this, 'enable_block_editor_in_enfold_theme' ] );
84
85 // Add action links to the plugin page.
86 add_filter( 'plugin_action_links_' . SRFM_BASENAME, [ $this, 'add_action_links' ] );
87 // Check if admin notification is enabled and add entries badge.
88 $general_options = get_option( 'srfm_general_settings_options', [] );
89 $admin_notification_on = isset( $general_options['srfm_admin_notification'] ) ? (bool) $general_options['srfm_admin_notification'] : true;
90
91 if ( $admin_notification_on ) {
92 add_action( 'admin_menu', [ $this, 'maybe_add_entries_badge' ], 99 );
93 }
94
95 add_action( 'admin_menu', [ $this, 'add_payments_badge' ], 99 );
96
97 add_filter( 'wpforms_current_user_can', [ $this, 'disable_wpforms_capabilities' ], 10, 3 );
98
99 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_pointer' ] );
100 // Ajax callbacks for wp-pointer functionality.
101 add_action( 'wp_ajax_should_show_pointer', [ $this, 'pointer_should_show' ] );
102 add_action( 'wp_ajax_sureforms_dismiss_pointer', [ $this, 'pointer_dismissed' ] );
103 add_action( 'wp_ajax_sureforms_accept_cta', [ $this, 'pointer_accepted_cta' ] );
104
105 // Register dashboard widget only if there are recent entries.
106 add_action( 'admin_init', [ $this, 'maybe_register_dashboard_widget' ] );
107
108 // Save first form creation time stamp.
109 add_action( 'admin_init', [ $this, 'save_first_form_creation_time_stamp' ] );
110 }
111
112 /**
113 * Get the first form creation time stamp.
114 *
115 * @since 1.10.1
116 * @return int|false
117 */
118 public static function get_first_form_creation_time_stamp() {
119 return Helper::get_srfm_option( 'first_form_created_at', false );
120 }
121
122 /**
123 * Check if the first form has been created.
124 *
125 * @since 1.10.1
126 * @return bool
127 */
128 public static function is_first_form_created() {
129 // Convert the first form creation time stamp to a boolean. If it exists, it will return true, otherwise false.
130 $first_form_creation_time_stamp = self::get_first_form_creation_time_stamp();
131
132 // If the first form creation time stamp is not set, return false.
133 if ( ! $first_form_creation_time_stamp ) {
134 return false; // No forms created yet.
135 }
136
137 // Check if the first form creation time stamp is a valid integer and greater than zero.
138 return is_int( $first_form_creation_time_stamp ) && $first_form_creation_time_stamp > 0;
139 }
140
141 /**
142 * Check and save the first form creation time stamp.
143 * If not already saved.
144 *
145 * @since 1.10.1
146 * @return void
147 */
148 public static function save_first_form_creation_time_stamp() {
149 if ( ! Helper::current_user_can() || self::is_first_form_created() || ! defined( 'SRFM_FORMS_POST_TYPE' ) || ! post_type_exists( SRFM_FORMS_POST_TYPE ) ) {
150 return;
151 }
152
153 // Get the first form creation time from the database that is published.
154 $query = new \WP_Query(
155 [
156 'post_type' => SRFM_FORMS_POST_TYPE,
157 'posts_per_page' => 1,
158 'orderby' => 'date',
159 'order' => 'ASC',
160 'fields' => 'ids',
161 'post_status' => 'publish',
162 ]
163 );
164
165 if ( ! empty( $query->posts ) && isset( $query->posts[0] ) ) {
166 // Get the first post from the query result.
167 $post_id = $query->posts[0];
168 // Get the post creation time in GMT.
169 $creation_time = get_post_field( 'post_date_gmt', $post_id );
170 // Convert the creation time to a timestamp.
171 $timestamp = strtotime( $creation_time );
172
173 if ( ! $timestamp ) {
174 return;
175 }
176
177 Helper::update_srfm_option( 'first_form_created_at', $timestamp );
178 }
179 }
180
181 /**
182 * Check if n days have passed since the first form creation.
183 * This is used to determine if the dynamic nudges should be shown.
184 *
185 * @param int $days Number of days to check.
186 * @since 1.10.1
187 * @return bool
188 */
189 public static function check_first_form_creation_threshold( $days = 3 ) {
190 $first_form_creation_time_stamp = self::get_first_form_creation_time_stamp();
191
192 if ( ! $first_form_creation_time_stamp ) {
193 return false; // No forms created yet.
194 }
195
196 /**
197 * Calculate the number of days since the first form was created.
198 */
199 $days_from_creation = ( strtotime( current_time( 'mysql' ) ) - $first_form_creation_time_stamp ) / DAY_IN_SECONDS;
200
201 // Return a boolean indicating if the number of days since creation is greater than the specified days.
202 return $days_from_creation > $days;
203 }
204
205 /**
206 * Show action on plugin page.
207 *
208 * @param array $links links.
209 * @return array
210 * @since 1.4.2
211 */
212 public function add_action_links( $links ) {
213 if ( ! Helper::has_pro() ) {
214 // Display upsell link if SureForms Pro is not installed.
215 $upsell_link = add_query_arg(
216 [
217 'utm_medium' => 'plugin-list',
218 ],
219 Helper::get_sureforms_website_url( 'pricing' )
220 );
221
222 ob_start();
223 ?>
224 <a href="<?php echo esc_url( $upsell_link ); ?>" target="_blank" rel="noreferrer" class="sureforms-plugins-go-pro">
225 <?php echo esc_html__( 'Get SureForms Pro', 'sureforms' ); ?>
226 </a>
227 <?php
228 $links[] = trim( ob_get_clean() );
229 }
230
231 return $links;
232 }
233
234 /**
235 * Enable block editor in Enfold theme for SureForms post type.
236 *
237 * @param bool $use_block_editor Whether to use block editor.
238 * @since 1.3.1
239 */
240 public function enable_block_editor_in_enfold_theme( $use_block_editor ) {
241 // if SureForms form post type then return true.
242 if ( SRFM_FORMS_POST_TYPE === get_current_screen()->post_type ) {
243 return true;
244 }
245 return $use_block_editor;
246 }
247
248 /**
249 * Enable Gutenberg for SureForms associated post types.
250 *
251 * @since 0.0.10
252 */
253 public function enable_gutenberg_for_sureforms() {
254 /**
255 * Check if the classic editor is enabled from Classic Editor plugin settings or Divi settings.
256 */
257 if ( 'block' === get_option( 'classic-editor-replace' ) || 'on' === get_option( 'et_enable_classic_editor' ) ) {
258 return;
259 }
260
261 $srfm_post_types = apply_filters( 'srfm_enable_gutenberg_post_types', [ SRFM_FORMS_POST_TYPE ] );
262
263 if ( in_array( get_current_screen()->post_type, $srfm_post_types, true ) ) {
264 add_filter( 'use_block_editor_for_post_type', '__return_true', 110 );
265 add_filter( 'gutenberg_can_edit_post_type', '__return_true', 110 );
266 }
267 }
268
269 /**
270 * Sureforms editor header styles.
271 *
272 * @since 0.0.1
273 */
274 public function enqueue_header_styles() {
275 $current_screen = get_current_screen();
276 $file_prefix = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? '' : '.min';
277 $dir_name = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? 'unminified' : 'minified';
278
279 $css_uri = SRFM_URL . 'assets/css/' . $dir_name . '/';
280
281 /* RTL */
282 if ( is_rtl() ) {
283 $file_prefix .= '-rtl';
284 }
285
286 if ( 'sureforms_form' === $current_screen->id ) {
287 wp_enqueue_style( SRFM_SLUG . '-editor-header-styles', $css_uri . 'header-styles' . $file_prefix . '.css', [], SRFM_VER );
288 }
289 }
290
291 /**
292 * Add menu page.
293 *
294 * @return void
295 * @since 0.0.1
296 */
297 public function add_menu_page() {
298 $menu_slug = 'sureforms_menu';
299
300 $logo = file_get_contents( plugin_dir_path( SRFM_FILE ) . 'images/icon.svg' );
301 add_menu_page(
302 __( 'SureForms', 'sureforms' ),
303 __( 'SureForms', 'sureforms' ),
304 self::$sureforms_page_default_capability,
305 $menu_slug,
306 static function () {
307 },
308 'data:image/svg+xml;base64,' . base64_encode( $logo ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
309 30
310 );
311
312 // Add the Dashboard Submenu.
313 add_submenu_page(
314 $menu_slug,
315 __( 'Dashboard', 'sureforms' ),
316 __( 'Dashboard', 'sureforms' ),
317 self::$sureforms_page_default_capability,
318 $menu_slug,
319 [ $this, 'render_dashboard' ]
320 );
321 }
322
323 /**
324 * Add Settings page.
325 *
326 * @return void
327 * @since 0.0.1
328 */
329 public function settings_page() {
330 $callback = [ $this, 'settings_page_callback' ];
331 add_submenu_page(
332 'sureforms_menu',
333 __( 'Settings', 'sureforms' ),
334 __( 'Settings', 'sureforms' ),
335 self::$sureforms_page_default_capability,
336 'sureforms_form_settings',
337 $callback
338 );
339
340 // Get the current submenu page.
341 $submenu_page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['page'] does not provide nonce.
342
343 if ( ! isset( $_GET['tab'] ) && 'sureforms_form_settings' === $submenu_page ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['page'] does not provide nonce.
344 wp_safe_redirect( admin_url( 'admin.php?page=sureforms_form_settings&tab=general-settings' ) );
345 exit;
346 }
347 }
348
349 /**
350 * Open to Upgrade to Pro submenu link in new tab.
351 *
352 * @return void
353 * @since 1.6.1
354 */
355 public function add_upgrade_to_pro_target_attr() {
356 ?>
357 <script type="text/javascript">
358 document.addEventListener('DOMContentLoaded', function () {
359 // Upgrade link handler.
360 // IMPORTANT: If this URL changes, also update it in the `add_upgrade_to_pro` function.
361 const upgradeLink = document.querySelector('a[href*="https://sureforms.com/upgrade"]');
362 if (upgradeLink) {
363 upgradeLink.addEventListener('click', e => {
364 e.preventDefault();
365 window.open(upgradeLink.href, '_blank');
366 });
367 }
368 });
369 </script>
370 <?php
371 }
372
373 /**
374 * Add Upgrade to pro menu item.
375 *
376 * @return void
377 * @since 1.6.1
378 */
379 public function add_upgrade_to_pro() {
380 // The url used here is used as a selector for css to style the upgrade to pro submenu.
381 // If you are changing this url, please make sure to update the css as well.
382 $upgrade_url = add_query_arg(
383 [
384 'utm_medium' => 'submenu_link_upgrade',
385 ],
386 Helper::get_sureforms_website_url( 'upgrade' )
387 );
388
389 add_submenu_page(
390 'sureforms_menu',
391 __( 'Upgrade', 'sureforms' ),
392 __( 'Upgrade', 'sureforms' ),
393 self::$sureforms_page_default_capability,
394 $upgrade_url
395 );
396 }
397
398 /**
399 * Add SMTP promotional submenu page.
400 *
401 * @return void
402 * @since 1.7.1
403 */
404 public function add_suremail_page() {
405 add_submenu_page(
406 'sureforms_menu',
407 __( 'SMTP', 'sureforms' ),
408 __( 'SMTP', 'sureforms' ),
409 self::$sureforms_page_default_capability,
410 'sureforms_smtp',
411 [ $this, 'suremail_page_callback' ]
412 );
413
414 // Get the current submenu page.
415 $submenu_page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['page'] does not provide nonce.
416
417 // Check if SureMail is installed and active.
418 if ( 'sureforms_smtp' === $submenu_page && file_exists( WP_PLUGIN_DIR . '/suremails/suremails.php' ) && is_plugin_active( 'suremails/suremails.php' ) ) {
419 // Plugin is installed and active - redirect to SureMail dashboard.
420 wp_safe_redirect( admin_url( 'options-general.php?page=suremail#/dashboard' ) );
421 exit;
422 }
423 }
424
425 /**
426 * SMTP promotional page callback.
427 *
428 * @return void
429 * @since 1.7.1
430 */
431 public function suremail_page_callback() {
432 ?>
433 <div id="srfm-suremail-container" class="srfm-admin-wrapper"></div>
434 <?php
435 }
436
437 /**
438 * Render Admin Dashboard.
439 *
440 * @return void
441 * @since 0.0.1
442 */
443 public function render_dashboard() {
444 ?>
445 <div id="srfm-dashboard-container" class="srfm-admin-wrapper"></div>
446 <?php
447 }
448
449 /**
450 * Settings page callback.
451 *
452 * @return void
453 * @since 0.0.1
454 */
455 public function settings_page_callback() {
456 ?>
457 <div id="srfm-settings-container" class="srfm-admin-wrapper"></div>
458 <?php
459 }
460
461 /**
462 * Add new form menu item.
463 *
464 * @return void
465 * @since 0.0.1
466 */
467 public function add_new_form() {
468 add_submenu_page(
469 'sureforms_menu',
470 __( 'Forms', 'sureforms' ),
471 __( 'Forms', 'sureforms' ),
472 self::$sureforms_page_default_capability,
473 'sureforms_forms',
474 [ $this, 'render_forms' ],
475 1
476 );
477 add_submenu_page(
478 'sureforms_menu',
479 __( 'New Form', 'sureforms' ),
480 __( 'New Form', 'sureforms' ),
481 self::$sureforms_page_default_capability,
482 'add-new-form',
483 [ $this, 'add_new_form_callback' ],
484 2
485 );
486 $entries_hook = add_submenu_page(
487 'sureforms_menu',
488 __( 'Entries', 'sureforms' ),
489 __( 'Entries', 'sureforms' ),
490 self::$sureforms_page_default_capability,
491 SRFM_ENTRIES,
492 [ $this, 'render_entries' ],
493 3
494 );
495
496 add_submenu_page(
497 'sureforms_menu',
498 __( 'Payments', 'sureforms' ),
499 __( 'Payments', 'sureforms' ),
500 self::$sureforms_page_default_capability,
501 SRFM_PAYMENTS,
502 [ $this, 'render_payments' ],
503 4
504 );
505
506 if ( $entries_hook ) {
507 add_action( 'load-' . $entries_hook, [ $this, 'mark_entries_page_visit' ] );
508 }
509 }
510
511 /**
512 * Payments page callback.
513 *
514 * @return void
515 * @since 2.0.0
516 */
517 public function render_payments() {
518 ?>
519 <div id="srfm-payments-react-container" class="srfm-admin-wrapper"></div>
520 <?php
521 }
522
523 /**
524 * Add new form mentu item callback.
525 *
526 * @return void
527 * @since 0.0.1
528 */
529 public function add_new_form_callback() {
530 ?>
531 <div id="srfm-add-new-form-container" class="srfm-admin-wrapper"></div>
532 <?php
533 }
534
535 /**
536 * Forms page callback.
537 *
538 * @return void
539 * @since 2.0.0
540 */
541 public function render_forms() {
542 ?>
543 <div id="srfm-forms-root" class="srfm-admin-wrapper"></div>
544 <?php
545 }
546
547 /**
548 * Entries page callback.
549 *
550 * @since 0.0.13
551 * @since 2.0.0 - Updated the entries UI and the function definition.
552 * @return void
553 */
554 public function render_entries() {
555 echo '<div id="srfm-entries-root"></div>';
556 }
557
558 /**
559 * Add notification badge to SureForms menu when there are new entries.
560 *
561 * @since 1.7.3
562 * @return void
563 */
564 public function maybe_add_entries_badge() {
565 if ( ! Helper::current_user_can() ) {
566 return;
567 }
568
569 // If currently viewing the entries listing page, mark it as visited and skip the badge.
570 if ( isset( $_GET['page'] ) && SRFM_ENTRIES === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Only checking the page slug.
571 $this->mark_entries_page_visit();
572 return;
573 }
574
575 $srfm_options = get_option( 'srfm_options', [] );
576 $last_visit = isset( $srfm_options['entries_last_visited'] ) ? absint( $srfm_options['entries_last_visited'] ) : 0;
577 $new_entries = Entries::get_entries_count_after( $last_visit );
578
579 if ( $new_entries <= 0 ) {
580 return;
581 }
582
583 global $menu;
584 foreach ( $menu as $index => $item ) {
585 if ( isset( $item[2] ) && 'sureforms_menu' === $item[2] ) {
586 ob_start();
587 ?>
588 <span class="srfm-update-dot"></span>
589 <?php
590 $dot_html = ob_get_clean();
591 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Adding notifications for menu item.
592 $menu[ $index ][0] .= $dot_html;
593 break;
594 }
595 }
596
597 global $submenu;
598 if ( isset( $submenu['sureforms_menu'] ) ) {
599 foreach ( $submenu['sureforms_menu'] as $index => $sub_item ) {
600 if ( isset( $sub_item[2] ) && SRFM_ENTRIES === $sub_item[2] ) {
601 ob_start();
602 ?>
603 <span class="update-plugins count-<?php echo absint( $new_entries ); ?>">
604 <span class="plugin-count"><?php echo absint( $new_entries ); ?></span>
605 </span>
606 <?php
607 $badge_html = ob_get_clean();
608 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Adding notifications for submenu item.
609 $submenu['sureforms_menu'][ $index ][0] .= $badge_html;
610 break;
611 }
612 }
613 }
614 }
615
616 /**
617 * Summary of add_payments_badge
618 *
619 * @since 2.0.0
620 * @return void
621 */
622 public function add_payments_badge() {
623 if ( ! Helper::current_user_can() ) {
624 return;
625 }
626
627 global $submenu;
628 if ( isset( $submenu['sureforms_menu'] ) ) {
629 foreach ( $submenu['sureforms_menu'] as $index => $sub_item ) {
630 if ( isset( $sub_item[2] ) && SRFM_PAYMENTS === $sub_item[2] ) {
631 ob_start();
632 ?>
633 <span style="color: #4ADE80;font-size: 9px;font-weight: 600;"><?php echo esc_html__( 'New', 'sureforms' ); ?></span>
634 <?php
635 $new_badge_html = ob_get_clean();
636 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Adding notifications for submenu item.
637 $submenu['sureforms_menu'][ $index ][0] .= $new_badge_html;
638 break;
639 }
640 }
641 }
642 }
643
644 /**
645 * Mark the user's visit to the entries page.
646 *
647 * @since 1.7.3
648 * @return void
649 */
650 public function mark_entries_page_visit() {
651 if ( Helper::current_user_can() ) {
652 $srfm_options = get_option( 'srfm_options', [] );
653 $srfm_options['entries_last_visited'] = time();
654 \SRFM\Inc\Helper::update_admin_settings_option( 'srfm_options', $srfm_options );
655 }
656 }
657
658 /**
659 * Adds a settings link to the plugin action links on the plugins page.
660 *
661 * @param array $links An array of plugin action links.
662 * @param string $file The plugin file path.
663 * @return array The updated array of plugin action links.
664 * @since 0.0.1
665 */
666 public function add_settings_link( $links, $file ) {
667 if ( 'sureforms/sureforms.php' === $file ) {
668 ob_start();
669 ?>
670 <a href="<?php echo esc_url( admin_url( 'admin.php?page=sureforms_form_settings&tab=general-settings' ) ); ?>">
671 <?php echo esc_html__( 'Settings', 'sureforms' ); ?>
672 </a>
673 <?php
674 $settings_link_html = ob_get_clean();
675 $plugin_links = apply_filters(
676 'sureforms_plugin_action_links',
677 [
678 'sureforms_settings' => $settings_link_html,
679 ]
680 );
681 $links = array_merge( $plugin_links, $links );
682 }
683 return $links;
684 }
685
686 /**
687 * Sureforms block editor styles.
688 *
689 * @since 0.0.1
690 */
691 public function enqueue_styles() {
692 $current_screen = get_current_screen();
693 global $wp_version;
694
695 $file_prefix = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? '' : '.min';
696 $dir_name = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? 'unminified' : 'minified';
697
698 $css_uri = SRFM_URL . 'assets/css/' . $dir_name . '/';
699 $vendor_css_uri = SRFM_URL . 'assets/css/minified/deps/';
700
701 /* RTL */
702 if ( is_rtl() ) {
703 $file_prefix .= '-rtl';
704 }
705
706 // Enqueue editor styles for post and page.
707 if ( SRFM_FORMS_POST_TYPE === $current_screen->post_type ) {
708 wp_enqueue_style( SRFM_SLUG . '-editor', $css_uri . 'backend/editor' . $file_prefix . '.css', [], SRFM_VER );
709 wp_enqueue_style( SRFM_SLUG . '-backend-blocks', $css_uri . 'blocks/default/backend' . $file_prefix . '.css', [], SRFM_VER );
710 wp_enqueue_style( SRFM_SLUG . '-intl', $vendor_css_uri . 'intl/intlTelInput-backend.min.css', [], SRFM_VER );
711 wp_enqueue_style( SRFM_SLUG . '-common', $css_uri . 'common' . $file_prefix . '.css', [], SRFM_VER );
712 wp_enqueue_style( SRFM_SLUG . '-reactQuill', $vendor_css_uri . 'quill/quill.snow.css', [], SRFM_VER );
713 wp_enqueue_style( SRFM_SLUG . '-single-form-modal', $css_uri . 'single-form-setting' . $file_prefix . '.css', [], SRFM_VER );
714
715 // if version is equal to or lower than 6.6.2 then add compatibility css.
716 if ( version_compare( $wp_version, '6.6.2', '<=' ) ) {
717 $srfm_inline_css = '.srfm-settings-modal .srfm-setting-modal-container .components-toggle-control .components-base-control__help{
718 margin-left: 4em;
719 }';
720 wp_add_inline_style( SRFM_SLUG . '-single-form-modal', $srfm_inline_css );
721 }
722 }
723
724 wp_enqueue_style( SRFM_SLUG . '-form-selector', $css_uri . 'srfm-form-selector' . $file_prefix . '.css', [], SRFM_VER );
725 wp_enqueue_style( SRFM_SLUG . '-common-editor', SRFM_URL . 'assets/build/common-editor.css', [], SRFM_VER, 'all' );
726 }
727
728 /**
729 * Get Breadcrumbs for current page.
730 *
731 * @since 0.0.1
732 * @return array Breadcrumbs Array.
733 */
734 public function get_breadcrumbs_for_current_page() {
735 global $post, $pagenow;
736 $breadcrumbs = [];
737
738 if ( 'admin.php' === $pagenow && isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- We don't need nonce verification here.
739 $page_title = get_admin_page_title();
740 $breadcrumbs[] = [
741 'title' => $page_title,
742 'link' => '',
743 ];
744 } elseif ( $post && in_array( $pagenow, [ 'post.php', 'post-new.php', 'edit.php' ], true ) ) {
745 $post_type_obj = get_post_type_object( get_post_type() );
746 if ( $post_type_obj ) {
747 $post_type_plural = $post_type_obj->labels->name;
748 $breadcrumbs[] = [
749 'title' => $post_type_plural,
750 'link' => admin_url( 'edit.php?post_type=' . $post_type_obj->name ),
751 ];
752
753 if ( 'edit.php' === $pagenow && ! isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- We don't need nonce verification here.
754 $breadcrumbs[ count( $breadcrumbs ) - 1 ]['link'] = '';
755 } else {
756 $breadcrumbs[] = [
757 /* Translators: Post Title. */
758 'title' => sprintf( __( 'Edit %1$s', 'sureforms' ), get_the_title() ),
759 'link' => get_edit_post_link( $post->ID ),
760 ];
761 }
762 }
763 } else {
764 $current_screen = get_current_screen();
765 if ( $current_screen && 'sureforms_form' === $current_screen->post_type ) {
766 $breadcrumbs[] = [
767 'title' => 'Forms',
768 'link' => '',
769 ];
770 } else {
771 $breadcrumbs[] = [
772 'title' => '',
773 'link' => '',
774 ];
775 }
776 }
777
778 return $breadcrumbs;
779 }
780
781 /**
782 * Enqueue Admin Scripts.
783 *
784 * @return void
785 * @since 0.0.1
786 */
787 public function enqueue_scripts() {
788 $current_screen = get_current_screen();
789 global $wp_version;
790
791 $file_prefix = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? '' : '.min';
792 $dir_name = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? 'unminified' : 'minified';
793 $css_uri = SRFM_URL . 'assets/css/' . $dir_name . '/';
794 $is_rtl = is_rtl();
795 $rtl = $is_rtl ? '-rtl' : '';
796
797 /**
798 * List of the handles in which we need to add translation compatibility.
799 */
800 $script_translations_handlers = [];
801 $onboarding_instance = Onboarding::get_instance();
802
803 $localization_data = [
804 'site_url' => get_site_url(),
805 'breadcrumbs' => $this->get_breadcrumbs_for_current_page(),
806 'sureforms_dashboard_url' => admin_url( '/admin.php?page=sureforms_menu' ),
807 'plugin_version' => SRFM_VER,
808 'global_settings_nonce' => Helper::current_user_can() ? wp_create_nonce( 'wp_rest' ) : '',
809 'is_pro_active' => Helper::has_pro(),
810 'is_first_form_created' => self::is_first_form_created(),
811 'check_three_days_threshold' => self::check_first_form_creation_threshold(),
812 'check_eight_days_threshold' => self::check_first_form_creation_threshold( 8 ),
813 'pro_plugin_version' => Helper::has_pro() ? SRFM_PRO_VER : '',
814 'pro_plugin_name' => Helper::has_pro() && defined( 'SRFM_PRO_PRODUCT' ) ? SRFM_PRO_PRODUCT : 'SureForms Pro',
815 'sureforms_pricing_page' => Helper::get_sureforms_website_url( 'pricing' ),
816 'field_spacing_vars' => Helper::get_css_vars(),
817 'is_ver_lower_than_6_7' => version_compare( $wp_version, '6.6.2', '<=' ),
818 'integrations' => Helper::sureforms_get_integration(),
819 'rotating_plugin_banner' => Helper::get_rotating_plugin_banner(),
820 'ajax_url' => admin_url( 'admin-ajax.php' ),
821 'sf_plugin_manager_nonce' => wp_create_nonce( 'sf_plugin_manager_nonce' ),
822 'plugin_installer_nonce' => wp_create_nonce( 'updates' ),
823 'plugin_activating_text' => __( 'Activating...', 'sureforms' ),
824 'plugin_activated_text' => __( 'Activated', 'sureforms' ),
825 'plugin_activate_text' => __( 'Activate', 'sureforms' ),
826 'plugin_installing_text' => __( 'Installing...', 'sureforms' ),
827 'plugin_installed_text' => __( 'Installed', 'sureforms' ),
828 'is_rtl' => $is_rtl,
829 'onboarding_completed' => method_exists( $onboarding_instance, 'get_onboarding_status' ) ? $onboarding_instance->get_onboarding_status() : false,
830 'onboarding_redirect' => isset( $_GET['srfm-activation-redirect'] ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce is not required for the activation redirection.
831 'pointer_nonce' => wp_create_nonce( 'sureforms_pointer_action' ),
832 'general_settings_url' => admin_url( '/options-general.php' ),
833 'payments' => apply_filters(
834 'srfm_admin_localize_payments_data',
835 [
836 'stripe_connected' => Stripe_Helper::is_stripe_connected(),
837 'stripe_mode' => Stripe_Helper::get_stripe_mode(),
838 'stripe_connect_url' => Stripe_Helper::get_stripe_settings_url(),
839 'currencies_data' => Payment_Helper::get_all_currencies_data(),
840 'zero_decimal_currencies' => Payment_Helper::get_zero_decimal_currencies(),
841 'webhook_url' => Stripe_Helper::get_webhook_url(),
842 'webhook_test_connected' => Stripe_Helper::is_webhook_configured( 'test', true ),
843 'webhook_live_connected' => Stripe_Helper::is_webhook_configured( 'live', true ),
844 'is_transaction_present' => Stripe_Helper::is_transaction_present(),
845 'payment_currency' => Payment_Helper::get_currency(),
846 ]
847 ),
848 ];
849
850 $is_screen_sureforms_menu = Helper::validate_request_context( 'sureforms_menu', 'page' );
851 $is_screen_add_new_form = Helper::validate_request_context( 'add-new-form', 'page' );
852 $is_screen_sureforms_forms = Helper::validate_request_context( 'sureforms_forms', 'page' );
853 $is_screen_sureforms_form_settings = Helper::validate_request_context( 'sureforms_form_settings', 'page' );
854 $is_screen_sureforms_payments = Helper::validate_request_context( 'sureforms_payments', 'page' );
855 $is_screen_sureforms_entries = Helper::validate_request_context( SRFM_ENTRIES, 'page' );
856 $is_post_type_sureforms_form = SRFM_FORMS_POST_TYPE === $current_screen->post_type;
857
858 /**
859 * Check if the current screen is the SureForms Menu and AI Auth Email is present then we will add user type as registered.
860 * Compatibility with existing UI code that checks for this condition.
861 */
862 if ( $is_screen_sureforms_menu ) {
863 // If email is stored send the user type as registered else non-registered.
864 $localization_data['srfm_ai_details'] = [
865 'type' => ! empty( get_option( 'srfm_ai_auth_user_email' ) ) ? 'registered' : 'non-registered',
866 ];
867 }
868
869 if ( $is_screen_sureforms_menu || $is_post_type_sureforms_form || $is_screen_add_new_form || $is_screen_sureforms_forms || $is_screen_sureforms_form_settings || $is_screen_sureforms_entries || $is_screen_sureforms_payments ) {
870 $asset_handle = '-dashboard';
871
872 wp_enqueue_style( SRFM_SLUG . $asset_handle . '-font', 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap', [], SRFM_VER );
873
874 $script_asset_path = SRFM_DIR . 'assets/build/dashboard.asset.php';
875 $script_info = file_exists( $script_asset_path )
876 ? include $script_asset_path
877 : [
878 'dependencies' => [],
879 'version' => SRFM_VER,
880 ];
881 wp_enqueue_script( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/dashboard.js', $script_info['dependencies'], SRFM_VER, true );
882
883 wp_localize_script( SRFM_SLUG . $asset_handle, 'scIcons', [ 'path' => SRFM_URL . 'assets/build/icon-assets' ] );
884
885 $script_translations_handlers[] = SRFM_SLUG . $asset_handle;
886
887 if ( class_exists( 'SRFM_PRO\Admin\Licensing' ) ) {
888 $license_active = \SRFM_PRO\Admin\Licensing::is_license_active();
889 $localization_data['is_license_active'] = $license_active;
890
891 // Updating current licensing status.
892 $srfm_pro_license_status = get_option( 'srfm_pro_license_status', '' );
893 $current_license_status = $license_active ? 'licensed' : 'unlicensed';
894 if ( $current_license_status !== $srfm_pro_license_status ) {
895 update_option( 'srfm_pro_license_status', $current_license_status );
896 }
897 }
898
899 $localization_data['security_settings_url'] = admin_url( '/admin.php?page=sureforms_form_settings&tab=security-settings&subpage=recaptcha' );
900 $localization_data['integration_settings_url'] = admin_url( '/admin.php?page=sureforms_form_settings&tab=integration-settings' );
901 wp_localize_script(
902 SRFM_SLUG . $asset_handle,
903 SRFM_SLUG . '_admin',
904 apply_filters(
905 SRFM_SLUG . '_admin_filter',
906 $localization_data
907 )
908 );
909 wp_enqueue_style( SRFM_SLUG . '-dashboard', SRFM_URL . 'assets/build/dashboard.css', [], SRFM_VER, 'all' );
910 }
911
912 if ( $is_screen_sureforms_form_settings || $is_screen_sureforms_forms ) {
913 wp_enqueue_style( SRFM_SLUG . '-settings', $css_uri . 'backend/settings' . $file_prefix . $rtl . '.css', [], SRFM_VER );
914 }
915
916 // Enqueue styles for the entries page.
917 if ( $is_screen_sureforms_entries ) {
918 $asset_handle = '-entries';
919 wp_enqueue_script( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/entries.js', $script_info['dependencies'], SRFM_VER, true );
920
921 $script_translations_handlers[] = SRFM_SLUG . $asset_handle;
922 }
923
924 // Enqueue scripts for the forms page.
925 if ( $is_screen_sureforms_forms ) {
926 $asset_handle = '-forms';
927
928 $script_asset_path = SRFM_DIR . 'assets/build/forms.asset.php';
929 $script_info = file_exists( $script_asset_path )
930 ? include $script_asset_path
931 : [
932 'dependencies' => [],
933 'version' => SRFM_VER,
934 ];
935
936 wp_enqueue_script( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/forms.js', $script_info['dependencies'], SRFM_VER, true );
937 wp_localize_script(
938 SRFM_SLUG . $asset_handle,
939 SRFM_SLUG . '_admin',
940 $localization_data
941 );
942 wp_enqueue_style( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/forms.css', [], SRFM_VER, 'all' );
943
944 $script_translations_handlers[] = SRFM_SLUG . $asset_handle;
945 }
946
947 // Enqueue scripts for the SureMail promotional page.
948 $is_screen_sureforms_smtp = Helper::validate_request_context( 'sureforms_smtp', 'page' );
949 if ( $is_screen_sureforms_smtp ) {
950 $asset_handle = 'suremail';
951
952 $script_asset_path = SRFM_DIR . 'assets/build/' . $asset_handle . '.asset.php';
953 $script_info = file_exists( $script_asset_path )
954 ? include $script_asset_path
955 : [
956 'dependencies' => [],
957 'version' => SRFM_VER,
958 ];
959
960 wp_enqueue_script( SRFM_SLUG . '-suremail', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
961 wp_enqueue_style( SRFM_SLUG . '-suremail', SRFM_URL . 'assets/build/suremail.css', [], SRFM_VER, 'all' );
962
963 // Localize script for SureMail page.
964 $suremail_localization_data = [
965 'ajax_url' => admin_url( 'admin-ajax.php' ),
966 'admin_url' => admin_url(),
967 'suremail_url' => 'https://sureforms.com/suremail/',
968 'plugin_installer_nonce' => wp_create_nonce( 'updates' ),
969 'sfPluginManagerNonce' => wp_create_nonce( 'sf_plugin_manager_nonce' ),
970 'suremail_status' => file_exists( WP_PLUGIN_DIR . '/suremails/suremails.php' )
971 ? ( is_plugin_active( 'suremails/suremails.php' ) ? 'active' : 'installed' )
972 : 'not_installed',
973 ];
974
975 wp_localize_script(
976 SRFM_SLUG . '-suremail',
977 SRFM_SLUG . '_admin',
978 apply_filters(
979 SRFM_SLUG . '_suremail_admin_filter',
980 $suremail_localization_data
981 )
982 );
983
984 $script_translations_handlers[] = SRFM_SLUG . '-suremail';
985 }
986
987 // Admin Submenu Styles.
988 wp_enqueue_style( SRFM_SLUG . '-admin', $css_uri . 'backend/admin' . $file_prefix . $rtl . '.css', [], SRFM_VER );
989
990 if ( $is_screen_sureforms_form_settings ) {
991 $asset_handle = 'settings';
992
993 $script_asset_path = SRFM_DIR . 'assets/build/' . $asset_handle . '.asset.php';
994 $script_info = file_exists( $script_asset_path )
995 ? include $script_asset_path
996 : [
997 'dependencies' => [],
998 'version' => SRFM_VER,
999 ];
1000
1001 wp_enqueue_script( SRFM_SLUG . '-settings', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
1002 wp_localize_script(
1003 SRFM_SLUG . '-settings',
1004 SRFM_SLUG . '_admin',
1005 $localization_data
1006 );
1007
1008 $script_translations_handlers[] = SRFM_SLUG . '-settings';
1009 }
1010
1011 if ( $is_screen_add_new_form ) {
1012 wp_enqueue_style( SRFM_SLUG . '-template-picker', $css_uri . 'template-picker' . $file_prefix . $rtl . '.css', [], SRFM_VER );
1013
1014 $sureforms_admin = 'templatePicker';
1015
1016 $script_asset_path = SRFM_DIR . 'assets/build/' . $sureforms_admin . '.asset.php';
1017 $script_info = file_exists( $script_asset_path )
1018 ? include $script_asset_path
1019 : [
1020 'dependencies' => [],
1021 'version' => SRFM_VER,
1022 ];
1023 wp_enqueue_script( SRFM_SLUG . '-template-picker', SRFM_URL . 'assets/build/' . $sureforms_admin . '.js', $script_info['dependencies'], SRFM_VER, true );
1024
1025 wp_localize_script(
1026 SRFM_SLUG . '-template-picker',
1027 SRFM_SLUG . '_admin',
1028 [
1029 'site_url' => get_site_url(),
1030 'plugin_url' => SRFM_URL,
1031 'admin_url' => admin_url( 'admin.php' ),
1032 'new_template_picker_base_url' => admin_url( 'post-new.php?post_type=sureforms_form' ),
1033 'capability' => Helper::current_user_can(),
1034 'template_picker_nonce' => Helper::current_user_can() ? wp_create_nonce( 'wp_rest' ) : '',
1035 'is_pro_active' => Helper::has_pro(),
1036 'srfm_ai_usage_details' => AI_Helper::get_current_usage_details(),
1037 'is_pro_license_active' => AI_Helper::is_pro_license_active(),
1038 'srfm_ai_auth_user_email' => get_option( 'srfm_ai_auth_user_email' ),
1039 'pricing_page_url' => Helper::get_sureforms_website_url( 'pricing' ),
1040 'licensing_nonce' => wp_create_nonce( 'srfm_pro_licensing_nonce' ),
1041 ]
1042 );
1043
1044 $script_translations_handlers[] = SRFM_SLUG . '-template-picker';
1045 }
1046 // Quick action sidebar.
1047 $default_allowed_quick_sidebar_blocks = apply_filters(
1048 'srfm_quick_sidebar_allowed_blocks',
1049 [
1050 'srfm/input',
1051 'srfm/email',
1052 'srfm/textarea',
1053 'srfm/checkbox',
1054 'srfm/number',
1055 'srfm/inline-button',
1056 'srfm/advanced-heading',
1057 'srfm/payment',
1058 ]
1059 );
1060 if ( ! is_array( $default_allowed_quick_sidebar_blocks ) ) {
1061 $default_allowed_quick_sidebar_blocks = [];
1062 }
1063
1064 $srfm_enable_quick_action_sidebar = get_option( 'srfm_enable_quick_action_sidebar' );
1065 if ( ! $srfm_enable_quick_action_sidebar ) {
1066 $srfm_enable_quick_action_sidebar = 'disabled';
1067 }
1068 $quick_sidebar_allowed_blocks = get_option( 'srfm_quick_sidebar_allowed_blocks' );
1069 $quick_sidebar_allowed_blocks = ! empty( $quick_sidebar_allowed_blocks ) && is_array( $quick_sidebar_allowed_blocks ) ? $quick_sidebar_allowed_blocks : $default_allowed_quick_sidebar_blocks;
1070 $srfm_ajax_nonce = wp_create_nonce( 'srfm_ajax_nonce' );
1071
1072 if ( Helper::is_sureforms_admin_page() ) {
1073 wp_enqueue_script( SRFM_SLUG . '-quick-action-siderbar', SRFM_URL . 'assets/build/quickActionSidebar.js', [], SRFM_VER, true );
1074 wp_localize_script(
1075 SRFM_SLUG . '-quick-action-siderbar',
1076 SRFM_SLUG . '_quick_sidebar_blocks',
1077 [
1078 'allowed_blocks' => $quick_sidebar_allowed_blocks,
1079 'srfm_enable_quick_action_sidebar' => $srfm_enable_quick_action_sidebar,
1080 'srfm_ajax_nonce' => $srfm_ajax_nonce,
1081 'srfm_ajax_url' => admin_url( 'admin-ajax.php' ),
1082 ]
1083 );
1084
1085 $script_translations_handlers[] = SRFM_SLUG . '-quick-action-siderbar';
1086 }
1087
1088 /**
1089 * Enqueuing SureTriggers Integration script.
1090 * This script loads suretriggers iframe in Intergations tab.
1091 */
1092 if ( $is_post_type_sureforms_form ) {
1093 wp_enqueue_script( SRFM_SLUG . '-suretriggers-integration', SRFM_SURETRIGGERS_INTEGRATION_BASE_URL . 'js/v2/embed.js', [], SRFM_VER, true );
1094 }
1095
1096 // Check $script_translations_handlers is not empty before calling the function.
1097 if ( ! empty( $script_translations_handlers ) ) {
1098 // Remove duplicates values from the array.
1099 $script_translations_handlers = array_unique( $script_translations_handlers );
1100
1101 foreach ( $script_translations_handlers as $script_handle ) {
1102 Helper::register_script_translations( $script_handle );
1103 }
1104 }
1105 }
1106
1107 /**
1108 * Form Template Picker Admin Body Classes
1109 * WordPress sometimes translates class names in the admin body tag, which can result in
1110 * incorrect or missing class names when rendering the admin pages. This function ensures
1111 * that essential class names are manually added to the body tag to maintain proper functionality.
1112 *
1113 * @since 0.0.1
1114 * @param string $classes Space separated class string.
1115 */
1116 public function admin_template_picker_body_class( $classes = '' ) {
1117 // Define an associative array of class names and their corresponding conditions.
1118 // Each condition checks whether a specific request context matches.
1119 $srfm_classes = [
1120 'sureforms_page_sureforms_entries' => Helper::validate_request_context( SRFM_ENTRIES, 'page' ),
1121 'sureforms_page_sureforms_form_settings' => Helper::validate_request_context( 'sureforms_form_settings', 'page' ),
1122 'srfm-template-picker' => Helper::validate_request_context( 'add-new-form', 'page' ),
1123 ];
1124
1125 $add_srfm_classes = '';
1126
1127 // Loop through the defined classes and conditions.
1128 foreach ( $srfm_classes as $class => $condition ) {
1129 // Check if the condition evaluates to true.
1130 if ( $condition ) {
1131 // Append the class to the existing classes string, followed by a space.
1132 $add_srfm_classes .= empty( $add_srfm_classes ) ? $class : ' ' . $class;
1133 }
1134 }
1135
1136 // Append the new classes to the existing classes string.
1137 if ( ! empty( $add_srfm_classes ) ) {
1138 $classes .= ' ' . $add_srfm_classes;
1139 }
1140
1141 // Return the updated list of classes.
1142 return $classes;
1143 }
1144
1145 /**
1146 * Disable spectra's quick action bar in sureforms CPT.
1147 *
1148 * @param string $status current status of the quick action bar.
1149 * @since 0.0.2
1150 * @return string
1151 */
1152 public function restrict_spectra_quick_action_bar( $status ) {
1153 $screen = get_current_screen();
1154 if ( 'disabled' !== $status && isset( $screen->id ) && 'sureforms_form' === $screen->id ) {
1155 $status = 'disabled';
1156 }
1157
1158 return $status;
1159 }
1160
1161 /**
1162 * Admin Notice Callback if sureforms pro is out of date.
1163 *
1164 * Hooked - admin_notices
1165 *
1166 * @return void
1167 * @since 1.0.4
1168 */
1169 public function srfm_pro_version_compatibility() {
1170 if ( ! Helper::has_pro() ) {
1171 return;
1172 }
1173
1174 if ( empty( get_current_screen() ) ) {
1175 return;
1176 }
1177
1178 if ( ! Helper::current_user_can() ) {
1179 return;
1180 }
1181
1182 $srfm_pro_license_status = get_option( 'srfm_pro_license_status', '' );
1183 /**
1184 * If the license status is not set then get the license status and update the option accordingly.
1185 * This will be executed only once. Subsequently, the option status is updated by the licensing class on license activation or deactivation.
1186 */
1187 if ( empty( $srfm_pro_license_status ) && class_exists( 'SRFM_PRO\Admin\Licensing' ) ) {
1188 $srfm_pro_license_status = \SRFM_PRO\Admin\Licensing::is_license_active() ? 'licensed' : 'unlicensed';
1189 update_option( 'srfm_pro_license_status', $srfm_pro_license_status );
1190 }
1191
1192 $pro_plugin_name = defined( 'SRFM_PRO_PRODUCT' ) ? SRFM_PRO_PRODUCT : 'SureForms Pro';
1193 $message = '';
1194 $url = admin_url( 'admin.php?page=sureforms_form_settings&tab=account-settings' );
1195 if ( 'unlicensed' === $srfm_pro_license_status ) {
1196 ob_start();
1197 ?>
1198 <p>
1199 <?php
1200 printf(
1201 // translators: %1$s: Opening anchor tag with URL, %2$s: Closing anchor tag, %3$s: SureForms Pro Plugin Name.
1202 esc_html__( 'Please %1$sactivate%2$s your copy of %3$s to get new features, access support, receive update notifications, and more.', 'sureforms' ),
1203 '<a href="' . esc_url( $url ) . '">',
1204 '</a>',
1205 '<i>' . esc_html( $pro_plugin_name ) . '</i>'
1206 );
1207 ?>
1208 </p>
1209 <?php
1210 $message = ob_get_clean();
1211 }
1212
1213 if ( ! version_compare( SRFM_PRO_VER, SRFM_PRO_RECOMMENDED_VER, '>=' ) ) {
1214 ob_start();
1215 ?>
1216 <p>
1217 <?php
1218 printf(
1219 // translators: %1$s: SureForms version, %2$s: SureForms Pro Plugin Name, %3$s: SureForms Pro Version, %4$s: Anchor tag open, %5$s: Closing anchor tag.
1220 esc_html__( 'SureForms %1$s requires minimum %2$s %3$s to work properly. Please update to the latest version from %4$shere%5$s.', 'sureforms' ),
1221 esc_html( SRFM_VER ),
1222 esc_html( $pro_plugin_name ),
1223 esc_html( SRFM_PRO_RECOMMENDED_VER ),
1224 '<a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">',
1225 '</a>'
1226 );
1227 ?>
1228 </p>
1229 <?php
1230 $message .= ob_get_clean();
1231 }
1232
1233 if ( ! empty( $message ) ) {
1234 // Phpcs ignore comment is required as $message variable is already escaped.
1235 ?>
1236 <div class="notice notice-warning"><?php echo wp_kses_post( $message ); ?></div>
1237 <?php
1238 }
1239 }
1240
1241 /**
1242 * Disables the capabilities for WPForms to avoid conflicts when enqueueing
1243 * scripts and styles for WPForms.
1244 *
1245 * This function is intended to prevent any potential conflicts that may arise
1246 * when WPForms scripts and styles are enqueued. By disabling certain capabilities,
1247 * it ensures that WPForms does not interfere with other functionalities.
1248 *
1249 * @param bool $user_can A boolean indicating whether the user has the capability.
1250 * @return bool Returns true if the capabilities are successfully disabled, false otherwise.
1251 * @since 1.4.2
1252 */
1253 public function disable_wpforms_capabilities( $user_can ) {
1254 // Note: Nonce verification is intentionally omitted here as no database operations are performed.
1255 // The values of the $_REQUEST variables are strictly validated, ensuring security without the need for nonce verification.
1256
1257 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1258 $post_id = ! empty( $_REQUEST['post'] ) && ! empty( $_REQUEST['action'] ) ? absint( $_REQUEST['post'] ) : 0;
1259
1260 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1261 $post_type = $post_id ? get_post_type( $post_id ) : sanitize_text_field( wp_unslash( $_REQUEST['post_type'] ?? '' ) );
1262 return SRFM_FORMS_POST_TYPE === $post_type ? false : $user_can;
1263 }
1264
1265 /**
1266 * Enqueueus the admin pointer script and styles.
1267 *
1268 * @return void
1269 * @since 1.8.0
1270 */
1271 public function enqueue_admin_pointer() {
1272 if ( ! $this->is_admin_pointer_visible() ) {
1273 return;
1274 }
1275 wp_enqueue_style( 'wp-pointer' );
1276 wp_enqueue_script( 'wp-pointer' );
1277 wp_enqueue_script(
1278 'sureforms-admin-pointer',
1279 plugins_url( 'admin/assets/js/sureforms-pointer.js', SRFM_FILE ),
1280 [ 'wp-pointer', 'jquery' ],
1281 SRFM_VER,
1282 true
1283 );
1284 wp_localize_script(
1285 'sureforms-admin-pointer',
1286 'sureformsPointerData',
1287 [
1288 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1289 'pointer_nonce' => wp_create_nonce( 'sureforms_pointer_action' ),
1290 ]
1291 );
1292 }
1293
1294 /**
1295 * Ajax handler for pointer popup visibility.
1296 *
1297 * @return void
1298 * @since 1.8.0
1299 */
1300 public function pointer_should_show() {
1301 // Security: Check user capability.
1302 if ( ! Helper::current_user_can() ) {
1303 wp_send_json_error( [ 'message' => __( 'Unauthorized user.', 'sureforms' ) ], 403 );
1304 }
1305 // Security: Nonce check.
1306 if ( empty( $_POST['pointer_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pointer_nonce'] ) ), 'sureforms_pointer_action' ) ) {
1307 wp_send_json_error( [ 'message' => __( 'Invalid nonce.', 'sureforms' ) ], 403 );
1308 }
1309
1310 $content_markup = sprintf(
1311 /* translators: 1: opening span, 2: opening strong (inline), 3: closing strong, 4: closing span, 5: opening strong (block), 6: closing strong */
1312 __( '%1$sGet started by %2$sbuilding your first form%3$s.%4$s%5$sExperience the power of our intuitive AI Form Builder%6$s', 'sureforms' ),
1313 '<span>',
1314 '<strong>',
1315 '</strong>',
1316 '</span><br/>',
1317 '<strong style="font-size:1.1em;">',
1318 '</strong>'
1319 );
1320 wp_send_json(
1321 [
1322 'show' => true,
1323 'title' => esc_html( __( 'SureForms is waiting for you!', 'sureforms' ) ),
1324 'content' => wp_kses_post( $content_markup ),
1325 'button_text' => esc_html( __( 'Build My First Form', 'sureforms' ) ),
1326 'dismiss' => esc_html( __( 'Dismiss', 'sureforms' ) ),
1327 'button_url' => admin_url( 'admin.php?page=add-new-form' ),
1328 ]
1329 );
1330 }
1331
1332 /**
1333 * Ajax callback for pointer popup dismissed action.
1334 *
1335 * @return void
1336 * @since 1.8.0
1337 */
1338 public function pointer_dismissed() {
1339 // Security: Check user capability.
1340 if ( ! Helper::current_user_can() ) {
1341 wp_send_json_error( [ 'message' => __( 'Unauthorized user.', 'sureforms' ) ], 403 );
1342 }
1343 // Security: Nonce check.
1344 if ( empty( $_POST['pointer_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pointer_nonce'] ) ), 'sureforms_pointer_action' ) ) {
1345 wp_send_json_error( [ 'message' => __( 'Invalid nonce.', 'sureforms' ) ], 403 );
1346 }
1347 // Use Helper to update srfm_options key.
1348 Helper::update_srfm_option( 'pointer_popup_dismissed', time() );
1349
1350 wp_send_json_success();
1351 }
1352
1353 /**
1354 * Ajax pointer accepted CTA callback.
1355 *
1356 * @return void
1357 * @since 1.8.0
1358 */
1359 public function pointer_accepted_cta() {
1360 // Security: Check user capability.
1361 if ( ! Helper::current_user_can() ) {
1362 wp_send_json_error( [ 'message' => __( 'Unauthorized user.', 'sureforms' ) ], 403 );
1363 }
1364 // Security: Nonce check.
1365 if ( empty( $_POST['pointer_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pointer_nonce'] ) ), 'sureforms_pointer_action' ) ) {
1366 wp_send_json_error( [ 'message' => __( 'Invalid nonce.', 'sureforms' ) ], 403 );
1367 }
1368 // Use Helper to update srfm_options key.
1369 Helper::update_srfm_option( 'pointer_popup_accepted', time() );
1370
1371 wp_send_json_success();
1372 }
1373
1374 /**
1375 * Maybe register the dashboard widget based on entries.
1376 *
1377 * @return void
1378 * @since 1.9.1
1379 */
1380 public function maybe_register_dashboard_widget() {
1381
1382 // Only for users with manage_options capability.
1383 if ( ! Helper::current_user_can() ) {
1384 return;
1385 }
1386
1387 // Quick check if there are any entries in the last 7 days.
1388 $seven_days_ago = strtotime( '-7 days' );
1389 $total_entries = Entries::get_entries_count_after( $seven_days_ago );
1390
1391 // Only add the dashboard setup hook if there are entries.
1392 if ( $total_entries > 0 ) {
1393 // Get forms with entries (limit 4 for dashboard widget).
1394 $this->dashboard_widget_data = Helper::get_forms_with_entry_counts( $seven_days_ago, 4 );
1395
1396 // Only show dashboard widget if there are forms with entries.
1397 if ( ! empty( $this->dashboard_widget_data ) ) {
1398 add_action( 'wp_dashboard_setup', [ $this, 'register_dashboard_widget' ] );
1399 }
1400 }
1401 }
1402
1403 /**
1404 * Register the dashboard widget.
1405 *
1406 * @return void
1407 * @since 1.9.1
1408 */
1409 public function register_dashboard_widget() {
1410 // Add the widget with high priority to position it at the top.
1411 wp_add_dashboard_widget(
1412 'sureforms_recent_entries',
1413 __( 'SureForms', 'sureforms' ),
1414 [ $this, 'render_dashboard_widget' ],
1415 null,
1416 null,
1417 'normal',
1418 'high'
1419 );
1420 }
1421
1422 /**
1423 * Render the dashboard widget content.
1424 *
1425 * @return void
1426 * @since 1.9.1
1427 */
1428 public function render_dashboard_widget() {
1429 // Use the pre-fetched data to avoid duplicate queries.
1430 $entries_data = $this->dashboard_widget_data;
1431
1432 // Display the widget content.
1433 ?>
1434 <div class="srfm-dashboard-widget">
1435 <div class="srfm-widget-header">
1436 <h3 class="srfm-widget-title">
1437 <?php esc_html_e( 'Recent Entries', 'sureforms' ); ?>
1438 <span class="srfm-widget-subtitle"><?php esc_html_e( '( Last 7 days )', 'sureforms' ); ?></span>
1439 </h3>
1440 <a href="<?php echo esc_url( admin_url( 'admin.php?page=sureforms_entries' ) ); ?>" class="srfm-widget-view-link">
1441 <?php esc_html_e( 'View', 'sureforms' ); ?>
1442 </a>
1443 </div>
1444
1445 <div class="srfm-table-wrapper">
1446 <table class="srfm-entries-table">
1447 <thead>
1448 <tr>
1449 <th><?php esc_html_e( 'Form Name', 'sureforms' ); ?></th>
1450 <th><?php esc_html_e( 'Entries', 'sureforms' ); ?></th>
1451 </tr>
1452 </thead>
1453 <tbody>
1454 <?php foreach ( $entries_data as $form_data ) { ?>
1455 <tr>
1456 <td class="form-name"><?php echo esc_html( $form_data['title'] ); ?></td>
1457 <td class="entry-count"><?php echo esc_html( $form_data['count'] ); ?></td>
1458 </tr>
1459 <?php } ?>
1460 </tbody>
1461 </table>
1462 </div>
1463
1464 <?php
1465 // Render footer if applicable.
1466 $this->render_dashboard_widget_footer( $entries_data );
1467 ?>
1468 </div>
1469 <?php
1470 }
1471
1472 /**
1473 * Get random premium feature text.
1474 *
1475 * @return string Random feature text.
1476 * @since 1.9.1
1477 */
1478 private function get_random_premium_feature_text() {
1479 $features = [
1480 __( 'Use Conditional Logic to show only what matters', 'sureforms' ),
1481 __( 'Split your form into steps to keep it easy', 'sureforms' ),
1482 __( 'Let people upload files directly to your form', 'sureforms' ),
1483 __( 'Turn responses into downloadable PDFs automatically', 'sureforms' ),
1484 __( 'Let users sign with a simple signature field', 'sureforms' ),
1485 __( 'Connect your form to other tools using webhooks', 'sureforms' ),
1486 __( 'Use Conversational Forms for a chat-like experience', 'sureforms' ),
1487 __( 'Let users register or log in through your form', 'sureforms' ),
1488 __( 'Build forms that create WordPress user accounts', 'sureforms' ),
1489 __( 'Add calculations to auto-total scores or prices', 'sureforms' ),
1490 ];
1491
1492 // Get a random feature.
1493 $random_key = array_rand( $features );
1494 return $features[ $random_key ];
1495 }
1496
1497 /**
1498 * Render the dashboard widget footer for upsell.
1499 *
1500 * @param array $entries_data The entries data array.
1501 * @return void
1502 * @since 1.9.1
1503 */
1504 private function render_dashboard_widget_footer( $entries_data ) {
1505 // Only show footer if Pro is not active.
1506 if ( Helper::has_pro() ) {
1507 return;
1508 }
1509
1510 // Count total entries in last 7 days.
1511 $total_entries = 0;
1512 foreach ( $entries_data as $form_data ) {
1513 $total_entries += $form_data['count'];
1514 }
1515
1516 // Count total published forms.
1517 $published_forms_count = wp_count_posts( SRFM_FORMS_POST_TYPE )->publish;
1518
1519 // Show footer only if 3+ entries received OR 3+ forms published.
1520 if ( $total_entries >= 3 || $published_forms_count >= 3 ) {
1521 ?>
1522 <div class="srfm-widget-footer">
1523 <div class="srfm-upgrade-content">
1524 <svg class="srfm-logo-icon" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
1525 <rect width="20" height="20" fill="#D54407"/>
1526 <path d="M5.7139 4.2854H14.2853V7.1425H7.1424L5.7139 8.5711V7.1425V4.2854Z" fill="white"/>
1527 <path d="M5.7139 4.2854H14.2853V7.1425H7.1424L5.7139 8.5711V7.1425V4.2854Z" fill="white"/>
1528 <path d="M5.7148 8.5713H12.8577V11.4284H7.1434L5.7148 12.857V11.4284V8.5713Z" fill="white"/>
1529 <path d="M5.7148 8.5713H12.8577V11.4284H7.1434L5.7148 12.857V11.4284V8.5713Z" fill="white"/>
1530 <path d="M5.7148 12.8569H10.0006V15.7141H5.7148V12.8569Z" fill="white"/>
1531 <path d="M5.7148 12.8569H10.0006V15.7141H5.7148V12.8569Z" fill="white"/>
1532 </svg>
1533 <span><?php echo esc_html( $this->get_random_premium_feature_text() ); ?></span>
1534 </div>
1535 <?php
1536 $upgrade_url = add_query_arg(
1537 [
1538 'utm_medium' => 'dashboard-widget',
1539 ],
1540 Helper::get_sureforms_website_url( 'pricing' )
1541 );
1542 ?>
1543 <a href="<?php echo esc_url( $upgrade_url ); ?>" class="srfm-upgrade-link" target="_blank">
1544 <?php esc_html_e( 'Upgrade', 'sureforms' ); ?>
1545 </a>
1546 </div>
1547 <?php
1548 }
1549 }
1550
1551 /**
1552 * Determine if the admin pointer should be visible on this page.
1553 *
1554 * @since 1.8.0
1555 * @return bool
1556 */
1557 private function is_admin_pointer_visible() {
1558 global $pagenow;
1559 $allowed_pages = [ 'index.php', 'options-general.php' ];
1560
1561 // Do not show if pointer dismissed, accepted, or more than 1 form exists.
1562 if (
1563 ! empty( Helper::get_srfm_option( 'pointer_popup_dismissed' ) )
1564 || ! empty( Helper::get_srfm_option( 'pointer_popup_accepted' ) )
1565 || (int) ( wp_count_posts( SRFM_FORMS_POST_TYPE )->publish ?? 0 ) > 1
1566 ) {
1567 return false;
1568 }
1569
1570 if ( in_array( $pagenow, $allowed_pages, true ) ) {
1571 return true;
1572 }
1573
1574 return false;
1575 }
1576
1577 }
1578