| 1 |
<?php |
| 2 |
/** |
| 3 |
* WPZOOM Forms - Custom forms for WordPress, by WPZOOM. |
| 4 |
* |
| 5 |
* @package WPZOOM_Forms |
| 6 |
* @author WPZOOM |
| 7 |
* @copyright 2023 WPZOOM |
| 8 |
* @license GPL-2.0-or-later |
| 9 |
* |
| 10 |
* @wordpress-plugin |
| 11 |
* Plugin Name: WPZOOM Forms |
| 12 |
* Plugin URI: https://www.wpzoom.com/plugins/wpzoom-forms |
| 13 |
* Description: Simple, user-friendly contact form plugin for WordPress with a dedicated drag-and-drop builder. |
| 14 |
* Author: WPZOOM |
| 15 |
* Author URI: https://www.wpzoom.com |
| 16 |
* Version: 2.0.4 |
| 17 |
* License: GPL2+ |
| 18 |
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt |
| 19 |
*/ |
| 20 |
|
| 21 |
// Exit if accessed directly |
| 22 |
defined( 'ABSPATH' ) || exit; |
| 23 |
|
| 24 |
// settings page url attribute |
| 25 |
define( 'WPZOOM_FORMS_SETTINGS_PAGE', 'wpzf-settings' ); |
| 26 |
|
| 27 |
if ( ! defined( 'WPZOOM_FORMS_VERSION' ) ) { |
| 28 |
define( 'WPZOOM_FORMS_VERSION', get_file_data( __FILE__, [ 'Version' ] )[0] ); // phpcs:ignore |
| 29 |
} |
| 30 |
|
| 31 |
define( 'WPZOOM_FORMS__FILE__', __FILE__ ); |
| 32 |
define( 'WPZOOM_FORMS_PLUGIN_BASE', plugin_basename( WPZOOM_FORMS__FILE__ ) ); |
| 33 |
define( 'WPZOOM_FORMS_PLUGIN_DIR', dirname( WPZOOM_FORMS_PLUGIN_BASE ) ); |
| 34 |
|
| 35 |
define( 'WPZOOM_FORMS_PATH', plugin_dir_path( WPZOOM_FORMS__FILE__ ) ); |
| 36 |
define( 'WPZOOM_FORMS_URL', plugin_dir_url( WPZOOM_FORMS__FILE__ ) ); |
| 37 |
|
| 38 |
|
| 39 |
// WPZOOM Notice Center (submodule at classes/notice-center). |
| 40 |
$wpz_notice_center_path = WPZOOM_FORMS_PATH . 'classes/notice-center/'; |
| 41 |
$wpz_notice_center_url = WPZOOM_FORMS_URL . 'classes/notice-center/'; |
| 42 |
if ( is_admin() && ! class_exists( 'WPZOOM_Notice_Center' ) && file_exists( $wpz_notice_center_path . 'notice-center.php' ) ) { |
| 43 |
require_once $wpz_notice_center_path . 'notice-center.php'; |
| 44 |
WPZOOM_Notice_Center::get_instance()->set_assets( array( |
| 45 |
'css_url' => $wpz_notice_center_url . 'assets/notice-center.css', |
| 46 |
'js_url' => $wpz_notice_center_url . 'assets/notice-center.js', |
| 47 |
) ); |
| 48 |
} |
| 49 |
|
| 50 |
// Instance the plugin |
| 51 |
$wpzoom_forms = new WPZOOM_Forms(); |
| 52 |
|
| 53 |
// Register plugin activation hook |
| 54 |
register_activation_hook( __FILE__, array( $wpzoom_forms, 'activate' ) ); |
| 55 |
|
| 56 |
// Hook the plugin into WordPress |
| 57 |
add_action( 'init', array( $wpzoom_forms, 'init' ), 9 ); |
| 58 |
|
| 59 |
|
| 60 |
|
| 61 |
/** |
| 62 |
* Class WPZOOM_Forms |
| 63 |
* |
| 64 |
* Main container class of the ZOOM Forms WordPress plugin. |
| 65 |
* |
| 66 |
* @since 1.0.0 |
| 67 |
*/ |
| 68 |
class WPZOOM_Forms { |
| 69 |
|
| 70 |
/** |
| 71 |
* Whether the plugin has been initialized. |
| 72 |
* |
| 73 |
* @var boolean |
| 74 |
* @access public |
| 75 |
* @since 1.0.0 |
| 76 |
*/ |
| 77 |
public $initialized = false; |
| 78 |
|
| 79 |
/** |
| 80 |
* The path to this plugin's root directory. |
| 81 |
* |
| 82 |
* @var string |
| 83 |
* @access public |
| 84 |
* @since 1.0.0 |
| 85 |
*/ |
| 86 |
public $plugin_dir_path; |
| 87 |
|
| 88 |
/** |
| 89 |
* The URL to this plugin's root directory. |
| 90 |
* |
| 91 |
* @var string |
| 92 |
* @access public |
| 93 |
* @since 1.0.0 |
| 94 |
*/ |
| 95 |
public $plugin_dir_url; |
| 96 |
|
| 97 |
/** |
| 98 |
* The path to this plugin's "main" directory. |
| 99 |
* |
| 100 |
* @var string |
| 101 |
* @access public |
| 102 |
* @since 1.0.0 |
| 103 |
*/ |
| 104 |
public $main_dir_path; |
| 105 |
|
| 106 |
/** |
| 107 |
* The URL to this plugin's "main" directory. |
| 108 |
* |
| 109 |
* @var string |
| 110 |
* @access public |
| 111 |
* @since 1.0.0 |
| 112 |
*/ |
| 113 |
public $main_dir_url; |
| 114 |
|
| 115 |
/** |
| 116 |
* The URL to this plugin's "dist" directory. |
| 117 |
* |
| 118 |
* @var string |
| 119 |
* @access public |
| 120 |
* @since 1.0.0 |
| 121 |
*/ |
| 122 |
public $dist_dir_url; |
| 123 |
|
| 124 |
/** |
| 125 |
* UTM source for header and footer links. |
| 126 |
* |
| 127 |
* @var string |
| 128 |
*/ |
| 129 |
public $utm_source = '?utm_source=wpadmin&utm_medium=wpzoom-forms-free&utm_campaign=header-footer-links'; |
| 130 |
|
| 131 |
/** |
| 132 |
* Initializes the plugin and sets up needed hooks and features. |
| 133 |
* |
| 134 |
* @access public |
| 135 |
* @return void |
| 136 |
* @since 1.0.0 |
| 137 |
* @see ZOOM_Forms::block_setup() |
| 138 |
*/ |
| 139 |
public function init() { |
| 140 |
if ( false === $this->initialized ) { |
| 141 |
$this->plugin_dir_path = plugin_dir_path( __FILE__ ); |
| 142 |
$this->plugin_dir_url = plugin_dir_url( __FILE__ ); |
| 143 |
$this->main_dir_path = trailingslashit( $this->plugin_dir_path . 'build' ); |
| 144 |
$this->main_dir_url = trailingslashit( $this->plugin_dir_url . 'build' ); |
| 145 |
$this->dist_dir_url = trailingslashit( $this->plugin_dir_url . 'dist' ); |
| 146 |
|
| 147 |
load_plugin_textdomain( 'wpzoom-forms', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); |
| 148 |
|
| 149 |
// Register welcome guide setting |
| 150 |
register_setting( |
| 151 |
'general', |
| 152 |
'wpzoom_forms_welcome_guide_shown', |
| 153 |
array( |
| 154 |
'type' => 'boolean', |
| 155 |
'default' => false, |
| 156 |
'show_in_rest' => true, |
| 157 |
'sanitize_callback' => 'rest_sanitize_boolean', |
| 158 |
) |
| 159 |
); |
| 160 |
|
| 161 |
add_filter( 'allowed_block_types_all', array( $this, 'filter_allowed_block_types' ), 10, 2 ); |
| 162 |
add_filter( 'block_categories_all', array( $this, 'filter_block_categories' ), 10, 2 ); |
| 163 |
add_filter( 'post_row_actions', array( $this, 'modify_row_actions' ), 10, 2 ); |
| 164 |
add_filter( 'bulk_actions-edit-wpzf-form', array( $this, 'remove_bulk_actions' ), 10 ); |
| 165 |
add_filter( 'bulk_actions-edit-wpzf-submission', array( $this, 'remove_bulk_actions' ), 10 ); |
| 166 |
add_filter( 'manage_edit-wpzf-form_columns', array( $this, 'post_list_columns_form' ), 10 ); |
| 167 |
add_filter( 'manage_edit-wpzf-submission_columns', array( $this, 'post_list_columns_submit' ), 10 ); |
| 168 |
add_filter( 'manage_edit-wpzf-submission_sortable_columns', array( $this, 'post_list_sortable_columns_submit' ), 10 ); |
| 169 |
add_filter( 'screen_options_show_screen', array( $this, 'remove_screen_options' ), 10, 2 ); |
| 170 |
add_filter( 'views_edit-wpzf-form', array( $this, 'post_list_views' ), 10 ); |
| 171 |
add_filter( 'list_table_primary_column', array( $this, 'post_list_primary_column' ), 10, 2 ); |
| 172 |
add_action( 'admin_menu', array( $this, 'admin_menu' ), 10 ); |
| 173 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 100 ); |
| 174 |
add_action( 'enqueue_block_editor_assets', array( $this, 'register_backend_assets' ), 10 ); |
| 175 |
add_action( 'enqueue_block_assets', array( $this, 'register_frontend_assets' ), 10 ); |
| 176 |
add_action( 'enqueue_block_assets', array( $this, 'block_frontend_assets' ), 10 ); |
| 177 |
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_scripts' ), 10 ); |
| 178 |
add_action( 'all_admin_notices', array( $this, 'admin_page_header' ), 1 ); |
| 179 |
add_action( 'in_admin_footer', array( $this, 'admin_page_footer' ), 10 ); |
| 180 |
add_filter( 'admin_body_class', array( $this, 'admin_body_class_filter' ), 10 ); |
| 181 |
add_action( 'manage_wpzf-form_posts_custom_column', array( $this, 'post_list_custom_columns_form' ), 10, 2 ); |
| 182 |
add_action( 'manage_wpzf-submission_posts_custom_column', array( $this, 'post_list_custom_columns_submit' ), 10, 2 ); |
| 183 |
add_action( 'pre_get_posts', array( $this, 'sort_custom_column' ), 10 ); |
| 184 |
add_action( 'in_admin_header', array( $this, 'remove_meta_boxes' ), 100 ); |
| 185 |
add_action( 'add_meta_boxes_wpzf-submission', array( $this, 'add_meta_boxes' ), 10 ); |
| 186 |
add_action( 'admin_post_wpzf_submit', array( $this, 'action_form_post' ), 10 ); |
| 187 |
add_action( 'admin_post_nopriv_wpzf_submit', array( $this, 'action_form_post' ), 10 ); |
| 188 |
|
| 189 |
add_action( 'restrict_manage_posts', array( $this, 'custom_filter_by_form' ), 10 ); |
| 190 |
add_action( 'parse_query', array( $this, 'filter_posts_by_form' ), 10 ); |
| 191 |
|
| 192 |
// Upsell notice for PRO version (via WPZOOM Notice Center) |
| 193 |
add_filter( 'wpzoom_notice_center_notices', array( $this, 'register_upsell_notice' ) ); |
| 194 |
|
| 195 |
register_post_type( |
| 196 |
'wpzf-form', |
| 197 |
array( |
| 198 |
'label' => __( 'WPZOOM Forms', 'wpzoom-forms' ), |
| 199 |
'labels' => array( |
| 200 |
'name' => _x( 'WPZOOM Forms', 'post type general name', 'wpzoom-forms' ), |
| 201 |
'singular_name' => _x( 'Form', 'post type singular name', 'wpzoom-forms' ), |
| 202 |
'add_new' => _x( 'Add New', 'post', 'wpzoom-forms' ), |
| 203 |
'add_new_item' => __( 'Add New Form', 'wpzoom-forms' ), |
| 204 |
'edit_item' => __( 'Edit Form', 'wpzoom-forms' ), |
| 205 |
'new_item' => __( 'New Form', 'wpzoom-forms' ), |
| 206 |
'view_item' => __( 'View Form', 'wpzoom-forms' ), |
| 207 |
'view_items' => __( 'View Forms', 'wpzoom-forms' ), |
| 208 |
'search_items' => __( 'Search Forms', 'wpzoom-forms' ), |
| 209 |
'not_found' => __( 'No forms found.', 'wpzoom-forms' ), |
| 210 |
'not_found_in_trash' => __( 'No forms found in Trash.', 'wpzoom-forms' ), |
| 211 |
'all_items' => __( 'All Forms', 'wpzoom-forms' ), |
| 212 |
'archives' => __( 'Form Archives', 'wpzoom-forms' ), |
| 213 |
'attributes' => __( 'Form Attributes', 'wpzoom-forms' ), |
| 214 |
'insert_into_item' => __( 'Insert into form', 'wpzoom-forms' ), |
| 215 |
'uploaded_to_this_item' => __( 'Uploaded to this form', 'wpzoom-forms' ), |
| 216 |
'featured_image' => _x( 'Featured image', 'post', 'wpzoom-forms' ), |
| 217 |
'set_featured_image' => _x( 'Set featured image', 'post', 'wpzoom-forms' ), |
| 218 |
'remove_featured_image' => _x( 'Remove featured image', 'post', 'wpzoom-forms' ), |
| 219 |
'use_featured_image' => _x( 'Use as featured image', 'post', 'wpzoom-forms' ), |
| 220 |
'filter_items_list' => __( 'Filter forms list', 'wpzoom-forms' ), |
| 221 |
'items_list_navigation' => __( 'Forms list navigation', 'wpzoom-forms' ), |
| 222 |
'items_list' => __( 'Forms list', 'wpzoom-forms' ), |
| 223 |
'item_published' => __( 'Form saved.', 'wpzoom-forms' ), |
| 224 |
'item_published_privately' => __( 'Form saved privately.', 'wpzoom-forms' ), |
| 225 |
'item_reverted_to_draft' => __( 'Form reverted to draft.', 'wpzoom-forms' ), |
| 226 |
'item_scheduled' => __( 'Form scheduled.', 'wpzoom-forms' ), |
| 227 |
'item_updated' => __( 'Form updated.', 'wpzoom-forms' ) |
| 228 |
), |
| 229 |
'public' => true, |
| 230 |
'exclude_from_search' => true, |
| 231 |
'publicly_queryable' => false, |
| 232 |
'show_in_rest' => true, |
| 233 |
'menu_position' => 30, |
| 234 |
'menu_icon' => 'data:image/svg+xml;base64,' . base64_encode('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fillRule="evenodd" clipRule="evenodd" d="M7.33333 2H20.6667V22H4V5.33333H7.33333V2ZM17.3333 5.33333H10.6667V8.66667H7.33333V18.6667H10.6667V15.3333H14V12H10.6667V8.66667H17.3333V5.33333Z" fill="#a7aaad"/></svg>'), |
| 235 |
'supports' => array( 'title', 'editor', 'custom-fields', 'revisions' ) |
| 236 |
) |
| 237 |
); |
| 238 |
|
| 239 |
register_post_type( |
| 240 |
'wpzf-submission', |
| 241 |
array( |
| 242 |
'label' => __( 'WPZOOM Form Submissions', 'wpzoom-forms' ), |
| 243 |
'labels' => array( |
| 244 |
'name' => _x( 'WPZOOM Form Submissions', 'post type general name', 'wpzoom-forms' ), |
| 245 |
'singular_name' => _x( 'WPZOOM Form Submission', 'post type singular name', 'wpzoom-forms' ), |
| 246 |
'add_new' => _x( 'Add New', 'post', 'wpzoom-forms' ), |
| 247 |
'add_new_item' => __( 'Add New Submission', 'wpzoom-forms' ), |
| 248 |
'edit_item' => __( 'WPZOOM Form Submission', 'wpzoom-forms' ), |
| 249 |
'new_item' => __( 'New Submission', 'wpzoom-forms' ), |
| 250 |
'view_item' => __( 'View Submission', 'wpzoom-forms' ), |
| 251 |
'view_items' => __( 'View Submissions', 'wpzoom-forms' ), |
| 252 |
'search_items' => __( 'Search Submissions', 'wpzoom-forms' ), |
| 253 |
'not_found' => __( 'No submissions found.', 'wpzoom-forms' ), |
| 254 |
'not_found_in_trash' => __( 'No submissions found in Trash.', 'wpzoom-forms' ), |
| 255 |
'all_items' => __( 'Submissions', 'wpzoom-forms' ), |
| 256 |
'archives' => __( 'Submission Archives', 'wpzoom-forms' ), |
| 257 |
'attributes' => __( 'Submission Attributes', 'wpzoom-forms' ), |
| 258 |
'insert_into_item' => __( 'Insert into submission', 'wpzoom-forms' ), |
| 259 |
'uploaded_to_this_item' => __( 'Uploaded to this submission', 'wpzoom-forms' ), |
| 260 |
'featured_image' => _x( 'Featured image', 'post', 'wpzoom-forms' ), |
| 261 |
'set_featured_image' => _x( 'Set featured image', 'post', 'wpzoom-forms' ), |
| 262 |
'remove_featured_image' => _x( 'Remove featured image', 'post', 'wpzoom-forms' ), |
| 263 |
'use_featured_image' => _x( 'Use as featured image', 'post', 'wpzoom-forms' ), |
| 264 |
'filter_items_list' => __( 'Filter form submission list', 'wpzoom-forms' ), |
| 265 |
'items_list_navigation' => __( 'Form Submissions list navigation', 'wpzoom-forms' ), |
| 266 |
'items_list' => __( 'Form Submissions list', 'wpzoom-forms' ), |
| 267 |
'item_published' => __( 'Form Submission saved.', 'wpzoom-forms' ), |
| 268 |
'item_published_privately' => __( 'Form Submission saved privately.', 'wpzoom-forms' ), |
| 269 |
'item_reverted_to_draft' => __( 'Form Submission reverted to draft.', 'wpzoom-forms' ), |
| 270 |
'item_scheduled' => __( 'Form Submission scheduled.', 'wpzoom-forms' ), |
| 271 |
'item_updated' => __( 'Form Submission updated.', 'wpzoom-forms' ) |
| 272 |
), |
| 273 |
'public' => true, |
| 274 |
'exclude_from_search' => true, |
| 275 |
'publicly_queryable' => false, |
| 276 |
'show_in_nav_menus' => false, |
| 277 |
'show_in_admin_bar' => false, |
| 278 |
'show_in_rest' => false, |
| 279 |
'show_in_menu' => 'edit.php?post_type=wpzf-form', |
| 280 |
'menu_position' => 31, |
| 281 |
'menu_icon' => 'dashicons-email-alt2', |
| 282 |
'supports' => array( '' ), |
| 283 |
'capabilities' => array( |
| 284 |
'create_posts' => 'do_not_allow', |
| 285 |
'publish_posts' => 'do_not_allow', |
| 286 |
'edit_posts' => 'edit_posts', |
| 287 |
'delete_posts' => 'delete_posts' |
| 288 |
), |
| 289 |
'map_meta_cap' => true |
| 290 |
) |
| 291 |
); |
| 292 |
|
| 293 |
register_post_status( |
| 294 |
'spam', |
| 295 |
array( |
| 296 |
'label' => esc_html_x( 'Spam', 'post', 'wpzoom-forms' ), |
| 297 |
'label_count' => _n_noop( 'Spam <span class="count">(%s)</span>', 'Spam <span class="count">(%s)</span>', 'wpzoom-forms' ), |
| 298 |
'public' => false |
| 299 |
) |
| 300 |
); |
| 301 |
|
| 302 |
register_meta( |
| 303 |
'post', |
| 304 |
'_form_method', |
| 305 |
array( |
| 306 |
'object_subtype' => 'wpzf-form', |
| 307 |
'show_in_rest' => true, |
| 308 |
'single' => true, |
| 309 |
'type' => 'string', |
| 310 |
'default' => 'email', |
| 311 |
'sanitize_callback' => 'sanitize_text_field', |
| 312 |
'auth_callback' => function() { return current_user_can( 'edit_posts' ); } |
| 313 |
) |
| 314 |
); |
| 315 |
|
| 316 |
register_meta( |
| 317 |
'post', |
| 318 |
'_form_email', |
| 319 |
array( |
| 320 |
'object_subtype' => 'wpzf-form', |
| 321 |
'show_in_rest' => true, |
| 322 |
'single' => true, |
| 323 |
'type' => 'string', |
| 324 |
'default' => '', |
| 325 |
'sanitize_callback' => 'sanitize_text_field', |
| 326 |
'auth_callback' => function() { return current_user_can( 'edit_posts' ); } |
| 327 |
) |
| 328 |
); |
| 329 |
|
| 330 |
register_meta( |
| 331 |
'post', |
| 332 |
'_form_subject', |
| 333 |
array( |
| 334 |
'object_subtype' => 'wpzf-form', |
| 335 |
'show_in_rest' => true, |
| 336 |
'single' => true, |
| 337 |
'type' => 'string', |
| 338 |
'default' => esc_html__( 'New Form Submission', 'wpzoom-forms' ), |
| 339 |
'sanitize_callback' => 'sanitize_text_field', |
| 340 |
'auth_callback' => function() { return current_user_can( 'edit_posts' ); } |
| 341 |
) |
| 342 |
); |
| 343 |
|
| 344 |
register_meta( |
| 345 |
'post', |
| 346 |
'_form_success_message', |
| 347 |
array( |
| 348 |
'object_subtype' => 'wpzf-form', |
| 349 |
'show_in_rest' => true, |
| 350 |
'single' => true, |
| 351 |
'type' => 'string', |
| 352 |
'default' => __( 'Thanks! We\'ve received your submission!', 'wpzoom-forms' ), |
| 353 |
'sanitize_callback' => function( $value ) { |
| 354 |
return wp_kses( $value, array() ); |
| 355 |
}, |
| 356 |
'auth_callback' => function() { return current_user_can( 'edit_posts' ); } |
| 357 |
) |
| 358 |
); |
| 359 |
|
| 360 |
register_meta( |
| 361 |
'post', |
| 362 |
'_form_failure_message', |
| 363 |
array( |
| 364 |
'object_subtype' => 'wpzf-form', |
| 365 |
'show_in_rest' => true, |
| 366 |
'single' => true, |
| 367 |
'type' => 'string', |
| 368 |
'default' => __( 'Submission failed!', 'wpzoom-forms' ), |
| 369 |
'sanitize_callback' => function( $value ) { |
| 370 |
return wp_kses( $value, array() ); |
| 371 |
}, |
| 372 |
'auth_callback' => function() { return current_user_can( 'edit_posts' ); } |
| 373 |
) |
| 374 |
); |
| 375 |
|
| 376 |
add_shortcode( 'wpzf_form', array( $this, 'shortcode_output' ) ); |
| 377 |
|
| 378 |
//$form_pto = get_post_type_object( 'wpzf-form' ); |
| 379 |
//$form_pto->template = array( array( 'wpzoom-forms/form' ) ); |
| 380 |
|
| 381 |
if ( $this->is_post_type( 'wpzf-form' ) ) { |
| 382 |
$this->forms_display(); |
| 383 |
$this->register_blocks(); |
| 384 |
} elseif ( $this->is_post_type( 'wpzf-submission' ) ) { |
| 385 |
$this->submissions_display(); |
| 386 |
} else { |
| 387 |
$this->register_form_block(); |
| 388 |
} |
| 389 |
|
| 390 |
$this->initialized = true; |
| 391 |
} |
| 392 |
} |
| 393 |
|
| 394 |
/** |
| 395 |
* Runs once during the activation of the plugin to run some one-time setup functions. |
| 396 |
* |
| 397 |
* @access public |
| 398 |
* @return void |
| 399 |
* @since 1.0.0 |
| 400 |
* @see ZOOM_Forms::init() |
| 401 |
*/ |
| 402 |
public function activate() { |
| 403 |
$this->init(); |
| 404 |
|
| 405 |
flush_rewrite_rules(); |
| 406 |
|
| 407 |
// If this is the first time activating the plugin... |
| 408 |
if ( ! get_option( 'wpzf-form_first-activate' ) ) { |
| 409 |
// Insert an initial example form post |
| 410 |
wp_insert_post( array( |
| 411 |
'post_type' => 'wpzf-form', |
| 412 |
'post_status' => 'publish', |
| 413 |
'post_title' => __( 'Example Form', 'wpzoom-forms' ), |
| 414 |
'post_content' => '<!-- wp:wpzoom-forms/form --> |
| 415 |
<div class="wp-block-wpzoom-forms-form"><!-- wp:wpzoom-forms/text-name-field {"id":"input_ae87379b","name":"Name"} --> |
| 416 |
<label for="input_ae87379b"><span>Name</span><sup class="wp-block-wpzoom-forms-required">*</sup></label><input type="text" name="input_ae87379b" id="input_ae87379b" placeholder="" required class="wp-block-wpzoom-forms-text-name-field"/> |
| 417 |
<!-- /wp:wpzoom-forms/text-name-field --> |
| 418 |
|
| 419 |
<!-- wp:wpzoom-forms/text-email-field {"id":"input_8468ae36","name":"Email"} --> |
| 420 |
<label for="input_8468ae36"><span>Email</span><sup class="wp-block-wpzoom-forms-required">*</sup></label><input type="email" name="input_8468ae36" id="input_8468ae36" placeholder="" required data-replyto="false" class="wp-block-wpzoom-forms-text-email-field"/> |
| 421 |
<!-- /wp:wpzoom-forms/text-email-field --> |
| 422 |
|
| 423 |
<!-- wp:wpzoom-forms/text-plain-field {"id":"input_85d61063","name":"Subject","label":"Subject","subject":true} --> |
| 424 |
<label for="input_85d61063"><span>Subject</span><sup class="wp-block-wpzoom-forms-required">*</sup></label><input type="text" name="input_85d61063" id="input_85d61063" placeholder="" required data-subject="true" class="wp-block-wpzoom-forms-text-plain-field"/> |
| 425 |
<!-- /wp:wpzoom-forms/text-plain-field --> |
| 426 |
|
| 427 |
<!-- wp:wpzoom-forms/textarea-field {"id":"input_7f6bf203","name":"Message"} --> |
| 428 |
<label for="input_7f6bf203"><span>Message</span></label><textarea name="input_7f6bf203" id="input_7f6bf203" cols="55" rows="10" placeholder="" class="wp-block-wpzoom-forms-textarea-field"></textarea> |
| 429 |
<!-- /wp:wpzoom-forms/textarea-field --> |
| 430 |
|
| 431 |
<!-- wp:columns {"verticalAlignment":"center"} --> |
| 432 |
<div class="wp-block-columns are-vertically-aligned-center"><!-- wp:column {"verticalAlignment":"center","width":"30%"} --> |
| 433 |
<div class="wp-block-column is-vertically-aligned-center" style="flex-basis:30%"><!-- wp:wpzoom-forms/submit-field {"id":"input_submit"} --> |
| 434 |
<input type="submit" id="input_submit" value="Submit" class="wp-block-wpzoom-forms-submit-field"/> |
| 435 |
<!-- /wp:wpzoom-forms/submit-field --></div> |
| 436 |
<!-- /wp:column --> |
| 437 |
|
| 438 |
<!-- wp:column {"verticalAlignment":"center","width":"70%"} --> |
| 439 |
<div class="wp-block-column is-vertically-aligned-center" style="flex-basis:70%"><!-- wp:paragraph {"align":"right","style":{"typography":{"fontSize":16}}} --> |
| 440 |
<p class="has-text-align-right" style="font-size:16px">Fields marked with <strong class="has-accent-color has-text-color">*</strong> are required.</p> |
| 441 |
<!-- /wp:paragraph --></div> |
| 442 |
<!-- /wp:column --></div> |
| 443 |
<!-- /wp:columns --></div> |
| 444 |
<!-- /wp:wpzoom-forms/form -->', |
| 445 |
'meta_input' => array( |
| 446 |
'_form_method' => 'email', |
| 447 |
'_form_email' => trim( get_option( 'admin_email' ) ), |
| 448 |
'_form_subject' => esc_html__( 'New Form Submission', 'wpzoom-forms' ), |
| 449 |
'_form_success_message' => __( 'Thanks! We\'ve received your submission!', 'wpzoom-forms' ), |
| 450 |
'_form_failure_message' => __( 'Submission failed!', 'wpzoom-forms' ), |
| 451 |
|
| 452 |
) |
| 453 |
) ); |
| 454 |
|
| 455 |
// Make sure we don't insert an example form on every activation |
| 456 |
update_option( 'wpzf-form_first-activate', true ); |
| 457 |
} |
| 458 |
} |
| 459 |
|
| 460 |
/** |
| 461 |
* Modifies the way the backend forms list is displayed. |
| 462 |
* |
| 463 |
* @access public |
| 464 |
* @return void |
| 465 |
* @since 1.0.0 |
| 466 |
*/ |
| 467 |
public function forms_display() { |
| 468 |
global $wp_post_statuses; |
| 469 |
|
| 470 |
$publish = $wp_post_statuses['publish']; |
| 471 |
$publish->label = __( 'Saved', 'wpzoom-forms' ); |
| 472 |
$publish->label_count[0] = __( 'Saved <span class="count">(%s)</span>', 'wpzoom-forms' ); |
| 473 |
$publish->label_count[1] = __( 'Saved <span class="count">(%s)</span>', 'wpzoom-forms' ); |
| 474 |
$publish->label_count['singular'] = __( 'Saved <span class="count">(%s)</span>', 'wpzoom-forms' ); |
| 475 |
$publish->label_count['plural'] = __( 'Saved <span class="count">(%s)</span>', 'wpzoom-forms' ); |
| 476 |
|
| 477 |
$wp_post_statuses['publish'] = $publish; |
| 478 |
|
| 479 |
$wp_post_statuses = array_diff_key( |
| 480 |
$wp_post_statuses, |
| 481 |
array_flip( array( |
| 482 |
'future', |
| 483 |
'pending', |
| 484 |
'private', |
| 485 |
'request-pending', |
| 486 |
'request-confirmed', |
| 487 |
'request-failed', |
| 488 |
'request-completed' |
| 489 |
) ) |
| 490 |
); |
| 491 |
|
| 492 |
add_filter( 'post_date_column_status', function() { return __( 'Last Modified', 'wpzoom-forms' ); } ); |
| 493 |
add_filter( 'post_date_column_time', function( $time, $post ) { |
| 494 |
return sprintf( |
| 495 |
__( '%1$s at %2$s', 'wpzoom-forms' ), |
| 496 |
get_the_modified_time( __( 'Y/m/d', 'wpzoom-forms' ), $post ), |
| 497 |
get_the_modified_time( __( 'g:i a', 'wpzoom-forms' ), $post ) |
| 498 |
); |
| 499 |
}, 10, 2 ); |
| 500 |
} |
| 501 |
|
| 502 |
/** |
| 503 |
* Modifies the way the backend submissions list is displayed. |
| 504 |
* |
| 505 |
* @access public |
| 506 |
* @return void |
| 507 |
* @since 1.0.0 |
| 508 |
*/ |
| 509 |
public function submissions_display() { |
| 510 |
global $wp_post_statuses; |
| 511 |
|
| 512 |
$wp_post_statuses = array_diff_key( |
| 513 |
$wp_post_statuses, |
| 514 |
array_flip( [ |
| 515 |
'future', |
| 516 |
'pending', |
| 517 |
'private', |
| 518 |
'request-pending', |
| 519 |
'request-confirmed', |
| 520 |
'request-failed', |
| 521 |
'request-completed' |
| 522 |
] ) |
| 523 |
); |
| 524 |
|
| 525 |
add_filter( 'post_date_column_status', function() { return __( 'Submitted', 'wpzoom-forms' ); } ); |
| 526 |
} |
| 527 |
|
| 528 |
/** |
| 529 |
* Registers all the custom blocks for this plugin. |
| 530 |
* |
| 531 |
* @access public |
| 532 |
* @return void |
| 533 |
* @since 1.0.0 |
| 534 |
*/ |
| 535 |
public function register_blocks() { |
| 536 |
register_block_type( |
| 537 |
'wpzoom-forms/form', |
| 538 |
array( |
| 539 |
'script' => 'wpzoom-forms-js-frontend-formblock', |
| 540 |
'style' => 'wpzoom-forms-css-frontend-formblock', |
| 541 |
'editor_script' => 'wpzoom-forms-js-backend-main', |
| 542 |
'editor_style' => 'wpzoom-forms-css-backend-main' |
| 543 |
) |
| 544 |
); |
| 545 |
|
| 546 |
foreach ( array( 'multi-checkbox', 'checkbox', 'email', 'label', 'name', 'phone', 'plain', 'radio', 'select', 'submit', 'textarea', 'website', 'datepicker' ) as $block ) { |
| 547 |
register_block_type( $this->main_dir_path . 'fields/' . $block . '/block.json' ); |
| 548 |
} |
| 549 |
} |
| 550 |
|
| 551 |
/** |
| 552 |
* Registers the main form block used for inserting a form into a regular post/page. |
| 553 |
* |
| 554 |
* @access public |
| 555 |
* @return void |
| 556 |
* @since 1.0.0 |
| 557 |
*/ |
| 558 |
public function register_form_block() { |
| 559 |
register_block_type( |
| 560 |
'wpzoom-forms/form-block', |
| 561 |
array( |
| 562 |
'attributes' => array( |
| 563 |
'formId' => array( |
| 564 |
'type' => 'string', |
| 565 |
'default' => '-1' |
| 566 |
), |
| 567 |
'align' => array( |
| 568 |
'type' => 'string', |
| 569 |
'default' => 'none' |
| 570 |
), |
| 571 |
'formBgColor' => array( |
| 572 |
'type' => 'string', |
| 573 |
'default' => '' |
| 574 |
), |
| 575 |
'formBrd' => array( |
| 576 |
'type' => 'string', |
| 577 |
'default' => '' |
| 578 |
), |
| 579 |
|
| 580 |
'fieldBrdStyle' => array( |
| 581 |
'type' => 'string', |
| 582 |
'default' => 'default' |
| 583 |
), |
| 584 |
'fieldBrdWidth' => array( |
| 585 |
'type' => 'number', |
| 586 |
'default' => 0 |
| 587 |
), |
| 588 |
'fieldBrdRadius' => array( |
| 589 |
'type' => 'number', |
| 590 |
'default' => 0 |
| 591 |
), |
| 592 |
|
| 593 |
'fieldBrdColor' => array( |
| 594 |
'type' => 'string', |
| 595 |
'default' => '' |
| 596 |
), |
| 597 |
'fieldTextColor' => array( |
| 598 |
'type' => 'string', |
| 599 |
'default' => '' |
| 600 |
), |
| 601 |
'fieldBgColor' => array( |
| 602 |
'type' => 'string', |
| 603 |
'default' => '' |
| 604 |
), |
| 605 |
'labelTextColor' => array( |
| 606 |
'type' => 'string', |
| 607 |
'default' => '' |
| 608 |
), |
| 609 |
'btnBgColor' => array( |
| 610 |
'type' => 'string', |
| 611 |
'default' => '' |
| 612 |
), |
| 613 |
'btnTextColor' => array( |
| 614 |
'type' => 'string', |
| 615 |
'default' => '' |
| 616 |
), |
| 617 |
'btnBrdWidth' => array( |
| 618 |
'type' => 'number', |
| 619 |
'default' => 0 |
| 620 |
), |
| 621 |
'btnBrdStyle' => array( |
| 622 |
'type' => 'string', |
| 623 |
'default' => 'default' |
| 624 |
), |
| 625 |
'btnBrdRadius' => array( |
| 626 |
'type' => 'number', |
| 627 |
'default' => 0 |
| 628 |
), |
| 629 |
'btnBrdColor' => array( |
| 630 |
'type' => 'string', |
| 631 |
'default' => '' |
| 632 |
), |
| 633 |
'btnHoverBgColor' => array( |
| 634 |
'type' => 'string', |
| 635 |
'default' => '' |
| 636 |
), |
| 637 |
'btnHoverTextColor' => array( |
| 638 |
'type' => 'string', |
| 639 |
'default' => '' |
| 640 |
), |
| 641 |
'btnHoverBrdColor' => array( |
| 642 |
'type' => 'string', |
| 643 |
'default' => '' |
| 644 |
), |
| 645 |
|
| 646 |
), |
| 647 |
'script' => 'wpzoom-forms-js-frontend-formblock', |
| 648 |
'style' => 'wpzoom-forms-css-frontend-formblock', |
| 649 |
'editor_script' => 'wpzoom-forms-js-backend-formblock', |
| 650 |
'editor_style' => 'wpzoom-forms-css-backend-formblock', |
| 651 |
'render_callback' => array( $this, 'form_block_render' ) |
| 652 |
) |
| 653 |
); |
| 654 |
} |
| 655 |
|
| 656 |
/** |
| 657 |
* Filters the allowed Gutenberg block types for a given post. |
| 658 |
* |
| 659 |
* @access public |
| 660 |
* @param array $allowed_block_types An array of all the allowed block types. |
| 661 |
* @param WP_Block_Editor_Context $block_editor_context The current block editor context. |
| 662 |
* @return array |
| 663 |
* @since 1.0.0 |
| 664 |
*/ |
| 665 |
public function filter_allowed_block_types( $allowed_block_types, $block_editor_context ) { |
| 666 |
if ( null !== $block_editor_context->post && 'wpzf-form' == $block_editor_context->post->post_type ) { |
| 667 |
$allowed_block_types = array( |
| 668 |
'wpzoom-forms/form', |
| 669 |
'wpzoom-forms/datepicker-field', |
| 670 |
'wpzoom-forms/text-plain-field', |
| 671 |
'wpzoom-forms/text-name-field', |
| 672 |
'wpzoom-forms/text-email-field', |
| 673 |
'wpzoom-forms/text-website-field', |
| 674 |
'wpzoom-forms/text-phone-field', |
| 675 |
'wpzoom-forms/textarea-field', |
| 676 |
'wpzoom-forms/select-field', |
| 677 |
'wpzoom-forms/multi-checkbox-field', |
| 678 |
'wpzoom-forms/checkbox-field', |
| 679 |
'wpzoom-forms/radio-field', |
| 680 |
'wpzoom-forms/label-field', |
| 681 |
'wpzoom-forms/submit-field', |
| 682 |
'core/paragraph', |
| 683 |
'core/heading', |
| 684 |
'core/list', |
| 685 |
'core/quote', |
| 686 |
'core/code', |
| 687 |
'core/preformatted', |
| 688 |
'core/pullquote', |
| 689 |
'core/table', |
| 690 |
'core/verse', |
| 691 |
'core/image', |
| 692 |
'core/gallery', |
| 693 |
'core/audio', |
| 694 |
'core/cover', |
| 695 |
'core/file', |
| 696 |
'core/media-text', |
| 697 |
'core/video', |
| 698 |
'core/buttons', |
| 699 |
'core/columns', |
| 700 |
'core/group', |
| 701 |
'core/more', |
| 702 |
'core/nextpage', |
| 703 |
'core/separator', |
| 704 |
'core/spacer' |
| 705 |
); |
| 706 |
} |
| 707 |
|
| 708 |
return $allowed_block_types; |
| 709 |
} |
| 710 |
|
| 711 |
/** |
| 712 |
* Adds needed categories to the Gutenberg block categories, if not already present. |
| 713 |
* |
| 714 |
* @access public |
| 715 |
* @param array $categories Array containing all registered Gutenberg block categories. |
| 716 |
* @param WP_Block_Editor_Context $block_editor_context The current block editor context. |
| 717 |
* @return array |
| 718 |
* @since 1.0.0 |
| 719 |
*/ |
| 720 |
public function filter_block_categories( $categories, $block_editor_context ) { |
| 721 |
if ( null !== $block_editor_context->post && 'wpzf-form' == $block_editor_context->post->post_type ) { |
| 722 |
$category_slugs = wp_list_pluck( $categories, 'slug' ); |
| 723 |
|
| 724 |
if ( ! in_array( 'wpzoom-forms', $category_slugs, true ) ) { |
| 725 |
array_unshift( |
| 726 |
$categories, |
| 727 |
array( |
| 728 |
'slug' => 'wpzoom-forms', |
| 729 |
'title' => __( 'WPZOOM Forms', 'wpzoom-forms' ), |
| 730 |
'icon' => 'wordpress' |
| 731 |
) |
| 732 |
); |
| 733 |
} |
| 734 |
} else { |
| 735 |
$category_slugs = wp_list_pluck( $categories, 'slug' ); |
| 736 |
|
| 737 |
if ( ! in_array( 'wpzoom-blocks', $category_slugs, true ) ) { |
| 738 |
$categories = array_merge( |
| 739 |
$categories, |
| 740 |
array( |
| 741 |
array( |
| 742 |
'slug' => 'wpzoom-blocks', |
| 743 |
'title' => __( 'WPZOOM Blocks', 'wpzoom-forms' ), |
| 744 |
'icon' => 'wordpress' |
| 745 |
) |
| 746 |
) |
| 747 |
); |
| 748 |
} |
| 749 |
} |
| 750 |
|
| 751 |
return $categories; |
| 752 |
} |
| 753 |
|
| 754 |
/** |
| 755 |
* Add some extra admin menu items. |
| 756 |
* |
| 757 |
* @access public |
| 758 |
* @return void |
| 759 |
* @since 1.0.0 |
| 760 |
*/ |
| 761 |
public function admin_menu() { |
| 762 |
|
| 763 |
global $submenu; |
| 764 |
|
| 765 |
$page_title = esc_html__( 'WPZOOM Forms Settings Page', 'wpzoom-forms' ); |
| 766 |
|
| 767 |
add_submenu_page( |
| 768 |
'edit.php?post_type=wpzf-form', |
| 769 |
$page_title, |
| 770 |
esc_html__( 'Settings', 'wpzoom-forms' ), |
| 771 |
'manage_options', |
| 772 |
'wpzf-settings', |
| 773 |
array( $this, 'render_settings_page' ) |
| 774 |
); |
| 775 |
|
| 776 |
add_submenu_page( |
| 777 |
'edit.php?post_type=wpzf-form', |
| 778 |
$page_title, |
| 779 |
'<span style="color:#3496fe; font-weight: 600;">' . esc_html__( 'UPGRADE', 'wpzoom-forms' ) . ' → <span class="wpz-premium-badge" style="background-color: #3496fe; color: #fff; margin-left: 3px; font-size: 9px; min-height: 14px; border-radius: 3px; display: inline-block; font-weight: 600; line-height: 1.4; padding: 0 5px">PRO</span></span>', |
| 780 |
'manage_options', |
| 781 |
'wpzf-pro-page', |
| 782 |
array( $this, 'render_upsell_page' ) |
| 783 |
); |
| 784 |
|
| 785 |
add_submenu_page( |
| 786 |
'edit.php?post_type=wpzf-form', |
| 787 |
esc_html__( 'Import & Export', 'wpzoom-forms' ), |
| 788 |
esc_html__( 'Import & Export', 'wpzoom-forms' ) . ' <span class="wpz-premium-badge" style="background-color: #3496fe; color: #fff; margin-left: 3px; font-size: 9px; min-height: 14px; border-radius: 3px; display: inline-block; font-weight: 600; line-height: 1.4; padding: 0 5px">PRO</span>', |
| 789 |
'edit_posts', |
| 790 |
'wpzf-import', |
| 791 |
array( $this, 'render_import_export_upsell_page' ) |
| 792 |
); |
| 793 |
|
| 794 |
} |
| 795 |
|
| 796 |
/** |
| 797 |
* Registers needed scripts for use on the admin backend. |
| 798 |
* |
| 799 |
* @access public |
| 800 |
* @return void |
| 801 |
* @since 1.0.0 |
| 802 |
*/ |
| 803 |
public function admin_enqueue_scripts() { |
| 804 |
if ( 'wpzf-submission' == get_post_type() ) { |
| 805 |
wp_dequeue_script( 'autosave' ); |
| 806 |
|
| 807 |
wp_enqueue_style( |
| 808 |
'wpzoom-forms-css-backend-submissions', |
| 809 |
trailingslashit( $this->main_dir_url ) . 'submissions/backend/style.css', |
| 810 |
array(), |
| 811 |
WPZOOM_FORMS_VERSION |
| 812 |
); |
| 813 |
} |
| 814 |
|
| 815 |
$current_page = get_current_screen()->id; |
| 816 |
|
| 817 |
if ( 'edit-wpzf-form' == $current_page || 'wpzf-form' == $current_page || 'edit-wpzf-submission' == $current_page || 'wpzf-submission' == $current_page || 'wpzf-form_page_wpzf-settings' == $current_page || 'wpzf-form_page_wpzoom-forms-pro-license' == $current_page || 'wpzf-form_page_wpzf-pro-page' == $current_page || 'wpzf-form_page_wpzf-import' == $current_page ) { |
| 818 |
wp_enqueue_style( |
| 819 |
'wpzoom-forms-css-backend-main', |
| 820 |
trailingslashit( $this->main_dir_url ) . 'main/backend/style.css', |
| 821 |
array(), |
| 822 |
WPZOOM_FORMS_VERSION |
| 823 |
); |
| 824 |
} |
| 825 |
|
| 826 |
if ( 'edit-wpzf-form' == $current_page || 'wpzf-form' == $current_page ) { |
| 827 |
wp_enqueue_script( |
| 828 |
'wpzoom-forms-cpt', |
| 829 |
WPZOOM_FORMS_URL . 'dist/assets/admin/js/forms-cpt.js', |
| 830 |
array( 'wp-data' ), |
| 831 |
WPZOOM_FORMS_VERSION, |
| 832 |
true |
| 833 |
); |
| 834 |
} |
| 835 |
|
| 836 |
} |
| 837 |
|
| 838 |
/** |
| 839 |
* Registers needed scripts and styles for use on the backend. |
| 840 |
* |
| 841 |
* @access public |
| 842 |
* @return void |
| 843 |
* @since 1.0.0 |
| 844 |
*/ |
| 845 |
public function register_backend_assets() { |
| 846 |
if ( 'wpzf-form' == get_post_type() ) { |
| 847 |
wp_register_script( |
| 848 |
'wpzoom-forms-js-backend-main', |
| 849 |
trailingslashit( $this->main_dir_url ) . 'main/backend/script.js', |
| 850 |
array( 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-polyfill' ), |
| 851 |
WPZOOM_FORMS_VERSION, |
| 852 |
true |
| 853 |
); |
| 854 |
|
| 855 |
wp_localize_script( |
| 856 |
'wpzoom-forms-js-backend-main', |
| 857 |
'wpzf_formblock', |
| 858 |
array( |
| 859 |
'admin_url' => trailingslashit( admin_url() ), |
| 860 |
'admin_email' => '' . get_site_option( 'admin_email', '' ) |
| 861 |
) |
| 862 |
); |
| 863 |
|
| 864 |
wp_set_script_translations( 'wpzoom-forms-js-backend-main', 'wpzoom-forms' ); |
| 865 |
|
| 866 |
wp_register_style( |
| 867 |
'wpzoom-forms-css-backend-main', |
| 868 |
trailingslashit( $this->main_dir_url ) . 'main/backend/style.css', |
| 869 |
array(), |
| 870 |
WPZOOM_FORMS_VERSION |
| 871 |
); |
| 872 |
} else { |
| 873 |
wp_register_script( |
| 874 |
'wpzoom-forms-js-backend-formblock', |
| 875 |
trailingslashit( $this->main_dir_url ) . 'form-block/backend/script.js', |
| 876 |
array( 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-polyfill' ), |
| 877 |
WPZOOM_FORMS_VERSION, |
| 878 |
true |
| 879 |
); |
| 880 |
|
| 881 |
wp_localize_script( |
| 882 |
'wpzoom-forms-js-backend-formblock', |
| 883 |
'wpzf_formblock', |
| 884 |
array( |
| 885 |
'admin_url' => trailingslashit( admin_url() ), |
| 886 |
'admin_email' => '' . get_site_option( 'admin_email', '' ) |
| 887 |
) |
| 888 |
); |
| 889 |
|
| 890 |
wp_set_script_translations( 'wpzoom-forms-js-backend-formblock', 'wpzoom-forms' ); |
| 891 |
|
| 892 |
wp_register_style( |
| 893 |
'wpzoom-forms-css-backend-formblock', |
| 894 |
trailingslashit( $this->main_dir_url ) . 'form-block/backend/style.css', |
| 895 |
array(), |
| 896 |
WPZOOM_FORMS_VERSION |
| 897 |
); |
| 898 |
} |
| 899 |
} |
| 900 |
|
| 901 |
/** |
| 902 |
* Get normalized spam protection settings and whether the selected method is fully configured. |
| 903 |
* |
| 904 |
* @access private |
| 905 |
* @return array |
| 906 |
* @since 1.3.7 |
| 907 |
*/ |
| 908 |
public function get_spam_protection_config() { |
| 909 |
$service = sanitize_text_field( (string) WPZOOM_Forms_Settings::get( 'wpzf_global_captcha_service' ) ); |
| 910 |
$type = sanitize_text_field( (string) WPZOOM_Forms_Settings::get( 'wpzf_global_captcha_type' ) ); |
| 911 |
|
| 912 |
if ( ! in_array( $service, array( 'none', 'recaptcha', 'turnstile' ), true ) ) { |
| 913 |
$service = 'none'; |
| 914 |
} |
| 915 |
|
| 916 |
if ( ! in_array( $type, array( 'v2', 'v3' ), true ) ) { |
| 917 |
$type = 'v2'; |
| 918 |
} |
| 919 |
|
| 920 |
$recaptcha_v2_site_key = trim( sanitize_text_field( (string) WPZOOM_Forms_Settings::get( 'wpzf_global_captcha_site_key' ) ) ); |
| 921 |
$recaptcha_v2_secret_key = trim( sanitize_text_field( (string) WPZOOM_Forms_Settings::get( 'wpzf_global_captcha_secret_key' ) ) ); |
| 922 |
$recaptcha_v3_site_key = trim( sanitize_text_field( (string) WPZOOM_Forms_Settings::get( 'wpzf_global_captcha_site_key_v3' ) ) ); |
| 923 |
$recaptcha_v3_secret_key = trim( sanitize_text_field( (string) WPZOOM_Forms_Settings::get( 'wpzf_global_captcha_secret_key_v3' ) ) ); |
| 924 |
$turnstile_site_key = trim( sanitize_text_field( (string) WPZOOM_Forms_Settings::get( 'wpzf_global_turnstile_site_key' ) ) ); |
| 925 |
$turnstile_secret_key = trim( sanitize_text_field( (string) WPZOOM_Forms_Settings::get( 'wpzf_global_turnstile_secret_key' ) ) ); |
| 926 |
|
| 927 |
$active_service = 'none'; |
| 928 |
|
| 929 |
if ( 'recaptcha' === $service ) { |
| 930 |
if ( 'v3' === $type && ! empty( $recaptcha_v3_site_key ) && ! empty( $recaptcha_v3_secret_key ) ) { |
| 931 |
$active_service = 'recaptcha'; |
| 932 |
} elseif ( 'v2' === $type && ! empty( $recaptcha_v2_site_key ) && ! empty( $recaptcha_v2_secret_key ) ) { |
| 933 |
$active_service = 'recaptcha'; |
| 934 |
} |
| 935 |
} elseif ( 'turnstile' === $service && ! empty( $turnstile_site_key ) && ! empty( $turnstile_secret_key ) ) { |
| 936 |
$active_service = 'turnstile'; |
| 937 |
} |
| 938 |
|
| 939 |
return array( |
| 940 |
'service' => $service, |
| 941 |
'type' => $type, |
| 942 |
'active_service' => $active_service, |
| 943 |
'recaptcha_v2_site_key' => $recaptcha_v2_site_key, |
| 944 |
'recaptcha_v2_secret_key' => $recaptcha_v2_secret_key, |
| 945 |
'recaptcha_v3_site_key' => $recaptcha_v3_site_key, |
| 946 |
'recaptcha_v3_secret_key' => $recaptcha_v3_secret_key, |
| 947 |
'turnstile_site_key' => $turnstile_site_key, |
| 948 |
'turnstile_secret_key' => $turnstile_secret_key, |
| 949 |
); |
| 950 |
} |
| 951 |
|
| 952 |
/** |
| 953 |
* Registers needed scripts and styles for use on the frontend. |
| 954 |
* |
| 955 |
* @access public |
| 956 |
* @return void |
| 957 |
* @since 1.0.0 |
| 958 |
*/ |
| 959 |
public function register_frontend_assets() { |
| 960 |
|
| 961 |
$depends = array( 'jquery' ); |
| 962 |
$captcha = $this->get_spam_protection_config(); |
| 963 |
$captcha_type = $captcha['type']; |
| 964 |
$active_method = $captcha['active_service']; |
| 965 |
|
| 966 |
if ( ! is_admin() ) { |
| 967 |
if ( 'recaptcha' === $active_method ) { |
| 968 |
$site_key = ( 'v3' === $captcha_type ) ? $captcha['recaptcha_v3_site_key'] : $captcha['recaptcha_v2_site_key']; |
| 969 |
|
| 970 |
if ( 'v2' === $captcha_type ) { |
| 971 |
wp_register_script( |
| 972 |
'google-recaptcha', |
| 973 |
'https://www.google.com/recaptcha/api.js', |
| 974 |
array(), |
| 975 |
WPZOOM_FORMS_VERSION, |
| 976 |
true |
| 977 |
); |
| 978 |
} |
| 979 |
elseif ( 'v3' === $captcha_type ) { |
| 980 |
wp_register_script( |
| 981 |
'google-recaptcha', |
| 982 |
"https://www.google.com/recaptcha/api.js?render={$site_key}", |
| 983 |
array(), |
| 984 |
WPZOOM_FORMS_VERSION, |
| 985 |
true |
| 986 |
); |
| 987 |
} |
| 988 |
|
| 989 |
$depends[] = 'google-recaptcha'; |
| 990 |
} elseif ( 'turnstile' === $active_method ) { |
| 991 |
wp_register_script( |
| 992 |
'turnstile-recaptcha', |
| 993 |
'https://challenges.cloudflare.com/turnstile/v0/api.js', |
| 994 |
array(), |
| 995 |
null, |
| 996 |
array( 'strategy' => 'defer' ), |
| 997 |
); |
| 998 |
|
| 999 |
$depends[] = 'turnstile-recaptcha'; |
| 1000 |
} |
| 1001 |
} |
| 1002 |
|
| 1003 |
wp_register_script( |
| 1004 |
'wpzoom-forms-js-frontend-formblock', |
| 1005 |
trailingslashit( $this->dist_dir_url ) . 'assets/frontend/js/script.js', |
| 1006 |
$depends, |
| 1007 |
WPZOOM_FORMS_VERSION, |
| 1008 |
array( |
| 1009 |
'in_footer' => true, |
| 1010 |
'strategy' => 'defer', |
| 1011 |
) |
| 1012 |
); |
| 1013 |
|
| 1014 |
$use_theme_style = boolval( WPZOOM_Forms_Settings::get( 'wpzf_use_theme_styles' ) ); |
| 1015 |
|
| 1016 |
wp_register_style( |
| 1017 |
'wpzoom-forms-css-frontend-formblock', |
| 1018 |
( $use_theme_style ? trailingslashit( $this->main_dir_url ) . 'form-block/frontend/style.css' : false ), |
| 1019 |
array(), |
| 1020 |
WPZOOM_FORMS_VERSION |
| 1021 |
); |
| 1022 |
|
| 1023 |
// Register style for datepicker field |
| 1024 |
wp_register_style( |
| 1025 |
'wpzoom-forms-css-frontend-flatpickr', |
| 1026 |
trailingslashit( $this->dist_dir_url ) . 'assets/frontend/flatpickr/css/flatpickr.min.css', |
| 1027 |
array(), |
| 1028 |
WPZOOM_FORMS_VERSION |
| 1029 |
); |
| 1030 |
|
| 1031 |
//Register script for datepicker field |
| 1032 |
wp_register_script( |
| 1033 |
'wpzoom-forms-js-frontend-flatpickr', |
| 1034 |
trailingslashit( $this->dist_dir_url ) . 'assets/frontend/flatpickr/js/flatpickr.js', |
| 1035 |
array( 'jquery' ), |
| 1036 |
WPZOOM_FORMS_VERSION, |
| 1037 |
array( |
| 1038 |
'in_footer' => true, |
| 1039 |
'strategy' => 'defer', |
| 1040 |
) |
| 1041 |
); |
| 1042 |
|
| 1043 |
wp_register_script( |
| 1044 |
'wpzoom-forms-js-frontend-datepicker', |
| 1045 |
trailingslashit( $this->dist_dir_url ) . 'assets/frontend/js/datepicker.js', |
| 1046 |
array( 'wpzoom-forms-js-frontend-flatpickr' ), |
| 1047 |
WPZOOM_FORMS_VERSION, |
| 1048 |
array( |
| 1049 |
'in_footer' => true, |
| 1050 |
'strategy' => 'defer', |
| 1051 |
) |
| 1052 |
); |
| 1053 |
} |
| 1054 |
|
| 1055 |
/** |
| 1056 |
* Enqueues needed scripts and styles for use on the frontend. |
| 1057 |
* |
| 1058 |
* @access public |
| 1059 |
* @return void |
| 1060 |
* @since 1.0.0 |
| 1061 |
*/ |
| 1062 |
public function enqueue_frontend_scripts() { |
| 1063 |
|
| 1064 |
$global_load_assets = boolval( WPZOOM_Forms_Settings::get( 'wpzf_global_assets_load' ) ); |
| 1065 |
|
| 1066 |
if ( $global_load_assets ) { |
| 1067 |
wp_enqueue_style( 'wpzoom-forms-css-frontend-formblock' ); |
| 1068 |
wp_enqueue_script( 'wpzoom-forms-js-frontend-formblock' ); |
| 1069 |
} |
| 1070 |
|
| 1071 |
} |
| 1072 |
|
| 1073 |
/** |
| 1074 |
* Enqueues needed scripts and styles for use on the frontend. |
| 1075 |
* |
| 1076 |
* @access public |
| 1077 |
* @return void |
| 1078 |
* @since 1.0.0 |
| 1079 |
*/ |
| 1080 |
public function block_frontend_assets() { |
| 1081 |
|
| 1082 |
if( self::has_block( 'wpzoom-forms/datepicker-field' ) || self::has_elementor_widget() || self::has_cpt_form_shortcode() ) { |
| 1083 |
wp_enqueue_style( 'wpzoom-forms-css-frontend-flatpickr' ); |
| 1084 |
wp_enqueue_script( 'wpzoom-forms-js-frontend-flatpickr' ); |
| 1085 |
wp_enqueue_script( 'wpzoom-forms-js-frontend-datepicker' ); |
| 1086 |
} |
| 1087 |
|
| 1088 |
} |
| 1089 |
|
| 1090 |
// Check if a block exists in the post content |
| 1091 |
static function has_block( $block_name ) { |
| 1092 |
|
| 1093 |
if( ! has_block( 'wpzoom-forms/form-block' ) ) { |
| 1094 |
return false; |
| 1095 |
} |
| 1096 |
|
| 1097 |
global $post; |
| 1098 |
|
| 1099 |
$gutenberg_matches = array(); |
| 1100 |
$gutenberg_patern = '/<!--\s+wp:(wpzoom\-forms\/form\-block)(\s+(\{.*?\}))?\s+(\/)?-->/'; |
| 1101 |
preg_match_all( $gutenberg_patern, $post->post_content, $matches ); |
| 1102 |
|
| 1103 |
// Check if the block exists in the post content |
| 1104 |
if ( isset( $matches[3] ) ) { |
| 1105 |
foreach ( $matches[3] as $block_attributes_json ) { |
| 1106 |
if ( ! empty( $block_attributes_json ) ) { |
| 1107 |
$atts = json_decode( $block_attributes_json, true ); |
| 1108 |
} |
| 1109 |
} |
| 1110 |
} |
| 1111 |
|
| 1112 |
$form_ID = isset( $atts['formId'] ) ? $atts['formId'] : ''; |
| 1113 |
|
| 1114 |
if( $form_ID ) { |
| 1115 |
$form_post = get_post( $form_ID ); |
| 1116 |
if( has_block( $block_name, $form_post ) ) { |
| 1117 |
return true; |
| 1118 |
} |
| 1119 |
} |
| 1120 |
|
| 1121 |
return false; |
| 1122 |
|
| 1123 |
} |
| 1124 |
|
| 1125 |
// Check the form exists in the elementor posts content |
| 1126 |
public static function has_elementor_widget( $post_id = 0 ) { |
| 1127 |
|
| 1128 |
if ( ! defined( 'ELEMENTOR_VERSION' ) && ! is_callable( 'Elementor\Plugin::instance' ) ) { |
| 1129 |
return false; |
| 1130 |
} |
| 1131 |
|
| 1132 |
$post_id = $post_id > 0 ? $post_id : get_the_ID(); |
| 1133 |
|
| 1134 |
$elementor_data = get_post_meta( $post_id, '_elementor_data' ); |
| 1135 |
|
| 1136 |
if ( isset( $elementor_data[0] ) && is_string( $elementor_data[0] ) ) { |
| 1137 |
|
| 1138 |
$regExp = '/"widgetType":"([^"]*)/i'; |
| 1139 |
$outputArray = array(); |
| 1140 |
|
| 1141 |
// Define the pattern to match the shortcode |
| 1142 |
$scPattern = '/\[wpzf_form([^\]]*)\]/'; |
| 1143 |
preg_match_all( $scPattern, $elementor_data[0], $matches ); |
| 1144 |
|
| 1145 |
// Check if any matches are found |
| 1146 |
if ( ! empty( $matches[0] ) ) { |
| 1147 |
return true; |
| 1148 |
} |
| 1149 |
|
| 1150 |
if ( preg_match_all( $regExp, $elementor_data[0], $outputArray, PREG_SET_ORDER) ) {} |
| 1151 |
|
| 1152 |
foreach( $outputArray as $found ) { |
| 1153 |
if( in_array( 'wpzoom-forms-widget-cpt', $found ) ) { |
| 1154 |
return true; |
| 1155 |
} |
| 1156 |
} |
| 1157 |
|
| 1158 |
} |
| 1159 |
|
| 1160 |
return false; |
| 1161 |
} |
| 1162 |
|
| 1163 |
/** |
| 1164 |
* Check the post content has cpt form shortcode |
| 1165 |
* |
| 1166 |
* @since 1.2.0 |
| 1167 |
* @param int $post_id The post ID. |
| 1168 |
* @param boolean|int $content The post content. |
| 1169 |
* @return boolean Return true if post content has cpt form shortcode, else return false. |
| 1170 |
*/ |
| 1171 |
public static function has_cpt_form_shortcode( $post_id = 0, $content = '' ) { |
| 1172 |
|
| 1173 |
$post_id = $post_id > 0 ? $post_id : get_the_ID(); |
| 1174 |
|
| 1175 |
if ( empty( $content ) ) { |
| 1176 |
$content = get_post_field( 'post_content', $post_id ); |
| 1177 |
} |
| 1178 |
|
| 1179 |
if ( $content ) { |
| 1180 |
if ( has_shortcode( $content, 'wpzf_form' ) ) { |
| 1181 |
return true; |
| 1182 |
} |
| 1183 |
} |
| 1184 |
return false; |
| 1185 |
} |
| 1186 |
|
| 1187 |
/** |
| 1188 |
* Changes the row actions in post lists for certain post types. |
| 1189 |
* |
| 1190 |
* @access public |
| 1191 |
* @param array $actions An array of all the possible post row actions. |
| 1192 |
* @param WP_Post $post The post object for the post that is being displayed. |
| 1193 |
* @return array |
| 1194 |
* @since 1.0.0 |
| 1195 |
*/ |
| 1196 |
public function modify_row_actions( $actions, $post ) { |
| 1197 |
if ( 'wpzf-form' == $post->post_type || 'wpzf-submission' == $post->post_type ) { |
| 1198 |
if ( 'wpzf-submission' == $post->post_type && isset( $actions['edit'] ) ) { |
| 1199 |
$actions['edit'] = preg_replace( '/\<a([^>]+)\>(.+)\<\/a\>/i', '<a$1>' . __( 'View', 'wpzoom-forms' ) . '</a>', $actions['edit'] ); |
| 1200 |
} |
| 1201 |
|
| 1202 |
if ( isset( $actions['inline hide-if-no-js'] ) ) { |
| 1203 |
unset( $actions['inline hide-if-no-js'] ); |
| 1204 |
} |
| 1205 |
} |
| 1206 |
|
| 1207 |
return $actions; |
| 1208 |
} |
| 1209 |
|
| 1210 |
/** |
| 1211 |
* Removes the Inline Edit option from post types it doesn't make sense for. |
| 1212 |
* |
| 1213 |
* @access public |
| 1214 |
* @param array $actions An array of all the possible bulk actions. |
| 1215 |
* @return array |
| 1216 |
* @since 1.0.0 |
| 1217 |
*/ |
| 1218 |
public function remove_bulk_actions( $actions ) { |
| 1219 |
if ( isset( $actions['edit'] ) ) { |
| 1220 |
unset( $actions['edit'] ); |
| 1221 |
} |
| 1222 |
|
| 1223 |
return $actions; |
| 1224 |
} |
| 1225 |
|
| 1226 |
/** |
| 1227 |
* Changes the columns displayed in the post list for the form custom post type. |
| 1228 |
* |
| 1229 |
* @access public |
| 1230 |
* @param array $columns An array of all the columns. |
| 1231 |
* @return array |
| 1232 |
* @since 1.0.0 |
| 1233 |
*/ |
| 1234 |
public function post_list_columns_form( $columns ) { |
| 1235 |
return array( |
| 1236 |
'cb' => $columns['cb'], |
| 1237 |
'title' => __( 'Title', 'wpzoom-forms' ), |
| 1238 |
'responses' => __( 'Responses', 'wpzoom-forms' ), |
| 1239 |
'shortcode' => __( 'Shortcode', 'wpzoom-forms' ), |
| 1240 |
'date' => $columns['date'] |
| 1241 |
); |
| 1242 |
} |
| 1243 |
|
| 1244 |
/** |
| 1245 |
* Changes the columns displayed in the post list for the submissions custom post type. |
| 1246 |
* |
| 1247 |
* @access public |
| 1248 |
* @param array $columns An array of all the columns. |
| 1249 |
* @return array |
| 1250 |
* @since 1.0.0 |
| 1251 |
*/ |
| 1252 |
public function post_list_columns_submit( $columns ) { |
| 1253 |
return array( |
| 1254 |
'cb' => $columns['cb'], |
| 1255 |
'submission_id' => __( 'ID', 'wpzoom-forms' ), |
| 1256 |
'name' => __( 'Name', 'wpzoom-forms' ), |
| 1257 |
'email' => __( 'Email', 'wpzoom-forms' ), |
| 1258 |
'subject' => __( 'Subject', 'wpzoom-forms' ), |
| 1259 |
'form' => __( 'Form', 'wpzoom-forms' ), |
| 1260 |
'date' => $columns['date'] |
| 1261 |
); |
| 1262 |
} |
| 1263 |
|
| 1264 |
/** |
| 1265 |
* Changes the sortable columns displayed in the post list for the submissions custom post type. |
| 1266 |
* |
| 1267 |
* @access public |
| 1268 |
* @param array $columns An array of all the sortable columns. |
| 1269 |
* @return array |
| 1270 |
* @since 1.0.0 |
| 1271 |
*/ |
| 1272 |
public function post_list_sortable_columns_submit( $columns ) { |
| 1273 |
$columns['submission_id'] = 'ID'; |
| 1274 |
$columns['form'] = 'wpzf_form'; |
| 1275 |
|
| 1276 |
return $columns; |
| 1277 |
} |
| 1278 |
|
| 1279 |
// Add the filter dropdown to the posts list |
| 1280 |
public function custom_filter_by_form() { |
| 1281 |
global $wpdb; |
| 1282 |
|
| 1283 |
// Check if we are on the posts list page |
| 1284 |
if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wpzf-submission' ) { |
| 1285 |
|
| 1286 |
$form_id_filter_selected = isset( $_GET['form_id_filter'] ) ? $_GET['form_id_filter'] : ''; |
| 1287 |
|
| 1288 |
// Fetch unique form IDs and their corresponding titles from your database |
| 1289 |
$form_ids_query = $wpdb->get_results("SELECT ID AS form_id, post_title |
| 1290 |
FROM $wpdb->posts |
| 1291 |
WHERE post_type = 'wpzf-form' |
| 1292 |
AND post_status = 'publish'"); |
| 1293 |
|
| 1294 |
|
| 1295 |
// If we have forms, display the dropdown |
| 1296 |
if ( ! empty( $form_ids_query ) ) { |
| 1297 |
// Initialize an array to store unique form IDs |
| 1298 |
$form_ids = array(); |
| 1299 |
?> |
| 1300 |
<select name="form_id_filter" id="form_id_filter"> |
| 1301 |
<option value=""><?php echo esc_html__( 'All Forms', 'wpzoom-forms' ); ?></option> |
| 1302 |
<?php |
| 1303 |
foreach ( $form_ids_query as $result ) { |
| 1304 |
|
| 1305 |
// Check if the form ID already exists in the array |
| 1306 |
if ( ! in_array( $result->form_id, $form_ids ) ) { |
| 1307 |
|
| 1308 |
// Add form ID to the array to prevent duplication |
| 1309 |
$form_ids[] = $result->form_id; |
| 1310 |
|
| 1311 |
// Output the option with form ID as value and post title as option name |
| 1312 |
echo '<option '. selected( $result->form_id, $form_id_filter_selected, true ) .' value="' . $result->form_id . '">' . $result->post_title . '</option>'; |
| 1313 |
} |
| 1314 |
} |
| 1315 |
?> |
| 1316 |
</select> |
| 1317 |
<?php |
| 1318 |
} |
| 1319 |
|
| 1320 |
|
| 1321 |
} |
| 1322 |
} |
| 1323 |
|
| 1324 |
// Modify the query based on the selected form ID |
| 1325 |
public function filter_posts_by_form ( $query ) { |
| 1326 |
|
| 1327 |
global $pagenow; |
| 1328 |
|
| 1329 |
// Check if we are on the posts list page and a form ID filter is set |
| 1330 |
if ( is_admin() && $pagenow == 'edit.php' && isset( $_GET['form_id_filter'] ) && $_GET['form_id_filter'] != '' ) { |
| 1331 |
|
| 1332 |
$query->query_vars['meta_key'] = '_wpzf_form_id'; |
| 1333 |
$query->query_vars['meta_value'] = $_GET['form_id_filter']; |
| 1334 |
|
| 1335 |
} |
| 1336 |
} |
| 1337 |
|
| 1338 |
/** |
| 1339 |
* Changes the column content displayed in the post list for the form custom post type. |
| 1340 |
* |
| 1341 |
* @access public |
| 1342 |
* @param string $column The name of the column to display. |
| 1343 |
* @param int $post_id The ID of the current post. |
| 1344 |
* @return array |
| 1345 |
* @since 1.0.0 |
| 1346 |
*/ |
| 1347 |
public function post_list_custom_columns_form( $column, $post_id ) { |
| 1348 |
|
| 1349 |
if ( 'shortcode' == $column ) { |
| 1350 |
printf( '<input type="text" value="[wpzf_form id="%d"]" readonly />', absint( $post_id ) ); |
| 1351 |
} |
| 1352 |
|
| 1353 |
if( 'responses' == $column ) { |
| 1354 |
|
| 1355 |
$args = array( |
| 1356 |
'post_type' => 'wpzf-submission', |
| 1357 |
'post_status' => 'publish', |
| 1358 |
'posts_per_page' => -1, |
| 1359 |
'meta_query' => array( |
| 1360 |
array( |
| 1361 |
'key' => '_wpzf_form_id', |
| 1362 |
'value' => $post_id, |
| 1363 |
'compare' => '=' |
| 1364 |
) |
| 1365 |
) |
| 1366 |
); |
| 1367 |
|
| 1368 |
$forms_count = 0; |
| 1369 |
|
| 1370 |
$responses = new WP_Query( $args ); |
| 1371 |
|
| 1372 |
if( $responses && $responses->have_posts() ) { |
| 1373 |
$forms_count = $responses->post_count; |
| 1374 |
} |
| 1375 |
|
| 1376 |
if( 0 < $forms_count ) { |
| 1377 |
printf( '<a href="%s">%s</a>', admin_url( 'edit.php?post_type=wpzf-submission&&form_id_filter=' . $post_id ), $forms_count ); |
| 1378 |
} else { |
| 1379 |
echo $forms_count; |
| 1380 |
} |
| 1381 |
|
| 1382 |
} |
| 1383 |
} |
| 1384 |
|
| 1385 |
/** |
| 1386 |
* Changes the column content displayed in the post list for the submissions custom post type. |
| 1387 |
* |
| 1388 |
* @access public |
| 1389 |
* @param string $column The name of the column to display. |
| 1390 |
* @param int $post_id The ID of the current post. |
| 1391 |
* @return array |
| 1392 |
* @since 1.0.0 |
| 1393 |
*/ |
| 1394 |
public function post_list_custom_columns_submit( $column, $post_id ) { |
| 1395 |
$fields = get_post_meta( $post_id, '_wpzf_fields', true ); |
| 1396 |
|
| 1397 |
switch ( $column ) { |
| 1398 |
case 'submission_id': |
| 1399 |
printf( |
| 1400 |
'<strong><a href="%s" class="row-title">%s #%s</a></strong>', |
| 1401 |
esc_url( get_edit_post_link( $post_id ) ), |
| 1402 |
esc_html__( 'Submission', 'wpzoom-forms' ), |
| 1403 |
esc_html( $post_id ) |
| 1404 |
); |
| 1405 |
break; |
| 1406 |
|
| 1407 |
case 'name': |
| 1408 |
$name_found = false; |
| 1409 |
|
| 1410 |
if ( ! empty( $fields ) && is_array( $fields ) ) { |
| 1411 |
// Common name field patterns |
| 1412 |
$name_patterns = array( 'name', 'full_name', 'first_name', 'last_name', 'fullname', 'your_name' ); |
| 1413 |
|
| 1414 |
foreach ( $fields as $name => $value ) { |
| 1415 |
$field_name = strtolower( $name ); |
| 1416 |
foreach ( $name_patterns as $pattern ) { |
| 1417 |
if ( strpos( $field_name, $pattern ) !== false && ! empty( $value ) ) { |
| 1418 |
echo '<strong>' . esc_html( $value ) . '</strong>'; |
| 1419 |
$name_found = true; |
| 1420 |
break 2; |
| 1421 |
} |
| 1422 |
} |
| 1423 |
} |
| 1424 |
} |
| 1425 |
|
| 1426 |
if ( ! $name_found ) { |
| 1427 |
echo '—'; |
| 1428 |
} |
| 1429 |
break; |
| 1430 |
|
| 1431 |
case 'email': |
| 1432 |
$email_found = false; |
| 1433 |
|
| 1434 |
if ( ! empty( $fields ) && is_array( $fields ) ) { |
| 1435 |
// Common email field patterns |
| 1436 |
$email_patterns = array( 'email', 'e-mail', 'mail', 'email_address', 'your_email' ); |
| 1437 |
|
| 1438 |
foreach ( $fields as $name => $value ) { |
| 1439 |
$field_name = strtolower( $name ); |
| 1440 |
foreach ( $email_patterns as $pattern ) { |
| 1441 |
if ( strpos( $field_name, $pattern ) !== false && ! empty( $value ) ) { |
| 1442 |
echo '<a href="mailto:' . esc_attr( $value ) . '">' . esc_html( $value ) . '</a>'; |
| 1443 |
$email_found = true; |
| 1444 |
break 2; |
| 1445 |
} |
| 1446 |
} |
| 1447 |
} |
| 1448 |
} |
| 1449 |
|
| 1450 |
if ( ! $email_found ) { |
| 1451 |
echo '—'; |
| 1452 |
} |
| 1453 |
break; |
| 1454 |
|
| 1455 |
case 'subject': |
| 1456 |
$subject_found = false; |
| 1457 |
|
| 1458 |
if ( ! empty( $fields ) && is_array( $fields ) ) { |
| 1459 |
// First try to find a subject field |
| 1460 |
foreach ( $fields as $name => $value ) { |
| 1461 |
if ( stripos( $name, 'subject' ) !== false || stripos( $name, 'title' ) !== false || stripos( $name, 'topic' ) !== false ) { |
| 1462 |
echo esc_html( $value ); |
| 1463 |
$subject_found = true; |
| 1464 |
break; |
| 1465 |
} |
| 1466 |
} |
| 1467 |
|
| 1468 |
// If no subject field found, show first non-empty field (likely message) |
| 1469 |
if ( ! $subject_found ) { |
| 1470 |
foreach ( $fields as $name => $value ) { |
| 1471 |
// Skip name and email fields |
| 1472 |
$field_name = strtolower( $name ); |
| 1473 |
if ( strpos( $field_name, 'name' ) !== false || strpos( $field_name, 'email' ) !== false ) { |
| 1474 |
continue; |
| 1475 |
} |
| 1476 |
if ( ! empty( $value ) ) { |
| 1477 |
echo esc_html( wp_trim_words( $value, 10, '...' ) ); |
| 1478 |
$subject_found = true; |
| 1479 |
break; |
| 1480 |
} |
| 1481 |
} |
| 1482 |
} |
| 1483 |
} |
| 1484 |
|
| 1485 |
if ( ! $subject_found ) { |
| 1486 |
echo '—'; |
| 1487 |
} |
| 1488 |
break; |
| 1489 |
|
| 1490 |
case 'form': |
| 1491 |
$form_id = intval( get_post_meta( $post_id, '_wpzf_form_id', true ) ); |
| 1492 |
$form_name = __( '[Unknown]', 'wpzoom-forms' ); |
| 1493 |
|
| 1494 |
if ( $form_id > 0 ) { |
| 1495 |
$form_post = get_post( $form_id ); |
| 1496 |
|
| 1497 |
if ( ! is_null( $form_post ) && 'wpzf-form' === $form_post->post_type ) { |
| 1498 |
$form_title = get_the_title( $form_id ); |
| 1499 |
|
| 1500 |
if ( ! empty( $form_title ) && 'trash' !== $form_post->post_status ) { |
| 1501 |
$form_name = '<a href="' . esc_url( get_edit_post_link( $form_id ) ) . '">' . esc_html( $form_title ) . '</a>'; |
| 1502 |
} elseif ( 'trash' === $form_post->post_status ) { |
| 1503 |
$form_name = sprintf( |
| 1504 |
'<span style="color: #d63638;">%s</span> <small>(%s)</small>', |
| 1505 |
esc_html( $form_title ?: __( 'Untitled Form', 'wpzoom-forms' ) ), |
| 1506 |
esc_html__( 'Trashed', 'wpzoom-forms' ) |
| 1507 |
); |
| 1508 |
} |
| 1509 |
} |
| 1510 |
} |
| 1511 |
|
| 1512 |
echo wp_kses( $form_name, array( 'a' => array( 'href' => array() ), 'span' => array( 'style' => array() ), 'small' => array() ) ); |
| 1513 |
break; |
| 1514 |
} |
| 1515 |
} |
| 1516 |
|
| 1517 |
/** |
| 1518 |
* Sets what the primary column is in the post list for certain post types. |
| 1519 |
* |
| 1520 |
* @access public |
| 1521 |
* @param string $default The default/primary column. |
| 1522 |
* @param string $screen Which screen is currently being rendered. |
| 1523 |
* @return array |
| 1524 |
* @since 1.0.0 |
| 1525 |
*/ |
| 1526 |
public function post_list_primary_column( $default, $screen ) { |
| 1527 |
if ( 'edit-wpzf-submission' == $screen ) { |
| 1528 |
$default = 'submission_id'; |
| 1529 |
} |
| 1530 |
|
| 1531 |
return $default; |
| 1532 |
} |
| 1533 |
|
| 1534 |
/** |
| 1535 |
* Handles sorting of custom columns in the post list for certain post types. |
| 1536 |
* |
| 1537 |
* @access public |
| 1538 |
* @param WP_Query $query The current query. |
| 1539 |
* @return array |
| 1540 |
* @since 1.0.0 |
| 1541 |
*/ |
| 1542 |
public function sort_custom_column( $query ) { |
| 1543 |
$orderby = $query->get( 'orderby' ); |
| 1544 |
|
| 1545 |
if ( 'wpzf_desc' == $orderby || 'wpzf_form' == $orderby ) { |
| 1546 |
$key = 'wpzf_desc' == $orderby ? '_wpzf_fields' : '_wpzf_form_id'; |
| 1547 |
|
| 1548 |
$query->set( 'meta_query', array( |
| 1549 |
'relation' => 'OR', |
| 1550 |
array( |
| 1551 |
'key' => $key, |
| 1552 |
'compare' => 'NOT EXISTS' |
| 1553 |
), |
| 1554 |
array( |
| 1555 |
'key' => $key |
| 1556 |
) |
| 1557 |
) ); |
| 1558 |
|
| 1559 |
$query->set( 'orderby', 'meta_value' ); |
| 1560 |
} |
| 1561 |
} |
| 1562 |
|
| 1563 |
/** |
| 1564 |
* Changes things on the edit screen of certain post types. |
| 1565 |
* |
| 1566 |
* @access public |
| 1567 |
* @return void |
| 1568 |
* @since 1.0.0 |
| 1569 |
*/ |
| 1570 |
public function remove_meta_boxes() { |
| 1571 |
global $current_screen; |
| 1572 |
|
| 1573 |
if ( 'wpzf-submission' == $current_screen->post_type && 'wpzf-submission' == $current_screen->id ) { |
| 1574 |
global $wp_meta_boxes; |
| 1575 |
|
| 1576 |
$wp_meta_boxes = array( |
| 1577 |
'wpzf-submission' => array( |
| 1578 |
'advanced' => array(), |
| 1579 |
'side' => array( |
| 1580 |
'high' => array( |
| 1581 |
'wpzf-submission-details-mb' => $wp_meta_boxes['wpzf-submission']['side']['high']['wpzf-submission-details-mb'] |
| 1582 |
) |
| 1583 |
), |
| 1584 |
'normal' => array( |
| 1585 |
'high' => array( |
| 1586 |
'wpzf-submission-mb' => $wp_meta_boxes['wpzf-submission']['normal']['high']['wpzf-submission-mb'] |
| 1587 |
) |
| 1588 |
) |
| 1589 |
) |
| 1590 |
); |
| 1591 |
|
| 1592 |
add_screen_option( 'layout_columns', array( 'max' => 2, 'default' => 2 ) ); |
| 1593 |
} |
| 1594 |
} |
| 1595 |
|
| 1596 |
/** |
| 1597 |
* Removes screen options where not needed. |
| 1598 |
* |
| 1599 |
* @access public |
| 1600 |
* @param bool $show_screen Whether to show Screen Options tab. |
| 1601 |
* @param WP_Screen $screen Current WP_Screen instance. |
| 1602 |
* @return bool |
| 1603 |
* @since 1.0.0 |
| 1604 |
*/ |
| 1605 |
public function remove_screen_options( $show_screen, $screen ) { |
| 1606 |
return 'wpzf-submission' == $screen->post_type && 'post' == $screen->base ? false : $show_screen; |
| 1607 |
} |
| 1608 |
|
| 1609 |
/** |
| 1610 |
* Changes the views items for certain post types. |
| 1611 |
* |
| 1612 |
* @access public |
| 1613 |
* @param array $views All the possible views. |
| 1614 |
* @return bool |
| 1615 |
* @since 1.0.0 |
| 1616 |
*/ |
| 1617 |
public function post_list_views( $views ) { |
| 1618 |
if ( isset( $views['publish'] ) ) { |
| 1619 |
unset( $views['publish'] ); |
| 1620 |
} |
| 1621 |
|
| 1622 |
$current_page = get_current_screen()->id; |
| 1623 |
|
| 1624 |
?> |
| 1625 |
<div class="wpzf_wrap wpzf_settings-add-new"> |
| 1626 |
<?php |
| 1627 |
if ( 'edit-wpzf-form' == $current_page ) { |
| 1628 |
echo '<a href="' . esc_url( admin_url( 'post-new.php?post_type=wpzf-form' ) ) . '" class="button-primary">' . __( 'Add new form', 'wpzoom-forms' ) . '</a>'; |
| 1629 |
} |
| 1630 |
?> |
| 1631 |
</div> |
| 1632 |
<?php |
| 1633 |
|
| 1634 |
return $views; |
| 1635 |
} |
| 1636 |
|
| 1637 |
/** |
| 1638 |
* Adds custom meta boxes to certain post types. |
| 1639 |
* |
| 1640 |
* @access public |
| 1641 |
* @return void |
| 1642 |
* @since 1.0.0 |
| 1643 |
*/ |
| 1644 |
public function add_meta_boxes() { |
| 1645 |
add_meta_box( |
| 1646 |
'wpzf-submission-details-mb', |
| 1647 |
__( 'Submission Details', 'wpzoom-forms' ), |
| 1648 |
array( $this, 'submission_meta_box_details' ), |
| 1649 |
'wpzf-submission', |
| 1650 |
'side', |
| 1651 |
'high' |
| 1652 |
); |
| 1653 |
|
| 1654 |
add_meta_box( |
| 1655 |
'wpzf-submission-mb', |
| 1656 |
__( 'Submission', 'wpzoom-forms' ), |
| 1657 |
array( $this, 'submission_meta_box' ), |
| 1658 |
'wpzf-submission', |
| 1659 |
'normal', |
| 1660 |
'high' |
| 1661 |
); |
| 1662 |
} |
| 1663 |
|
| 1664 |
/** |
| 1665 |
* Outputs the content for the submission details sidebar meta box. |
| 1666 |
* |
| 1667 |
* @access public |
| 1668 |
* @return void |
| 1669 |
* @since 1.3.5 |
| 1670 |
*/ |
| 1671 |
public function submission_meta_box_details() { |
| 1672 |
$post_id = get_the_ID(); |
| 1673 |
$post = get_post( $post_id ); |
| 1674 |
|
| 1675 |
// Get form info |
| 1676 |
$form_id = get_post_meta( $post_id, '_wpzf_form_id', true ); |
| 1677 |
$form_name = __( '[Unknown]', 'wpzoom-forms' ); |
| 1678 |
$show_form_link = false; |
| 1679 |
|
| 1680 |
if ( $form_id > 0 ) { |
| 1681 |
$form_post = get_post( $form_id ); |
| 1682 |
|
| 1683 |
if ( ! is_null( $form_post ) && 'wpzf-form' === $form_post->post_type ) { |
| 1684 |
$form_title = get_the_title( $form_id ); |
| 1685 |
|
| 1686 |
if ( ! empty( $form_title ) && 'trash' !== $form_post->post_status ) { |
| 1687 |
$form_name = $form_title; |
| 1688 |
$show_form_link = true; |
| 1689 |
} elseif ( 'trash' === $form_post->post_status ) { |
| 1690 |
$form_name = sprintf( |
| 1691 |
'<span style="color: #d63638;">%s</span> <small>(%s)</small>', |
| 1692 |
$form_title ?: __( 'Untitled Form', 'wpzoom-forms' ), |
| 1693 |
__( 'Trashed', 'wpzoom-forms' ) |
| 1694 |
); |
| 1695 |
} |
| 1696 |
} |
| 1697 |
} |
| 1698 |
|
| 1699 |
// Get submission date |
| 1700 |
$date = sprintf( |
| 1701 |
__( 'Submitted on %1$s at %2$s', 'wpzoom-forms' ), |
| 1702 |
get_the_date(), |
| 1703 |
get_the_time() |
| 1704 |
); |
| 1705 |
|
| 1706 |
// Get trash/delete link |
| 1707 |
$delete_link = ''; |
| 1708 |
$action_text = ''; |
| 1709 |
if ( current_user_can( 'delete_post', $post_id ) ) { |
| 1710 |
if ( 'trash' === $post->post_status ) { |
| 1711 |
$delete_link = get_delete_post_link( $post_id, '', true ); |
| 1712 |
$action_text = __( 'Delete Permanently', 'wpzoom-forms' ); |
| 1713 |
} else { |
| 1714 |
$delete_link = get_delete_post_link( $post_id ); |
| 1715 |
$action_text = _x( 'Move to Trash', 'verb', 'wpzoom-forms' ); |
| 1716 |
} |
| 1717 |
} |
| 1718 |
|
| 1719 |
// Output the details |
| 1720 |
?> |
| 1721 |
<style> |
| 1722 |
#wpzf-submission-details-mb { |
| 1723 |
display: block !important; |
| 1724 |
} |
| 1725 |
#wpzf-submission-details-mb .inside { |
| 1726 |
margin: 0; |
| 1727 |
padding: 0; |
| 1728 |
} |
| 1729 |
.wpzf-submission-details { |
| 1730 |
margin: 0; |
| 1731 |
padding: 0; |
| 1732 |
list-style: none; |
| 1733 |
display: block !important; |
| 1734 |
} |
| 1735 |
.wpzf-submission-details li { |
| 1736 |
margin: 0; |
| 1737 |
padding: 8px 12px; |
| 1738 |
border-bottom: 1px solid #eee; |
| 1739 |
display: block; |
| 1740 |
line-height: 1.5; |
| 1741 |
} |
| 1742 |
.wpzf-submission-details li:last-child { |
| 1743 |
border-bottom: none; |
| 1744 |
} |
| 1745 |
.wpzf-submission-details li strong { |
| 1746 |
display: block; |
| 1747 |
margin-bottom: 4px; |
| 1748 |
color: #1d2327; |
| 1749 |
} |
| 1750 |
.wpzf-submission-details .wpzf-submission-actions { |
| 1751 |
padding: 12px; |
| 1752 |
} |
| 1753 |
.wpzf-submission-details .submitdelete { |
| 1754 |
color: #b32d2e; |
| 1755 |
text-decoration: none; |
| 1756 |
} |
| 1757 |
.wpzf-submission-details .submitdelete:hover { |
| 1758 |
color: #a00; |
| 1759 |
} |
| 1760 |
</style> |
| 1761 |
<ul class="wpzf-submission-details"> |
| 1762 |
<li> |
| 1763 |
<strong><?php esc_html_e( 'Submission ID:', 'wpzoom-forms' ); ?></strong> |
| 1764 |
#<?php echo esc_html( $post_id ); ?> |
| 1765 |
</li> |
| 1766 |
<li> |
| 1767 |
<strong><?php esc_html_e( 'Form:', 'wpzoom-forms' ); ?></strong> |
| 1768 |
<?php if ( $show_form_link ) : ?> |
| 1769 |
<a href="<?php echo esc_url( get_edit_post_link( $form_id ) ); ?>"><?php echo esc_html( $form_name ); ?></a> |
| 1770 |
<?php else : ?> |
| 1771 |
<?php echo wp_kses_post( $form_name ); ?> |
| 1772 |
<?php endif; ?> |
| 1773 |
</li> |
| 1774 |
<li> |
| 1775 |
<strong><?php esc_html_e( 'Date:', 'wpzoom-forms' ); ?></strong> |
| 1776 |
<?php echo esc_html( $date ); ?> |
| 1777 |
</li> |
| 1778 |
<?php if ( ! empty( $delete_link ) ) : ?> |
| 1779 |
<li class="wpzf-submission-actions"> |
| 1780 |
<a href="<?php echo esc_url( $delete_link ); ?>" class="submitdelete deletion"> |
| 1781 |
<?php echo esc_html( $action_text ); ?> |
| 1782 |
</a> |
| 1783 |
</li> |
| 1784 |
<?php endif; ?> |
| 1785 |
</ul> |
| 1786 |
<?php |
| 1787 |
} |
| 1788 |
|
| 1789 |
/** |
| 1790 |
* Outputs the content for the submission meta box. |
| 1791 |
* |
| 1792 |
* @access public |
| 1793 |
* @return void |
| 1794 |
* @since 1.0.0 |
| 1795 |
*/ |
| 1796 |
public function submission_meta_box() { |
| 1797 |
$fields = get_post_meta( get_the_ID(), '_wpzf_fields', true ); |
| 1798 |
|
| 1799 |
if ( ! is_null( $fields ) && false !== $fields && is_array( $fields ) && ! empty( $fields ) ) { |
| 1800 |
echo '<ul class="wpzf-submission-view">'; |
| 1801 |
|
| 1802 |
$form_id = intval( get_post_meta( get_the_ID(), '_wpzf_form_id', true ) ); |
| 1803 |
$form_name = __( '[Unknown]', 'wpzoom-forms' ); |
| 1804 |
|
| 1805 |
if ( $form_id > 0 ) { |
| 1806 |
$form_name = $form_id; |
| 1807 |
|
| 1808 |
if ( ! is_null( get_post( $form_id ) ) ) { |
| 1809 |
$form_name = '<a href="' . esc_url( get_edit_post_link( $form_id ) ) . '">' . get_the_title( $form_id ) . '</a>'; |
| 1810 |
} |
| 1811 |
} |
| 1812 |
|
| 1813 |
$form_name = wp_kses( $form_name, array( 'a' => array( 'href' => array() ) ) ); |
| 1814 |
|
| 1815 |
echo '<li class="top"><h3>' . sprintf( __( 'Form: %s', 'wpzoom-forms' ), $form_name ) . '</h3></li>'; |
| 1816 |
|
| 1817 |
foreach ( $fields as $name => $value ) { |
| 1818 |
echo '<li><h3>' . esc_html( $name ) . '</h3><div>' . make_clickable( nl2br( esc_html( $value ) ) ) . '</div></li>'; |
| 1819 |
} |
| 1820 |
|
| 1821 |
echo '</ul>'; |
| 1822 |
|
| 1823 |
return; |
| 1824 |
} |
| 1825 |
|
| 1826 |
printf( '<p class="empty">%s</p>', __( 'Submission is empty…', 'wpzoom-forms' ) ); |
| 1827 |
} |
| 1828 |
|
| 1829 |
/** |
| 1830 |
* Returns whether the current page is related to the given post type. |
| 1831 |
* |
| 1832 |
* @access public |
| 1833 |
* @param string $type The type to check for. |
| 1834 |
* @return bool |
| 1835 |
* @since 1.0.0 |
| 1836 |
*/ |
| 1837 |
public function is_post_type( $type ) { |
| 1838 |
$typenow = ''; |
| 1839 |
|
| 1840 |
if ( is_admin() && current_user_can( 'edit_posts' ) ) { |
| 1841 |
if ( isset( $_REQUEST['post_type'] ) && post_type_exists( sanitize_key( $_REQUEST['post_type'] ) ) ) { |
| 1842 |
$typenow = sanitize_key( $_REQUEST['post_type'] ); |
| 1843 |
} else { |
| 1844 |
$post_id = -1; |
| 1845 |
|
| 1846 |
if ( isset( $_GET['post'] ) && isset( $_POST['post_ID'] ) && (int) $_GET['post'] !== (int) $_POST['post_ID'] ) { |
| 1847 |
// Do nothing |
| 1848 |
} elseif ( isset( $_GET['post'] ) ) { |
| 1849 |
$post_id = (int) $_GET['post']; |
| 1850 |
} elseif ( isset( $_POST['post_ID'] ) ) { |
| 1851 |
$post_id = (int) $_POST['post_ID']; |
| 1852 |
} |
| 1853 |
|
| 1854 |
if ( $post_id > -1 ) { |
| 1855 |
$post = get_post( $post_id ); |
| 1856 |
|
| 1857 |
if ( ! is_null( $post ) && $post instanceof WP_Post ) { |
| 1858 |
$typenow = $post->post_type; |
| 1859 |
} |
| 1860 |
} |
| 1861 |
} |
| 1862 |
} |
| 1863 |
|
| 1864 |
return $type == $typenow; |
| 1865 |
} |
| 1866 |
|
| 1867 |
/** |
| 1868 |
* Called to render the form block on the frontend. |
| 1869 |
* |
| 1870 |
* @access public |
| 1871 |
* @param array $attributes An array containing the attributes for the block. |
| 1872 |
* @param string $content A string containing the content of the block. |
| 1873 |
* @param WP_Block $block The WP_Block representation of the block. |
| 1874 |
* @return string |
| 1875 |
* @since 1.0.0 |
| 1876 |
*/ |
| 1877 |
public function form_block_render( $attributes, $content = '', $block = null ) { |
| 1878 |
global $current_screen; |
| 1879 |
|
| 1880 |
$current_screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; |
| 1881 |
|
| 1882 |
// Allow rendering during REST API requests (ServerSideRender / block preview) |
| 1883 |
// and during Elementor's AJAX-driven widget preview in the editor. |
| 1884 |
$is_rest = defined( 'REST_REQUEST' ) && REST_REQUEST; |
| 1885 |
$is_elementor_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_REQUEST['action'] ) && strpos( sanitize_key( wp_unslash( $_REQUEST['action'] ) ), 'elementor' ) === 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 1886 |
if ( ( is_admin() && ! $is_rest && ! $is_elementor_ajax ) || ( ! is_null( $current_screen ) && $current_screen->is_block_editor() ) ) return ''; |
| 1887 |
|
| 1888 |
// Get form ID and validate form exists and is published |
| 1889 |
$form_id = isset( $attributes['formId'] ) ? intval( $attributes['formId'] ) : 0; |
| 1890 |
$form_post = get_post( $form_id ); |
| 1891 |
|
| 1892 |
// Check if form exists and is published |
| 1893 |
if ( ! $form_post || 'wpzf-form' !== $form_post->post_type || 'publish' !== $form_post->post_status ) { |
| 1894 |
// Show message only to administrators |
| 1895 |
if ( current_user_can( 'manage_options' ) ) { |
| 1896 |
$message = ''; |
| 1897 |
if ( ! $form_post ) { |
| 1898 |
$message = sprintf( |
| 1899 |
__( 'Contact form not found (ID: %d). Please select a different form or create a new one.', 'wpzoom-forms' ), |
| 1900 |
$form_id |
| 1901 |
); |
| 1902 |
} elseif ( 'wpzf-form' !== $form_post->post_type ) { |
| 1903 |
$message = sprintf( |
| 1904 |
__( 'Invalid form type (ID: %d). Please select a valid WPZOOM form.', 'wpzoom-forms' ), |
| 1905 |
$form_id |
| 1906 |
); |
| 1907 |
} elseif ( 'trash' === $form_post->post_status ) { |
| 1908 |
$message = sprintf( |
| 1909 |
__( 'Contact form "%s" is in trash (ID: %d). Please restore it or select a different form.', 'wpzoom-forms' ), |
| 1910 |
$form_post->post_title, |
| 1911 |
$form_id |
| 1912 |
); |
| 1913 |
} else { |
| 1914 |
$message = sprintf( |
| 1915 |
__( 'Contact form "%s" is not published (ID: %d). Please publish it or select a different form.', 'wpzoom-forms' ), |
| 1916 |
$form_post->post_title, |
| 1917 |
$form_id |
| 1918 |
); |
| 1919 |
} |
| 1920 |
|
| 1921 |
return sprintf( |
| 1922 |
'<div class="wpzoom-forms-admin-notice" style="background: #fff; border: 1px solid #c3c4c7; border-left: 4px solid #d63638; box-shadow: 0 1px 1px rgba(0,0,0,0.04); padding: 1em 12px; margin: 1em 0;"> |
| 1923 |
<p style="margin: 0; font-size: 14px; color: #d63638;"> |
| 1924 |
<strong>%s:</strong> %s |
| 1925 |
</p> |
| 1926 |
<p style="margin: 8px 0 0 0; font-size: 13px; color: #646970;"> |
| 1927 |
<a href="%s" target="_blank">%s</a> |
| 1928 |
</p> |
| 1929 |
</div>', |
| 1930 |
esc_html__( 'WPZOOM Forms Admin Notice', 'wpzoom-forms' ), |
| 1931 |
esc_html( $message ), |
| 1932 |
esc_url( admin_url( 'edit.php?post_type=wpzf-form' ) ), |
| 1933 |
esc_html__( 'Manage Forms', 'wpzoom-forms' ) |
| 1934 |
); |
| 1935 |
} |
| 1936 |
|
| 1937 |
// Don't show anything to non-administrators |
| 1938 |
return ''; |
| 1939 |
} |
| 1940 |
|
| 1941 |
$align = isset( $attributes['align'] ) && ! empty( $attributes['align'] ) ? $attributes['align'] : 'none'; |
| 1942 |
|
| 1943 |
//Get styles from the block |
| 1944 |
|
| 1945 |
$fieldBgColor = isset( $attributes['fieldBgColor'] ) ? $attributes['fieldBgColor'] : ''; |
| 1946 |
$fieldBrdStyle = isset( $attributes['fieldBrdStyle'] ) ? $attributes['fieldBrdStyle'] : ''; |
| 1947 |
$fieldBrdWidth = isset( $attributes['fieldBrdWidth'] ) ? $attributes['fieldBrdWidth'] . 'px' : ''; |
| 1948 |
$fieldBrdRadius = isset( $attributes['fieldBrdRadius'] ) ? $attributes['fieldBrdRadius'] . 'px' : ''; |
| 1949 |
$fieldBrdColor = isset( $attributes['fieldBrdColor'] ) ? $attributes['fieldBrdColor'] : ''; |
| 1950 |
$fieldTextColor = isset( $attributes['fieldTextColor'] ) ? $attributes['fieldTextColor'] : ''; |
| 1951 |
$labelTextColor = isset( $attributes['labelTextColor'] ) ? $attributes['labelTextColor'] : ''; |
| 1952 |
$btnBrdRadius = isset( $attributes['btnBrdRadius'] ) ? $attributes['btnBrdRadius'] . 'px' : ''; |
| 1953 |
$btnBrdStyle = isset( $attributes['btnBrdStyle'] ) ? $attributes['btnBrdStyle'] : ''; |
| 1954 |
$btnTextColor = isset( $attributes['btnTextColor'] ) ? $attributes['btnTextColor'] : ''; |
| 1955 |
$btnBrdWidth = isset( $attributes['btnBrdWidth'] ) ? $attributes['btnBrdWidth']. 'px' : ''; |
| 1956 |
$btnBrdColor = isset( $attributes['btnBrdColor'] ) ? $attributes['btnBrdColor'] : ''; |
| 1957 |
$btnBgColor = isset( $attributes['btnBgColor'] ) ? $attributes['btnBgColor'] : ''; |
| 1958 |
|
| 1959 |
$form_ID = 'wpzf-' . intval( $attributes['formId'] ); |
| 1960 |
$form_notice_id = $form_ID . '-notice'; |
| 1961 |
$form_success_message = get_post_meta( intval( $attributes['formId'] ), '_form_success_message', true ); |
| 1962 |
$form_failure_message = get_post_meta( intval( $attributes['formId'] ), '_form_failure_message', true ); |
| 1963 |
|
| 1964 |
// Use default messages if custom ones are not set |
| 1965 |
if ( empty( $form_success_message ) ) { |
| 1966 |
$form_success_message = __( 'Thanks! We\'ve received your submission!', 'wpzoom-forms' ); |
| 1967 |
} |
| 1968 |
if ( empty( $form_failure_message ) ) { |
| 1969 |
$form_failure_message = __( 'Submission failed!', 'wpzoom-forms' ); |
| 1970 |
} |
| 1971 |
|
| 1972 |
// Enqueue core block library styles for inner blocks (columns, group, spacer, etc.) |
| 1973 |
wp_enqueue_style( 'wp-block-library' ); |
| 1974 |
|
| 1975 |
// Process form content through do_blocks() to render inner blocks and enqueue their styles |
| 1976 |
$form_content = get_post_field( 'post_content', intval( $attributes['formId'] ), 'raw' ); |
| 1977 |
$form_content = do_blocks( $form_content ); |
| 1978 |
$form_content = preg_replace( |
| 1979 |
array( '/<!--(.*)-->/Uis', '/<(input|textarea|select)(.*)name="([^"]+)"/Uis' ), |
| 1980 |
array( '', '<$1$2name="wpzf_$3"' ), |
| 1981 |
$form_content |
| 1982 |
); |
| 1983 |
|
| 1984 |
// If this (legacy) form actually contains a date field, make sure the |
| 1985 |
// datepicker assets load. We enqueue here — at render time — rather than |
| 1986 |
// relying solely on the page-scan in block_frontend_assets(), which only |
| 1987 |
// inspects a single form-block per page and misses multi-form pages, |
| 1988 |
// shortcode and Elementor embeds. The scripts are registered in_footer so |
| 1989 |
// this late enqueue still prints correctly. |
| 1990 |
if ( false !== strpos( $form_content, 'data-datepicker' ) ) { |
| 1991 |
wp_enqueue_style( 'wpzoom-forms-css-frontend-flatpickr' ); |
| 1992 |
wp_enqueue_script( 'wpzoom-forms-js-frontend-flatpickr' ); |
| 1993 |
wp_enqueue_script( 'wpzoom-forms-js-frontend-datepicker' ); |
| 1994 |
} |
| 1995 |
|
| 1996 |
$submitted_form_id = isset( $_GET['wpzf_submitted_form'] ) ? intval( $_GET['wpzf_submitted_form'] ) : -1; |
| 1997 |
$show_notice = isset( $_GET['success'] ) && ( -1 === $submitted_form_id || $submitted_form_id === intval( $attributes['formId'] ) ); |
| 1998 |
|
| 1999 |
$content = sprintf( |
| 2000 |
'<!-- ZOOM Forms Start --> |
| 2001 |
<form id="wpzf-%2$s" method="post" action="%1$s" class="wpzoom-forms_form%6$s"> |
| 2002 |
<input type="hidden" name="action" value="wpzf_submit" /> |
| 2003 |
<input type="hidden" name="form_id" value="%2$s" /> |
| 2004 |
%3$s |
| 2005 |
%5$s |
| 2006 |
</form> |
| 2007 |
%4$s |
| 2008 |
<!-- ZOOM Forms End -->', |
| 2009 |
admin_url( 'admin-post.php' ), |
| 2010 |
intval( $attributes['formId'] ), |
| 2011 |
wp_nonce_field( 'wpzf_submit', '_wpnonce', true, false ), |
| 2012 |
( $show_notice |
| 2013 |
? '<div id="' . esc_attr( $form_notice_id ) . '" class="notice ' . ( '1' == $_GET['success'] ? 'success' : 'error' ) . '" tabindex="-1"><p>' . |
| 2014 |
( '1' == $_GET['success'] ? wp_kses_post($form_success_message) : wp_kses_post($form_failure_message) ) . |
| 2015 |
'</p></div>' |
| 2016 |
: '' |
| 2017 |
), |
| 2018 |
$form_content, |
| 2019 |
( 'none' !== $align ? ' align' . $align : '' ) |
| 2020 |
); |
| 2021 |
|
| 2022 |
preg_match( '/<input(?:.*)name="([^"]+)"(?:.*)data-replyto="true"/is', $content, $match1 ); |
| 2023 |
preg_match( '/<input(?:.*)name="([^"]+)"(?:.*)data-subject="true"/is', $content, $match2 ); |
| 2024 |
|
| 2025 |
if ( ! empty( $match1 ) && is_array( $match1 ) && isset( $match1[1] ) ) { |
| 2026 |
$content = preg_replace( '/<\/form>/is', '<input type="hidden" name="wpzf_replyto" value="' . $match1[1] . '" /></form>', $content ); |
| 2027 |
} |
| 2028 |
|
| 2029 |
if ( ! empty( $match2 ) && is_array( $match2 ) && isset( $match2[1] ) ) { |
| 2030 |
$content = preg_replace( '/<\/form>/is', '<input type="hidden" name="wpzf_subject" value="' . $match2[1] . '" /></form>', $content ); |
| 2031 |
} |
| 2032 |
|
| 2033 |
$captcha_config = $this->get_spam_protection_config(); |
| 2034 |
$captcha_method = $captcha_config['active_service']; |
| 2035 |
$recaptcha_type = $captcha_config['type']; |
| 2036 |
$recaptcha_badge_location = esc_attr( sanitize_text_field( WPZOOM_Forms_Settings::get( 'wpzf_global_recaptcha_badge_location' ) ) ); |
| 2037 |
$turnstile_site_key = esc_attr( $captcha_config['turnstile_site_key'] ); |
| 2038 |
$turnstile_widget_theme = esc_attr( sanitize_text_field( WPZOOM_Forms_Settings::get( 'wpzf_global_turnstile_widget_theme' ) ) ); |
| 2039 |
|
| 2040 |
if ( 'recaptcha' === $captcha_method ) { |
| 2041 |
$recaptcha_site_key = ( 'v3' === $recaptcha_type ) ? $captcha_config['recaptcha_v3_site_key'] : $captcha_config['recaptcha_v2_site_key']; |
| 2042 |
$data_badge_location = ''; |
| 2043 |
if ( ! empty( $recaptcha_badge_location ) ) { |
| 2044 |
$data_badge_location = 'data-badge="' . $recaptcha_badge_location . '"'; |
| 2045 |
} |
| 2046 |
|
| 2047 |
$content = preg_replace( '/<input([^>]*)type="submit"([^>]*)class="([^"]+)"/i', '<input $1 type="submit" data-sitekey="' . $recaptcha_site_key . '" data-callback="wpzf_submit" data-action="submit" ' . $data_badge_location . ' $2 class="$3 g-recaptcha"', $content ); |
| 2048 |
} elseif ( 'turnstile' === $captcha_method ) { |
| 2049 |
$turnstile_widget = '<div class="cf-turnstile" data-theme="' . $turnstile_widget_theme . '" data-sitekey="' . $turnstile_site_key . '"></div>'; |
| 2050 |
$content = preg_replace( '/<input([^>]*)type="submit"([^>]*)class="([^"]+)"([^>]*)>/i', '<input $1 type="submit" data-callback="wpzf_submit" data-action="submit" $2 class="$3 cf-captcha" $4>' . $turnstile_widget, $content ); |
| 2051 |
} |
| 2052 |
|
| 2053 |
$style = $styleOutput = ''; |
| 2054 |
|
| 2055 |
// Add custom styles to the form |
| 2056 |
$field_sel = '#' . $form_ID . ' input:not([type="submit"]), #' . $form_ID . ' textarea, #' . $form_ID . ' select'; |
| 2057 |
if( ! empty( $fieldBgColor ) ) { |
| 2058 |
$styleOutput .= sprintf( $field_sel . ' { background-color: %s; }', $fieldBgColor ); |
| 2059 |
} |
| 2060 |
if( ! empty( $fieldBrdStyle ) && 'default' !== $fieldBrdStyle ) { |
| 2061 |
$styleOutput .= sprintf( $field_sel . ' { border-style: %s; }', $fieldBrdStyle ); |
| 2062 |
if( ! empty( $fieldBrdWidth ) ) { |
| 2063 |
$styleOutput .= sprintf( $field_sel . ' { border-width: %s; }', $fieldBrdWidth ); |
| 2064 |
} |
| 2065 |
if( ! empty( $fieldBrdRadius ) ) { |
| 2066 |
$styleOutput .= sprintf( $field_sel . ' { border-radius: %s; }', $fieldBrdRadius ); |
| 2067 |
} |
| 2068 |
} |
| 2069 |
|
| 2070 |
if( ! empty( $fieldBrdColor ) ) { |
| 2071 |
$styleOutput .= sprintf( $field_sel . ' { border-color: %s; }', $fieldBrdColor ); |
| 2072 |
} |
| 2073 |
if( ! empty( $fieldTextColor ) ) { |
| 2074 |
$styleOutput .= sprintf( $field_sel . ' { color: %s; }', $fieldTextColor ); |
| 2075 |
} |
| 2076 |
|
| 2077 |
//Label styles |
| 2078 |
if( ! empty( $labelTextColor ) ) { |
| 2079 |
$styleOutput .= sprintf( '#' . $form_ID . ' label { color: %s; }', $labelTextColor ); |
| 2080 |
} |
| 2081 |
|
| 2082 |
//Button styles — target both old <input type="submit"> and new builder's <button class="wpzf-submit__btn"> |
| 2083 |
$btn_sel = '#' . $form_ID . ' input[type="submit"], #' . $form_ID . ' button.wpzf-submit__btn'; |
| 2084 |
if( ! empty( $btnBrdStyle ) && 'default' !== $btnBrdStyle ) { |
| 2085 |
$styleOutput .= sprintf( $btn_sel . ' { border-style: %s; }', $btnBrdStyle ); |
| 2086 |
if( ! empty( $btnBrdWidth ) ) { |
| 2087 |
$styleOutput .= sprintf( $btn_sel . ' { border-width: %s; }', $btnBrdWidth ); |
| 2088 |
} |
| 2089 |
if( ! empty( $btnBrdRadius ) ) { |
| 2090 |
$styleOutput .= sprintf( $btn_sel . ' { border-radius: %s; }', $btnBrdRadius ); |
| 2091 |
} |
| 2092 |
} |
| 2093 |
if( ! empty( $btnTextColor ) ) { |
| 2094 |
$styleOutput .= sprintf( $btn_sel . ' { color: %s; }', $btnTextColor ); |
| 2095 |
} |
| 2096 |
if( ! empty( $btnBrdColor ) ) { |
| 2097 |
$styleOutput .= sprintf( $btn_sel . ' { border-color: %s; }', $btnBrdColor ); |
| 2098 |
} |
| 2099 |
if( ! empty( $btnBgColor ) ) { |
| 2100 |
$styleOutput .= sprintf( $btn_sel . ' { background-color: %s; }', $btnBgColor ); |
| 2101 |
} |
| 2102 |
|
| 2103 |
// Add styles for the notice |
| 2104 |
$styleOutput .= sprintf( '#%s + .notice { margin-top: 20px; padding: 15px; border-radius: 4px; }', $form_ID ); |
| 2105 |
$styleOutput .= sprintf( '#%s + .notice.success { background-color: #e7f7ed; color: #227045; border-left: 4px solid #46b450; }', $form_ID ); |
| 2106 |
$styleOutput .= sprintf( '#%s + .notice.error { background-color: #fde8e8; color: #8a1f11; border-left: 4px solid #cc0000; }', $form_ID ); |
| 2107 |
$styleOutput .= sprintf( '#%s + .notice p { margin: 0; }', $form_ID ); |
| 2108 |
$styleOutput .= sprintf( '#%s { scroll-margin-top: 24px; }', $form_notice_id ); |
| 2109 |
|
| 2110 |
$style = sprintf( '<style>%s</style>', |
| 2111 |
$styleOutput |
| 2112 |
); |
| 2113 |
|
| 2114 |
$content = $content . $style; |
| 2115 |
|
| 2116 |
return $content; |
| 2117 |
} |
| 2118 |
|
| 2119 |
/** |
| 2120 |
* Render the contents of the settings page in the admin. |
| 2121 |
* |
| 2122 |
* @access public |
| 2123 |
* @return void |
| 2124 |
* @since 1.0.0 |
| 2125 |
*/ |
| 2126 |
public function render_settings_page() { |
| 2127 |
do_action( 'wpzoom_forms_admin_page' ); |
| 2128 |
} |
| 2129 |
|
| 2130 |
/** |
| 2131 |
* Render the contents of the upsell page in the admin. |
| 2132 |
* |
| 2133 |
* @access public |
| 2134 |
* @return void |
| 2135 |
* @since 1.0.0 |
| 2136 |
*/ |
| 2137 |
public function render_upsell_page() { |
| 2138 |
do_action( 'wpzoom_forms_admin_page_upsell' ); |
| 2139 |
} |
| 2140 |
|
| 2141 |
/** |
| 2142 |
* Render the Import & Export upsell page. |
| 2143 |
* |
| 2144 |
* @access public |
| 2145 |
* @return void |
| 2146 |
* @since 1.3.4 |
| 2147 |
*/ |
| 2148 |
public function render_import_export_upsell_page() { |
| 2149 |
if ( ! current_user_can( 'edit_posts' ) ) { |
| 2150 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wpzoom-forms' ) ); |
| 2151 |
} |
| 2152 |
|
| 2153 |
$pro_url = 'https://www.wpzoom.com/plugins/wpzoom-forms/?utm_source=wpadmin&utm_medium=wpzoom-forms-free&utm_campaign=import-export-upsell'; |
| 2154 |
?> |
| 2155 |
<div class="wrap wpzoom-forms-import-export-upsell-page" style="position: relative;"> |
| 2156 |
<h1><?php esc_html_e( 'Import & Export Forms', 'wpzoom-forms' ); ?></h1> |
| 2157 |
<div class="wpzoom-forms-import-export-upsell-container"> |
| 2158 |
<!-- Blurred placeholder content --> |
| 2159 |
<div class="wpzoom-forms-import-export-blurred-content" style="filter: blur(4px); pointer-events: none; opacity: 0.3; margin-bottom: 40px;"> |
| 2160 |
<div style="background: #fff; border: 1px solid #c3c4c7; padding: 20px; margin: 20px 0; border-radius: 4px;"> |
| 2161 |
<div style="display: flex; gap: 20px; margin-bottom: 30px;"> |
| 2162 |
<div style="flex: 1;"> |
| 2163 |
<label style="display: block; margin-bottom: 8px; font-weight: 600; color: #1d2327;"><?php esc_html_e( 'Export Forms', 'wpzoom-forms' ); ?></label> |
| 2164 |
<select style="width: 100%; padding: 8px; border: 1px solid #c3c4c7; border-radius: 4px;"> |
| 2165 |
<option><?php esc_html_e( 'Select forms to export...', 'wpzoom-forms' ); ?></option> |
| 2166 |
<option><?php esc_html_e( 'Contact Form', 'wpzoom-forms' ); ?></option> |
| 2167 |
<option><?php esc_html_e( 'Newsletter Form', 'wpzoom-forms' ); ?></option> |
| 2168 |
</select> |
| 2169 |
</div> |
| 2170 |
<div style="flex: 1;"> |
| 2171 |
<label style="display: block; margin-bottom: 8px; font-weight: 600; color: #1d2327;"><?php esc_html_e( 'Export Format', 'wpzoom-forms' ); ?></label> |
| 2172 |
<select style="width: 100%; padding: 8px; border: 1px solid #c3c4c7; border-radius: 4px;"> |
| 2173 |
<option>JSON</option> |
| 2174 |
<option>CSV</option> |
| 2175 |
</select> |
| 2176 |
</div> |
| 2177 |
</div> |
| 2178 |
<div style="display: flex; gap: 20px; margin-bottom: 30px;"> |
| 2179 |
<div style="flex: 1;"> |
| 2180 |
<label style="display: block; margin-bottom: 8px; font-weight: 600; color: #1d2327;"><?php esc_html_e( 'Import Forms', 'wpzoom-forms' ); ?></label> |
| 2181 |
<input type="file" style="width: 100%; padding: 8px; border: 1px solid #c3c4c7; border-radius: 4px;" /> |
| 2182 |
</div> |
| 2183 |
<div style="flex: 1;"> |
| 2184 |
<label style="display: block; margin-bottom: 8px; font-weight: 600; color: #1d2327;"><?php esc_html_e( 'Export Submissions', 'wpzoom-forms' ); ?></label> |
| 2185 |
<select style="width: 100%; padding: 8px; border: 1px solid #c3c4c7; border-radius: 4px;"> |
| 2186 |
<option><?php esc_html_e( 'Select form...', 'wpzoom-forms' ); ?></option> |
| 2187 |
</select> |
| 2188 |
</div> |
| 2189 |
</div> |
| 2190 |
<div style="display: flex; gap: 10px;"> |
| 2191 |
<button style="padding: 10px 20px; background: #2271b1; color: #fff; border: none; border-radius: 4px; cursor: pointer;"><?php esc_html_e( 'Export', 'wpzoom-forms' ); ?></button> |
| 2192 |
<button style="padding: 10px 20px; background: #2271b1; color: #fff; border: none; border-radius: 4px; cursor: pointer;"><?php esc_html_e( 'Import', 'wpzoom-forms' ); ?></button> |
| 2193 |
<button style="padding: 10px 20px; background: #2271b1; color: #fff; border: none; border-radius: 4px; cursor: pointer;"><?php esc_html_e( 'Export CSV', 'wpzoom-forms' ); ?></button> |
| 2194 |
</div> |
| 2195 |
</div> |
| 2196 |
</div> |
| 2197 |
|
| 2198 |
<!-- Overlay with Popover Modal --> |
| 2199 |
<div class="import-export-upsell-overlay"> |
| 2200 |
<div class="wpzoom-forms-import-export-popover" style="background: #fff; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.15); padding: 40px; max-width: 500px; width: 90%;"> |
| 2201 |
<!-- Icon --> |
| 2202 |
<div style="text-align: center; margin-bottom: 20px;"> |
| 2203 |
<div style="width: 60px; height: 60px; margin: 0 auto; background-color: #3496FF; border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 12px rgba(52, 150, 255, 0.3);"> |
| 2204 |
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 2205 |
<path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z" fill="#fff"/> |
| 2206 |
</svg> |
| 2207 |
</div> |
| 2208 |
</div> |
| 2209 |
|
| 2210 |
<!-- Title --> |
| 2211 |
<h2 style="text-align: center; margin: 0 0 15px 0; font-size: 24px; font-weight: 600; color: #1d2327;"> |
| 2212 |
<?php esc_html_e( 'Unlock Import & Export', 'wpzoom-forms' ); ?> |
| 2213 |
</h2> |
| 2214 |
|
| 2215 |
<!-- Description --> |
| 2216 |
<p style="text-align: center; margin: 0 0 25px 0; color: #50575e; font-size: 14px; line-height: 1.6;"> |
| 2217 |
<?php esc_html_e( 'Transfer your forms between sites, back up your work, and export submissions for analysis. Manage your forms with powerful import and export tools.', 'wpzoom-forms' ); ?> |
| 2218 |
</p> |
| 2219 |
|
| 2220 |
<!-- Features List --> |
| 2221 |
<ul style="list-style: none; padding: 0; margin: 0 0 30px 0;"> |
| 2222 |
<li style="display: flex; align-items: flex-start; margin-bottom: 12px; color: #1d2327; font-size: 14px;"> |
| 2223 |
<span style="display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; background: #3496FF; border-radius: 50%; margin-right: 12px; flex-shrink: 0; margin-top: 2px;"> |
| 2224 |
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 2225 |
<path d="M10 3L4.5 8.5L2 6" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
| 2226 |
</svg> |
| 2227 |
</span> |
| 2228 |
<span><?php esc_html_e( 'Export forms to JSON files for backup or migration', 'wpzoom-forms' ); ?></span> |
| 2229 |
</li> |
| 2230 |
<li style="display: flex; align-items: flex-start; margin-bottom: 12px; color: #1d2327; font-size: 14px;"> |
| 2231 |
<span style="display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; background: #3496FF; border-radius: 50%; margin-right: 12px; flex-shrink: 0; margin-top: 2px;"> |
| 2232 |
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 2233 |
<path d="M10 3L4.5 8.5L2 6" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
| 2234 |
</svg> |
| 2235 |
</span> |
| 2236 |
<span><?php esc_html_e( 'Import forms from JSON files to quickly set up new sites', 'wpzoom-forms' ); ?></span> |
| 2237 |
</li> |
| 2238 |
<li style="display: flex; align-items: flex-start; margin-bottom: 12px; color: #1d2327; font-size: 14px;"> |
| 2239 |
<span style="display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; background: #3496FF; border-radius: 50%; margin-right: 12px; flex-shrink: 0; margin-top: 2px;"> |
| 2240 |
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 2241 |
<path d="M10 3L4.5 8.5L2 6" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
| 2242 |
</svg> |
| 2243 |
</span> |
| 2244 |
<span><?php esc_html_e( 'Export form submissions to CSV for data analysis', 'wpzoom-forms' ); ?></span> |
| 2245 |
</li> |
| 2246 |
<li style="display: flex; align-items: flex-start; margin-bottom: 12px; color: #1d2327; font-size: 14px;"> |
| 2247 |
<span style="display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; background: #3496FF; border-radius: 50%; margin-right: 12px; flex-shrink: 0; margin-top: 2px;"> |
| 2248 |
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 2249 |
<path d="M10 3L4.5 8.5L2 6" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
| 2250 |
</svg> |
| 2251 |
</span> |
| 2252 |
<span><?php esc_html_e( 'Transfer forms between multiple WordPress sites', 'wpzoom-forms' ); ?></span> |
| 2253 |
</li> |
| 2254 |
<li style="display: flex; align-items: flex-start; margin-bottom: 12px; color: #1d2327; font-size: 14px;"> |
| 2255 |
<span style="display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; background: #3496FF; border-radius: 50%; margin-right: 12px; flex-shrink: 0; margin-top: 2px;"> |
| 2256 |
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 2257 |
<path d="M10 3L4.5 8.5L2 6" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> |
| 2258 |
</svg> |
| 2259 |
</span> |
| 2260 |
<span><?php esc_html_e( 'Backup your forms before making major changes', 'wpzoom-forms' ); ?></span> |
| 2261 |
</li> |
| 2262 |
</ul> |
| 2263 |
|
| 2264 |
<!-- CTA Button --> |
| 2265 |
<div style="text-align: center; margin-bottom: 15px;"> |
| 2266 |
<a href="<?php echo esc_url( $pro_url ); ?>" class="button button-primary button-large" style="background-color: #3496FF; border: none; border-radius: 6px; padding: 16px 20px; line-height: 1; font-size: 16px; font-weight: 600; color: #fff; text-decoration: none; display: inline-block; box-shadow: 0 4px 12px rgba(52, 150, 255, 0.3); transition: transform 0.2s, box-shadow 0.2s;" target="_blank" onmouseover="this.style.transform='translateY(-2px)'; this.style.boxShadow='0 6px 16px rgba(52, 150, 255, 0.4)';" onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 4px 12px rgba(52, 150, 255, 0.3)';"> |
| 2267 |
<?php esc_html_e( 'Upgrade to PRO', 'wpzoom-forms' ); ?> |
| 2268 |
</a> |
| 2269 |
</div> |
| 2270 |
|
| 2271 |
<!-- Plugin Attribution --> |
| 2272 |
<p style="text-align: center; margin: 0; color: #8c8f94; font-size: 12px;"> |
| 2273 |
<?php esc_html_e( 'Part of the WPZOOM Forms PRO plugin', 'wpzoom-forms' ); ?> |
| 2274 |
</p> |
| 2275 |
</div> |
| 2276 |
</div> |
| 2277 |
</di> |
| 2278 |
</div> |
| 2279 |
|
| 2280 |
<style> |
| 2281 |
.wpzoom-forms-import-export-upsell-container { |
| 2282 |
position: relative; |
| 2283 |
min-height: 680px; |
| 2284 |
} |
| 2285 |
.wpzoom-forms-import-export-blurred-content { |
| 2286 |
z-index: 1; |
| 2287 |
} |
| 2288 |
.import-export-upsell-overlay { |
| 2289 |
position: absolute; |
| 2290 |
top: 60px; |
| 2291 |
left: 0; |
| 2292 |
right: 0; |
| 2293 |
bottom: 0; |
| 2294 |
display: flex; |
| 2295 |
align-items: flex-start; |
| 2296 |
justify-content: center; |
| 2297 |
padding-top: 80px; |
| 2298 |
z-index: 100; |
| 2299 |
background: hsla(0, 0%, 100%, .1); |
| 2300 |
} |
| 2301 |
.wpzoom-forms-import-export-popover { |
| 2302 |
z-index: 10000; |
| 2303 |
} |
| 2304 |
@media screen and (max-width: 782px) { |
| 2305 |
.wpzoom-forms-import-export-popover { |
| 2306 |
padding: 30px 20px; |
| 2307 |
max-width: 90%; |
| 2308 |
} |
| 2309 |
} |
| 2310 |
</style> |
| 2311 |
<?php |
| 2312 |
} |
| 2313 |
|
| 2314 |
/** |
| 2315 |
* Page header used on all admin pages. |
| 2316 |
* |
| 2317 |
* @access public |
| 2318 |
* @return void |
| 2319 |
* @since 1.0.0 |
| 2320 |
*/ |
| 2321 |
public function admin_page_header() { |
| 2322 |
|
| 2323 |
$current_page = get_current_screen()->id; |
| 2324 |
|
| 2325 |
if ( 'edit-wpzf-form' == $current_page || 'edit-wpzf-submission' == $current_page || 'wpzf-submission' == $current_page || 'wpzf-form_page_wpzf-settings' == $current_page || 'wpzf-form_page_wpzoom-forms-pro-license' == $current_page || 'wpzf-form_page_wpzf-pro-page' == $current_page ) { |
| 2326 |
?> |
| 2327 |
<header class="wpzoom-new-admin-wrap wpzoom-new-admin_settings-header"> |
| 2328 |
<h1 class="wpzoom-new-admin_settings-main-title wp-heading"> |
| 2329 |
<?php |
| 2330 |
echo apply_filters( |
| 2331 |
'wpzf_admin-header-title', |
| 2332 |
sprintf( |
| 2333 |
__( 'WPZOOM Forms <small>Lite</small>', 'wpzoom-forms' ) |
| 2334 |
) |
| 2335 |
); |
| 2336 |
?> |
| 2337 |
|
| 2338 |
<span class="wpzoom-new-admin_settings-main-title-version"> |
| 2339 |
<?php |
| 2340 |
echo apply_filters( |
| 2341 |
'wpzf_admin-header-title-version', |
| 2342 |
sprintf( |
| 2343 |
esc_html__( 'v %s', 'wpzoom-forms' ), |
| 2344 |
WPZOOM_FORMS_VERSION |
| 2345 |
) |
| 2346 |
); |
| 2347 |
?> |
| 2348 |
</span> |
| 2349 |
</h1> |
| 2350 |
|
| 2351 |
<nav class="wpzoom-new-admin_settings-main-nav"> |
| 2352 |
<ul> |
| 2353 |
<?php |
| 2354 |
$pages = apply_filters( |
| 2355 |
'wpzoom_forms_settings_menu_items', |
| 2356 |
array( |
| 2357 |
'edit-wpzf-form' => array( |
| 2358 |
'name' => __( 'Forms', 'wpzoom-forms' ), |
| 2359 |
'url' => admin_url( 'edit.php?post_type=wpzf-form' ), |
| 2360 |
), |
| 2361 |
'edit-wpzf-submission' => array( |
| 2362 |
'name' => __( 'Submissions', 'wpzoom-forms' ), |
| 2363 |
'url' => admin_url( 'edit.php?post_type=wpzf-submission' ), |
| 2364 |
'altid' => 'wpzf-submission' |
| 2365 |
), |
| 2366 |
'wpzf-form_page_wpzf-settings' => array( |
| 2367 |
'name' => esc_html__( 'Settings', 'wpzoom-forms' ), |
| 2368 |
'url' => admin_url( 'edit.php?post_type=wpzf-form&page=wpzf-settings' ), |
| 2369 |
), |
| 2370 |
'wpzf-form_page_wpzf-pro-page' => array( |
| 2371 |
'name' => esc_html__( 'Upgrade to PRO', 'wpzoom-forms' ), |
| 2372 |
'url' => admin_url( 'edit.php?post_type=wpzf-form&page=wpzf-pro-page' ), |
| 2373 |
), |
| 2374 |
'wpzf-form_page_wpzf-import' => array( |
| 2375 |
'name' => esc_html__( 'Import & Export', 'wpzoom-forms' ), |
| 2376 |
'url' => admin_url( 'edit.php?post_type=wpzf-form&page=wpzf-import' ), |
| 2377 |
), |
| 2378 |
) |
| 2379 |
); |
| 2380 |
|
| 2381 |
foreach ( $pages as $id => $atts ) { |
| 2382 |
printf( |
| 2383 |
// translators: %1$s = possible class attribute, %2$s = page url, %3$s = page name. |
| 2384 |
_x( '<li%1$s><a href="%2$s">%3$s</a></li>', 'Main menu page item', 'wpzoom-forms' ), |
| 2385 |
( $current_page === $id || ( isset( $atts['altid'] ) && $current_page == $atts['altid'] ) ? ' class="active"' : '' ), |
| 2386 |
esc_url( $atts['url'] ), |
| 2387 |
esc_html( $atts['name'] ) |
| 2388 |
); |
| 2389 |
} |
| 2390 |
?> |
| 2391 |
</ul> |
| 2392 |
</nav> |
| 2393 |
</header> |
| 2394 |
<?php |
| 2395 |
} |
| 2396 |
|
| 2397 |
if ( 'edit-wpzf-form' == $current_page || 'wpzf-form' == $current_page ) { |
| 2398 |
$forms_count = wp_count_posts( 'wpzf-form' ); |
| 2399 |
|
| 2400 |
if ( $forms_count->publish < 1 && $forms_count->draft < 1 && $forms_count->trash < 1 ) { |
| 2401 |
?> |
| 2402 |
<div class="wpzf_no-forms"> |
| 2403 |
<div class="left-column"> |
| 2404 |
<h3> |
| 2405 |
<?php esc_html_e( 'Hi there!', 'wpzoom-forms' ); ?> |
| 2406 |
</h3> |
| 2407 |
|
| 2408 |
<h2> |
| 2409 |
<?php esc_html_e( 'It appears that you haven’t made any forms yet.', 'wpzoom-forms' ); ?> |
| 2410 |
</h2> |
| 2411 |
|
| 2412 |
<p> |
| 2413 |
<?php esc_html_e( 'With WPZOOM Forms, you have the ability to create contact forms, surveys, and various other types of forms effortlessly and swiftly.', 'wpzoom-forms' ); ?> |
| 2414 |
</p> |
| 2415 |
|
| 2416 |
<a href="<?php echo esc_url( admin_url( 'post-new.php?post_type=wpzf-form' ) ); ?>" class="button-primary wpzf-add-form-btn"> |
| 2417 |
<?php esc_html_e( 'Add new form', 'wpzoom-forms' ); ?> |
| 2418 |
</a> |
| 2419 |
</div> |
| 2420 |
|
| 2421 |
<div class="right-column"> |
| 2422 |
<svg width="360" height="360" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 2423 |
<mask id="a" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="25" y="140" width="304" height="175"> |
| 2424 |
<path d="M305.985 314.458H47.535a24.293 24.293 0 0 1-3.753-.29c-3.966-.621-7.575-2.21-10.528-4.493a21.616 21.616 0 0 1-2.11-1.862.535.535 0 0 0 .502-.168l94.603-106.18 50.511 30.403 50.49-30.425 94.623 106.202a.531.531 0 0 0 .504.168 21.988 21.988 0 0 1-4.388 3.406 22.998 22.998 0 0 1-6.489 2.603 24 24 0 0 1-5.515.636zm16.809-7.078a.517.517 0 0 0-.126-.438l-37.526-42.119c.465.15.961.263 1.488.328 4.522.558 10.117-.941 13.717 7.925 1.072 2.64 2.755 3.646 4.524 3.646 4.168 0 8.8-5.601 6.971-8.59-2.605-4.255 2.223-7.364 4.674-12.255 1.591-3.176-.007-5.899-3.066-7.309-2.354-1.081-6.664-.35-7.987-3.181-.961-2.057-.308-4.881-.825-7.094-.735-3.151-2.695-4.059-4.592-4.059-1.46 0-2.883.538-3.683 1.003-1.056.616-2.896 1.835-4.431 1.835-1.137 0-2.108-.671-2.466-2.751-.628-3.647-4.487-5.975-8.17-5.975-1.26 0-2.499.273-3.581.859-.469.23-.835.496-1.121.781-2.489 2.275 0 5.251 0 5.251-4.981 4.511.69 11.772 2.376 13.454 1.684 1.682 3.294 4.052 2.067 8.025-.341 1.111-.408 2.215-.23 3.241l-52.631-59.072 24.464-14.743 75.566-45.435V294.001c0 4.5-1.578 8.66-4.253 12.039-.366.461-.753.909-1.159 1.34zm-292.07 0c-.024-.025-.048-.053-.073-.078-3.327-3.577-5.337-8.222-5.337-13.301V140.707l75.566 45.486 24.443 14.714-94.471 106.035a.522.522 0 0 0-.128.438z" fill="#fff" /> |
| 2425 |
</mask> |
| 2426 |
<g mask="url(#a)"> |
| 2427 |
<path d="M305.983 314.458H47.534a24.564 24.564 0 0 1-3.752-.29c-3.966-.621-7.575-2.21-10.528-4.493a21.583 21.583 0 0 1-2.111-1.862.537.537 0 0 0 .503-.168l94.603-106.18 50.509 30.404 50.491-30.426 94.622 106.202a.538.538 0 0 0 .504.168 21.982 21.982 0 0 1-4.387 3.406 23.044 23.044 0 0 1-6.49 2.604c-1.762.415-3.61.635-5.515.635zm16.809-7.078a.513.513 0 0 0-.125-.438l-37.525-42.118c.465.15.961.262 1.488.327 4.52.559 10.117-.941 13.717 7.925 1.071 2.641 2.754 3.647 4.523 3.647 4.169 0 8.799-5.602 6.971-8.591-2.604-4.255 2.222-7.364 4.674-12.255 1.59-3.176-.009-5.899-3.067-7.308-2.352-1.082-6.663-.351-7.986-3.181-.961-2.058-.309-4.882-.825-7.094-.734-3.152-2.695-4.06-4.591-4.06-1.462 0-2.885.538-3.684 1.004-1.057.615-2.896 1.834-4.43 1.834-1.136 0-2.108-.67-2.468-2.751-.626-3.646-4.486-5.974-8.168-5.974-1.261 0-2.499.273-3.582.858a4.227 4.227 0 0 0-1.122.781c-2.488 2.276 0 5.252 0 5.252-4.98 4.51.691 11.771 2.378 13.453 1.683 1.683 3.293 4.053 2.066 8.025-.341 1.111-.409 2.215-.23 3.241l-52.631-59.071 24.464-14.743 75.566-45.436V294.001c0 4.501-1.579 8.661-4.254 12.04-.365.46-.751.908-1.159 1.339zm-292.067 0-.074-.078c-3.327-3.577-5.337-8.222-5.337-13.301V140.708l75.565 45.485 24.444 14.715-94.471 106.034a.522.522 0 0 0-.127.438z" fill="#083EA7" /> |
| 2428 |
</g> |
| 2429 |
<mask id="b" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="25" y="52" width="304" height="180"> |
| 2430 |
<path d="m176.76 231.868-50.511-30.403.038-.04a.533.533 0 0 0-.399-.883.53.53 0 0 0-.396.178l-.169.187-24.443-14.714-75.565-45.486-.315-.19 17.42-10.512 58.46-35.278 65.693-39.64c3.197-1.93 6.689-2.894 10.184-2.894 3.496 0 6.993.966 10.19 2.894L252.64 94.74l60.632 36.579 15.248 9.198-.314.19-75.566 45.435-24.464 14.743-.148-.165a.53.53 0 0 0-.75-.044.533.533 0 0 0-.045.749l.017.018-50.49 30.425z" fill="#fff" /> |
| 2431 |
</mask> |
| 2432 |
<g mask="url(#b)"> |
| 2433 |
<path d="m176.76 231.868-50.511-30.404.038-.039a.533.533 0 0 0-.399-.883.53.53 0 0 0-.396.178l-.169.187-24.443-14.714-75.565-45.486-.315-.19 17.42-10.512 58.46-35.277 65.693-39.643c3.196-1.929 6.69-2.89 10.184-2.89 3.497 0 6.993.964 10.189 2.89l65.695 39.655 60.63 36.579 15.249 9.198-.315.189-75.564 45.436-24.466 14.743-.147-.165a.529.529 0 0 0-.749-.044.533.533 0 0 0-.045.749l.017.018-50.491 30.425z" fill="#242628" /> |
| 2434 |
</g> |
| 2435 |
<mask id="c" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="30" y="200" width="97" height="108"> |
| 2436 |
<path d="M31.25 307.823a.536.536 0 0 1-.107-.01 26.971 26.971 0 0 1-.418-.433.522.522 0 0 1 .127-.438l94.472-106.035.926.558-94.604 106.18a.53.53 0 0 1-.397.178z" fill="#fff" /> |
| 2437 |
</mask> |
| 2438 |
<g mask="url(#c)"> |
| 2439 |
<path d="M31.25 307.823a.536.536 0 0 1-.107-.01 26.971 26.971 0 0 1-.418-.433.522.522 0 0 1 .127-.438l94.472-106.035.926.558-94.604 106.18a.53.53 0 0 1-.397.178z" fill="#fff" /> |
| 2440 |
</g> |
| 2441 |
<mask id="d" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="227" y="200" width="96" height="108"> |
| 2442 |
<path d="M322.272 307.823a.531.531 0 0 1-.399-.178L227.25 201.443l.926-.558 52.631 59.072c.386 2.223 1.927 4.085 4.335 4.866l37.526 42.119a.517.517 0 0 1 .126.438c-.136.147-.276.29-.417.433a.533.533 0 0 1-.105.01z" fill="#fff" /> |
| 2443 |
</mask> |
| 2444 |
<g mask="url(#d)"> |
| 2445 |
<path d="M322.27 307.822a.532.532 0 0 1-.397-.177l-94.622-106.202.924-.558 52.63 59.072c.387 2.223 1.927 4.085 4.336 4.866l37.527 42.118a.523.523 0 0 1 .126.439c-.137.147-.277.29-.417.433a.533.533 0 0 1-.107.009z" fill="#fff" /> |
| 2446 |
</g> |
| 2447 |
<mask id="e" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="274" y="228" width="44" height="49"> |
| 2448 |
<path d="M304.871 276.722c-1.769 0-3.452-1.006-4.524-3.646-3.6-8.866-9.196-7.367-13.717-7.925a8.029 8.029 0 0 1-1.488-.328c-2.409-.781-3.949-2.643-4.336-4.866-.178-1.026-.11-2.13.231-3.241 1.227-3.973-.384-6.343-2.067-8.025-1.686-1.682-7.357-8.943-2.376-13.454 0 0-2.489-2.976 0-5.251-1.877 1.87-.259 4.62-.259 4.62l1.38-.961c5.861.078 3.5 6.673 3.5 6.673l.369.188s.638-.686 1.207-.686c.236 0 .462.118.625.451.552 1.136-.808 3.259-.808 3.259s.497 1.239 1.636 1.239c.502 0 1.129-.24 1.892-.936 1.882-1.707 2.845-3.868 2.567-6.854.072.398.24.894.619 1.269.364.366.861.549 1.471.549.055 0 .113-.003.17-.005.901-.048 2.186-.446 3.548-.869 1.769-.548 3.691-1.144 5.219-1.144.793 0 1.48.163 1.982.576.743.608 1.014 1.699.836 3.341l.205.02c.189-1.712-.11-2.866-.908-3.521-.544-.446-1.277-.619-2.115-.619-1.563 0-3.5.599-5.282 1.152-1.347.418-2.622.811-3.497.858a2.709 2.709 0 0 1-.156.005c-.554 0-1.001-.162-1.327-.485-.665-.664-.617-1.79-.615-1.8l-.208-.01c0 .01-.003.088.002.205a16.274 16.274 0 0 0-.634-2.743c-1.102-3.484-4.236-5.246-7.219-5.246-1.081 0-2.14.23-3.079.693 1.082-.586 2.321-.859 3.581-.859 3.683 0 7.542 2.328 8.169 5.975.359 2.08 1.33 2.751 2.467 2.751 1.535 0 3.375-1.219 4.431-1.835.8-.465 2.223-1.003 3.683-1.003 1.897 0 3.857.908 4.592 4.059.517 2.213-.136 5.037.825 7.094 1.323 2.831 5.633 2.1 7.987 3.181 3.058 1.41 4.657 4.133 3.066 7.309-2.452 4.891-7.279 8-4.675 12.255 1.83 2.989-2.802 8.59-6.97 8.59zm3.297-27.44-.028.205c.048.005 4.725.673 6.133 2.966.451.736.519 1.569.203 2.478-.66 1.902-1.894 3.487-2.983 4.886-1.516 1.942-2.823 3.619-2.339 5.604l.201-.05c-.459-1.887.818-3.529 2.298-5.429 1.102-1.409 2.346-3.008 3.019-4.943.338-.969.263-1.863-.224-2.654-1.46-2.375-6.084-3.036-6.28-3.063z" fill="#fff" /> |
| 2449 |
</mask> |
| 2450 |
<g mask="url(#e)"> |
| 2451 |
<path d="M304.871 276.723c-1.77 0-3.455-1.006-4.526-3.647-3.601-8.866-9.194-7.367-13.717-7.925a8.002 8.002 0 0 1-1.488-.328c-2.409-.781-3.947-2.643-4.335-4.865-.179-1.027-.11-2.13.23-3.242 1.228-3.972-.382-6.343-2.066-8.024-1.688-1.683-7.358-8.944-2.376-13.454 0 0-2.49-2.976 0-5.252-1.879 1.87-.26 4.621-.26 4.621l1.38-.961c5.861.077 3.502 6.673 3.502 6.673l.368.188s.636-.686 1.206-.686c.238 0 .462.118.625.45.553 1.137-.808 3.259-.808 3.259s.498 1.239 1.638 1.239c.5 0 1.128-.24 1.889-.936 1.884-1.707 2.846-3.867 2.567-6.853.075.398.241.893.62 1.269.365.365.863.548 1.471.548.056 0 .114-.003.172-.005.899-.048 2.185-.445 3.546-.869 1.77-.548 3.693-1.144 5.22-1.144.793 0 1.479.163 1.983.576.741.609 1.012 1.7.835 3.342l.205.02c.188-1.712-.111-2.866-.907-3.522-.545-.446-1.278-.618-2.116-.618-1.563 0-3.5.598-5.281 1.151-1.35.418-2.622.811-3.499.859-.053.002-.102.005-.155.005-.556 0-1.001-.163-1.328-.486-.664-.663-.617-1.79-.614-1.8l-.207-.009c0 .009-.003.087 0 .205-.111-.849-.324-1.76-.634-2.744-1.101-3.484-4.235-5.246-7.219-5.246a6.967 6.967 0 0 0-3.079.694c1.081-.586 2.321-.859 3.582-.859 3.682 0 7.541 2.328 8.168 5.975.36 2.08 1.331 2.75 2.468 2.75 1.535 0 3.375-1.219 4.431-1.834.8-.466 2.221-1.004 3.682-1.004 1.898 0 3.856.909 4.592 4.06.517 2.213-.136 5.036.827 7.093 1.322 2.831 5.632 2.101 7.986 3.182 3.059 1.409 4.655 4.132 3.065 7.308-2.451 4.892-7.278 8-4.675 12.256 1.831 2.988-2.802 8.59-6.968 8.59zm3.294-27.441-.027.205c.049.005 4.724.674 6.132 2.967.454.735.52 1.569.205 2.478-.661 1.902-1.895 3.486-2.985 4.885-1.516 1.943-2.821 3.62-2.337 5.605l.199-.05c-.459-1.888.819-3.53 2.299-5.43 1.103-1.409 2.345-3.008 3.02-4.943.338-.969.263-1.862-.224-2.653-1.46-2.375-6.085-3.036-6.282-3.064z" fill="#242628" /> |
| 2452 |
</g> |
| 2453 |
<mask id="f" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="261" y="282" width="18" height="42"> |
| 2454 |
<path d="M270.028 282.812s-3.402.526-7.229 3.079a1.904 1.904 0 0 0-.843 1.82c.459 3.619 2.344 15.338 8.556 26.785.326.603.422 1.306.276 1.977l-1.079 5.011-2.002 1.872h5.156l3.433-9.266-1.468-.463a2.772 2.772 0 0 1-1.94-2.596l-.173-9.939c.148-4.43-2.722-7.487-2.722-7.487l8.235-.398-8.2-10.395z" fill="#fff" /> |
| 2455 |
</mask> |
| 2456 |
<g mask="url(#f)"> |
| 2457 |
<path d="M270.028 282.812s-3.402.526-7.229 3.079a1.898 1.898 0 0 0-.844 1.82c.46 3.619 2.343 15.338 8.556 26.785.326.603.422 1.306.275 1.977l-1.077 5.011-2.004 1.872h5.156l3.435-9.266-1.469-.463a2.774 2.774 0 0 1-1.941-2.596l-.171-9.939c.146-4.43-2.723-7.486-2.723-7.486l8.235-.399-8.199-10.395z" fill="url(#g)" /> |
| 2458 |
</g> |
| 2459 |
<mask id="h" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="265" y="313" width="13" height="13"> |
| 2460 |
<path d="M265.694 324.26c-.469.613 5.053 1.422 7.844.083 0 0 3.869-6.716 3.869-10.173 0 0-.309-.703-2.58-.543 0 0-1.3 7.947-2.669 8.838-1.373.891-3.837.09-3.837.09s-1.934.801-2.627 1.705z" fill="#fff" /> |
| 2461 |
</mask> |
| 2462 |
<g mask="url(#h)"> |
| 2463 |
<path d="M265.693 324.26c-.469.614 5.052 1.422 7.842.083 0 0 3.869-6.716 3.869-10.172 0 0-.307-.704-2.58-.543 0 0-1.299 7.946-2.669 8.837-1.372.892-3.836.091-3.836.091s-1.935.801-2.626 1.704z" fill="#242628" /> |
| 2464 |
</g> |
| 2465 |
<mask id="i" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="242" y="284" width="36" height="41"> |
| 2466 |
<path d="M277.186 293.753c-.045-.078-8.864-1.059-8.864-1.059s.288 2.676-.615 6.358c-.901 3.684-13.853 19.641-13.853 19.641l1.358 4.295c-4.198 1.46-8.328 1.692-12.393.744l8.416-5.039s7.876-26.775 12.701-31.553l8.842-3.051 4.408 9.664z" fill="#fff" /> |
| 2467 |
</mask> |
| 2468 |
<g mask="url(#i)"> |
| 2469 |
<path d="M277.185 293.754c-.046-.078-8.864-1.059-8.864-1.059s.287 2.675-.615 6.357c-.9 3.685-13.853 19.641-13.853 19.641l1.356 4.295c-4.197 1.46-8.327 1.693-12.391.744l8.415-5.039s7.876-26.774 12.701-31.553l8.842-3.051 4.409 9.665z" fill="url(#j)" /> |
| 2470 |
</g> |
| 2471 |
<mask id="k" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="264" y="278" width="39" height="17"> |
| 2472 |
<path d="M296.968 278.172s5.083 7.541 5.5 10.98c.416 3.44-1.393 4.839-6.725 5.069-5.334.23-19.568.225-19.568.225l-12.152-10.357s8.855-3.151 11.158-4.043c2.301-.891 21.787-1.874 21.787-1.874z" fill="#fff" /> |
| 2473 |
</mask> |
| 2474 |
<g mask="url(#k)"> |
| 2475 |
<path d="M296.969 278.172s5.082 7.541 5.5 10.98c.415 3.439-1.392 4.839-6.724 5.069-5.334.23-19.571.225-19.571.225l-12.149-10.357s8.854-3.152 11.156-4.043c2.302-.891 21.788-1.874 21.788-1.874z" fill="#001C37" /> |
| 2476 |
</g> |
| 2477 |
<mask id="l" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="240" y="321" width="16" height="5"> |
| 2478 |
<path d="M254.7 321.542s1.46 1.411.474 2.983c0 0-11.582 2.048-14.726 1.119 0 0 .653-1.487 4.193-3.179l-.261.201c-.331.252-.136.781.278.758 2.334-.133 7.164-.561 10.042-1.882z" fill="#fff" /> |
| 2479 |
</mask> |
| 2480 |
<g mask="url(#l)"> |
| 2481 |
<path d="M254.7 321.542s1.46 1.411.474 2.983c0 0-11.582 2.048-14.726 1.119 0 0 .653-1.487 4.193-3.179l-.261.201c-.331.252-.136.781.278.758 2.334-.133 7.164-.561 10.042-1.882z" fill="#242628" /> |
| 2482 |
</g> |
| 2483 |
<mask id="m" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="272" y="249" width="31" height="29"> |
| 2484 |
<path d="M283.223 277.173s-5.916-5.622-8.829-9.344a7.887 7.887 0 0 1-1.343-7.111c1.33-4.47 3.694-9.098 3.91-9.819.331-1.107 6.967-1.059 6.967-1.059s13.058 8.455 18.189 22.775l-5.764 1.79s-3.409-5.707-6.777-9.334c0 0 5.829 7.682 6.035 10.825l-12.388 1.277z" fill="#fff" /> |
| 2485 |
</mask> |
| 2486 |
<g mask="url(#m)"> |
| 2487 |
<path d="M283.222 277.173s-5.915-5.622-8.829-9.344a7.89 7.89 0 0 1-1.343-7.111c1.332-4.47 3.696-9.098 3.91-9.819.331-1.106 6.968-1.059 6.968-1.059s13.057 8.455 18.188 22.775l-5.762 1.79s-3.412-5.707-6.779-9.334c0 0 5.83 7.682 6.035 10.825l-12.388 1.277z" fill="#1FDE91" /> |
| 2488 |
</g> |
| 2489 |
<mask id="n" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="276" y="243" width="8" height="8"> |
| 2490 |
<path d="M276.157 244.726c.07.228 1.802 5.957 1.937 6.075.136.12 3.799.315 5.523-.858l-2.926-6.11-4.534.893z" fill="#fff" /> |
| 2491 |
</mask> |
| 2492 |
<g mask="url(#n)"> |
| 2493 |
<path d="M276.158 244.726c.069.228 1.8 5.957 1.936 6.075.136.12 3.8.315 5.523-.859l-2.927-6.11-4.532.894z" fill="url(#o)" /> |
| 2494 |
</g> |
| 2495 |
<mask id="p" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="272" y="232" width="13" height="14"> |
| 2496 |
<path d="M279.003 232.694s-3.127 1.317-5.252 5.825c-2.128 4.508-.539 6.588 1.455 6.873 1.995.288 4.976.243 8.132-2.668 3.154-2.911-.271-11.592-4.335-10.03z" fill="#fff" /> |
| 2497 |
</mask> |
| 2498 |
<g mask="url(#p)"> |
| 2499 |
<path d="M279.003 232.694s-3.128 1.317-5.253 5.825c-2.128 4.508-.539 6.588 1.455 6.873 1.997.288 4.976.243 8.133-2.668 3.154-2.911-.272-11.591-4.335-10.03z" fill="url(#q)" /> |
| 2500 |
</g> |
| 2501 |
<mask id="r" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="275" y="228" width="14" height="17"> |
| 2502 |
<path d="M284.245 244.769c-1.14 0-1.636-1.239-1.636-1.239s1.36-2.123.808-3.259c-.164-.333-.389-.451-.625-.451-.57 0-1.207.686-1.207.686l-.369-.188s2.361-6.595-3.5-6.673l-1.38.961s-1.618-2.75.258-4.62a4.172 4.172 0 0 1 1.122-.781 6.96 6.96 0 0 1 3.079-.693c2.983 0 6.117 1.762 7.218 5.246.311.984.522 1.895.635 2.743.005.123.02.291.055.478.279 2.986-.685 5.147-2.567 6.854-.762.695-1.39.936-1.891.936z" fill="#fff" /> |
| 2503 |
</mask> |
| 2504 |
<g mask="url(#r)"> |
| 2505 |
<path d="M284.246 244.768c-1.14 0-1.635-1.239-1.635-1.239s1.358-2.122.806-3.259c-.163-.332-.389-.45-.625-.45-.57 0-1.205.686-1.205.686l-.371-.188s2.362-6.596-3.499-6.673l-1.379.961s-1.62-2.751.257-4.621c.287-.285.653-.55 1.122-.781a6.956 6.956 0 0 1 3.079-.693c2.984 0 6.118 1.762 7.219 5.247.311.983.521 1.894.635 2.743.003.122.019.29.055.478.277 2.986-.684 5.146-2.566 6.853-.765.696-1.392.936-1.893.936z" fill="#242628" /> |
| 2506 |
</g> |
| 2507 |
<mask id="s" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="280" y="239" width="4" height="5"> |
| 2508 |
<path d="M280.594 241.37s1.192-3.397 2.782-2.045c1.591 1.354-1.292 3.138-2.421 3.717l-.361-1.672z" fill="#fff" /> |
| 2509 |
</mask> |
| 2510 |
<g mask="url(#s)"> |
| 2511 |
<path d="M280.593 241.37s1.191-3.397 2.782-2.045c1.591 1.354-1.294 3.139-2.421 3.717l-.361-1.672z" fill="url(#t)" /> |
| 2512 |
</g> |
| 2513 |
<mask id="u" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="271" y="272" width="33" height="8"> |
| 2514 |
<path d="m271.167 277.591 4.348-4.18 6.015 2.536s5.989.923 9.414 0l3.427-.927 7.746-2.405 1.214 3.429c.309.871 0 1.837-.755 2.371-.67.475-1.455.998-1.957 1.216-1.019.446-25.139-.308-25.139-.308l-4.313-1.732z" fill="#fff" /> |
| 2515 |
</mask> |
| 2516 |
<g mask="url(#u)"> |
| 2517 |
<path d="m271.167 277.591 4.348-4.18 6.016 2.535s5.987.924 9.412 0l3.428-.926 7.747-2.405 1.215 3.429c.308.871 0 1.837-.757 2.37-.67.476-1.456.999-1.958 1.217-1.016.445-25.138-.308-25.138-.308l-4.313-1.732z" fill="url(#v)" /> |
| 2518 |
</g> |
| 2519 |
<mask id="w" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="288" y="236" width="15" height="5"> |
| 2520 |
<path d="m302.754 240.716-.206-.02c.178-1.642-.093-2.733-.835-3.341-.502-.413-1.19-.576-1.983-.576-1.528 0-3.45.596-5.219 1.144-1.362.423-2.647.821-3.547.869-.058.002-.116.005-.171.005-.61 0-1.107-.183-1.47-.549-.379-.375-.547-.871-.62-1.269-.015-.157-.035-.315-.055-.478-.005-.117-.003-.195-.003-.205l.208.01c-.002.01-.05 1.136.615 1.8.326.323.773.485 1.327.485.053 0 .103-.002.156-.005.876-.047 2.15-.44 3.498-.858 1.781-.553 3.718-1.152 5.281-1.152.838 0 1.571.173 2.116.619.797.655 1.096 1.809.908 3.521z" fill="#fff" /> |
| 2521 |
</mask> |
| 2522 |
<g mask="url(#w)"> |
| 2523 |
<path d="m302.753 240.717-.206-.02c.177-1.642-.094-2.734-.836-3.342-.503-.413-1.189-.575-1.981-.575-1.53 0-3.45.595-5.22 1.143-1.364.424-2.647.821-3.549.869-.056.002-.115.005-.169.005-.61 0-1.106-.183-1.47-.548-.38-.376-.549-.871-.622-1.269-.013-.158-.034-.316-.053-.478-.005-.118-.003-.196-.003-.206l.209.01c-.003.01-.051 1.137.613 1.8.327.323.774.486 1.329.486.051 0 .102-.003.155-.005.876-.048 2.151-.441 3.498-.859 1.781-.553 3.717-1.151 5.282-1.151.838 0 1.569.172 2.113.618.798.656 1.098 1.81.91 3.522z" fill="#424242" /> |
| 2524 |
</g> |
| 2525 |
<mask id="x" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="288" y="236" width="1" height="1"> |
| 2526 |
<path d="M288.703 236.979a3.421 3.421 0 0 1-.056-.478c.021.163.041.321.056.478z" fill="#fff" /> |
| 2527 |
</mask> |
| 2528 |
<g mask="url(#x)"> |
| 2529 |
<path d="M288.701 236.98a3.415 3.415 0 0 1-.055-.478c.019.163.039.32.055.478z" fill="url(#y)" /> |
| 2530 |
</g> |
| 2531 |
<mask id="z" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="308" y="249" width="7" height="17"> |
| 2532 |
<path d="M309.154 265.421c-.484-1.985.823-3.662 2.339-5.604 1.089-1.399 2.323-2.984 2.983-4.886.316-.909.248-1.742-.203-2.478-1.408-2.293-6.085-2.961-6.132-2.966l.027-.205c.196.027 4.82.688 6.28 3.063.487.791.563 1.685.224 2.654-.673 1.934-1.917 3.534-3.019 4.943-1.48 1.9-2.757 3.542-2.298 5.429l-.201.05z" fill="#fff" /> |
| 2533 |
</mask> |
| 2534 |
<g mask="url(#z)"> |
| 2535 |
<path d="M309.153 265.422c-.484-1.985.823-3.662 2.337-5.605 1.09-1.399 2.326-2.983 2.984-4.885.316-.909.25-1.743-.201-2.479-1.409-2.292-6.086-2.961-6.132-2.966l.027-.205c.196.028 4.819.688 6.278 3.064.487.791.564 1.684.226 2.653-.674 1.935-1.919 3.534-3.019 4.943-1.481 1.9-2.758 3.542-2.299 5.43l-.201.05z" fill="#424242" /> |
| 2536 |
</g> |
| 2537 |
<mask id="A" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="285" y="299" width="4" height="25"> |
| 2538 |
<path d="M288.083 324h-2.291v-24.71h2.291V324z" fill="#fff" /> |
| 2539 |
</mask> |
| 2540 |
<g mask="url(#A)"> |
| 2541 |
<path d="M288.083 324h-2.29v-24.71h2.29V324z" fill="#242628" /> |
| 2542 |
</g> |
| 2543 |
<mask id="B" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="276" y="322" width="21" height="3"> |
| 2544 |
<path d="M296.967 324.475h-20.06a1.49 1.49 0 0 1 1.491-1.487h17.079c.823 0 1.49.666 1.49 1.487z" fill="#fff" /> |
| 2545 |
</mask> |
| 2546 |
<g mask="url(#B)"> |
| 2547 |
<path d="M296.966 324.475h-20.061a1.49 1.49 0 0 1 1.491-1.486h17.08c.822 0 1.49.665 1.49 1.486z" fill="#242628" /> |
| 2548 |
</g> |
| 2549 |
<mask id="C" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="274" y="293" width="26" height="8"> |
| 2550 |
<path d="M299.947 298.431a2.468 2.468 0 0 1-2.464 2.458h-20.296a2.468 2.468 0 0 1-2.464-2.458v-2.222a2.467 2.467 0 0 1 2.464-2.456h20.296a2.467 2.467 0 0 1 2.464 2.456v2.222z" fill="#fff" /> |
| 2551 |
</mask> |
| 2552 |
<g mask="url(#C)"> |
| 2553 |
<path d="M299.949 298.431a2.47 2.47 0 0 1-2.464 2.458h-20.296a2.467 2.467 0 0 1-2.463-2.458v-2.223a2.464 2.464 0 0 1 2.463-2.455h20.296a2.466 2.466 0 0 1 2.464 2.455v2.223z" fill="#242628" /> |
| 2554 |
</g> |
| 2555 |
<mask id="D" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="261" y="277" width="28" height="3"> |
| 2556 |
<path d="M287.621 279.563h-.058l-25.224-.027a1.127 1.127 0 1 1 .003-2.253l25.224.028c.625 0 1.129.505 1.129 1.129a1.132 1.132 0 0 1-1.074 1.123z" fill="#fff" /> |
| 2557 |
</mask> |
| 2558 |
<g mask="url(#D)"> |
| 2559 |
<path d="M287.624 279.563h-.06l-25.222-.028a1.126 1.126 0 0 1-1.127-1.126c0-.623.508-1.136 1.127-1.126l25.225.027c.624 0 1.13.506 1.13 1.129a1.132 1.132 0 0 1-1.073 1.124z" fill="#242628" /> |
| 2560 |
</g> |
| 2561 |
<mask id="E" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="237" y="256" width="38" height="24"> |
| 2562 |
<path d="M239.665 256.716h21.006c1.551 0 2.961.893 3.623 2.29l9.71 20.542H247.9a2.431 2.431 0 0 1-2.263-1.534l-7.53-19.008a1.674 1.674 0 0 1 1.558-2.29z" fill="#fff" /> |
| 2563 |
</mask> |
| 2564 |
<g mask="url(#E)"> |
| 2565 |
<path d="M239.665 256.716h21.006c1.551 0 2.961.893 3.623 2.29l9.71 20.542H247.9a2.431 2.431 0 0 1-2.263-1.534l-7.53-19.008a1.674 1.674 0 0 1 1.558-2.29z" fill="#242628" /> |
| 2566 |
</g> |
| 2567 |
<mask id="F" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="215" y="279" width="108" height="6"> |
| 2568 |
<path d="M322.877 280.482a.938.938 0 0 0-.221-.806 1.07 1.07 0 0 0-.803-.353H216.599c-.409 0-.79.195-1.011.518a1.062 1.062 0 0 0-.078 1.071l1.142 2.311c.261.528.828.866 1.45.866h103.031c.579 0 1.076-.383 1.187-.916l.557-2.691z" fill="#fff" /> |
| 2569 |
</mask> |
| 2570 |
<g mask="url(#F)"> |
| 2571 |
<path d="M322.876 280.482a.94.94 0 0 0-.222-.806 1.077 1.077 0 0 0-.804-.353H216.596c-.409 0-.79.196-1.008.519-.219.32-.25.726-.079 1.071l1.14 2.31c.261.528.83.866 1.452.866H321.13c.58 0 1.076-.383 1.188-.916l.558-2.691z" fill="#1FDE91" /> |
| 2572 |
</g> |
| 2573 |
<mask id="G" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="221" y="281" width="22" height="49"> |
| 2574 |
<path d="M222.498 329.136a.883.883 0 0 1-.364-.078.95.95 0 0 1-.484-1.239l19.373-45.963a.915.915 0 0 1 1.212-.495c.469.207.685.76.484 1.239l-19.373 45.965a.92.92 0 0 1-.848.571z" fill="#fff" /> |
| 2575 |
</mask> |
| 2576 |
<g mask="url(#G)"> |
| 2577 |
<path d="M222.498 329.136a.883.883 0 0 1-.364-.078.95.95 0 0 1-.484-1.239l19.373-45.963a.915.915 0 0 1 1.212-.495c.469.207.685.76.484 1.239l-19.373 45.965a.92.92 0 0 1-.848.571z" fill="#1FDE91" /> |
| 2578 |
</g> |
| 2579 |
<mask id="H" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="224" y="281" width="22" height="49"> |
| 2580 |
<path d="M244.322 329.136a.922.922 0 0 1-.85-.571l-19.37-45.965a.95.95 0 0 1 .481-1.239.918.918 0 0 1 1.215.495l19.372 45.963a.95.95 0 0 1-.484 1.239.89.89 0 0 1-.364.078z" fill="#fff" /> |
| 2581 |
</mask> |
| 2582 |
<g mask="url(#H)"> |
| 2583 |
<path d="M244.322 329.136a.922.922 0 0 1-.85-.571l-19.37-45.965a.95.95 0 0 1 .481-1.239.918.918 0 0 1 1.215.495l19.372 45.963a.95.95 0 0 1-.484 1.239.89.89 0 0 1-.364.078z" fill="#1FDE91" /> |
| 2584 |
</g> |
| 2585 |
<mask id="I" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="297" y="281" width="23" height="49"> |
| 2586 |
<path d="M298.785 329.136a.907.907 0 0 1-.367-.078.95.95 0 0 1-.482-1.239l19.371-45.963a.918.918 0 0 1 1.214-.495c.469.207.685.76.484 1.239l-19.372 45.965a.924.924 0 0 1-.848.571z" fill="#fff" /> |
| 2587 |
</mask> |
| 2588 |
<g mask="url(#I)"> |
| 2589 |
<path d="M298.785 329.136a.914.914 0 0 1-.367-.078.95.95 0 0 1-.481-1.239l19.37-45.963a.918.918 0 0 1 1.214-.495c.469.207.686.76.486 1.238l-19.375 45.966a.922.922 0 0 1-.847.571z" fill="#1FDE91" /> |
| 2590 |
</g> |
| 2591 |
<mask id="J" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="300" y="281" width="22" height="49"> |
| 2592 |
<path d="M320.606 329.136a.924.924 0 0 1-.848-.571L300.386 282.6a.951.951 0 0 1 .484-1.239.917.917 0 0 1 1.214.495l19.37 45.963a.949.949 0 0 1-.481 1.239.907.907 0 0 1-.367.078z" fill="#fff" /> |
| 2593 |
</mask> |
| 2594 |
<g mask="url(#J)"> |
| 2595 |
<path d="M320.607 329.136a.923.923 0 0 1-.849-.571L300.385 282.6a.951.951 0 0 1 .483-1.239.918.918 0 0 1 1.215.495l19.37 45.963a.948.948 0 0 1-.48 1.239.9.9 0 0 1-.366.078z" fill="#1FDE91" /> |
| 2596 |
</g> |
| 2597 |
<mask id="K" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="37" y="31" width="272" height="201"> |
| 2598 |
<path d="m37.887 148.035 139.064 83.741 131.13-78.792V31H48.806l-10.92 117.035z" fill="#fff" /> |
| 2599 |
</mask> |
| 2600 |
<g mask="url(#K)"> |
| 2601 |
<path d="M270.976 66.156H58.964c-3.739 0-6.835 3.235-6.835 6.966v171.639h249.263V96.978l-30.416-30.822z" fill="#fff" /> |
| 2602 |
<path d="m301.274 96.979-27.82.24c-.742.007-1.316-.283-1.841-.8-.524-.519-.577-1.224-.577-1.959V66.37l30.238 30.609z" fill="#81909C" /> |
| 2603 |
</g> |
| 2604 |
<path d="M335.988 197.782v21.17c0 1.725-1.055 3.124-2.355 3.124h-77.309c-1.078 0-2.02.976-2.282 2.365l-1.389 7.372c-.182.976-1.208 1.059-1.479.115l-1.786-6.225c-.349-1.211-1.225-2.013-2.199-2.013h-3.323c-1.3 0-2.354-1.399-2.354-3.123v-21.762c0-1.715 1.043-3.11 2.334-3.124l89.767-1.022c1.311-.015 2.375 1.387 2.375 3.123z" fill="#fff" /> |
| 2605 |
<path d="M243.993 208.501c0 5.36 4.246 9.708 9.482 9.708 5.237 0 9.482-4.348 9.482-9.708 0-5.362-4.245-9.709-9.482-9.709-5.236 0-9.482 4.347-9.482 9.709z" fill="#1FDE91" /> |
| 2606 |
<mask id="L" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="250" y="201" width="7" height="8"> |
| 2607 |
<path d="M256.911 204.565c0 1.744-1.418 3.627-3.164 3.627-1.749 0-3.167-1.883-3.167-3.627 0-1.744 1.418-2.981 3.167-2.981 1.746 0 3.164 1.237 3.164 2.981z" fill="#fff" /> |
| 2608 |
</mask> |
| 2609 |
<g mask="url(#L)"> |
| 2610 |
<path d="M256.911 204.565c0 1.744-1.418 3.627-3.164 3.627-1.749 0-3.167-1.883-3.167-3.627 0-1.744 1.418-2.981 3.167-2.981 1.746 0 3.164 1.237 3.164 2.981z" fill="#242628" /> |
| 2611 |
</g> |
| 2612 |
<mask id="M" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="247" y="209" width="13" height="6"> |
| 2613 |
<path d="M249.817 214.908h7.728c.813 0 1.533-.526 1.782-1.299l.414-1.297a1.86 1.86 0 0 0-1.127-2.318c-3.146-1.148-6.398-1.001-9.728.105a1.859 1.859 0 0 0-1.194 2.253l.321 1.176c.221.814.959 1.38 1.804 1.38z" fill="#fff" /> |
| 2614 |
</mask> |
| 2615 |
<g mask="url(#M)"> |
| 2616 |
<path d="M249.817 214.908h7.728c.813 0 1.533-.526 1.782-1.299l.414-1.297a1.86 1.86 0 0 0-1.127-2.318c-3.146-1.148-6.398-1.001-9.728.105a1.859 1.859 0 0 0-1.194 2.253l.321 1.176c.221.814.959 1.38 1.804 1.38z" fill="#242628" /> |
| 2617 |
</g> |
| 2618 |
<mask id="N" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="268" y="209" width="61" height="4"> |
| 2619 |
<path d="M328.603 211.033c0 1.014-.858 1.837-1.917 1.837h-56.427c-1.059 0-1.917-.823-1.917-1.837s.858-1.834 1.917-1.834h56.427c1.059 0 1.917.82 1.917 1.834z" fill="#fff" /> |
| 2620 |
</mask> |
| 2621 |
<g mask="url(#N)"> |
| 2622 |
<path d="M328.601 211.033c0 1.014-.859 1.837-1.917 1.837h-56.426c-1.061 0-1.917-.823-1.917-1.837 0-1.013.856-1.833 1.917-1.833h56.426c1.058 0 1.917.82 1.917 1.833z" fill="#242628" /> |
| 2623 |
</g> |
| 2624 |
<mask id="O" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="268" y="215" width="34" height="4"> |
| 2625 |
<path d="M301.329 216.787c0 .922-.748 1.667-1.671 1.667h-29.583a1.668 1.668 0 1 1 0-3.336h29.583a1.67 1.67 0 0 1 1.671 1.669z" fill="#fff" /> |
| 2626 |
</mask> |
| 2627 |
<g mask="url(#O)"> |
| 2628 |
<path d="M301.328 216.788c0 .921-.748 1.667-1.67 1.667h-29.582a1.667 1.667 0 1 1 0-3.337h29.582c.922 0 1.67.746 1.67 1.67z" fill="#242628" /> |
| 2629 |
</g> |
| 2630 |
<mask id="P" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="303" y="215" width="26" height="4"> |
| 2631 |
<path d="M328.665 216.787a1.67 1.67 0 0 1-1.673 1.667h-21.35a1.667 1.667 0 1 1 0-3.336h21.35a1.67 1.67 0 0 1 1.673 1.669z" fill="#fff" /> |
| 2632 |
</mask> |
| 2633 |
<g mask="url(#P)"> |
| 2634 |
<path d="M328.666 216.787a1.67 1.67 0 0 1-1.674 1.667h-21.349a1.667 1.667 0 1 1 0-3.336h21.349a1.67 1.67 0 0 1 1.674 1.669z" fill="#242628" /> |
| 2635 |
</g> |
| 2636 |
<path d="M301.368 202.131a2.345 2.345 0 0 1-2.347 2.342h-28.487a2.345 2.345 0 0 1-2.349-2.342v-.191a2.345 2.345 0 0 1 2.349-2.342h28.487a2.346 2.346 0 0 1 2.347 2.342v.191zM82.198 81.84h9.38v.938h-9.38zM82.198 90.282h9.38v.938h-9.38zM82.198 82.778h.938v.938h-.938zM82.198 89.344h.938v.938h-.938zM90.64 89.344h.938v.938h-.938z" fill="#1FDE91" /> |
| 2637 |
<path fill="#1FDE91" d="M81.26 82.778h.938v7.504h-.938zM91.578 82.778h.938v7.504h-.938zM83.136 83.716h.938v.938h-.938zM89.702 83.716h.938v.938h-.938zM84.074 84.654h.938v.938h-.938zM88.764 84.654h.938v.938h-.938zM85.012 85.592h.938v.938h-.938zM87.826 85.592h.938v.938h-.938z" /> |
| 2638 |
<path fill="#1FDE91" d="M85.95 86.529h1.876v.938H85.95zM90.64 82.778h.938v.938h-.938z" /> |
| 2639 |
<rect x="81.26" y="151.468" width="182.938" height="14.146" rx="1.286" fill="#fff" /> |
| 2640 |
<rect x="86.26" y="157.058" width="33" height="2" rx="1" fill="#8B8D8F" /> |
| 2641 |
<rect x="80.869" y="151.077" width="183.72" height="14.928" rx="1.677" stroke="#242628" stroke-opacity=".5" stroke-width=".782" /> |
| 2642 |
<rect x="81.26" y="127.644" width="182.938" height="14.146" rx="1.286" fill="#fff" /> |
| 2643 |
<rect x="86.26" y="134.058" width="33" height="2" rx="1" fill="#8B8D8F" /> |
| 2644 |
<rect x="80.869" y="127.253" width="183.72" height="14.928" rx="1.677" stroke="#242628" stroke-opacity=".5" stroke-width=".782" /> |
| 2645 |
<rect x="81.26" y="103.726" width="182.938" height="14.146" rx="1.286" fill="#fff" /> |
| 2646 |
<rect x="86.26" y="110.058" width="33" height="2" rx="1" fill="#8B8D8F" /> |
| 2647 |
<rect x="80.869" y="103.335" width="183.72" height="14.928" rx="1.677" stroke="#242628" stroke-opacity=".5" stroke-width=".782" /> |
| 2648 |
<path d="M104.812 83.524c-1.74 0-2.736 1.26-2.736 3.156 0 1.956 1.128 3.024 2.748 3.024 1.524 0 2.448-.84 2.448-2.244v-.036h-2.652v-1.356h4.08V91h-1.296l-.096-1.008c-.48.672-1.476 1.14-2.664 1.14-2.46 0-4.176-1.788-4.176-4.488 0-2.664 1.74-4.56 4.38-4.56 2.004 0 3.552 1.164 3.804 2.952h-1.62c-.276-1.032-1.164-1.512-2.22-1.512zm7.983 7.632c-1.764 0-3-1.284-3-3.12 0-1.86 1.212-3.144 2.952-3.144 1.776 0 2.904 1.188 2.904 3.036v.444l-4.464.012c.108 1.044.66 1.572 1.632 1.572.804 0 1.332-.312 1.5-.876h1.356c-.252 1.296-1.332 2.076-2.88 2.076zm-.036-5.064c-.864 0-1.392.468-1.536 1.356h2.976c0-.816-.564-1.356-1.44-1.356zM118.78 91h-1.464v-4.704h-1.14v-1.224h1.14v-1.848h1.464v1.848h1.152v1.224h-1.152V91zm6.028-7.116a.889.889 0 0 1-.9-.888c0-.492.396-.876.9-.876.48 0 .876.384.876.876a.884.884 0 0 1-.876.888zM124.076 91v-5.928h1.464V91h-1.464zm4.441 0h-1.464v-5.928h1.356l.12.768c.372-.6 1.092-.948 1.896-.948 1.488 0 2.256.924 2.256 2.46V91h-1.464v-3.3c0-.996-.492-1.476-1.248-1.476-.9 0-1.452.624-1.452 1.584V91zm10.853 0h-1.464v-4.704h-1.14v-1.224h1.14v-1.848h1.464v1.848h1.152v1.224h-1.152V91zm1.655-2.976c0-1.848 1.332-3.12 3.168-3.12s3.168 1.272 3.168 3.12-1.332 3.12-3.168 3.12-3.168-1.272-3.168-3.12zm1.464 0c0 1.08.696 1.812 1.704 1.812s1.704-.732 1.704-1.812-.696-1.812-1.704-1.812-1.704.732-1.704 1.812zm9.912-2.952h1.464V91h-1.356l-.108-.792c-.36.564-1.128.948-1.92.948-1.368 0-2.172-.924-2.172-2.376v-3.708h1.464v3.192c0 1.128.444 1.584 1.26 1.584.924 0 1.368-.54 1.368-1.668v-3.108zm2.511 2.952c0-1.836 1.212-3.132 2.964-3.132 1.62 0 2.724.9 2.88 2.328h-1.464c-.168-.672-.66-1.02-1.356-1.02-.936 0-1.56.708-1.56 1.824s.576 1.812 1.512 1.812c.732 0 1.248-.36 1.404-1.008h1.476c-.18 1.38-1.332 2.328-2.88 2.328-1.8 0-2.976-1.248-2.976-3.132zm8.41 2.976h-1.464v-8.928h1.476v3.768c.372-.576 1.068-.948 1.92-.948 1.464 0 2.232.924 2.232 2.46V91h-1.464v-3.3c0-.996-.492-1.476-1.236-1.476-.924 0-1.464.648-1.464 1.536V91z" fill="#242628" /> |
| 2649 |
<path fill="#1FDE91" d="M158.26 148.058h2.736v54.717h-2.736z" /> |
| 2650 |
<path fill="#1FDE91" d="M160.995 150.794h2.736v2.736h-2.736zM171.939 161.737h2.736v2.736h-2.736zM182.883 172.681h2.736v2.736h-2.736zM166.468 156.265h2.736v2.736h-2.736zM177.411 167.209h2.736v2.736h-2.736zM188.354 178.152h2.736v2.736h-2.736zM169.203 189.096h2.736v2.736h-2.736z" /> |
| 2651 |
<path fill="#1FDE91" d="M166.468 191.831h2.736v2.736h-2.736zM163.731 194.567h2.736v2.736h-2.736zM160.995 197.303h2.736v2.736h-2.736zM180.146 183.624h2.736v8.208h-2.736zM182.883 191.831h2.736v5.472h-2.736zM174.675 191.831h2.736v5.472h-2.736zM171.939 186.36h2.736v5.472h-2.736zM185.618 197.303h2.736v5.472h-2.736zM177.411 197.303h2.736v5.472h-2.736zM188.354 202.775h2.736v5.472h-2.736zM180.146 202.775h2.736v5.472h-2.736zM163.731 153.53h2.736v2.736h-2.736zM174.675 164.473h2.736v2.736h-2.736zM185.618 175.416h2.736v2.736h-2.736zM169.203 159.001h2.736v2.736h-2.736zM180.146 169.945h2.736v2.736h-2.736zM180.146 180.888h13.679v2.736h-13.679zM182.883 208.247h5.472v2.736h-5.472z" /> |
| 2652 |
<defs> |
| 2653 |
<linearGradient id="g" x1="279.23" y1="322.708" x2="271.012" y2="285.385" gradientUnits="userSpaceOnUse"> |
| 2654 |
<stop stop-color="#FF928E" /> |
| 2655 |
<stop offset="1" stop-color="#FEB3B1" /> |
| 2656 |
</linearGradient> |
| 2657 |
<linearGradient id="j" x1="292.659" y1="233.667" x2="273.411" y2="280.645" gradientUnits="userSpaceOnUse"> |
| 2658 |
<stop stop-color="#FF928E" /> |
| 2659 |
<stop offset="1" stop-color="#FEB3B1" /> |
| 2660 |
</linearGradient> |
| 2661 |
<linearGradient id="o" x1="285.033" y1="237.355" x2="293.362" y2="257.803" gradientUnits="userSpaceOnUse"> |
| 2662 |
<stop stop-color="#FF928E" /> |
| 2663 |
<stop offset="1" stop-color="#FEB3B1" /> |
| 2664 |
</linearGradient> |
| 2665 |
<linearGradient id="q" x1="-716.313" y1="340.056" x2="-703.14" y2="338.684" gradientUnits="userSpaceOnUse"> |
| 2666 |
<stop stop-color="#FF928E" /> |
| 2667 |
<stop offset="1" stop-color="#FEB3B1" /> |
| 2668 |
</linearGradient> |
| 2669 |
<linearGradient id="t" x1="-715.046" y1="342.488" x2="-701.896" y2="341.119" gradientUnits="userSpaceOnUse"> |
| 2670 |
<stop stop-color="#FF928E" /> |
| 2671 |
<stop offset="1" stop-color="#FEB3B1" /> |
| 2672 |
</linearGradient> |
| 2673 |
<linearGradient id="v" x1="352.794" y1="272.43" x2="310.594" y2="268.666" gradientUnits="userSpaceOnUse"> |
| 2674 |
<stop stop-color="#FF928E" /> |
| 2675 |
<stop offset="1" stop-color="#FEB3B1" /> |
| 2676 |
</linearGradient> |
| 2677 |
<linearGradient id="y" x1="222.273" y1="156.367" x2="354.285" y2="289.941" gradientUnits="userSpaceOnUse"> |
| 2678 |
<stop stop-color="#B05B34" /> |
| 2679 |
<stop offset="1" stop-color="#3225BE" /> |
| 2680 |
</linearGradient> |
| 2681 |
</defs> |
| 2682 |
</svg> |
| 2683 |
</div> |
| 2684 |
</div> |
| 2685 |
<?php |
| 2686 |
} |
| 2687 |
} |
| 2688 |
} |
| 2689 |
|
| 2690 |
/** |
| 2691 |
* Page footer used on all admin pages. |
| 2692 |
* |
| 2693 |
* @access public |
| 2694 |
* @return void |
| 2695 |
* @since 1.0.0 |
| 2696 |
*/ |
| 2697 |
public function admin_page_footer() { |
| 2698 |
$current_page = get_current_screen()->id; |
| 2699 |
|
| 2700 |
if ( 'edit-wpzf-form' == $current_page || 'wpzf-form' == $current_page || 'edit-wpzf-submission' == $current_page || 'wpzf-submission' == $current_page || 'wpzf-form_page_wpzf-settings' == $current_page || 'wpzf-form_page_wpzoom-forms-pro-license' == $current_page || 'wpzf-form_page_wpzf-pro-page' == $current_page ) { |
| 2701 |
?> |
| 2702 |
<footer class="wpzoom-new-admin_settings-footer"> |
| 2703 |
<div class="wpzoom-new-admin_settings-footer-wrap"> |
| 2704 |
<h3 class="wpzoom-new-admin_settings-footer-logo"> |
| 2705 |
<a href="https://www.wpzoom.com/<?php echo $this->utm_source; ?>" target="_blank" title="<?php esc_html_e( 'WPZOOM - WordPress themes with modern features and professional support', 'wpzoom-forms' ); ?>"> |
| 2706 |
<?php _e( 'WPZOOM', 'wpzoom-forms' ); ?> |
| 2707 |
</a> |
| 2708 |
</h3> |
| 2709 |
|
| 2710 |
<ul class="wpzoom-new-admin_settings-footer-links"> |
| 2711 |
<li class="wpzoom-new-admin_settings-footer-links-themes"> |
| 2712 |
<a href="https://www.wpzoom.com/themes/<?php echo $this->utm_source; ?>" target="_blank" title="<?php _e( 'Check out our themes', 'wpzoom-forms' ); ?>"> |
| 2713 |
<?php _e( 'Our Themes', 'wpzoom-forms' ); ?> |
| 2714 |
</a> |
| 2715 |
</li> |
| 2716 |
|
| 2717 |
<li class="wpzoom-new-admin_settings-footer-links-themes"> |
| 2718 |
<a href="https://www.wpzoom.com/plugins/<?php echo $this->utm_source; ?>" target="_blank" title="<?php _e( 'Check out our plugins', 'wpzoom-forms' ); ?>"> |
| 2719 |
<?php _e( 'Our Plugins', 'wpzoom-forms' ); ?> |
| 2720 |
</a> |
| 2721 |
</li> |
| 2722 |
|
| 2723 |
<li class="wpzoom-new-admin_settings-footer-links-blog"> |
| 2724 |
<a href="https://www.wpzoom.com/blog/" target="_blank" title="<?php _e( 'See the latest updates on our blog', 'wpzoom-forms' ); ?>"> |
| 2725 |
<?php _e( 'Blog', 'wpzoom-forms' ); ?> |
| 2726 |
</a> |
| 2727 |
</li> |
| 2728 |
|
| 2729 |
<li class="wpzoom-new-admin_settings-footer-links-themes"> |
| 2730 |
<a href="https://www.wpzoom.com/documentation/wpzoom-forms/" target="_blank" title="<?php _e( 'Documentation', 'wpzoom-forms' ); ?>"> |
| 2731 |
<?php _e( 'Documentation', 'wpzoom-forms' ); ?> |
| 2732 |
</a> |
| 2733 |
</li> |
| 2734 |
|
| 2735 |
<li class="wpzoom-new-admin_settings-footer-links-support"> |
| 2736 |
<a href="https://www.wpzoom.com/support/" target="_blank" title="<?php _e( 'Get support', 'wpzoom-forms' ); ?>"> |
| 2737 |
<?php _e( 'Support', 'wpzoom-forms' ); ?> |
| 2738 |
</a> |
| 2739 |
</li> |
| 2740 |
</ul> |
| 2741 |
</div> |
| 2742 |
</footer> |
| 2743 |
<?php |
| 2744 |
} |
| 2745 |
} |
| 2746 |
|
| 2747 |
public function admin_body_class_filter( $classes ) { |
| 2748 |
$current_page = get_current_screen()->id; |
| 2749 |
|
| 2750 |
if ( 'edit-wpzf-form' == $current_page || 'wpzf-form' == $current_page || 'edit-wpzf-submission' == $current_page || 'wpzf-submission' == $current_page || 'wpzf-form_page_wpzf-settings' == $current_page || 'wpzf-form_page_wpzoom-forms-pro-license' == $current_page || 'wpzf-form_page_wpzf-pro-page' == $current_page || 'wpzf-form_page_wpzf-import' == $current_page ) { |
| 2751 |
$classes .= ' wpzoom-new-admin'; |
| 2752 |
} |
| 2753 |
|
| 2754 |
$forms_count = wp_count_posts( 'wpzf-form' ); |
| 2755 |
|
| 2756 |
if ( 'edit-wpzf-form' == $current_page && $forms_count->publish < 1 && $forms_count->draft < 1 && $forms_count->trash < 1 ) { |
| 2757 |
$classes .= ' wpzf-no-forms'; |
| 2758 |
} |
| 2759 |
|
| 2760 |
return $classes; |
| 2761 |
} |
| 2762 |
|
| 2763 |
/** |
| 2764 |
* Returns whether the given input is considered spam by checking it with Akismet. |
| 2765 |
* |
| 2766 |
* @since 1.0.4 |
| 2767 |
* @access public |
| 2768 |
* @param array $input The input to check for spam. |
| 2769 |
* @return bool Whether it is spam. |
| 2770 |
*/ |
| 2771 |
public function not_spam( $input ) { |
| 2772 |
|
| 2773 |
// Check if Akismet class exists and has required methods |
| 2774 |
if( class_exists( 'Akismet' ) && is_callable( array( 'Akismet', 'get_api_key' ) ) && is_callable( array( 'Akismet', 'http_post' ) ) ) { |
| 2775 |
|
| 2776 |
$request = array( |
| 2777 |
'comment_type' => 'contact-form', |
| 2778 |
'comment_author' => isset( $input['name'] ) ? $input['name'] : '', |
| 2779 |
'comment_author_email' => isset( $input['from'] ) ? $input['from'] : '', |
| 2780 |
'comment_author_url' => isset( $input['url'] ) ? $input['url'] : '', |
| 2781 |
'comment_content' => isset( $input['message'] ) ? $input['message'] : '', |
| 2782 |
'blog' => get_option( 'home' ), |
| 2783 |
'user_ip' => $this->get_remote_address(), |
| 2784 |
// phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| 2785 |
'user_agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) : null, |
| 2786 |
'referrer' => wp_get_referer() ? wp_get_referer() : null, |
| 2787 |
// phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| 2788 |
'permalink' => get_permalink(), |
| 2789 |
'blog_lang' => get_locale(), |
| 2790 |
'blog_charset' => get_bloginfo( 'charset' ), |
| 2791 |
'user_role' => Akismet::get_user_roles( get_current_user_id() ), |
| 2792 |
'is_test' => false, |
| 2793 |
|
| 2794 |
); |
| 2795 |
|
| 2796 |
$response = Akismet::http_post( build_query( $request ), 'comment-check' ); |
| 2797 |
|
| 2798 |
if( ! empty( $response ) && isset( $response[1] ) && 'true' === trim( $response[1] ) ) { |
| 2799 |
return false; |
| 2800 |
} |
| 2801 |
|
| 2802 |
} |
| 2803 |
|
| 2804 |
return true; |
| 2805 |
} |
| 2806 |
|
| 2807 |
/** |
| 2808 |
* Returns the remote address of the connected peer. |
| 2809 |
* |
| 2810 |
* @since 1.0.4 |
| 2811 |
* @access public |
| 2812 |
* @return string The remote address, or empty string on failure. |
| 2813 |
*/ |
| 2814 |
public function get_remote_address() { |
| 2815 |
$server_variable_keys = array( |
| 2816 |
'HTTP_CLIENT_IP', |
| 2817 |
'HTTP_X_FORWARDED_FOR', |
| 2818 |
'HTTP_X_FORWARDED', |
| 2819 |
'HTTP_X_CLUSTER_CLIENT_IP', |
| 2820 |
'HTTP_FORWARDED_FOR', |
| 2821 |
'HTTP_FORWARDED', |
| 2822 |
'REMOTE_ADDR' |
| 2823 |
); |
| 2824 |
|
| 2825 |
foreach ( $server_variable_keys as $key ) { |
| 2826 |
if ( array_key_exists( $key, $_SERVER ) === true ) { |
| 2827 |
foreach ( array_map( 'trim', explode( ',', $_SERVER[ $key ] ) ) as $ip ) { |
| 2828 |
if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) !== false ) { |
| 2829 |
return $ip; |
| 2830 |
} |
| 2831 |
} |
| 2832 |
} |
| 2833 |
} |
| 2834 |
|
| 2835 |
return ''; |
| 2836 |
} |
| 2837 |
|
| 2838 |
/** |
| 2839 |
* Callback that is triggered when a form is submitted on the frontend. |
| 2840 |
* |
| 2841 |
* @access public |
| 2842 |
* @return void |
| 2843 |
* @since 1.0.0 |
| 2844 |
*/ |
| 2845 |
public function action_form_post() { |
| 2846 |
$success = false; |
| 2847 |
$url = isset( $_POST['_wp_http_referer'] ) ? sanitize_text_field( wp_unslash( $_POST['_wp_http_referer'] ) ) : home_url(); |
| 2848 |
$form_id = -1; |
| 2849 |
$captcha_check_passed = true; |
| 2850 |
|
| 2851 |
if ( isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'wpzf_submit' ) ) { |
| 2852 |
$form_id = isset( $_POST['form_id'] ) ? intval( $_POST['form_id'] ) : -1; |
| 2853 |
$blocks = parse_blocks( $form_id > -1 ? get_post_field( 'post_content', $form_id, 'raw' ) : '' ); |
| 2854 |
|
| 2855 |
// Check if spam protection is fully configured and validate only then. |
| 2856 |
$captcha_config = $this->get_spam_protection_config(); |
| 2857 |
if ( 'recaptcha' === $captcha_config['active_service'] ) { |
| 2858 |
$captcha_check_passed = false; |
| 2859 |
$captcha = false; |
| 2860 |
$recaptchaType = $captcha_config['type']; |
| 2861 |
|
| 2862 |
if ( isset( $_POST['g-recaptcha-response'] ) ) { |
| 2863 |
$captcha = trim( sanitize_text_field( $_POST['g-recaptcha-response'] ) ); |
| 2864 |
} |
| 2865 |
|
| 2866 |
if( 'v3' == $recaptchaType && isset( $_POST['recaptcha_token'] ) ) { |
| 2867 |
$captcha = trim( sanitize_text_field( $_POST['recaptcha_token'] ) ); |
| 2868 |
} |
| 2869 |
|
| 2870 |
|
| 2871 |
if ( ! empty( $captcha ) ) { |
| 2872 |
$secret = false; |
| 2873 |
if ( 'v3' === $recaptchaType && ! empty( $captcha_config['recaptcha_v3_secret_key'] ) ) { |
| 2874 |
$secret = trim( $captcha_config['recaptcha_v3_secret_key'] ); |
| 2875 |
} else { |
| 2876 |
$secret = trim( $captcha_config['recaptcha_v2_secret_key'] ); |
| 2877 |
} |
| 2878 |
|
| 2879 |
if ( ! empty( $secret ) ) { |
| 2880 |
$response = file_get_contents( |
| 2881 |
sprintf( |
| 2882 |
'https://www.google.com/recaptcha/api/siteverify?secret=%1$s&response=%2$s&remoteip=%3$s', |
| 2883 |
$secret, |
| 2884 |
$captcha, |
| 2885 |
$_SERVER['REMOTE_ADDR'] |
| 2886 |
) |
| 2887 |
); |
| 2888 |
|
| 2889 |
if ( false !== $response && ! empty( $response ) ) { |
| 2890 |
$json = json_decode( $response ); |
| 2891 |
|
| 2892 |
if( 'v3' == $recaptchaType ) { |
| 2893 |
if ( null !== $json && is_object( $json ) && true === $json->success && $json->score >= 0.5 ) { |
| 2894 |
$captcha_check_passed = true; |
| 2895 |
} |
| 2896 |
} |
| 2897 |
else { |
| 2898 |
if ( null !== $json && is_object( $json ) && true === $json->success ) { |
| 2899 |
$captcha_check_passed = true; |
| 2900 |
} |
| 2901 |
} |
| 2902 |
|
| 2903 |
} |
| 2904 |
} |
| 2905 |
} |
| 2906 |
} elseif ( 'turnstile' === $captcha_config['active_service'] ) { |
| 2907 |
$captcha_check_passed = false; |
| 2908 |
|
| 2909 |
$captcha = isset( $_POST['cf-turnstile-response'] ) ? sanitize_text_field( wp_unslash( $_POST['cf-turnstile-response'] ) ) : ''; |
| 2910 |
if ( ! empty( $captcha ) ) { |
| 2911 |
$secret = trim( $captcha_config['turnstile_secret_key'] ); |
| 2912 |
$ip = $_SERVER['REMOTE_ADDR']; |
| 2913 |
|
| 2914 |
$url_path = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'; |
| 2915 |
$data = array( |
| 2916 |
'secret' => $secret, |
| 2917 |
'response' => $captcha, |
| 2918 |
'remoteip' => $ip |
| 2919 |
); |
| 2920 |
|
| 2921 |
$options = array( |
| 2922 |
'http' => array( |
| 2923 |
'method' => 'POST', |
| 2924 |
'content' => http_build_query($data) |
| 2925 |
) |
| 2926 |
); |
| 2927 |
$stream = stream_context_create($options); |
| 2928 |
$result = file_get_contents($url_path, false, $stream); |
| 2929 |
$result = json_decode($result, true); |
| 2930 |
|
| 2931 |
if ( intval( $result['success'] ) !== 1 ) { |
| 2932 |
$captcha_check_passed = false; |
| 2933 |
} else { |
| 2934 |
$captcha_check_passed = true; |
| 2935 |
} |
| 2936 |
} |
| 2937 |
} |
| 2938 |
|
| 2939 |
if ( $captcha_check_passed && count( $blocks ) > 0 ) { |
| 2940 |
$clean_site_name = sanitize_text_field( get_bloginfo( 'name' ) ); |
| 2941 |
$input_blocks = $this->get_input_blocks( $blocks ); |
| 2942 |
$form_method = get_post_meta( $form_id, '_form_method', true ) ?: 'email'; |
| 2943 |
$form_email = get_post_meta( $form_id, '_form_email', true ); |
| 2944 |
$form_subject = get_post_meta( $form_id, '_form_subject', true ); |
| 2945 |
$fallback_email = trim( get_option( 'admin_email' ) ); |
| 2946 |
$sendto = sanitize_email( false !== $form_email && ! empty( $form_email ) && filter_var( $form_email, FILTER_VALIDATE_EMAIL ) ? $form_email : $fallback_email ); |
| 2947 |
|
| 2948 |
if ( 'email' == $form_method || 'combined' == $form_method ) { |
| 2949 |
$email_body = '<html> |
| 2950 |
<head> |
| 2951 |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
| 2952 |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| 2953 |
<meta name="viewport" content="width=device-width"> |
| 2954 |
|
| 2955 |
<style type="text/css"> |
| 2956 |
body { |
| 2957 |
-ms-text-size-adjust: 100%;height: 100%; line-height: 1.6; |
| 2958 |
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; |
| 2959 |
} |
| 2960 |
a { color: #4477bd; } |
| 2961 |
a:hover { |
| 2962 |
color: #e2911a !important; |
| 2963 |
} |
| 2964 |
a:active { |
| 2965 |
color: #0d3d62 !important; |
| 2966 |
} |
| 2967 |
p{ |
| 2968 |
margin:10px 0; |
| 2969 |
padding:0; |
| 2970 |
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; |
| 2971 |
} |
| 2972 |
table{ |
| 2973 |
border-collapse:collapse; |
| 2974 |
} |
| 2975 |
h1,h2,h3,h4,h5,h6{ |
| 2976 |
display:block; |
| 2977 |
margin:0; |
| 2978 |
padding:0; |
| 2979 |
} |
| 2980 |
img,a img{ |
| 2981 |
border:0; |
| 2982 |
height:auto; |
| 2983 |
outline:none; |
| 2984 |
text-decoration:none; |
| 2985 |
} |
| 2986 |
body,#bodyTable,#bodyCell{ |
| 2987 |
height:100%; |
| 2988 |
margin:0; |
| 2989 |
padding:0; |
| 2990 |
} |
| 2991 |
#outlook a{ |
| 2992 |
padding:0; |
| 2993 |
} |
| 2994 |
img{ |
| 2995 |
-ms-interpolation-mode:bicubic; |
| 2996 |
} |
| 2997 |
table{ |
| 2998 |
mso-table-lspace:0pt; |
| 2999 |
mso-table-rspace:0pt; |
| 3000 |
} |
| 3001 |
p,a,li,td,blockquote{ |
| 3002 |
mso-line-height-rule:exactly; |
| 3003 |
} |
| 3004 |
a[href^=tel],a[href^=sms]{ |
| 3005 |
color:inherit; |
| 3006 |
cursor:default; |
| 3007 |
text-decoration:none; |
| 3008 |
} |
| 3009 |
p,a,li,td,body,table,blockquote{ |
| 3010 |
-ms-text-size-adjust:100%; |
| 3011 |
-webkit-text-size-adjust:100%; |
| 3012 |
} |
| 3013 |
a[x-apple-data-detectors]{ |
| 3014 |
color:inherit !important; |
| 3015 |
text-decoration:none !important; |
| 3016 |
font-size:inherit !important; |
| 3017 |
font-family:inherit !important; |
| 3018 |
font-weight:inherit !important; |
| 3019 |
line-height:inherit !important; |
| 3020 |
} |
| 3021 |
@media only screen and (max-width: 480px){ |
| 3022 |
body,table,td,p,a,li,blockquote{ |
| 3023 |
-webkit-text-size-adjust:none !important; |
| 3024 |
} |
| 3025 |
} |
| 3026 |
@media only screen and (max-width: 480px){ |
| 3027 |
body{ |
| 3028 |
width:100% !important; |
| 3029 |
min-width:100% !important; |
| 3030 |
} |
| 3031 |
} |
| 3032 |
</style> |
| 3033 |
</head> |
| 3034 |
<body style="height: 100%;margin: 0;padding: 0;width: 100%;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%;"> |
| 3035 |
<div style="font-family:-apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;box-sizing:border-box;font-size:14px;line-height:1.5;max-width:600px;overflow:visible;display:block;margin:0"> |
| 3036 |
<table width="100%" cellpadding="0" cellspacing="0" style="font-family:-apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;box-sizing:border-box;font-size:14px;line-height:1.5"> |
| 3037 |
<tbody> |
| 3038 |
<tr style="font-family:-apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;box-sizing:border-box;font-size:14px;line-height:1.5"> |
| 3039 |
<td style="font-family:-apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;box-sizing:border-box;font-size:14px;line-height:1.5;vertical-align:top;color:#222222;padding:25px" valign="top">'; |
| 3040 |
$replyto = ''; |
| 3041 |
$sbj = ''; |
| 3042 |
$raw_content = array( |
| 3043 |
'_wpzf_fields' => array() |
| 3044 |
); |
| 3045 |
|
| 3046 |
foreach ( $_REQUEST as $key => $value ) { |
| 3047 |
if ( strpos( $key, 'wpzf_' ) === 0 ) { |
| 3048 |
$id = substr( $key, 5 ); |
| 3049 |
$name = isset( $input_blocks[ $id ] ) ? $input_blocks[ $id ] : __( 'Unnamed Input', 'wpzoom-forms' ); |
| 3050 |
$value = is_array( $value ) ? implode( ', ', $value ) : $value; |
| 3051 |
|
| 3052 |
if ( 'wpzf_replyto' == $key ) { |
| 3053 |
$replyto = sanitize_text_field( $value ); |
| 3054 |
continue; |
| 3055 |
} elseif ( 'wpzf_subject' == $key ) { |
| 3056 |
$sbj = sanitize_text_field( $value ); |
| 3057 |
continue; |
| 3058 |
} |
| 3059 |
|
| 3060 |
$email_body .= '<strong>' . wp_kses_post( wp_unslash( $name ) ) . ':</strong><br/>' . nl2br( wp_kses_post( wp_unslash( $value ) ) ) . '<br/><br/>'; |
| 3061 |
$raw_content['_wpzf_fields'][ $name ] = sanitize_textarea_field( $value ); |
| 3062 |
} |
| 3063 |
} |
| 3064 |
|
| 3065 |
$fromaddr = ! empty( $replyto ) && isset( $_REQUEST[ $replyto ] ) ? sanitize_email( $_REQUEST[ $replyto ] ) : $sendto; |
| 3066 |
$cleanname = sanitize_text_field( get_bloginfo( 'name' ) ); |
| 3067 |
$subjectline = ! empty( $sbj ) && isset( $_REQUEST[ $sbj ] ) ? sanitize_text_field( wp_unslash( $_REQUEST[ $sbj ] ) ) : $form_subject; |
| 3068 |
$subjectline .= sprintf( __( ' - %s', 'wpzoom-forms' ), $cleanname ); |
| 3069 |
|
| 3070 |
$email_body = '<html style="background-color:#f4f3f3;"><body style="background-color:#f4f3f3;padding:2em;"><div style="background-color:#ffffff;width:70%;padding:2em;border-radius:10px;">' . preg_replace( '/<br\/><br\/><hr\/><br\/>$/is', '', $email_body ) . '</div></body></html>'; |
| 3071 |
|
| 3072 |
$headers = sprintf( |
| 3073 |
"Content-Type: text/html; charset=UTF-8\r\nFrom: %s <%s>\r\nReply-To: %s", |
| 3074 |
$cleanname, |
| 3075 |
$fromaddr, |
| 3076 |
$fromaddr |
| 3077 |
); |
| 3078 |
|
| 3079 |
$email_body .= '</td> |
| 3080 |
</tr> |
| 3081 |
</tbody></table> |
| 3082 |
</div> |
| 3083 |
|
| 3084 |
<div style="font-family:-apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;box-sizing:border-box;font-size:14px;line-height:1.5;max-width:600px;overflow:visible;display:block;margin:0"> |
| 3085 |
<table width="100%" cellpadding="0" cellspacing="0" style="font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;box-sizing:border-box;font-size:14px;line-height:1.5"> |
| 3086 |
<tbody><tr style="font-family:-apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;box-sizing:border-box;font-size:14px;line-height:1.5"> |
| 3087 |
<td style="font-family:-apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;box-sizing:border-box;font-size:14px;line-height:1.5;vertical-align:top;width:100%;clear:both;color:#777;border-top-width:1px;border-top-color:#d0d0d0;border-top-style:solid;padding:25px" valign="top"> |
| 3088 |
<p>Sent from <a href="' . esc_attr( get_bloginfo( 'url' ) ) . '">' . $cleanname . '</a> using the <strong>WPZOOM Forms</strong> plugin.</p> |
| 3089 |
<br style="font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;box-sizing:border-box;font-size:14px;line-height:1.5"> |
| 3090 |
</td> |
| 3091 |
</tr> |
| 3092 |
</tbody></table> |
| 3093 |
</div> |
| 3094 |
</body> |
| 3095 |
</html>'; |
| 3096 |
|
| 3097 |
$details = array( |
| 3098 |
'from' => $fromaddr, |
| 3099 |
'message' => $raw_content |
| 3100 |
); |
| 3101 |
|
| 3102 |
if ( $this->not_spam( $details ) ) { |
| 3103 |
$success = wp_mail( $sendto, $subjectline, $email_body, $headers ); |
| 3104 |
} |
| 3105 |
} |
| 3106 |
if ( 'db' == $form_method || 'combined' == $form_method ) { |
| 3107 |
$content = array( |
| 3108 |
'_wpzf_form_id' => $form_id, |
| 3109 |
'_wpzf_fields' => array() |
| 3110 |
); |
| 3111 |
|
| 3112 |
$replyto = ''; |
| 3113 |
$sbj = ''; |
| 3114 |
|
| 3115 |
foreach ( $_REQUEST as $key => $value ) { |
| 3116 |
if ( strpos( $key, 'wpzf_' ) === 0 ) { |
| 3117 |
$id = substr( $key, 5 ); |
| 3118 |
$name = isset( $input_blocks[ $id ] ) ? $input_blocks[ $id ] : __( 'Unnamed Input', 'wpzoom-forms' ); |
| 3119 |
$value = is_array( $value ) ? implode( ', ', $value ) : $value; |
| 3120 |
|
| 3121 |
if ( 'wpzf_replyto' == $key || 'wpzf_subject' == $key ) { |
| 3122 |
if ( 'wpzf_replyto' == $key ) { |
| 3123 |
$replyto = sanitize_text_field( $value ); |
| 3124 |
} elseif ( 'wpzf_subject' == $key ) { |
| 3125 |
$sbj = sanitize_text_field( $value ); |
| 3126 |
} |
| 3127 |
|
| 3128 |
continue; |
| 3129 |
} |
| 3130 |
|
| 3131 |
$content['_wpzf_fields'][ $name ] = sanitize_textarea_field( $value ); |
| 3132 |
} |
| 3133 |
} |
| 3134 |
|
| 3135 |
$details = array( |
| 3136 |
'from' => '', |
| 3137 |
'message' => $content |
| 3138 |
); |
| 3139 |
|
| 3140 |
if ( ! empty( $replyto ) ) { |
| 3141 |
$fromaddr = isset( $_REQUEST[ $replyto ] ) ? sanitize_email( $_REQUEST[ $replyto ] ) : $sendto; |
| 3142 |
$details['from'] = $fromaddr; |
| 3143 |
} |
| 3144 |
|
| 3145 |
if ( $this->not_spam( $details ) ) { |
| 3146 |
$success = false !== $content && 0 < wp_insert_post( array( |
| 3147 |
'post_type' => 'wpzf-submission', |
| 3148 |
'post_status' => 'publish', |
| 3149 |
'comment_status' => 'closed', |
| 3150 |
'ping_status' => 'closed', |
| 3151 |
'post_title' => __( 'Submission', 'wpzoom-forms' ), |
| 3152 |
'post_author' => 1, |
| 3153 |
'post_category' => array( 1 ), |
| 3154 |
'post_content' => __( 'Submission', 'wpzoom-forms' ), |
| 3155 |
'meta_input' => $content |
| 3156 |
) ); |
| 3157 |
} |
| 3158 |
} |
| 3159 |
} |
| 3160 |
} |
| 3161 |
|
| 3162 |
$redirect_url = urldecode( |
| 3163 |
add_query_arg( |
| 3164 |
array( |
| 3165 |
'success' => ( $success ? '1' : '0' ), |
| 3166 |
'wpzf_submitted_form' => $form_id, |
| 3167 |
), |
| 3168 |
$url |
| 3169 |
) |
| 3170 |
); |
| 3171 |
|
| 3172 |
wp_safe_redirect( |
| 3173 |
$redirect_url . ( $form_id > -1 ? '#wpzf-' . $form_id . '-notice' : '' ) |
| 3174 |
); |
| 3175 |
|
| 3176 |
exit; |
| 3177 |
} |
| 3178 |
|
| 3179 |
/** |
| 3180 |
* Filters a hierarchical array of Gutenberg blocks to return just the blocks added by this plugin. |
| 3181 |
* |
| 3182 |
* @access public |
| 3183 |
* @param array $blocks A hierarchical array of Gutenberg blocks. |
| 3184 |
* @return array |
| 3185 |
* @since 1.0.0 |
| 3186 |
*/ |
| 3187 |
public function get_input_blocks( $blocks ) { |
| 3188 |
$found = array(); |
| 3189 |
|
| 3190 |
if ( is_array( $blocks ) && count( $blocks ) > 0 ) { |
| 3191 |
for ( $i = 0; $i < count( $blocks ); $i++ ) { |
| 3192 |
$block = $blocks[ $i ]; |
| 3193 |
|
| 3194 |
if ( isset( $block['blockName'] ) && |
| 3195 |
preg_match( '/^wpzoom\-forms\//i', $block['blockName'] ) && |
| 3196 |
! preg_match( '/(label|submit)\-field$/i', $block['blockName'] ) && |
| 3197 |
isset( $block['attrs'] ) ) { |
| 3198 |
$attrs = $block['attrs']; |
| 3199 |
|
| 3200 |
if ( array_key_exists( 'id', $attrs ) && array_key_exists( 'name', $attrs ) ) { |
| 3201 |
$found[ $attrs['id'] ] = $attrs['name']; |
| 3202 |
} |
| 3203 |
} |
| 3204 |
|
| 3205 |
if ( isset( $block['innerBlocks'] ) ) { |
| 3206 |
$found = array_merge( $found, $this->get_input_blocks( $block['innerBlocks'] ) ); |
| 3207 |
} |
| 3208 |
} |
| 3209 |
} |
| 3210 |
|
| 3211 |
return $found; |
| 3212 |
} |
| 3213 |
|
| 3214 |
/** |
| 3215 |
* Returns the output for the form shortcode. |
| 3216 |
* |
| 3217 |
* @access public |
| 3218 |
* @param array|string $atts Shortcode attributes array or empty string. |
| 3219 |
* @param string $content The shortcode content, or null if not set. |
| 3220 |
* @param string $tag The shortcode name. |
| 3221 |
* @return string The shortcode output. |
| 3222 |
* @since 1.0.0 |
| 3223 |
*/ |
| 3224 |
public function shortcode_output( $atts, $content, $tag ) { |
| 3225 |
$id = is_array( $atts ) && array_key_exists( 'id', $atts ) ? intval( $atts['id'] ) : -1; |
| 3226 |
$output = ''; |
| 3227 |
|
| 3228 |
if ( $id > 0 ) { |
| 3229 |
wp_enqueue_script( 'wpzoom-forms-js-frontend-formblock' ); |
| 3230 |
wp_enqueue_style( 'wpzoom-forms-css-frontend-formblock' ); |
| 3231 |
|
| 3232 |
$output = $this->form_block_render( array( 'formId' => $id ) ); |
| 3233 |
} |
| 3234 |
|
| 3235 |
return $output; |
| 3236 |
} |
| 3237 |
|
| 3238 |
/** |
| 3239 |
* Register the PRO upsell notice with WPZOOM Notice Center. |
| 3240 |
* |
| 3241 |
* @since 1.3.4 |
| 3242 |
* @param array $notices Existing notices from the filter. |
| 3243 |
* @return array Notices with upsell notice added when applicable. |
| 3244 |
*/ |
| 3245 |
public function register_upsell_notice( $notices ) { |
| 3246 |
if ( ! is_array( $notices ) ) { |
| 3247 |
$notices = array(); |
| 3248 |
} |
| 3249 |
|
| 3250 |
// Don't add if PRO version is active. |
| 3251 |
if ( defined( 'WPZOOM_FORMS_PRO_VERSION' ) ) { |
| 3252 |
return $notices; |
| 3253 |
} |
| 3254 |
|
| 3255 |
$upsell_url = admin_url( 'edit.php?post_type=wpzf-form&page=wpzf-pro-page' ); |
| 3256 |
$pro_url = 'https://www.wpzoom.com/plugins/wpzoom-forms/?utm_source=wpadmin&utm_medium=wpzoom-forms-free&utm_campaign=upsell-notice'; |
| 3257 |
|
| 3258 |
$content = '<p>' . esc_html__( 'Unlock powerful features to build smarter, more flexible forms:', 'wpzoom-forms' ) . '</p>'; |
| 3259 |
$content .= '<ul>'; |
| 3260 |
$content .= '<li><strong>' . esc_html__( 'AI Form Generator', 'wpzoom-forms' ) . '</strong> — ' . esc_html__( 'Describe your form in simple words and let AI create it for you!', 'wpzoom-forms' ) . '</li>'; |
| 3261 |
$content .= '<li><strong>' . esc_html__( '30+ Pre-built Templates', 'wpzoom-forms' ) . '</strong> — ' . esc_html__( 'Healthcare, education, real estate, restaurant, HR, and more categories.', 'wpzoom-forms' ) . '</li>'; |
| 3262 |
$content .= '<li><strong>' . esc_html__( 'Conditional Logic', 'wpzoom-forms' ) . '</strong> — ' . esc_html__( 'Show or hide fields dynamically based on user selections.', 'wpzoom-forms' ) . '</li>'; |
| 3263 |
$content .= '<li><strong>' . esc_html__( 'Mailchimp Integration', 'wpzoom-forms' ) . '</strong> — ' . esc_html__( 'Automatically add subscribers to your Mailchimp audiences.', 'wpzoom-forms' ) . '</li>'; |
| 3264 |
$content .= '<li><strong>' . esc_html__( 'Import/Export Forms', 'wpzoom-forms' ) . '</strong> — ' . esc_html__( 'Easily transfer forms between sites or back up your work.', 'wpzoom-forms' ) . '</li>'; |
| 3265 |
$content .= '<li><strong>' . esc_html__( 'Export Submissions to CSV', 'wpzoom-forms' ) . '</strong> — ' . esc_html__( 'Download form submissions as CSV files for reporting.', 'wpzoom-forms' ) . '</li>'; |
| 3266 |
$content .= '</ul>'; |
| 3267 |
|
| 3268 |
$notices[] = array( |
| 3269 |
'id' => 'wpzf_upsell_pro', |
| 3270 |
'priority' => 10, |
| 3271 |
'heading' => __( 'Upgrade to WPZOOM Forms PRO', 'wpzoom-forms' ), |
| 3272 |
'content' => $content, |
| 3273 |
'icon' => array( |
| 3274 |
'type' => 'image', |
| 3275 |
'src' => plugins_url( 'dist/assets/admin/images/icon-forms.svg', __FILE__ ), |
| 3276 |
), |
| 3277 |
'primary_button' => array( |
| 3278 |
'label' => __( 'Upgrade to PRO', 'wpzoom-forms' ), |
| 3279 |
'url' => $pro_url, |
| 3280 |
'new_tab' => true, |
| 3281 |
), |
| 3282 |
'secondary_button' => array( |
| 3283 |
'label' => __( 'Learn More', 'wpzoom-forms' ), |
| 3284 |
'url' => $upsell_url, |
| 3285 |
'new_tab' => false, |
| 3286 |
), |
| 3287 |
'capability' => 'manage_options', |
| 3288 |
'screens' => array( 'dashboard', 'edit-wpzf-form', 'wpzf-form', 'edit-wpzf-submission', 'wpzf-submission' ), |
| 3289 |
'source' => 'WPZOOM Forms', |
| 3290 |
'conditions' => function () { |
| 3291 |
return ! get_option( 'wpzf_upsell_notice_dismissed' ); |
| 3292 |
}, |
| 3293 |
); |
| 3294 |
|
| 3295 |
return $notices; |
| 3296 |
} |
| 3297 |
} |
| 3298 |
|
| 3299 |
if( ! function_exists ( 'wpzoom_forms_load_files' ) ) { |
| 3300 |
function wpzoom_forms_load_files() { |
| 3301 |
|
| 3302 |
//Load Settings Panel |
| 3303 |
require_once 'classes/class-wpzoom-forms-settings-fields.php'; |
| 3304 |
require_once 'classes/class-wpzoom-forms-settings-page.php'; |
| 3305 |
require_once 'classes/class-wpzoom-forms-template-manager.php'; |
| 3306 |
require_once 'classes/class-wpzoom-forms-settings-upsell.php'; |
| 3307 |
|
| 3308 |
} |
| 3309 |
add_action( 'plugin_loaded', 'wpzoom_forms_load_files' ); |
| 3310 |
} |
| 3311 |
|
| 3312 |
if ( ! function_exists( 'wpzoom_forms_plugin_action_links' ) ) { |
| 3313 |
/** |
| 3314 |
* Plugin action links. |
| 3315 |
* |
| 3316 |
* Adds action links to the plugin list table. |
| 3317 |
* |
| 3318 |
* Fired by `plugin_action_links` filter. |
| 3319 |
* |
| 3320 |
* @since 1.3.5 |
| 3321 |
* |
| 3322 |
* @param array $links An array of plugin action links. |
| 3323 |
* |
| 3324 |
* @return array An array of plugin action links. |
| 3325 |
*/ |
| 3326 |
function wpzoom_forms_plugin_action_links( $links ) { |
| 3327 |
$settings_link = sprintf( |
| 3328 |
'<a href="%1$s">%2$s</a>', |
| 3329 |
admin_url( 'edit.php?post_type=wpzf-form&page=' . WPZOOM_FORMS_SETTINGS_PAGE ), |
| 3330 |
esc_html__( 'Settings', 'wpzoom-forms' ) |
| 3331 |
); |
| 3332 |
|
| 3333 |
array_unshift( $links, $settings_link ); |
| 3334 |
|
| 3335 |
$links['go_pro'] = sprintf( |
| 3336 |
'<a href="%1$s" target="_blank" class="wpzoom-forms-gopro" style="color:#2271b1;font-weight:bold;">%2$s → <span class="wpzoom-premium-badge" style="background-color: #2271b1; color: #fff; margin-left: 5px; font-size: 11px; min-height: 16px; border-radius: 8px; display: inline-block; font-weight: 600; line-height: 1.6; padding: 0 8px;">%3$s</span></a>', |
| 3337 |
'https://www.wpzoom.com/plugins/wpzoom-forms/?utm_source=wpadmin&utm_medium=plugin&utm_campaign=wpzoom-forms-free&utm_content=plugins-page', |
| 3338 |
esc_html__( 'UPGRADE', 'wpzoom-forms' ), |
| 3339 |
esc_html__( 'PRO', 'wpzoom-forms' ) |
| 3340 |
); |
| 3341 |
|
| 3342 |
return $links; |
| 3343 |
} |
| 3344 |
add_filter( 'plugin_action_links_' . WPZOOM_FORMS_PLUGIN_BASE, 'wpzoom_forms_plugin_action_links' ); |
| 3345 |
} |
| 3346 |
|
| 3347 |
/** |
| 3348 |
* Check if the Elementor Page Builder is enabled load the widget |
| 3349 |
*/ |
| 3350 |
if ( defined( 'ELEMENTOR_VERSION' ) && is_callable( 'Elementor\Plugin::instance' ) ) { |
| 3351 |
require_once 'elementor/wpzoom-forms-elementor.php'; |
| 3352 |
} |
| 3353 |
|
| 3354 |
/* -------------------------------------------------------------------------- */ |
| 3355 |
/* WPZOOM Forms v2 — schema-driven builder, REST API, renderer. */ |
| 3356 |
/* Coexists with the legacy block system: schema is the source of truth, the */ |
| 3357 |
/* legacy renderer remains a fallback during/after migration. */ |
| 3358 |
/* -------------------------------------------------------------------------- */ |
| 3359 |
require_once WPZOOM_FORMS_PATH . 'classes/class-wpzoom-forms-schema.php'; |
| 3360 |
require_once WPZOOM_FORMS_PATH . 'classes/class-wpzoom-forms-migration.php'; |
| 3361 |
require_once WPZOOM_FORMS_PATH . 'classes/class-wpzoom-forms-templates.php'; |
| 3362 |
require_once WPZOOM_FORMS_PATH . 'classes/class-wpzoom-forms-option-lists.php'; |
| 3363 |
require_once WPZOOM_FORMS_PATH . 'classes/class-wpzoom-forms-rest.php'; |
| 3364 |
require_once WPZOOM_FORMS_PATH . 'classes/class-wpzoom-forms-renderer.php'; |
| 3365 |
require_once WPZOOM_FORMS_PATH . 'classes/class-wpzoom-forms-submission-handler.php'; |
| 3366 |
require_once WPZOOM_FORMS_PATH . 'classes/class-wpzoom-forms-builder-page.php'; |
| 3367 |
require_once WPZOOM_FORMS_PATH . 'classes/class-wpzoom-forms-submission-view.php'; |
| 3368 |
|
| 3369 |
/** |
| 3370 |
* Shared embed helper used by the shortcode and the Elementor widget. |
| 3371 |
* |
| 3372 |
* Routes to the v2 renderer for forms saved through the new builder |
| 3373 |
* (_wpzf_schema postmeta present) and to the legacy block renderer for |
| 3374 |
* old block-based forms that have no schema yet. |
| 3375 |
* |
| 3376 |
* @param int $id Form post ID. |
| 3377 |
* @return string Rendered HTML. |
| 3378 |
*/ |
| 3379 |
function wpzoom_forms_render_embed( $id ) { |
| 3380 |
global $wpzoom_forms; |
| 3381 |
$id = (int) $id; |
| 3382 |
if ( $id < 1 ) { |
| 3383 |
return ''; |
| 3384 |
} |
| 3385 |
|
| 3386 |
if ( get_post_meta( $id, WPZOOM_Forms_Schema::META_KEY, true ) ) { |
| 3387 |
return WPZOOM_Forms_Renderer::render( $id ); |
| 3388 |
} |
| 3389 |
|
| 3390 |
// Legacy form — fall back to the block-based renderer. |
| 3391 |
if ( $wpzoom_forms ) { |
| 3392 |
wp_enqueue_script( 'wpzoom-forms-js-frontend-formblock' ); |
| 3393 |
wp_enqueue_style( 'wpzoom-forms-css-frontend-formblock' ); |
| 3394 |
return $wpzoom_forms->form_block_render( array( 'formId' => $id ) ); |
| 3395 |
} |
| 3396 |
|
| 3397 |
return ''; |
| 3398 |
} |
| 3399 |
|
| 3400 |
add_action( 'init', function() { |
| 3401 |
global $wpzoom_forms; |
| 3402 |
|
| 3403 |
// Take over form submission from the legacy handler. |
| 3404 |
if ( $wpzoom_forms ) { |
| 3405 |
remove_action( 'admin_post_wpzf_submit', array( $wpzoom_forms, 'action_form_post' ), 10 ); |
| 3406 |
remove_action( 'admin_post_nopriv_wpzf_submit', array( $wpzoom_forms, 'action_form_post' ), 10 ); |
| 3407 |
// The legacy class whitelist-resets $wp_meta_boxes to keep ONLY its own boxes — |
| 3408 |
// drop that hook so our submission-detail boxes survive. |
| 3409 |
remove_action( 'in_admin_header', array( $wpzoom_forms, 'remove_meta_boxes' ), 100 ); |
| 3410 |
// The legacy meta-box registration adds boxes we replace with our own. |
| 3411 |
remove_action( 'add_meta_boxes_wpzf-submission', array( $wpzoom_forms, 'add_meta_boxes' ), 10 ); |
| 3412 |
} |
| 3413 |
|
| 3414 |
// Disable the legacy template-picker modal — our React builder owns templates now. |
| 3415 |
if ( class_exists( 'WPZOOM_Forms_Template_Manager' ) ) { |
| 3416 |
$legacy_tm = WPZOOM_Forms_Template_Manager::instance(); |
| 3417 |
remove_action( 'admin_enqueue_scripts', array( $legacy_tm, 'scripts' ) ); |
| 3418 |
remove_action( 'admin_footer', array( $legacy_tm, 'modal_window' ) ); |
| 3419 |
remove_filter( 'default_content', array( $legacy_tm, 'default_form_content' ), 10 ); |
| 3420 |
} |
| 3421 |
|
| 3422 |
// Register meta so REST/admin can expose it. |
| 3423 |
register_post_meta( 'wpzf-form', WPZOOM_Forms_Schema::META_KEY, array( |
| 3424 |
'type' => 'string', |
| 3425 |
'single' => true, |
| 3426 |
'show_in_rest' => true, |
| 3427 |
'auth_callback' => function() { return current_user_can( 'edit_posts' ); }, |
| 3428 |
) ); |
| 3429 |
|
| 3430 |
( new WPZOOM_Forms_REST() )->register(); |
| 3431 |
( new WPZOOM_Forms_Submission_Handler() )->register(); |
| 3432 |
( new WPZOOM_Forms_Builder_Page() )->register(); |
| 3433 |
( new WPZOOM_Forms_Submission_View() )->register(); |
| 3434 |
}, 11 ); // After main class init (priority 9). |
| 3435 |
|
| 3436 |
/** |
| 3437 |
* Override the legacy shortcode to route through the shared embed helper, |
| 3438 |
* which selects v2 or legacy renderer based on whether _wpzf_schema exists. |
| 3439 |
*/ |
| 3440 |
add_action( 'init', function() { |
| 3441 |
remove_shortcode( 'wpzf_form' ); |
| 3442 |
add_shortcode( 'wpzf_form', function( $atts ) { |
| 3443 |
$atts = shortcode_atts( array( 'id' => 0 ), $atts, 'wpzf_form' ); |
| 3444 |
return wpzoom_forms_render_embed( (int) $atts['id'] ); |
| 3445 |
} ); |
| 3446 |
}, 12 ); |
| 3447 |
|
| 3448 |
/** |
| 3449 |
* For the form-block (Gutenberg block that embeds a form by id), substitute |
| 3450 |
* the render callback to use the new renderer. The block remains registered |
| 3451 |
* so existing content keeps working. We hook `render_block` (rather than |
| 3452 |
* patching the block type at registration time) because the main class |
| 3453 |
* registers the block at init:9, before our filters get a chance to attach. |
| 3454 |
*/ |
| 3455 |
add_filter( 'render_block', function( $block_content, $block ) { |
| 3456 |
if ( ! isset( $block['blockName'] ) || $block['blockName'] !== 'wpzoom-forms/form-block' ) return $block_content; |
| 3457 |
if ( is_admin() ) return $block_content; |
| 3458 |
$id = isset( $block['attrs']['formId'] ) ? (int) $block['attrs']['formId'] : 0; |
| 3459 |
if ( $id < 1 ) return $block_content; |
| 3460 |
|
| 3461 |
// Only switch to the v2 renderer when the form has been saved through the new |
| 3462 |
// builder (_wpzf_schema exists). Otherwise return the original block output |
| 3463 |
// unchanged so old forms keep all their existing styling and behaviour. |
| 3464 |
if ( ! get_post_meta( $id, WPZOOM_Forms_Schema::META_KEY, true ) ) { |
| 3465 |
return $block_content; |
| 3466 |
} |
| 3467 |
|
| 3468 |
// The render_callback (form_block_render) already built a <style> tag containing |
| 3469 |
// per-form color/border overrides from the block attributes (fieldBgColor, btnBgColor, …). |
| 3470 |
// Preserve it so those settings actually apply to the new renderer's output. |
| 3471 |
$block_styles = ''; |
| 3472 |
if ( preg_match( '/(<style\b[^>]*>.*?<\/style>)/is', $block_content, $m ) ) { |
| 3473 |
$block_styles = $m[1]; |
| 3474 |
} |
| 3475 |
|
| 3476 |
// Preserve the block's alignment (wide/full) on the rendered wrapper. The |
| 3477 |
// render callback no longer produces this output, so the align class set in |
| 3478 |
// the editor must be re-applied here or the frontend ignores it. |
| 3479 |
$align = isset( $block['attrs']['align'] ) ? $block['attrs']['align'] : ''; |
| 3480 |
$root_classes = ( $align && 'none' !== $align ) ? 'align' . $align : ''; |
| 3481 |
|
| 3482 |
return $block_styles . WPZOOM_Forms_Renderer::render( $id, $root_classes ); |
| 3483 |
}, 9, 2 ); |
| 3484 |
|
| 3485 |
|
| 3486 |
/** |
| 3487 |
* Customize the "All Forms" admin list a bit: |
| 3488 |
* - rename "Add New" wording, replace target link with our builder. |
| 3489 |
*/ |
| 3490 |
add_action( 'admin_head-edit.php', function() { |
| 3491 |
$screen = get_current_screen(); |
| 3492 |
if ( ! $screen || $screen->post_type !== 'wpzf-form' ) return; |
| 3493 |
?> |
| 3494 |
<style> |
| 3495 |
.wp-heading-inline + .page-title-action { background: #2271b1; color: #fff; border-color: #2271b1; } |
| 3496 |
.wp-heading-inline + .page-title-action:hover { background: #135e96; } |
| 3497 |
</style> |
| 3498 |
<script> |
| 3499 |
jQuery(function($){ |
| 3500 |
var btn = $('.page-title-action').first(); |
| 3501 |
if (btn.length) { |
| 3502 |
btn.attr('href', '<?php echo esc_js( admin_url( 'admin.php?page=wpzf-form-builder' ) ); ?>'); |
| 3503 |
btn.text(<?php echo wp_json_encode( __( 'Add New Form', 'wpzoom-forms' ) ); ?>); |
| 3504 |
} |
| 3505 |
}); |
| 3506 |
</script> |
| 3507 |
<?php |
| 3508 |
} ); |
| 3509 |
|
| 3510 |
/** |
| 3511 |
* Render the legacy "Upgrade to PRO" sidebar banner on the forms list page. |
| 3512 |
* The legacy template-manager modal used to ship this; we disabled that modal |
| 3513 |
* when replacing the form editor, so re-emit the banner here so the upsell |
| 3514 |
* isn't lost. |
| 3515 |
*/ |
| 3516 |
add_action( 'admin_footer-edit.php', function() { |
| 3517 |
$screen = get_current_screen(); |
| 3518 |
if ( ! $screen || $screen->post_type !== 'wpzf-form' ) return; |
| 3519 |
if ( ! class_exists( 'WPZOOM_Forms_Settings' ) ) return; |
| 3520 |
|
| 3521 |
$settings_class = new WPZOOM_Forms_Settings(); |
| 3522 |
$settings_class->upsell_banner(); // echoes the .wpzoom-forms-settings-upsell-container markup |
| 3523 |
?> |
| 3524 |
<script> |
| 3525 |
jQuery(function($){ |
| 3526 |
var $banner = $('.wpzoom-forms-settings-upsell-container').last(); |
| 3527 |
if ( ! $banner.length ) return; |
| 3528 |
// Drop the upsell into the right rail next to the posts table. |
| 3529 |
var $filter = $('#posts-filter'); |
| 3530 |
if ( $filter.length ) { |
| 3531 |
$banner.css({ 'float':'right', 'margin-left':'20px', 'max-width':'340px' }); |
| 3532 |
$filter.before( $banner ); |
| 3533 |
} |
| 3534 |
}); |
| 3535 |
</script> |
| 3536 |
<?php |
| 3537 |
} ); |
| 3538 |
|
| 3539 |
|