PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 0.0.7
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v0.0.7
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
← All changes | admin/admin.php +131 -1642 2.8.20.0.7 View file →
@@ -6,24 +6,14 @@
6 6 */
7 7
8 8 namespace SRFM\Admin;
9 9
10 -use Astra_Notices;
11 -use SRFM\Inc\AI_Form_Builder\AI_Helper;
12 -use SRFM\Inc\Database\Tables\Entries;
10 +use SRFM\Inc\Traits\Get_Instance;
13 11 use SRFM\Inc\Helper;
14 -use SRFM\Inc\Onboarding;
15 -use SRFM\Inc\Payments\Payment_Helper;
16 -use SRFM\Inc\Payments\Stripe\Stripe_Helper;
17 -use SRFM\Inc\Traits\Get_Instance;
18 12
19 13 if ( ! defined( 'ABSPATH' ) ) {
20 14 exit; // Exit if accessed directly.
21 15 }
22 -
23 -if ( ! class_exists( 'BSF_Admin_Notices' ) ) {
24 - require_once SRFM_DIR . 'inc/lib/astra-notices/class-bsf-admin-notices.php';
25 -}
26 16 /**
27 17 * Admin handler class.
28 18 *
29 19 * @since 0.0.1
@@ -28,42 +18,12 @@
28 18 *
29 19 * @since 0.0.1
30 20 */
31 21 class Admin {
22 +
32 23 use Get_Instance;
33 24
34 25 /**
35 - * Minimum number of forms or entries required to show the rating notice.
36 - *
37 - * @since 2.5.2
38 - */
39 - public const RATING_NOTICE_THRESHOLD = 3;
40 -
41 - /**
42 - * Dashboard widget entries data.
43 - *
44 - * @var array
45 - * @since 1.9.1
46 - */
47 - private $dashboard_widget_data = [];
48 -
49 - /**
50 - * Cached result for whether the rating notice should display.
51 - *
52 - * @var bool|null
53 - * @since 2.5.2
54 - */
55 - private $should_show_rating = null;
56 -
57 - /**
58 - * SureForms Page Default permission.
59 - *
60 - * @var string
61 - * @since 1.12.2
62 - */
63 - private static $sureforms_page_default_capability = 'manage_options';
64 -
65 - /**
66 26 * Class constructor.
67 27 *
68 28 * @return void
69 29 * @since 0.0.1
@@ -71,221 +31,19 @@
71 31 public function __construct() {
72 32 add_action( 'admin_menu', [ $this, 'add_menu_page' ], 9 );
73 33 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
74 34 add_action( 'admin_menu', [ $this, 'settings_page' ] );
75 - add_action( 'admin_menu', [ $this, 'add_learn_page' ] );
76 35 add_action( 'admin_menu', [ $this, 'add_new_form' ] );
77 - add_action( 'admin_menu', [ $this, 'add_suremail_page' ] );
78 - if ( ! Helper::has_pro() ) {
79 - add_action( 'admin_menu', [ $this, 'add_quiz_page' ] );
80 - add_action( 'admin_menu', [ $this, 'add_survey_reports_page' ] );
81 - add_action( 'admin_menu', [ $this, 'add_upgrade_to_pro' ] );
82 - add_action( 'admin_footer', [ $this, 'add_upgrade_to_pro_target_attr' ] );
83 - }
84 -
85 36 add_filter( 'plugin_action_links', [ $this, 'add_settings_link' ], 10, 2 );
86 37 add_action( 'enqueue_block_assets', [ $this, 'enqueue_styles' ] );
87 38 add_action( 'admin_head', [ $this, 'enqueue_header_styles' ] );
88 - add_filter( 'admin_body_class', [ $this, 'admin_template_picker_body_class' ] );
39 + add_action( 'admin_body_class', [ $this, 'admin_template_picker_body_class' ] );
89 40
90 41 // this action is used to restrict Spectra's quick action bar on SureForms CPTS.
91 42 add_action( 'uag_enable_quick_action_sidebar', [ $this, 'restrict_spectra_quick_action_bar' ] );
92 -
93 - add_action( 'current_screen', [ $this, 'enable_gutenberg_for_sureforms' ], 100 );
94 - // Register notices early for React pages (before admin_enqueue_scripts).
95 - add_action( 'admin_init', [ $this, 'register_pro_compatibility_notices' ], 5 );
96 - // Display notices on traditional WordPress admin pages.
97 - add_action( 'admin_notices', [ $this, 'srfm_pro_version_compatibility' ] );
98 -
99 - // Enfold theme compatibility to enable block editor for SureForms post type.
100 - add_filter( 'avf_use_block_editor_for_post', [ $this, 'enable_block_editor_in_enfold_theme' ] );
101 -
102 - // Add action links to the plugin page.
103 - add_filter( 'plugin_action_links_' . SRFM_BASENAME, [ $this, 'add_action_links' ] );
104 - // Check if admin notification is enabled and add entries badge.
105 - $general_options = get_option( 'srfm_general_settings_options', [] );
106 - $admin_notification_on = isset( $general_options['srfm_admin_notification'] ) ? (bool) $general_options['srfm_admin_notification'] : true;
107 -
108 - if ( $admin_notification_on ) {
109 - add_action( 'admin_menu', [ $this, 'maybe_add_entries_badge' ], 99 );
110 - }
111 -
112 - add_filter( 'wpforms_current_user_can', [ $this, 'disable_wpforms_capabilities' ], 10, 3 );
113 -
114 - add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_pointer' ] );
115 - // Ajax callbacks for wp-pointer functionality.
116 - add_action( 'wp_ajax_should_show_pointer', [ $this, 'pointer_should_show' ] );
117 - add_action( 'wp_ajax_sureforms_dismiss_pointer', [ $this, 'pointer_dismissed' ] );
118 - add_action( 'wp_ajax_sureforms_accept_cta', [ $this, 'pointer_accepted_cta' ] );
119 - add_action( 'wp_ajax_srfm_notice_response', [ $this, 'handle_notice_response' ] );
120 -
121 - // Register dashboard widget only if there are recent entries.
122 - add_action( 'admin_init', [ $this, 'maybe_register_dashboard_widget' ] );
123 -
124 - // Save first form creation time stamp.
125 - add_action( 'admin_init', [ $this, 'save_first_form_creation_time_stamp' ] );
126 - add_action( 'admin_notices', [ $this, 'display_srfm_rating_notice' ] );
127 - add_action( 'admin_notices', [ $this, 'display_srfm_getting_started_notice' ] );
128 43 }
129 44
130 45 /**
131 - * Get the first form creation time stamp.
132 - *
133 - * @since 1.10.1
134 - * @return int|false
135 - */
136 - public static function get_first_form_creation_time_stamp() {
137 - return Helper::get_srfm_option( 'first_form_created_at', false );
138 - }
139 -
140 - /**
141 - * Check if the first form has been created.
142 - *
143 - * @since 1.10.1
144 - * @return bool
145 - */
146 - public static function is_first_form_created() {
147 - // Convert the first form creation time stamp to a boolean. If it exists, it will return true, otherwise false.
148 - $first_form_creation_time_stamp = self::get_first_form_creation_time_stamp();
149 -
150 - // If the first form creation time stamp is not set, return false.
151 - if ( ! $first_form_creation_time_stamp ) {
152 - return false; // No forms created yet.
153 - }
154 -
155 - // Check if the first form creation time stamp is a valid integer and greater than zero.
156 - return is_int( $first_form_creation_time_stamp ) && $first_form_creation_time_stamp > 0;
157 - }
158 -
159 - /**
160 - * Check and save the first form creation time stamp.
161 - * If not already saved.
162 - *
163 - * @since 1.10.1
164 - * @return void
165 - */
166 - public static function save_first_form_creation_time_stamp() {
167 - if ( ! Helper::current_user_can() || self::is_first_form_created() || ! defined( 'SRFM_FORMS_POST_TYPE' ) || ! post_type_exists( SRFM_FORMS_POST_TYPE ) ) {
168 - return;
169 - }
170 -
171 - // Get the first form creation time from the database that is published.
172 - $query = new \WP_Query(
173 - [
174 - 'post_type' => SRFM_FORMS_POST_TYPE,
175 - 'posts_per_page' => 1,
176 - 'orderby' => 'date',
177 - 'order' => 'ASC',
178 - 'fields' => 'ids',
179 - 'post_status' => 'publish',
180 - ]
181 - );
182 -
183 - if ( ! empty( $query->posts ) && isset( $query->posts[0] ) ) {
184 - // Get the first post from the query result.
185 - $post_id = $query->posts[0];
186 - // Get the post creation time in GMT.
187 - $creation_time = get_post_field( 'post_date_gmt', $post_id );
188 - // Convert the creation time to a timestamp.
189 - $timestamp = strtotime( $creation_time );
190 -
191 - if ( ! $timestamp ) {
192 - return;
193 - }
194 -
195 - Helper::update_srfm_option( 'first_form_created_at', $timestamp );
196 - }
197 - }
198 -
199 - /**
200 - * Check if n days have passed since the first form creation.
201 - * This is used to determine if the dynamic nudges should be shown.
202 - *
203 - * @param int $days Number of days to check.
204 - * @since 1.10.1
205 - * @return bool
206 - */
207 - public static function check_first_form_creation_threshold( $days = 3 ) {
208 - $first_form_creation_time_stamp = self::get_first_form_creation_time_stamp();
209 -
210 - if ( ! $first_form_creation_time_stamp ) {
211 - return false; // No forms created yet.
212 - }
213 -
214 - /**
215 - * Calculate the number of days since the first form was created.
216 - */
217 - $days_from_creation = ( strtotime( current_time( 'mysql' ) ) - $first_form_creation_time_stamp ) / DAY_IN_SECONDS;
218 -
219 - // Return a boolean indicating if the number of days since creation is greater than the specified days.
220 - return $days_from_creation > $days;
221 - }
222 -
223 - /**
224 - * Show action on plugin page.
225 - *
226 - * @param array $links links.
227 - * @return array
228 - * @since 1.4.2
229 - */
230 - public function add_action_links( $links ) {
231 - if ( ! Helper::has_pro() ) {
232 - // Display upsell link if SureForms Pro is not installed.
233 - $upsell_link = add_query_arg(
234 - [
235 - 'utm_medium' => 'plugin-list',
236 - ],
237 - Helper::get_sureforms_website_url( 'pricing' )
238 - );
239 -
240 - ob_start();
241 - ?>
242 - <a href="<?php echo esc_url( $upsell_link ); ?>" target="_blank" rel="noreferrer" class="sureforms-plugins-go-pro">
243 - <?php echo esc_html__( 'Get SureForms Pro', 'sureforms' ); ?>
244 - </a>
245 - <?php
246 - $links[] = trim( ob_get_clean() );
247 - }
248 -
249 - return $links;
250 - }
251 -
252 - /**
253 - * Enable block editor in Enfold theme for SureForms post type.
254 - *
255 - * @param bool $use_block_editor Whether to use block editor.
256 - * @since 1.3.1
257 - */
258 - public function enable_block_editor_in_enfold_theme( $use_block_editor ) {
259 - // if SureForms form post type then return true.
260 - if ( SRFM_FORMS_POST_TYPE === get_current_screen()->post_type ) {
261 - return true;
262 - }
263 - return $use_block_editor;
264 - }
265 -
266 - /**
267 - * Enable Gutenberg for SureForms associated post types.
268 - *
269 - * @since 0.0.10
270 - */
271 - public function enable_gutenberg_for_sureforms() {
272 - /**
273 - * Check if the classic editor is enabled from Classic Editor plugin settings or Divi settings.
274 - */
275 - if ( 'block' === get_option( 'classic-editor-replace' ) || 'on' === get_option( 'et_enable_classic_editor' ) ) {
276 - return;
277 - }
278 -
279 - $srfm_post_types = apply_filters( 'srfm_enable_gutenberg_post_types', [ SRFM_FORMS_POST_TYPE ] );
280 -
281 - if ( in_array( get_current_screen()->post_type, $srfm_post_types, true ) ) {
282 - add_filter( 'use_block_editor_for_post_type', '__return_true', 110 );
283 - add_filter( 'gutenberg_can_edit_post_type', '__return_true', 110 );
284 - }
285 - }
286 -
287 - /**
288 46 * Sureforms editor header styles.
289 47 *
290 48 * @since 0.0.1
291 49 */
@@ -312,18 +70,22 @@
312 70 * @return void
313 71 * @since 0.0.1
314 72 */
315 73 public function add_menu_page() {
316 - $menu_slug = 'sureforms_menu';
74 + if ( ! current_user_can( 'manage_options' ) ) {
75 + return;
76 + }
317 77
78 + $capability = 'manage_options';
79 + $menu_slug = 'sureforms_menu';
80 +
318 81 $logo = file_get_contents( plugin_dir_path( SRFM_FILE ) . 'images/icon.svg' );
319 82 add_menu_page(
320 83 __( 'SureForms', 'sureforms' ),
321 84 __( 'SureForms', 'sureforms' ),
322 - self::$sureforms_page_default_capability,
85 + 'edit_others_posts',
323 86 $menu_slug,
324 - static function () {
325 - },
87 + function () {},
326 88 'data:image/svg+xml;base64,' . base64_encode( $logo ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
327 89 30
328 90 );
329 91
@@ -331,9 +93,9 @@
331 93 add_submenu_page(
332 94 $menu_slug,
333 95 __( 'Dashboard', 'sureforms' ),
334 96 __( 'Dashboard', 'sureforms' ),
335 - self::$sureforms_page_default_capability,
97 + $capability,
336 98 $menu_slug,
337 99 [ $this, 'render_dashboard' ]
338 100 );
339 101 }
@@ -349,9 +111,9 @@
349 111 add_submenu_page(
350 112 'sureforms_menu',
351 113 __( 'Settings', 'sureforms' ),
352 114 __( 'Settings', 'sureforms' ),
353 - self::$sureforms_page_default_capability,
115 + 'edit_others_posts',
354 116 'sureforms_form_settings',
355 117 $callback
356 118 );
357 119
@@ -364,162 +126,8 @@
364 126 }
365 127 }
366 128
367 129 /**
368 - * Open to Upgrade to Pro submenu link in new tab.
369 - *
370 - * @return void
371 - * @since 1.6.1
372 - */
373 - public function add_upgrade_to_pro_target_attr() {
374 - ?>
375 - <script type="text/javascript">
376 - document.addEventListener('DOMContentLoaded', function () {
377 - // Upgrade link handler.
378 - // IMPORTANT: If this URL changes, also update it in the `add_upgrade_to_pro` function.
379 - const upgradeLink = document.querySelector('a[href*="https://sureforms.com/upgrade"]');
380 - if (upgradeLink) {
381 - upgradeLink.addEventListener('click', e => {
382 - e.preventDefault();
383 - window.open(upgradeLink.href, '_blank');
384 - });
385 - }
386 - });
387 - </script>
388 - <?php
389 - }
390 -
391 - /**
392 - * Add Upgrade to pro menu item.
393 - *
394 - * @return void
395 - * @since 1.6.1
396 - */
397 - public function add_upgrade_to_pro() {
398 - // The url used here is used as a selector for css to style the upgrade to pro submenu.
399 - // If you are changing this url, please make sure to update the css as well.
400 - $upgrade_url = add_query_arg(
401 - [
402 - 'utm_medium' => 'submenu_link_upgrade',
403 - ],
404 - Helper::get_sureforms_website_url( 'upgrade' )
405 - );
406 -
407 - add_submenu_page(
408 - 'sureforms_menu',
409 - __( 'Upgrade', 'sureforms' ),
410 - __( 'Upgrade', 'sureforms' ),
411 - self::$sureforms_page_default_capability,
412 - $upgrade_url
413 - );
414 - }
415 -
416 - /**
417 - * Add Quiz empty state submenu page for free users.
418 - *
419 - * @return void
420 - * @since 2.7.0
421 - */
422 - public function add_quiz_page() {
423 - add_submenu_page(
424 - 'sureforms_menu',
425 - __( 'Quiz Entries', 'sureforms' ),
426 - __( 'Quizzes', 'sureforms' ) .
427 - ' <span style="color:#4ADE80;font-size:9px;font-weight:600;">' .
428 - esc_html__( 'New', 'sureforms' ) .
429 - '</span>',
430 - self::$sureforms_page_default_capability,
431 - 'sureforms_quiz_entries',
432 - [ $this, 'render_quiz_empty_state' ],
433 - 5
434 - );
435 - }
436 -
437 - /**
438 - * Quiz empty state page callback.
439 - *
440 - * @return void
441 - * @since 2.7.0
442 - */
443 - public function render_quiz_empty_state() {
444 - ?>
445 - <div id="srfm-quiz-entries-root" class="srfm-admin-wrapper"></div>
446 - <?php
447 - }
448 -
449 - /**
450 - * Add Survey Reports promotional submenu page for free users.
451 - *
452 - * @return void
453 - * @since 2.8.0
454 - */
455 - public function add_survey_reports_page() {
456 - add_submenu_page(
457 - 'sureforms_menu',
458 - __( 'Survey Reports', 'sureforms' ),
459 - __( 'Survey Reports', 'sureforms' ) .
460 - ' <span style="color:#4ADE80;font-size:9px;font-weight:600;">' .
461 - esc_html__( 'New', 'sureforms' ) .
462 - '</span>',
463 - self::$sureforms_page_default_capability,
464 - 'sureforms_survey_reports',
465 - [ $this, 'render_survey_empty_state' ],
466 - 6
467 - );
468 - }
469 -
470 - /**
471 - * Survey empty state page callback.
472 - *
473 - * @return void
474 - * @since 2.8.0
475 - */
476 - public function render_survey_empty_state() {
477 - ?>
478 - <div id="srfm-survey-empty-state-root" class="srfm-admin-wrapper"></div>
479 - <?php
480 - }
481 -
482 - /**
483 - * Add SMTP promotional submenu page.
484 - *
485 - * @return void
486 - * @since 1.7.1
487 - */
488 - public function add_suremail_page() {
489 - add_submenu_page(
490 - 'sureforms_menu',
491 - __( 'SMTP', 'sureforms' ),
492 - __( 'SMTP', 'sureforms' ),
493 - self::$sureforms_page_default_capability,
494 - 'sureforms_smtp',
495 - [ $this, 'suremail_page_callback' ]
496 - );
497 -
498 - // Get the current submenu page.
499 - $submenu_page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['page'] does not provide nonce.
500 -
501 - // Check if SureMail is installed and active.
502 - if ( 'sureforms_smtp' === $submenu_page && file_exists( WP_PLUGIN_DIR . '/suremails/suremails.php' ) && is_plugin_active( 'suremails/suremails.php' ) ) {
503 - // Plugin is installed and active - redirect to SureMail dashboard.
504 - wp_safe_redirect( admin_url( 'options-general.php?page=suremail#/dashboard' ) );
505 - exit;
506 - }
507 - }
508 -
509 - /**
510 - * SMTP promotional page callback.
511 - *
512 - * @return void
513 - * @since 1.7.1
514 - */
515 - public function suremail_page_callback() {
516 - ?>
517 - <div id="srfm-suremail-container" class="srfm-admin-wrapper"></div>
518 - <?php
519 - }
520 -
521 - /**
522 130 * Render Admin Dashboard.
523 131 *
524 132 * @return void
525 133 * @since 0.0.1
@@ -524,11 +132,9 @@
524 132 * @return void
525 133 * @since 0.0.1
526 134 */
527 135 public function render_dashboard() {
528 - ?>
529 - <div id="srfm-dashboard-container" class="srfm-admin-wrapper"></div>
530 - <?php
136 + echo '<div id="srfm-dashboard-container"></div>';
531 137 }
532 138
533 139 /**
534 140 * Settings page callback.
@@ -536,43 +142,12 @@
536 142 * @return void
537 143 * @since 0.0.1
538 144 */
539 145 public function settings_page_callback() {
540 - ?>
541 - <div id="srfm-settings-container" class="srfm-admin-wrapper"></div>
542 - <?php
146 + echo '<div id="srfm-settings-container"></div>';
543 147 }
544 148
545 149 /**
546 - * Add Learn submenu page.
547 - *
548 - * @return void
549 - * @since 2.5.2
550 - */
551 - public function add_learn_page() {
552 - add_submenu_page(
553 - 'sureforms_menu',
554 - __( 'Learn', 'sureforms' ),
555 - __( 'Learn', 'sureforms' ),
556 - self::$sureforms_page_default_capability,
557 - 'sureforms_learn',
558 - [ $this, 'render_learn' ]
559 - );
560 - }
561 -
562 - /**
563 - * Learn page callback.
564 - *
565 - * @return void
566 - * @since 2.5.2
567 - */
568 - public function render_learn() {
569 - ?>
570 - <div id="srfm-learn-root" class="srfm-admin-wrapper"></div>
571 - <?php
572 - }
573 -
574 - /**
575 150 * Add new form menu item.
576 151 *
577 152 * @return void
578 153 * @since 0.0.1
@@ -579,62 +154,18 @@
579 154 */
580 155 public function add_new_form() {
581 156 add_submenu_page(
582 157 'sureforms_menu',
583 - __( 'Forms', 'sureforms' ),
584 - __( 'Forms', 'sureforms' ),
585 - self::$sureforms_page_default_capability,
586 - 'sureforms_forms',
587 - [ $this, 'render_forms' ],
588 - 1
589 - );
590 - add_submenu_page(
591 - 'sureforms_menu',
592 158 __( 'New Form', 'sureforms' ),
593 159 __( 'New Form', 'sureforms' ),
594 - self::$sureforms_page_default_capability,
160 + 'edit_others_posts',
595 161 'add-new-form',
596 162 [ $this, 'add_new_form_callback' ],
597 163 2
598 164 );
599 - $entries_hook = add_submenu_page(
600 - 'sureforms_menu',
601 - __( 'Entries', 'sureforms' ),
602 - __( 'Entries', 'sureforms' ),
603 - self::$sureforms_page_default_capability,
604 - SRFM_ENTRIES,
605 - [ $this, 'render_entries' ],
606 - 3
607 - );
608 -
609 - add_submenu_page(
610 - 'sureforms_menu',
611 - __( 'Payments', 'sureforms' ),
612 - __( 'Payments', 'sureforms' ),
613 - self::$sureforms_page_default_capability,
614 - SRFM_PAYMENTS,
615 - [ $this, 'render_payments' ],
616 - 4
617 - );
618 -
619 - if ( $entries_hook ) {
620 - add_action( 'load-' . $entries_hook, [ $this, 'mark_entries_page_visit' ] );
621 - }
622 165 }
623 166
624 167 /**
625 - * Payments page callback.
626 - *
627 - * @return void
628 - * @since 2.0.0
629 - */
630 - public function render_payments() {
631 - ?>
632 - <div id="srfm-payments-react-container" class="srfm-admin-wrapper"></div>
633 - <?php
634 - }
635 -
636 - /**
637 168 * Add new form mentu item callback.
638 169 *
639 170 * @return void
640 171 * @since 0.0.1
@@ -639,109 +170,12 @@
639 170 * @return void
640 171 * @since 0.0.1
641 172 */
642 173 public function add_new_form_callback() {
643 - ?>
644 - <div id="srfm-add-new-form-container" class="srfm-admin-wrapper"></div>
645 - <?php
174 + echo '<div id="srfm-add-new-form-container"></div>';
646 175 }
647 176
648 177 /**
649 - * Forms page callback.
650 - *
651 - * @return void
652 - * @since 2.0.0
653 - */
654 - public function render_forms() {
655 - ?>
656 - <div id="srfm-forms-root" class="srfm-admin-wrapper"></div>
657 - <?php
658 - }
659 -
660 - /**
661 - * Entries page callback.
662 - *
663 - * @since 0.0.13
664 - * @since 2.0.0 - Updated the entries UI and the function definition.
665 - * @return void
666 - */
667 - public function render_entries() {
668 - echo '<div id="srfm-entries-root"></div>';
669 - }
670 -
671 - /**
672 - * Add notification badge to SureForms menu when there are new entries.
673 - *
674 - * @since 1.7.3
675 - * @return void
676 - */
677 - public function maybe_add_entries_badge() {
678 - if ( ! Helper::current_user_can() ) {
679 - return;
680 - }
681 -
682 - // If currently viewing the entries listing page, mark it as visited and skip the badge.
683 - if ( isset( $_GET['page'] ) && SRFM_ENTRIES === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Only checking the page slug.
684 - $this->mark_entries_page_visit();
685 - return;
686 - }
687 -
688 - $srfm_options = get_option( 'srfm_options', [] );
689 - $last_visit = isset( $srfm_options['entries_last_visited'] ) ? absint( $srfm_options['entries_last_visited'] ) : 0;
690 - $new_entries = Entries::get_entries_count_after( $last_visit );
691 -
692 - if ( $new_entries <= 0 ) {
693 - return;
694 - }
695 -
696 - global $menu;
697 - foreach ( $menu as $index => $item ) {
698 - if ( isset( $item[2] ) && 'sureforms_menu' === $item[2] ) {
699 - ob_start();
700 - ?>
701 - <span class="srfm-update-dot"></span>
702 - <?php
703 - $dot_html = ob_get_clean();
704 - // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Adding notifications for menu item.
705 - $menu[ $index ][0] .= $dot_html;
706 - break;
707 - }
708 - }
709 -
710 - global $submenu;
711 - if ( isset( $submenu['sureforms_menu'] ) ) {
712 - foreach ( $submenu['sureforms_menu'] as $index => $sub_item ) {
713 - if ( isset( $sub_item[2] ) && SRFM_ENTRIES === $sub_item[2] ) {
714 - ob_start();
715 - ?>
716 - <span class="update-plugins count-<?php echo absint( $new_entries ); ?>">
717 - <span class="plugin-count"><?php echo absint( $new_entries ); ?></span>
718 - </span>
719 - <?php
720 - $badge_html = ob_get_clean();
721 - // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Adding notifications for submenu item.
722 - $submenu['sureforms_menu'][ $index ][0] .= $badge_html;
723 - break;
724 - }
725 - }
726 - }
727 - }
728 -
729 - /**
730 - * Mark the user's visit to the entries page.
731 - *
732 - * @since 1.7.3
733 - * @return void
734 - */
735 - public function mark_entries_page_visit() {
736 - if ( Helper::current_user_can() ) {
737 - $srfm_options = get_option( 'srfm_options', [] );
738 - $srfm_options['entries_last_visited'] = time();
739 - \SRFM\Inc\Helper::update_admin_settings_option( 'srfm_options', $srfm_options );
740 - }
741 - }
742 -
743 - /**
744 178 * Adds a settings link to the plugin action links on the plugins page.
745 179 *
746 180 * @param array $links An array of plugin action links.
747 181 * @param string $file The plugin file path.
@@ -749,22 +183,15 @@
749 183 * @since 0.0.1
750 184 */
751 185 public function add_settings_link( $links, $file ) {
752 186 if ( 'sureforms/sureforms.php' === $file ) {
753 - ob_start();
754 - ?>
755 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=sureforms_form_settings&tab=general-settings' ) ); ?>">
756 - <?php echo esc_html__( 'Settings', 'sureforms' ); ?>
757 - </a>
758 - <?php
759 - $settings_link_html = ob_get_clean();
760 - $plugin_links = apply_filters(
187 + $plugin_links = apply_filters(
761 188 'sureforms_plugin_action_links',
762 189 [
763 - 'sureforms_settings' => $settings_link_html,
190 + 'sureforms_settings' => '<a href="' . esc_url( admin_url( 'admin.php?page=sureforms_form_settings&tab=general-settings' ) ) . '">' . esc_html__( 'Settings', 'sureforms' ) . '</a>',
764 191 ]
765 192 );
766 - $links = array_merge( $plugin_links, $links );
193 + $links = array_merge( $plugin_links, $links );
767 194 }
768 195 return $links;
769 196 }
770 197
@@ -774,9 +201,8 @@
774 201 * @since 0.0.1
775 202 */
776 203 public function enqueue_styles() {
777 204 $current_screen = get_current_screen();
778 - global $wp_version;
779 205
780 206 $file_prefix = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? '' : '.min';
781 207 $dir_name = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? 'unminified' : 'minified';
782 208
@@ -795,16 +221,8 @@
795 221 wp_enqueue_style( SRFM_SLUG . '-intl', $vendor_css_uri . 'intl/intlTelInput-backend.min.css', [], SRFM_VER );
796 222 wp_enqueue_style( SRFM_SLUG . '-common', $css_uri . 'common' . $file_prefix . '.css', [], SRFM_VER );
797 223 wp_enqueue_style( SRFM_SLUG . '-reactQuill', $vendor_css_uri . 'quill/quill.snow.css', [], SRFM_VER );
798 224 wp_enqueue_style( SRFM_SLUG . '-single-form-modal', $css_uri . 'single-form-setting' . $file_prefix . '.css', [], SRFM_VER );
799 -
800 - // if version is equal to or lower than 6.6.2 then add compatibility css.
801 - if ( version_compare( $wp_version, '6.6.2', '<=' ) ) {
802 - $srfm_inline_css = '.srfm-settings-modal .srfm-setting-modal-container .components-toggle-control .components-base-control__help{
803 - margin-left: 4em;
804 - }';
805 - wp_add_inline_style( SRFM_SLUG . '-single-form-modal', $srfm_inline_css );
806 - }
807 225 }
808 226
809 227 wp_enqueue_style( SRFM_SLUG . '-form-selector', $css_uri . 'srfm-form-selector' . $file_prefix . '.css', [], SRFM_VER );
810 228 wp_enqueue_style( SRFM_SLUG . '-common-editor', SRFM_URL . 'assets/build/common-editor.css', [], SRFM_VER, 'all' );
@@ -819,9 +237,9 @@
819 237 public function get_breadcrumbs_for_current_page() {
820 238 global $post, $pagenow;
821 239 $breadcrumbs = [];
822 240
823 - if ( 'admin.php' === $pagenow && isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- We don't need nonce verification here.
241 + if ( 'admin.php' === $pagenow && isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
824 242 $page_title = get_admin_page_title();
825 243 $breadcrumbs[] = [
826 244 'title' => $page_title,
827 245 'link' => '',
@@ -834,9 +252,9 @@
834 252 'title' => $post_type_plural,
835 253 'link' => admin_url( 'edit.php?post_type=' . $post_type_obj->name ),
836 254 ];
837 255
838 - if ( 'edit.php' === $pagenow && ! isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- We don't need nonce verification here.
256 + if ( 'edit.php' === $pagenow && ! isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
839 257 $breadcrumbs[ count( $breadcrumbs ) - 1 ]['link'] = '';
840 258 } else {
841 259 $breadcrumbs[] = [
842 260 /* Translators: Post Title. */
@@ -851,8 +269,13 @@
851 269 $breadcrumbs[] = [
852 270 'title' => 'Forms',
853 271 'link' => '',
854 272 ];
273 + } elseif ( $current_screen && 'sureforms_entry' === $current_screen->post_type ) {
274 + $breadcrumbs[] = [
275 + 'title' => 'Entries',
276 + 'link' => '',
277 + ];
855 278 } else {
856 279 $breadcrumbs[] = [
857 280 'title' => '',
858 281 'link' => '',
@@ -862,8 +285,9 @@
862 285
863 286 return $breadcrumbs;
864 287 }
865 288
289 +
866 290 /**
867 291 * Enqueue Admin Scripts.
868 292 *
869 293 * @return void
@@ -870,131 +294,39 @@
870 294 * @since 0.0.1
871 295 */
872 296 public function enqueue_scripts() {
873 297 $current_screen = get_current_screen();
874 - global $wp_version;
875 298
876 - $file_prefix = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? '' : '.min';
877 - $dir_name = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? 'unminified' : 'minified';
878 - $css_uri = SRFM_URL . 'assets/css/' . $dir_name . '/';
879 - $is_rtl = is_rtl();
880 - $rtl = $is_rtl ? '-rtl' : '';
299 + $file_prefix = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? '' : '.min';
300 + $dir_name = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? 'unminified' : 'minified';
301 + $js_uri = SRFM_URL . 'assets/js/' . $dir_name . '/';
302 + $css_uri = SRFM_URL . 'assets/css/' . $dir_name . '/';
881 303
882 - /**
883 - * List of the handles in which we need to add translation compatibility.
884 - */
885 - $script_translations_handlers = [];
886 - $onboarding_instance = Onboarding::get_instance();
887 - $current_user = wp_get_current_user();
304 + /* RTL */
305 + if ( is_rtl() ) {
306 + $file_prefix .= '-rtl';
307 + }
888 308
889 309 $localization_data = [
890 - 'site_url' => get_site_url(),
891 - 'current_user_login' => $current_user->user_login ?? '',
892 - 'website_lead_details' => [
893 - 'first_name' => $current_user->first_name ?? '',
894 - 'last_name' => $current_user->last_name ?? '',
895 - 'email' => $current_user->user_email ?? '',
896 - ],
897 - 'breadcrumbs' => $this->get_breadcrumbs_for_current_page(),
898 - 'sureforms_dashboard_url' => admin_url( '/admin.php?page=sureforms_menu' ),
899 - 'plugin_version' => SRFM_VER,
900 - 'global_settings_nonce' => Helper::current_user_can() ? wp_create_nonce( 'wp_rest' ) : '',
901 - 'is_pro_active' => Helper::has_pro(),
902 - 'is_first_form_created' => self::is_first_form_created(),
903 - 'check_three_days_threshold' => self::check_first_form_creation_threshold(),
904 - 'check_eight_days_threshold' => self::check_first_form_creation_threshold( 8 ),
905 - 'pro_plugin_version' => Helper::has_pro() ? SRFM_PRO_VER : '',
906 - 'pro_plugin_name' => Helper::has_pro() && defined( 'SRFM_PRO_PRODUCT' ) ? SRFM_PRO_PRODUCT : 'SureForms Pro',
907 - 'sureforms_pricing_page' => Helper::get_sureforms_website_url( 'pricing' ),
908 - 'field_spacing_vars' => Helper::get_css_vars(),
909 - 'is_ver_lower_than_6_7' => version_compare( $wp_version, '6.6.2', '<=' ),
910 - 'integrations' => Helper::sureforms_get_integration(),
911 - 'rotating_plugin_banner' => Helper::get_rotating_plugin_banner(),
912 - 'ajax_url' => admin_url( 'admin-ajax.php' ),
913 - 'sf_plugin_manager_nonce' => wp_create_nonce( 'sf_plugin_manager_nonce' ),
914 - 'plugin_installer_nonce' => wp_create_nonce( 'updates' ),
915 - 'plugin_activating_text' => __( 'Activating...', 'sureforms' ),
916 - 'plugin_activated_text' => __( 'Activated', 'sureforms' ),
917 - 'plugin_activate_text' => __( 'Activate', 'sureforms' ),
918 - 'plugin_installing_text' => __( 'Installing...', 'sureforms' ),
919 - 'plugin_installed_text' => __( 'Installed', 'sureforms' ),
920 - 'privacy_policy_url' => Helper::get_sureforms_website_url( 'privacy-policy/' ),
921 - 'is_rtl' => $is_rtl,
922 - 'onboarding_completed' => method_exists( $onboarding_instance, 'get_onboarding_status' ) ? $onboarding_instance->get_onboarding_status() : false,
923 - 'onboarding_redirect' => isset( $_GET['srfm-activation-redirect'] ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce is not required for the activation redirection.
924 - 'pointer_nonce' => wp_create_nonce( 'sureforms_pointer_action' ),
925 - 'general_settings_url' => admin_url( '/options-general.php' ),
926 - 'additional_header_nav_items' => [],
927 - 'payments' => apply_filters(
928 - 'srfm_admin_localize_payments_data',
929 - [
930 - 'stripe_connected' => Stripe_Helper::is_stripe_connected(),
931 - 'stripe_mode' => Stripe_Helper::get_stripe_mode(),
932 - 'stripe_connect_url' => Stripe_Helper::get_stripe_settings_url(),
933 - 'currencies_data' => Payment_Helper::get_all_currencies_data(),
934 - 'zero_decimal_currencies' => Payment_Helper::get_zero_decimal_currencies(),
935 - 'webhook_url' => Stripe_Helper::get_webhook_url(),
936 - 'webhook_test_connected' => Stripe_Helper::is_webhook_configured( 'test', true ),
937 - 'webhook_live_connected' => Stripe_Helper::is_webhook_configured( 'live', true ),
938 - 'is_transaction_present' => Stripe_Helper::is_transaction_present(),
939 - 'payment_currency' => Payment_Helper::get_currency(),
940 - 'currency_sign_position' => Payment_Helper::get_currency_sign_position(),
941 - ]
942 - ),
943 - 'mcp_adapter_status' => file_exists( WP_PLUGIN_DIR . '/mcp-adapter/mcp-adapter.php' )
944 - ? ( is_plugin_active( 'mcp-adapter/mcp-adapter.php' ) ? 'active' : 'installed' )
945 - : 'not_installed',
946 - 'mcp_endpoint_url' => esc_url_raw( rest_url( 'sureforms/v1/mcp' ) ),
310 + 'site_url' => get_site_url(),
311 + 'breadcrumbs' => $this->get_breadcrumbs_for_current_page(),
312 + 'sureforms_dashboard_url' => admin_url( '/admin.php?page=sureforms_menu' ),
313 + 'plugin_version' => SRFM_VER,
314 + 'global_settings_nonce' => current_user_can( 'manage_options' ) ? wp_create_nonce( 'wp_rest' ) : '',
315 + 'is_pro_active' => defined( 'SRFM_PRO_VER' ),
316 + 'pro_plugin_version' => defined( 'SRFM_PRO_VER' ) ? SRFM_PRO_VER : '',
317 + 'sureforms_pricing_page' => $this->get_sureforms_website_url( 'pricing' ),
318 + 'field_spacing_vars' => Helper::get_css_vars(),
947 319 ];
948 320
949 - $is_screen_sureforms_menu = Helper::validate_request_context( 'sureforms_menu', 'page' );
950 - $is_screen_add_new_form = Helper::validate_request_context( 'add-new-form', 'page' );
951 - $is_screen_sureforms_forms = Helper::validate_request_context( 'sureforms_forms', 'page' );
952 - $is_screen_sureforms_form_settings = Helper::validate_request_context( 'sureforms_form_settings', 'page' );
953 - $is_screen_sureforms_payments = Helper::validate_request_context( 'sureforms_payments', 'page' );
954 - $is_screen_sureforms_entries = Helper::validate_request_context( SRFM_ENTRIES, 'page' );
955 - $is_screen_sureforms_learn = Helper::validate_request_context( 'sureforms_learn', 'page' );
956 - $is_screen_quiz_empty_state = Helper::validate_request_context( 'sureforms_quiz_entries', 'page' );
957 - $is_screen_survey_empty_state = Helper::validate_request_context( 'sureforms_survey_reports', 'page' );
958 - $is_post_type_sureforms_form = SRFM_FORMS_POST_TYPE === $current_screen->post_type;
959 -
960 - /**
961 - * Check if the current screen is the SureForms Menu and AI Auth Email is present then we will add user type as registered.
962 - * Compatibility with existing UI code that checks for this condition.
963 - */
964 - if ( $is_screen_sureforms_menu ) {
965 - // If email is stored send the user type as registered else non-registered.
966 - $localization_data['srfm_ai_details'] = [
967 - 'type' => ! empty( get_option( 'srfm_ai_auth_user_email' ) ) ? 'registered' : 'non-registered',
968 - ];
321 + if ( class_exists( 'SRFM_PRO\Admin\Licensing' ) ) {
322 + $license_active = \SRFM_PRO\Admin\Licensing::is_license_active();
323 + $localization_data['is_license_active'] = $license_active;
969 324 }
970 325
971 - // Add the Quizzes and Survey Reports nav items when pro is not active.
972 - if ( ! Helper::has_pro() ) {
973 - $localization_data['additional_header_nav_items'][] = [
974 - 'slug' => 'sureforms_quiz_entries',
975 - 'text' => __( 'Quizzes', 'sureforms' ),
976 - 'link' => admin_url( 'admin.php?page=sureforms_quiz_entries' ),
977 - ];
978 - $localization_data['additional_header_nav_items'][] = [
979 - 'slug' => 'sureforms_survey_reports',
980 - 'text' => __( 'Survey Reports', 'sureforms' ),
981 - 'link' => admin_url( 'admin.php?page=sureforms_survey_reports' ),
982 - ];
983 - }
984 -
985 - $is_sureforms_screen = $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 || $is_screen_sureforms_learn || $is_screen_quiz_empty_state || $is_screen_survey_empty_state;
986 -
987 - /**
988 - * Filter to allow extending the SureForms dashboard screen check.
989 - *
990 - * @since 2.6.0
991 - *
992 - * @param bool $is_sureforms_screen Whether the current screen is a SureForms dashboard screen.
993 - */
994 - $is_sureforms_screen = apply_filters( 'srfm_is_dashboard_screen', $is_sureforms_screen );
995 -
996 - if ( $is_sureforms_screen ) {
326 + if ( SRFM_FORMS_POST_TYPE === $current_screen->post_type || 'toplevel_page_sureforms_menu' === $current_screen->base || SRFM_ENTRIES_POST_TYPE === $current_screen->post_type
327 + || 'sureforms_page_sureforms_form_settings' === $current_screen->id
328 + ) {
997 329 $asset_handle = '-dashboard';
998 330
999 331 wp_enqueue_style( SRFM_SLUG . $asset_handle . '-font', 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap', [], SRFM_VER );
1000 332
@@ -1008,24 +340,9 @@
1008 340 wp_enqueue_script( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/dashboard.js', $script_info['dependencies'], SRFM_VER, true );
1009 341
1010 342 wp_localize_script( SRFM_SLUG . $asset_handle, 'scIcons', [ 'path' => SRFM_URL . 'assets/build/icon-assets' ] );
1011 343
1012 - $script_translations_handlers[] = SRFM_SLUG . $asset_handle;
1013 -
1014 - if ( class_exists( 'SRFM_PRO\Admin\Licensing' ) ) {
1015 - $license_active = \SRFM_PRO\Admin\Licensing::is_license_active();
1016 - $localization_data['is_license_active'] = $license_active;
1017 -
1018 - // Updating current licensing status.
1019 - $srfm_pro_license_status = get_option( 'srfm_pro_license_status', '' );
1020 - $current_license_status = $license_active ? 'licensed' : 'unlicensed';
1021 - if ( $current_license_status !== $srfm_pro_license_status ) {
1022 - update_option( 'srfm_pro_license_status', $current_license_status );
1023 - }
1024 - }
1025 -
1026 - $localization_data['security_settings_url'] = admin_url( '/admin.php?page=sureforms_form_settings&tab=security-settings&subpage=recaptcha' );
1027 - $localization_data['integration_settings_url'] = admin_url( '/admin.php?page=sureforms_form_settings&tab=integration-settings' );
344 + $localization_data['security_settings_url'] = admin_url( '/admin.php?page=sureforms_form_settings&tab=security-settings' );
1028 345 wp_localize_script(
1029 346 SRFM_SLUG . $asset_handle,
1030 347 SRFM_SLUG . '_admin',
1031 348 apply_filters(
@@ -1033,152 +350,32 @@
1033 350 $localization_data
1034 351 )
1035 352 );
1036 353 wp_enqueue_style( SRFM_SLUG . '-dashboard', SRFM_URL . 'assets/build/dashboard.css', [], SRFM_VER, 'all' );
1037 - }
1038 354
1039 - if ( $is_screen_sureforms_form_settings || $is_screen_sureforms_forms ) {
1040 - wp_enqueue_style( SRFM_SLUG . '-settings', $css_uri . 'backend/settings' . $file_prefix . $rtl . '.css', [], SRFM_VER );
1041 355 }
1042 356
1043 - // Enqueue styles for the entries page.
1044 - if ( $is_screen_sureforms_entries ) {
1045 - $asset_handle = '-entries';
1046 - wp_enqueue_script( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/entries.js', $script_info['dependencies'], SRFM_VER, true );
1047 -
1048 - wp_localize_script(
1049 - SRFM_SLUG . $asset_handle,
1050 - SRFM_SLUG . '_admin',
1051 - apply_filters(
1052 - SRFM_SLUG . '_admin_filter',
1053 - $localization_data
1054 - )
1055 - );
1056 - $script_translations_handlers[] = SRFM_SLUG . $asset_handle;
357 + if ( 'sureforms_page_sureforms_form_settings' === $current_screen->id ) {
358 + wp_enqueue_style( SRFM_SLUG . '-settings', $css_uri . 'backend/settings' . $file_prefix . '.css', [], SRFM_VER );
1057 359 }
1058 360
1059 - // Enqueue scripts for the learn page.
1060 - if ( $is_screen_sureforms_learn ) {
1061 - $asset_handle = '-learn';
1062 - wp_enqueue_script( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/learn.js', $script_info['dependencies'], SRFM_VER, true );
361 + // Admin Submenu Styles.
362 + wp_enqueue_style( SRFM_SLUG . '-admin', $css_uri . 'backend/admin' . $file_prefix . '.css', [], SRFM_VER );
1063 363
1064 - wp_localize_script(
1065 - SRFM_SLUG . $asset_handle,
1066 - SRFM_SLUG . '_admin',
1067 - apply_filters(
1068 - SRFM_SLUG . '_admin_filter',
1069 - $localization_data
1070 - )
1071 - );
1072 - $script_translations_handlers[] = SRFM_SLUG . $asset_handle;
1073 - }
364 + if ( 'edit-' . SRFM_FORMS_POST_TYPE === $current_screen->id || 'edit-' . SRFM_ENTRIES_POST_TYPE === $current_screen->id ) {
365 + $asset_handle = 'page_header';
1074 366
1075 - // Enqueue scripts for the forms page.
1076 - if ( $is_screen_sureforms_forms ) {
1077 - $asset_handle = '-forms';
1078 -
1079 - $script_asset_path = SRFM_DIR . 'assets/build/forms.asset.php';
1080 - $script_info = file_exists( $script_asset_path )
1081 - ? include $script_asset_path
1082 - : [
1083 - 'dependencies' => [],
1084 - 'version' => SRFM_VER,
1085 - ];
1086 -
1087 - wp_enqueue_script( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/forms.js', $script_info['dependencies'], SRFM_VER, true );
1088 - wp_localize_script(
1089 - SRFM_SLUG . $asset_handle,
1090 - SRFM_SLUG . '_admin',
1091 - apply_filters(
1092 - SRFM_SLUG . '_admin_filter',
1093 - $localization_data
1094 - )
1095 - );
1096 - wp_enqueue_style( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/forms.css', [], SRFM_VER, 'all' );
1097 -
1098 - $script_translations_handlers[] = SRFM_SLUG . $asset_handle;
1099 - }
1100 -
1101 - // Enqueue scripts for the SureMail promotional page.
1102 - $is_screen_sureforms_smtp = Helper::validate_request_context( 'sureforms_smtp', 'page' );
1103 - if ( $is_screen_sureforms_smtp ) {
1104 - $asset_handle = 'suremail';
1105 -
1106 367 $script_asset_path = SRFM_DIR . 'assets/build/' . $asset_handle . '.asset.php';
1107 368 $script_info = file_exists( $script_asset_path )
1108 - ? include $script_asset_path
1109 - : [
1110 - 'dependencies' => [],
1111 - 'version' => SRFM_VER,
1112 - ];
1113 -
1114 - wp_enqueue_script( SRFM_SLUG . '-suremail', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
1115 - wp_enqueue_style( SRFM_SLUG . '-suremail', SRFM_URL . 'assets/build/suremail.css', [], SRFM_VER, 'all' );
1116 -
1117 - // Localize script for SureMail page.
1118 - $suremail_localization_data = [
1119 - 'ajax_url' => admin_url( 'admin-ajax.php' ),
1120 - 'admin_url' => admin_url(),
1121 - 'suremail_url' => 'https://sureforms.com/suremail/',
1122 - 'plugin_installer_nonce' => wp_create_nonce( 'updates' ),
1123 - 'sfPluginManagerNonce' => wp_create_nonce( 'sf_plugin_manager_nonce' ),
1124 - 'suremail_status' => file_exists( WP_PLUGIN_DIR . '/suremails/suremails.php' )
1125 - ? ( is_plugin_active( 'suremails/suremails.php' ) ? 'active' : 'installed' )
1126 - : 'not_installed',
369 + ? include $script_asset_path
370 + : [
371 + 'dependencies' => [],
372 + 'version' => SRFM_VER,
1127 373 ];
1128 -
1129 - wp_localize_script(
1130 - SRFM_SLUG . '-suremail',
1131 - SRFM_SLUG . '_admin',
1132 - apply_filters(
1133 - SRFM_SLUG . '_suremail_admin_filter',
1134 - $suremail_localization_data
1135 - )
1136 - );
1137 -
1138 - $script_translations_handlers[] = SRFM_SLUG . '-suremail';
374 + wp_enqueue_script( SRFM_SLUG . '-form-page-header', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
375 + wp_enqueue_style( SRFM_SLUG . '-form-archive-styles', $css_uri . 'form-archive-styles' . $file_prefix . '.css', [], SRFM_VER );
1139 376 }
1140 -
1141 - // Enqueue scripts for the Quiz empty state page (free users only).
1142 - if ( $is_screen_quiz_empty_state && ! Helper::has_pro() ) {
1143 - $asset_handle = 'quizEmptyState';
1144 -
1145 - $script_asset_path = SRFM_DIR . 'assets/build/' . $asset_handle . '.asset.php';
1146 - $script_info = file_exists( $script_asset_path )
1147 - ? include $script_asset_path
1148 - : [
1149 - 'dependencies' => [],
1150 - 'version' => SRFM_VER,
1151 - ];
1152 -
1153 - wp_enqueue_script( SRFM_SLUG . '-quiz-empty-state', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
1154 - wp_enqueue_style( SRFM_SLUG . '-quiz-empty-state', SRFM_URL . 'assets/build/' . $asset_handle . '.css', [], SRFM_VER, 'all' );
1155 -
1156 - $script_translations_handlers[] = SRFM_SLUG . '-quiz-empty-state';
1157 - }
1158 -
1159 - // Enqueue scripts for the Survey Reports empty state page (free users only).
1160 - if ( $is_screen_survey_empty_state && ! Helper::has_pro() ) {
1161 - $asset_handle = 'surveyEmptyState';
1162 -
1163 - $script_asset_path = SRFM_DIR . 'assets/build/' . $asset_handle . '.asset.php';
1164 - $script_info = file_exists( $script_asset_path )
1165 - ? include $script_asset_path
1166 - : [
1167 - 'dependencies' => [],
1168 - 'version' => SRFM_VER,
1169 - ];
1170 -
1171 - wp_enqueue_script( SRFM_SLUG . '-survey-empty-state', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
1172 - wp_enqueue_style( SRFM_SLUG . '-survey-empty-state', SRFM_URL . 'assets/build/' . $asset_handle . '.css', [], SRFM_VER, 'all' );
1173 -
1174 - $script_translations_handlers[] = SRFM_SLUG . '-survey-empty-state';
1175 - }
1176 -
1177 - // Admin Submenu Styles.
1178 - wp_enqueue_style( SRFM_SLUG . '-admin', $css_uri . 'backend/admin' . $file_prefix . $rtl . '.css', [], SRFM_VER );
1179 -
1180 - if ( $is_screen_sureforms_form_settings ) {
377 + if ( 'sureforms_page_' . SRFM_FORMS_POST_TYPE . '_settings' === $current_screen->base ) {
1181 378 $asset_handle = 'settings';
1182 379
1183 380 $script_asset_path = SRFM_DIR . 'assets/build/' . $asset_handle . '.asset.php';
1184 381 $script_info = file_exists( $script_asset_path )
@@ -1188,23 +385,55 @@
1188 385 'version' => SRFM_VER,
1189 386 ];
1190 387
1191 388 wp_enqueue_script( SRFM_SLUG . '-settings', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
389 + wp_enqueue_style( SRFM_SLUG . '-setting-styles', SRFM_URL . 'assets/build/' . $asset_handle . '.css', [ 'wp-components' ], SRFM_VER, 'all' );
1192 390 wp_localize_script(
1193 391 SRFM_SLUG . '-settings',
1194 392 SRFM_SLUG . '_admin',
1195 - apply_filters(
1196 - SRFM_SLUG . '_admin_filter',
1197 - $localization_data
1198 - )
393 + $localization_data
1199 394 );
395 + }
396 + if ( 'edit-' . SRFM_FORMS_POST_TYPE === $current_screen->id ) {
397 + wp_enqueue_script( SRFM_SLUG . '-form-archive', $js_uri . 'form-archive' . $file_prefix . '.js', [], SRFM_VER, true );
398 + wp_enqueue_script( SRFM_SLUG . '-export', $js_uri . 'export' . $file_prefix . '.js', [ 'wp-i18n' ], SRFM_VER, true );
399 + wp_localize_script(
400 + SRFM_SLUG . '-export',
401 + SRFM_SLUG . '_export',
402 + [
403 + 'ajaxurl' => admin_url( 'admin-ajax.php' ),
404 + 'srfm_export_nonce' => wp_create_nonce( 'export_form_nonce' ),
405 + 'site_url' => get_site_url(),
406 + 'srfm_import_endpoint' => '/wp-json/sureforms/v1/sureforms_import',
407 + 'import_form_nonce' => ( current_user_can( 'edit_posts' ) ) ? wp_create_nonce( 'wp_rest' ) : '',
408 + ]
409 + );
1200 410
1201 - $script_translations_handlers[] = SRFM_SLUG . '-settings';
411 + wp_enqueue_script( SRFM_SLUG . '-backend', $js_uri . 'backend' . $file_prefix . '.js', [], SRFM_VER, true );
412 + wp_localize_script(
413 + SRFM_SLUG . '-backend',
414 + SRFM_SLUG . '_backend',
415 + [
416 + 'site_url' => get_site_url(),
417 + ]
418 + );
419 +
1202 420 }
1203 421
1204 - if ( $is_screen_add_new_form ) {
1205 - wp_enqueue_style( SRFM_SLUG . '-template-picker', $css_uri . 'template-picker' . $file_prefix . $rtl . '.css', [], SRFM_VER );
422 + if ( 'sureforms_page_add-new-form' === $current_screen->id ) {
1206 423
424 + $file_prefix = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? '' : '.min';
425 + $dir_name = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? 'unminified' : 'minified';
426 +
427 + $css_uri = SRFM_URL . 'assets/css/' . $dir_name . '/';
428 +
429 + /* RTL */
430 + if ( is_rtl() ) {
431 + $file_prefix .= '-rtl';
432 + }
433 +
434 + wp_enqueue_style( SRFM_SLUG . '-template-picker', $css_uri . 'template-picker' . $file_prefix . '.css', [], SRFM_VER );
435 +
1207 436 $sureforms_admin = 'templatePicker';
1208 437
1209 438 $script_asset_path = SRFM_DIR . 'assets/build/' . $sureforms_admin . '.asset.php';
1210 439 $script_info = file_exists( $script_asset_path )
@@ -1220,22 +449,16 @@
1220 449 SRFM_SLUG . '_admin',
1221 450 [
1222 451 'site_url' => get_site_url(),
1223 452 'plugin_url' => SRFM_URL,
453 + 'preview_images_url' => SRFM_URL . 'images/template-previews/',
1224 454 'admin_url' => admin_url( 'admin.php' ),
1225 455 'new_template_picker_base_url' => admin_url( 'post-new.php?post_type=sureforms_form' ),
1226 - 'capability' => Helper::current_user_can(),
1227 - 'template_picker_nonce' => Helper::current_user_can() ? wp_create_nonce( 'wp_rest' ) : '',
1228 - 'is_pro_active' => Helper::has_pro(),
1229 - 'srfm_ai_usage_details' => AI_Helper::get_current_usage_details(),
1230 - 'is_pro_license_active' => AI_Helper::is_pro_license_active(),
1231 - 'srfm_ai_auth_user_email' => get_option( 'srfm_ai_auth_user_email' ),
1232 - 'pricing_page_url' => Helper::get_sureforms_website_url( 'pricing' ),
1233 - 'licensing_nonce' => wp_create_nonce( 'srfm_pro_licensing_nonce' ),
456 + 'capability' => current_user_can( 'edit_posts' ),
457 + 'template_picker_nonce' => current_user_can( 'edit_posts' ) ? wp_create_nonce( 'wp_rest' ) : '',
458 + 'is_pro_active' => defined( 'SRFM_PRO_VER' ),
1234 459 ]
1235 460 );
1236 -
1237 - $script_translations_handlers[] = SRFM_SLUG . '-template-picker';
1238 461 }
1239 462 // Quick action sidebar.
1240 463 $default_allowed_quick_sidebar_blocks = apply_filters(
1241 464 'srfm_quick_sidebar_allowed_blocks',
@@ -1246,9 +469,8 @@
1246 469 'srfm/checkbox',
1247 470 'srfm/number',
1248 471 'srfm/inline-button',
1249 472 'srfm/advanced-heading',
1250 - 'srfm/payment',
1251 473 ]
1252 474 );
1253 475 if ( ! is_array( $default_allowed_quick_sidebar_blocks ) ) {
1254 476 $default_allowed_quick_sidebar_blocks = [];
@@ -1260,80 +482,33 @@
1260 482 }
1261 483 $quick_sidebar_allowed_blocks = get_option( 'srfm_quick_sidebar_allowed_blocks' );
1262 484 $quick_sidebar_allowed_blocks = ! empty( $quick_sidebar_allowed_blocks ) && is_array( $quick_sidebar_allowed_blocks ) ? $quick_sidebar_allowed_blocks : $default_allowed_quick_sidebar_blocks;
1263 485 $srfm_ajax_nonce = wp_create_nonce( 'srfm_ajax_nonce' );
1264 -
1265 - if ( Helper::is_sureforms_admin_page() ) {
1266 - wp_enqueue_script( SRFM_SLUG . '-quick-action-siderbar', SRFM_URL . 'assets/build/quickActionSidebar.js', [], SRFM_VER, true );
1267 - wp_localize_script(
1268 - SRFM_SLUG . '-quick-action-siderbar',
1269 - SRFM_SLUG . '_quick_sidebar_blocks',
1270 - [
1271 - 'allowed_blocks' => $quick_sidebar_allowed_blocks,
1272 - 'srfm_enable_quick_action_sidebar' => $srfm_enable_quick_action_sidebar,
1273 - 'srfm_ajax_nonce' => $srfm_ajax_nonce,
1274 - 'srfm_ajax_url' => admin_url( 'admin-ajax.php' ),
1275 - ]
1276 - );
1277 -
1278 - $script_translations_handlers[] = SRFM_SLUG . '-quick-action-siderbar';
1279 - }
1280 -
1281 - /**
1282 - * Enqueuing SureTriggers Integration script.
1283 - * This script loads suretriggers iframe in Intergations tab.
1284 - */
1285 - if ( $is_post_type_sureforms_form ) {
1286 - wp_enqueue_script( SRFM_SLUG . '-suretriggers-integration', SRFM_SURETRIGGERS_INTEGRATION_BASE_URL . 'js/v2/embed.js', [], SRFM_VER, true );
1287 - }
1288 -
1289 - // Check $script_translations_handlers is not empty before calling the function.
1290 - if ( ! empty( $script_translations_handlers ) ) {
1291 - // Remove duplicates values from the array.
1292 - $script_translations_handlers = array_unique( $script_translations_handlers );
1293 -
1294 - foreach ( $script_translations_handlers as $script_handle ) {
1295 - Helper::register_script_translations( $script_handle );
1296 - }
1297 - }
486 + wp_enqueue_script( SRFM_SLUG . '-quick-action-siderbar', SRFM_URL . 'assets/build/quickActionSidebar.js', [], SRFM_VER, true );
487 + wp_localize_script(
488 + SRFM_SLUG . '-quick-action-siderbar',
489 + SRFM_SLUG . '_quick_sidebar_blocks',
490 + [
491 + 'allowed_blocks' => $quick_sidebar_allowed_blocks,
492 + 'srfm_enable_quick_action_sidebar' => $srfm_enable_quick_action_sidebar,
493 + 'srfm_ajax_nonce' => $srfm_ajax_nonce,
494 + 'srfm_ajax_url' => admin_url( 'admin-ajax.php' ),
495 + ]
496 + );
1298 497 }
1299 498
1300 499 /**
1301 500 * Form Template Picker Admin Body Classes
1302 - * WordPress sometimes translates class names in the admin body tag, which can result in
1303 - * incorrect or missing class names when rendering the admin pages. This function ensures
1304 - * that essential class names are manually added to the body tag to maintain proper functionality.
1305 501 *
1306 502 * @since 0.0.1
1307 503 * @param string $classes Space separated class string.
1308 504 */
1309 505 public function admin_template_picker_body_class( $classes = '' ) {
1310 - // Define an associative array of class names and their corresponding conditions.
1311 - // Each condition checks whether a specific request context matches.
1312 - $srfm_classes = [
1313 - 'sureforms_page_sureforms_entries' => Helper::validate_request_context( SRFM_ENTRIES, 'page' ),
1314 - 'sureforms_page_sureforms_form_settings' => Helper::validate_request_context( 'sureforms_form_settings', 'page' ),
1315 - 'srfm-template-picker' => Helper::validate_request_context( 'add-new-form', 'page' ),
1316 - ];
506 + $theme_builder_class = isset( $_GET['page'] ) && 'add-new-form' === $_GET['page'] ? 'srfm-template-picker' : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Fetching a $_GET value, no nonce available to validate.
507 + $classes .= ' ' . $theme_builder_class . ' ';
1317 508
1318 - $add_srfm_classes = '';
509 + return $classes;
1319 510
1320 - // Loop through the defined classes and conditions.
1321 - foreach ( $srfm_classes as $class => $condition ) {
1322 - // Check if the condition evaluates to true.
1323 - if ( $condition ) {
1324 - // Append the class to the existing classes string, followed by a space.
1325 - $add_srfm_classes .= empty( $add_srfm_classes ) ? $class : ' ' . $class;
1326 - }
1327 - }
1328 -
1329 - // Append the new classes to the existing classes string.
1330 - if ( ! empty( $add_srfm_classes ) ) {
1331 - $classes .= ' ' . $add_srfm_classes;
1332 - }
1333 -
1334 - // Return the updated list of classes.
1335 - return $classes;
1336 511 }
1337 512
1338 513 /**
1339 514 * Disable spectra's quick action bar in sureforms CPT.
@@ -1351,705 +526,19 @@
1351 526 return $status;
1352 527 }
1353 528
1354 529 /**
1355 - * Register Pro compatibility notices early for React pages.
530 + * Get SureForms Website URL.
1356 531 *
1357 - * This method runs on admin_init (priority 5) to ensure notices are
1358 - * registered BEFORE admin_enqueue_scripts, so they're available when
1359 - * wp_localize_script runs.
1360 - *
1361 - * Hooked - admin_init (priority 5)
1362 - *
1363 - * @return void
1364 - * @since 2.5.0
532 + * @param string $trail The URL trail to append to SureForms website URL. The parameter should not include a leading slash as the base URL already ends with a trailing slash.
533 + * @since 0.0.7
534 + * @return string
1365 535 */
1366 - public function register_pro_compatibility_notices() {
1367 - // Early exit if Pro is not active, user lacks permissions, or Notice_Manager is unavailable.
1368 - if ( ! Helper::has_pro() || ! Helper::current_user_can() || ! class_exists( 'SRFM\Admin\Notice_Manager' ) ) {
1369 - return;
536 + public static function get_sureforms_website_url( $trail ) {
537 + $url = SRFM_WEBSITE;
538 + if ( ! empty( $trail ) && is_string( $trail ) ) {
539 + $url = SRFM_WEBSITE . $trail;
1370 540 }
1371 541
1372 - // Register version outdated notice for React pages.
1373 - if ( ! version_compare( SRFM_PRO_VER, SRFM_PRO_RECOMMENDED_VER, '>=' ) ) {
1374 - $pro_plugin_name = defined( 'SRFM_PRO_PRODUCT' ) ? SRFM_PRO_PRODUCT : 'SureForms Pro';
1375 - $react_outdated_message = sprintf(
1376 - // translators: %1$s: SureForms version, %2$s: SureForms Pro Plugin Name, %3$s: SureForms Pro Version.
1377 - esc_html__( 'SureForms %1$s requires minimum %2$s %3$s to work properly. Please update to the latest version.', 'sureforms' ),
1378 - esc_html( SRFM_VER ),
1379 - esc_html( $pro_plugin_name ),
1380 - esc_html( SRFM_PRO_RECOMMENDED_VER )
1381 - );
1382 -
1383 - \SRFM\Admin\Notice_Manager::register_notice(
1384 - [
1385 - 'id' => 'sureforms-pro-version-outdated',
1386 - 'variant' => 'warning',
1387 - 'message' => $react_outdated_message,
1388 - 'actions' => [
1389 - [
1390 - 'label' => esc_html__( 'Update Now', 'sureforms' ),
1391 - 'url' => admin_url( 'update-core.php' ),
1392 - 'variant' => 'primary',
1393 - ],
1394 - ],
1395 - 'pages' => [ 'all' ],
1396 - ]
1397 - );
1398 - }
542 + return esc_url( $url );
1399 543 }
1400 -
1401 - /**
1402 - * Admin Notice Callback if sureforms pro is out of date.
1403 - *
1404 - * Hooked - admin_notices
1405 - *
1406 - * @return void
1407 - * @since 1.0.4
1408 - */
1409 - public function srfm_pro_version_compatibility() {
1410 - if ( ! Helper::has_pro() ) {
1411 - return;
1412 - }
1413 -
1414 - if ( empty( get_current_screen() ) ) {
1415 - return;
1416 - }
1417 -
1418 - if ( ! Helper::current_user_can() ) {
1419 - return;
1420 - }
1421 -
1422 - $srfm_pro_license_status = get_option( 'srfm_pro_license_status', '' );
1423 - /**
1424 - * If the license status is not set then get the license status and update the option accordingly.
1425 - * This will be executed only once. Subsequently, the option status is updated by the licensing class on license activation or deactivation.
1426 - */
1427 - if ( empty( $srfm_pro_license_status ) && class_exists( 'SRFM_PRO\Admin\Licensing' ) ) {
1428 - $srfm_pro_license_status = \SRFM_PRO\Admin\Licensing::is_license_active() ? 'licensed' : 'unlicensed';
1429 - update_option( 'srfm_pro_license_status', $srfm_pro_license_status );
1430 - }
1431 -
1432 - $pro_plugin_name = defined( 'SRFM_PRO_PRODUCT' ) ? SRFM_PRO_PRODUCT : 'SureForms Pro';
1433 - $message = '';
1434 - $url = admin_url( 'admin.php?page=sureforms_form_settings&tab=account-settings' );
1435 - if ( 'unlicensed' === $srfm_pro_license_status ) {
1436 - ob_start();
1437 - ?>
1438 - <p>
1439 - <?php
1440 - printf(
1441 - // translators: %1$s: Opening anchor tag with URL, %2$s: Closing anchor tag, %3$s: SureForms Pro Plugin Name.
1442 - esc_html__( 'Please %1$sactivate%2$s your copy of %3$s to get new features, access support, receive update notifications, and more.', 'sureforms' ),
1443 - '<a href="' . esc_url( $url ) . '">',
1444 - '</a>',
1445 - '<i>' . esc_html( $pro_plugin_name ) . '</i>'
1446 - );
1447 - ?>
1448 - </p>
1449 - <?php
1450 - $message = ob_get_clean();
1451 - }
1452 -
1453 - if ( ! version_compare( SRFM_PRO_VER, SRFM_PRO_RECOMMENDED_VER, '>=' ) ) {
1454 - ob_start();
1455 - ?>
1456 - <p>
1457 - <?php
1458 - printf(
1459 - // 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.
1460 - 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' ),
1461 - esc_html( SRFM_VER ),
1462 - esc_html( $pro_plugin_name ),
1463 - esc_html( SRFM_PRO_RECOMMENDED_VER ),
1464 - '<a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">',
1465 - '</a>'
1466 - );
1467 - ?>
1468 - </p>
1469 - <?php
1470 - $message .= ob_get_clean();
1471 - }
1472 -
1473 - if ( ! empty( $message ) ) {
1474 - // Phpcs ignore comment is required as $message variable is already escaped.
1475 - ?>
1476 - <div class="notice notice-warning"><?php echo wp_kses_post( $message ); ?></div>
1477 - <?php
1478 - }
1479 - }
1480 -
1481 - /**
1482 - * Display a notice to the user about providing a review.
1483 - *
1484 - * @since 2.5.2
1485 - * @return void
1486 - */
1487 - public function display_srfm_rating_notice() {
1488 - // Only show to admins.
1489 - if ( ! Helper::current_user_can() ) {
1490 - return;
1491 - }
1492 -
1493 - // Allow the notice to be disabled.
1494 - if ( ! apply_filters( 'srfm_show_rating_notice', true ) ) {
1495 - return;
1496 - }
1497 -
1498 - Astra_Notices::add_notice(
1499 - [
1500 - 'id' => 'srfm-plugin-review-notice',
1501 - 'type' => '',
1502 - 'message' => $this->build_notice_markup(
1503 - esc_html__( 'Amazing! SureForms is powering your forms and submissions - let\'s keep growing together!', 'sureforms' ),
1504 - esc_html__( 'If SureForms has been helpful, would you mind taking a moment to leave a 5-star review on WordPress.org?', 'sureforms' ),
1505 - esc_url( 'https://wordpress.org/support/plugin/sureforms/reviews/?filter=5#new-post' ),
1506 - esc_html__( 'Rate SureForms', 'sureforms' ),
1507 - esc_html__( 'Maybe later', 'sureforms' ),
1508 - esc_html__( 'I already did', 'sureforms' ),
1509 - WEEK_IN_SECONDS,
1510 - true
1511 - ),
1512 - 'repeat-notice-after' => WEEK_IN_SECONDS,
1513 - 'show_if' => $this->maybe_display_rating_notice(),
1514 - 'display-with-other-notices' => true,
1515 - ]
1516 - );
1517 -
1518 - add_action( 'astra_notice_after_markup_srfm-plugin-review-notice', [ $this, 'enqueue_notice_response_script' ] );
1519 - }
1520 -
1521 - /**
1522 - * Display a "Getting Started" admin notice for new users who haven't yet
1523 - * reached the rating-notice milestone (3+ forms or 3+ entries).
1524 - *
1525 - * The Astra Notices library handles the 7-day delay via the
1526 - * `display-notice-after` parameter.
1527 - *
1528 - * @since 2.5.2
1529 - * @return void
1530 - */
1531 - public function display_srfm_getting_started_notice() {
1532 - // Only show to admins.
1533 - if ( ! Helper::current_user_can() ) {
1534 - return;
1535 - }
1536 -
1537 - // Allow the notice to be disabled programmatically.
1538 - if ( ! apply_filters( 'srfm_show_getting_started_notice', true ) ) {
1539 - return;
1540 - }
1541 -
1542 - Astra_Notices::add_notice(
1543 - [
1544 - 'id' => 'srfm-getting-started-notice',
1545 - 'type' => '',
1546 - 'message' => $this->build_notice_markup(
1547 - esc_html__( 'SureForms is ready to power your forms — explore what\'s possible!', 'sureforms' ),
1548 - esc_html__( 'Manage your forms, track submissions, and discover features like AI Form Builder, payment integrations, and more from the SureForms dashboard.', 'sureforms' ),
1549 - esc_url( admin_url( 'admin.php?page=sureforms_menu' ) ),
1550 - esc_html__( 'Go to Dashboard', 'sureforms' ),
1551 - esc_html__( 'Maybe later', 'sureforms' ),
1552 - esc_html__( 'I already know', 'sureforms' ),
1553 - WEEK_IN_SECONDS
1554 - ),
1555 - 'repeat-notice-after' => WEEK_IN_SECONDS,
1556 - 'show_if' => ! $this->maybe_display_rating_notice(),
1557 - 'display-notice-after' => WEEK_IN_SECONDS,
1558 - 'display-with-other-notices' => true,
1559 - ]
1560 - );
1561 -
1562 - add_action( 'astra_notice_after_markup_srfm-getting-started-notice', [ $this, 'enqueue_notice_response_script' ] );
1563 - }
1564 -
1565 - /**
1566 - * Enqueue the notice response analytics script.
1567 - *
1568 - * Called via the astra_notice_after_markup_{id} hook so the script
1569 - * only loads when a SureForms notice is actually rendered.
1570 - *
1571 - * @since 2.5.2
1572 - * @return void
1573 - */
1574 - public function enqueue_notice_response_script() {
1575 - if ( wp_script_is( 'srfm-notice-response', 'enqueued' ) ) {
1576 - return;
1577 - }
1578 -
1579 - wp_enqueue_script(
1580 - 'srfm-notice-response',
1581 - SRFM_URL . 'admin/assets/js/notice-response.js',
1582 - [],
1583 - SRFM_VER,
1584 - true
1585 - );
1586 -
1587 - wp_localize_script(
1588 - 'srfm-notice-response',
1589 - 'srfmNoticeResponse',
1590 - [
1591 - 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1592 - 'nonce' => wp_create_nonce( 'srfm_notice_response' ),
1593 - ]
1594 - );
1595 - }
1596 -
1597 - /**
1598 - * Handle the notice response AJAX request.
1599 - *
1600 - * Validates the request and records the analytics event
1601 - * for the notice button that was clicked.
1602 - *
1603 - * @since 2.5.2
1604 - * @return void
1605 - */
1606 - public function handle_notice_response() {
1607 - if ( ! check_ajax_referer( 'srfm_notice_response', 'nonce', false ) ) {
1608 - wp_send_json_error( [ 'message' => __( 'Invalid nonce.', 'sureforms' ) ], 403 );
1609 - }
1610 -
1611 - if ( ! Helper::current_user_can() ) {
1612 - wp_send_json_error( [ 'message' => __( 'Unauthorized user.', 'sureforms' ) ], 403 );
1613 - }
1614 -
1615 - $notice_id = isset( $_POST['notice_id'] ) ? sanitize_text_field( wp_unslash( $_POST['notice_id'] ) ) : '';
1616 - $button = isset( $_POST['button'] ) ? sanitize_text_field( wp_unslash( $_POST['button'] ) ) : '';
1617 -
1618 - $valid = [
1619 - 'srfm-getting-started-notice' => [
1620 - 'go_to_dashboard' => 'getting_started_notice_cta',
1621 - 'maybe_later' => 'getting_started_notice_snooze',
1622 - 'dismissed' => 'getting_started_notice_dismiss',
1623 - ],
1624 - 'srfm-plugin-review-notice' => [
1625 - 'rate_sureforms' => 'rating_notice_cta',
1626 - 'maybe_later' => 'rating_notice_snooze',
1627 - 'dismissed' => 'rating_notice_dismiss',
1628 - ],
1629 - ];
1630 -
1631 - if ( ! isset( $valid[ $notice_id ][ $button ] ) ) {
1632 - wp_send_json_error( [ 'message' => __( 'Invalid parameters.', 'sureforms' ) ], 400 );
1633 - }
1634 -
1635 - $event_name = $valid[ $notice_id ][ $button ];
1636 - Analytics::events()->track( $event_name, $button );
1637 -
1638 - wp_send_json_success();
1639 - }
1640 -
1641 - /**
1642 - * Disables the capabilities for WPForms to avoid conflicts when enqueueing
1643 - * scripts and styles for WPForms.
1644 - *
1645 - * This function is intended to prevent any potential conflicts that may arise
1646 - * when WPForms scripts and styles are enqueued. By disabling certain capabilities,
1647 - * it ensures that WPForms does not interfere with other functionalities.
1648 - *
1649 - * @param bool $user_can A boolean indicating whether the user has the capability.
1650 - * @return bool Returns true if the capabilities are successfully disabled, false otherwise.
1651 - * @since 1.4.2
1652 - */
1653 - public function disable_wpforms_capabilities( $user_can ) {
1654 - // Note: Nonce verification is intentionally omitted here as no database operations are performed.
1655 - // The values of the $_REQUEST variables are strictly validated, ensuring security without the need for nonce verification.
1656 -
1657 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1658 - $post_id = ! empty( $_REQUEST['post'] ) && ! empty( $_REQUEST['action'] ) ? absint( $_REQUEST['post'] ) : 0;
1659 -
1660 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1661 - $post_type = $post_id ? get_post_type( $post_id ) : sanitize_text_field( wp_unslash( $_REQUEST['post_type'] ?? '' ) );
1662 - return SRFM_FORMS_POST_TYPE === $post_type ? false : $user_can;
1663 - }
1664 -
1665 - /**
1666 - * Enqueueus the admin pointer script and styles.
1667 - *
1668 - * @return void
1669 - * @since 1.8.0
1670 - */
1671 - public function enqueue_admin_pointer() {
1672 - if ( ! $this->is_admin_pointer_visible() ) {
1673 - return;
1674 - }
1675 - wp_enqueue_style( 'wp-pointer' );
1676 - wp_enqueue_script( 'wp-pointer' );
1677 - wp_enqueue_script(
1678 - 'sureforms-admin-pointer',
1679 - plugins_url( 'admin/assets/js/sureforms-pointer.js', SRFM_FILE ),
1680 - [ 'wp-pointer', 'jquery' ],
1681 - SRFM_VER,
1682 - true
1683 - );
1684 - wp_localize_script(
1685 - 'sureforms-admin-pointer',
1686 - 'sureformsPointerData',
1687 - [
1688 - 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1689 - 'pointer_nonce' => wp_create_nonce( 'sureforms_pointer_action' ),
1690 - ]
1691 - );
1692 - }
1693 -
1694 - /**
1695 - * Ajax handler for pointer popup visibility.
1696 - *
1697 - * @return void
1698 - * @since 1.8.0
1699 - */
1700 - public function pointer_should_show() {
1701 - // Security: Check user capability.
1702 - if ( ! Helper::current_user_can() ) {
1703 - wp_send_json_error( [ 'message' => __( 'Unauthorized user.', 'sureforms' ) ], 403 );
1704 - }
1705 - // Security: Nonce check.
1706 - if ( empty( $_POST['pointer_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pointer_nonce'] ) ), 'sureforms_pointer_action' ) ) {
1707 - wp_send_json_error( [ 'message' => __( 'Invalid nonce.', 'sureforms' ) ], 403 );
1708 - }
1709 -
1710 - $content_markup = sprintf(
1711 - /* translators: 1: opening span, 2: opening strong (inline), 3: closing strong, 4: closing span, 5: opening strong (block), 6: closing strong */
1712 - __( '%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' ),
1713 - '<span>',
1714 - '<strong>',
1715 - '</strong>',
1716 - '</span><br/>',
1717 - '<strong style="font-size:1.1em;">',
1718 - '</strong>'
1719 - );
1720 - wp_send_json(
1721 - [
1722 - 'show' => true,
1723 - 'title' => esc_html( __( 'SureForms is waiting for you!', 'sureforms' ) ),
1724 - 'content' => wp_kses_post( $content_markup ),
1725 - 'button_text' => esc_html( __( 'Build My First Form', 'sureforms' ) ),
1726 - 'dismiss' => esc_html( __( 'Dismiss', 'sureforms' ) ),
1727 - 'button_url' => admin_url( 'admin.php?page=add-new-form' ),
1728 - ]
1729 - );
1730 - }
1731 -
1732 - /**
1733 - * Ajax callback for pointer popup dismissed action.
1734 - *
1735 - * @return void
1736 - * @since 1.8.0
1737 - */
1738 - public function pointer_dismissed() {
1739 - // Security: Check user capability.
1740 - if ( ! Helper::current_user_can() ) {
1741 - wp_send_json_error( [ 'message' => __( 'Unauthorized user.', 'sureforms' ) ], 403 );
1742 - }
1743 - // Security: Nonce check.
1744 - if ( empty( $_POST['pointer_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pointer_nonce'] ) ), 'sureforms_pointer_action' ) ) {
1745 - wp_send_json_error( [ 'message' => __( 'Invalid nonce.', 'sureforms' ) ], 403 );
1746 - }
1747 - // Use Helper to update srfm_options key.
1748 - Helper::update_srfm_option( 'pointer_popup_dismissed', time() );
1749 -
1750 - wp_send_json_success();
1751 - }
1752 -
1753 - /**
1754 - * Ajax pointer accepted CTA callback.
1755 - *
1756 - * @return void
1757 - * @since 1.8.0
1758 - */
1759 - public function pointer_accepted_cta() {
1760 - // Security: Check user capability.
1761 - if ( ! Helper::current_user_can() ) {
1762 - wp_send_json_error( [ 'message' => __( 'Unauthorized user.', 'sureforms' ) ], 403 );
1763 - }
1764 - // Security: Nonce check.
1765 - if ( empty( $_POST['pointer_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pointer_nonce'] ) ), 'sureforms_pointer_action' ) ) {
1766 - wp_send_json_error( [ 'message' => __( 'Invalid nonce.', 'sureforms' ) ], 403 );
1767 - }
1768 - // Use Helper to update srfm_options key.
1769 - Helper::update_srfm_option( 'pointer_popup_accepted', time() );
1770 -
1771 - wp_send_json_success();
1772 - }
1773 -
1774 - /**
1775 - * Maybe register the dashboard widget based on entries.
1776 - *
1777 - * @return void
1778 - * @since 1.9.1
1779 - */
1780 - public function maybe_register_dashboard_widget() {
1781 -
1782 - // Only for users with manage_options capability.
1783 - if ( ! Helper::current_user_can() ) {
1784 - return;
1785 - }
1786 -
1787 - // Quick check if there are any entries in the last 7 days.
1788 - $seven_days_ago = strtotime( '-7 days' );
1789 - $total_entries = Entries::get_entries_count_after( $seven_days_ago );
1790 -
1791 - // Only add the dashboard setup hook if there are entries.
1792 - if ( $total_entries > 0 ) {
1793 - // Get forms with entries (limit 4 for dashboard widget).
1794 - $this->dashboard_widget_data = Helper::get_forms_with_entry_counts( $seven_days_ago, 4 );
1795 -
1796 - // Only show dashboard widget if there are forms with entries.
1797 - if ( ! empty( $this->dashboard_widget_data ) ) {
1798 - add_action( 'wp_dashboard_setup', [ $this, 'register_dashboard_widget' ] );
1799 - }
1800 - }
1801 - }
1802 -
1803 - /**
1804 - * Register the dashboard widget.
1805 - *
1806 - * @return void
1807 - * @since 1.9.1
1808 - */
1809 - public function register_dashboard_widget() {
1810 - // Add the widget with high priority to position it at the top.
1811 - wp_add_dashboard_widget(
1812 - 'sureforms_recent_entries',
1813 - __( 'SureForms', 'sureforms' ),
1814 - [ $this, 'render_dashboard_widget' ],
1815 - null,
1816 - null,
1817 - 'normal',
1818 - 'high'
1819 - );
1820 - }
1821 -
1822 - /**
1823 - * Render the dashboard widget content.
1824 - *
1825 - * @return void
1826 - * @since 1.9.1
1827 - */
1828 - public function render_dashboard_widget() {
1829 - // Use the pre-fetched data to avoid duplicate queries.
1830 - $entries_data = $this->dashboard_widget_data;
1831 -
1832 - // Display the widget content.
1833 - ?>
1834 - <div class="srfm-dashboard-widget">
1835 - <div class="srfm-widget-header">
1836 - <h3 class="srfm-widget-title">
1837 - <?php esc_html_e( 'Recent Entries', 'sureforms' ); ?>
1838 - <span class="srfm-widget-subtitle"><?php esc_html_e( '( Last 7 days )', 'sureforms' ); ?></span>
1839 - </h3>
1840 - <a href="<?php echo esc_url( admin_url( 'admin.php?page=sureforms_entries' ) ); ?>" class="srfm-widget-view-link">
1841 - <?php esc_html_e( 'View', 'sureforms' ); ?>
1842 - </a>
1843 - </div>
1844 -
1845 - <div class="srfm-table-wrapper">
1846 - <table class="srfm-entries-table">
1847 - <thead>
1848 - <tr>
1849 - <th><?php esc_html_e( 'Form Name', 'sureforms' ); ?></th>
1850 - <th><?php esc_html_e( 'Entries', 'sureforms' ); ?></th>
1851 - </tr>
1852 - </thead>
1853 - <tbody>
1854 - <?php foreach ( $entries_data as $form_data ) { ?>
1855 - <tr>
1856 - <td class="form-name"><?php echo esc_html( $form_data['title'] ); ?></td>
1857 - <td class="entry-count"><?php echo esc_html( $form_data['count'] ); ?></td>
1858 - </tr>
1859 - <?php } ?>
1860 - </tbody>
1861 - </table>
1862 - </div>
1863 -
1864 - <?php
1865 - // Render footer if applicable.
1866 - $this->render_dashboard_widget_footer( $entries_data );
1867 - ?>
1868 - </div>
1869 - <?php
1870 - }
1871 -
1872 - /**
1873 - * Build the shared HTML markup for admin notices.
1874 - *
1875 - * @since 2.5.2
1876 - *
1877 - * All text parameters must be pre-escaped by the caller (e.g. via esc_html__()).
1878 - * URL parameters must be pre-escaped via esc_url().
1879 - *
1880 - * @param string $heading The notice heading text (pre-escaped).
1881 - * @param string $message The notice body text (pre-escaped).
1882 - * @param string $cta_url The primary CTA URL (pre-escaped).
1883 - * @param string $cta_text The primary CTA button text (pre-escaped).
1884 - * @param string $snooze_text The snooze button text (pre-escaped).
1885 - * @param string $dismiss_text The dismiss button text (pre-escaped).
1886 - * @param int $snooze_duration Snooze duration in seconds for the data-repeat-notice-after attribute.
1887 - * @param bool $external_cta Whether the CTA opens in a new tab and also dismisses the notice
1888 - * via the astra-notice-close class. Default false.
1889 - * @return string The notice HTML markup.
1890 - */
1891 - private function build_notice_markup( $heading, $message, $cta_url, $cta_text, $snooze_text, $dismiss_text, $snooze_duration, $external_cta = false ) {
1892 - $image_path = esc_url( SRFM_URL . 'admin/assets/sureforms-logo.png' );
1893 - $cta_class = $external_cta ? 'astra-notice-close button-primary' : 'button-primary';
1894 - $cta_attrs = $external_cta ? ' target="_blank" rel="noopener noreferrer"' : '';
1895 -
1896 - return sprintf(
1897 - '<div class="notice-image">
1898 - <img src="%1$s" class="custom-logo" alt="SureForms" itemprop="logo">
1899 - </div>
1900 - <div class="notice-content">
1901 - <div class="notice-heading">
1902 - %2$s
1903 - </div>
1904 - %3$s<br />
1905 - <div class="astra-review-notice-container">
1906 - <a href="%4$s" class="%5$s"%6$s>
1907 - %7$s
1908 - </a>
1909 - <span class="dashicons dashicons-clock" aria-hidden="true"></span>
1910 - <a href="#" data-repeat-notice-after="%8$s" class="astra-notice-close">
1911 - %9$s
1912 - </a>
1913 - <span class="dashicons dashicons-smiley" aria-hidden="true"></span>
1914 - <a href="#" class="astra-notice-close">
1915 - %10$s
1916 - </a>
1917 - </div>
1918 - </div>',
1919 - $image_path,
1920 - $heading,
1921 - $message,
1922 - $cta_url,
1923 - esc_attr( $cta_class ),
1924 - $cta_attrs,
1925 - $cta_text,
1926 - $snooze_duration,
1927 - $snooze_text,
1928 - $dismiss_text
1929 - );
1930 - }
1931 -
1932 - /**
1933 - * Callback for displaying the rating notice conditionally.
1934 - *
1935 - * Returns true if the user has 3 or more published forms or 3 or more form entries.
1936 - *
1937 - * @since 2.5.2
1938 - * @return bool
1939 - */
1940 - private function maybe_display_rating_notice() {
1941 - if ( null === $this->should_show_rating ) {
1942 - $entries_count = Entries::get_total_entries_by_status( 'all' );
1943 - $form_count = wp_count_posts( SRFM_FORMS_POST_TYPE );
1944 - $this->should_show_rating = $entries_count >= self::RATING_NOTICE_THRESHOLD || Helper::get_integer_value( $form_count->publish ?? 0 ) >= self::RATING_NOTICE_THRESHOLD;
1945 - }
1946 -
1947 - return $this->should_show_rating;
1948 - }
1949 -
1950 - /**
1951 - * Get random premium feature text.
1952 - *
1953 - * @return string Random feature text.
1954 - * @since 1.9.1
1955 - */
1956 - private function get_random_premium_feature_text() {
1957 - $features = [
1958 - __( 'Use Conditional Logic to show only what matters', 'sureforms' ),
1959 - __( 'Split your form into steps to keep it easy', 'sureforms' ),
1960 - __( 'Let people upload files directly to your form', 'sureforms' ),
1961 - __( 'Turn responses into downloadable PDFs automatically', 'sureforms' ),
1962 - __( 'Let users sign with a simple signature field', 'sureforms' ),
1963 - __( 'Connect your form to other tools using webhooks', 'sureforms' ),
1964 - __( 'Use Conversational Forms for a chat-like experience', 'sureforms' ),
1965 - __( 'Let users register or log in through your form', 'sureforms' ),
1966 - __( 'Build forms that create WordPress user accounts', 'sureforms' ),
1967 - __( 'Add calculations to auto-total scores or prices', 'sureforms' ),
1968 - ];
1969 -
1970 - // Get a random feature.
1971 - $random_key = array_rand( $features );
1972 - return $features[ $random_key ];
1973 - }
1974 -
1975 - /**
1976 - * Render the dashboard widget footer for upsell.
1977 - *
1978 - * @param array $entries_data The entries data array.
1979 - * @return void
1980 - * @since 1.9.1
1981 - */
1982 - private function render_dashboard_widget_footer( $entries_data ) {
1983 - // Only show footer if Pro is not active.
1984 - if ( Helper::has_pro() ) {
1985 - return;
1986 - }
1987 -
1988 - // Count total entries in last 7 days.
1989 - $total_entries = 0;
1990 - foreach ( $entries_data as $form_data ) {
1991 - $total_entries += $form_data['count'];
1992 - }
1993 -
1994 - // Count total published forms.
1995 - $published_forms_count = wp_count_posts( SRFM_FORMS_POST_TYPE )->publish;
1996 -
1997 - // Show footer only if 3+ entries received OR 3+ forms published.
1998 - if ( $total_entries >= 3 || $published_forms_count >= 3 ) {
1999 - ?>
2000 - <div class="srfm-widget-footer">
2001 - <div class="srfm-upgrade-content">
2002 - <svg class="srfm-logo-icon" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2003 - <rect width="20" height="20" fill="#D54407"/>
2004 - <path d="M5.7139 4.2854H14.2853V7.1425H7.1424L5.7139 8.5711V7.1425V4.2854Z" fill="white"/>
2005 - <path d="M5.7139 4.2854H14.2853V7.1425H7.1424L5.7139 8.5711V7.1425V4.2854Z" fill="white"/>
2006 - <path d="M5.7148 8.5713H12.8577V11.4284H7.1434L5.7148 12.857V11.4284V8.5713Z" fill="white"/>
2007 - <path d="M5.7148 8.5713H12.8577V11.4284H7.1434L5.7148 12.857V11.4284V8.5713Z" fill="white"/>
2008 - <path d="M5.7148 12.8569H10.0006V15.7141H5.7148V12.8569Z" fill="white"/>
2009 - <path d="M5.7148 12.8569H10.0006V15.7141H5.7148V12.8569Z" fill="white"/>
2010 - </svg>
2011 - <span><?php echo esc_html( $this->get_random_premium_feature_text() ); ?></span>
2012 - </div>
2013 - <?php
2014 - $upgrade_url = add_query_arg(
2015 - [
2016 - 'utm_medium' => 'dashboard-widget',
2017 - ],
2018 - Helper::get_sureforms_website_url( 'pricing' )
2019 - );
2020 - ?>
2021 - <a href="<?php echo esc_url( $upgrade_url ); ?>" class="srfm-upgrade-link" target="_blank">
2022 - <?php esc_html_e( 'Upgrade', 'sureforms' ); ?>
2023 - </a>
2024 - </div>
2025 - <?php
2026 - }
2027 - }
2028 -
2029 - /**
2030 - * Determine if the admin pointer should be visible on this page.
2031 - *
2032 - * @since 1.8.0
2033 - * @return bool
2034 - */
2035 - private function is_admin_pointer_visible() {
2036 - global $pagenow;
2037 - $allowed_pages = [ 'index.php', 'options-general.php' ];
2038 -
2039 - // Do not show if pointer dismissed, accepted, or more than 1 form exists.
2040 - if (
2041 - ! empty( Helper::get_srfm_option( 'pointer_popup_dismissed' ) )
2042 - || ! empty( Helper::get_srfm_option( 'pointer_popup_accepted' ) )
2043 - || (int) ( wp_count_posts( SRFM_FORMS_POST_TYPE )->publish ?? 0 ) > 1
2044 - ) {
2045 - return false;
2046 - }
2047 -
2048 - if ( in_array( $pagenow, $allowed_pages, true ) ) {
2049 - return true;
2050 - }
2051 -
2052 - return false;
2053 - }
2054 -
2055 544 }