PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 1.7.3
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v1.7.3
2.12.6 2.12.5 2.12.4 2.12.3 2.12.2 2.12.1 2.12.0 2.11.1 2.11.0 2.10.1 2.10.0 2.9.1 2.9.0 2.8.2 2.8.1 2.7.0 2.7.1 2.8.0 trunk 0.0.10 0.0.11 0.0.12 0.0.13 0.0.2 0.0.3 All 96 releases
sureforms / admin / admin.php
admin.php
1,069 lines 38.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Admin Class.
4 *
5 * @package sureforms.
6 */
7
8 namespace SRFM\Admin;
9
10 use SRFM\Admin\Views\Entries_List_Table;
11 use SRFM\Admin\Views\Single_Entry;
12 use SRFM\Inc\AI_Form_Builder\AI_Helper;
13 use SRFM\Inc\Database\Tables\Entries;
14 use SRFM\Inc\Helper;
15 use SRFM\Inc\Post_Types;
16 use SRFM\Inc\Traits\Get_Instance;
17
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit; // Exit if accessed directly.
20 }
21 /**
22 * Admin handler class.
23 *
24 * @since 0.0.1
25 */
26 class Admin {
27 use Get_Instance;
28
29 /**
30 * Class constructor.
31 *
32 * @return void
33 * @since 0.0.1
34 */
35 public function __construct() {
36 add_action( 'admin_menu', [ $this, 'add_menu_page' ], 9 );
37 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
38 add_action( 'admin_menu', [ $this, 'settings_page' ] );
39 add_action( 'admin_menu', [ $this, 'add_new_form' ] );
40 add_action( 'admin_menu', [ $this, 'add_suremail_page' ] );
41 if ( ! defined( 'SRFM_PRO_VER' ) ) {
42 add_action( 'admin_menu', [ $this, 'add_upgrade_to_pro' ] );
43 add_action( 'admin_footer', [ $this, 'add_upgrade_to_pro_target_attr' ] );
44 }
45
46 add_filter( 'plugin_action_links', [ $this, 'add_settings_link' ], 10, 2 );
47 add_action( 'enqueue_block_assets', [ $this, 'enqueue_styles' ] );
48 add_action( 'admin_head', [ $this, 'enqueue_header_styles' ] );
49 add_filter( 'admin_body_class', [ $this, 'admin_template_picker_body_class' ] );
50
51 // this action is used to restrict Spectra's quick action bar on SureForms CPTS.
52 add_action( 'uag_enable_quick_action_sidebar', [ $this, 'restrict_spectra_quick_action_bar' ] );
53
54 add_action( 'current_screen', [ $this, 'enable_gutenberg_for_sureforms' ], 100 );
55 add_action( 'admin_notices', [ $this, 'srfm_pro_version_compatibility' ] );
56
57 // Handle entry actions.
58 add_action( 'admin_init', [ $this, 'handle_entry_actions' ] );
59 add_action( 'admin_notices', [ Entries_List_Table::class, 'display_bulk_action_notice' ] );
60
61 // This action enqueues translations for NPS Survey library.
62 // A better solution will be required from library to resolve plugin conflict.
63 add_action(
64 'admin_footer',
65 static function() {
66 Helper::register_script_translations( 'nps-survey-script' );
67 },
68 1000
69 );
70 // Enfold theme compatibility to enable block editor for SureForms post type.
71 add_filter( 'avf_use_block_editor_for_post', [ $this, 'enable_block_editor_in_enfold_theme' ] );
72
73 // Add action links to the plugin page.
74 add_filter( 'plugin_action_links_' . SRFM_BASENAME, [ $this, 'add_action_links' ] );
75 // Check if admin notification is enabled and add entries badge.
76 $general_options = get_option( 'srfm_general_settings_options', [] );
77 $admin_notification_on = isset( $general_options['srfm_admin_notification'] ) ? (bool) $general_options['srfm_admin_notification'] : true;
78
79 if ( $admin_notification_on ) {
80 add_action( 'admin_menu', [ $this, 'maybe_add_entries_badge' ], 99 );
81 }
82 add_filter( 'wpforms_current_user_can', [ $this, 'disable_wpforms_capabilities' ], 10, 3 );
83 }
84
85 /**
86 * Show action on plugin page.
87 *
88 * @param array $links links.
89 * @return array
90 * @since 1.4.2
91 */
92 public function add_action_links( $links ) {
93 if ( ! defined( 'SRFM_PRO_FILE' ) && ! file_exists( WP_PLUGIN_DIR . '/sureforms-pro/sureforms-pro.php' ) ) {
94 // Display upsell link if SureForms Pro is not installed.
95 $upsell_link = add_query_arg(
96 [
97 'utm_medium' => 'plugin-list',
98 ],
99 Helper::get_sureforms_website_url( 'pricing' )
100 );
101 $links[] = '<a href="' . esc_url( $upsell_link ) . '" target="_blank" rel="noreferrer" class="sureforms-plugins-go-pro">' . esc_html__( 'Get SureForms Pro', 'sureforms' ) . '</a>';
102 }
103
104 return $links;
105 }
106
107 /**
108 * Enable block editor in Enfold theme for SureForms post type.
109 *
110 * @param bool $use_block_editor Whether to use block editor.
111 * @since 1.3.1
112 */
113 public function enable_block_editor_in_enfold_theme( $use_block_editor ) {
114 // if SureForms form post type then return true.
115 if ( SRFM_FORMS_POST_TYPE === get_current_screen()->post_type ) {
116 return true;
117 }
118 return $use_block_editor;
119 }
120
121 /**
122 * Enable Gutenberg for SureForms associated post types.
123 *
124 * @since 0.0.10
125 */
126 public function enable_gutenberg_for_sureforms() {
127 /**
128 * Check if the classic editor is enabled from Classic Editor plugin settings or Divi settings.
129 */
130 if ( 'block' === get_option( 'classic-editor-replace' ) || 'on' === get_option( 'et_enable_classic_editor' ) ) {
131 return;
132 }
133
134 $srfm_post_types = apply_filters( 'srfm_enable_gutenberg_post_types', [ SRFM_FORMS_POST_TYPE ] );
135
136 if ( in_array( get_current_screen()->post_type, $srfm_post_types, true ) ) {
137 add_filter( 'use_block_editor_for_post_type', '__return_true', 110 );
138 add_filter( 'gutenberg_can_edit_post_type', '__return_true', 110 );
139 }
140 }
141
142 /**
143 * Sureforms editor header styles.
144 *
145 * @since 0.0.1
146 */
147 public function enqueue_header_styles() {
148 $current_screen = get_current_screen();
149 $file_prefix = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? '' : '.min';
150 $dir_name = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? 'unminified' : 'minified';
151
152 $css_uri = SRFM_URL . 'assets/css/' . $dir_name . '/';
153
154 /* RTL */
155 if ( is_rtl() ) {
156 $file_prefix .= '-rtl';
157 }
158
159 if ( 'sureforms_form' === $current_screen->id ) {
160 wp_enqueue_style( SRFM_SLUG . '-editor-header-styles', $css_uri . 'header-styles' . $file_prefix . '.css', [], SRFM_VER );
161 }
162 }
163
164 /**
165 * Add menu page.
166 *
167 * @return void
168 * @since 0.0.1
169 */
170 public function add_menu_page() {
171 if ( ! current_user_can( 'manage_options' ) ) {
172 return;
173 }
174
175 $capability = 'manage_options';
176 $menu_slug = 'sureforms_menu';
177
178 $logo = file_get_contents( plugin_dir_path( SRFM_FILE ) . 'images/icon.svg' );
179 add_menu_page(
180 __( 'SureForms', 'sureforms' ),
181 __( 'SureForms', 'sureforms' ),
182 'edit_others_posts',
183 $menu_slug,
184 static function () {
185 },
186 'data:image/svg+xml;base64,' . base64_encode( $logo ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
187 30
188 );
189
190 // Add the Dashboard Submenu.
191 add_submenu_page(
192 $menu_slug,
193 __( 'Dashboard', 'sureforms' ),
194 __( 'Dashboard', 'sureforms' ),
195 $capability,
196 $menu_slug,
197 [ $this, 'render_dashboard' ]
198 );
199 }
200
201 /**
202 * Add Settings page.
203 *
204 * @return void
205 * @since 0.0.1
206 */
207 public function settings_page() {
208 $callback = [ $this, 'settings_page_callback' ];
209 add_submenu_page(
210 'sureforms_menu',
211 __( 'Settings', 'sureforms' ),
212 __( 'Settings', 'sureforms' ),
213 'edit_others_posts',
214 'sureforms_form_settings',
215 $callback
216 );
217
218 // Get the current submenu page.
219 $submenu_page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['page'] does not provide nonce.
220
221 if ( ! isset( $_GET['tab'] ) && 'sureforms_form_settings' === $submenu_page ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['page'] does not provide nonce.
222 wp_safe_redirect( admin_url( 'admin.php?page=sureforms_form_settings&tab=general-settings' ) );
223 exit;
224 }
225 }
226
227 /**
228 * Open to Upgrade to Pro submenu link in new tab.
229 *
230 * @return void
231 * @since 1.6.1
232 */
233 public function add_upgrade_to_pro_target_attr() {
234 ?>
235 <script type="text/javascript">
236 document.addEventListener('DOMContentLoaded', function () {
237 // Upgrade link handler.
238 // IMPORTANT: If this URL changes, also update it in the `add_upgrade_to_pro` function.
239 const upgradeLink = document.querySelector('a[href*="https://sureforms.com/upgrade"]');
240 if (upgradeLink) {
241 upgradeLink.addEventListener('click', e => {
242 e.preventDefault();
243 window.open(upgradeLink.href, '_blank');
244 });
245 }
246 });
247 </script>
248 <?php
249 }
250
251 /**
252 * Add Upgrade to pro menu item.
253 *
254 * @return void
255 * @since 1.6.1
256 */
257 public function add_upgrade_to_pro() {
258 // The url used here is used as a selector for css to style the upgrade to pro submenu.
259 // If you are changing this url, please make sure to update the css as well.
260 $upgrade_url = add_query_arg(
261 [
262 'utm_medium' => 'submenu_link_upgrade',
263 ],
264 Helper::get_sureforms_website_url( 'upgrade' )
265 );
266
267 add_submenu_page(
268 'sureforms_menu',
269 __( 'Upgrade', 'sureforms' ),
270 __( 'Upgrade', 'sureforms' ),
271 'edit_others_posts',
272 $upgrade_url
273 );
274 }
275
276 /**
277 * Add SMTP promotional submenu page.
278 *
279 * @return void
280 * @since 1.7.1
281 */
282 public function add_suremail_page() {
283 add_submenu_page(
284 'sureforms_menu',
285 __( 'SMTP', 'sureforms' ),
286 __( 'SMTP', 'sureforms' ),
287 'edit_others_posts',
288 'sureforms_smtp',
289 [ $this, 'suremail_page_callback' ]
290 );
291
292 // Get the current submenu page.
293 $submenu_page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['page'] does not provide nonce.
294
295 // Check if SureMail is installed and active.
296 if ( 'sureforms_smtp' === $submenu_page && file_exists( WP_PLUGIN_DIR . '/suremails/suremails.php' ) && is_plugin_active( 'suremails/suremails.php' ) ) {
297 // Plugin is installed and active - redirect to SureMail dashboard.
298 wp_safe_redirect( admin_url( 'options-general.php?page=suremail#/dashboard' ) );
299 exit;
300 }
301 }
302
303 /**
304 * SMTP promotional page callback.
305 *
306 * @return void
307 * @since 1.7.1
308 */
309 public function suremail_page_callback() {
310 echo '<div id="srfm-suremail-container" class="srfm-admin-wrapper"></div>';
311 }
312
313 /**
314 * Render Admin Dashboard.
315 *
316 * @return void
317 * @since 0.0.1
318 */
319 public function render_dashboard() {
320 echo '<div id="srfm-dashboard-container" class="srfm-admin-wrapper"></div>';
321 }
322
323 /**
324 * Settings page callback.
325 *
326 * @return void
327 * @since 0.0.1
328 */
329 public function settings_page_callback() {
330 echo '<div id="srfm-settings-container" class="srfm-admin-wrapper"></div>';
331 }
332
333 /**
334 * Add new form menu item.
335 *
336 * @return void
337 * @since 0.0.1
338 */
339 public function add_new_form() {
340 add_submenu_page(
341 'sureforms_menu',
342 __( 'New Form', 'sureforms' ),
343 __( 'New Form', 'sureforms' ),
344 'edit_others_posts',
345 'add-new-form',
346 [ $this, 'add_new_form_callback' ],
347 2
348 );
349 $entries_hook = add_submenu_page(
350 'sureforms_menu',
351 __( 'Entries', 'sureforms' ),
352 __( 'Entries', 'sureforms' ),
353 'edit_others_posts',
354 SRFM_ENTRIES,
355 [ $this, 'render_entries' ],
356 3
357 );
358
359 if ( $entries_hook ) {
360 add_action( 'load-' . $entries_hook, [ $this, 'mark_entries_page_visit' ] );
361 }
362 }
363
364 /**
365 * Add new form mentu item callback.
366 *
367 * @return void
368 * @since 0.0.1
369 */
370 public function add_new_form_callback() {
371 echo '<div id="srfm-add-new-form-container" class="srfm-admin-wrapper"></div>';
372 }
373
374 /**
375 * Entries page callback.
376 *
377 * @since 0.0.13
378 * @return void
379 */
380 public function render_entries() {
381 // Render single entry view.
382 // Adding the phpcs ignore nonce verification as no database operations are performed in this function, it is used to display the single entry view.
383 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.
384 $single_entry_view = new Single_Entry();
385 $single_entry_view->render();
386 return;
387 }
388
389 // Render all entries view.
390 $entries_table = new Entries_List_Table();
391 $entries_table->prepare_items();
392 echo '<div class="wrap"><h1 class="wp-heading-inline">' . esc_html__( 'Entries', 'sureforms' ) . '</h1>';
393 if ( empty( $entries_table->all_entries_count ) && empty( $entries_table->trash_entries_count ) ) {
394 $instance = Post_Types::get_instance();
395 $instance->sureforms_render_blank_state( SRFM_ENTRIES );
396 $instance->get_blank_state_styles();
397 return;
398 }
399 echo '<form method="get">';
400 echo '<input type="hidden" name="page" value="sureforms_entries">';
401 $entries_table->display();
402 echo '</form>';
403 echo '</div>';
404 }
405
406 /**
407 * Add notification badge to SureForms menu when there are new entries.
408 *
409 * @since 1.7.3
410 * @return void
411 */
412 public function maybe_add_entries_badge() {
413 if ( ! current_user_can( 'edit_others_posts' ) ) {
414 return;
415 }
416
417 // If currently viewing the entries listing page, mark it as visited and skip the badge.
418 if ( isset( $_GET['page'] ) && SRFM_ENTRIES === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Only checking the page slug.
419 $this->mark_entries_page_visit();
420 return;
421 }
422
423 $srfm_options = get_option( 'srfm_options', [] );
424 $last_visit = isset( $srfm_options['entries_last_visited'] ) ? absint( $srfm_options['entries_last_visited'] ) : 0;
425 $new_entries = Entries::get_entries_count_after( $last_visit );
426
427 if ( $new_entries <= 0 ) {
428 return;
429 }
430
431 global $menu;
432 foreach ( $menu as $index => $item ) {
433 if ( isset( $item[2] ) && 'sureforms_menu' === $item[2] ) {
434 $menu[ $index ][0] .= sprintf( // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Adding notifications for menu item.
435 ' <span class="update-plugins count-%1$d"><span class="plugin-count">%1$d</span></span>',
436 absint( $new_entries )
437 );
438 break;
439 }
440 }
441
442 global $submenu;
443 if ( isset( $submenu['sureforms_menu'] ) ) {
444 foreach ( $submenu['sureforms_menu'] as $index => $sub_item ) {
445 if ( isset( $sub_item[2] ) && SRFM_ENTRIES === $sub_item[2] ) {
446 $submenu['sureforms_menu'][ $index ][0] .= sprintf( // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Adding notifications for submenu item.
447 ' <span class="update-plugins count-%1$d"><span class="plugin-count">%1$d</span></span>',
448 absint( $new_entries )
449 );
450 break;
451 }
452 }
453 }
454 }
455
456 /**
457 * Mark the user's visit to the entries page.
458 *
459 * @since 1.7.3
460 * @return void
461 */
462 public function mark_entries_page_visit() {
463 if ( current_user_can( 'edit_others_posts' ) ) {
464 $srfm_options = get_option( 'srfm_options', [] );
465 $srfm_options['entries_last_visited'] = time();
466 \SRFM\Inc\Helper::update_admin_settings_option( 'srfm_options', $srfm_options );
467 }
468 }
469
470 /**
471 * Adds a settings link to the plugin action links on the plugins page.
472 *
473 * @param array $links An array of plugin action links.
474 * @param string $file The plugin file path.
475 * @return array The updated array of plugin action links.
476 * @since 0.0.1
477 */
478 public function add_settings_link( $links, $file ) {
479 if ( 'sureforms/sureforms.php' === $file ) {
480 $plugin_links = apply_filters(
481 'sureforms_plugin_action_links',
482 [
483 'sureforms_settings' => '<a href="' . esc_url( admin_url( 'admin.php?page=sureforms_form_settings&tab=general-settings' ) ) . '">' . esc_html__( 'Settings', 'sureforms' ) . '</a>',
484 ]
485 );
486 $links = array_merge( $plugin_links, $links );
487 }
488 return $links;
489 }
490
491 /**
492 * Sureforms block editor styles.
493 *
494 * @since 0.0.1
495 */
496 public function enqueue_styles() {
497 $current_screen = get_current_screen();
498 global $wp_version;
499
500 $file_prefix = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? '' : '.min';
501 $dir_name = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? 'unminified' : 'minified';
502
503 $css_uri = SRFM_URL . 'assets/css/' . $dir_name . '/';
504 $vendor_css_uri = SRFM_URL . 'assets/css/minified/deps/';
505
506 /* RTL */
507 if ( is_rtl() ) {
508 $file_prefix .= '-rtl';
509 }
510
511 // Enqueue editor styles for post and page.
512 if ( SRFM_FORMS_POST_TYPE === $current_screen->post_type ) {
513 wp_enqueue_style( SRFM_SLUG . '-editor', $css_uri . 'backend/editor' . $file_prefix . '.css', [], SRFM_VER );
514 wp_enqueue_style( SRFM_SLUG . '-backend-blocks', $css_uri . 'blocks/default/backend' . $file_prefix . '.css', [], SRFM_VER );
515 wp_enqueue_style( SRFM_SLUG . '-intl', $vendor_css_uri . 'intl/intlTelInput-backend.min.css', [], SRFM_VER );
516 wp_enqueue_style( SRFM_SLUG . '-common', $css_uri . 'common' . $file_prefix . '.css', [], SRFM_VER );
517 wp_enqueue_style( SRFM_SLUG . '-reactQuill', $vendor_css_uri . 'quill/quill.snow.css', [], SRFM_VER );
518 wp_enqueue_style( SRFM_SLUG . '-single-form-modal', $css_uri . 'single-form-setting' . $file_prefix . '.css', [], SRFM_VER );
519
520 // if version is equal to or lower than 6.6.2 then add compatibility css.
521 if ( version_compare( $wp_version, '6.6.2', '<=' ) ) {
522 $srfm_inline_css = '.srfm-settings-modal .srfm-setting-modal-container .components-toggle-control .components-base-control__help{
523 margin-left: 4em;
524 }';
525 wp_add_inline_style( SRFM_SLUG . '-single-form-modal', $srfm_inline_css );
526 }
527 }
528
529 wp_enqueue_style( SRFM_SLUG . '-form-selector', $css_uri . 'srfm-form-selector' . $file_prefix . '.css', [], SRFM_VER );
530 wp_enqueue_style( SRFM_SLUG . '-common-editor', SRFM_URL . 'assets/build/common-editor.css', [], SRFM_VER, 'all' );
531 }
532
533 /**
534 * Get Breadcrumbs for current page.
535 *
536 * @since 0.0.1
537 * @return array Breadcrumbs Array.
538 */
539 public function get_breadcrumbs_for_current_page() {
540 global $post, $pagenow;
541 $breadcrumbs = [];
542
543 if ( 'admin.php' === $pagenow && isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- We don't need nonce verification here.
544 $page_title = get_admin_page_title();
545 $breadcrumbs[] = [
546 'title' => $page_title,
547 'link' => '',
548 ];
549 } elseif ( $post && in_array( $pagenow, [ 'post.php', 'post-new.php', 'edit.php' ], true ) ) {
550 $post_type_obj = get_post_type_object( get_post_type() );
551 if ( $post_type_obj ) {
552 $post_type_plural = $post_type_obj->labels->name;
553 $breadcrumbs[] = [
554 'title' => $post_type_plural,
555 'link' => admin_url( 'edit.php?post_type=' . $post_type_obj->name ),
556 ];
557
558 if ( 'edit.php' === $pagenow && ! isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- We don't need nonce verification here.
559 $breadcrumbs[ count( $breadcrumbs ) - 1 ]['link'] = '';
560 } else {
561 $breadcrumbs[] = [
562 /* Translators: Post Title. */
563 'title' => sprintf( __( 'Edit %1$s', 'sureforms' ), get_the_title() ),
564 'link' => get_edit_post_link( $post->ID ),
565 ];
566 }
567 }
568 } else {
569 $current_screen = get_current_screen();
570 if ( $current_screen && 'sureforms_form' === $current_screen->post_type ) {
571 $breadcrumbs[] = [
572 'title' => 'Forms',
573 'link' => '',
574 ];
575 } else {
576 $breadcrumbs[] = [
577 'title' => '',
578 'link' => '',
579 ];
580 }
581 }
582
583 return $breadcrumbs;
584 }
585
586 /**
587 * Enqueue Admin Scripts.
588 *
589 * @return void
590 * @since 0.0.1
591 */
592 public function enqueue_scripts() {
593 $current_screen = get_current_screen();
594 global $wp_version;
595
596 $file_prefix = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? '' : '.min';
597 $dir_name = defined( 'SRFM_DEBUG' ) && SRFM_DEBUG ? 'unminified' : 'minified';
598 $js_uri = SRFM_URL . 'assets/js/' . $dir_name . '/';
599 $css_uri = SRFM_URL . 'assets/css/' . $dir_name . '/';
600 $is_rtl = is_rtl();
601 $rtl = $is_rtl ? '-rtl' : '';
602
603 /**
604 * List of the handles in which we need to add translation compatibility.
605 */
606 $script_translations_handlers = [];
607
608 $localization_data = [
609 'site_url' => get_site_url(),
610 'breadcrumbs' => $this->get_breadcrumbs_for_current_page(),
611 'sureforms_dashboard_url' => admin_url( '/admin.php?page=sureforms_menu' ),
612 'plugin_version' => SRFM_VER,
613 'global_settings_nonce' => current_user_can( 'manage_options' ) ? wp_create_nonce( 'wp_rest' ) : '',
614 'is_pro_active' => defined( 'SRFM_PRO_VER' ),
615 'pro_plugin_version' => defined( 'SRFM_PRO_VER' ) ? SRFM_PRO_VER : '',
616 'pro_plugin_name' => defined( 'SRFM_PRO_VER' ) && defined( 'SRFM_PRO_PRODUCT' ) ? SRFM_PRO_PRODUCT : 'SureForms Pro',
617 'sureforms_pricing_page' => Helper::get_sureforms_website_url( 'pricing' ),
618 'field_spacing_vars' => Helper::get_css_vars(),
619 'is_ver_lower_than_6_7' => version_compare( $wp_version, '6.6.2', '<=' ),
620 'integrations' => Helper::sureforms_get_integration(),
621 'ajax_url' => admin_url( 'admin-ajax.php' ),
622 'sf_plugin_manager_nonce' => wp_create_nonce( 'sf_plugin_manager_nonce' ),
623 'plugin_installer_nonce' => wp_create_nonce( 'updates' ),
624 'plugin_activating_text' => __( 'Activating...', 'sureforms' ),
625 'plugin_activated_text' => __( 'Activated', 'sureforms' ),
626 'plugin_activate_text' => __( 'Activate', 'sureforms' ),
627 'plugin_installing_text' => __( 'Installing...', 'sureforms' ),
628 'plugin_installed_text' => __( 'Installed', 'sureforms' ),
629 'is_rtl' => $is_rtl,
630 ];
631
632 $is_screen_sureforms_menu = Helper::validate_request_context( 'sureforms_menu', 'page' );
633 $is_screen_add_new_form = Helper::validate_request_context( 'add-new-form', 'page' );
634 $is_screen_sureforms_form_settings = Helper::validate_request_context( 'sureforms_form_settings', 'page' );
635 $is_screen_sureforms_entries = Helper::validate_request_context( SRFM_ENTRIES, 'page' );
636 $is_post_type_sureforms_form = SRFM_FORMS_POST_TYPE === $current_screen->post_type;
637
638 if ( $is_screen_sureforms_menu || $is_post_type_sureforms_form || $is_screen_add_new_form || $is_screen_sureforms_form_settings || $is_screen_sureforms_entries ) {
639 $asset_handle = '-dashboard';
640
641 wp_enqueue_style( SRFM_SLUG . $asset_handle . '-font', 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap', [], SRFM_VER );
642
643 $script_asset_path = SRFM_DIR . 'assets/build/dashboard.asset.php';
644 $script_info = file_exists( $script_asset_path )
645 ? include $script_asset_path
646 : [
647 'dependencies' => [],
648 'version' => SRFM_VER,
649 ];
650 wp_enqueue_script( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/dashboard.js', $script_info['dependencies'], SRFM_VER, true );
651
652 wp_localize_script( SRFM_SLUG . $asset_handle, 'scIcons', [ 'path' => SRFM_URL . 'assets/build/icon-assets' ] );
653
654 $script_translations_handlers[] = SRFM_SLUG . $asset_handle;
655
656 if ( class_exists( 'SRFM_PRO\Admin\Licensing' ) ) {
657 $license_active = \SRFM_PRO\Admin\Licensing::is_license_active();
658 $localization_data['is_license_active'] = $license_active;
659
660 // Updating current licensing status.
661 $srfm_pro_license_status = get_option( 'srfm_pro_license_status', '' );
662 $current_license_status = $license_active ? 'licensed' : 'unlicensed';
663 if ( $current_license_status !== $srfm_pro_license_status ) {
664 update_option( 'srfm_pro_license_status', $current_license_status );
665 }
666 }
667
668 $localization_data['security_settings_url'] = admin_url( '/admin.php?page=sureforms_form_settings&tab=security-settings' );
669 $localization_data['integration_settings_url'] = admin_url( '/admin.php?page=sureforms_form_settings&tab=integration-settings' );
670 wp_localize_script(
671 SRFM_SLUG . $asset_handle,
672 SRFM_SLUG . '_admin',
673 apply_filters(
674 SRFM_SLUG . '_admin_filter',
675 $localization_data
676 )
677 );
678 wp_enqueue_style( SRFM_SLUG . '-dashboard', SRFM_URL . 'assets/build/dashboard.css', [], SRFM_VER, 'all' );
679
680 }
681
682 if ( $is_screen_sureforms_form_settings ) {
683 wp_enqueue_style( SRFM_SLUG . '-settings', $css_uri . 'backend/settings' . $file_prefix . $rtl . '.css', [], SRFM_VER );
684 }
685
686 // Enqueue styles for the entries page.
687 if ( $is_screen_sureforms_entries ) {
688 $asset_handle = '-entries';
689 wp_enqueue_script( SRFM_SLUG . $asset_handle, SRFM_URL . 'assets/build/entries.js', $script_info['dependencies'], SRFM_VER, true );
690
691 $script_translations_handlers[] = SRFM_SLUG . $asset_handle;
692 }
693
694 // Enqueue scripts for the SureMail promotional page.
695 $is_screen_sureforms_smtp = Helper::validate_request_context( 'sureforms_smtp', 'page' );
696 if ( $is_screen_sureforms_smtp ) {
697 $asset_handle = 'suremail';
698
699 $script_asset_path = SRFM_DIR . 'assets/build/' . $asset_handle . '.asset.php';
700 $script_info = file_exists( $script_asset_path )
701 ? include $script_asset_path
702 : [
703 'dependencies' => [],
704 'version' => SRFM_VER,
705 ];
706
707 wp_enqueue_script( SRFM_SLUG . '-suremail', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
708 wp_enqueue_style( SRFM_SLUG . '-suremail', SRFM_URL . 'assets/build/suremail.css', [], SRFM_VER, 'all' );
709
710 // Localize script for SureMail page.
711 $suremail_localization_data = [
712 'ajax_url' => admin_url( 'admin-ajax.php' ),
713 'admin_url' => admin_url(),
714 'suremail_url' => 'https://sureforms.com/suremail/',
715 'plugin_installer_nonce' => wp_create_nonce( 'updates' ),
716 'sfPluginManagerNonce' => wp_create_nonce( 'sf_plugin_manager_nonce' ),
717 'suremail_status' => file_exists( WP_PLUGIN_DIR . '/suremails/suremails.php' )
718 ? ( is_plugin_active( 'suremails/suremails.php' ) ? 'active' : 'installed' )
719 : 'not_installed',
720 ];
721
722 wp_localize_script(
723 SRFM_SLUG . '-suremail',
724 SRFM_SLUG . '_admin',
725 apply_filters(
726 SRFM_SLUG . '_suremail_admin_filter',
727 $suremail_localization_data
728 )
729 );
730
731 $script_translations_handlers[] = SRFM_SLUG . '-suremail';
732 }
733
734 // Admin Submenu Styles.
735 wp_enqueue_style( SRFM_SLUG . '-admin', $css_uri . 'backend/admin' . $file_prefix . $rtl . '.css', [], SRFM_VER );
736
737 if ( 'edit-' . SRFM_FORMS_POST_TYPE === $current_screen->id ) {
738 $asset_handle = 'page_header';
739
740 $script_asset_path = SRFM_DIR . 'assets/build/' . $asset_handle . '.asset.php';
741 $script_info = file_exists( $script_asset_path )
742 ? include $script_asset_path
743 : [
744 'dependencies' => [],
745 'version' => SRFM_VER,
746 ];
747 wp_enqueue_script( SRFM_SLUG . '-form-page-header', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
748 wp_enqueue_style( SRFM_SLUG . '-form-archive-styles', $css_uri . 'form-archive-styles' . $file_prefix . $rtl . '.css', [], SRFM_VER );
749
750 $script_translations_handlers[] = SRFM_SLUG . '-form-page-header';
751 }
752
753 if ( $is_screen_sureforms_form_settings ) {
754 $asset_handle = 'settings';
755
756 $script_asset_path = SRFM_DIR . 'assets/build/' . $asset_handle . '.asset.php';
757 $script_info = file_exists( $script_asset_path )
758 ? include $script_asset_path
759 : [
760 'dependencies' => [],
761 'version' => SRFM_VER,
762 ];
763
764 wp_enqueue_script( SRFM_SLUG . '-settings', SRFM_URL . 'assets/build/' . $asset_handle . '.js', $script_info['dependencies'], SRFM_VER, true );
765 wp_localize_script(
766 SRFM_SLUG . '-settings',
767 SRFM_SLUG . '_admin',
768 $localization_data
769 );
770
771 $script_translations_handlers[] = SRFM_SLUG . '-settings';
772 }
773 if ( 'edit-' . SRFM_FORMS_POST_TYPE === $current_screen->id ) {
774 wp_enqueue_script( SRFM_SLUG . '-form-archive', $js_uri . 'form-archive' . $file_prefix . '.js', [], SRFM_VER, true );
775 wp_enqueue_script( SRFM_SLUG . '-export', $js_uri . 'export' . $file_prefix . '.js', [ 'wp-i18n' ], SRFM_VER, true );
776 wp_localize_script(
777 SRFM_SLUG . '-export',
778 SRFM_SLUG . '_export',
779 [
780 'ajaxurl' => admin_url( 'admin-ajax.php' ),
781 'srfm_export_nonce' => wp_create_nonce( 'export_form_nonce' ),
782 'site_url' => get_site_url(),
783 'import_form_nonce' => current_user_can( 'edit_posts' ) ? wp_create_nonce( 'wp_rest' ) : '',
784 'import_btn_string' => __( 'Import Form', 'sureforms' ),
785 ]
786 );
787
788 wp_enqueue_script( SRFM_SLUG . '-backend', $js_uri . 'backend' . $file_prefix . '.js', [], SRFM_VER, true );
789 wp_localize_script(
790 SRFM_SLUG . '-backend',
791 SRFM_SLUG . '_backend',
792 [
793 'site_url' => get_site_url(),
794 ]
795 );
796
797 $script_translations_handlers[] = SRFM_SLUG . '-form-archive';
798 $script_translations_handlers[] = SRFM_SLUG . '-export';
799 $script_translations_handlers[] = SRFM_SLUG . '-backend';
800 }
801
802 if ( $is_screen_add_new_form ) {
803 wp_enqueue_style( SRFM_SLUG . '-template-picker', $css_uri . 'template-picker' . $file_prefix . $rtl . '.css', [], SRFM_VER );
804
805 $sureforms_admin = 'templatePicker';
806
807 $script_asset_path = SRFM_DIR . 'assets/build/' . $sureforms_admin . '.asset.php';
808 $script_info = file_exists( $script_asset_path )
809 ? include $script_asset_path
810 : [
811 'dependencies' => [],
812 'version' => SRFM_VER,
813 ];
814 wp_enqueue_script( SRFM_SLUG . '-template-picker', SRFM_URL . 'assets/build/' . $sureforms_admin . '.js', $script_info['dependencies'], SRFM_VER, true );
815
816 wp_localize_script(
817 SRFM_SLUG . '-template-picker',
818 SRFM_SLUG . '_admin',
819 [
820 'site_url' => get_site_url(),
821 'plugin_url' => SRFM_URL,
822 'preview_images_url' => SRFM_URL . 'images/template-previews/',
823 'admin_url' => admin_url( 'admin.php' ),
824 'new_template_picker_base_url' => admin_url( 'post-new.php?post_type=sureforms_form' ),
825 'capability' => current_user_can( 'edit_posts' ),
826 'template_picker_nonce' => current_user_can( 'edit_posts' ) ? wp_create_nonce( 'wp_rest' ) : '',
827 'is_pro_active' => defined( 'SRFM_PRO_VER' ),
828 'srfm_ai_usage_details' => AI_Helper::get_current_usage_details(),
829 'is_pro_license_active' => AI_Helper::is_pro_license_active(),
830 'srfm_ai_auth_user_email' => get_option( 'srfm_ai_auth_user_email' ),
831 'pricing_page_url' => Helper::get_sureforms_website_url( 'pricing' ),
832 ]
833 );
834
835 $script_translations_handlers[] = SRFM_SLUG . '-template-picker';
836 }
837 // Quick action sidebar.
838 $default_allowed_quick_sidebar_blocks = apply_filters(
839 'srfm_quick_sidebar_allowed_blocks',
840 [
841 'srfm/input',
842 'srfm/email',
843 'srfm/textarea',
844 'srfm/checkbox',
845 'srfm/number',
846 'srfm/inline-button',
847 'srfm/advanced-heading',
848 ]
849 );
850 if ( ! is_array( $default_allowed_quick_sidebar_blocks ) ) {
851 $default_allowed_quick_sidebar_blocks = [];
852 }
853
854 $srfm_enable_quick_action_sidebar = get_option( 'srfm_enable_quick_action_sidebar' );
855 if ( ! $srfm_enable_quick_action_sidebar ) {
856 $srfm_enable_quick_action_sidebar = 'disabled';
857 }
858 $quick_sidebar_allowed_blocks = get_option( 'srfm_quick_sidebar_allowed_blocks' );
859 $quick_sidebar_allowed_blocks = ! empty( $quick_sidebar_allowed_blocks ) && is_array( $quick_sidebar_allowed_blocks ) ? $quick_sidebar_allowed_blocks : $default_allowed_quick_sidebar_blocks;
860 $srfm_ajax_nonce = wp_create_nonce( 'srfm_ajax_nonce' );
861 wp_enqueue_script( SRFM_SLUG . '-quick-action-siderbar', SRFM_URL . 'assets/build/quickActionSidebar.js', [], SRFM_VER, true );
862 wp_localize_script(
863 SRFM_SLUG . '-quick-action-siderbar',
864 SRFM_SLUG . '_quick_sidebar_blocks',
865 [
866 'allowed_blocks' => $quick_sidebar_allowed_blocks,
867 'srfm_enable_quick_action_sidebar' => $srfm_enable_quick_action_sidebar,
868 'srfm_ajax_nonce' => $srfm_ajax_nonce,
869 'srfm_ajax_url' => admin_url( 'admin-ajax.php' ),
870 ]
871 );
872
873 $script_translations_handlers[] = SRFM_SLUG . '-quick-action-siderbar';
874
875 /**
876 * Enqueuing SureTriggers Integration script.
877 * This script loads suretriggers iframe in Intergations tab.
878 */
879 if ( $is_post_type_sureforms_form ) {
880 wp_enqueue_script( SRFM_SLUG . '-suretriggers-integration', SRFM_SURETRIGGERS_INTEGRATION_BASE_URL . 'js/v2/embed.js', [], SRFM_VER, true );
881 }
882
883 // Check $script_translations_handlers is not empty before calling the function.
884 if ( ! empty( $script_translations_handlers ) ) {
885 // Remove duplicates values from the array.
886 $script_translations_handlers = array_unique( $script_translations_handlers );
887
888 foreach ( $script_translations_handlers as $script_handle ) {
889 Helper::register_script_translations( $script_handle );
890 }
891 }
892 }
893
894 /**
895 * Form Template Picker Admin Body Classes
896 * WordPress sometimes translates class names in the admin body tag, which can result in
897 * incorrect or missing class names when rendering the admin pages. This function ensures
898 * that essential class names are manually added to the body tag to maintain proper functionality.
899 *
900 * @since 0.0.1
901 * @param string $classes Space separated class string.
902 */
903 public function admin_template_picker_body_class( $classes = '' ) {
904 // Define an associative array of class names and their corresponding conditions.
905 // Each condition checks whether a specific request context matches.
906 $srfm_classes = [
907 'sureforms_page_sureforms_entries' => Helper::validate_request_context( SRFM_ENTRIES, 'page' ),
908 'sureforms_page_sureforms_form_settings' => Helper::validate_request_context( 'sureforms_form_settings', 'page' ),
909 'srfm-template-picker' => Helper::validate_request_context( 'add-new-form', 'page' ),
910 ];
911
912 $add_srfm_classes = '';
913
914 // Loop through the defined classes and conditions.
915 foreach ( $srfm_classes as $class => $condition ) {
916 // Check if the condition evaluates to true.
917 if ( $condition ) {
918 // Append the class to the existing classes string, followed by a space.
919 $add_srfm_classes .= empty( $add_srfm_classes ) ? $class : ' ' . $class;
920 }
921 }
922
923 // Append the new classes to the existing classes string.
924 if ( ! empty( $add_srfm_classes ) ) {
925 $classes .= ' ' . $add_srfm_classes;
926 }
927
928 // Return the updated list of classes.
929 return $classes;
930 }
931
932 /**
933 * Disable spectra's quick action bar in sureforms CPT.
934 *
935 * @param string $status current status of the quick action bar.
936 * @since 0.0.2
937 * @return string
938 */
939 public function restrict_spectra_quick_action_bar( $status ) {
940 $screen = get_current_screen();
941 if ( 'disabled' !== $status && isset( $screen->id ) && 'sureforms_form' === $screen->id ) {
942 $status = 'disabled';
943 }
944
945 return $status;
946 }
947
948 // Entries methods.
949
950 /**
951 * Handle entry actions.
952 *
953 * @since 0.0.13
954 * @return void
955 */
956 public function handle_entry_actions() {
957 Entries_List_Table::process_bulk_actions();
958
959 if ( ! isset( $_GET['page'] ) || SRFM_ENTRIES !== $_GET['page'] ) {
960 return;
961 }
962 if ( ! isset( $_GET['entry_id'] ) || ! isset( $_GET['action'] ) ) {
963 return;
964 }
965 if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'srfm_entries_action' ) ) {
966 wp_die( esc_html__( 'Nonce verification failed.', 'sureforms' ) );
967 }
968 $action = isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : '';
969 $entry_id = Helper::get_integer_value( sanitize_text_field( wp_unslash( $_GET['entry_id'] ) ) );
970 $view = isset( $_GET['view'] ) ? sanitize_text_field( wp_unslash( $_GET['view'] ) ) : '';
971 if ( $entry_id > 0 ) {
972 if ( 'read' === $action && 'details' === $view ) {
973 $entry_status = Entries::get( $entry_id )['status'];
974 if ( 'trash' === $entry_status ) {
975 wp_die( esc_html__( 'You cannot view this entry because it is in trash.', 'sureforms' ) );
976 }
977 }
978 Entries_List_Table::handle_entry_status( $entry_id, $action, $view );
979 }
980 }
981
982 /**
983 * Admin Notice Callback if sureforms pro is out of date.
984 *
985 * Hooked - admin_notices
986 *
987 * @return void
988 * @since 1.0.4
989 */
990 public function srfm_pro_version_compatibility() {
991 $plugin_file = 'sureforms-pro/sureforms-pro.php';
992 if ( ! is_plugin_active( $plugin_file ) || ! defined( 'SRFM_PRO_VER' ) ) {
993 return;
994 }
995
996 if ( empty( get_current_screen() ) ) {
997 return;
998 }
999
1000 if ( ! current_user_can( 'update_plugins' ) ) {
1001 return;
1002 }
1003
1004 $srfm_pro_license_status = get_option( 'srfm_pro_license_status', '' );
1005 /**
1006 * If the license status is not set then get the license status and update the option accordingly.
1007 * This will be executed only once. Subsequently, the option status is updated by the licensing class on license activation or deactivation.
1008 */
1009 if ( empty( $srfm_pro_license_status ) && class_exists( 'SRFM_PRO\Admin\Licensing' ) ) {
1010 $srfm_pro_license_status = \SRFM_PRO\Admin\Licensing::is_license_active() ? 'licensed' : 'unlicensed';
1011 update_option( 'srfm_pro_license_status', $srfm_pro_license_status );
1012 }
1013
1014 $pro_plugin_name = defined( 'SRFM_PRO_PRODUCT' ) ? SRFM_PRO_PRODUCT : 'SureForms Pro';
1015 $message = '';
1016 $url = admin_url( 'admin.php?page=sureforms_form_settings&tab=account-settings' );
1017 if ( 'unlicensed' === $srfm_pro_license_status ) {
1018 $message = '<p>' . sprintf(
1019 // translators: %1$s: Opening anchor tag with URL, %2$s: Closing anchor tag, %3$s: SureForms Pro Plugin Name.
1020 esc_html__( 'Please %1$sactivate%2$s your copy of %3$s to get new features, access support, receive update notifications, and more.', 'sureforms' ),
1021 '<a href="' . esc_url( $url ) . '">',
1022 '</a>',
1023 '<i>' . esc_html( $pro_plugin_name ) . '</i>'
1024 ) . '</p>';
1025 }
1026
1027 if ( ! version_compare( SRFM_PRO_VER, SRFM_PRO_RECOMMENDED_VER, '>=' ) ) {
1028 $message .= '<p>' . sprintf(
1029 // 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.
1030 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' ),
1031 esc_html( SRFM_VER ),
1032 esc_html( $pro_plugin_name ),
1033 esc_html( SRFM_PRO_RECOMMENDED_VER ),
1034 '<a href=' . esc_url( admin_url( 'update-core.php' ) ) . '>',
1035 '</a>'
1036 ) . '</p>';
1037 }
1038
1039 if ( ! empty( $message ) ) {
1040 // Phpcs ignore comment is required as $message variable is already escaped.
1041 echo '<div class="notice notice-warning">' . wp_kses_post( $message ) . '</div>';
1042 }
1043 }
1044
1045 /**
1046 * Disables the capabilities for WPForms to avoid conflicts when enqueueing
1047 * scripts and styles for WPForms.
1048 *
1049 * This function is intended to prevent any potential conflicts that may arise
1050 * when WPForms scripts and styles are enqueued. By disabling certain capabilities,
1051 * it ensures that WPForms does not interfere with other functionalities.
1052 *
1053 * @param bool $user_can A boolean indicating whether the user has the capability.
1054 * @return bool Returns true if the capabilities are successfully disabled, false otherwise.
1055 * @since 1.4.2
1056 */
1057 public function disable_wpforms_capabilities( $user_can ) {
1058 // Note: Nonce verification is intentionally omitted here as no database operations are performed.
1059 // The values of the $_REQUEST variables are strictly validated, ensuring security without the need for nonce verification.
1060
1061 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1062 $post_id = ! empty( $_REQUEST['post'] ) && ! empty( $_REQUEST['action'] ) ? absint( $_REQUEST['post'] ) : 0;
1063
1064 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
1065 $post_type = $post_id ? get_post_type( $post_id ) : sanitize_text_field( wp_unslash( $_REQUEST['post_type'] ?? '' ) );
1066 return SRFM_FORMS_POST_TYPE === $post_type ? false : $user_can;
1067 }
1068 }
1069