PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 1.5.1
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v1.5.1
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 +186 -1375 2.8.21.5.1 View file →
@@ -6,24 +6,19 @@
6 6 */
7 7
8 8 namespace SRFM\Admin;
9 9
10 -use Astra_Notices;
10 +use SRFM\Admin\Views\Entries_List_Table;
11 +use SRFM\Admin\Views\Single_Entry;
11 12 use SRFM\Inc\AI_Form_Builder\AI_Helper;
12 13 use SRFM\Inc\Database\Tables\Entries;
13 14 use SRFM\Inc\Helper;
14 -use SRFM\Inc\Onboarding;
15 -use SRFM\Inc\Payments\Payment_Helper;
16 -use SRFM\Inc\Payments\Stripe\Stripe_Helper;
15 +use SRFM\Inc\Post_Types;
17 16 use SRFM\Inc\Traits\Get_Instance;
18 17
19 18 if ( ! defined( 'ABSPATH' ) ) {
20 19 exit; // Exit if accessed directly.
21 20 }
22 -
23 -if ( ! class_exists( 'BSF_Admin_Notices' ) ) {
24 - require_once SRFM_DIR . 'inc/lib/astra-notices/class-bsf-admin-notices.php';
25 -}
26 21 /**
27 22 * Admin handler class.
28 23 *
29 24 * @since 0.0.1
@@ -31,39 +26,8 @@
31 26 class Admin {
32 27 use Get_Instance;
33 28
34 29 /**
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 30 * Class constructor.
67 31 *
68 32 * @return void
69 33 * @since 0.0.1
@@ -71,18 +35,9 @@
71 35 public function __construct() {
72 36 add_action( 'admin_menu', [ $this, 'add_menu_page' ], 9 );
73 37 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
74 38 add_action( 'admin_menu', [ $this, 'settings_page' ] );
75 - add_action( 'admin_menu', [ $this, 'add_learn_page' ] );
76 39 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 40 add_filter( 'plugin_action_links', [ $this, 'add_settings_link' ], 10, 2 );
86 41 add_action( 'enqueue_block_assets', [ $this, 'enqueue_styles' ] );
87 42 add_action( 'admin_head', [ $this, 'enqueue_header_styles' ] );
88 43 add_filter( 'admin_body_class', [ $this, 'admin_template_picker_body_class' ] );
@@ -90,138 +45,32 @@
90 45 // this action is used to restrict Spectra's quick action bar on SureForms CPTS.
91 46 add_action( 'uag_enable_quick_action_sidebar', [ $this, 'restrict_spectra_quick_action_bar' ] );
92 47
93 48 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 49 add_action( 'admin_notices', [ $this, 'srfm_pro_version_compatibility' ] );
98 50
51 + // Handle entry actions.
52 + add_action( 'admin_init', [ $this, 'handle_entry_actions' ] );
53 + add_action( 'admin_notices', [ Entries_List_Table::class, 'display_bulk_action_notice' ] );
54 +
55 + // This action enqueues translations for NPS Survey library.
56 + // A better solution will be required from library to resolve plugin conflict.
57 + add_action(
58 + 'admin_footer',
59 + static function() {
60 + Helper::register_script_translations( 'nps-survey-script' );
61 + },
62 + 1000
63 + );
99 64 // Enfold theme compatibility to enable block editor for SureForms post type.
100 65 add_filter( 'avf_use_block_editor_for_post', [ $this, 'enable_block_editor_in_enfold_theme' ] );
101 66
102 67 // Add action links to the plugin page.
103 68 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 69 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 70 }
129 71
130 72 /**
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 73 * Show action on plugin page.
225 74 *
226 75 * @param array $links links.
227 76 * @return array
@@ -227,9 +76,9 @@
227 76 * @return array
228 77 * @since 1.4.2
229 78 */
230 79 public function add_action_links( $links ) {
231 - if ( ! Helper::has_pro() ) {
80 + if ( ! defined( 'SRFM_PRO_FILE' ) && ! file_exists( WP_PLUGIN_DIR . '/sureforms-pro/sureforms-pro.php' ) ) {
232 81 // Display upsell link if SureForms Pro is not installed.
233 82 $upsell_link = add_query_arg(
234 83 [
235 84 'utm_medium' => 'plugin-list',
@@ -235,16 +84,9 @@
235 84 'utm_medium' => 'plugin-list',
236 85 ],
237 86 Helper::get_sureforms_website_url( 'pricing' )
238 87 );
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() );
88 + $links[] = '<a href="' . esc_url( $upsell_link ) . '" target="_blank" rel="noreferrer" class="sureforms-plugins-go-pro">' . esc_html__( 'Get SureForms Pro', 'sureforms' ) . '</a>';
247 89 }
248 90
249 91 return $links;
250 92 }
@@ -312,15 +154,20 @@
312 154 * @return void
313 155 * @since 0.0.1
314 156 */
315 157 public function add_menu_page() {
316 - $menu_slug = 'sureforms_menu';
158 + if ( ! current_user_can( 'manage_options' ) ) {
159 + return;
160 + }
317 161
162 + $capability = 'manage_options';
163 + $menu_slug = 'sureforms_menu';
164 +
318 165 $logo = file_get_contents( plugin_dir_path( SRFM_FILE ) . 'images/icon.svg' );
319 166 add_menu_page(
320 167 __( 'SureForms', 'sureforms' ),
321 168 __( 'SureForms', 'sureforms' ),
322 - self::$sureforms_page_default_capability,
169 + 'edit_others_posts',
323 170 $menu_slug,
324 171 static function () {
325 172 },
326 173 'data:image/svg+xml;base64,' . base64_encode( $logo ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
@@ -331,9 +178,9 @@
331 178 add_submenu_page(
332 179 $menu_slug,
333 180 __( 'Dashboard', 'sureforms' ),
334 181 __( 'Dashboard', 'sureforms' ),
335 - self::$sureforms_page_default_capability,
182 + $capability,
336 183 $menu_slug,
337 184 [ $this, 'render_dashboard' ]
338 185 );
339 186 }
@@ -349,9 +196,9 @@
349 196 add_submenu_page(
350 197 'sureforms_menu',
351 198 __( 'Settings', 'sureforms' ),
352 199 __( 'Settings', 'sureforms' ),
353 - self::$sureforms_page_default_capability,
200 + 'edit_others_posts',
354 201 'sureforms_form_settings',
355 202 $callback
356 203 );
357 204
@@ -364,162 +211,8 @@
364 211 }
365 212 }
366 213
367 214 /**
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 215 * Render Admin Dashboard.
523 216 *
524 217 * @return void
525 218 * @since 0.0.1
@@ -524,11 +217,9 @@
524 217 * @return void
525 218 * @since 0.0.1
526 219 */
527 220 public function render_dashboard() {
528 - ?>
529 - <div id="srfm-dashboard-container" class="srfm-admin-wrapper"></div>
530 - <?php
221 + echo '<div id="srfm-dashboard-container"></div>';
531 222 }
532 223
533 224 /**
534 225 * Settings page callback.
@@ -536,43 +227,12 @@
536 227 * @return void
537 228 * @since 0.0.1
538 229 */
539 230 public function settings_page_callback() {
540 - ?>
541 - <div id="srfm-settings-container" class="srfm-admin-wrapper"></div>
542 - <?php
231 + echo '<div id="srfm-settings-container"></div>';
543 232 }
544 233
545 234 /**
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 235 * Add new form menu item.
576 236 *
577 237 * @return void
578 238 * @since 0.0.1
@@ -579,62 +239,27 @@
579 239 */
580 240 public function add_new_form() {
581 241 add_submenu_page(
582 242 '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 243 __( 'New Form', 'sureforms' ),
593 244 __( 'New Form', 'sureforms' ),
594 - self::$sureforms_page_default_capability,
245 + 'edit_others_posts',
595 246 'add-new-form',
596 247 [ $this, 'add_new_form_callback' ],
597 248 2
598 249 );
599 - $entries_hook = add_submenu_page(
250 + add_submenu_page(
600 251 'sureforms_menu',
601 252 __( 'Entries', 'sureforms' ),
602 253 __( 'Entries', 'sureforms' ),
603 - self::$sureforms_page_default_capability,
254 + 'edit_others_posts',
604 255 SRFM_ENTRIES,
605 256 [ $this, 'render_entries' ],
606 257 3
607 258 );
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 259 }
623 260
624 261 /**
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 262 * Add new form mentu item callback.
638 263 *
639 264 * @return void
640 265 * @since 0.0.1
@@ -639,109 +264,44 @@
639 264 * @return void
640 265 * @since 0.0.1
641 266 */
642 267 public function add_new_form_callback() {
643 - ?>
644 - <div id="srfm-add-new-form-container" class="srfm-admin-wrapper"></div>
645 - <?php
268 + echo '<div id="srfm-add-new-form-container"></div>';
646 269 }
647 270
648 271 /**
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 272 * Entries page callback.
662 273 *
663 274 * @since 0.0.13
664 - * @since 2.0.0 - Updated the entries UI and the function definition.
665 275 * @return void
666 276 */
667 277 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() ) {
278 + // Render single entry view.
279 + // Adding the phpcs ignore nonce verification as no database operations are performed in this function, it is used to display the single entry view.
280 + if ( isset( $_GET['entry_id'] ) && is_numeric( $_GET['entry_id'] ) && isset( $_GET['view'] ) && 'details' === $_GET['view'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not needed here and explained in the comments above as well.
281 + $single_entry_view = new Single_Entry();
282 + $single_entry_view->render();
679 283 return;
680 284 }
681 285
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();
286 + // Render all entries view.
287 + $entries_table = new Entries_List_Table();
288 + $entries_table->prepare_items();
289 + echo '<div class="wrap"><h1 class="wp-heading-inline">' . esc_html__( 'Entries', 'sureforms' ) . '</h1>';
290 + if ( empty( $entries_table->all_entries_count ) && empty( $entries_table->trash_entries_count ) ) {
291 + $instance = Post_Types::get_instance();
292 + $instance->sureforms_render_blank_state( SRFM_ENTRIES );
293 + $instance->get_blank_state_styles();
685 294 return;
686 295 }
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 - }
296 + echo '<form method="get">';
297 + echo '<input type="hidden" name="page" value="sureforms_entries">';
298 + $entries_table->display();
299 + echo '</form>';
300 + echo '</div>';
727 301 }
728 302
729 303 /**
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 304 * Adds a settings link to the plugin action links on the plugins page.
745 305 *
746 306 * @param array $links An array of plugin action links.
747 307 * @param string $file The plugin file path.
@@ -749,22 +309,15 @@
749 309 * @since 0.0.1
750 310 */
751 311 public function add_settings_link( $links, $file ) {
752 312 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(
313 + $plugin_links = apply_filters(
761 314 'sureforms_plugin_action_links',
762 315 [
763 - 'sureforms_settings' => $settings_link_html,
316 + 'sureforms_settings' => '<a href="' . esc_url( admin_url( 'admin.php?page=sureforms_form_settings&tab=general-settings' ) ) . '">' . esc_html__( 'Settings', 'sureforms' ) . '</a>',
764 317 ]
765 318 );
766 - $links = array_merge( $plugin_links, $links );
319 + $links = array_merge( $plugin_links, $links );
767 320 }
768 321 return $links;
769 322 }
770 323
@@ -874,8 +427,9 @@
874 427 global $wp_version;
875 428
876 429 $file_prefix = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? '' : '.min';
877 430 $dir_name = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? 'unminified' : 'minified';
431 + $js_uri = SRFM_URL . 'assets/js/' . $dir_name . '/';
878 432 $css_uri = SRFM_URL . 'assets/css/' . $dir_name . '/';
879 433 $is_rtl = is_rtl();
880 434 $rtl = $is_rtl ? '-rtl' : '';
881 435
@@ -882,119 +436,30 @@
882 436 /**
883 437 * List of the handles in which we need to add translation compatibility.
884 438 */
885 439 $script_translations_handlers = [];
886 - $onboarding_instance = Onboarding::get_instance();
887 - $current_user = wp_get_current_user();
888 440
889 441 $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' ) ),
442 + 'site_url' => get_site_url(),
443 + 'breadcrumbs' => $this->get_breadcrumbs_for_current_page(),
444 + 'sureforms_dashboard_url' => admin_url( '/admin.php?page=sureforms_menu' ),
445 + 'plugin_version' => SRFM_VER,
446 + 'global_settings_nonce' => current_user_can( 'manage_options' ) ? wp_create_nonce( 'wp_rest' ) : '',
447 + 'is_pro_active' => defined( 'SRFM_PRO_VER' ),
448 + 'pro_plugin_version' => defined( 'SRFM_PRO_VER' ) ? SRFM_PRO_VER : '',
449 + 'pro_plugin_name' => defined( 'SRFM_PRO_VER' ) && defined( 'SRFM_PRO_PRODUCT' ) ? SRFM_PRO_PRODUCT : 'SureForms Pro',
450 + 'sureforms_pricing_page' => Helper::get_sureforms_website_url( 'pricing' ),
451 + 'field_spacing_vars' => Helper::get_css_vars(),
452 + 'is_ver_lower_than_6_7' => version_compare( $wp_version, '6.6.2', '<=' ),
947 453 ];
948 454
949 455 $is_screen_sureforms_menu = Helper::validate_request_context( 'sureforms_menu', 'page' );
950 456 $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 457 $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 458 $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 459 $is_post_type_sureforms_form = SRFM_FORMS_POST_TYPE === $current_screen->post_type;
959 460
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 - ];
969 - }
970 -
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 ) {
461 + if ( $is_screen_sureforms_menu || $is_post_type_sureforms_form || $is_screen_add_new_form || $is_screen_sureforms_form_settings || $is_screen_sureforms_entries ) {
997 462 $asset_handle = '-dashboard';
998 463
999 464 wp_enqueue_style( SRFM_SLUG . $asset_handle . '-font', 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap', [], SRFM_VER );
1000 465
@@ -1022,9 +487,9 @@
1022 487 update_option( 'srfm_pro_license_status', $current_license_status );
1023 488 }
1024 489 }
1025 490
1026 - $localization_data['security_settings_url'] = admin_url( '/admin.php?page=sureforms_form_settings&tab=security-settings&subpage=recaptcha' );
491 + $localization_data['security_settings_url'] = admin_url( '/admin.php?page=sureforms_form_settings&tab=security-settings' );
1027 492 $localization_data['integration_settings_url'] = admin_url( '/admin.php?page=sureforms_form_settings&tab=integration-settings' );
1028 493 wp_localize_script(
1029 494 SRFM_SLUG . $asset_handle,
1030 495 SRFM_SLUG . '_admin',
@@ -1033,12 +498,27 @@
1033 498 $localization_data
1034 499 )
1035 500 );
1036 501 wp_enqueue_style( SRFM_SLUG . '-dashboard', SRFM_URL . 'assets/build/dashboard.css', [], SRFM_VER, 'all' );
502 +
1037 503 }
1038 504
1039 - if ( $is_screen_sureforms_form_settings || $is_screen_sureforms_forms ) {
505 + if ( $is_screen_sureforms_form_settings ) {
1040 506 wp_enqueue_style( SRFM_SLUG . '-settings', $css_uri . 'backend/settings' . $file_prefix . $rtl . '.css', [], SRFM_VER );
507 +
508 + // if version is equal to or lower than 6.6.2 then add compatibility css.
509 + if ( version_compare( $wp_version, '6.6.2', '<=' ) ) {
510 + $srfm_inline_css = '
511 + .srfm-settings-page-container
512 + .components-toggle-control {
513 + .components-base-control__help{
514 + margin-left: 4em;
515 + }
516 + }
517 + }
518 + ';
519 + wp_add_inline_style( SRFM_SLUG . '-settings', $srfm_inline_css );
520 + }
1041 521 }
1042 522
1043 523 // Enqueue styles for the entries page.
1044 524 if ( $is_screen_sureforms_entries ) {
@@ -1044,140 +524,30 @@
1044 524 if ( $is_screen_sureforms_entries ) {
1045 525 $asset_handle = '-entries';
1046 526 wp_enqueue_script( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/entries.js', $script_info['dependencies'], SRFM_VER, true );
1047 527
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 528 $script_translations_handlers[] = SRFM_SLUG . $asset_handle;
1057 529 }
1058 530
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 );
531 + // Admin Submenu Styles.
532 + wp_enqueue_style( SRFM_SLUG . '-admin', $css_uri . 'backend/admin' . $file_prefix . $rtl . '.css', [], SRFM_VER );
1063 533
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 - }
534 + if ( 'edit-' . SRFM_FORMS_POST_TYPE === $current_screen->id ) {
535 + $asset_handle = 'page_header';
1074 536
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 537 $script_asset_path = SRFM_DIR . 'assets/build/' . $asset_handle . '.asset.php';
1107 538 $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',
539 + ? include $script_asset_path
540 + : [
541 + 'dependencies' => [],
542 + 'version' => SRFM_VER,
1127 543 ];
544 + wp_enqueue_script( SRFM_SLUG . '-form-page-header', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
545 + wp_enqueue_style( SRFM_SLUG . '-form-archive-styles', $css_uri . 'form-archive-styles' . $file_prefix . $rtl . '.css', [], SRFM_VER );
1128 546
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';
547 + $script_translations_handlers[] = SRFM_SLUG . '-form-page-header';
1139 548 }
1140 549
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 550 if ( $is_screen_sureforms_form_settings ) {
1181 551 $asset_handle = 'settings';
1182 552
1183 553 $script_asset_path = SRFM_DIR . 'assets/build/' . $asset_handle . '.asset.php';
@@ -1188,20 +558,46 @@
1188 558 'version' => SRFM_VER,
1189 559 ];
1190 560
1191 561 wp_enqueue_script( SRFM_SLUG . '-settings', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
562 + wp_enqueue_style( SRFM_SLUG . '-setting-styles', SRFM_URL . 'assets/build/' . $asset_handle . '.css', [ 'wp-components' ], SRFM_VER, 'all' );
1192 563 wp_localize_script(
1193 564 SRFM_SLUG . '-settings',
1194 565 SRFM_SLUG . '_admin',
1195 - apply_filters(
1196 - SRFM_SLUG . '_admin_filter',
1197 - $localization_data
1198 - )
566 + $localization_data
1199 567 );
1200 568
1201 569 $script_translations_handlers[] = SRFM_SLUG . '-settings';
1202 570 }
571 + if ( 'edit-' . SRFM_FORMS_POST_TYPE === $current_screen->id ) {
572 + wp_enqueue_script( SRFM_SLUG . '-form-archive', $js_uri . 'form-archive' . $file_prefix . '.js', [], SRFM_VER, true );
573 + wp_enqueue_script( SRFM_SLUG . '-export', $js_uri . 'export' . $file_prefix . '.js', [ 'wp-i18n' ], SRFM_VER, true );
574 + wp_localize_script(
575 + SRFM_SLUG . '-export',
576 + SRFM_SLUG . '_export',
577 + [
578 + 'ajaxurl' => admin_url( 'admin-ajax.php' ),
579 + 'srfm_export_nonce' => wp_create_nonce( 'export_form_nonce' ),
580 + 'site_url' => get_site_url(),
581 + 'import_form_nonce' => current_user_can( 'edit_posts' ) ? wp_create_nonce( 'wp_rest' ) : '',
582 + 'import_btn_string' => __( 'Import Form', 'sureforms' ),
583 + ]
584 + );
1203 585
586 + wp_enqueue_script( SRFM_SLUG . '-backend', $js_uri . 'backend' . $file_prefix . '.js', [], SRFM_VER, true );
587 + wp_localize_script(
588 + SRFM_SLUG . '-backend',
589 + SRFM_SLUG . '_backend',
590 + [
591 + 'site_url' => get_site_url(),
592 + ]
593 + );
594 +
595 + $script_translations_handlers[] = SRFM_SLUG . '-form-archive';
596 + $script_translations_handlers[] = SRFM_SLUG . '-export';
597 + $script_translations_handlers[] = SRFM_SLUG . '-backend';
598 + }
599 +
1204 600 if ( $is_screen_add_new_form ) {
1205 601 wp_enqueue_style( SRFM_SLUG . '-template-picker', $css_uri . 'template-picker' . $file_prefix . $rtl . '.css', [], SRFM_VER );
1206 602
1207 603 $sureforms_admin = 'templatePicker';
@@ -1220,18 +616,18 @@
1220 616 SRFM_SLUG . '_admin',
1221 617 [
1222 618 'site_url' => get_site_url(),
1223 619 'plugin_url' => SRFM_URL,
620 + 'preview_images_url' => SRFM_URL . 'images/template-previews/',
1224 621 'admin_url' => admin_url( 'admin.php' ),
1225 622 '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(),
623 + 'capability' => current_user_can( 'edit_posts' ),
624 + 'template_picker_nonce' => current_user_can( 'edit_posts' ) ? wp_create_nonce( 'wp_rest' ) : '',
625 + 'is_pro_active' => defined( 'SRFM_PRO_VER' ),
1229 626 'srfm_ai_usage_details' => AI_Helper::get_current_usage_details(),
1230 627 'is_pro_license_active' => AI_Helper::is_pro_license_active(),
1231 628 'srfm_ai_auth_user_email' => get_option( 'srfm_ai_auth_user_email' ),
1232 629 'pricing_page_url' => Helper::get_sureforms_website_url( 'pricing' ),
1233 - 'licensing_nonce' => wp_create_nonce( 'srfm_pro_licensing_nonce' ),
1234 630 ]
1235 631 );
1236 632
1237 633 $script_translations_handlers[] = SRFM_SLUG . '-template-picker';
@@ -1246,9 +642,8 @@
1246 642 'srfm/checkbox',
1247 643 'srfm/number',
1248 644 'srfm/inline-button',
1249 645 'srfm/advanced-heading',
1250 - 'srfm/payment',
1251 646 ]
1252 647 );
1253 648 if ( ! is_array( $default_allowed_quick_sidebar_blocks ) ) {
1254 649 $default_allowed_quick_sidebar_blocks = [];
@@ -1260,25 +655,22 @@
1260 655 }
1261 656 $quick_sidebar_allowed_blocks = get_option( 'srfm_quick_sidebar_allowed_blocks' );
1262 657 $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 658 $srfm_ajax_nonce = wp_create_nonce( 'srfm_ajax_nonce' );
659 + wp_enqueue_script( SRFM_SLUG . '-quick-action-siderbar', SRFM_URL . 'assets/build/quickActionSidebar.js', [], SRFM_VER, true );
660 + wp_localize_script(
661 + SRFM_SLUG . '-quick-action-siderbar',
662 + SRFM_SLUG . '_quick_sidebar_blocks',
663 + [
664 + 'allowed_blocks' => $quick_sidebar_allowed_blocks,
665 + 'srfm_enable_quick_action_sidebar' => $srfm_enable_quick_action_sidebar,
666 + 'srfm_ajax_nonce' => $srfm_ajax_nonce,
667 + 'srfm_ajax_url' => admin_url( 'admin-ajax.php' ),
668 + ]
669 + );
1264 670
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 - );
671 + $script_translations_handlers[] = SRFM_SLUG . '-quick-action-siderbar';
1277 672
1278 - $script_translations_handlers[] = SRFM_SLUG . '-quick-action-siderbar';
1279 - }
1280 -
1281 673 /**
1282 674 * Enqueuing SureTriggers Integration script.
1283 675 * This script loads suretriggers iframe in Intergations tab.
1284 676 */
@@ -1350,53 +742,40 @@
1350 742
1351 743 return $status;
1352 744 }
1353 745
746 + // Entries methods.
747 +
1354 748 /**
1355 - * Register Pro compatibility notices early for React pages.
749 + * Handle entry actions.
1356 750 *
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 - *
751 + * @since 0.0.13
1363 752 * @return void
1364 - * @since 2.5.0
1365 753 */
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' ) ) {
754 + public function handle_entry_actions() {
755 + Entries_List_Table::process_bulk_actions();
756 +
757 + if ( ! isset( $_GET['page'] ) || SRFM_ENTRIES !== $_GET['page'] ) {
1369 758 return;
1370 759 }
1371 -
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 - );
760 + if ( ! isset( $_GET['entry_id'] ) || ! isset( $_GET['action'] ) ) {
761 + return;
1398 762 }
763 + if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'srfm_entries_action' ) ) {
764 + wp_die( esc_html__( 'Nonce verification failed.', 'sureforms' ) );
765 + }
766 + $action = isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : '';
767 + $entry_id = Helper::get_integer_value( sanitize_text_field( wp_unslash( $_GET['entry_id'] ) ) );
768 + $view = isset( $_GET['view'] ) ? sanitize_text_field( wp_unslash( $_GET['view'] ) ) : '';
769 + if ( $entry_id > 0 ) {
770 + if ( 'read' === $action && 'details' === $view ) {
771 + $entry_status = Entries::get( $entry_id )['status'];
772 + if ( 'trash' === $entry_status ) {
773 + wp_die( esc_html__( 'You cannot view this entry because it is in trash.', 'sureforms' ) );
774 + }
775 + }
776 + Entries_List_Table::handle_entry_status( $entry_id, $action, $view );
777 + }
1399 778 }
1400 779
1401 780 /**
1402 781 * Admin Notice Callback if sureforms pro is out of date.
@@ -1406,9 +785,10 @@
1406 785 * @return void
1407 786 * @since 1.0.4
1408 787 */
1409 788 public function srfm_pro_version_compatibility() {
1410 - if ( ! Helper::has_pro() ) {
789 + $plugin_file = 'sureforms-pro/sureforms-pro.php';
790 + if ( ! is_plugin_active( $plugin_file ) || ! defined( 'SRFM_PRO_VER' ) ) {
1411 791 return;
1412 792 }
1413 793
1414 794 if ( empty( get_current_screen() ) ) {
@@ -1414,9 +794,9 @@
1414 794 if ( empty( get_current_screen() ) ) {
1415 795 return;
1416 796 }
1417 797
1418 - if ( ! Helper::current_user_can() ) {
798 + if ( ! current_user_can( 'update_plugins' ) ) {
1419 799 return;
1420 800 }
1421 801
1422 802 $srfm_pro_license_status = get_option( 'srfm_pro_license_status', '' );
@@ -1432,214 +812,36 @@
1432 812 $pro_plugin_name = defined( 'SRFM_PRO_PRODUCT' ) ? SRFM_PRO_PRODUCT : 'SureForms Pro';
1433 813 $message = '';
1434 814 $url = admin_url( 'admin.php?page=sureforms_form_settings&tab=account-settings' );
1435 815 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();
816 + $message = '<p>' . sprintf(
817 + // translators: %1$s: Opening anchor tag with URL, %2$s: Closing anchor tag, %3$s: SureForms Pro Plugin Name.
818 + esc_html__( 'Please %1$sactivate%2$s your copy of %3$s to get new features, access support, receive update notifications, and more.', 'sureforms' ),
819 + '<a href="' . esc_url( $url ) . '">',
820 + '</a>',
821 + '<i>' . esc_html( $pro_plugin_name ) . '</i>'
822 + ) . '</p>';
1451 823 }
1452 824
1453 825 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();
826 + $message .= '<p>' . sprintf(
827 + // 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.
828 + 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' ),
829 + esc_html( SRFM_VER ),
830 + esc_html( $pro_plugin_name ),
831 + esc_html( SRFM_PRO_RECOMMENDED_VER ),
832 + '<a href=' . esc_url( admin_url( 'update-core.php' ) ) . '>',
833 + '</a>'
834 + ) . '</p>';
1471 835 }
1472 836
1473 837 if ( ! empty( $message ) ) {
1474 838 // 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
839 + echo '<div class="notice notice-warning">' . wp_kses_post( $message ) . '</div>';
1478 840 }
1479 841 }
1480 842
1481 843 /**
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 844 * Disables the capabilities for WPForms to avoid conflicts when enqueueing
1643 845 * scripts and styles for WPForms.
1644 846 *
1645 847 * This function is intended to prevent any potential conflicts that may arise
@@ -1660,396 +862,5 @@
1660 862 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1661 863 $post_type = $post_id ? get_post_type( $post_id ) : sanitize_text_field( wp_unslash( $_REQUEST['post_type'] ?? '' ) );
1662 864 return SRFM_FORMS_POST_TYPE === $post_type ? false : $user_can;
1663 865 }
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 866 }