| @@ -7,13 +7,12 @@ | ||
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | namespace SRFM\Inc; |
| 10 | 10 | |
| 11 | -use WP_Query; | |
| 11 | +use SRFM\Inc\Traits\Get_Instance; | |
| 12 | 12 | use WP_Admin_Bar; |
| 13 | -use SRFM\Inc\Traits\Get_Instance; | |
| 14 | -use SRFM\Inc\Generate_Form_Markup; | |
| 15 | -use SRFM\Inc\Helper; | |
| 13 | +use WP_Post; | |
| 14 | +use WP_REST_Response; | |
| 16 | 15 | |
| 17 | 16 | if ( ! defined( 'ABSPATH' ) ) { |
| 18 | 17 | exit; // Exit if accessed directly. |
| 19 | 18 | } |
| @@ -34,26 +33,178 @@ | ||
| 34 | 33 | public function __construct() { |
| 35 | 34 | $this->restrict_unwanted_insertions(); |
| 36 | 35 | add_action( 'init', [ $this, 'register_post_types' ] ); |
| 37 | 36 | add_action( 'init', [ $this, 'register_post_metas' ] ); |
| 38 | - add_filter( 'manage_sureforms_form_posts_columns', [ $this, 'custom_form_columns' ] ); | |
| 39 | - add_action( 'manage_sureforms_form_posts_custom_column', [ $this, 'custom_form_column_data' ], 10, 2 ); | |
| 40 | - add_filter( 'manage_sureforms_entry_posts_columns', [ $this, 'custom_entry_columns' ] ); | |
| 41 | - add_action( 'manage_sureforms_entry_posts_custom_column', [ $this, 'custom_entry_column_data' ], 10, 2 ); | |
| 42 | 37 | add_shortcode( 'sureforms', [ $this, 'forms_shortcode' ] ); |
| 43 | - add_action( 'add_meta_boxes', [ $this, 'entries_meta_box' ] ); | |
| 44 | - add_action( 'restrict_manage_posts', [ $this, 'add_tax_filter' ] ); | |
| 45 | 38 | add_action( 'manage_posts_extra_tablenav', [ $this, 'maybe_render_blank_form_state' ] ); |
| 46 | - add_action( 'in_admin_header', [ $this, 'embed_page_header' ] ); | |
| 47 | - add_action( 'admin_head', [ $this, 'remove_entries_publishing_actions' ] ); | |
| 48 | - add_filter( 'post_row_actions', [ $this, 'modify_entries_list_row_actions' ], 10, 2 ); | |
| 49 | - add_filter( 'post_updated_messages', [ $this, 'entries_updated_message' ] ); | |
| 50 | - add_filter( 'bulk_actions-edit-sureforms_form', [ $this, 'register_modify_bulk_actions' ], 99 ); | |
| 51 | - add_action( 'admin_notices', [ $this, 'import_form_popup' ] ); | |
| 52 | - add_action( 'admin_bar_menu', [ $this, 'remove_admin_bar_menu_item' ], 80, 1 ); | |
| 53 | - add_action( 'template_redirect', [ $this, 'srfm_instant_form_redirect' ] );} | |
| 39 | + add_action( 'template_redirect', [ $this, 'srfm_instant_form_redirect' ] ); | |
| 40 | + add_action( 'template_redirect', [ $this, 'disable_sureforms_archive_page' ], 9 ); | |
| 41 | + add_action( 'load-edit.php', [ $this, 'redirect_forms_listing_page' ] ); | |
| 54 | 42 | |
| 43 | + add_filter( 'rest_prepare_sureforms_form', [ $this, 'sureforms_normalize_meta_for_rest' ], 10, 2 ); | |
| 44 | + add_action( 'admin_bar_menu', [ $this, 'add_edit_form_to_admin_bar_menu' ], 100 ); | |
| 45 | + add_action( 'admin_bar_menu', [ $this, 'add_new_form_to_admin_bar_menu' ], 100 ); | |
| 46 | + } | |
| 47 | + | |
| 55 | 48 | /** |
| 49 | + * Redirect the forms listing page to the updated forms page. | |
| 50 | + * | |
| 51 | + * @return void | |
| 52 | + * @since 2.0.0 | |
| 53 | + */ | |
| 54 | + public function redirect_forms_listing_page() { | |
| 55 | + global $pagenow; | |
| 56 | + | |
| 57 | + if ( 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && SRFM_FORMS_POST_TYPE === $_GET['post_type'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce is not required for the redirection. | |
| 58 | + wp_safe_redirect( admin_url( 'admin.php?page=sureforms_forms' ) ); | |
| 59 | + exit; | |
| 60 | + } | |
| 61 | + } | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * Add "Edit Form" link to the admin bar menu. | |
| 65 | + * | |
| 66 | + * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance. | |
| 67 | + * @since 2.0.0 | |
| 68 | + * @return void | |
| 69 | + */ | |
| 70 | + public function add_edit_form_to_admin_bar_menu( $wp_admin_bar ) { | |
| 71 | + | |
| 72 | + // Bail early if admin bar or user isn’t available. | |
| 73 | + if ( ! is_user_logged_in() || ! is_admin_bar_showing() || ! $wp_admin_bar instanceof WP_Admin_Bar ) { | |
| 74 | + return; | |
| 75 | + } | |
| 76 | + | |
| 77 | + global $post; | |
| 78 | + | |
| 79 | + // Bail if no valid post or wrong post type. | |
| 80 | + if ( empty( $post ) || SRFM_FORMS_POST_TYPE !== $post->post_type ) { | |
| 81 | + return; | |
| 82 | + } | |
| 83 | + | |
| 84 | + $edit_link = get_edit_post_link( $post->ID ); | |
| 85 | + if ( ! $edit_link ) { | |
| 86 | + return; | |
| 87 | + } | |
| 88 | + | |
| 89 | + $wp_admin_bar->add_node( | |
| 90 | + [ | |
| 91 | + 'id' => 'edit-form', | |
| 92 | + 'title' => sprintf( | |
| 93 | + '<span class="ab-icon dashicons dashicons-edit" style="line-height:1.2;margin-right:4px;"></span> | |
| 94 | + <span class="ab-label" style="position:relative;top:-1px;">%s</span>', | |
| 95 | + esc_html__( 'Edit Form', 'sureforms' ) | |
| 96 | + ), | |
| 97 | + 'href' => esc_url( $edit_link ), | |
| 98 | + 'meta' => [ | |
| 99 | + 'title' => esc_attr__( 'Edit this form', 'sureforms' ), | |
| 100 | + ], | |
| 101 | + 'html' => true, | |
| 102 | + ] | |
| 103 | + ); | |
| 104 | + } | |
| 105 | + | |
| 106 | + /** | |
| 107 | + * Add a "Form" shortcut to the admin bar "+ New" menu (#3026). | |
| 108 | + * | |
| 109 | + * Mirrors how core post types appear under "+ New", but added manually rather | |
| 110 | + * than via `show_in_admin_bar` so it does not also register a second front-end | |
| 111 | + * "Edit" node alongside the custom one in add_edit_form_to_admin_bar_menu(). | |
| 112 | + * Gated on the form CPT's own create capability (manage_options for this CPT), | |
| 113 | + * so it only shows for users who can actually create a form. | |
| 114 | + * | |
| 115 | + * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance. | |
| 116 | + * @since 2.12.4 | |
| 117 | + * @return void | |
| 118 | + */ | |
| 119 | + public function add_new_form_to_admin_bar_menu( $wp_admin_bar ) { | |
| 120 | + if ( ! is_admin_bar_showing() || ! $wp_admin_bar instanceof WP_Admin_Bar ) { | |
| 121 | + return; | |
| 122 | + } | |
| 123 | + | |
| 124 | + $post_type = get_post_type_object( SRFM_FORMS_POST_TYPE ); | |
| 125 | + | |
| 126 | + if ( ! $post_type || empty( $post_type->cap->create_posts ) || ! current_user_can( $post_type->cap->create_posts ) ) { | |
| 127 | + return; | |
| 128 | + } | |
| 129 | + | |
| 130 | + // Core registers the "+ New" (new-content) group at priority 70, so running at | |
| 131 | + // 100 places this node inside it. If core skipped the group (the user can create | |
| 132 | + // nothing else), WP_Admin_Bar::_bind() drops this orphan node silently. | |
| 133 | + // name_admin_bar is the label core uses for "+ New" children; escaped because | |
| 134 | + // WP_Admin_Bar echoes node titles unescaped. | |
| 135 | + $wp_admin_bar->add_node( | |
| 136 | + [ | |
| 137 | + 'id' => 'new-' . SRFM_FORMS_POST_TYPE, | |
| 138 | + 'parent' => 'new-content', | |
| 139 | + 'title' => esc_html( $post_type->labels->name_admin_bar ), | |
| 140 | + 'href' => esc_url( admin_url( 'post-new.php?post_type=' . SRFM_FORMS_POST_TYPE ) ), | |
| 141 | + ] | |
| 142 | + ); | |
| 143 | + } | |
| 144 | + | |
| 145 | + /** | |
| 146 | + * Remove this method in the future once _srfm_form_confirmation meta is updated. | |
| 147 | + * Normalize the _srfm_form_confirmation meta before it's sent to the REST API. | |
| 148 | + * Ensures the meta data is type-safe and includes necessary defaults like `hide_copy`. | |
| 149 | + * | |
| 150 | + * @param WP_REST_Response $response The REST response object. | |
| 151 | + * @param WP_Post $post The post object. | |
| 152 | + * | |
| 153 | + * @return WP_REST_Response Modified REST response with normalized meta. | |
| 154 | + * @since 1.7.3 | |
| 155 | + */ | |
| 156 | + public function sureforms_normalize_meta_for_rest( $response, $post ) { | |
| 157 | + $meta_raw = get_post_meta( $post->ID, '_srfm_form_confirmation', true ); | |
| 158 | + // Meta may be a PHP array (new forms stored via update_post_meta with an array) | |
| 159 | + // or a serialized/JSON string (legacy forms). Handle both. | |
| 160 | + $form_confirmation = is_array( $meta_raw ) ? $meta_raw : maybe_unserialize( is_string( $meta_raw ) ? $meta_raw : '' ); | |
| 161 | + | |
| 162 | + if ( ! is_array( $form_confirmation ) ) { | |
| 163 | + return $response; | |
| 164 | + } | |
| 165 | + | |
| 166 | + // Only normalize keys that extensions (e.g. SureForms Pro) have actually | |
| 167 | + // declared in the REST schema; otherwise REST PUT validation rejects them | |
| 168 | + // with "<key> is not a valid property of Object.". | |
| 169 | + $registered = get_registered_meta_keys( 'post', SRFM_FORMS_POST_TYPE ); | |
| 170 | + $item_properties = $registered['_srfm_form_confirmation']['show_in_rest']['schema']['items']['properties'] ?? []; | |
| 171 | + | |
| 172 | + foreach ( $form_confirmation as $index => $item ) { | |
| 173 | + if ( ! is_array( $item ) ) { | |
| 174 | + continue; | |
| 175 | + } | |
| 176 | + | |
| 177 | + if ( isset( $item_properties['hide_copy'] ) ) { | |
| 178 | + $form_confirmation[ $index ]['hide_copy'] = ! empty( $item['hide_copy'] ); | |
| 179 | + } | |
| 180 | + if ( isset( $item_properties['hide_download_all'] ) ) { | |
| 181 | + $form_confirmation[ $index ]['hide_download_all'] = ! empty( $item['hide_download_all'] ); | |
| 182 | + } | |
| 183 | + | |
| 184 | + // DOMDocument::saveHTML() strips the "data:" prefix from data URIs in src attributes. | |
| 185 | + // Restore it so the editor displays SVG images correctly. | |
| 186 | + if ( isset( $item['message'] ) && is_string( $item['message'] ) && false !== strpos( $item['message'], 'src="image/svg+xml;base64' ) ) { | |
| 187 | + $normalized = preg_replace( '/src="image\/svg\+xml;base64/', 'src="data:image/svg+xml;base64', $item['message'] ); | |
| 188 | + if ( is_string( $normalized ) ) { | |
| 189 | + $form_confirmation[ $index ]['message'] = $normalized; | |
| 190 | + } | |
| 191 | + } | |
| 192 | + } | |
| 193 | + | |
| 194 | + $response_data = $response->get_data(); | |
| 195 | + if ( is_array( $response_data ) ) { | |
| 196 | + if ( ! isset( $response_data['meta'] ) || ! is_array( $response_data['meta'] ) ) { | |
| 197 | + $response_data['meta'] = []; | |
| 198 | + } | |
| 199 | + | |
| 200 | + $response_data['meta']['_srfm_form_confirmation'] = $form_confirmation; | |
| 201 | + $response->set_data( $response_data ); | |
| 202 | + } | |
| 203 | + return $response; | |
| 204 | + } | |
| 205 | + | |
| 206 | + /** | |
| 56 | 207 | * Add SureForms menu. |
| 57 | 208 | * |
| 58 | 209 | * @param string $title Parent slug. |
| 59 | 210 | * @param string $subtitle Parent slug. |
| @@ -59,25 +210,28 @@ | ||
| 59 | 210 | * @param string $subtitle Parent slug. |
| 60 | 211 | * @param string $image Parent slug. |
| 61 | 212 | * @param string $button_text Parent slug. |
| 62 | 213 | * @param string $button_url Parent slug. |
| 214 | + * @param string $after_button After button content. | |
| 63 | 215 | * @return void |
| 64 | 216 | * @since 0.0.1 |
| 65 | 217 | */ |
| 66 | - public function get_blank_page_markup( $title, $subtitle, $image, $button_text = '', $button_url = '' ) { | |
| 67 | - echo '<div class="sureform-add-new-form">'; | |
| 68 | - | |
| 69 | - echo '<p class="sureform-blank-page-title">' . esc_html( $title ) . '</p>'; | |
| 70 | - | |
| 71 | - echo '<p class="sureform-blank-page-subtitle">' . esc_html( $subtitle ) . '</p>'; | |
| 72 | - | |
| 73 | - echo '<img src="' . esc_url( SRFM_URL . '/images/' . $image . '.svg' ) . '">'; | |
| 74 | - | |
| 75 | - if ( ! empty( $button_text ) && ! empty( $button_url ) ) { | |
| 76 | - echo '<div class="sureforms-add-new-form-container"><a class="sf-add-new-form-button" href="' . esc_url( $button_url ) . '"><div class="button-secondary">' . esc_html( $button_text ) . '</div></a></div>'; | |
| 77 | - } | |
| 78 | - | |
| 79 | - echo '</div>'; | |
| 218 | + public function get_blank_page_markup( $title, $subtitle, $image, $button_text = '', $button_url = '', $after_button = '' ) { | |
| 219 | + ?> | |
| 220 | + <div class="sureform-add-new-form"> | |
| 221 | + <p class="sureform-blank-page-title"><?php echo esc_html( $title ); ?></p> | |
| 222 | + <p class="sureform-blank-page-subtitle"><?php echo esc_html( $subtitle ); ?></p> | |
| 223 | + <img src="<?php echo esc_url( SRFM_URL . '/images/' . $image . '.svg' ); ?>" alt=""/> | |
| 224 | + <?php if ( ! empty( $button_text ) && ! empty( $button_url ) ) { ?> | |
| 225 | + <div class="sureforms-add-new-form-container"> | |
| 226 | + <a class="sf-add-new-form-button" href="<?php echo esc_url( $button_url ); ?>"> | |
| 227 | + <div class="button-secondary"><?php echo esc_html( $button_text ); ?></div> | |
| 228 | + </a> | |
| 229 | + <?php echo wp_kses_post( $after_button ); ?> | |
| 230 | + </div> | |
| 231 | + <?php } ?> | |
| 232 | + </div> | |
| 233 | + <?php | |
| 80 | 234 | } |
| 81 | 235 | |
| 82 | 236 | /** |
| 83 | 237 | * Render blank state for add new form screen. |
| @@ -86,28 +240,11 @@ | ||
| 86 | 240 | * @return void |
| 87 | 241 | * @since 0.0.1 |
| 88 | 242 | */ |
| 89 | 243 | public function sureforms_render_blank_state( $post_type ) { |
| 244 | + if ( SRFM_ENTRIES === $post_type ) { | |
| 90 | 245 | |
| 91 | - if ( SRFM_FORMS_POST_TYPE === $post_type ) { | |
| 92 | - $page_name = 'add-new-form'; | |
| 93 | - $new_form_url = admin_url( 'admin.php?page=' . $page_name ); | |
| 94 | - | |
| 95 | 246 | $this->get_blank_page_markup( |
| 96 | - esc_html__( 'Let’s build your first form', 'sureforms' ), | |
| 97 | - esc_html__( | |
| 98 | - 'Craft beautiful and functional forms in minutes', | |
| 99 | - 'sureforms' | |
| 100 | - ), | |
| 101 | - 'add-new-form', | |
| 102 | - esc_html__( 'Add New Form', 'sureforms' ), | |
| 103 | - $new_form_url | |
| 104 | - ); | |
| 105 | - } | |
| 106 | - | |
| 107 | - if ( SRFM_ENTRIES_POST_TYPE === $post_type ) { | |
| 108 | - | |
| 109 | - $this->get_blank_page_markup( | |
| 110 | 247 | esc_html__( 'No records found', 'sureforms' ), |
| 111 | 248 | esc_html__( |
| 112 | 249 | 'This is where your form entries will appear', |
| 113 | 250 | 'sureforms' |
| @@ -148,67 +285,23 @@ | ||
| 148 | 285 | 'labels' => $form_labels, |
| 149 | 286 | 'rewrite' => [ 'slug' => 'form' ], |
| 150 | 287 | 'public' => true, |
| 151 | 288 | 'show_in_rest' => true, |
| 152 | - 'has_archive' => false, | |
| 289 | + 'has_archive' => true, | |
| 153 | 290 | 'show_ui' => true, |
| 154 | 291 | 'supports' => [ 'title', 'author', 'editor', 'custom-fields' ], |
| 155 | - 'show_in_menu' => 'sureforms_menu', | |
| 292 | + 'show_in_menu' => false, | |
| 156 | 293 | 'show_in_nav_menus' => true, |
| 157 | - ] | |
| 158 | - ); | |
| 159 | - | |
| 160 | - $result_labels = [ | |
| 161 | - 'name' => _x( 'Entries', 'post type general name', 'sureforms' ), | |
| 162 | - 'singular_name' => _x( 'Entry', 'post type singular name', 'sureforms' ), | |
| 163 | - 'menu_name' => _x( 'Entries', 'admin menu', 'sureforms' ), | |
| 164 | - 'name_admin_bar' => _x( 'Entry', 'add new on admin bar', 'sureforms' ), | |
| 165 | - 'add_new' => _x( 'Add New', 'Entry', 'sureforms' ), | |
| 166 | - 'add_new_item' => __( 'Add New Entry', 'sureforms' ), | |
| 167 | - 'new_item' => __( 'New Entry', 'sureforms' ), | |
| 168 | - 'edit_item' => __( 'View Entry', 'sureforms' ), | |
| 169 | - 'view_item' => __( 'View Entry', 'sureforms' ), | |
| 170 | - 'all_items' => __( 'Entries', 'sureforms' ), | |
| 171 | - 'search_items' => __( 'Search Entries', 'sureforms' ), | |
| 172 | - 'parent_item_colon' => __( 'Parent Entries:', 'sureforms' ), | |
| 173 | - 'not_found' => __( 'No results found.', 'sureforms' ), | |
| 174 | - 'not_found_in_trash' => __( 'No results found in Trash.', 'sureforms' ), | |
| 175 | - ]; | |
| 176 | - register_post_type( | |
| 177 | - SRFM_ENTRIES_POST_TYPE, | |
| 178 | - [ | |
| 179 | - 'labels' => $result_labels, | |
| 180 | - 'supports' => [ 'title' ], | |
| 181 | - 'public' => false, | |
| 182 | - 'show_in_rest' => true, | |
| 183 | - 'exclude_from_search' => true, | |
| 184 | - 'publicly_queryable' => false, | |
| 185 | - 'has_archive' => true, | |
| 186 | - 'capability_type' => 'post', | |
| 187 | - 'capabilities' => [ | |
| 188 | - 'create_posts' => 'do_not_allow', | |
| 189 | - ], | |
| 190 | - 'map_meta_cap' => true, | |
| 191 | - 'show_ui' => true, | |
| 192 | - 'show_in_menu' => 'sureforms_menu', | |
| 193 | - ] | |
| 194 | - ); | |
| 195 | - register_taxonomy( | |
| 196 | - 'sureforms_tax', | |
| 197 | - 'sureforms_entry', | |
| 198 | - [ | |
| 199 | - 'label' => __( 'Form ID', 'sureforms' ), | |
| 200 | - 'hierarchical' => true, | |
| 201 | 294 | 'capabilities' => [ |
| 202 | - 'assign_terms' => 'god', | |
| 203 | - 'edit_terms' => 'god', | |
| 204 | - 'manage_terms' => 'god', | |
| 295 | + 'edit_post' => 'manage_options', | |
| 296 | + 'read_post' => 'manage_options', | |
| 297 | + 'delete_post' => 'manage_options', | |
| 298 | + 'edit_posts' => 'manage_options', | |
| 299 | + 'edit_others_posts' => 'manage_options', | |
| 300 | + 'publish_posts' => 'manage_options', | |
| 301 | + 'read_private_posts' => 'manage_options', | |
| 302 | + 'create_posts' => 'manage_options', | |
| 205 | 303 | ], |
| 206 | - 'public' => false, | |
| 207 | - 'show_in_rest' => true, | |
| 208 | - 'show_admin_column' => false, | |
| 209 | - 'show_in_nav_menus' => false, | |
| 210 | - 'show_ui' => false, | |
| 211 | 304 | ] |
| 212 | 305 | ); |
| 213 | 306 | // will be used later. |
| 214 | 307 | // register_post_status( |
| @@ -225,108 +318,21 @@ | ||
| 225 | 318 | // );. |
| 226 | 319 | } |
| 227 | 320 | |
| 228 | 321 | /** |
| 229 | - * Remove add new form menu item. | |
| 322 | + * Redirects requests for SureForms archieve page to homeurl | |
| 230 | 323 | * |
| 231 | - * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance. | |
| 232 | - * | |
| 324 | + * @since 1.4.0 | |
| 233 | 325 | * @return void |
| 234 | - * @since 0.0.1 | |
| 235 | 326 | */ |
| 236 | - public function remove_admin_bar_menu_item( $wp_admin_bar ) { | |
| 237 | - $wp_admin_bar->remove_node( 'new-sureforms_form' ); | |
| 238 | - } | |
| 239 | - | |
| 240 | - /** | |
| 241 | - * Modify post update message for Entry post type. | |
| 242 | - * | |
| 243 | - * @param string $messages Post type. | |
| 244 | - * @return string | |
| 245 | - * @since 0.0.1 | |
| 246 | - */ | |
| 247 | - public function entries_updated_message( $messages ) { | |
| 248 | - global $post_ID; | |
| 249 | - | |
| 250 | - $post_type = get_post_type( $post_ID ); | |
| 251 | - | |
| 252 | - if ( SRFM_ENTRIES_POST_TYPE === $post_type ) { | |
| 253 | - // @phpstan-ignore-next-line -- False positive | |
| 254 | - $messages['post'][1] = __( 'Entry updated.', 'sureforms' ); | |
| 327 | + public function disable_sureforms_archive_page() { | |
| 328 | + if ( is_post_type_archive( SRFM_FORMS_POST_TYPE ) ) { | |
| 329 | + wp_safe_redirect( home_url(), 301 ); | |
| 330 | + exit; | |
| 255 | 331 | } |
| 256 | - | |
| 257 | - return $messages; | |
| 258 | 332 | } |
| 259 | 333 | |
| 260 | 334 | /** |
| 261 | - * Remove publishing actions from single entries page. | |
| 262 | - * | |
| 263 | - * @return void | |
| 264 | - * @since 0.0.1 | |
| 265 | - */ | |
| 266 | - public function remove_entries_publishing_actions() { | |
| 267 | - global $typenow; | |
| 268 | - if ( 'sureforms_entry' === $typenow ) { ?> | |
| 269 | - <style> | |
| 270 | - .misc-pub-post-status { | |
| 271 | - display: none !important; | |
| 272 | - } | |
| 273 | - .misc-pub-visibility { | |
| 274 | - display: none !important; | |
| 275 | - } | |
| 276 | - </style> | |
| 277 | - <?php | |
| 278 | - } | |
| 279 | - } | |
| 280 | - | |
| 281 | - /** | |
| 282 | - * Modify list row actions. | |
| 283 | - * | |
| 284 | - * @param array<mixed> $actions An array of row action links. | |
| 285 | - * @param \WP_Post $post The current WP_Post object. | |
| 286 | - * | |
| 287 | - * @return array<mixed> $actions Modified row action links. | |
| 288 | - * @since 0.0.1 | |
| 289 | - */ | |
| 290 | - public function modify_entries_list_row_actions( $actions, $post ) { | |
| 291 | - if ( 'sureforms_entry' === $post->post_type ) { | |
| 292 | - $actions['edit'] = '<a href="' . get_edit_post_link( $post->ID ) . '">View</a>'; | |
| 293 | - } | |
| 294 | - if ( 'sureforms_form' === $post->post_type ) { | |
| 295 | - $actions['export'] = '<a href="#" onclick="exportForm(' . $post->ID . ')">Export</a>'; | |
| 296 | - } | |
| 297 | - | |
| 298 | - return $actions; | |
| 299 | - } | |
| 300 | - | |
| 301 | - /** | |
| 302 | - * Modify list bulk actions. | |
| 303 | - * | |
| 304 | - * @param array<mixed> $bulk_actions An array of bulk action links. | |
| 305 | - * @since 0.0.1 | |
| 306 | - * @return array<mixed> $bulk_actions Modified action links. | |
| 307 | - */ | |
| 308 | - public function register_modify_bulk_actions( $bulk_actions ) { | |
| 309 | - | |
| 310 | - $white_listed_actions = [ | |
| 311 | - 'edit', | |
| 312 | - 'trash', | |
| 313 | - 'delete', | |
| 314 | - 'untrash', | |
| 315 | - ]; | |
| 316 | - | |
| 317 | - // remove all actions except white listed actions. | |
| 318 | - $bulk_actions = array_intersect_key( $bulk_actions, array_flip( $white_listed_actions ) ); | |
| 319 | - | |
| 320 | - // Add export action only if edit and trash actions are present in bulk actions. | |
| 321 | - if ( isset( $bulk_actions['edit'] ) && isset( $bulk_actions['trash'] ) ) { | |
| 322 | - $bulk_actions['export'] = __( 'Export', 'sureforms' ); | |
| 323 | - } | |
| 324 | - | |
| 325 | - return $bulk_actions; | |
| 326 | - } | |
| 327 | - | |
| 328 | - /** | |
| 329 | 335 | * Show blank slate styles. |
| 330 | 336 | * |
| 331 | 337 | * @return void |
| 332 | 338 | * @since 0.0.1 |
| @@ -331,9 +337,51 @@ | ||
| 331 | 337 | * @return void |
| 332 | 338 | * @since 0.0.1 |
| 333 | 339 | */ |
| 334 | 340 | public function get_blank_state_styles() { |
| 335 | - echo '<style type="text/css">.sf-add-new-form-button:focus { box-shadow:none !important; outline:none !important; } #posts-filter .wp-list-table, #posts-filter .tablenav.top, .tablenav.bottom .actions, .wrap .subsubsub { display: none; } #posts-filter .tablenav.bottom { height: auto; } .sureform-add-new-form{ display: flex; flex-direction: column; gap: 8px; justify-content: center; align-items: center; padding: 24px 0 24px 0; } .sureform-blank-page-title { color: var(--dashboard-heading); font-family: Inter; font-size: 22px; font-style: normal; font-weight: 600; line-height: 28px; margin: 0; } .sureform-blank-page-subtitle { color: var(--dashboard-text); margin: 0; font-family: Inter; font-size: 14px; font-style: normal; font-weight: 400; line-height: 16px; }</style>'; | |
| 341 | + ?> | |
| 342 | + <style type="text/css"> | |
| 343 | + .sf-add-new-form-button:focus { | |
| 344 | + box-shadow: none !important; | |
| 345 | + outline: none !important; | |
| 346 | + } | |
| 347 | + #posts-filter .wp-list-table, | |
| 348 | + #posts-filter .tablenav.top, | |
| 349 | + .tablenav.bottom .actions, | |
| 350 | + .wrap .subsubsub { | |
| 351 | + display: none; | |
| 352 | + } | |
| 353 | + #posts-filter .tablenav.bottom { | |
| 354 | + height: auto; | |
| 355 | + } | |
| 356 | + .sureform-add-new-form { | |
| 357 | + display: flex; | |
| 358 | + flex-direction: column; | |
| 359 | + gap: 8px; | |
| 360 | + justify-content: center; | |
| 361 | + align-items: center; | |
| 362 | + padding: 24px 0 24px 0; | |
| 363 | + } | |
| 364 | + .sureform-blank-page-title { | |
| 365 | + color: var(--dashboard-heading); | |
| 366 | + font-family: Inter; | |
| 367 | + font-size: 22px; | |
| 368 | + font-style: normal; | |
| 369 | + font-weight: 600; | |
| 370 | + line-height: 28px; | |
| 371 | + margin: 0; | |
| 372 | + } | |
| 373 | + .sureform-blank-page-subtitle { | |
| 374 | + color: var(--dashboard-text); | |
| 375 | + margin: 0; | |
| 376 | + font-family: Inter; | |
| 377 | + font-size: 14px; | |
| 378 | + font-style: normal; | |
| 379 | + font-weight: 400; | |
| 380 | + line-height: 16px; | |
| 381 | + } | |
| 382 | + </style> | |
| 383 | + <?php | |
| 336 | 384 | } |
| 337 | 385 | |
| 338 | 386 | /** |
| 339 | 387 | * Show blank slate. |
| @@ -360,51 +408,11 @@ | ||
| 360 | 408 | |
| 361 | 409 | $this->get_blank_state_styles(); |
| 362 | 410 | |
| 363 | 411 | } |
| 364 | - | |
| 365 | - if ( SRFM_ENTRIES_POST_TYPE === $post_type && 'bottom' === $which ) { | |
| 366 | - | |
| 367 | - $counts = (array) wp_count_posts( SRFM_ENTRIES_POST_TYPE ); | |
| 368 | - unset( $counts['auto-draft'] ); | |
| 369 | - $count = array_sum( $counts ); | |
| 370 | - | |
| 371 | - if ( 0 < $count ) { | |
| 372 | - return; | |
| 373 | - } | |
| 374 | - | |
| 375 | - $this->sureforms_render_blank_state( $post_type ); | |
| 376 | - | |
| 377 | - $this->get_blank_state_styles(); | |
| 378 | - | |
| 379 | - } | |
| 380 | 412 | } |
| 381 | 413 | |
| 382 | 414 | /** |
| 383 | - * Set up a div for the header to render into it. | |
| 384 | - * | |
| 385 | - * @return void | |
| 386 | - * @since 0.0.1 | |
| 387 | - */ | |
| 388 | - public static function embed_page_header() { | |
| 389 | - $screen = get_current_screen(); | |
| 390 | - $screen_id = $screen ? $screen->id : ''; | |
| 391 | - | |
| 392 | - if ( 'edit-' . SRFM_FORMS_POST_TYPE === $screen_id || 'edit-' . SRFM_ENTRIES_POST_TYPE === $screen_id ) { | |
| 393 | - ?> | |
| 394 | - <style> | |
| 395 | - .srfm-page-header { | |
| 396 | - @media screen and ( max-width: 600px ) { | |
| 397 | - padding-top: 46px; | |
| 398 | - } | |
| 399 | - } | |
| 400 | - </style> | |
| 401 | - <div id="srfm-page-header" class="srfm-page-header"></div> | |
| 402 | - <?php | |
| 403 | - } | |
| 404 | - } | |
| 405 | - | |
| 406 | - /** | |
| 407 | 415 | * Registers the sureforms metas. |
| 408 | 416 | * |
| 409 | 417 | * @return void |
| 410 | 418 | * @since 0.0.1 |
| @@ -434,42 +442,71 @@ | ||
| 434 | 442 | '_srfm_submit_type' => 'string', |
| 435 | 443 | // Security. |
| 436 | 444 | '_srfm_captcha_security_type' => 'string', |
| 437 | 445 | '_srfm_form_recaptcha' => 'string', |
| 446 | + // post meta to store if the form is AI generated. | |
| 447 | + '_srfm_is_ai_generated' => 'boolean', | |
| 438 | 448 | ] |
| 439 | 449 | ); |
| 440 | 450 | |
| 451 | + // NOTE: `_srfm_form_views` is intentionally NOT registered here. It is a | |
| 452 | + // server-side counter written only by Form_Views (get/add_post_meta + atomic | |
| 453 | + // SQL). Exposing it to the block editor via show_in_rest let a form save / | |
| 454 | + // autosave round-trip a stale value and clobber the live count back to 0. | |
| 455 | + | |
| 441 | 456 | // Form Custom CSS meta. |
| 442 | 457 | register_post_meta( |
| 443 | 458 | 'sureforms_form', |
| 444 | 459 | '_srfm_form_custom_css', |
| 445 | 460 | [ |
| 446 | - 'show_in_rest' => true, | |
| 461 | + 'show_in_rest' => [ | |
| 462 | + 'schema' => [ | |
| 463 | + 'type' => 'string', | |
| 464 | + 'context' => [ 'edit' ], | |
| 465 | + ], | |
| 466 | + ], | |
| 447 | 467 | 'type' => 'string', |
| 448 | 468 | 'single' => true, |
| 449 | - 'auth_callback' => function() { | |
| 450 | - return current_user_can( 'edit_posts' ); | |
| 469 | + 'auth_callback' => static function() { | |
| 470 | + return Helper::current_user_can(); | |
| 451 | 471 | }, |
| 452 | - 'sanitize_callback' => function( $meta_value ) { | |
| 472 | + 'sanitize_callback' => static function( $meta_value ) { | |
| 453 | 473 | return wp_kses_post( $meta_value ); |
| 454 | 474 | }, |
| 455 | 475 | ] |
| 456 | 476 | ); |
| 457 | 477 | |
| 478 | + // Get default values for meta keys. | |
| 479 | + $default_meta_keys = Create_New_Form::get_default_meta_keys(); | |
| 480 | + | |
| 458 | 481 | foreach ( $metas as $meta => $type ) { |
| 459 | - register_meta( | |
| 460 | - 'post', | |
| 482 | + // Get default value if exists. | |
| 483 | + $default_value = $default_meta_keys[ $meta ] ?? null; | |
| 484 | + | |
| 485 | + $meta_args = [ | |
| 486 | + 'show_in_rest' => [ | |
| 487 | + 'schema' => [ | |
| 488 | + 'type' => $type, | |
| 489 | + 'context' => [ 'edit' ], | |
| 490 | + ], | |
| 491 | + ], | |
| 492 | + 'single' => true, | |
| 493 | + 'type' => $type, | |
| 494 | + 'sanitize_callback' => 'sanitize_text_field', | |
| 495 | + 'auth_callback' => static function() { | |
| 496 | + return Helper::current_user_can(); | |
| 497 | + }, | |
| 498 | + ]; | |
| 499 | + | |
| 500 | + // Add default value if it exists. | |
| 501 | + if ( null !== $default_value ) { | |
| 502 | + $meta_args['default'] = $default_value; | |
| 503 | + } | |
| 504 | + | |
| 505 | + register_post_meta( | |
| 506 | + SRFM_FORMS_POST_TYPE, | |
| 461 | 507 | $meta, |
| 462 | - [ | |
| 463 | - 'object_subtype' => SRFM_FORMS_POST_TYPE, | |
| 464 | - 'show_in_rest' => true, | |
| 465 | - 'single' => true, | |
| 466 | - 'type' => $type, | |
| 467 | - 'sanitize_callback' => 'sanitize_text_field', | |
| 468 | - 'auth_callback' => function() { | |
| 469 | - return current_user_can( 'edit_posts' ); | |
| 470 | - }, | |
| 471 | - ] | |
| 508 | + $meta_args | |
| 472 | 509 | ); |
| 473 | 510 | } |
| 474 | 511 | |
| 475 | 512 | // Registers meta to handle values associated with form styling. |
| @@ -476,14 +513,38 @@ | ||
| 476 | 513 | register_post_meta( |
| 477 | 514 | SRFM_FORMS_POST_TYPE, |
| 478 | 515 | '_srfm_instant_form_settings', |
| 479 | 516 | [ |
| 480 | - 'single' => true, | |
| 481 | - 'type' => 'object', | |
| 482 | - 'auth_callback' => '__return_true', | |
| 483 | - 'show_in_rest' => [ | |
| 517 | + 'single' => true, | |
| 518 | + 'type' => 'object', | |
| 519 | + 'auth_callback' => static function() { | |
| 520 | + return Helper::current_user_can(); | |
| 521 | + }, | |
| 522 | + 'sanitize_callback' => static function( $meta_value ) { | |
| 523 | + if ( ! is_array( $meta_value ) ) { | |
| 524 | + return []; | |
| 525 | + } | |
| 526 | + return [ | |
| 527 | + 'site_logo' => isset( $meta_value['site_logo'] ) ? esc_url_raw( $meta_value['site_logo'] ) : '', | |
| 528 | + 'site_logo_id' => isset( $meta_value['site_logo_id'] ) ? absint( $meta_value['site_logo_id'] ) : 0, | |
| 529 | + 'cover_type' => isset( $meta_value['cover_type'] ) ? sanitize_text_field( $meta_value['cover_type'] ) : '', | |
| 530 | + 'cover_color' => isset( $meta_value['cover_color'] ) ? sanitize_text_field( $meta_value['cover_color'] ) : '', | |
| 531 | + 'cover_image' => isset( $meta_value['cover_image'] ) ? esc_url_raw( $meta_value['cover_image'] ) : '', | |
| 532 | + 'cover_image_id' => isset( $meta_value['cover_image_id'] ) ? absint( $meta_value['cover_image_id'] ) : 0, | |
| 533 | + 'bg_type' => isset( $meta_value['bg_type'] ) ? sanitize_text_field( $meta_value['bg_type'] ) : '', | |
| 534 | + 'bg_color' => isset( $meta_value['bg_color'] ) ? sanitize_text_field( $meta_value['bg_color'] ) : '', | |
| 535 | + 'bg_image' => isset( $meta_value['bg_image'] ) ? esc_url_raw( $meta_value['bg_image'] ) : '', | |
| 536 | + 'bg_image_id' => isset( $meta_value['bg_image_id'] ) ? absint( $meta_value['bg_image_id'] ) : 0, | |
| 537 | + 'enable_instant_form' => isset( $meta_value['enable_instant_form'] ) ? filter_var( $meta_value['enable_instant_form'], FILTER_VALIDATE_BOOLEAN ) : false, | |
| 538 | + 'form_container_width' => isset( $meta_value['form_container_width'] ) ? absint( $meta_value['form_container_width'] ) : 620, | |
| 539 | + 'single_page_form_title' => isset( $meta_value['single_page_form_title'] ) ? filter_var( $meta_value['single_page_form_title'], FILTER_VALIDATE_BOOLEAN ) : true, | |
| 540 | + 'use_banner_as_page_background' => isset( $meta_value['use_banner_as_page_background'] ) ? filter_var( $meta_value['use_banner_as_page_background'], FILTER_VALIDATE_BOOLEAN ) : false, | |
| 541 | + ]; | |
| 542 | + }, | |
| 543 | + 'show_in_rest' => [ | |
| 484 | 544 | 'schema' => [ |
| 485 | 545 | 'type' => 'object', |
| 546 | + 'context' => [ 'edit' ], | |
| 486 | 547 | 'properties' => [ |
| 487 | 548 | 'site_logo' => [ |
| 488 | 549 | 'type' => 'string', |
| 489 | 550 | ], |
| @@ -530,15 +591,15 @@ | ||
| 530 | 591 | ], |
| 531 | 592 | ], |
| 532 | 593 | ], |
| 533 | 594 | ], |
| 534 | - 'default' => [ | |
| 595 | + 'default' => [ | |
| 535 | 596 | 'bg_type' => 'color', |
| 536 | 597 | 'bg_color' => '#ffffff', |
| 537 | 598 | 'bg_image' => '', |
| 538 | 599 | 'site_logo' => '', |
| 539 | 600 | 'cover_type' => 'color', |
| 540 | - 'cover_color' => '#0C78FB', | |
| 601 | + 'cover_color' => '#111C44', | |
| 541 | 602 | 'cover_image' => '', |
| 542 | 603 | 'enable_instant_form' => false, |
| 543 | 604 | 'form_container_width' => 620, |
| 544 | 605 | 'single_page_form_title' => true, |
| @@ -550,39 +611,337 @@ | ||
| 550 | 611 | register_post_meta( |
| 551 | 612 | SRFM_FORMS_POST_TYPE, |
| 552 | 613 | '_srfm_forms_styling', |
| 553 | 614 | [ |
| 554 | - 'single' => true, | |
| 555 | - 'type' => 'object', | |
| 556 | - 'auth_callback' => '__return_true', | |
| 557 | - 'show_in_rest' => [ | |
| 615 | + 'single' => true, | |
| 616 | + 'type' => 'object', | |
| 617 | + 'auth_callback' => static function() { | |
| 618 | + return Helper::current_user_can(); | |
| 619 | + }, | |
| 620 | + 'sanitize_callback' => static function( $meta_value ) { | |
| 621 | + return Helper::sanitize_by_type( $meta_value ); | |
| 622 | + }, | |
| 623 | + 'show_in_rest' => [ | |
| 558 | 624 | 'schema' => [ |
| 559 | 625 | 'type' => 'object', |
| 626 | + 'context' => [ 'edit' ], | |
| 560 | 627 | 'properties' => [ |
| 561 | - 'primary_color' => [ | |
| 628 | + 'primary_color' => [ | |
| 562 | 629 | 'type' => 'string', |
| 563 | 630 | ], |
| 564 | - 'text_color' => [ | |
| 631 | + 'text_color' => [ | |
| 565 | 632 | 'type' => 'string', |
| 566 | 633 | ], |
| 567 | - 'text_color_on_primary' => [ | |
| 634 | + 'text_color_on_primary' => [ | |
| 568 | 635 | 'type' => 'string', |
| 569 | 636 | ], |
| 570 | - 'field_spacing' => [ | |
| 637 | + 'field_spacing' => [ | |
| 571 | 638 | 'type' => 'string', |
| 572 | 639 | ], |
| 573 | - 'submit_button_alignment' => [ | |
| 640 | + 'submit_button_alignment' => [ | |
| 574 | 641 | 'type' => 'string', |
| 575 | 642 | ], |
| 643 | + 'bg_type' => [ | |
| 644 | + 'type' => 'string', | |
| 645 | + ], | |
| 646 | + 'bg_color' => [ | |
| 647 | + 'type' => 'string', | |
| 648 | + ], | |
| 649 | + 'bg_image' => [ | |
| 650 | + 'type' => 'string', | |
| 651 | + ], | |
| 652 | + 'bg_image_id' => [ | |
| 653 | + 'type' => 'integer', | |
| 654 | + ], | |
| 655 | + // Image Properties. | |
| 656 | + 'bg_image_position' => [ | |
| 657 | + 'type' => 'object', | |
| 658 | + 'properties' => [ | |
| 659 | + 'x' => [ | |
| 660 | + 'type' => 'number', | |
| 661 | + 'format' => 'float', | |
| 662 | + ], | |
| 663 | + 'y' => [ | |
| 664 | + 'type' => 'number', | |
| 665 | + 'format' => 'float', | |
| 666 | + ], | |
| 667 | + ], | |
| 668 | + ], | |
| 669 | + 'bg_image_attachment' => [ | |
| 670 | + 'type' => 'string', | |
| 671 | + ], | |
| 672 | + 'bg_image_repeat' => [ | |
| 673 | + 'type' => 'string', | |
| 674 | + ], | |
| 675 | + 'bg_image_size' => [ | |
| 676 | + 'type' => 'string', | |
| 677 | + ], | |
| 678 | + 'bg_image_size_custom' => [ | |
| 679 | + 'type' => 'integer', | |
| 680 | + ], | |
| 681 | + 'bg_image_size_custom_unit' => [ | |
| 682 | + 'type' => 'string', | |
| 683 | + ], | |
| 684 | + // Gradient Properties. | |
| 685 | + 'bg_gradient' => [ | |
| 686 | + 'type' => 'string', | |
| 687 | + ], | |
| 688 | + 'gradient_type' => [ | |
| 689 | + 'type' => 'string', | |
| 690 | + ], | |
| 691 | + 'bg_gradient_type' => [ | |
| 692 | + 'type' => 'string', | |
| 693 | + ], | |
| 694 | + 'bg_gradient_color_1' => [ | |
| 695 | + 'type' => 'string', | |
| 696 | + ], | |
| 697 | + 'bg_gradient_color_2' => [ | |
| 698 | + 'type' => 'string', | |
| 699 | + ], | |
| 700 | + 'bg_gradient_angle' => [ | |
| 701 | + 'type' => 'integer', | |
| 702 | + ], | |
| 703 | + 'bg_gradient_location_1' => [ | |
| 704 | + 'type' => 'integer', | |
| 705 | + ], | |
| 706 | + 'bg_gradient_location_2' => [ | |
| 707 | + 'type' => 'integer', | |
| 708 | + ], | |
| 709 | + // Overlay Properties. | |
| 710 | + 'bg_overlay_size' => [ | |
| 711 | + 'type' => 'string', | |
| 712 | + ], | |
| 713 | + 'bg_gradient_overlay_type' => [ | |
| 714 | + 'type' => 'string', | |
| 715 | + ], | |
| 716 | + 'bg_overlay_opacity' => [ | |
| 717 | + 'type' => 'number', | |
| 718 | + ], | |
| 719 | + 'bg_overlay_image' => [ | |
| 720 | + 'type' => 'string', | |
| 721 | + ], | |
| 722 | + 'bg_overlay_image_id' => [ | |
| 723 | + 'type' => 'integer', | |
| 724 | + ], | |
| 725 | + 'bg_image_overlay_color' => [ | |
| 726 | + 'type' => 'string', | |
| 727 | + ], | |
| 728 | + 'bg_overlay_custom_size_unit' => [ | |
| 729 | + 'type' => 'string', | |
| 730 | + ], | |
| 731 | + 'bg_overlay_custom_size' => [ | |
| 732 | + 'type' => 'integer', | |
| 733 | + ], | |
| 734 | + 'bg_overlay_blend_mode' => [ | |
| 735 | + 'type' => 'string', | |
| 736 | + ], | |
| 737 | + 'bg_overlay_position' => [ | |
| 738 | + 'type' => 'object', | |
| 739 | + 'properties' => [ | |
| 740 | + 'x' => [ | |
| 741 | + 'type' => 'number', | |
| 742 | + 'format' => 'float', | |
| 743 | + ], | |
| 744 | + 'y' => [ | |
| 745 | + 'type' => 'number', | |
| 746 | + 'format' => 'float', | |
| 747 | + ], | |
| 748 | + ], | |
| 749 | + ], | |
| 750 | + 'bg_overlay_attachment' => [ | |
| 751 | + 'type' => 'string', | |
| 752 | + ], | |
| 753 | + 'bg_overlay_repeat' => [ | |
| 754 | + 'type' => 'string', | |
| 755 | + ], | |
| 756 | + // Gradient Overlay Properties. | |
| 757 | + 'bg_overlay_gradient' => [ | |
| 758 | + 'type' => 'string', | |
| 759 | + ], | |
| 760 | + 'overlay_gradient_type' => [ | |
| 761 | + 'type' => 'string', | |
| 762 | + ], | |
| 763 | + 'bg_overlay_gradient_type' => [ | |
| 764 | + 'type' => 'string', | |
| 765 | + ], | |
| 766 | + 'bg_overlay_gradient_color_1' => [ | |
| 767 | + 'type' => 'string', | |
| 768 | + ], | |
| 769 | + 'bg_overlay_gradient_color_2' => [ | |
| 770 | + 'type' => 'string', | |
| 771 | + ], | |
| 772 | + 'bg_overlay_gradient_angle' => [ | |
| 773 | + 'type' => 'integer', | |
| 774 | + ], | |
| 775 | + 'bg_overlay_gradient_location_1' => [ | |
| 776 | + 'type' => 'integer', | |
| 777 | + ], | |
| 778 | + 'bg_overlay_gradient_location_2' => [ | |
| 779 | + 'type' => 'integer', | |
| 780 | + ], | |
| 781 | + // Form Padding. | |
| 782 | + 'form_padding_top' => [ | |
| 783 | + 'type' => 'number', | |
| 784 | + ], | |
| 785 | + 'form_padding_right' => [ | |
| 786 | + 'type' => 'number', | |
| 787 | + ], | |
| 788 | + 'form_padding_bottom' => [ | |
| 789 | + 'type' => 'number', | |
| 790 | + ], | |
| 791 | + 'form_padding_left' => [ | |
| 792 | + 'type' => 'number', | |
| 793 | + ], | |
| 794 | + 'form_padding_unit' => [ | |
| 795 | + 'type' => 'string', | |
| 796 | + ], | |
| 797 | + 'form_padding_link' => [ | |
| 798 | + 'type' => 'boolean', | |
| 799 | + ], | |
| 800 | + // Border Radius. | |
| 801 | + 'form_border_radius_top' => [ | |
| 802 | + 'type' => 'number', | |
| 803 | + ], | |
| 804 | + 'form_border_radius_right' => [ | |
| 805 | + 'type' => 'number', | |
| 806 | + ], | |
| 807 | + 'form_border_radius_bottom' => [ | |
| 808 | + 'type' => 'number', | |
| 809 | + ], | |
| 810 | + 'form_border_radius_left' => [ | |
| 811 | + 'type' => 'number', | |
| 812 | + ], | |
| 813 | + 'form_border_radius_unit' => [ | |
| 814 | + 'type' => 'string', | |
| 815 | + ], | |
| 816 | + 'form_border_radius_link' => [ | |
| 817 | + 'type' => 'boolean', | |
| 818 | + ], | |
| 819 | + // Form Padding and Border Radius. | |
| 820 | + // Form Padding. | |
| 821 | + 'instant_form_padding_top' => [ | |
| 822 | + 'type' => 'number', | |
| 823 | + ], | |
| 824 | + 'instant_form_padding_right' => [ | |
| 825 | + 'type' => 'number', | |
| 826 | + ], | |
| 827 | + 'instant_form_padding_bottom' => [ | |
| 828 | + 'type' => 'number', | |
| 829 | + ], | |
| 830 | + 'instant_form_padding_left' => [ | |
| 831 | + 'type' => 'number', | |
| 832 | + ], | |
| 833 | + 'instant_form_padding_unit' => [ | |
| 834 | + 'type' => 'string', | |
| 835 | + ], | |
| 836 | + 'instant_form_padding_link' => [ | |
| 837 | + 'type' => 'boolean', | |
| 838 | + ], | |
| 839 | + // Border Radius. | |
| 840 | + 'instant_form_border_radius_top' => [ | |
| 841 | + 'type' => 'number', | |
| 842 | + ], | |
| 843 | + 'instant_form_border_radius_right' => [ | |
| 844 | + 'type' => 'number', | |
| 845 | + ], | |
| 846 | + 'instant_form_border_radius_bottom' => [ | |
| 847 | + 'type' => 'number', | |
| 848 | + ], | |
| 849 | + 'instant_form_border_radius_left' => [ | |
| 850 | + 'type' => 'number', | |
| 851 | + ], | |
| 852 | + 'instant_form_border_radius_unit' => [ | |
| 853 | + 'type' => 'string', | |
| 854 | + ], | |
| 855 | + 'instant_form_border_radius_link' => [ | |
| 856 | + 'type' => 'boolean', | |
| 857 | + ], | |
| 858 | + // Disable default SureForms styling. | |
| 859 | + 'disable_default_styles' => [ | |
| 860 | + 'type' => 'boolean', | |
| 861 | + ], | |
| 576 | 862 | ], |
| 577 | 863 | ], |
| 578 | 864 | ], |
| 579 | - 'default' => [ | |
| 580 | - 'primary_color' => '#0C78FB', | |
| 581 | - 'text_color' => '#1E1E1E', | |
| 582 | - 'text_color_on_primary' => '#FFFFFF', | |
| 583 | - 'field_spacing' => 'medium', | |
| 584 | - 'submit_button_alignment' => 'left', | |
| 865 | + 'default' => [ | |
| 866 | + 'primary_color' => '#111C44', | |
| 867 | + 'text_color' => '#1E1E1E', | |
| 868 | + 'text_color_on_primary' => '#FFFFFF', | |
| 869 | + 'field_spacing' => 'medium', | |
| 870 | + 'submit_button_alignment' => 'left', | |
| 871 | + 'bg_type' => 'color', | |
| 872 | + 'bg_color' => '#ffffff', | |
| 873 | + 'bg_image' => '', | |
| 874 | + 'bg_image_position' => [ | |
| 875 | + 'x' => 0.5, | |
| 876 | + 'y' => 0.5, | |
| 877 | + ], | |
| 878 | + 'bg_image_attachment' => 'scroll', | |
| 879 | + 'bg_image_repeat' => 'no-repeat', | |
| 880 | + 'bg_image_size' => 'cover', | |
| 881 | + 'bg_image_size_custom' => 100, // Image width when set to custom. | |
| 882 | + 'bg_image_size_custom_unit' => '%', | |
| 883 | + 'gradient_type' => 'basic', | |
| 884 | + 'bg_gradient_type' => 'linear', | |
| 885 | + 'bg_gradient_color_1' => '#FFC9B2', | |
| 886 | + 'bg_gradient_color_2' => '#C7CBFF', | |
| 887 | + 'bg_gradient_angle' => 90, | |
| 888 | + 'bg_gradient_location_1' => 0, | |
| 889 | + 'bg_gradient_location_2' => 100, | |
| 890 | + 'bg_overlay_size' => 'cover', | |
| 891 | + 'bg_gradient_overlay_type' => '', | |
| 892 | + 'bg_overlay_opacity' => 1, | |
| 893 | + 'bg_overlay_image' => '', | |
| 894 | + 'bg_image_overlay_color' => '#FFFFFF75', | |
| 895 | + 'bg_overlay_custom_size_unit' => '%', | |
| 896 | + 'bg_overlay_custom_size' => 100, | |
| 897 | + 'bg_overlay_position' => [ | |
| 898 | + 'x' => 0.5, | |
| 899 | + 'y' => 0.5, | |
| 900 | + ], | |
| 901 | + 'bg_overlay_attachment' => 'scroll', | |
| 902 | + 'bg_overlay_repeat' => 'no-repeat', | |
| 903 | + 'bg_overlay_blend_mode' => 'normal', | |
| 904 | + // Gradient Overlay Properties. | |
| 905 | + 'overlay_gradient_type' => 'basic', | |
| 906 | + 'bg_overlay_gradient_type' => 'linear', | |
| 907 | + 'bg_overlay_gradient_color_1' => '#FFC9B2', | |
| 908 | + 'bg_overlay_gradient_color_2' => '#C7CBFF', | |
| 909 | + 'bg_overlay_gradient_angle' => 90, | |
| 910 | + 'bg_overlay_gradient_location_1' => 0, | |
| 911 | + 'bg_overlay_gradient_location_2' => 100, | |
| 912 | + // Form Properties. | |
| 913 | + // Padding. | |
| 914 | + 'form_padding_top' => 0, | |
| 915 | + 'form_padding_right' => 0, | |
| 916 | + 'form_padding_bottom' => 0, | |
| 917 | + 'form_padding_left' => 0, | |
| 918 | + 'form_padding_unit' => 'px', | |
| 919 | + 'form_padding_link' => true, | |
| 920 | + // Border Radius. | |
| 921 | + 'form_border_radius_top' => 0, | |
| 922 | + 'form_border_radius_right' => 0, | |
| 923 | + 'form_border_radius_bottom' => 0, | |
| 924 | + 'form_border_radius_left' => 0, | |
| 925 | + 'form_border_radius_unit' => 'px', | |
| 926 | + 'form_border_radius_link' => true, | |
| 927 | + // Form Properties. | |
| 928 | + // Padding. | |
| 929 | + 'instant_form_padding_top' => 32, | |
| 930 | + 'instant_form_padding_right' => 32, | |
| 931 | + 'instant_form_padding_bottom' => 32, | |
| 932 | + 'instant_form_padding_left' => 32, | |
| 933 | + 'instant_form_padding_unit' => 'px', | |
| 934 | + 'instant_form_padding_link' => true, | |
| 935 | + // Border Radius. | |
| 936 | + 'instant_form_border_radius_top' => 12, | |
| 937 | + 'instant_form_border_radius_right' => 12, | |
| 938 | + 'instant_form_border_radius_bottom' => 12, | |
| 939 | + 'instant_form_border_radius_left' => 12, | |
| 940 | + 'instant_form_border_radius_unit' => 'px', | |
| 941 | + 'instant_form_border_radius_link' => true, | |
| 942 | + // Disable default SureForms styling. | |
| 943 | + 'disable_default_styles' => false, | |
| 585 | 944 | ], |
| 586 | 945 | ] |
| 587 | 946 | ); |
| 588 | 947 | |
| @@ -590,15 +949,44 @@ | ||
| 590 | 949 | register_post_meta( |
| 591 | 950 | 'sureforms_form', |
| 592 | 951 | '_srfm_email_notification', |
| 593 | 952 | [ |
| 594 | - 'single' => true, | |
| 595 | - 'type' => 'array', | |
| 596 | - 'auth_callback' => '__return_true', | |
| 597 | - 'show_in_rest' => [ | |
| 953 | + 'single' => true, | |
| 954 | + 'type' => 'array', | |
| 955 | + 'auth_callback' => static function() { | |
| 956 | + return Helper::current_user_can(); | |
| 957 | + }, | |
| 958 | + 'sanitize_callback' => static function( $meta_value ) { | |
| 959 | + if ( ! is_array( $meta_value ) ) { | |
| 960 | + return []; | |
| 961 | + } | |
| 962 | + $sanitized = []; | |
| 963 | + foreach ( $meta_value as $item ) { | |
| 964 | + if ( ! is_array( $item ) ) { | |
| 965 | + continue; | |
| 966 | + } | |
| 967 | + $sanitized[] = [ | |
| 968 | + 'id' => isset( $item['id'] ) ? intval( $item['id'] ) : 0, | |
| 969 | + 'status' => isset( $item['status'] ) ? filter_var( $item['status'], FILTER_VALIDATE_BOOLEAN ) : false, | |
| 970 | + 'is_raw_format' => isset( $item['is_raw_format'] ) ? filter_var( $item['is_raw_format'], FILTER_VALIDATE_BOOLEAN ) : false, | |
| 971 | + 'name' => isset( $item['name'] ) ? sanitize_text_field( $item['name'] ) : '', | |
| 972 | + 'email_to' => isset( $item['email_to'] ) ? sanitize_text_field( $item['email_to'] ) : '', | |
| 973 | + 'email_reply_to' => isset( $item['email_reply_to'] ) ? sanitize_text_field( $item['email_reply_to'] ) : '', | |
| 974 | + 'from_name' => isset( $item['from_name'] ) ? sanitize_text_field( $item['from_name'] ) : '', | |
| 975 | + 'from_email' => isset( $item['from_email'] ) ? sanitize_text_field( $item['from_email'] ) : '', | |
| 976 | + 'email_cc' => isset( $item['email_cc'] ) ? sanitize_text_field( $item['email_cc'] ) : '', | |
| 977 | + 'email_bcc' => isset( $item['email_bcc'] ) ? sanitize_text_field( $item['email_bcc'] ) : '', | |
| 978 | + 'subject' => isset( $item['subject'] ) ? sanitize_text_field( $item['subject'] ) : '', | |
| 979 | + 'email_body' => isset( $item['email_body'] ) ? wp_kses_post( $item['email_body'] ) : '', | |
| 980 | + ]; | |
| 981 | + } | |
| 982 | + return $sanitized; | |
| 983 | + }, | |
| 984 | + 'show_in_rest' => [ | |
| 598 | 985 | 'schema' => [ |
| 599 | - 'type' => 'array', | |
| 600 | - 'items' => [ | |
| 986 | + 'type' => 'array', | |
| 987 | + 'context' => [ 'edit' ], | |
| 988 | + 'items' => [ | |
| 601 | 989 | 'type' => 'object', |
| 602 | 990 | 'properties' => [ |
| 603 | 991 | 'id' => [ |
| 604 | 992 | 'type' => 'integer', |
| @@ -617,8 +1005,14 @@ | ||
| 617 | 1005 | ], |
| 618 | 1006 | 'email_reply_to' => [ |
| 619 | 1007 | 'type' => 'string', |
| 620 | 1008 | ], |
| 1009 | + 'from_name' => [ | |
| 1010 | + 'type' => 'string', | |
| 1011 | + ], | |
| 1012 | + 'from_email' => [ | |
| 1013 | + 'type' => 'string', | |
| 1014 | + ], | |
| 621 | 1015 | 'email_cc' => [ |
| 622 | 1016 | 'type' => 'string', |
| 623 | 1017 | ], |
| 624 | 1018 | 'email_bcc' => [ |
| @@ -633,19 +1027,21 @@ | ||
| 633 | 1027 | ], |
| 634 | 1028 | ], |
| 635 | 1029 | ], |
| 636 | 1030 | ], |
| 637 | - 'default' => [ | |
| 1031 | + 'default' => [ | |
| 638 | 1032 | [ |
| 639 | 1033 | 'id' => 1, |
| 640 | 1034 | 'status' => true, |
| 641 | 1035 | 'is_raw_format' => false, |
| 642 | - 'name' => 'Admin Notification Email', | |
| 1036 | + 'name' => __( 'Admin Notification Email', 'sureforms' ), | |
| 643 | 1037 | 'email_to' => '{admin_email}', |
| 644 | 1038 | 'email_reply_to' => '{admin_email}', |
| 1039 | + 'from_name' => '{site_title}', | |
| 1040 | + 'from_email' => '{admin_email}', | |
| 645 | 1041 | 'email_cc' => '{admin_email}', |
| 646 | 1042 | 'email_bcc' => '{admin_email}', |
| 647 | - 'subject' => 'New Form Submission', | |
| 1043 | + 'subject' => sprintf( /* translators: %s: Form title smart tag */ __( 'New Form Submission - %s', 'sureforms' ), '{form_title}' ), | |
| 648 | 1044 | 'email_body' => '{all_data}', |
| 649 | 1045 | ], |
| 650 | 1046 | ], |
| 651 | 1047 | ] |
| @@ -655,15 +1051,37 @@ | ||
| 655 | 1051 | register_post_meta( |
| 656 | 1052 | 'sureforms_form', |
| 657 | 1053 | '_srfm_compliance', |
| 658 | 1054 | [ |
| 659 | - 'single' => true, | |
| 660 | - 'type' => 'array', | |
| 661 | - 'auth_callback' => '__return_true', | |
| 662 | - 'show_in_rest' => [ | |
| 1055 | + 'single' => true, | |
| 1056 | + 'type' => 'array', | |
| 1057 | + 'auth_callback' => static function() { | |
| 1058 | + return Helper::current_user_can(); | |
| 1059 | + }, | |
| 1060 | + 'sanitize_callback' => static function( $meta_value ) { | |
| 1061 | + if ( ! is_array( $meta_value ) ) { | |
| 1062 | + return []; | |
| 1063 | + } | |
| 1064 | + $sanitized = []; | |
| 1065 | + foreach ( $meta_value as $item ) { | |
| 1066 | + if ( ! is_array( $item ) ) { | |
| 1067 | + continue; | |
| 1068 | + } | |
| 1069 | + $sanitized[] = [ | |
| 1070 | + 'id' => isset( $item['id'] ) ? sanitize_text_field( $item['id'] ) : '', | |
| 1071 | + 'gdpr' => isset( $item['gdpr'] ) ? filter_var( $item['gdpr'], FILTER_VALIDATE_BOOLEAN ) : false, | |
| 1072 | + 'do_not_store_entries' => isset( $item['do_not_store_entries'] ) ? filter_var( $item['do_not_store_entries'], FILTER_VALIDATE_BOOLEAN ) : false, | |
| 1073 | + 'auto_delete_entries' => isset( $item['auto_delete_entries'] ) ? filter_var( $item['auto_delete_entries'], FILTER_VALIDATE_BOOLEAN ) : false, | |
| 1074 | + 'auto_delete_days' => isset( $item['auto_delete_days'] ) ? sanitize_text_field( $item['auto_delete_days'] ) : '', | |
| 1075 | + ]; | |
| 1076 | + } | |
| 1077 | + return $sanitized; | |
| 1078 | + }, | |
| 1079 | + 'show_in_rest' => [ | |
| 663 | 1080 | 'schema' => [ |
| 664 | - 'type' => 'array', | |
| 665 | - 'items' => [ | |
| 1081 | + 'type' => 'array', | |
| 1082 | + 'context' => [ 'edit' ], | |
| 1083 | + 'items' => [ | |
| 666 | 1084 | 'type' => 'object', |
| 667 | 1085 | 'properties' => [ |
| 668 | 1086 | 'id' => [ |
| 669 | 1087 | 'type' => 'string', |
| @@ -683,9 +1101,9 @@ | ||
| 683 | 1101 | ], |
| 684 | 1102 | ], |
| 685 | 1103 | ], |
| 686 | 1104 | ], |
| 687 | - 'default' => [ | |
| 1105 | + 'default' => [ | |
| 688 | 1106 | [ |
| 689 | 1107 | 'id' => 'gdpr', |
| 690 | 1108 | 'gdpr' => false, |
| 691 | 1109 | 'do_not_store_entries' => false, |
| @@ -695,51 +1113,107 @@ | ||
| 695 | 1113 | ], |
| 696 | 1114 | ] |
| 697 | 1115 | ); |
| 698 | 1116 | |
| 1117 | + ob_start(); | |
| 1118 | + ?> | |
| 1119 | + <p style="text-align: center;"><img src="<?php echo esc_attr( $check_icon ); ?>" alt="" aria-hidden="true" /></p><h2 style="text-align: center;"><?php echo esc_html__( 'Thank you', 'sureforms' ); ?></h2><p style="text-align: center;"><?php echo esc_html__( 'Your form has been submitted successfully. We\'ll review your details and get back to you soon.', 'sureforms' ); ?></p> | |
| 1120 | + <?php | |
| 1121 | + $default_confirmation_message = ob_get_clean(); | |
| 1122 | + | |
| 699 | 1123 | // form confirmation. |
| 700 | 1124 | register_post_meta( |
| 701 | 1125 | 'sureforms_form', |
| 702 | 1126 | '_srfm_form_confirmation', |
| 703 | 1127 | [ |
| 704 | - 'single' => true, | |
| 705 | - 'type' => 'array', | |
| 706 | - 'auth_callback' => '__return_true', | |
| 707 | - 'show_in_rest' => [ | |
| 1128 | + 'single' => true, | |
| 1129 | + 'type' => 'array', | |
| 1130 | + 'auth_callback' => static function() { | |
| 1131 | + return Helper::current_user_can(); | |
| 1132 | + }, | |
| 1133 | + 'sanitize_callback' => static function( $meta_value ) { | |
| 1134 | + if ( ! is_array( $meta_value ) ) { | |
| 1135 | + return []; | |
| 1136 | + } | |
| 1137 | + $sanitized = []; | |
| 1138 | + foreach ( $meta_value as $item ) { | |
| 1139 | + if ( ! is_array( $item ) ) { | |
| 1140 | + continue; | |
| 1141 | + } | |
| 1142 | + $sanitized_item = [ | |
| 1143 | + 'id' => isset( $item['id'] ) ? intval( $item['id'] ) : 0, | |
| 1144 | + 'confirmation_type' => isset( $item['confirmation_type'] ) ? sanitize_text_field( $item['confirmation_type'] ) : '', | |
| 1145 | + 'page_url' => isset( $item['page_url'] ) ? esc_url_raw( $item['page_url'] ) : '', | |
| 1146 | + 'custom_url' => isset( $item['custom_url'] ) ? esc_url_raw( $item['custom_url'] ) : '', | |
| 1147 | + 'message' => isset( $item['message'] ) ? wp_kses_post( $item['message'] ) : '', | |
| 1148 | + 'submission_action' => isset( $item['submission_action'] ) ? sanitize_text_field( $item['submission_action'] ) : '', | |
| 1149 | + 'enable_query_params' => isset( $item['enable_query_params'] ) ? filter_var( $item['enable_query_params'], FILTER_VALIDATE_BOOLEAN ) : false, | |
| 1150 | + 'query_params' => isset( $item['query_params'] ) && is_array( $item['query_params'] ) | |
| 1151 | + ? array_map( | |
| 1152 | + static function ( $pair ) { | |
| 1153 | + if ( ! is_array( $pair ) ) { | |
| 1154 | + return []; | |
| 1155 | + } | |
| 1156 | + $key = key( $pair ); | |
| 1157 | + $value = current( $pair ); | |
| 1158 | + | |
| 1159 | + return [ | |
| 1160 | + sanitize_text_field( Helper::get_string_value( $key ) ) => sanitize_text_field( Helper::get_string_value( $value ) ), | |
| 1161 | + ]; | |
| 1162 | + }, | |
| 1163 | + $item['query_params'] | |
| 1164 | + ) | |
| 1165 | + : [], | |
| 1166 | + ]; | |
| 1167 | + | |
| 1168 | + $sanitized_item = apply_filters( 'srfm_form_confirmation_params', $sanitized_item, $item ); | |
| 1169 | + | |
| 1170 | + $sanitized[] = $sanitized_item; | |
| 1171 | + } | |
| 1172 | + return $sanitized; | |
| 1173 | + }, | |
| 1174 | + 'show_in_rest' => [ | |
| 708 | 1175 | 'schema' => [ |
| 709 | - 'type' => 'array', | |
| 710 | - 'items' => [ | |
| 1176 | + 'type' => 'array', | |
| 1177 | + 'context' => [ 'edit' ], | |
| 1178 | + 'items' => [ | |
| 711 | 1179 | 'type' => 'object', |
| 712 | 1180 | 'properties' => [ |
| 713 | - 'id' => [ | |
| 1181 | + 'id' => [ | |
| 714 | 1182 | 'type' => 'integer', |
| 715 | 1183 | ], |
| 716 | - 'confirmation_type' => [ | |
| 1184 | + 'confirmation_type' => [ | |
| 717 | 1185 | 'type' => 'string', |
| 718 | 1186 | ], |
| 719 | - 'page_url' => [ | |
| 1187 | + 'page_url' => [ | |
| 720 | 1188 | 'type' => 'string', |
| 721 | 1189 | ], |
| 722 | - 'custom_url' => [ | |
| 1190 | + 'custom_url' => [ | |
| 723 | 1191 | 'type' => 'string', |
| 724 | 1192 | ], |
| 725 | - 'message' => [ | |
| 1193 | + 'message' => [ | |
| 726 | 1194 | 'type' => 'string', |
| 727 | 1195 | ], |
| 728 | - 'submission_action' => [ | |
| 1196 | + 'submission_action' => [ | |
| 729 | 1197 | 'type' => 'string', |
| 730 | 1198 | ], |
| 1199 | + 'enable_query_params' => [ | |
| 1200 | + 'type' => 'boolean', | |
| 1201 | + ], | |
| 1202 | + 'query_params' => [ | |
| 1203 | + 'type' => 'array', | |
| 1204 | + ], | |
| 731 | 1205 | ], |
| 732 | 1206 | ], |
| 733 | 1207 | ], |
| 734 | 1208 | ], |
| 735 | - 'default' => [ | |
| 1209 | + 'default' => [ | |
| 736 | 1210 | [ |
| 737 | 1211 | 'id' => 1, |
| 738 | 1212 | 'confirmation_type' => 'same page', |
| 739 | 1213 | 'page_url' => '', |
| 740 | 1214 | 'custom_url' => '', |
| 741 | - 'message' => '<p style="text-align: center;"><img src="' . esc_attr( $check_icon ) . '"></img></p><h2 style="text-align: center;">Thank you</h2><p style="text-align: center;">We have received your email. You\'ll hear from us as soon as possible.</p><p style="text-align: center;">Please be sure to whitelist our {admin_email} email address to ensure our replies reach your inbox safely.</p>', | |
| 1215 | + 'message' => $default_confirmation_message, | |
| 742 | 1216 | 'submission_action' => 'hide form', |
| 743 | 1217 | ], |
| 744 | 1218 | ], |
| 745 | 1219 | ] |
| @@ -744,50 +1218,8 @@ | ||
| 744 | 1218 | ], |
| 745 | 1219 | ] |
| 746 | 1220 | ); |
| 747 | 1221 | |
| 748 | - // Sureforms entry metas. | |
| 749 | - register_post_meta( | |
| 750 | - 'sureforms_entry', | |
| 751 | - '_srfm_submission_info', | |
| 752 | - [ | |
| 753 | - 'single' => true, | |
| 754 | - 'type' => 'array', | |
| 755 | - 'auth_callback' => '__return_true', | |
| 756 | - 'show_in_rest' => [ | |
| 757 | - 'schema' => [ | |
| 758 | - 'type' => 'array', | |
| 759 | - 'items' => [ | |
| 760 | - 'type' => 'object', | |
| 761 | - 'properties' => [ | |
| 762 | - 'user_ip' => [ | |
| 763 | - 'type' => 'string', | |
| 764 | - ], | |
| 765 | - 'browser_name' => [ | |
| 766 | - 'type' => 'string', | |
| 767 | - ], | |
| 768 | - 'device_name' => [ | |
| 769 | - 'type' => 'string', | |
| 770 | - ], | |
| 771 | - ], | |
| 772 | - ], | |
| 773 | - ], | |
| 774 | - ], | |
| 775 | - ] | |
| 776 | - ); | |
| 777 | - | |
| 778 | - // store form id in entry. | |
| 779 | - register_post_meta( | |
| 780 | - 'sureforms_entry', | |
| 781 | - '_srfm_entry_form_id', | |
| 782 | - [ | |
| 783 | - 'single' => true, | |
| 784 | - 'type' => 'integer', | |
| 785 | - 'auth_callback' => '__return_true', | |
| 786 | - 'show_in_rest' => true, | |
| 787 | - ] | |
| 788 | - ); | |
| 789 | - | |
| 790 | 1222 | // conditional logic. |
| 791 | 1223 | do_action( 'srfm_register_conditional_logic_post_meta' ); |
| 792 | 1224 | /** |
| 793 | 1225 | * Hook for registering additional Post Meta |
| @@ -793,231 +1225,110 @@ | ||
| 793 | 1225 | * Hook for registering additional Post Meta |
| 794 | 1226 | */ |
| 795 | 1227 | do_action( 'srfm_register_additional_post_meta' ); |
| 796 | 1228 | |
| 1229 | + register_meta( | |
| 1230 | + 'post', | |
| 1231 | + '_srfm_form_restriction', | |
| 1232 | + [ | |
| 1233 | + 'type' => 'string', // Will store as JSON string. | |
| 1234 | + 'single' => true, // Store as single value. | |
| 1235 | + 'show_in_rest' => [ | |
| 1236 | + 'schema' => [ | |
| 1237 | + 'type' => 'string', | |
| 1238 | + 'context' => [ 'edit' ], | |
| 1239 | + ], | |
| 1240 | + ], | |
| 1241 | + // Custom callback to sanitize the data. | |
| 1242 | + 'sanitize_callback' => [ $this, 'sanitize_form_restriction_data' ], | |
| 1243 | + 'object_subtype' => SRFM_FORMS_POST_TYPE, | |
| 1244 | + 'auth_callback' => static function () { | |
| 1245 | + return Helper::current_user_can(); | |
| 1246 | + }, | |
| 1247 | + 'default' => wp_json_encode( | |
| 1248 | + [ | |
| 1249 | + 'status' => false, | |
| 1250 | + 'maxEntries' => 0, | |
| 1251 | + 'date' => '', | |
| 1252 | + 'hours' => '12', | |
| 1253 | + 'minutes' => '00', | |
| 1254 | + 'meridiem' => 'AM', | |
| 1255 | + 'message' => Translatable::get_default_form_restriction_message(), | |
| 1256 | + // Form Scheduling meta. | |
| 1257 | + 'schedulingStatus' => false, | |
| 1258 | + 'startDate' => '', | |
| 1259 | + 'startHours' => '12', | |
| 1260 | + 'startMinutes' => '00', | |
| 1261 | + 'startMeridiem' => 'AM', | |
| 1262 | + 'schedulingNotStartedMessage' => __( 'This form is not yet available. Check back after the scheduled start time.', 'sureforms' ), | |
| 1263 | + 'schedulingEndedMessage' => __( 'This form is closed. The submission period has ended.', 'sureforms' ), | |
| 1264 | + ] | |
| 1265 | + ), | |
| 1266 | + ] | |
| 1267 | + ); | |
| 797 | 1268 | } |
| 798 | 1269 | |
| 799 | 1270 | /** |
| 800 | - * Sureforms entries meta box callback. | |
| 1271 | + * Sanitizes the form restriction data. | |
| 801 | 1272 | * |
| 802 | - * @param \WP_Post $post Template. | |
| 803 | - * @return void | |
| 804 | - * @since 0.0.1 | |
| 1273 | + * @param mixed $meta_value The meta value to sanitize. | |
| 1274 | + * @return string|false Sanitized JSON string. | |
| 805 | 1275 | */ |
| 806 | - public function sureforms_meta_box_callback( \WP_Post $post ) { | |
| 807 | - $meta_data = get_post_meta( $post->ID, 'srfm_entry_meta', true ); | |
| 808 | - if ( ! is_array( $meta_data ) ) { | |
| 809 | - return; | |
| 1276 | + public function sanitize_form_restriction_data( $meta_value ) { | |
| 1277 | + if ( empty( $meta_value ) || ! is_string( $meta_value ) ) { | |
| 1278 | + return wp_json_encode( [] ); | |
| 810 | 1279 | } |
| 811 | - $excluded_fields = [ 'srfm-honeypot-field', 'g-recaptcha-response', 'srfm-sender-email-field' ]; | |
| 812 | 1280 | |
| 813 | - ?> | |
| 814 | - <table class="widefat striped"> | |
| 815 | - <tbody> | |
| 816 | - <tr><th><b><?php esc_html_e( 'Fields', 'sureforms' ); ?></b></th><th><b><?php esc_html_e( 'Values', 'sureforms' ); ?></b></th></tr> | |
| 817 | - <?php | |
| 818 | - foreach ( $meta_data as $field_name => $value ) : | |
| 819 | - if ( in_array( $field_name, $excluded_fields, true ) ) { | |
| 820 | - continue; | |
| 821 | - } | |
| 1281 | + $meta_value = json_decode( $meta_value, true ); | |
| 822 | 1282 | |
| 823 | - if ( false === str_contains( $field_name, '-lbl-' ) ) { | |
| 824 | - continue; | |
| 825 | - } | |
| 1283 | + if ( ! is_array( $meta_value ) || json_last_error() !== JSON_ERROR_NONE ) { | |
| 1284 | + // If the JSON is invalid, return an empty array as JSON. | |
| 1285 | + return wp_json_encode( [] ); | |
| 1286 | + } | |
| 826 | 1287 | |
| 827 | - $label = explode( '-lbl-', $field_name )[1]; | |
| 828 | - // Getting the encrypted label. we are removing the block slug here. | |
| 829 | - $label = explode( '-', $label )[0]; | |
| 1288 | + $sanitized = [ | |
| 1289 | + 'status' => isset( $meta_value['status'] ) ? wp_validate_boolean( $meta_value['status'] ) : false, | |
| 1290 | + 'maxEntries' => isset( $meta_value['maxEntries'] ) ? absint( $meta_value['maxEntries'] ) : 0, | |
| 1291 | + 'date' => isset( $meta_value['date'] ) ? sanitize_text_field( $meta_value['date'] ) : '', | |
| 1292 | + 'hours' => isset( $meta_value['hours'] ) ? sanitize_text_field( $meta_value['hours'] ) : '12', | |
| 1293 | + 'minutes' => isset( $meta_value['minutes'] ) ? sanitize_text_field( $meta_value['minutes'] ) : '00', | |
| 1294 | + 'meridiem' => isset( $meta_value['meridiem'] ) ? sanitize_text_field( $meta_value['meridiem'] ) : 'AM', | |
| 1295 | + 'message' => isset( $meta_value['message'] ) ? sanitize_textarea_field( $meta_value['message'] ) : Translatable::get_default_form_restriction_message(), | |
| 1296 | + // Form Scheduling meta. | |
| 1297 | + 'schedulingStatus' => isset( $meta_value['schedulingStatus'] ) ? wp_validate_boolean( $meta_value['schedulingStatus'] ) : false, | |
| 1298 | + 'startDate' => isset( $meta_value['startDate'] ) ? sanitize_text_field( $meta_value['startDate'] ) : '', | |
| 1299 | + 'startHours' => isset( $meta_value['startHours'] ) ? sanitize_text_field( $meta_value['startHours'] ) : '12', | |
| 1300 | + 'startMinutes' => isset( $meta_value['startMinutes'] ) ? sanitize_text_field( $meta_value['startMinutes'] ) : '00', | |
| 1301 | + 'startMeridiem' => isset( $meta_value['startMeridiem'] ) ? sanitize_text_field( $meta_value['startMeridiem'] ) : 'AM', | |
| 1302 | + 'schedulingNotStartedMessage' => isset( $meta_value['schedulingNotStartedMessage'] ) ? sanitize_textarea_field( $meta_value['schedulingNotStartedMessage'] ) : __( 'This form is not yet available. Check back after the scheduled start time.', 'sureforms' ), | |
| 1303 | + 'schedulingEndedMessage' => isset( $meta_value['schedulingEndedMessage'] ) ? sanitize_textarea_field( $meta_value['schedulingEndedMessage'] ) : __( 'This form is closed. The submission period has ended.', 'sureforms' ), | |
| 1304 | + ]; | |
| 830 | 1305 | |
| 831 | - ?> | |
| 832 | - <tr> | |
| 833 | - <td><b><?php echo $label ? esc_html( Helper::decrypt( $label ) ) : ''; ?><b></td> | |
| 834 | - <?php if ( strpos( $field_name, 'srfm-upload' ) !== false ) : ?> | |
| 835 | - <style> | |
| 836 | - .file-cards-container { | |
| 837 | - display: flex; | |
| 838 | - flex-wrap: wrap; | |
| 839 | - gap: 10px; | |
| 840 | - } | |
| 1306 | + // Validate scheduling: start date/time must be before end date/time. | |
| 1307 | + if ( $sanitized['schedulingStatus'] && ! empty( $sanitized['startDate'] ) && ! empty( $sanitized['date'] ) ) { | |
| 1308 | + $start_datetime = $this->create_datetime_object( | |
| 1309 | + $sanitized['startDate'], | |
| 1310 | + $sanitized['startHours'], | |
| 1311 | + $sanitized['startMinutes'], | |
| 1312 | + $sanitized['startMeridiem'] | |
| 1313 | + ); | |
| 841 | 1314 | |
| 842 | - .file-card { | |
| 843 | - border: 1px solid #ddd; | |
| 844 | - border-radius: 4px; | |
| 845 | - padding: 10px; | |
| 846 | - width: 100px; /* Reduced width */ | |
| 847 | - text-align: center; | |
| 848 | - background: #f9f9f9; | |
| 849 | - font-size: 12px; /* Reduced font size for smaller cards */ | |
| 850 | - } | |
| 1315 | + $end_datetime = $this->create_datetime_object( | |
| 1316 | + $sanitized['date'], | |
| 1317 | + $sanitized['hours'], | |
| 1318 | + $sanitized['minutes'], | |
| 1319 | + $sanitized['meridiem'] | |
| 1320 | + ); | |
| 851 | 1321 | |
| 852 | - .file-card-image img { | |
| 853 | - max-width: 80px; /* Reduced max width */ | |
| 854 | - max-height: 80px; /* Reduced max height */ | |
| 855 | - object-fit: cover; | |
| 856 | - } | |
| 857 | - | |
| 858 | - .file-card-icon { | |
| 859 | - font-size: 24px; /* Reduced icon size */ | |
| 860 | - margin-bottom: 5px; | |
| 861 | - } | |
| 862 | - | |
| 863 | - .file-card-details { | |
| 864 | - margin-bottom: 5px; | |
| 865 | - font-weight: bold; | |
| 866 | - } | |
| 867 | - | |
| 868 | - .file-card-url a { | |
| 869 | - color: #007bff; | |
| 870 | - text-decoration: none; | |
| 871 | - font-size: 12px; /* Reduced font size */ | |
| 872 | - } | |
| 873 | - | |
| 874 | - .file-card-url a:hover { | |
| 875 | - text-decoration: underline; | |
| 876 | - } | |
| 877 | - </style> | |
| 878 | - <td> | |
| 879 | - <div class="file-cards-container"> | |
| 880 | - <?php | |
| 881 | - $upload_values = $value; | |
| 882 | - if ( ! empty( $upload_values ) && is_array( $upload_values ) ) { | |
| 883 | - foreach ( $upload_values as $value ) { | |
| 884 | - $value = Helper::get_string_value( $value ); | |
| 885 | - if ( ! empty( $value ) ) { | |
| 886 | - $file_type = pathinfo( $value, PATHINFO_EXTENSION ); | |
| 887 | - $is_image = in_array( $file_type, [ 'gif', 'png', 'bmp', 'jpg', 'jpeg', 'svg' ], true ); | |
| 888 | - ?> | |
| 889 | - <div class="file-card"> | |
| 890 | - <?php if ( $is_image ) : ?> | |
| 891 | - <div class="file-card-image"> | |
| 892 | - <a target="_blank" href="<?php echo esc_attr( urldecode( $value ) ); ?>"> | |
| 893 | - <img src="<?php echo esc_attr( urldecode( $value ) ); ?>" alt="img" /> | |
| 894 | - </a> | |
| 895 | - </div> | |
| 896 | - <?php else : ?> | |
| 897 | - <div class="file-card-icon"> | |
| 898 | - <?php echo '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16.333V4.667a1.333 1.333 0 011.333-1.333h13.334a1.333 1.333 0 011.333 1.333v11.666a1.333 1.333 0 01-1.333 1.333H5.333A1.333 1.333 0 014 16.333zm8-8h2v6h-2v-6zm-2 8h6v2H10v-2zm-6-6h4v6H4v-6zm0-4h16v2H4V6z"/></svg>'; ?> | |
| 899 | - </div> | |
| 900 | - <div class="file-card-details"> | |
| 901 | - <span><?php echo esc_html( strtoupper( $file_type ) ); ?></span> | |
| 902 | - </div> | |
| 903 | - <?php endif; ?> | |
| 904 | - <div class="file-card-url"> | |
| 905 | - <a target="_blank" href="<?php echo esc_attr( urldecode( $value ) ); ?>"><?php echo esc_html__( 'Open', 'sureforms' ); ?></a> | |
| 906 | - </div> | |
| 907 | - </div> | |
| 908 | - <?php | |
| 909 | - } | |
| 910 | - } | |
| 911 | - } | |
| 912 | - ?> | |
| 913 | - </div> | |
| 914 | - </td> | |
| 915 | - <?php elseif ( strpos( $field_name, 'srfm-url' ) !== false ) : ?> | |
| 916 | - <?php if ( ! $value ) : ?> | |
| 917 | - <td><?php echo ''; ?></td> | |
| 918 | - <?php else : ?> | |
| 919 | - <?php | |
| 920 | - if ( | |
| 921 | - substr( $value, 0, 7 ) !== 'http://' && | |
| 922 | - substr( $value, 0, 8 ) !== 'https://' | |
| 923 | - ) { | |
| 924 | - $value = 'https://' . $value; | |
| 925 | - } | |
| 926 | - ?> | |
| 927 | - <td><a target="_blank" href="<?php echo esc_url( $value ); ?>"><?php echo esc_url( $value ); ?></a></td> | |
| 928 | - <?php endif; ?> | |
| 929 | - <?php else : ?> | |
| 930 | - <td><?php echo false !== strpos( $value, PHP_EOL ) ? wp_kses_post( wpautop( $value ) ) : wp_kses_post( $value ); ?></td> | |
| 931 | - <?php endif; ?> | |
| 932 | - </tr> | |
| 933 | - <?php endforeach; ?> | |
| 934 | - </tbody> | |
| 935 | - </table> | |
| 936 | - <?php | |
| 937 | - } | |
| 938 | - | |
| 939 | - | |
| 940 | - /** | |
| 941 | - * Add Sureforms entries meta box. | |
| 942 | - * | |
| 943 | - * @return void | |
| 944 | - * @since 0.0.1 | |
| 945 | - */ | |
| 946 | - public function entries_meta_box() { | |
| 947 | - add_meta_box( | |
| 948 | - 'sureform_entry_meta', | |
| 949 | - 'Form Data', | |
| 950 | - [ $this, 'sureforms_meta_box_callback' ], | |
| 951 | - 'sureforms_entry', | |
| 952 | - 'normal', | |
| 953 | - 'high' | |
| 954 | - ); | |
| 955 | - add_meta_box( | |
| 956 | - 'sureform_form_name_meta', | |
| 957 | - 'Submission Info', | |
| 958 | - [ $this, 'sureforms_form_name_meta_callback' ], | |
| 959 | - 'sureforms_entry', | |
| 960 | - 'side', | |
| 961 | - 'low' | |
| 962 | - ); | |
| 963 | - } | |
| 964 | - | |
| 965 | - /** | |
| 966 | - * Sureforms box Form Name meta box callback. | |
| 967 | - * | |
| 968 | - * @param \WP_Post $post Template. | |
| 969 | - * @return void | |
| 970 | - * @since 0.0.1 | |
| 971 | - */ | |
| 972 | - public function sureforms_form_name_meta_callback( \WP_Post $post ) { | |
| 973 | - $post_id = $post->ID; | |
| 974 | - $taxonomy = 'sureforms_tax'; | |
| 975 | - $terms = wp_get_post_terms( $post_id, $taxonomy ); | |
| 976 | - if ( is_array( $terms ) && count( $terms ) > 0 ) { | |
| 977 | - $form_id = intval( $terms[0]->slug ); | |
| 978 | - $form_name = ! empty( get_the_title( $form_id ) ) ? get_the_title( $form_id ) : 'SureForms Form'; | |
| 979 | - $submission_info = get_post_meta( $post_id, '_srfm_submission_info', true ); | |
| 980 | - if ( is_array( $submission_info ) && count( $submission_info ) > 0 ) { | |
| 981 | - $user_ip = $submission_info[0]['user_ip'] ? $submission_info[0]['user_ip'] : ''; | |
| 982 | - $browser_name = $submission_info[0]['browser_name'] ? $submission_info[0]['browser_name'] : ''; | |
| 983 | - $device_name = $submission_info[0]['device_name'] ? $submission_info[0]['device_name'] : ''; | |
| 984 | - $entry_form_id = Helper::get_string_value( get_post_meta( $post_id, '_srfm_entry_form_id', true ) ); | |
| 985 | - } else { | |
| 986 | - $user_ip = ''; | |
| 987 | - $browser_name = ''; | |
| 988 | - $device_name = ''; | |
| 989 | - $entry_form_id = ''; | |
| 1322 | + // If start date/time is not before end date/time, disable scheduling. | |
| 1323 | + if ( $start_datetime && $end_datetime && $start_datetime >= $end_datetime ) { | |
| 1324 | + // Disable scheduling status due to invalid date range. | |
| 1325 | + $sanitized['schedulingStatus'] = false; | |
| 990 | 1326 | } |
| 991 | - ?> | |
| 992 | - <table style="border-collapse: separate; border-spacing: 5px 5px;"> | |
| 993 | - <tr style="margin-bottom: 10px;"> | |
| 994 | - <td><b><?php echo esc_html( __( 'Form Name:', 'sureforms' ) ); ?></b></td> | |
| 995 | - <td><?php echo esc_html( $form_name ); ?></td> | |
| 996 | - </tr> | |
| 997 | - <tr style="margin-bottom: 10px;"> | |
| 998 | - <td><b><?php echo esc_html( __( 'Form ID:', 'sureforms' ) ); ?></b></td> | |
| 999 | - <td><?php echo esc_html( $entry_form_id ); ?></td> | |
| 1000 | - </tr> | |
| 1001 | - <tr style="margin-bottom: 10px;"> | |
| 1002 | - <td><b><?php echo esc_html( __( 'User IP:', 'sureforms' ) ); ?></b></td> | |
| 1003 | - <td><a target="_blank" rel="noopener" href="https://ipinfo.io/<?php echo esc_html( $user_ip ); ?>"><?php echo esc_html( $user_ip ); ?></a></td> | |
| 1004 | - </tr> | |
| 1005 | - <tr style="margin-bottom: 10px;"> | |
| 1006 | - <td><b><?php echo esc_html( __( 'Browser:', 'sureforms' ) ); ?></b></td> | |
| 1007 | - <td><?php echo esc_html( $browser_name ); ?></td> | |
| 1008 | - </tr> | |
| 1009 | - <tr style="margin-bottom: 10px;"> | |
| 1010 | - <td><b><?php echo esc_html( __( 'Device:', 'sureforms' ) ); ?></b></td> | |
| 1011 | - <td><?php echo esc_html( $device_name ); ?></td> | |
| 1012 | - </tr> | |
| 1013 | - </table> | |
| 1014 | - <?php | |
| 1015 | - } else { | |
| 1016 | - ?> | |
| 1017 | - <p><?php echo esc_html__( 'SureForms Form', 'sureforms' ); ?></p> | |
| 1018 | - <?php | |
| 1019 | 1327 | } |
| 1328 | + | |
| 1329 | + // Return the sanitized data as a JSON string. | |
| 1330 | + return wp_json_encode( $sanitized ); | |
| 1020 | 1331 | } |
| 1021 | 1332 | |
| 1022 | 1333 | /** |
| 1023 | 1334 | * Custom Shortcode. |
| @@ -1025,9 +1336,9 @@ | ||
| 1025 | 1336 | * @param array<mixed> $atts Attributes. |
| 1026 | 1337 | * @return string|false. $content Post Content. |
| 1027 | 1338 | * @since 0.0.1 |
| 1028 | 1339 | */ |
| 1029 | - public function forms_shortcode( array $atts ) { | |
| 1340 | + public function forms_shortcode( $atts ) { | |
| 1030 | 1341 | $atts = shortcode_atts( |
| 1031 | 1342 | [ |
| 1032 | 1343 | 'id' => '', |
| 1033 | 1344 | 'show_title' => true, |
| @@ -1037,232 +1348,150 @@ | ||
| 1037 | 1348 | |
| 1038 | 1349 | $id = intval( $atts['id'] ); |
| 1039 | 1350 | $post = get_post( $id ); |
| 1040 | 1351 | |
| 1041 | - if ( ! empty( $id ) && $post ) { | |
| 1042 | - $content = Generate_Form_Markup::get_form_markup( $id, ! filter_var( $atts['show_title'], FILTER_VALIDATE_BOOLEAN ), '', 'post', true ); | |
| 1043 | - return $content; | |
| 1352 | + if ( ! empty( $id ) && $post && ( 'publish' === $post->post_status || 'protected' === $post->post_status ) ) { | |
| 1353 | + return Generate_Form_Markup::get_form_markup( $id, ! filter_var( $atts['show_title'], FILTER_VALIDATE_BOOLEAN ), '', 'post', true ); | |
| 1044 | 1354 | } |
| 1045 | 1355 | |
| 1046 | - return ''; | |
| 1356 | + return esc_html__( 'This form has been deleted or is unavailable.', 'sureforms' ); | |
| 1047 | 1357 | } |
| 1048 | 1358 | |
| 1049 | 1359 | /** |
| 1050 | - * Add custom column header. | |
| 1360 | + * Redirect to home page if instant form is not enabled. | |
| 1051 | 1361 | * |
| 1052 | - * @param array<mixed> $columns Attributes. | |
| 1053 | - * @return array<mixed> $columns Post Content. | |
| 1054 | 1362 | * @since 0.0.1 |
| 1055 | - */ | |
| 1056 | - public function custom_form_columns( $columns ) { | |
| 1057 | - $columns = [ | |
| 1058 | - 'cb' => $columns['cb'], | |
| 1059 | - 'title' => $columns['title'], | |
| 1060 | - 'sureforms' => __( 'Shortcode', 'sureforms' ), | |
| 1061 | - 'entries' => __( 'Entries', 'sureforms' ), | |
| 1062 | - 'author' => $columns['author'], | |
| 1063 | - 'date' => $columns['date'], | |
| 1064 | - ]; | |
| 1065 | - return $columns; | |
| 1066 | - } | |
| 1067 | - | |
| 1068 | - /** | |
| 1069 | - * Populate custom column with data. | |
| 1070 | - * | |
| 1071 | - * @param string $column Attributes. | |
| 1072 | - * @param integer $post_id Attributes. | |
| 1073 | 1363 | * @return void |
| 1074 | - * @since 0.0.1 | |
| 1075 | 1364 | */ |
| 1076 | - public function custom_form_column_data( $column, $post_id ) { | |
| 1077 | - $post_id_formatted = strval( $post_id ); | |
| 1078 | - if ( 'sureforms' === $column ) { | |
| 1079 | - ob_start(); | |
| 1080 | - ?> | |
| 1081 | - <div class="srfm-shortcode-container"> | |
| 1082 | - <input id="srfm-shortcode-input-<?php echo esc_attr( strval( $post_id ) ); ?>" class="srfm-shortcode-input" type="text" readonly value="[sureforms id='<?php echo esc_attr( $post_id_formatted ); ?>']" /> | |
| 1083 | - <button type="button" class="components-button components-clipboard-button has-icon srfm-shortcode" onclick="handleFormShortcode(this)"> | |
| 1084 | - <span id="srfm-copy-icon" class="dashicon dashicons dashicons-admin-page"></span> | |
| 1085 | - </button> | |
| 1086 | - </div> | |
| 1087 | - <?php | |
| 1088 | - ob_end_flush(); | |
| 1089 | - } | |
| 1090 | - if ( 'entries' === $column ) { | |
| 1091 | - $entries_url = admin_url( 'edit.php?post_status=all&post_type=' . SRFM_ENTRIES_POST_TYPE . '&sureforms_tax=' . $post_id_formatted . '&filter_action=Filter&paged=1' ); | |
| 1365 | + public function srfm_instant_form_redirect() { | |
| 1092 | 1366 | |
| 1093 | - $taxonomy = 'sureforms_tax'; | |
| 1367 | + $form_id = Helper::get_integer_value( get_the_ID() ); | |
| 1094 | 1368 | |
| 1095 | - $args = [ | |
| 1096 | - 'post_type' => SRFM_ENTRIES_POST_TYPE, | |
| 1097 | - 'tax_query' // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query. -- We require tax_query for this function to work. | |
| 1098 | - => [ | |
| 1099 | - [ | |
| 1100 | - 'taxonomy' => $taxonomy, | |
| 1101 | - 'field' => 'slug', | |
| 1102 | - 'terms' => $post_id_formatted, | |
| 1103 | - ], | |
| 1104 | - ], | |
| 1105 | - ]; | |
| 1369 | + $instant_form_settings = Helper::get_array_value( Helper::get_post_meta( $form_id, '_srfm_instant_form_settings' ) ); | |
| 1370 | + $enable_instant_form = ! empty( $instant_form_settings['enable_instant_form'] ) ? boolval( $instant_form_settings['enable_instant_form'] ) : false; | |
| 1106 | 1371 | |
| 1107 | - $key = 'sureforms_entries_count_' . $post_id_formatted; | |
| 1108 | - $query = wp_cache_get( $key ); | |
| 1372 | + if ( $enable_instant_form ) { | |
| 1373 | + return; | |
| 1374 | + } | |
| 1109 | 1375 | |
| 1110 | - if ( ! $query ) { | |
| 1111 | - $query = new WP_Query( $args ); | |
| 1112 | - wp_cache_set( $key, $query, '', 3600 ); | |
| 1113 | - } | |
| 1376 | + $form_preview = ''; | |
| 1114 | 1377 | |
| 1115 | - if ( $query instanceof WP_Query ) { | |
| 1116 | - $post_count = $query->post_count; | |
| 1378 | + $form_preview_attr = isset( $_GET['preview'] ) ? sanitize_text_field( wp_unslash( $_GET['preview'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not needed here. | |
| 1117 | 1379 | |
| 1118 | - $post_count = strval( $post_count ); | |
| 1380 | + if ( $form_preview_attr ) { | |
| 1381 | + $form_preview = filter_var( $form_preview_attr, FILTER_VALIDATE_BOOLEAN ); | |
| 1382 | + } | |
| 1119 | 1383 | |
| 1120 | - ob_start(); | |
| 1121 | - ?> | |
| 1122 | - <p class="srfm-entries-number"><a href="<?php echo esc_url( $entries_url ); ?>"><?php echo esc_html( $post_count ); ?></a></p> | |
| 1123 | - <?php | |
| 1124 | - ob_end_flush(); | |
| 1125 | - } | |
| 1384 | + if ( is_singular( 'sureforms_form' ) && ! $form_preview && ! Helper::current_user_can() ) { | |
| 1385 | + wp_safe_redirect( home_url() ); | |
| 1386 | + return; | |
| 1126 | 1387 | } |
| 1127 | 1388 | } |
| 1128 | 1389 | |
| 1129 | 1390 | /** |
| 1130 | - * Add custom column header. | |
| 1391 | + * Restrict RankMath meta boxes in edit page. | |
| 1131 | 1392 | * |
| 1132 | - * @param array<mixed> $columns Attributes. | |
| 1133 | - * @return array<mixed> $columns Post Content. | |
| 1134 | - * @since 0.0.1 | |
| 1393 | + * @since 0.0.5 | |
| 1394 | + * @return void | |
| 1135 | 1395 | */ |
| 1136 | - public function custom_entry_columns( $columns ) { | |
| 1137 | - $columns = [ | |
| 1138 | - 'cb' => $columns['cb'], | |
| 1139 | - 'title' => __( 'First Field', 'sureforms' ), | |
| 1140 | - 'form_name' => __( 'Form Name', 'sureforms' ), | |
| 1141 | - 'entry_id' => __( 'ID', 'sureforms' ), | |
| 1142 | - 'date' => __( 'Submitted On', 'sureforms' ), | |
| 1143 | - ]; | |
| 1144 | - return $columns; | |
| 1396 | + public function restrict_data() { | |
| 1397 | + add_filter( 'rank_math/excluded_post_types', [ $this, 'unset_sureforms_post_type' ] ); | |
| 1145 | 1398 | } |
| 1146 | 1399 | |
| 1147 | 1400 | /** |
| 1148 | - * Populate custom column with data. | |
| 1401 | + * Remove SureForms post type from RankMath and Yoast. | |
| 1149 | 1402 | * |
| 1150 | - * @param string $column Attributes. | |
| 1151 | - * @param integer $post_id Attributes. | |
| 1152 | - * @return void | |
| 1153 | - * @since 0.0.1 | |
| 1403 | + * @param array<mixed> $post_types Post types. | |
| 1404 | + * @since 0.0.5 | |
| 1405 | + * @return array<mixed> $post_types Modified post types. | |
| 1154 | 1406 | */ |
| 1155 | - public function custom_entry_column_data( $column, $post_id ) { | |
| 1156 | - if ( 'entry_id' === $column ) { | |
| 1157 | - $entry_id = strval( $post_id ); | |
| 1158 | - echo '<p>#' . esc_html( $entry_id ) . '</p>'; | |
| 1159 | - } | |
| 1160 | - if ( 'form_name' === $column ) { | |
| 1161 | - $taxonomy = 'sureforms_tax'; | |
| 1162 | - $terms = wp_get_post_terms( $post_id, $taxonomy ); | |
| 1163 | - | |
| 1164 | - if ( is_array( $terms ) && count( $terms ) > 0 ) { | |
| 1165 | - $form_id = intval( $terms[0]->slug ); | |
| 1166 | - $form_name = ! empty( get_the_title( $form_id ) ) ? get_the_title( $form_id ) : 'SureForms Form'; | |
| 1167 | - echo '<p>' . esc_html( $form_name . ' #' . $form_id ) . '</p>'; | |
| 1168 | - } else { | |
| 1169 | - ?> | |
| 1170 | - <p><?php echo esc_html__( 'SureForms Form', 'sureforms' ); ?></p> | |
| 1171 | - <?php | |
| 1407 | + public function unset_sureforms_post_type( $post_types ) { | |
| 1408 | + return array_filter( | |
| 1409 | + $post_types, | |
| 1410 | + static function( $post_type ) { | |
| 1411 | + if ( is_array( $post_type ) && isset( $post_type['name'] ) ) { | |
| 1412 | + return SRFM_FORMS_POST_TYPE !== $post_type['name']; | |
| 1413 | + } | |
| 1414 | + return SRFM_FORMS_POST_TYPE !== $post_type; | |
| 1172 | 1415 | } |
| 1173 | - } | |
| 1416 | + ); | |
| 1174 | 1417 | } |
| 1175 | 1418 | |
| 1176 | 1419 | /** |
| 1177 | - * Add SureForms taxonomy filter. | |
| 1420 | + * Restrict unwanted insertions from the AIOSEO plugin. | |
| 1178 | 1421 | * |
| 1422 | + * This method ensures that the SureForms post type is excluded from AIOSEO's | |
| 1423 | + * public post types unless the current page is related to AIOSEO settings. | |
| 1424 | + * | |
| 1179 | 1425 | * @return void |
| 1180 | - * @since 0.0.1 | |
| 1426 | + * @since 1.6.0 | |
| 1181 | 1427 | */ |
| 1182 | - public function add_tax_filter() { | |
| 1183 | - $screen = get_current_screen(); | |
| 1428 | + public function restrict_in_aioseo_plugin() { | |
| 1429 | + /** | |
| 1430 | + * Checks if the AIOSEO plugin is installed and excludes the SureForms post type from AIOSEO's public post types. | |
| 1431 | + * | |
| 1432 | + * - Verifies the presence of the AIOSEO_DIR constant to ensure AIOSEO is installed. | |
| 1433 | + * - Allows AIOSEO functionality on its own settings pages by checking the `REQUEST_URI` and `page` query parameter. | |
| 1434 | + * - Excludes the SureForms post type from AIOSEO's public post types using the `aioseo_public_post_types` filter. | |
| 1435 | + * | |
| 1436 | + * Security Note: | |
| 1437 | + * - Nonce verification is intentionally skipped (`phpcs:ignore WordPress.Security.NonceVerification.Recommended`) | |
| 1438 | + * because this code is only performing a read operation to check the current request URI and query parameters. | |
| 1439 | + * It does not modify or process sensitive data, making nonce verification unnecessary in this context. | |
| 1440 | + */ | |
| 1441 | + // Check if AIOSEO is installed by verifying the AIOSEO_DIR constant. | |
| 1442 | + if ( ! defined( 'AIOSEO_DIR' ) ) { | |
| 1443 | + return; | |
| 1444 | + } | |
| 1184 | 1445 | |
| 1185 | - if ( ! is_null( $screen ) && 'edit-sureforms_entry' === $screen->id ) { | |
| 1186 | - $forms = get_posts( | |
| 1187 | - [ | |
| 1188 | - 'post_type' => SRFM_FORMS_POST_TYPE, | |
| 1189 | - 'posts_per_page' => -1, | |
| 1190 | - 'orderby' => 'title', | |
| 1191 | - 'order' => 'ASC', | |
| 1192 | - ] | |
| 1193 | - ); | |
| 1194 | - | |
| 1195 | - if ( ! empty( $forms ) ) { | |
| 1196 | - $selected = isset( $_GET['sureforms_tax'] ) ? sanitize_key( wp_unslash( $_GET['sureforms_tax'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce Verification is not needed in this case. We are not getting the nonce value. | |
| 1197 | - echo '<select name="sureforms_tax" id="srfm-tax-filter">'; | |
| 1198 | - echo '<option value="">' . esc_html__( ' All Form Entries', 'sureforms' ) . '</option>'; | |
| 1199 | - | |
| 1200 | - foreach ( $forms as $form ) { | |
| 1201 | - $selected_attr = selected( $selected, $form->ID, false ); | |
| 1202 | - echo '<option value="' . esc_attr( strval( $form->ID ) ) . '" ' . esc_attr( $selected_attr ) . '>' . esc_html( $form->post_title ) . '</option>'; | |
| 1446 | + // Allow AIOSEO functionality on its own settings pages. | |
| 1447 | + if ( isset( $_SERVER['REQUEST_URI'] ) ) { | |
| 1448 | + $request_uri = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ); | |
| 1449 | + if ( strpos( $request_uri, 'admin.php' ) !== false ) { | |
| 1450 | + if ( isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here because Safe here as we're only reading the `page` parameter. | |
| 1451 | + $page = sanitize_text_field( wp_unslash( $_GET['page'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here because only we are reading the `page` parameter. | |
| 1452 | + if ( strpos( $page, 'aioseo' ) !== false ) { | |
| 1453 | + return; | |
| 1454 | + } | |
| 1203 | 1455 | } |
| 1204 | - | |
| 1205 | - echo '</select>'; | |
| 1206 | - | |
| 1207 | 1456 | } |
| 1208 | 1457 | } |
| 1209 | - } | |
| 1210 | 1458 | |
| 1211 | - /** | |
| 1212 | - * Show the import form popup | |
| 1213 | - * | |
| 1214 | - * @since 0.0.1 | |
| 1215 | - * @return void | |
| 1216 | - */ | |
| 1217 | - public function import_form_popup() { | |
| 1218 | - $screen = get_current_screen(); | |
| 1219 | - $id = $screen ? $screen->id : ''; | |
| 1220 | - if ( 'edit-sureforms_form' === $id ) { | |
| 1221 | - ?> | |
| 1222 | - <div class="srfm-import-plugin-wrap"> | |
| 1223 | - <div class="srfm-import-wrap"> | |
| 1224 | - <p class="srfm-import-help"><?php echo esc_html__( 'Please choose the SureForms export file (.json) that you wish to import.', 'sureforms' ); ?></p> | |
| 1225 | - <form method="post" enctype="multipart/form-data" class="srfm-import-form"> | |
| 1226 | - <input type="file" id="srfm-import-file" onchange="handleFileChange(event)" name="import form" accept=".json"> | |
| 1227 | - <input type="submit" name="import-form-submit" id="import-form-submit" class="srfm-import-button" value="Import Now" disabled> | |
| 1228 | - </form> | |
| 1229 | - <p id="srfm-import-error"><?php echo esc_html__( 'There is some error in json file, please export the SureForms Forms again.', 'sureforms' ); ?></p> | |
| 1230 | - </div> | |
| 1231 | - </div> | |
| 1232 | - <?php | |
| 1233 | - } | |
| 1459 | + // Exclude the SureForms post type from AIOSEO's public post types. | |
| 1460 | + add_filter( 'aioseo_public_post_types', [ $this, 'unset_sureforms_post_type' ] ); | |
| 1234 | 1461 | } |
| 1235 | 1462 | |
| 1236 | 1463 | /** |
| 1237 | - * Redirect to home page if instant form is not enabled. | |
| 1464 | + * Creates a DateTime object from date string and time components. | |
| 1238 | 1465 | * |
| 1239 | - * @since 0.0.1 | |
| 1240 | - * @return void | |
| 1466 | + * @param string $date_str Date string. | |
| 1467 | + * @param string $hours Hours in 12-hour format. | |
| 1468 | + * @param string $minutes Minutes. | |
| 1469 | + * @param string $meridiem AM or PM. | |
| 1470 | + * @since 2.4.0 | |
| 1471 | + * @return \DateTime|null DateTime object or null if invalid. | |
| 1241 | 1472 | */ |
| 1242 | - public function srfm_instant_form_redirect() { | |
| 1243 | - | |
| 1244 | - $form_id = Helper::get_integer_value( get_the_ID() ); | |
| 1245 | - | |
| 1246 | - $instant_form_settings = Helper::get_array_value( Helper::get_post_meta( $form_id, '_srfm_instant_form_settings' ) ); | |
| 1247 | - $enable_instant_form = ! empty( $instant_form_settings['enable_instant_form'] ) ? boolval( $instant_form_settings['enable_instant_form'] ) : false; | |
| 1248 | - | |
| 1249 | - if ( $enable_instant_form ) { | |
| 1250 | - return; | |
| 1473 | + private function create_datetime_object( $date_str, $hours, $minutes, $meridiem ) { | |
| 1474 | + if ( empty( $date_str ) ) { | |
| 1475 | + return null; | |
| 1251 | 1476 | } |
| 1252 | 1477 | |
| 1253 | - $form_preview = ''; | |
| 1478 | + try { | |
| 1479 | + $date = new \DateTime( $date_str ); | |
| 1254 | 1480 | |
| 1255 | - $form_preview_attr = isset( $_GET['preview'] ) ? sanitize_text_field( wp_unslash( $_GET['preview'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not needed here. | |
| 1481 | + // Convert 12-hour format to 24-hour format. | |
| 1482 | + $hour_24 = intval( $hours ); | |
| 1483 | + if ( 'PM' === $meridiem && 12 !== $hour_24 ) { | |
| 1484 | + $hour_24 += 12; | |
| 1485 | + } elseif ( 'AM' === $meridiem && 12 === $hour_24 ) { | |
| 1486 | + $hour_24 = 0; | |
| 1487 | + } | |
| 1256 | 1488 | |
| 1257 | - if ( $form_preview_attr ) { | |
| 1258 | - $form_preview = filter_var( $form_preview_attr, FILTER_VALIDATE_BOOLEAN ); | |
| 1489 | + $date->setTime( $hour_24, intval( $minutes ), 0 ); | |
| 1490 | + return $date; | |
| 1491 | + } catch ( \Exception $e ) { | |
| 1492 | + return null; | |
| 1259 | 1493 | } |
| 1260 | - | |
| 1261 | - if ( is_singular( 'sureforms_form' ) && ! $form_preview && ! current_user_can( 'manage_options' ) ) { | |
| 1262 | - wp_safe_redirect( home_url() ); | |
| 1263 | - return; | |
| 1264 | - } | |
| 1265 | 1494 | } |
| 1266 | 1495 | |
| 1267 | 1496 | /** |
| 1268 | 1497 | * Restrict interference of other plugins with SureForms. |
| @@ -1278,39 +1507,7 @@ | ||
| 1278 | 1507 | add_filter( 'wpseo_accessible_post_types', [ $this, 'unset_sureforms_post_type' ] ); |
| 1279 | 1508 | add_filter( 'wpseo_metabox_prio', '__return_false' ); |
| 1280 | 1509 | |
| 1281 | 1510 | // Restrict AIOSEO columns. |
| 1282 | - add_filter( 'aioseo_public_post_types', [ $this, 'unset_sureforms_post_type' ] ); | |
| 1283 | - } | |
| 1284 | - | |
| 1285 | - /** | |
| 1286 | - * Restrict RankMath meta boxes in edit page. | |
| 1287 | - * | |
| 1288 | - * @since 0.0.5 | |
| 1289 | - * @return void | |
| 1290 | - */ | |
| 1291 | - public function restrict_data() { | |
| 1292 | - add_filter( 'rank_math/excluded_post_types', [ $this, 'unset_sureforms_post_type' ] ); | |
| 1293 | - } | |
| 1294 | - | |
| 1295 | - /** | |
| 1296 | - * Remove SureForms post type from RankMath and Yoast. | |
| 1297 | - * | |
| 1298 | - * @param array<mixed> $post_types Post types. | |
| 1299 | - * @since 0.0.5 | |
| 1300 | - * @return array<mixed> $post_types Modified post types. | |
| 1301 | - */ | |
| 1302 | - public function unset_sureforms_post_type( $post_types ) { | |
| 1303 | - $filtered_post_types = array_filter( | |
| 1304 | - $post_types, | |
| 1305 | - function( $post_type ) { | |
| 1306 | - if ( is_array( $post_type ) && isset( $post_type['name'] ) ) { | |
| 1307 | - return SRFM_FORMS_POST_TYPE !== $post_type['name']; | |
| 1308 | - } else { | |
| 1309 | - return SRFM_FORMS_POST_TYPE !== $post_type; | |
| 1310 | - } | |
| 1311 | - } | |
| 1312 | - ); | |
| 1313 | - | |
| 1314 | - return $filtered_post_types; | |
| 1511 | + $this->restrict_in_aioseo_plugin(); | |
| 1315 | 1512 | } |
| 1316 | 1513 | } |