diff --git a/admin_credentials.txt b/admin_credentials.txt new file mode 100644 index 0000000..2157212 --- /dev/null +++ b/admin_credentials.txt @@ -0,0 +1,4 @@ +WordPress Admin Credentials: +URL: http://localhost/wp-admin +Username: admin +Password: xoPGNXoKaKVP1101 diff --git a/assets/vm-shot-2026-01-26T11-35-05-786Z.jpg b/assets/vm-shot-2026-01-26T11-35-05-786Z.jpg new file mode 100644 index 0000000..e9aa560 Binary files /dev/null and b/assets/vm-shot-2026-01-26T11-35-05-786Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T11-35-21-768Z.jpg b/assets/vm-shot-2026-01-26T11-35-21-768Z.jpg new file mode 100644 index 0000000..b08d88a Binary files /dev/null and b/assets/vm-shot-2026-01-26T11-35-21-768Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T11-35-30-801Z.jpg b/assets/vm-shot-2026-01-26T11-35-30-801Z.jpg new file mode 100644 index 0000000..b08d88a Binary files /dev/null and b/assets/vm-shot-2026-01-26T11-35-30-801Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T11-39-15-260Z.jpg b/assets/vm-shot-2026-01-26T11-39-15-260Z.jpg new file mode 100644 index 0000000..b08d88a Binary files /dev/null and b/assets/vm-shot-2026-01-26T11-39-15-260Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T11-54-24-787Z.jpg b/assets/vm-shot-2026-01-26T11-54-24-787Z.jpg new file mode 100644 index 0000000..54c0d09 Binary files /dev/null and b/assets/vm-shot-2026-01-26T11-54-24-787Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T11-54-38-389Z.jpg b/assets/vm-shot-2026-01-26T11-54-38-389Z.jpg new file mode 100644 index 0000000..b08d88a Binary files /dev/null and b/assets/vm-shot-2026-01-26T11-54-38-389Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T11-56-16-929Z.jpg b/assets/vm-shot-2026-01-26T11-56-16-929Z.jpg new file mode 100644 index 0000000..b08d88a Binary files /dev/null and b/assets/vm-shot-2026-01-26T11-56-16-929Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T13-33-13-586Z.jpg b/assets/vm-shot-2026-01-26T13-33-13-586Z.jpg new file mode 100644 index 0000000..d4da4ed Binary files /dev/null and b/assets/vm-shot-2026-01-26T13-33-13-586Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T13-41-42-697Z.jpg b/assets/vm-shot-2026-01-26T13-41-42-697Z.jpg new file mode 100644 index 0000000..4907d12 Binary files /dev/null and b/assets/vm-shot-2026-01-26T13-41-42-697Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T13-43-33-368Z.jpg b/assets/vm-shot-2026-01-26T13-43-33-368Z.jpg new file mode 100644 index 0000000..04a2163 Binary files /dev/null and b/assets/vm-shot-2026-01-26T13-43-33-368Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T14-46-07-412Z.jpg b/assets/vm-shot-2026-01-26T14-46-07-412Z.jpg new file mode 100644 index 0000000..384a225 Binary files /dev/null and b/assets/vm-shot-2026-01-26T14-46-07-412Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T14-58-14-516Z.jpg b/assets/vm-shot-2026-01-26T14-58-14-516Z.jpg new file mode 100644 index 0000000..384a225 Binary files /dev/null and b/assets/vm-shot-2026-01-26T14-58-14-516Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T14-58-25-621Z.jpg b/assets/vm-shot-2026-01-26T14-58-25-621Z.jpg new file mode 100644 index 0000000..384a225 Binary files /dev/null and b/assets/vm-shot-2026-01-26T14-58-25-621Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T14-58-42-937Z.jpg b/assets/vm-shot-2026-01-26T14-58-42-937Z.jpg new file mode 100644 index 0000000..384a225 Binary files /dev/null and b/assets/vm-shot-2026-01-26T14-58-42-937Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T15-04-37-249Z.jpg b/assets/vm-shot-2026-01-26T15-04-37-249Z.jpg new file mode 100644 index 0000000..54c0d09 Binary files /dev/null and b/assets/vm-shot-2026-01-26T15-04-37-249Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T15-04-49-828Z.jpg b/assets/vm-shot-2026-01-26T15-04-49-828Z.jpg new file mode 100644 index 0000000..b08d88a Binary files /dev/null and b/assets/vm-shot-2026-01-26T15-04-49-828Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T15-20-42-350Z.jpg b/assets/vm-shot-2026-01-26T15-20-42-350Z.jpg new file mode 100644 index 0000000..1cd6971 Binary files /dev/null and b/assets/vm-shot-2026-01-26T15-20-42-350Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T15-20-58-875Z.jpg b/assets/vm-shot-2026-01-26T15-20-58-875Z.jpg new file mode 100644 index 0000000..04a2163 Binary files /dev/null and b/assets/vm-shot-2026-01-26T15-20-58-875Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T15-21-19-157Z.jpg b/assets/vm-shot-2026-01-26T15-21-19-157Z.jpg new file mode 100644 index 0000000..5d5414a Binary files /dev/null and b/assets/vm-shot-2026-01-26T15-21-19-157Z.jpg differ diff --git a/assets/vm-shot-2026-01-26T15-21-45-883Z.jpg b/assets/vm-shot-2026-01-26T15-21-45-883Z.jpg new file mode 100644 index 0000000..1281974 Binary files /dev/null and b/assets/vm-shot-2026-01-26T15-21-45-883Z.jpg differ diff --git a/assets/vm-shot-2026-01-27T08-23-41-822Z.jpg b/assets/vm-shot-2026-01-27T08-23-41-822Z.jpg new file mode 100644 index 0000000..1cd6971 Binary files /dev/null and b/assets/vm-shot-2026-01-27T08-23-41-822Z.jpg differ diff --git a/assets/vm-shot-2026-01-27T08-23-57-939Z.jpg b/assets/vm-shot-2026-01-27T08-23-57-939Z.jpg new file mode 100644 index 0000000..1281974 Binary files /dev/null and b/assets/vm-shot-2026-01-27T08-23-57-939Z.jpg differ diff --git a/assets/vm-shot-2026-01-27T08-24-19-323Z.jpg b/assets/vm-shot-2026-01-27T08-24-19-323Z.jpg new file mode 100644 index 0000000..735e176 Binary files /dev/null and b/assets/vm-shot-2026-01-27T08-24-19-323Z.jpg differ diff --git a/assets/vm-shot-2026-01-27T08-24-32-288Z.jpg b/assets/vm-shot-2026-01-27T08-24-32-288Z.jpg new file mode 100644 index 0000000..99857ca Binary files /dev/null and b/assets/vm-shot-2026-01-27T08-24-32-288Z.jpg differ diff --git a/coaching_agreement.txt b/coaching_agreement.txt new file mode 100644 index 0000000..5cc6027 --- /dev/null +++ b/coaching_agreement.txt @@ -0,0 +1,15 @@ +## Coaching Agreement Summary + +By engaging in coaching services, you agree to the following terms: + +### 1. Liability Waiver +Coaching is for self-development purposes. You are responsible for all actions taken as a result of our sessions. You agree to hold [Your Name/Business Name] harmless from any damages arising from any action you take based on our coaching conversations. + +### 2. Confidentiality +All shared information during sessions will remain strictly confidential between coach and client, except where disclosure is required by law. + +### 3. Non-Compete / Professional Development +You agree not to establish yourself as a coaching service provider using the methodologies, materials, or frameworks shared within our sessions, unless agreed upon in writing in advance. + +--- +*A formal agreement document will be provided for your signature upon acceptance as a client.* diff --git a/pricing_content.html b/pricing_content.html new file mode 100644 index 0000000..f590b5e --- /dev/null +++ b/pricing_content.html @@ -0,0 +1,64 @@ + +
+

Coaching Packages

+ + + +

Coaching is a partnership, and I only work with clients who are fully committed to the process. Following a complimentary 30-minute preliminary consultation, we will determine if we are the right fit for each other.

+ + + +
+
+
+

Hourly

+ + + +

$650 / hour

+ + + +
  • Flexibility to book one hour at a time.
  • Focused, high-impact sessions.
+ + + + +
+
+ + + +
+
+

6-Month Engagement

+ + + +

$650 / month

+ + + +
  • 90-minute sessions per month.
  • Requires 6-month commitment, paid upfront.
  • Deep transformation focus.
+ + + + +
+
+
+ + + +

*All new clients must begin with a 30-minute preliminary consultation at no cost. Acceptance into a coaching engagement is subject to approval.

+ + + +

All coaching engagements require a signed agreement encompassing liability waiver, confidentiality, and non-compete terms.

+ +
+ \ No newline at end of file diff --git a/wp-content/mu-plugins/lead-form.php b/wp-content/mu-plugins/lead-form.php new file mode 100644 index 0000000..651f7d0 --- /dev/null +++ b/wp-content/mu-plugins/lead-form.php @@ -0,0 +1,79 @@ + [ + 'name' => 'Leads', + 'singular_name' => 'Lead', + ], + 'public' => false, + 'show_ui' => true, + 'menu_icon' => 'dashicons-groups', + 'supports' => ['title', 'editor', 'custom-fields'], + ]); +} +add_action('init', 'fl_register_lead_cpt'); + +function fl_lead_form_shortcode() { + if (!empty($_POST['fl_lead_nonce']) && wp_verify_nonce($_POST['fl_lead_nonce'], 'fl_lead_submit')) { + $name = sanitize_text_field($_POST['fl_name'] ?? ''); + $email = sanitize_email($_POST['fl_email'] ?? ''); + $role = sanitize_text_field($_POST['fl_role'] ?? ''); + $focus = sanitize_textarea_field($_POST['fl_focus'] ?? ''); + $q1 = sanitize_textarea_field($_POST['fl_q1'] ?? ''); + $q2 = sanitize_textarea_field($_POST['fl_q2'] ?? ''); + $q3 = sanitize_textarea_field($_POST['fl_q3'] ?? ''); + $q4 = sanitize_textarea_field($_POST['fl_q4'] ?? ''); + $q5 = sanitize_textarea_field($_POST['fl_q5'] ?? ''); + $agreement = isset($_POST['fl_agreement']) ? 'Agreed' : 'Not Agreed'; + + if ($name && $email) { + $lead_id = wp_insert_post([ + 'post_type' => 'fl_lead', + 'post_status' => 'publish', + 'post_title' => $name . ' — ' . $email, + 'post_content' => "Role/Context: $role\n\nFocus: $focus\n\n1. Tell me about yourself: $q1\n\n2. Signature strengths (friends): $q2\n\n3. Signature strengths (yourself): $q3\n\n4. Zone of genius (lose track of time): $q4\n\n5. Time you transformed yourself: $q5\n\nCoaching Agreement: $agreement", + ]); + if ($lead_id) { + return '
Thank you — your request was received. I will reply within 1–2 business days.
'; + } + } + return '
Please complete required fields and try again.
'; + } + + ob_start(); + ?> +
+ +


+


+


+


+


+


+


+


+


+

+

+
+ + .fl-lead-form input, .fl-lead-form textarea { width: 100%; padding: 10px 12px; border-radius: 10px; border: 1px solid #cbd5e1; } + .fl-lead-form button { background:#0f172a; color:#fff; padding:12px 18px; border-radius:999px; border:none; } + .fl-success { padding:12px 16px; background:#dcfce7; border:1px solid #86efac; border-radius:10px; } + .fl-error { padding:12px 16px; background:#fee2e2; border:1px solid #fca5a5; border-radius:10px; } + '; +} +add_action('wp_head', 'fl_lead_form_styles'); diff --git a/wp-content/plugins/contact-form-7/admin/admin.php b/wp-content/plugins/contact-form-7/admin/admin.php new file mode 100644 index 0000000..74162d7 --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/admin.php @@ -0,0 +1,759 @@ +service_exists() ) { + $integration = add_submenu_page( 'wpcf7', + __( 'Integration with External API', 'contact-form-7' ), + __( 'Integration', 'contact-form-7' ) + . wpcf7_admin_menu_change_notice( 'wpcf7-integration' ), + 'wpcf7_manage_integration', + 'wpcf7-integration', + 'wpcf7_admin_integration_page' + ); + + add_action( 'load-' . $integration, 'wpcf7_load_integration_page', 10, 0 ); + } +} + + +function wpcf7_admin_menu_change_notice( $menu_slug = '' ) { + $counts = apply_filters( 'wpcf7_admin_menu_change_notice', + array( + 'wpcf7' => 0, + 'wpcf7-new' => 0, + 'wpcf7-integration' => 0, + ) + ); + + if ( empty( $menu_slug ) ) { + $count = absint( array_sum( $counts ) ); + } elseif ( isset( $counts[$menu_slug] ) ) { + $count = absint( $counts[$menu_slug] ); + } else { + $count = 0; + } + + if ( $count ) { + return sprintf( + ' %2$s', + $count, + esc_html( number_format_i18n( $count ) ) + ); + } + + return ''; +} + + +add_action( + 'admin_enqueue_scripts', + 'wpcf7_admin_enqueue_scripts', + 10, 1 +); + +function wpcf7_admin_enqueue_scripts( $hook_suffix ) { + if ( false === strpos( $hook_suffix, 'wpcf7' ) ) { + return; + } + + wp_enqueue_style( 'contact-form-7-admin', + wpcf7_plugin_url( 'admin/includes/css/styles.css' ), + array(), WPCF7_VERSION, 'all' + ); + + if ( wpcf7_is_rtl() ) { + wp_enqueue_style( 'contact-form-7-admin-rtl', + wpcf7_plugin_url( 'admin/includes/css/styles-rtl.css' ), + array(), WPCF7_VERSION, 'all' + ); + } + + $assets = include wpcf7_plugin_path( 'admin/includes/js/index.asset.php' ); + + $assets = wp_parse_args( $assets, array( + 'dependencies' => array(), + 'version' => WPCF7_VERSION, + ) ); + + wp_enqueue_script( 'wpcf7-admin', + wpcf7_plugin_url( 'admin/includes/js/index.js' ), + $assets['dependencies'], + $assets['version'], + array( 'in_footer' => true ) + ); + + wp_set_script_translations( 'wpcf7-admin', 'contact-form-7' ); + + $wpcf7_obj = array( + 'apiSettings' => array( + 'root' => sanitize_url( rest_url( 'contact-form-7/v1' ) ), + 'namespace' => 'contact-form-7/v1', + ), + ); + + $post = wpcf7_get_current_contact_form(); + + if ( $post ) { + $wpcf7_obj = array_merge( $wpcf7_obj, array( + 'nonce' => array( + 'save' => wp_create_nonce( + sprintf( + 'wpcf7-save-contact-form_%s', + $post->initial() ? -1 : $post->id() + ) + ), + 'copy' => wp_create_nonce( + sprintf( + 'wpcf7-copy-contact-form_%s', + $post->initial() ? -1 : $post->id() + ) + ), + 'delete' => wp_create_nonce( + sprintf( + 'wpcf7-delete-contact-form_%s', + $post->initial() ? -1 : $post->id() + ) + ), + ), + 'configValidator' => array( + 'errors' => array(), + 'docUrl' => WPCF7_ConfigValidator::get_doc_link(), + ), + ) ); + + if ( + current_user_can( 'wpcf7_edit_contact_form', $post->id() ) and + wpcf7_validate_configuration() + ) { + $config_validator = new WPCF7_ConfigValidator( $post ); + $config_validator->restore(); + + $wpcf7_obj['configValidator'] = array_merge( + $wpcf7_obj['configValidator'], + array( + 'errors' => $config_validator->collect_error_messages( + array( 'decodes_html_entities' => true ) + ), + ) + ); + } + } + + wp_add_inline_script( 'wpcf7-admin', + sprintf( + 'var wpcf7 = %s;', + wp_json_encode( $wpcf7_obj, JSON_PRETTY_PRINT ) + ), + 'before' + ); +} + + +add_filter( + 'set_screen_option_wpcf7_contact_forms_per_page', + static function ( $result, $option, $value ) { + $wpcf7_screens = array( + 'wpcf7_contact_forms_per_page', + ); + + if ( in_array( $option, $wpcf7_screens, true ) ) { + $result = $value; + } + + return $result; + }, + 10, 3 +); + + +function wpcf7_load_contact_form_admin() { + global $plugin_page; + + $action = wpcf7_current_action(); + + do_action( 'wpcf7_admin_load', + wpcf7_superglobal_get( 'page' ), + $action + ); + + if ( 'save' === $action ) { + $id = wpcf7_superglobal_post( 'post_ID', '-1' ); + + check_admin_referer( 'wpcf7-save-contact-form_' . $id ); + + if ( ! current_user_can( 'wpcf7_edit_contact_form', $id ) ) { + wp_die( + esc_html( __( 'You are not allowed to edit this item.', 'contact-form-7' ) ) + ); + } + + $contact_form = wpcf7_save_contact_form( + array_merge( + wp_unslash( $_REQUEST ), + array( + 'id' => $id, + 'title' => wpcf7_superglobal_post( 'post_title', null ), + 'locale' => wpcf7_superglobal_post( 'wpcf7-locale', null ), + 'form' => wpcf7_superglobal_post( 'wpcf7-form', '' ), + 'mail' => wpcf7_superglobal_post( 'wpcf7-mail', array() ), + 'mail_2' => wpcf7_superglobal_post( 'wpcf7-mail-2', array() ), + 'messages' => wpcf7_superglobal_post( 'wpcf7-messages', array() ), + 'additional_settings' => wpcf7_superglobal_post( 'wpcf7-additional-settings', '' ), + ) + ) + ); + + if ( $contact_form and wpcf7_validate_configuration() ) { + $config_validator = new WPCF7_ConfigValidator( $contact_form ); + $config_validator->validate(); + $config_validator->save(); + } + + $query = array( + 'post' => $contact_form ? $contact_form->id() : 0, + 'active-tab' => wpcf7_canonicalize_name( + wpcf7_superglobal_post( 'active-tab' ) + ), + ); + + if ( ! $contact_form ) { + $query['message'] = 'failed'; + } elseif ( -1 === (int) $id ) { + $query['message'] = 'created'; + } else { + $query['message'] = 'saved'; + } + + $redirect_to = add_query_arg( $query, menu_page_url( 'wpcf7', false ) ); + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( 'copy' === $action ) { + $id = absint( $_POST['post_ID'] ?? $_REQUEST['post'] ?? '' ); + + check_admin_referer( 'wpcf7-copy-contact-form_' . $id ); + + if ( ! current_user_can( 'wpcf7_edit_contact_form', $id ) ) { + wp_die( + esc_html( __( 'You are not allowed to edit this item.', 'contact-form-7' ) ) + ); + } + + $query = array(); + + if ( $contact_form = wpcf7_contact_form( $id ) ) { + $new_contact_form = $contact_form->copy(); + $new_contact_form->save(); + + $query['post'] = $new_contact_form->id(); + $query['message'] = 'created'; + } + + $redirect_to = add_query_arg( $query, menu_page_url( 'wpcf7', false ) ); + + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( 'delete' === $action ) { + $nonce_action = 'bulk-posts'; + + if ( + $post_id = wpcf7_superglobal_post( 'post_ID' ) or + ! is_array( $post_id = wpcf7_superglobal_request( 'post', array() ) ) + ) { + $nonce_action = sprintf( 'wpcf7-delete-contact-form_%s', $post_id ); + } + + check_admin_referer( $nonce_action ); + + $posts = array_filter( (array) $post_id ); + + $deleted = 0; + + foreach ( $posts as $post ) { + $post = WPCF7_ContactForm::get_instance( $post ); + + if ( empty( $post ) ) { + continue; + } + + if ( ! current_user_can( 'wpcf7_delete_contact_form', $post->id() ) ) { + wp_die( + esc_html( __( 'You are not allowed to delete this item.', 'contact-form-7' ) ) + ); + } + + if ( ! $post->delete() ) { + wp_die( + esc_html( __( 'Error in deleting.', 'contact-form-7' ) ) + ); + } + + $deleted += 1; + } + + $query = array(); + + if ( ! empty( $deleted ) ) { + $query['message'] = 'deleted'; + } + + $redirect_to = add_query_arg( $query, menu_page_url( 'wpcf7', false ) ); + + wp_safe_redirect( $redirect_to ); + exit(); + } + + $post = null; + + if ( 'wpcf7-new' === $plugin_page ) { + $post = WPCF7_ContactForm::get_template( array( + 'locale' => wpcf7_superglobal_get( 'locale', null ), + ) ); + } elseif ( $post_id = wpcf7_superglobal_get( 'post' ) ) { + $post = WPCF7_ContactForm::get_instance( $post_id ); + } + + $current_screen = get_current_screen(); + + $help_tabs = new WPCF7_Help_Tabs( $current_screen ); + + if ( $post and current_user_can( 'wpcf7_edit_contact_form', $post->id() ) ) { + $help_tabs->set_help_tabs( 'edit' ); + } else { + $help_tabs->set_help_tabs( 'list' ); + + if ( ! class_exists( 'WPCF7_Contact_Form_List_Table' ) ) { + require_once WPCF7_PLUGIN_DIR . '/admin/includes/class-contact-forms-list-table.php'; + } + + add_filter( + 'manage_' . $current_screen->id . '_columns', + array( 'WPCF7_Contact_Form_List_Table', 'define_columns' ), + 10, 0 + ); + + add_screen_option( 'per_page', array( + 'default' => 20, + 'option' => 'wpcf7_contact_forms_per_page', + ) ); + } +} + + +function wpcf7_admin_management_page() { + if ( $post = wpcf7_get_current_contact_form() ) { + $post_id = $post->initial() ? -1 : $post->id(); + + require_once WPCF7_PLUGIN_DIR . '/admin/includes/editor.php'; + require_once WPCF7_PLUGIN_DIR . '/admin/edit-contact-form.php'; + return; + } + + if ( + 'validate' === wpcf7_current_action() and + wpcf7_validate_configuration() and + current_user_can( 'wpcf7_edit_contact_forms' ) + ) { + wpcf7_admin_bulk_validate_page(); + return; + } + + $list_table = new WPCF7_Contact_Form_List_Table(); + $list_table->prepare_items(); + + $formatter = new WPCF7_HTMLFormatter( array( + 'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array( + 'form' => array( + 'method' => true, + ), + ) ), + ) ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'wrap', + 'id' => 'wpcf7-contact-form-list-table', + ) ); + + $formatter->append_start_tag( 'h1', array( + 'class' => 'wp-heading-inline', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Contact Forms', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h1' ); + + if ( current_user_can( 'wpcf7_edit_contact_forms' ) ) { + $formatter->append_preformatted( + wpcf7_link( + menu_page_url( 'wpcf7-new', false ), + __( 'Add Contact Form', 'contact-form-7' ), + array( 'class' => 'page-title-action' ) + ) + ); + } + + if ( $search_keyword = wpcf7_superglobal_request( 's' ) ) { + $formatter->append_start_tag( 'span', array( + 'class' => 'subtitle', + ) ); + + $formatter->append_preformatted( + sprintf( + /* translators: %s: Search query. */ + __( 'Search results for: %s', 'contact-form-7' ), + esc_html( $search_keyword ) + ) + ); + + $formatter->end_tag( 'span' ); + } + + $formatter->append_start_tag( 'hr', array( + 'class' => 'wp-header-end', + ) ); + + $formatter->call_user_func( static function () { + do_action( 'wpcf7_admin_warnings', + 'wpcf7', wpcf7_current_action(), null + ); + + wpcf7_welcome_panel(); + + do_action( 'wpcf7_admin_notices', + 'wpcf7', wpcf7_current_action(), null + ); + } ); + + $formatter->append_start_tag( 'form', array( + 'method' => 'get', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'name' => 'page', + 'value' => wpcf7_superglobal_request( 'page' ), + ) ); + + $formatter->call_user_func( static function () use ( $list_table ) { + $list_table->search_box( + __( 'Search Contact Forms', 'contact-form-7' ), + 'wpcf7-contact' + ); + + $list_table->display(); + } ); + + $formatter->print(); +} + + +function wpcf7_admin_add_new_page() { + $post = wpcf7_get_current_contact_form(); + + if ( ! $post ) { + $post = WPCF7_ContactForm::get_template(); + } + + $post_id = -1; + + require_once WPCF7_PLUGIN_DIR . '/admin/includes/editor.php'; + require_once WPCF7_PLUGIN_DIR . '/admin/edit-contact-form.php'; +} + + +function wpcf7_load_integration_page() { + do_action( 'wpcf7_admin_load', + wpcf7_superglobal_get( 'page' ), + wpcf7_current_action() + ); + + $integration = WPCF7_Integration::get_instance(); + + if ( + $service_name = wpcf7_superglobal_request( 'service' ) and + $integration->service_exists( $service_name ) + ) { + $service = $integration->get_service( $service_name ); + $service->load( wpcf7_current_action() ); + } + + $help_tabs = new WPCF7_Help_Tabs( get_current_screen() ); + $help_tabs->set_help_tabs( 'integration' ); +} + + +function wpcf7_admin_integration_page() { + $integration = WPCF7_Integration::get_instance(); + + $service_name = wpcf7_superglobal_request( 'service' ); + $service = null; + + if ( $service_name and $integration->service_exists( $service_name ) ) { + $service = $integration->get_service( $service_name ); + } + + $formatter = new WPCF7_HTMLFormatter( array( + 'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array( + 'form' => array( + 'action' => true, + 'method' => true, + ), + ) ), + ) ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'wrap', + 'id' => 'wpcf7-integration', + ) ); + + $formatter->append_start_tag( 'h1' ); + + $formatter->append_preformatted( + esc_html( __( 'Integration with External API', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h1' ); + + $formatter->append_start_tag( 'p' ); + + $formatter->append_preformatted( + sprintf( + /* translators: %s: URL to support page about integration with external APIs */ + __( 'You can expand the possibilities of your contact forms by integrating them with external services. For details, see Integration with external APIs.', 'contact-form-7' ), + __( 'https://contactform7.com/integration-with-external-apis/', 'contact-form-7' ) + ) + ); + + $formatter->end_tag( 'p' ); + + $formatter->call_user_func( + static function () use ( $integration, $service, $service_name ) { + do_action( 'wpcf7_admin_warnings', + 'wpcf7-integration', wpcf7_current_action(), $service + ); + + do_action( 'wpcf7_admin_notices', + 'wpcf7-integration', wpcf7_current_action(), $service + ); + + if ( $service ) { + $message = wpcf7_superglobal_request( 'message' ); + $service->admin_notice( $message ); + + $integration->list_services( array( + 'include' => $service_name, + ) ); + } else { + $integration->list_services(); + } + } + ); + + $formatter->print(); +} + + +add_action( 'wpcf7_admin_notices', 'wpcf7_admin_updated_message', 10, 3 ); + +function wpcf7_admin_updated_message( $page, $action, $object ) { + if ( ! in_array( $page, array( 'wpcf7', 'wpcf7-new' ), true ) ) { + return; + } + + $message_type = wpcf7_superglobal_request( 'message' ); + + if ( ! $message_type ) { + return; + } + + $notice_type = 'success'; + + if ( 'created' === $message_type ) { + $message = __( 'Contact form created.', 'contact-form-7' ); + } elseif ( 'saved' === $message_type ) { + $message = __( 'Contact form saved.', 'contact-form-7' ); + } elseif ( 'deleted' === $message_type ) { + $message = __( 'Contact form deleted.', 'contact-form-7' ); + } elseif ( 'failed' === $message_type ) { + $notice_type = 'error'; + $message = __( 'There was an error saving the contact form.', 'contact-form-7' ); + } elseif ( 'validated' === $message_type ) { + $bulk_validate = WPCF7::get_option( 'bulk_validate', array() ); + $count_invalid = absint( $bulk_validate['count_invalid'] ?? 0 ); + + if ( $count_invalid ) { + $notice_type = 'warning'; + + $message = sprintf( + /* translators: %s: number of contact forms */ + _n( + 'Configuration validation completed. %s invalid contact form was found.', + 'Configuration validation completed. %s invalid contact forms were found.', + $count_invalid, 'contact-form-7' + ), + number_format_i18n( $count_invalid ) + ); + } else { + $message = __( 'Configuration validation completed. No invalid contact form was found.', 'contact-form-7' ); + } + } + + if ( ! empty( $message ) ) { + wp_admin_notice( + $message, + array( 'type' => $notice_type ) + ); + } +} + + +add_filter( 'plugin_action_links', 'wpcf7_plugin_action_links', 10, 2 ); + +function wpcf7_plugin_action_links( $links, $file ) { + if ( WPCF7_PLUGIN_BASENAME !== $file ) { + return $links; + } + + if ( ! current_user_can( 'wpcf7_read_contact_forms' ) ) { + return $links; + } + + $settings_link = wpcf7_link( + menu_page_url( 'wpcf7', false ), + __( 'Settings', 'contact-form-7' ) + ); + + array_unshift( $links, $settings_link ); + + return $links; +} + + +add_action( 'wpcf7_admin_warnings', 'wpcf7_old_wp_version_error', 10, 3 ); + +function wpcf7_old_wp_version_error( $page, $action, $object ) { + $wp_version = get_bloginfo( 'version' ); + + if ( version_compare( $wp_version, WPCF7_REQUIRED_WP_VERSION, '<' ) ) { + wp_admin_notice( + sprintf( + /* translators: 1: version of Contact Form 7, 2: version of WordPress, 3: URL */ + __( 'Contact Form 7 %1$s requires WordPress %2$s or higher. Please update WordPress first.', 'contact-form-7' ), + WPCF7_VERSION, + WPCF7_REQUIRED_WP_VERSION, + admin_url( 'update-core.php' ) + ), + array( 'type' => 'warning' ) + ); + } +} + + +add_action( 'wpcf7_admin_warnings', 'wpcf7_not_allowed_to_edit', 10, 3 ); + +function wpcf7_not_allowed_to_edit( $page, $action, $object ) { + if ( $object instanceof WPCF7_ContactForm ) { + $contact_form = $object; + } else { + return; + } + + if ( ! current_user_can( 'wpcf7_edit_contact_form', $contact_form->id() ) ) { + wp_admin_notice( + __( 'You are not allowed to edit this contact form.', 'contact-form-7' ), + array( 'type' => 'warning' ) + ); + } +} + + +add_action( 'wpcf7_admin_warnings', 'wpcf7_ctct_deprecated_warning', 10, 3 ); + +function wpcf7_ctct_deprecated_warning( $page, $action, $object ) { + $service = WPCF7_ConstantContact::get_instance(); + + if ( $service->is_active() ) { + wp_admin_notice( + __( 'Contact Form 7 has completed the removal of the Constant Contact integration. We recommend Brevo as an alternative.', 'contact-form-7' ), + array( 'type' => 'warning' ) + ); + } +} + + +add_action( 'wpcf7_admin_warnings', 'wpcf7_captcha_future_warning', 10, 3 ); + +function wpcf7_captcha_future_warning( $page, $action, $object ) { + $service = WPCF7_RECAPTCHA::get_instance(); + + if ( $service->is_active() ) { + wp_admin_notice( + __( 'Attention reCAPTCHA users: Google attempts to make all reCAPTCHA users migrate to reCAPTCHA Enterprise, meaning Google charges you for API calls exceeding the free tier. Contact Form 7 supports Cloudflare Turnstile, and we recommend it unless you have reasons to use reCAPTCHA.', 'contact-form-7' ), + array( 'type' => 'warning' ) + ); + } +} diff --git a/wp-content/plugins/contact-form-7/admin/edit-contact-form.php b/wp-content/plugins/contact-form-7/admin/edit-contact-form.php new file mode 100644 index 0000000..e63c20b --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/edit-contact-form.php @@ -0,0 +1,484 @@ +', + wpcf7_format_atts( array( + 'type' => 'submit', + 'class' => 'button-primary', + 'name' => 'wpcf7-save', + 'value' => __( 'Save', 'contact-form-7' ), + ) ) +); + +$formatter = new WPCF7_HTMLFormatter( array( + 'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array( + 'form' => array( + 'method' => true, + 'action' => true, + 'id' => true, + 'class' => true, + 'disabled' => true, + ), + ) ), +) ); + +$formatter->append_start_tag( 'div', array( + 'class' => 'wrap', + 'id' => 'wpcf7-contact-form-editor', +) ); + +$formatter->append_start_tag( 'h1', array( + 'class' => 'wp-heading-inline', +) ); + +$formatter->append_preformatted( + esc_html( $post->initial() + ? __( 'Add Contact Form', 'contact-form-7' ) + : __( 'Edit Contact Form', 'contact-form-7' ) + ) +); + +$formatter->end_tag( 'h1' ); + +if ( ! $post->initial() and current_user_can( 'wpcf7_edit_contact_forms' ) ) { + $formatter->append_whitespace(); + + $formatter->append_preformatted( + wpcf7_link( + menu_page_url( 'wpcf7-new', false ), + __( 'Add Contact Form', 'contact-form-7' ), + array( 'class' => 'page-title-action' ) + ) + ); +} + +$formatter->append_start_tag( 'hr', array( + 'class' => 'wp-header-end', +) ); + +$formatter->call_user_func( static function () use ( $post ) { + do_action( 'wpcf7_admin_warnings', + $post->initial() ? 'wpcf7-new' : 'wpcf7', + wpcf7_current_action(), + $post + ); + + do_action( 'wpcf7_admin_notices', + $post->initial() ? 'wpcf7-new' : 'wpcf7', + wpcf7_current_action(), + $post + ); +} ); + +if ( $post ) { + $formatter->append_start_tag( 'form', array( + 'method' => 'post', + 'action' => esc_url( add_query_arg( + array( 'post' => $post_id ), + menu_page_url( 'wpcf7', false ) + ) ), + 'id' => 'wpcf7-admin-form-element', + 'disabled' => ! current_user_can( 'wpcf7_edit_contact_form', $post_id ), + ) ); + + if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) { + $formatter->call_user_func( static function () use ( $post_id ) { + wp_nonce_field( 'wpcf7-save-contact-form_' . $post_id ); + } ); + } + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'id' => 'post_ID', + 'name' => 'post_ID', + 'value' => (int) $post_id, + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'id' => 'wpcf7-locale', + 'name' => 'wpcf7-locale', + 'value' => $post->locale(), + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'id' => 'hiddenaction', + 'name' => 'action', + 'value' => 'save', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'id' => 'active-tab', + 'name' => 'active-tab', + 'value' => wpcf7_superglobal_get( 'active-tab' ), + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'poststuff', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'post-body', + 'class' => 'metabox-holder columns-2 wp-clearfix', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'post-body-content', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'titlediv', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'titlewrap', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'name' => 'post_title', + 'value' => $post->initial() ? '' : $post->title(), + 'id' => 'title', + 'spellcheck' => 'true', + 'autocomplete' => 'off', + 'disabled' => ! current_user_can( 'wpcf7_edit_contact_form', $post_id ), + 'placeholder' => __( 'Enter title here', 'contact-form-7' ), + 'aria-label' => __( 'Enter title here', 'contact-form-7' ), + ) ); + + $formatter->end_tag( 'div' ); // #titlewrap + + $formatter->append_start_tag( 'div', array( + 'class' => 'inside', + ) ); + + if ( ! $post->initial() ) { + if ( $shortcode = $post->shortcode() ) { + $formatter->append_start_tag( 'p', array( + 'class' => 'description', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => 'wpcf7-shortcode', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Copy this shortcode and paste it into your post, page, or text widget content:', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'label' ); + + $formatter->append_whitespace(); + + $formatter->append_start_tag( 'span', array( + 'class' => 'shortcode wp-ui-highlight', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => 'wpcf7-shortcode', + 'readonly' => true, + 'class' => 'large-text code selectable', + 'value' => $shortcode, + ) ); + + $formatter->end_tag( 'p' ); + } + + if ( $shortcode = $post->shortcode( array( 'use_old_format' => true ) ) ) { + $formatter->append_start_tag( 'p', array( + 'class' => 'description', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => 'wpcf7-shortcode-old', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'You can also use this old-style shortcode:', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'label' ); + + $formatter->append_whitespace(); + + $formatter->append_start_tag( 'span', array( + 'class' => 'shortcode old', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => 'wpcf7-shortcode-old', + 'readonly' => true, + 'class' => 'large-text code selectable', + 'value' => $shortcode, + ) ); + + $formatter->end_tag( 'p' ); + } + } + + $formatter->end_tag( 'div' ); // .inside + $formatter->end_tag( 'div' ); // #titlediv + $formatter->end_tag( 'div' ); // #post-body-content + + $formatter->append_start_tag( 'div', array( + 'id' => 'postbox-container-1', + 'class' => 'postbox-container', + ) ); + + if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) { + $formatter->append_start_tag( 'section', array( + 'id' => 'submitdiv', + 'class' => 'postbox', + ) ); + + $formatter->append_start_tag( 'h2' ); + + $formatter->append_preformatted( + esc_html( __( 'Status', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h2' ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'inside', + ) ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'submitbox', + 'id' => 'submitpost', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'minor-publishing-actions', + ) ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'hidden', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'submit', + 'class' => 'button-primary', + 'name' => 'wpcf7-save', + 'value' => __( 'Save', 'contact-form-7' ), + ) ); + + $formatter->end_tag( 'div' ); // .hidden + + if ( ! $post->initial() ) { + $formatter->append_start_tag( 'input', array( + 'type' => 'submit', + 'name' => 'wpcf7-copy', + 'class' => 'copy button', + 'value' => __( 'Duplicate', 'contact-form-7' ), + ) ); + } + + $formatter->end_tag( 'div' ); // #minor-publishing-actions + + $formatter->append_start_tag( 'div', array( + 'id' => 'misc-publishing-actions', + ) ); + + $formatter->call_user_func( static function () use ( $post_id ) { + do_action( 'wpcf7_admin_misc_pub_section', $post_id ); + } ); + + $formatter->end_tag( 'div' ); // #misc-publishing-actions + + $formatter->append_start_tag( 'div', array( + 'id' => 'major-publishing-actions', + ) ); + + if ( ! $post->initial() ) { + $formatter->append_start_tag( 'div', array( + 'id' => 'delete-action', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'submit', + 'name' => 'wpcf7-delete', + 'class' => 'delete submitdelete', + 'value' => __( 'Delete', 'contact-form-7' ), + ) ); + + $formatter->end_tag( 'div' ); // #delete-action + } + + $formatter->append_start_tag( 'div', array( + 'id' => 'publishing-action', + ) ); + + $formatter->append_preformatted( '' ); + $formatter->append_preformatted( $save_button ); + + $formatter->end_tag( 'div' ); // #publishing-action + + $formatter->append_preformatted( '
' ); + + $formatter->end_tag( 'div' ); // #major-publishing-actions + $formatter->end_tag( 'div' ); // #submitpost + $formatter->end_tag( 'div' ); // .inside + $formatter->end_tag( 'section' ); // #submitdiv + } + + $formatter->append_start_tag( 'section', array( + 'id' => 'informationdiv', + 'class' => 'postbox', + ) ); + + $formatter->append_start_tag( 'h2' ); + + $formatter->append_preformatted( + esc_html( __( 'Do you need help?', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h2' ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'inside', + ) ); + + $formatter->append_start_tag( 'p' ); + + $formatter->append_preformatted( + esc_html( __( 'Here are some available options to help solve your problems.', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'p' ); + + $formatter->append_start_tag( 'ol' ); + + $formatter->append_start_tag( 'li' ); + + $formatter->append_preformatted( + sprintf( + /* translators: 1: URL to FAQ, 2: URL to docs */ + 'FAQ and docs', + __( 'https://contactform7.com/faq/', 'contact-form-7' ), + __( 'https://contactform7.com/docs/', 'contact-form-7' ) + ) + ); + + $formatter->append_start_tag( 'li' ); + + $formatter->append_preformatted( + wpcf7_link( + __( 'https://wordpress.org/support/plugin/contact-form-7/', 'contact-form-7' ), + __( 'Support forums', 'contact-form-7' ) + ) + ); + + $formatter->append_start_tag( 'li' ); + + $formatter->append_preformatted( + wpcf7_link( + __( 'https://contactform7.com/custom-development/', 'contact-form-7' ), + __( 'Professional services', 'contact-form-7' ) + ) + ); + + $formatter->end_tag( 'ol' ); + $formatter->end_tag( 'div' ); // .inside + $formatter->end_tag( 'section' ); // #informationdiv + $formatter->end_tag( 'div' ); // #postbox-container-1 + + $formatter->append_start_tag( 'div', array( + 'id' => 'postbox-container-2', + 'class' => 'postbox-container', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'contact-form-editor', + ) ); + + $formatter->call_user_func( static function () use ( $post, $post_id ) { + $editor = new WPCF7_Editor( $post ); + $panels = array(); + + if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) { + $panels = array( + 'form-panel' => array( + 'title' => __( 'Form', 'contact-form-7' ), + 'callback' => 'wpcf7_editor_panel_form', + ), + 'mail-panel' => array( + 'title' => __( 'Mail', 'contact-form-7' ), + 'callback' => 'wpcf7_editor_panel_mail', + ), + 'messages-panel' => array( + 'title' => __( 'Messages', 'contact-form-7' ), + 'callback' => 'wpcf7_editor_panel_messages', + ), + ); + + $additional_settings = $post->prop( 'additional_settings' ); + + if ( ! is_scalar( $additional_settings ) ) { + $additional_settings = ''; + } + + $additional_settings = trim( $additional_settings ); + $additional_settings = explode( "\n", $additional_settings ); + $additional_settings = array_filter( $additional_settings ); + $additional_settings = count( $additional_settings ); + + $panels['additional-settings-panel'] = array( + 'title' => $additional_settings + ? sprintf( + /* translators: %d: number of additional settings */ + __( 'Additional Settings (%d)', 'contact-form-7' ), + $additional_settings + ) + : __( 'Additional Settings', 'contact-form-7' ), + 'callback' => 'wpcf7_editor_panel_additional_settings', + ); + } + + $panels = apply_filters( 'wpcf7_editor_panels', $panels ); + + foreach ( $panels as $id => $panel ) { + $editor->add_panel( $id, $panel['title'], $panel['callback'] ); + } + + $editor->display(); + } ); + + $formatter->end_tag( 'div' ); // #contact-form-editor + + if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) { + $formatter->append_start_tag( 'p', array( + 'class' => 'submit', + ) ); + + $formatter->append_preformatted( $save_button ); + + $formatter->end_tag( 'p' ); + } + + $formatter->end_tag( 'div' ); // #postbox-container-2 + $formatter->end_tag( 'div' ); // #post-body + + $formatter->append_preformatted( '
' ); + + $formatter->end_tag( 'div' ); // #poststuff + $formatter->end_tag( 'form' ); +} + +$formatter->end_tag( 'div' ); // .wrap + +$formatter->print(); + +$tag_generator = WPCF7_TagGenerator::get_instance(); +$tag_generator->print_panels( $post ); + +do_action( 'wpcf7_admin_footer', $post ); diff --git a/wp-content/plugins/contact-form-7/admin/includes/admin-functions.php b/wp-content/plugins/contact-form-7/admin/includes/admin-functions.php new file mode 100644 index 0000000..11a5547 --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/includes/admin-functions.php @@ -0,0 +1,22 @@ +add( $name, $title, $callback, $options ); +} diff --git a/wp-content/plugins/contact-form-7/admin/includes/class-contact-forms-list-table.php b/wp-content/plugins/contact-form-7/admin/includes/class-contact-forms-list-table.php new file mode 100644 index 0000000..6235966 --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/includes/class-contact-forms-list-table.php @@ -0,0 +1,241 @@ + '', + 'title' => __( 'Title', 'contact-form-7' ), + 'shortcode' => __( 'Shortcode', 'contact-form-7' ), + 'author' => __( 'Author', 'contact-form-7' ), + 'date' => __( 'Date', 'contact-form-7' ), + ); + + return $columns; + } + + public function __construct() { + parent::__construct( array( + 'singular' => 'post', + 'plural' => 'posts', + 'ajax' => false, + ) ); + } + + public function prepare_items() { + $current_screen = get_current_screen(); + $per_page = $this->get_items_per_page( 'wpcf7_contact_forms_per_page' ); + + $args = array( + 'posts_per_page' => $per_page, + 'orderby' => 'title', + 'order' => 'ASC', + 'offset' => ( $this->get_pagenum() - 1 ) * $per_page, + ); + + if ( $search_keyword = wpcf7_superglobal_request( 's' ) ) { + $args['s'] = $search_keyword; + } + + if ( $order_by = wpcf7_superglobal_request( 'orderby' ) ) { + $args['orderby'] = $order_by; + } + + if ( + $order = wpcf7_superglobal_request( 'order' ) and + 'desc' === strtolower( $order ) + ) { + $args['order'] = 'DESC'; + } + + $this->items = WPCF7_ContactForm::find( $args ); + + $total_items = WPCF7_ContactForm::count(); + $total_pages = ceil( $total_items / $per_page ); + + $this->set_pagination_args( array( + 'total_items' => $total_items, + 'total_pages' => $total_pages, + 'per_page' => $per_page, + ) ); + } + + public function get_columns() { + return get_column_headers( get_current_screen() ); + } + + protected function get_sortable_columns() { + $columns = array( + 'title' => array( 'title', true ), + 'author' => array( 'author', false ), + 'date' => array( 'date', false ), + ); + + return $columns; + } + + protected function get_bulk_actions() { + $actions = array( + 'delete' => __( 'Delete', 'contact-form-7' ), + ); + + return $actions; + } + + protected function column_default( $item, $column_name ) { + return ''; + } + + public function column_cb( $item ) { + return sprintf( + '', + $this->_args['singular'], + $item->id() + ); + } + + public function column_title( $item ) { + $edit_link = add_query_arg( + array( + 'post' => absint( $item->id() ), + 'action' => 'edit', + ), + menu_page_url( 'wpcf7', false ) + ); + + $output = sprintf( + '%3$s', + esc_url( $edit_link ), + esc_attr( sprintf( + /* translators: %s: title of contact form */ + __( 'Edit “%s”', 'contact-form-7' ), + $item->title() + ) ), + esc_html( $item->title() ) + ); + + $output = sprintf( '%s', $output ); + + if ( wpcf7_validate_configuration() + and current_user_can( 'wpcf7_edit_contact_form', $item->id() ) ) { + $config_validator = new WPCF7_ConfigValidator( $item ); + $config_validator->restore(); + + if ( $count_errors = $config_validator->count_errors() ) { + $error_notice = sprintf( + /* translators: %s: number of errors detected */ + _n( + '%s configuration error detected', + '%s configuration errors detected', + $count_errors, 'contact-form-7' ), + number_format_i18n( $count_errors ) + ); + + $output .= sprintf( + '
%s
', + $error_notice + ); + } + } + + return $output; + } + + protected function handle_row_actions( $item, $column_name, $primary ) { + if ( $column_name !== $primary ) { + return ''; + } + + $edit_link = add_query_arg( + array( + 'post' => absint( $item->id() ), + 'action' => 'edit', + ), + menu_page_url( 'wpcf7', false ) + ); + + $actions = array( + 'edit' => wpcf7_link( $edit_link, __( 'Edit', 'contact-form-7' ) ), + ); + + if ( current_user_can( 'wpcf7_edit_contact_form', $item->id() ) ) { + $copy_link = add_query_arg( + array( + 'post' => absint( $item->id() ), + 'action' => 'copy', + ), + menu_page_url( 'wpcf7', false ) + ); + + $copy_link = wp_nonce_url( + $copy_link, + 'wpcf7-copy-contact-form_' . absint( $item->id() ) + ); + + $actions = array_merge( $actions, array( + 'copy' => wpcf7_link( $copy_link, __( 'Duplicate', 'contact-form-7' ) ), + ) ); + } + + return $this->row_actions( $actions ); + } + + public function column_author( $item ) { + $post = get_post( $item->id() ); + + if ( ! $post ) { + return; + } + + $author = get_userdata( $post->post_author ); + + if ( false === $author ) { + return; + } + + return esc_html( $author->display_name ); + } + + public function column_shortcode( $item ) { + $shortcodes = array( $item->shortcode() ); + + $output = ''; + + foreach ( $shortcodes as $shortcode ) { + $output .= "\n" . sprintf( + '', + wpcf7_format_atts( array( + 'type' => 'text', + 'readonly' => true, + 'value' => $shortcode, + 'class' => 'large-text code selectable', + ) ) + ); + } + + return trim( $output ); + } + + public function column_date( $item ) { + $datetime = get_post_datetime( $item->id() ); + + if ( false === $datetime ) { + return ''; + } + + $t_time = sprintf( + /* translators: 1: date, 2: time */ + __( '%1$s at %2$s', 'contact-form-7' ), + /* translators: date format, see https://www.php.net/date */ + $datetime->format( __( 'Y/m/d', 'contact-form-7' ) ), + /* translators: time format, see https://www.php.net/date */ + $datetime->format( __( 'g:i a', 'contact-form-7' ) ) + ); + + return $t_time; + } +} diff --git a/wp-content/plugins/contact-form-7/admin/includes/config-validator.php b/wp-content/plugins/contact-form-7/admin/includes/config-validator.php new file mode 100644 index 0000000..e727a90 --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/includes/config-validator.php @@ -0,0 +1,180 @@ + 'validate' ), + menu_page_url( 'wpcf7', false ) + ), + __( 'Validate Contact Form 7 Configuration', 'contact-form-7' ) + ) + ), + array( 'type' => 'warning' ) + ); +} + +add_action( 'wpcf7_admin_load', 'wpcf7_load_bulk_validate_page', 10, 2 ); + +function wpcf7_load_bulk_validate_page( $page, $action ) { + if ( + 'wpcf7' !== $page or + 'validate' !== $action or + ! wpcf7_validate_configuration() or + 'POST' !== wpcf7_superglobal_server( 'REQUEST_METHOD' ) + ) { + return; + } + + check_admin_referer( 'wpcf7-bulk-validate' ); + + if ( ! current_user_can( 'wpcf7_edit_contact_forms' ) ) { + wp_die( wp_kses_data( __( 'You are not allowed to validate configuration.', 'contact-form-7' ) ) ); + } + + $contact_forms = WPCF7_ContactForm::find(); + + $result = array( + 'timestamp' => time(), + 'version' => WPCF7_VERSION, + 'count_valid' => 0, + 'count_invalid' => 0, + ); + + foreach ( $contact_forms as $contact_form ) { + $config_validator = new WPCF7_ConfigValidator( $contact_form ); + $config_validator->validate(); + $config_validator->save(); + + if ( $config_validator->is_valid() ) { + $result['count_valid'] += 1; + } else { + $result['count_invalid'] += 1; + } + } + + WPCF7::update_option( 'bulk_validate', $result ); + + $redirect_to = add_query_arg( + array( + 'message' => 'validated', + ), + menu_page_url( 'wpcf7', false ) + ); + + wp_safe_redirect( $redirect_to ); + exit(); +} + +function wpcf7_admin_bulk_validate_page() { + $contact_forms = WPCF7_ContactForm::find(); + $count = WPCF7_ContactForm::count(); + + $submit_text = sprintf( + /* translators: %s: number of contact forms */ + _n( + 'Validate %s contact form now', + 'Validate %s contact forms now', + $count, 'contact-form-7' + ), + number_format_i18n( $count ) + ); + + $formatter = new WPCF7_HTMLFormatter( array( + 'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array( + 'form' => array( + 'action' => true, + 'method' => true, + ), + ) ), + ) ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'wrap', + ) ); + + $formatter->append_start_tag( 'h1' ); + + $formatter->append_preformatted( + esc_html( __( 'Validate Configuration', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h1' ); + + $formatter->append_start_tag( 'form', array( + 'method' => 'post', + 'action' => '', + ) ); + + $formatter->append_start_tag( 'p' ); + + $formatter->call_user_func( static function () { + wp_nonce_field( 'wpcf7-bulk-validate' ); + } ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'name' => 'action', + 'value' => 'validate', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'submit', + 'class' => 'button', + 'value' => $submit_text, + ) ); + + $formatter->end_tag( 'form' ); + + $formatter->append_preformatted( + wpcf7_link( + __( 'https://contactform7.com/configuration-validator-faq/', 'contact-form-7' ), + __( 'FAQ about Configuration Validator', 'contact-form-7' ) + ) + ); + + $formatter->print(); +} diff --git a/wp-content/plugins/contact-form-7/admin/includes/css/styles-rtl.css b/wp-content/plugins/contact-form-7/admin/includes/css/styles-rtl.css new file mode 100644 index 0000000..4b5de0f --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/includes/css/styles-rtl.css @@ -0,0 +1,77 @@ +/* + * Form Tab + */ +.tag-generator-panel { + text-align: right; +} + +.tag-generator-dialog > .close-button { + right: auto; + left: 8px; +} + +form.tag-generator-panel[data-version="1"] { + .control-box > fieldset > legend { + border: 1px solid #dfdfdf; + border-right: 4px solid #00a0d2; + } + + .insert-box input.tag { + float: right; + } + + .insert-box .submitbox input[type="button"] { + float: left; + } +} + +/* + * Mail Tab + */ +.contact-form-editor-box-mail span.mailtag { + margin: 0 4px 0 0; +} + +/* + * Welcome Panel + */ +.wpcf7-welcome-panel .welcome-panel-close { + left: 10px; + right: auto; + padding: 10px 21px 10px 15px; +} + +.wpcf7-welcome-panel .welcome-panel-close::before { + right: 0; + left: auto; +} + +.wpcf7-welcome-panel .welcome-panel-content { + margin-right: 13px; +} + +.wpcf7-welcome-panel .welcome-panel-column { + float: right; + padding: 0 0 0 2%; +} + +/* + * Integration + */ +.card { + border-left: 1px solid #e5e5e5; + border-right: 4px solid #e5e5e5; +} + +.card img.icon { + float: right; + margin: 8px -8px 8px 8px; +} + +.card h2.title { + float: right; +} + +.card .infobox { + float: left; +} diff --git a/wp-content/plugins/contact-form-7/admin/includes/css/styles.css b/wp-content/plugins/contact-form-7/admin/includes/css/styles.css new file mode 100644 index 0000000..0aa85ab --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/includes/css/styles.css @@ -0,0 +1,614 @@ +#titlediv .inside p.description { + margin: 8px 2px 0; +} + +#titlediv .inside p.description label { + cursor: pointer; +} + +span.shortcode { + display: block; + margin: 2px 0; +} + +span.shortcode.old { + background: #777; + color: #fff; +} + +span.shortcode input { + font-size: 12px; + border: none; + box-shadow: none; + padding: 4px 8px; + margin: 0; +} + +#wpcf7-contact-form-list-table span.shortcode input, +#wpcf7-contact-form-editor span.shortcode input { + background: transparent; +} + +#wpcf7-contact-form-list-table span.shortcode input { + color: #444; +} + +#wpcf7-contact-form-editor span.shortcode input { + color: #fff; + width: 100%; +} + +#submitpost input.copy { + margin-bottom: 10px; +} + +#submitpost input.delete { + padding: 0; + margin: 0; + border: none; + cursor: pointer; + background: inherit; + color: #a00; +} + +#submitpost input.delete:hover { + color: #dc3232; /* Red */ +} + +#submitpost input.delete:focus { + outline: thin dotted; +} + +.postbox-container .postbox h3 { + border-bottom: 1px solid transparent; +} + +div.config-error, span.config-error, ul.config-error { + color: #444; + font-style: normal; + font-size: 13px; +} + +ul.config-error { + margin: 2px 0; +} + +ul.config-error li { + list-style: none; + padding: 2px 2px; + margin: 0; +} + +#misc-publishing-actions .config-error { + line-height: 2; +} + +[data-config-field][aria-invalid="true"] { + border-color: #dc3232; +} + +#contact-form-editor-tabs .icon-in-circle, +#contact-form-editor .config-error .icon-in-circle, +.wp-list-table .config-error .icon-in-circle, +.icon-in-circle { + display: inline-block; + vertical-align: baseline; + margin: 1px 6px 0; + padding: 0 5px; + min-width: 7px; + height: 17px; + border-radius: 11px; + background-color: #ca4a1f; + color: #fff; + font-size: 12px; + font-weight: bold; + line-height: 17px; + text-align: center; + z-index: 26; +} + +/* + * Tabs + */ +#contact-form-editor-tabs { + border-bottom: 1px solid #aaa; + padding: 9px 10px 0; + margin: 0; +} + +#contact-form-editor-tabs button { + display: inline-block; + border: 1px solid #ccc; + border-bottom: 1px solid #aaa; + padding: 6px 10px; + margin: 0 4px -1px; + color: #333; + background-color: #e4e4e4; + font-size: 14px; + font-weight: normal; + line-height: 20px; +} + +#contact-form-editor-tabs button[aria-selected="true"] { + border-top: 1px solid #aaa; + border-right: 1px solid #aaa; + border-left: 1px solid #aaa; + border-bottom: 1px solid #f5f5f5; + color: #000; + background-color: #f5f5f5; + font-weight: bold; +} + +#contact-form-editor-tabs button:hover { + color: #000; +} + +#contact-form-editor .contact-form-editor-panel > div.config-error { + margin-bottom: 1.4em; +} + +#contact-form-editor-tabs button[aria-selected="true"] .icon-in-circle { + display: none; +} + +#contact-form-editor .contact-form-editor-panel h2 { + font-size: 18px; + font-weight: 400; + line-height: 24px; + margin: 8px 0; + padding: 0; +} + +#contact-form-editor .contact-form-editor-panel { + background-color: #f5f5f5; + border: 1px solid #aaa; + border-top: none; + padding: 16px; +} + +#contact-form-editor .form-table th { + width: 100px; +} + +#contact-form-editor .contact-form-editor-panel fieldset legend { + line-height: 1.5; + margin: .6em 0 .4em; +} + +/* + * Form Tab + */ +#tag-generator-list button { + font-size: 12px; + height: 26px; + line-height: 24px; + margin: 2px; + padding: 0 8px 1px; +} + +.tag-generator-dialog { + padding: 12px; + border: 1px solid #c3c4c7; + box-shadow: 0 1px 1px rgba( 0, 0, 0, 0.04 ); + height: 720px; + width: 720px; + overflow: auto; +} + +.tag-generator-dialog::backdrop { + background: rgb( 0 0 0 / 50% ); +} + +.tag-generator-dialog > .close-button { + position: absolute; + top: 8px; + right: 8px; +} + +form.tag-generator-panel { + display: flex; + flex-direction: column; + height: 720px; + width: 720px; + max-height: 100%; + max-width: 100%; + margin-block-end: 0; +} + +form.tag-generator-panel[data-version="2"] { + &:invalid .mail-tag-tip { + display: none; + } + + .description-box { + box-sizing: border-box; + flex: none; + margin-inline: -12px; + padding-inline: 12px; + border-bottom: 1px solid #dfdfdf; + } + + .control-box { + box-sizing: border-box; + flex: auto; + display: flex; + flex-direction: column; + gap: 12px 0; + min-height: 120px; + overflow: auto; + } + + .control-box > fieldset { + margin-block: 8px; + margin-inline-start: 10em; + line-height: 2.25; + } + + .control-box > fieldset > legend { + font-weight: bolder; + margin-block: 8px; + margin-inline-start: -10em; + line-height: 1.25; + } + + .control-box input[type="text"] { + width: 20rem; + max-width: 88%; + } + + .control-box input[type="number"] { + width: 8rem; + max-width: 44%; + } + + .control-box textarea { + height: 12ex; + width: 20rem; + max-width: 88%; + } + + .control-box select { + width: 20rem; + max-width: 88%; + } + + .control-box input:invalid, + .control-box textarea:invalid { + background-color: #ffe9de; + } + + .insert-box { + box-sizing: border-box; + flex: none; + margin-block-end: -12px; + margin-inline: -12px; + padding-block: 24px 12px; + padding-inline: 12px; + background-color: #fcfcfc; + border-top: 1px solid #dfdfdf; + } + + .insert-box .flex-container { + display: flex; + } + + .insert-box .flex-container > [data-tag-part="tag"] { + flex: auto; + margin-inline-end: 8px; + } + + .insert-box .mail-tag-tip::before { + font: 1.2rem dashicons; + content: "\f348" / ''; + color: #646970; + padding-inline-end: 4px; + vertical-align: top; + } +} + +form.tag-generator-panel[data-version="1"] { + .control-box { + padding: 0; + margin: 0; + overflow: auto; + flex-grow: 1; + } + + .control-box > fieldset > legend { + border: 1px solid #dfdfdf; + border-left: 4px solid #00a0d2; + background: #f7fcfe; + padding: 4px 12px; + margin: 4px 0; + line-height: 1.4em; + width: 100%; + box-sizing: border-box; + } + + table { + width: 100%; + } + + table.form-table th { + width: 120px; + padding: 4px 10px 4px 0; + font-size: 13px; + } + + table.form-table td { + padding: 4px 10px; + font-size: 13px; + } + + .control-box input.oneline { + width: 200px; + } + + .control-box input.large-text { + width: 400px; + } + + .control-box textarea.values { + width: 200px; + height: 6em; + } + + .control-box input[type="number"], + .control-box input[type="date"] { + width: 88px; + } + + .control-box table caption { + text-align: left; + font-size: 110%; + font-weight: bold; + color: #777; + margin: 10px 0 5px; + } + + .control-box table.form-table td label { + line-height: 1.1em; + } + + .control-box table.form-table td label .description { + line-height: 1.4em; + } + + .insert-box { + margin: 0 -15px -15px; + padding: 8px 16px; + background-color: #fcfcfc; + border-top: 1px solid #dfdfdf; + overflow: auto; + } + + .insert-box input.tag { + width: 510px; + float: left; + background-color: transparent; + box-shadow: none; + } + + .insert-box .submitbox { + padding: 0; + } + + .insert-box .submitbox input[type="button"] { + float: right; + } + + .insert-box .description label { + cursor: text; + } +} + +/* + * Mail Tab + */ +.contact-form-editor-box-mail span.mailtag { + display: inline-block; + margin: 0 0 0 4px; + padding: 1px 2px; + cursor: pointer; + color: #000; +} + +.contact-form-editor-box-mail span.mailtag.used { + color: #666; +} + +.contact-form-editor-box-mail span.mailtag.unused { + font-weight: bold; +} + +/* + * Messages Tab + */ +#messages-panel p.description { + margin: 5px 0 10px; +} + +/* + * Tabs for integration modules + */ +#sendinblue-panel table tr.inactive ~ tr { + display: none; +} + +#sendinblue-panel .dashicons { + text-decoration: none; +} + +#sendinblue-panel td p { + margin-top: 12px; +} + +/* + * List Table + */ +.fixed .column-title { + width: 38%; +} + +.fixed .column-shortcode { + width: 38%; +} + +/* + * Welcome Panel + */ +.wpcf7-welcome-panel { + position: relative; + overflow: auto; + margin: 16px 0; + padding: 23px 10px 0; + border: 1px solid #c3c4c7; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); + background: #fff; + font-size: 13px; + line-height: 1.7; +} + +.wpcf7-welcome-panel h3 { + font-size: 16px; + font-weight: 600; + line-height: 2.1em; + margin: 1em 0 1.2em; +} + +.wpcf7-welcome-panel h3 .dashicons { + position: relative; + top: -2px; + display: inline-block; + width: 60px; + color: #575757; + font-size: 40px; +} + +.wpcf7-welcome-panel p { + color: #646970; +} + +.wpcf7-welcome-panel p a { + font-weight: bold; +} + +.wpcf7-welcome-panel .welcome-panel-close { + position: absolute; + z-index: 2; + top: 10px; + right: 10px; + padding: 10px 15px 10px 21px; + font-size: 13px; + line-height: 1.23076923; /* Chrome rounding, needs to be 16px equivalent */ + text-decoration: none; +} + +.wpcf7-welcome-panel .welcome-panel-close::before { + background: 0 0; + color: #787c82; + content: "\f153" / ''; + display: block; + font: normal 16px/20px dashicons; + speak: never; + height: 20px; + text-align: center; + width: 20px; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + position: absolute; + top: 8px; + left: 0; + transition: all .1s ease-in-out; +} + +.wpcf7-welcome-panel .welcome-panel-content { + display: block; + margin-left: 13px; + max-width: 1500px; + min-height: auto; +} + +.wpcf7-welcome-panel .welcome-panel-column-container { + clear: both; + position: relative; +} + +.wpcf7-welcome-panel .welcome-panel-column { + display: block; + width: 48%; + min-width: 200px; + float: left; + padding: 0 2% 0 0; + margin: 0 0 1em 0; +} + +@media screen and (max-width: 870px) { + .wpcf7-welcome-panel .welcome-panel-column { + display: block; + float: none; + width: 100%; + } +} + +.wpcf7-welcome-panel .welcome-panel-column p { + margin-top: 7px; + color: #3c434a; +} + +/* + * Integration + */ +.card { + background: #fff none repeat scroll 0 0; + border: 1px solid #e5e5e5; + border-left: 4px solid #e5e5e5; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); + margin-top: 20px; + max-width: 520px; + min-width: 255px; + padding: 0.7em 2em 1em; + position: relative; +} + +.card.active { + border-color: #00a0d2; +} + +#constant_contact.card.active { + border-color: #dc3232; +} + +.card img.icon { + float: left; + margin: 8px 8px 8px -8px; +} + +.card h2.title { + float: left; + max-width: 240px; + font-size: 1.3em; + font-weight: 600; +} + +.card .infobox { + float: right; + font-size: 13px; + color: #666; + margin: 1em; + line-height: 1.5; + max-width: 240px; +} + +.card .inside .form-table th { + padding: 15px 10px 15px 0; + width: 160px; +} + +.card .inside .form-table td { + padding: 10px 10px; +} + +.card .checkboxes li { + margin: 0; +} diff --git a/wp-content/plugins/contact-form-7/admin/includes/editor.php b/wp-content/plugins/contact-form-7/admin/includes/editor.php new file mode 100644 index 0000000..cb58d26 --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/includes/editor.php @@ -0,0 +1,556 @@ +contact_form = $contact_form; + } + + public function add_panel( $panel_id, $title, $callback ) { + if ( wpcf7_is_name( $panel_id ) ) { + $this->panels[$panel_id] = array( + 'title' => $title, + 'callback' => $callback, + ); + } + } + + public function display() { + if ( empty( $this->panels ) ) { + return; + } + + $active_panel_id = wpcf7_superglobal_get( 'active-tab' ); + + if ( ! array_key_exists( $active_panel_id, $this->panels ) ) { + $active_panel_id = array_key_first( $this->panels ); + } + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'nav', array( + 'id' => 'contact-form-editor-tabs', + 'role' => 'tablist', + 'aria-label' => __( 'Contact form editor tabs', 'contact-form-7' ), + 'data-active-tab' => absint( array_search( + $active_panel_id, array_keys( $this->panels ), true + ) ), + ) ); + + foreach ( $this->panels as $panel_id => $panel ) { + $active = $panel_id === $active_panel_id; + + $formatter->append_start_tag( 'button', array( + 'type' => 'button', + 'role' => 'tab', + 'aria-selected' => $active ? 'true' : 'false', + 'aria-controls' => $panel_id, + 'id' => sprintf( '%s-tab', $panel_id ), + 'tabindex' => $active ? '0' : '-1', + ) ); + + $formatter->append_preformatted( esc_html( $panel['title'] ) ); + } + + $formatter->end_tag( 'nav' ); + + foreach ( $this->panels as $panel_id => $panel ) { + $active = $panel_id === $active_panel_id; + + $formatter->append_start_tag( 'section', array( + 'role' => 'tabpanel', + 'aria-labelledby' => sprintf( '%s-tab', $panel_id ), + 'id' => $panel_id, + 'class' => 'contact-form-editor-panel', + 'tabindex' => '0', + 'hidden' => ! $active, + ) ); + + if ( is_callable( $panel['callback'] ) ) { + $formatter->call_user_func( $panel['callback'], $this->contact_form ); + } + + $formatter->end_tag( 'section' ); + } + + $formatter->print(); + } +} + +function wpcf7_editor_panel_form( $post ) { + $description = sprintf( + /* translators: %s: URL to support page about the form template */ + __( 'You can edit the form template here. For details, see Editing form template.', 'contact-form-7' ), + __( 'https://contactform7.com/editing-form-template/', 'contact-form-7' ) + ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'h2' ); + $formatter->append_preformatted( esc_html( __( 'Form', 'contact-form-7' ) ) ); + $formatter->end_tag( 'h2' ); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend' ); + $formatter->append_preformatted( $description ); + $formatter->end_tag( 'legend' ); + + $formatter->call_user_func( static function () { + $tag_generator = WPCF7_TagGenerator::get_instance(); + $tag_generator->print_buttons(); + } ); + + $formatter->append_start_tag( 'textarea', array( + 'id' => 'wpcf7-form', + 'name' => 'wpcf7-form', + 'cols' => 100, + 'rows' => 24, + 'class' => 'large-text code', + 'data-config-field' => 'form.body', + ) ); + + $formatter->append_preformatted( esc_textarea( $post->prop( 'form' ) ) ); + + $formatter->end_tag( 'textarea' ); + + $formatter->print(); +} + +function wpcf7_editor_panel_mail( $post ) { + wpcf7_editor_box_mail( $post ); + + echo '
'; + + wpcf7_editor_box_mail( $post, array( + 'id' => 'wpcf7-mail-2', + 'name' => 'mail_2', + 'title' => __( 'Mail (2)', 'contact-form-7' ), + 'use' => __( 'Use Mail (2)', 'contact-form-7' ), + ) ); +} + +function wpcf7_editor_box_mail( $post, $options = '' ) { + $options = wp_parse_args( $options, array( + 'id' => 'wpcf7-mail', + 'name' => 'mail', + 'title' => __( 'Mail', 'contact-form-7' ), + 'use' => null, + ) ); + + $id = esc_attr( $options['id'] ); + + $mail = wp_parse_args( $post->prop( $options['name'] ), array( + 'active' => false, + 'recipient' => '', + 'sender' => '', + 'subject' => '', + 'body' => '', + 'additional_headers' => '', + 'attachments' => '', + 'use_html' => false, + 'exclude_blank' => false, + ) ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'div', array( + 'class' => 'contact-form-editor-box-mail', + 'id' => $id, + ) ); + + $formatter->append_start_tag( 'h2' ); + $formatter->append_preformatted( esc_html( $options['title'] ) ); + $formatter->end_tag( 'h2' ); + + if ( ! empty( $options['use'] ) ) { + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-active', $id ), + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'id' => sprintf( '%s-active', $id ), + 'name' => sprintf( '%s[active]', $id ), + 'data-config-field' => '', + 'data-toggle' => sprintf( '%s-fieldset', $id ), + 'value' => '1', + 'checked' => $mail['active'], + ) ); + + $formatter->append_whitespace(); + $formatter->append_preformatted( esc_html( $options['use'] ) ); + $formatter->end_tag( 'label' ); + + $formatter->append_start_tag( 'p', array( + 'class' => 'description', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Mail (2) is an additional mail template often used as an autoresponder.', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'p' ); + } + + $formatter->append_start_tag( 'fieldset', array( + 'id' => sprintf( '%s-fieldset', $id ), + ) ); + + $formatter->append_start_tag( 'legend' ); + + $description = sprintf( + /* translators: %s: URL to support page about the email template */ + __( 'You can edit the email template here. For details, see Setting up mail.', 'contact-form-7' ), + __( 'https://contactform7.com/setting-up-mail/', 'contact-form-7' ) + ); + + $formatter->append_preformatted( $description ); + + $formatter->append_start_tag( 'br' ); + + $formatter->append_preformatted( + esc_html( __( 'In the following fields, you can use these mail-tags:', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'br' ); + + $formatter->call_user_func( static function () use ( $post, $options ) { + $post->suggest_mail_tags( $options['name'] ); + } ); + + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'table', array( + 'class' => 'form-table', + ) ); + + $formatter->append_start_tag( 'tbody' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-recipient', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'To', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => sprintf( '%s-recipient', $id ), + 'name' => sprintf( '%s[recipient]', $id ), + 'class' => 'large-text code', + 'size' => 70, + 'value' => $mail['recipient'], + 'data-config-field' => sprintf( '%s.recipient', $options['name'] ), + ) ); + + $formatter->end_tag( 'tr' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-sender', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'From', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => sprintf( '%s-sender', $id ), + 'name' => sprintf( '%s[sender]', $id ), + 'class' => 'large-text code', + 'size' => 70, + 'value' => $mail['sender'], + 'data-config-field' => sprintf( '%s.sender', $options['name'] ), + ) ); + + $formatter->end_tag( 'tr' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-subject', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Subject', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => sprintf( '%s-subject', $id ), + 'name' => sprintf( '%s[subject]', $id ), + 'class' => 'large-text code', + 'size' => 70, + 'value' => $mail['subject'], + 'data-config-field' => sprintf( '%s.subject', $options['name'] ), + ) ); + + $formatter->end_tag( 'tr' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-additional-headers', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Additional headers', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'textarea', array( + 'id' => sprintf( '%s-additional-headers', $id ), + 'name' => sprintf( '%s[additional_headers]', $id ), + 'cols' => 100, + 'rows' => 4, + 'class' => 'large-text code', + 'data-config-field' => sprintf( '%s.additional_headers', $options['name'] ), + ) ); + + $formatter->append_preformatted( + esc_textarea( $mail['additional_headers'] ) + ); + + $formatter->end_tag( 'tr' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-body', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Message body', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'textarea', array( + 'id' => sprintf( '%s-body', $id ), + 'name' => sprintf( '%s[body]', $id ), + 'cols' => 100, + 'rows' => 18, + 'class' => 'large-text code', + 'data-config-field' => sprintf( '%s.body', $options['name'] ), + ) ); + + $formatter->append_preformatted( + esc_textarea( $mail['body'] ) + ); + + $formatter->end_tag( 'textarea' ); + + $formatter->append_start_tag( 'p' ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-exclude-blank', $id ), + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'id' => sprintf( '%s-exclude-blank', $id ), + 'name' => sprintf( '%s[exclude_blank]', $id ), + 'value' => '1', + 'checked' => $mail['exclude_blank'], + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'Exclude a line from output if all of its mail-tags are blank', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'p' ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-use-html', $id ), + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'id' => sprintf( '%s-use-html', $id ), + 'name' => sprintf( '%s[use_html]', $id ), + 'value' => '1', + 'checked' => $mail['use_html'], + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'Use HTML content type', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'tr' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-attachments', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'File attachments', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'textarea', array( + 'id' => sprintf( '%s-attachments', $id ), + 'name' => sprintf( '%s[attachments]', $id ), + 'cols' => 100, + 'rows' => 4, + 'class' => 'large-text code', + 'data-config-field' => sprintf( '%s.attachments', $options['name'] ), + ) ); + + $formatter->append_preformatted( + esc_textarea( $mail['attachments'] ) + ); + + $formatter->end_tag( 'textarea' ); + $formatter->end_tag( 'tr' ); + + $formatter->print(); +} + +function wpcf7_editor_panel_messages( $post ) { + $description = sprintf( + /* translators: %s: URL to support page about the messages editor */ + __( 'You can edit messages used in various situations here. For details, see Editing messages.', 'contact-form-7' ), + __( 'https://contactform7.com/editing-messages/', 'contact-form-7' ) + ); + + $messages = wpcf7_messages(); + + if ( + isset( $messages['captcha_not_match'] ) and + ! wpcf7_use_really_simple_captcha() + ) { + unset( $messages['captcha_not_match'] ); + } + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'h2' ); + + $formatter->append_preformatted( + esc_html( __( 'Messages', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h2' ); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend' ); + $formatter->append_preformatted( $description ); + $formatter->end_tag( 'legend' ); + + foreach ( $messages as $key => $arr ) { + $field_id = sprintf( 'wpcf7-message-%s', strtr( $key, '_', '-' ) ); + $field_name = sprintf( 'wpcf7-messages[%s]', $key ); + + $formatter->append_start_tag( 'p', array( + 'class' => 'description', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => $field_id, + ) ); + + $formatter->append_preformatted( esc_html( $arr['description'] ) ); + $formatter->append_start_tag( 'br' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => $field_id, + 'name' => $field_name, + 'class' => 'large-text', + 'size' => 70, + 'value' => $post->message( $key, false ), + 'data-config-field' => sprintf( 'messages.%s', $key ), + ) ); + } + + $formatter->print(); +} + +function wpcf7_editor_panel_additional_settings( $post ) { + $description = sprintf( + /* translators: %s: URL to support page about the additional settings editor */ + __( 'You can add customization code snippets here. For details, see Additional settings.', 'contact-form-7' ), + __( 'https://contactform7.com/additional-settings/', 'contact-form-7' ) + ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'h2' ); + + $formatter->append_preformatted( + esc_html( __( 'Additional Settings', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h2' ); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend' ); + $formatter->append_preformatted( $description ); + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'textarea', array( + 'id' => 'wpcf7-additional-settings', + 'name' => 'wpcf7-additional-settings', + 'cols' => 100, + 'rows' => 24, + 'class' => 'large-text', + 'data-config-field' => 'additional_settings.body', + ) ); + + $formatter->append_preformatted( + esc_textarea( $post->prop( 'additional_settings' ) ) + ); + + $formatter->end_tag( 'textarea' ); + + $formatter->print(); +} diff --git a/wp-content/plugins/contact-form-7/admin/includes/help-tabs.php b/wp-content/plugins/contact-form-7/admin/includes/help-tabs.php new file mode 100644 index 0000000..9b768b1 --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/includes/help-tabs.php @@ -0,0 +1,104 @@ +screen = $screen; + } + + public function set_help_tabs( $screen_type ) { + switch ( $screen_type ) { + case 'list': + $this->screen->add_help_tab( array( + 'id' => 'list_overview', + 'title' => __( 'Overview', 'contact-form-7' ), + 'content' => $this->content( 'list_overview' ), + ) ); + + $this->screen->add_help_tab( array( + 'id' => 'list_available_actions', + 'title' => __( 'Available Actions', 'contact-form-7' ), + 'content' => $this->content( 'list_available_actions' ), + ) ); + + $this->sidebar(); + + return; + case 'edit': + $this->screen->add_help_tab( array( + 'id' => 'edit_overview', + 'title' => __( 'Overview', 'contact-form-7' ), + 'content' => $this->content( 'edit_overview' ), + ) ); + + $this->screen->add_help_tab( array( + 'id' => 'edit_form_tags', + 'title' => __( 'Form-tags', 'contact-form-7' ), + 'content' => $this->content( 'edit_form_tags' ), + ) ); + + $this->screen->add_help_tab( array( + 'id' => 'edit_mail_tags', + 'title' => __( 'Mail-tags', 'contact-form-7' ), + 'content' => $this->content( 'edit_mail_tags' ), + ) ); + + $this->sidebar(); + + return; + case 'integration': + $this->screen->add_help_tab( array( + 'id' => 'integration_overview', + 'title' => __( 'Overview', 'contact-form-7' ), + 'content' => $this->content( 'integration_overview' ), + ) ); + + $this->sidebar(); + + return; + } + } + + private function content( $name ) { + $content = array(); + + $content['list_overview'] = '

' . __( 'On this screen, you can manage contact forms provided by Contact Form 7. You can manage an unlimited number of contact forms. Each contact form has a unique ID and Contact Form 7 shortcode ([contact-form-7 ...]). To insert a contact form into a post or a text widget, insert the shortcode into the target.', 'contact-form-7' ) . '

'; + + $content['list_available_actions'] = '

' . __( 'Hovering over a row in the contact forms list will display action links that allow you to manage your contact form. You can perform the following actions:', 'contact-form-7' ) . '

'; + $content['list_available_actions'] .= '

' . __( 'Edit - Navigates to the editing screen for that contact form. You can also reach that screen by clicking on the contact form title.', 'contact-form-7' ) . '

'; + $content['list_available_actions'] .= '

' . __( 'Duplicate - Clones that contact form. A cloned contact form inherits all content from the original, but has a different ID.', 'contact-form-7' ) . '

'; + + $content['edit_overview'] = '

' . __( 'On this screen, you can edit a contact form. A contact form is comprised of the following components:', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'Title is the title of a contact form. This title is only used for labeling a contact form, and can be edited.', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'Form is a content of HTML form. You can use arbitrary HTML, which is allowed inside a form element. You can also use Contact Form 7’s form-tags here.', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'Mail manages a mail template (headers and message body) that this contact form will send when users submit it. You can use Contact Form 7’s mail-tags here.', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'Mail (2) is an additional mail template that works similar to Mail. Mail (2) is different in that it is sent only when Mail has been sent successfully.', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'In Messages, you can edit various types of messages used for this contact form. These messages are relatively short messages, like a validation error message you see when you leave a required field blank.', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'Additional Settings provides a place where you can customize the behavior of this contact form by adding code snippets.', 'contact-form-7' ) . '

'; + + $content['edit_form_tags'] = '

' . __( 'A form-tag is a short code enclosed in square brackets used in a form content. A form-tag generally represents an input field, and its components can be separated into four parts: type, name, options, and values. Contact Form 7 supports several types of form-tags including text fields, number fields, date fields, checkboxes, radio buttons, menus, file-uploading fields, CAPTCHAs, and quiz fields.', 'contact-form-7' ) . '

'; + $content['edit_form_tags'] .= '

' . __( 'While form-tags have a comparatively complex syntax, you do not need to know the syntax to add form-tags because you can use the straightforward tag generator (Generate Tag button on this screen).', 'contact-form-7' ) . '

'; + + $content['edit_mail_tags'] = '

' . __( 'A mail-tag is also a short code enclosed in square brackets that you can use in every Mail and Mail (2) field. A mail-tag represents a user input value through an input field of a corresponding form-tag.', 'contact-form-7' ) . '

'; + $content['edit_mail_tags'] .= '

' . __( 'There are also special mail-tags that have specific names, but do not have corresponding form-tags. They are used to represent meta information of form submissions like the submitter’s IP address or the URL of the page.', 'contact-form-7' ) . '

'; + + $content['integration_overview'] = '

' . __( 'On this screen, you can manage services that are available through Contact Form 7. Using API will allow you to collaborate with any services that are available.', 'contact-form-7' ) . '

'; + $content['integration_overview'] .= '

' . __( 'You may need to first sign up for an account with the service that you plan to use. When you do so, you would need to authorize Contact Form 7 to access the service with your account.', 'contact-form-7' ) . '

'; + $content['integration_overview'] .= '

' . __( 'Any information you provide will not be shared with service providers without your authorization.', 'contact-form-7' ) . '

'; + + if ( ! empty( $content[$name] ) ) { + return $content[$name]; + } + } + + public function sidebar() { + $content = '

' . __( 'For more information:', 'contact-form-7' ) . '

'; + $content .= '

' . wpcf7_link( __( 'https://contactform7.com/docs/', 'contact-form-7' ), __( 'Docs', 'contact-form-7' ) ) . '

'; + $content .= '

' . wpcf7_link( __( 'https://contactform7.com/faq/', 'contact-form-7' ), __( 'FAQ', 'contact-form-7' ) ) . '

'; + $content .= '

' . wpcf7_link( __( 'https://contactform7.com/support/', 'contact-form-7' ), __( 'Support', 'contact-form-7' ) ) . '

'; + + $this->screen->set_help_sidebar( $content ); + } +} diff --git a/wp-content/plugins/contact-form-7/admin/includes/js/index.asset.php b/wp-content/plugins/contact-form-7/admin/includes/js/index.asset.php new file mode 100644 index 0000000..61de87f --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/includes/js/index.asset.php @@ -0,0 +1,9 @@ + array( + 'wp-api-fetch', + 'wp-i18n', + ), + 'version' => WPCF7_VERSION, +); diff --git a/wp-content/plugins/contact-form-7/admin/includes/js/index.js b/wp-content/plugins/contact-form-7/admin/includes/js/index.js new file mode 100644 index 0000000..7087e3d --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/includes/js/index.js @@ -0,0 +1 @@ +(()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var r in a)e.o(a,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:a[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.wp.i18n,a=document.querySelector("#contact-form-editor"),r=window.wp.apiFetch;var c=e.n(r);const o=e=>{const t=document.createElement("span");return t.classList.add("icon-in-circle"),t.setAttribute("aria-hidden","true"),t.append(e),t},n=e=>e.replace(/[^0-9a-z]+/gi,"-"),l=e=>{const t=document.querySelector(`#${e.dataset?.toggle}`);t&&(e.checked?t.classList.remove("hidden"):t.classList.add("hidden"))},i=()=>{document.querySelectorAll("#contact-form-editor .config-error, #misc-publishing-actions .config-error").forEach((e=>{e.remove()})),document.querySelectorAll("#contact-form-editor [data-config-field]").forEach((e=>{const t=e.dataset.configField;d(t).length?(e.setAttribute("aria-invalid","true"),e.setAttribute("aria-describedby",n(`wpcf7-config-error-for-${t}`)),e.after(u(t))):e.removeAttribute("aria-invalid")})),document.querySelectorAll("#contact-form-editor-tabs [data-panel]").forEach((e=>{e.querySelectorAll(".icon-in-circle").forEach((e=>{e.remove()})),s(e.dataset.panel)&&e.querySelector("a")?.append(o("!"))}));let e=0;if(document.querySelectorAll("#contact-form-editor .contact-form-editor-panel").forEach((a=>{const r=s(a.id);if(r){e+=r;const c=document.createElement("div");c.classList.add("config-error"),c.append(o("!"),(0,t.sprintf)((0,t._n)("%d configuration error detected in this tab panel.","%d configuration errors detected in this tab panel.",r,"contact-form-7"),r)),a.prepend(c)}})),e){const a=document.createElement("div");a.classList.add("misc-pub-section","config-error");const r=document.createElement("a");r.setAttribute("href",wpcf7.configValidator.docUrl),r.append((0,t.__)("How to resolve?","contact-form-7")),a.append(o("!"),(0,t.sprintf)((0,t._n)("%d configuration error detected.","%d configuration errors detected.",e,"contact-form-7"),e),document.createElement("br"),r),document.querySelector("#misc-publishing-actions")?.append(a)}},s=e=>document.querySelectorAll(`#${e} ul.config-error li`)?.length,d=e=>{const t=[];for(const a in wpcf7.configValidator.errors)a===e&&t.push(...wpcf7.configValidator.errors[a]);return t},u=e=>{if(!e)return"";const t=document.createElement("ul");return t.setAttribute("id",n(`wpcf7-config-error-for-${e}`)),t.classList.add("config-error"),d(e).forEach((e=>{if(!e.message)return;const a=document.createElement("li");if(a.append(o("!")),e.link){const t=document.createElement("a");t.setAttribute("href",e.link),t.append(e.message),a.append(" ",t)}else a.append(" ",e.message);t.append(a)})),t},m=document.querySelector("#wpcf7-welcome-panel"),p=e=>{const t=m.querySelector("#welcomepanelnonce")?.value;if(!t)return;const a=new FormData;a.append("action","wpcf7-update-welcome-panel"),a.append("visible",e),a.append("welcomepanelnonce",t),fetch(new Request(ajaxurl,{method:"POST",body:a})),e?m.classList.remove("hidden"):m.classList.add("hidden")},f=e=>{var t;const a=e.dataset.id,r=e.querySelector('[name="name"]');let c=null!==(t=r?.value.trim())&&void 0!==t?t:"";r&&(c||(c=`${a}-${Math.floor(1e3*Math.random())}`),r.value=c),e.querySelectorAll(".tag").forEach((t=>{const a=e.querySelector('[name="tagtype"]')?.value||t.name;a&&(t.value=v(a,e))})),e.querySelectorAll("span.mail-tag").forEach((e=>{e.innerText=`[${c}]`})),e.querySelectorAll("input.mail-tag").forEach((e=>{e.value=`[${c}]`}))},v=(e,t)=>{var a,r,c;const o=null!==(a=t.querySelector(`.scope.${e}`))&&void 0!==a?a:t,n=e+(t.querySelector('[name="required"]:checked')?"*":""),l=null!==(r=t.querySelector('[name="name"]')?.value)&&void 0!==r?r:"",i=[];o.querySelectorAll(".option").forEach((e=>{"checkbox"===e.type?e.checked&&i.push(e.name):"radio"===e.type?e.checked&&!e.classList.contains("default")&&i.push(`${e.name}:${e.value}`):""!==e.value&&(e.classList.contains("filetype")?i.push(`${e.name}:${e.value.split(/[,|\s]+/).join("|")}`):e.classList.contains("color")?i.push(`${e.name}:#${e.value}`):"class"===e.name?e.value.split(" ").forEach((e=>{i.push(`class:${e}`)})):i.push(`${e.name}:${e.value}`))})),"radio"===e&&i.push("default:1");const s=null!==(c=o.querySelector('[name="values"]')?.value.split("\n").map((e=>e.trim())).filter((e=>""!==e)).map((e=>`"${e.replace(/["]/g,""")}"`)))&&void 0!==c?c:[],d=[n,l,i.join(" "),s.join(" ")].map((e=>e.trim())).filter((e=>""!==e)),u=o.querySelector('[name="content"]')?.value.trim();return u?`[${d.join(" ")}] ${u} [/${n}]`:`[${d.join(" ")}]`},g=e=>{const t=h(e);t?(e.querySelectorAll('[data-tag-part="tag"]').forEach((e=>{e.value=t})),e.querySelectorAll('[data-taggen="insert-tag"]').forEach((e=>{e.disabled=!1})),e.querySelectorAll('[data-tag-part="mail-tag"]').forEach((t=>{const a=e.querySelector('[data-tag-part="name"]');a&&(t.innerText=`[${a.value.trim()}]`)}))):(e.querySelectorAll('[data-tag-part="tag"]').forEach((e=>{e.value=""})),e.querySelectorAll('[data-taggen="insert-tag"]').forEach((e=>{e.disabled=!0})))},h=e=>{var t,a;const r=e.querySelector('[data-tag-part="basetype"]')?.value.trim();if(!r)return;if(e.querySelector(":invalid"))return;let c=r;const o=e.querySelector('[data-tag-part="type-suffix"]');o&&(["checkbox","radio"].includes(o?.type)?c+=o.checked?o.value.trim():"":c+=o.value.trim());const n=e.querySelector('[data-tag-part="name"]');let l=null!==(t=n?.value.trim())&&void 0!==t?t:"";n&&(l||(l=`${r}-${Math.floor(1e3*Math.random())}`),n.value=l);const i=[];e.querySelectorAll('[data-tag-part="option"]').forEach((e=>{const t=e.dataset.tagOption?.trim();t&&(["checkbox","radio"].includes(e?.type)&&!e.checked||t.split(" ").forEach((t=>{t.endsWith(":")?e.value?.split(" ").forEach((e=>{(e=e.trim())&&i.push(t+e)})):i.push(t)})))}));const s=null!==(a=e.querySelector('[data-tag-part="value"]')?.value.split("\n").map((e=>e.trim())).filter((e=>""!==e)).map((e=>`"${e.replace(/["]/g,""")}"`)))&&void 0!==a?a:[],d=[c,l,i.join(" "),s.join(" ")].map((e=>e.trim())).filter((e=>""!==e)),u=e.querySelector('[data-tag-part="content"]')?.value.trim();return u?`[${d.join(" ")}] ${u} [/${c}]`:`[${d.join(" ")}]`},y=e=>{const t=document.querySelector("#wpcf7-admin-form-element");if(!t)return;let a=!1;t.querySelectorAll("input, textarea, select").forEach((e=>{if(!a)switch(e.type){case"button":case"hidden":case"image":case"reset":case"search":case"submit":break;case"checkbox":case"radio":a=e.defaultChecked!==e.checked;break;case"select-multiple":case"select-one":e.querySelectorAll("option").forEach((e=>{a||e.defaultSelected===e.selected||(a=!0)}));break;default:a=e.defaultValue!==e.value}})),a&&e.preventDefault()};document.addEventListener("DOMContentLoaded",(e=>{a&&a.querySelectorAll(':scope > [role="tablist"]').forEach((e=>{const t=e.querySelectorAll(':scope > [role="tab"]');let r=parseInt(e.dataset.activeTab);e.addEventListener("keydown",(a=>{["ArrowLeft","ArrowRight"].includes(a.key)&&(t[r].setAttribute("tabindex","-1"),"ArrowLeft"===a.key&&(r-=1,r<0&&(r=t.length-1)),"ArrowRight"===a.key&&(r+=1,t.length<=r&&(r=0)),t[r].setAttribute("tabindex","0"),t[r].focus(),e.dataset.activeTab=r)})),t.forEach((t=>{t.addEventListener("click",(r=>{const c=t.getAttribute("aria-controls");if(!c)return;const o=c.split(" ").reduceRight(((e,t)=>{const r=a.querySelector(`#${t}`);return r&&(e=r),e}),null);o&&(e.querySelectorAll(':scope > [aria-selected="true"]').forEach((e=>{e.setAttribute("aria-selected","false")})),t.setAttribute("aria-selected","true"),a.querySelectorAll(':scope > [role="tabpanel"]').forEach((e=>{e.setAttribute("hidden","hidden")})),o.removeAttribute("hidden"),document.querySelectorAll('input[name="active-tab"]').forEach((e=>{e.value=o.id})))}))}))})),document.querySelectorAll("#contact-form-editor [data-config-field]").forEach((e=>{e.addEventListener("change",(e=>{const t=document.querySelector('[name="post_ID"]')?.value;t&&0{const{namespace:t}=wpcf7.apiSettings,a=`/${t}/contact-forms/${e}`,r=new FormData;document.querySelectorAll("#contact-form-editor [data-config-field]").forEach((e=>{const t=e.name?.replace(/^wpcf7-/,"").replace(/-/g,"_");if(!t)return;let a;["checkbox","radio"].includes(e.type)?e.checked&&(a=e.value):a=e.value,void 0!==a&&(t.endsWith("[]")?r.append(t,a):r.set(t,a))})),r.set("context","dry-run"),c()({path:a,method:"POST",body:r}).then((e=>{wpcf7.configValidator.errors=e.config_errors,i()}))})(t)}))})),i(),(()=>{if(!m)return;const e=document.querySelector("#wpcf7-welcome-panel-show");m.querySelectorAll(".welcome-panel-close").forEach((t=>{t.addEventListener("click",(t=>{p(0),e?.removeAttribute("checked"),t.preventDefault()}))})),e?.addEventListener("click",(t=>{p(e?.checked?1:0)}))})(),document.querySelectorAll('[data-taggen="open-dialog"]').forEach((e=>{e.addEventListener("click",(t=>{const a=document.querySelector(`#${e.dataset.target}`);if(a){const e=a.querySelector("form.tag-generator-panel");e&&("1"===e.dataset.version?(e=>{f(e),e.querySelectorAll(".control-box").forEach((t=>{t.addEventListener("change",(t=>{var a;"name"===(a=t.target).name&&(a.value=a.value.replace(/[^0-9a-zA-Z:._-]/g,"").replace(/^[^a-zA-Z]+/,"")),a.classList.contains("numeric")&&(a.value=a.value.replace(/[^0-9.-]/g,"")),a.classList.contains("idvalue")&&(a.value=a.value.replace(/[^-0-9a-zA-Z_]/g,"")),a.classList.contains("classvalue")&&(a.value=a.value.split(" ").map((e=>e.replace(/[^-0-9a-zA-Z_]/g,""))).join(" ").replace(/\s+/g," ").trim()),a.classList.contains("color")&&(a.value=a.value.replace(/[^0-9a-fA-F]/g,"")),a.classList.contains("filesize")&&(a.value=a.value.replace(/[^0-9kKmMbB]/g,"")),a.classList.contains("filetype")&&(a.value=a.value.replace(/[^0-9a-zA-Z.,|\s]/g,"")),a.classList.contains("date")&&(a.value.match(/^\d{4}-\d{2}-\d{2}$/)||(a.value="")),"values"===a.name&&(a.value=a.value.trim()),f(e)}))}))})(e):"2"===e.dataset.version&&(e=>{var t;null!==(t=e.reset())&&void 0!==t||g(e),e.querySelectorAll(".control-box").forEach((t=>{t.addEventListener("change",(t=>{g(e)})),t.addEventListener("keyup",(t=>{var a;"text"!==(null!==(a=t.target.type)&&void 0!==a?a:"")&&"textarea"!==t.target.tagName?.toLowerCase()||g(e)}))}))})(e)),a.showModal()}}))})),document.querySelectorAll("dialog.tag-generator-dialog").forEach((e=>{e.querySelectorAll('[data-taggen="close-dialog"]').forEach((t=>{t.addEventListener("click",(t=>e.close("")))})),e.querySelectorAll('[data-taggen="insert-tag"], .insert-tag').forEach((t=>{t.addEventListener("click",(t=>{const a=e.querySelector('[data-tag-part="tag"], .tag');e.close(a?.value)}))})),e.addEventListener("close",(t=>{var a;const r=document.querySelector("textarea#wpcf7-form");if(null===r)return;if(""===e.returnValue)return;const c=null!==(a=r.selectionEnd)&&void 0!==a?a:0;0===c&&(e.returnValue+="\n\n"),r.value=r.value.substring(0,c)+e.returnValue+r.value.substring(c),r.selectionStart=c,r.selectionEnd=c+e.returnValue.length,r.focus()}))})),(()=>{const e=document.querySelector("#wpcf7-admin-form-element");e&&(window.addEventListener("beforeunload",y),e.addEventListener("submit",(e=>{e.submitter?.name&&"wpcf7-copy"===e.submitter.name||window.removeEventListener("beforeunload",y)})))})();const r=document.querySelector("input#title");r&&""===r.value&&r.focus(),document.querySelector("#wpcf7-admin-form-element")?.addEventListener("submit",(e=>{const a=document.querySelector('#wpcf7-admin-form-element [name="action"]'),r=document.querySelector('#wpcf7-admin-form-element [name="_wpnonce"]');"wpcf7-save"===e.submitter?.name&&(a&&(a.value="save"),r&&(r.value=wpcf7.nonce.save),document.querySelectorAll("#wpcf7-admin-form-element #publishing-action .spinner").forEach((e=>{e.classList.add("is-active")}))),"wpcf7-copy"===e.submitter?.name&&(a&&(a.value="copy"),r&&(r.value=wpcf7.nonce.copy)),"wpcf7-delete"===e.submitter?.name&&(window.confirm((0,t.__)("You are about to delete this contact form.\n 'Cancel' to stop, 'OK' to delete.","contact-form-7"))?(a&&(a.value="delete"),r&&(r.value=wpcf7.nonce.delete)):e.preventDefault())})),document.querySelectorAll('.contact-form-editor-box-mail span.mailtag, [data-tag-part="mail-tag"]').forEach((e=>{e.addEventListener("click",(t=>{const a=document.createRange();a.selectNodeContents(e),window.getSelection().addRange(a)}))})),document.querySelectorAll("input.selectable").forEach((e=>{e.addEventListener("click",(t=>{e.focus(),e.select()}))})),document.querySelectorAll("[data-toggle]").forEach((e=>{l(e),e.addEventListener("change",(t=>{l(e)}))})),document.querySelectorAll("#wpcf7-sendinblue-enable-contact-list, #wpcf7-sendinblue-enable-transactional-email").forEach((e=>{e.addEventListener("change",(t=>{e.checked?e.closest("tr").classList.remove("inactive"):e.closest("tr").classList.add("inactive")}))}))}))})(); \ No newline at end of file diff --git a/wp-content/plugins/contact-form-7/admin/includes/tag-generator.php b/wp-content/plugins/contact-form-7/admin/includes/tag-generator.php new file mode 100644 index 0000000..066b5c1 --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/includes/tag-generator.php @@ -0,0 +1,627 @@ + '1', + ) ); + + $this->panels[$id] = array( + 'title' => $title, + 'content' => 'tag-generator-panel-' . $id, + 'options' => $options, + 'callback' => $callback, + ); + + if ( version_compare( $options['version'], '2', '<' ) ) { + $message = sprintf( + /* translators: 1: version, 2: tag generator title */ + __( 'Use of tag generator instances older than version 2 is deprecated. Version %1$s instance (%2$s) detected.', 'contact-form-7' ), + $options['version'], + $title + ); + + wp_trigger_error( __METHOD__, $message, E_USER_DEPRECATED ); + } + + return true; + } + + + /** + * Renders form-tag generator calling buttons. + */ + public function print_buttons() { + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'span', array( + 'id' => 'tag-generator-list', + 'class' => 'hide-if-no-js', + ) ); + + foreach ( (array) $this->panels as $panel ) { + $formatter->append_start_tag( 'button', array( + 'type' => 'button', + 'data-taggen' => 'open-dialog', + 'data-target' => $panel['content'], + 'title' => sprintf( + /* translators: %s: title of form-tag */ + __( 'Form-tag Generator: %s', 'contact-form-7' ), + $panel['title'] + ), + ) ); + + $formatter->append_preformatted( esc_html( $panel['title'] ) ); + } + + $formatter->print(); + } + + + /** + * Renders form-tag generator dialog panels (hidden until called). + */ + public function print_panels( WPCF7_ContactForm $contact_form ) { + $formatter = new WPCF7_HTMLFormatter( array( + 'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array( + 'dialog' => array( + 'id' => true, + 'class' => true, + ), + 'form' => array( + 'method' => true, + 'class' => true, + 'data-*' => true, + ), + ) ), + ) ); + + foreach ( (array) $this->panels as $id => $panel ) { + $callback = $panel['callback']; + + $options = array_merge( $panel['options'], array( + 'id' => $id, + 'title' => $panel['title'], + 'content' => $panel['content'], + ) ); + + if ( is_callable( $callback ) ) { + $formatter->append_start_tag( 'dialog', array( + 'id' => $options['content'], + 'class' => 'tag-generator-dialog', + ) ); + + $formatter->append_start_tag( 'button', array( + 'class' => 'close-button', + 'title' => __( 'Close this dialog box', 'contact-form-7' ), + 'data-taggen' => 'close-dialog', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Close', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'button' ); + + $formatter->append_start_tag( 'form', array( + 'method' => 'dialog', + 'class' => 'tag-generator-panel', + 'data-id' => $options['id'], + 'data-version' => $options['version'], + ) ); + + $formatter->call_user_func( $callback, $contact_form, $options ); + + $formatter->close_all_tags(); + } + } + + $formatter->print(); + } + +} + + +/** + * Class helps to implement a form-tag generator content. + */ +class WPCF7_TagGeneratorGenerator { + + private $key = ''; + + + /** + * The constructor. + */ + public function __construct( $key ) { + $this->key = $key; + } + + + /** + * Returns a unique reference ID. + */ + public function ref( $suffix = '' ) { + $ref = sprintf( '%s-%s', $this->key, $suffix ); + $ref = strtolower( $ref ); + $ref = preg_replace( '/[^0-9a-z-]/', '', $ref ); + $ref = preg_replace( '/[-]+/', '-', $ref ); + $ref = trim( $ref, '-' ); + return $ref; + } + + + /** + * Calls one of the template methods. + */ + public function print( $part, $options = '' ) { + if ( is_callable( array( $this, $part ) ) ) { + call_user_func( array( $this, $part ), $options ); + } + } + + + /** + * Template method for field type field. + */ + private function field_type( $options = '' ) { + $options = wp_parse_args( $options, array( + 'with_required' => false, + 'with_optional' => false, + 'select_options' => array(), + ) ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend', array( + 'id' => $this->ref( 'type-legend' ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Field type', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'select', array( + 'data-tag-part' => 'basetype', + 'aria-labelledby' => $this->ref( 'type-legend' ), + ) ); + + foreach ( (array) $options['select_options'] as $basetype => $title ) { + $formatter->append_start_tag( 'option', array( + 'value' => $basetype, + ) ); + + $formatter->append_preformatted( esc_html( $title ) ); + } + + $formatter->end_tag( 'select' ); + + if ( $options['with_required'] ) { + $formatter->append_start_tag( 'br' ); + $formatter->append_start_tag( 'label' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'data-tag-part' => 'type-suffix', + 'value' => '*', + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'This is a required field.', 'contact-form-7' ) ) + ); + } + + if ( $options['with_optional'] ) { + $formatter->append_start_tag( 'br' ); + $formatter->append_start_tag( 'label' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'data-tag-part' => 'option', + 'data-tag-option' => 'optional', + 'checked' => true, + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'This checkbox is optional.', 'contact-form-7' ) ) + ); + } + + $formatter->print(); + } + + + /** + * Template method for field name field. + */ + private function field_name( $options = '' ) { + $options = wp_parse_args( $options, array( + 'ask_if' => '', + ) ); + +?> +
+ + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ 'number', + 'title' => __( 'Length', 'contact-form-7' ), + 'min_option' => 'minlength:', + 'max_option' => 'maxlength:', + 'accept_minus' => false, + ) ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend' ); + $formatter->append_preformatted( esc_html( $options['title'] ) ); + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'label' ); + + $formatter->append_preformatted( + esc_html( __( 'Min', 'contact-form-7' ) ) + ); + + $formatter->append_whitespace(); + + $formatter->append_start_tag( 'input', array( + 'type' => $options['type'], + 'data-tag-part' => 'option', + 'data-tag-option' => $options['min_option'], + 'min' => $options['accept_minus'] ? null : 0, + ) ); + + $formatter->end_tag( 'label' ); + + $formatter->append_preformatted( ' ⇔ ' ); + + $formatter->append_start_tag( 'label' ); + + $formatter->append_preformatted( + esc_html( __( 'Max', 'contact-form-7' ) ) + ); + + $formatter->append_whitespace(); + + $formatter->append_start_tag( 'input', array( + 'type' => $options['type'], + 'data-tag-part' => 'option', + 'data-tag-option' => $options['max_option'], + 'min' => $options['accept_minus'] ? null : 0, + ) ); + + $formatter->end_tag( 'label' ); + + $formatter->print(); + } + + + /** + * Template method for default value field. + */ + private function default_value( $options = '' ) { + $options = wp_parse_args( $options, array( + 'type' => 'text', + 'title' => __( 'Default value', 'contact-form-7' ), + 'with_placeholder' => false, + 'use_content' => false, + ) ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend', array( + 'id' => $this->ref( 'value-legend' ), + ) ); + + $formatter->append_preformatted( esc_html( $options['title'] ) ); + + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'input', array( + 'type' => $options['type'], + 'data-tag-part' => $options['use_content'] ? 'content' : 'value', + 'aria-labelledby' => $this->ref( 'value-legend' ), + ) ); + + if ( $options['with_placeholder'] ) { + $formatter->append_start_tag( 'br' ); + $formatter->append_start_tag( 'label' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'data-tag-part' => 'option', + 'data-tag-option' => 'placeholder', + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'Use this text as the placeholder.', 'contact-form-7' ) ) + ); + } + + $formatter->print(); + } + + + /** + * Template method for selectable values useful for checkboxes or a menu. + */ + private function selectable_values( $options = '' ) { + $options = wp_parse_args( $options, array( + 'first_as_label' => false, + 'use_label_element' => false, + ) ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend', array( + 'id' => $this->ref( 'selectable-values-legend' ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Selectable values', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'span', array( + 'id' => $this->ref( 'selectable-values-description' ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'One item per line.', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'span' ); + + $formatter->append_start_tag( 'br' ); + + $formatter->append_start_tag( 'textarea', array( + 'required' => true, + 'data-tag-part' => 'value', + 'aria-labelledby' => $this->ref( 'selectable-values-legend' ), + 'aria-describedby' => $this->ref( 'selectable-values-description' ), + ) ); + + $formatter->append_preformatted( + esc_html( __( "Option 1\nOption 2\nOption 3", 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'textarea' ); + + if ( $options['first_as_label'] ) { + $formatter->append_start_tag( 'br' ); + $formatter->append_start_tag( 'label' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'checked' => 'checked' === $options['first_as_label'], + 'data-tag-part' => 'option', + 'data-tag-option' => 'first_as_label', + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'Use the first item as a label.', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'label' ); + } + + if ( $options['use_label_element'] ) { + $formatter->append_start_tag( 'br' ); + $formatter->append_start_tag( 'label' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'checked' => 'checked' === $options['use_label_element'], + 'data-tag-part' => 'option', + 'data-tag-option' => 'use_label_element', + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'Wrap each item with a label element.', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'label' ); + } + + $formatter->print(); + } + + + /** + * Template method for insert-box content including the result form-tag. + */ + private function insert_box_content( $options = '' ) { + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'div', array( + 'class' => 'flex-container', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'class' => 'code selectable', + 'readonly' => true, + 'data-tag-part' => 'tag', + 'aria-label' => __( 'The form-tag to be inserted into the form template', 'contact-form-7' ), + ) ); + + $formatter->append_whitespace(); + + $formatter->append_start_tag( 'button', array( + 'type' => 'button', + 'class' => 'button button-primary', + 'data-taggen' => 'insert-tag', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Insert Tag', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'button' ); + + $formatter->print(); + } + + + /** + * Template method for a tip message about mail-tag. + */ + private function mail_tag_tip( $options = '' ) { + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'p', array( + 'class' => 'mail-tag-tip', + ) ); + + $formatter->append_preformatted( sprintf( + /* translators: %s: mail-tag corresponding to the form-tag */ + esc_html( __( 'To use the user input in the email, insert the corresponding mail-tag %s into the email template.', 'contact-form-7' ) ), + '' + ) ); + + $formatter->print(); + } + +} diff --git a/wp-content/plugins/contact-form-7/admin/includes/welcome-panel.php b/wp-content/plugins/contact-form-7/admin/includes/welcome-panel.php new file mode 100644 index 0000000..ae6ffc9 --- /dev/null +++ b/wp-content/plugins/contact-form-7/admin/includes/welcome-panel.php @@ -0,0 +1,280 @@ +content(); + + if ( is_array( $content ) ) { + $content = implode( "\n\n", $content ); + } + + $content = wp_kses_post( $content ); + $content = wptexturize( $content ); + $content = convert_chars( $content ); + $content = wpautop( $content ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'div', array( + 'class' => 'welcome-panel-column', + ) ); + + $formatter->append_start_tag( 'h3' ); + + $formatter->append_start_tag( 'span', array( + 'class' => sprintf( 'dashicons dashicons-%s', $this->icon() ), + 'aria-hidden' => 'true', + ) ); + + $formatter->end_tag( 'span' ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( $this->title() ); + + $formatter->end_tag( 'h3' ); + + $formatter->append_preformatted( $content ); + + $formatter->print(); + } +} + + +class WPCF7_WelcomePanelColumn_AntiSpam extends WPCF7_WelcomePanelColumn { + + protected function icon() { + return 'shield'; + } + + protected function title() { + return __( 'Getting spammed? You have protection.', 'contact-form-7' ); + } + + protected function content() { + return array( + __( 'Spammers target everything; your contact forms are not an exception. Before you get spammed, protect your contact forms with the powerful anti-spam features Contact Form 7 provides.', 'contact-form-7' ), + sprintf( + /* translators: 1: URL to support page about Akismet, 2: Cloudflare Turnstile, 3: Disallowed list */ + __( 'Contact Form 7 supports spam-filtering with Akismet. Cloudflare Turnstile blocks annoying spambots. Plus, using disallowed list, you can block messages containing specified keywords or those sent from specified IP addresses.', 'contact-form-7' ), + __( 'https://contactform7.com/spam-filtering-with-akismet/', 'contact-form-7' ), + __( 'https://contactform7.com/turnstile-integration/', 'contact-form-7' ), + __( 'https://contactform7.com/comment-blacklist/', 'contact-form-7' ) + ), + ); + } +} + + +class WPCF7_WelcomePanelColumn_Donation extends WPCF7_WelcomePanelColumn { + + protected function icon() { + return 'megaphone'; + } + + protected function title() { + return __( 'Contact Form 7 needs your support.', 'contact-form-7' ); + } + + protected function content() { + return array( + __( 'It is hard to continue to maintain this plugin without support from users like you.', 'contact-form-7' ), + sprintf( + /* translators: %s: URL to support page about ways to contribute */ + __( 'There are several ways for you to contribute to the project: testing, coding, translating it into your local languages, helping other users, financial donations, etc, etc. We equally welcome you regardless of the way you contribute.', 'contact-form-7' ), + __( 'https://contactform7.com/contributing/', 'contact-form-7' ) + ), + ); + } +} + + +class WPCF7_WelcomePanelColumn_Flamingo extends WPCF7_WelcomePanelColumn { + + protected function icon() { + return 'editor-help'; + } + + protected function title() { + return __( 'Before you cry over spilt mail…', 'contact-form-7' ); + } + + protected function content() { + return array( + __( 'Contact Form 7 does not store submitted messages anywhere. Therefore, you may lose important messages forever if your mail server has issues or you make a mistake in mail configuration.', 'contact-form-7' ), + sprintf( + /* translators: %s: URL to support page about the Flamingo plugin */ + __( 'Install a message storage plugin before this happens to you. Flamingo saves all messages through contact forms into the database. Flamingo is a free WordPress plugin created by the same author as Contact Form 7.', 'contact-form-7' ), + __( 'https://contactform7.com/save-submitted-messages-with-flamingo/', 'contact-form-7' ) + ), + ); + } +} + + +class WPCF7_WelcomePanelColumn_Integration extends WPCF7_WelcomePanelColumn { + + protected function icon() { + return 'superhero-alt'; + } + + protected function title() { + return __( 'You have strong allies to back you up.', 'contact-form-7' ); + } + + protected function content() { + return array( + sprintf( + /* translators: %s: URL to support page about the Brevo integration */ + __( 'Your contact forms will become more powerful and versatile by integrating them with external APIs. With CRM and email marketing services, you can build your own contact lists (Brevo).', 'contact-form-7' ), + __( 'https://contactform7.com/sendinblue-integration/', 'contact-form-7' ) + ), + sprintf( + /* translators: 1: URL to support page about Cloudflare Turnstile, 2: Stripe */ + __( 'With help from cloud-based machine learning, anti-spam services will protect your forms (Cloudflare Turnstile). Even payment services are natively supported (Stripe).', 'contact-form-7' ), + __( 'https://contactform7.com/turnstile-integration/', 'contact-form-7' ), + __( 'https://contactform7.com/stripe-integration/', 'contact-form-7' ) + ), + ); + } +} + + +function wpcf7_welcome_panel() { + $columns = array(); + + $flamingo_is_active = defined( 'FLAMINGO_VERSION' ); + + $sendinblue_is_active = false; + + if ( + class_exists( 'WPCF7_Sendinblue' ) and + $sendinblue = WPCF7_Sendinblue::get_instance() + ) { + $sendinblue_is_active = $sendinblue->is_active(); + } + + if ( $flamingo_is_active and $sendinblue_is_active ) { + $columns[] = new WPCF7_WelcomePanelColumn_AntiSpam(); + $columns[] = new WPCF7_WelcomePanelColumn_Donation(); + } elseif ( $flamingo_is_active ) { + $columns[] = new WPCF7_WelcomePanelColumn_Integration(); + $columns[] = new WPCF7_WelcomePanelColumn_AntiSpam(); + } elseif ( $sendinblue_is_active ) { + $columns[] = new WPCF7_WelcomePanelColumn_Flamingo(); + $columns[] = new WPCF7_WelcomePanelColumn_AntiSpam(); + } else { + $columns[] = new WPCF7_WelcomePanelColumn_Flamingo(); + $columns[] = new WPCF7_WelcomePanelColumn_Integration(); + } + + $classes = 'wpcf7-welcome-panel'; + + $vers = (array) get_user_meta( get_current_user_id(), + 'wpcf7_hide_welcome_panel_on', true + ); + + if ( wpcf7_version_grep( wpcf7_version( 'only_major=1' ), $vers ) ) { + $classes .= ' hidden'; + } + +?> +
+ + + +
+
+print_content(); + } + +?> +
+
+
+id ) { + return $screen_settings; + } + + $vers = (array) get_user_meta( get_current_user_id(), + 'wpcf7_hide_welcome_panel_on', true + ); + + $checkbox_id = 'wpcf7-welcome-panel-show'; + $checked = ! in_array( wpcf7_version( 'only_major=1' ), $vers, true ); + + $checkbox = sprintf( + '', + wpcf7_format_atts( array( + 'id' => $checkbox_id, + 'type' => 'checkbox', + 'checked' => $checked, + ) ) + ); + + $screen_settings .= sprintf( ' +
+%1$s + +
', + esc_html( __( 'Welcome panel', 'contact-form-7' ) ), + esc_attr( $checkbox_id ), + $checkbox, + esc_html( __( 'Show welcome panel', 'contact-form-7' ) ) + ); + + return $screen_settings; +} diff --git a/wp-content/plugins/contact-form-7/assets/icon.png b/wp-content/plugins/contact-form-7/assets/icon.png new file mode 100644 index 0000000..f66eefa Binary files /dev/null and b/wp-content/plugins/contact-form-7/assets/icon.png differ diff --git a/wp-content/plugins/contact-form-7/assets/icon.svg b/wp-content/plugins/contact-form-7/assets/icon.svg new file mode 100644 index 0000000..33df0bd --- /dev/null +++ b/wp-content/plugins/contact-form-7/assets/icon.svg @@ -0,0 +1 @@ + diff --git a/wp-content/plugins/contact-form-7/includes/block-editor/block-editor.php b/wp-content/plugins/contact-form-7/includes/block-editor/block-editor.php new file mode 100644 index 0000000..05a1794 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/block-editor/block-editor.php @@ -0,0 +1,13 @@ + array( + 'react-jsx-runtime', + 'wp-api-fetch', + 'wp-block-editor', + 'wp-blocks', + 'wp-components', + 'wp-element', + 'wp-i18n', + 'wp-url', + ), + 'version' => WPCF7_VERSION, +); diff --git a/wp-content/plugins/contact-form-7/includes/block-editor/index.js b/wp-content/plugins/contact-form-7/includes/block-editor/index.js new file mode 100644 index 0000000..eb68299 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/block-editor/index.js @@ -0,0 +1 @@ +(()=>{"use strict";var t={n:e=>{var l=e&&e.__esModule?()=>e.default:()=>e;return t.d(l,{a:l}),l},d:(e,l)=>{for(var a in l)t.o(l,a)&&!t.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:l[a]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)};const e=window.wp.i18n,l=window.wp.blocks,a=window.wp.blockEditor,r=window.ReactJSXRuntime,o=(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 242.5 239.46",children:[(0,r.jsx)("defs",{children:(0,r.jsx)("clipPath",{id:"clip-path",transform:"translate(1.72)",children:(0,r.jsx)("circle",{className:"cls-1",cx:"119.73",cy:"119.73",r:"116.15",fill:"none"})})}),(0,r.jsx)("g",{id:"Layer_2","data-name":"Layer 2",children:(0,r.jsxs)("g",{id:"Layer_1","data-name":"Layer 1",children:[(0,r.jsxs)("g",{className:"cls-2",clipPath:"url(#clip-path)",children:[(0,r.jsx)("circle",{className:"cls-3",cx:"121.45",cy:"119.73",r:"116.15",fill:"#33c6f4"}),(0,r.jsx)("path",{className:"cls-4",d:"M239.32,167.79c-53.41-24-108.37-91.46-113-94.55s-10.84.77-10.84.77c-3.87-6.19-10.06.77-10.06.77C76.77,123.55.14,170.11.14,170.11S36.94,237.79,122,237.79C208.48,237.79,239.32,167.79,239.32,167.79Z",transform:"translate(1.72)",fill:"#1b447e"}),(0,r.jsx)("path",{className:"cls-5",d:"M67.48,116.58s15.48-7,12.38,4.65-15.48,28.64-11.61,29.41S83,140.58,86.06,142.12s5.42.78,3.87,6.2-3.1,9.29,0,9.29,5.42-7,9.29-13.94,10.06-3.87,12.38-1.55,9.29,15.49,14.71,13.94,8.51-8.52,6.19-24,1.55-20.12,1.55-20.12,4.64-2.32,13.16,8.51,24,27.09,26.31,26.32-10.83-17.8-7.74-19.35,15.48,2.32,21.68,7.74c0,0,2.12,8.87,2.12.36L126.31,73.24,115.47,74l-10.06.77S80.64,111.94,67.48,116.58Z",transform:"translate(1.72)",fill:"#fff"}),(0,r.jsx)("path",{className:"cls-6",d:"M239.32,170.11c-53.41-24-108.37-93.78-113-96.87s-10.84.77-10.84.77c-3.87-6.19-10.06.77-10.06.77C76.77,123.55.14,170.11.14,170.11",transform:"translate(1.72)",fill:"none",stroke:"#221e1f",strokeMiterlimit:"10",strokeWidth:"8px"})]}),(0,r.jsx)("circle",{className:"cls-6",cx:"121.45",cy:"119.73",r:"116.15",fill:"none",stroke:"#1b447e",strokeMiterlimit:"10",strokeWidth:"8px"})]})})]}),s=window.wp.element,c=window.wp.components,n=window.wp.apiFetch;var i=t.n(n);const m=window.wp.url,h=async t=>i()({path:(0,m.addQueryArgs)("/contact-form-7/v1/contact-forms",{posts_per_page:20,orderby:"modified",order:"DESC",...t})}).then((t=>t)),d=t=>{let e="[contact-form-7]";return t.hash?e=e.replace(/\]$/,` id="${t.hash}"]`):t.id&&(e=e.replace(/\]$/,` id="${t.id}"]`)),t.title&&(e=e.replace(/\]$/,` title="${t.title}"]`)),t.htmlId&&(e=e.replace(/\]$/,` html_id="${t.htmlId}"]`)),t.htmlName&&(e=e.replace(/\]$/,` html_name="${t.htmlName}"]`)),t.htmlTitle&&(e=e.replace(/\]$/,` html_title="${t.htmlTitle}"]`)),t.htmlClass&&(e=e.replace(/\]$/,` html_class="${t.htmlClass}"]`)),"raw_form"===t.output&&(e=e.replace(/\]$/,` output="${t.output}"]`)),e},p=t=>{const e=ajaxurl.replace(/\/admin-ajax\.php$/,"/admin.php");return(0,m.addQueryArgs)(e,{page:"wpcf7",post:t.id,action:"edit"})},f={from:[],to:[{type:"block",blocks:["core/shortcode"],transform:t=>{const e=d(t);return(0,l.createBlock)("core/shortcode",{text:e})}}]};(0,l.registerBlockType)("contact-form-7/contact-form-selector",{icon:o,transforms:f,edit:function({attributes:t,setAttributes:l}){const o=t=>t.reduce(((t,e)=>t.set(e.id,e)),new Map),[n,i]=(0,s.useState)((()=>o([])));return(0,s.useEffect)((()=>{h().then((t=>{i(o(t))}))}),[]),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(a.InspectorControls,{children:[t.id&&(0,r.jsx)(c.PanelBody,{title:t.title,children:(0,r.jsx)(c.ExternalLink,{href:p(t),children:(0,e.__)("Edit this contact form","contact-form-7")})}),t.id&&(0,r.jsxs)(c.PanelBody,{title:(0,e.__)("Form attributes","contact-form-7"),initialOpen:!1,children:[(0,r.jsx)(c.TextControl,{label:(0,e.__)("ID","contact-form-7"),value:t.htmlId,onChange:t=>l({htmlId:t}),help:(0,e.__)("Used for the id attribute value of the form element.","contact-form-7")}),(0,r.jsx)(c.TextControl,{label:(0,e.__)("Name","contact-form-7"),value:t.htmlName,onChange:t=>l({htmlName:t}),help:(0,e.__)("Used for the name attribute value of the form element.","contact-form-7")}),(0,r.jsx)(c.TextControl,{label:(0,e.__)("Title","contact-form-7"),value:t.htmlTitle,onChange:t=>l({htmlTitle:t}),help:(0,e.__)("Used for the aria-label attribute value of the form element.","contact-form-7")}),(0,r.jsx)(c.TextControl,{label:(0,e.__)("Class","contact-form-7"),value:t.htmlClass,onChange:t=>l({htmlClass:t}),help:(0,e.__)("Used for the class attribute value of the form element.","contact-form-7")})]})]}),(0,r.jsx)("div",{...(0,a.useBlockProps)({className:"components-placeholder",style:{marginTop:"28px",marginBottom:"28px"}}),children:(0,r.jsx)(c.ComboboxControl,{label:(0,e.__)("Select a contact form:","contact-form-7"),options:(t=>{const e=[];for(const[l,a]of t)e.push({value:l,label:a.title});return e})(n),value:t.id,onChange:t=>l({id:parseInt(t),hash:n.get(parseInt(t))?.hash,title:n.get(parseInt(t))?.title}),onFilterValueChange:t=>{h({search:t}).then((t=>{i(o(t))}))}})})]})},save:({attributes:t})=>{const e=d(t);return(0,r.jsx)("div",{...a.useBlockProps.save(),children:e})}})})(); \ No newline at end of file diff --git a/wp-content/plugins/contact-form-7/includes/capabilities.php b/wp-content/plugins/contact-form-7/includes/capabilities.php new file mode 100644 index 0000000..09a478b --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/capabilities.php @@ -0,0 +1,26 @@ + WPCF7_ADMIN_READ_WRITE_CAPABILITY, + 'wpcf7_edit_contact_forms' => WPCF7_ADMIN_READ_WRITE_CAPABILITY, + 'wpcf7_read_contact_form' => WPCF7_ADMIN_READ_CAPABILITY, + 'wpcf7_read_contact_forms' => WPCF7_ADMIN_READ_CAPABILITY, + 'wpcf7_delete_contact_form' => WPCF7_ADMIN_READ_WRITE_CAPABILITY, + 'wpcf7_delete_contact_forms' => WPCF7_ADMIN_READ_WRITE_CAPABILITY, + 'wpcf7_manage_integration' => 'manage_options', + 'wpcf7_submit' => 'read', + ); + + $meta_caps = apply_filters( 'wpcf7_map_meta_cap', $meta_caps ); + + $caps = array_diff( $caps, array_keys( $meta_caps ) ); + + if ( isset( $meta_caps[$cap] ) ) { + $caps[] = $meta_caps[$cap]; + } + + return $caps; +} diff --git a/wp-content/plugins/contact-form-7/includes/config-validator/actions.php b/wp-content/plugins/contact-form-7/includes/config-validator/actions.php new file mode 100644 index 0000000..d045f75 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/config-validator/actions.php @@ -0,0 +1,27 @@ + 'unsafe_email_without_protection', + ); + + foreach ( $contact_forms as $contact_form ) { + $config_validator = new WPCF7_ConfigValidator( $contact_form, $options ); + $config_validator->restore(); + $config_validator->validate(); + $config_validator->save(); + } + } +} diff --git a/wp-content/plugins/contact-form-7/includes/config-validator/additional-settings.php b/wp-content/plugins/contact-form-7/includes/config-validator/additional-settings.php new file mode 100644 index 0000000..0d0c788 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/config-validator/additional-settings.php @@ -0,0 +1,28 @@ +supports( 'deprecated_settings' ) ) { + $deprecated_settings_used = + $this->contact_form->additional_setting( 'on_sent_ok' ) || + $this->contact_form->additional_setting( 'on_submit' ); + + if ( $deprecated_settings_used ) { + $this->add_error( $section, 'deprecated_settings', + array( + 'message' => __( 'Deprecated settings are used.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'deprecated_settings' ); + } + } + } + +} diff --git a/wp-content/plugins/contact-form-7/includes/config-validator/form.php b/wp-content/plugins/contact-form-7/includes/config-validator/form.php new file mode 100644 index 0000000..a480456 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/config-validator/form.php @@ -0,0 +1,278 @@ +contact_form->prop( 'form' ); + + if ( $this->supports( 'multiple_controls_in_label' ) ) { + if ( $this->detect_multiple_controls_in_label( $section, $form ) ) { + $this->add_error( $section, 'multiple_controls_in_label', + array( + 'message' => __( 'Multiple form controls are in a single label element.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'multiple_controls_in_label' ); + } + } + + if ( $this->supports( 'unavailable_names' ) ) { + $ng_names = $this->detect_unavailable_names( $section, $form ); + + if ( $ng_names ) { + $this->add_error( $section, 'unavailable_names', + array( + 'message' => + /* translators: %names%: a list of form control names */ + __( 'Unavailable names (%names%) are used for form controls.', 'contact-form-7' ), + 'params' => array( 'names' => implode( ', ', $ng_names ) ), + ) + ); + } else { + $this->remove_error( $section, 'unavailable_names' ); + } + } + + if ( $this->supports( 'unavailable_html_elements' ) ) { + if ( $this->detect_unavailable_html_elements( $section, $form ) ) { + $this->add_error( $section, 'unavailable_html_elements', + array( + 'message' => __( 'Unavailable HTML elements are used in the form template.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'unavailable_html_elements' ); + } + } + + if ( $this->supports( 'dots_in_names' ) ) { + if ( $this->detect_dots_in_names( $section, $form ) ) { + $this->add_error( $section, 'dots_in_names', + array( + 'message' => __( 'Dots are used in form-tag names.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'dots_in_names' ); + } + } + + if ( $this->supports( 'colons_in_names' ) ) { + if ( $this->detect_colons_in_names( $section, $form ) ) { + $this->add_error( $section, 'colons_in_names', + array( + 'message' => __( 'Colons are used in form-tag names.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'colons_in_names' ); + } + } + + if ( $this->supports( 'upload_filesize_overlimit' ) ) { + if ( $this->detect_upload_filesize_overlimit( $section, $form ) ) { + $this->add_error( $section, 'upload_filesize_overlimit', + array( + 'message' => __( 'Uploadable file size exceeds PHP’s maximum acceptable size.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'upload_filesize_overlimit' ); + } + } + } + + + /** + * Detects errors of multiple form controls in a single label. + * + * @link https://contactform7.com/configuration-errors/multiple-controls-in-label/ + */ + public function detect_multiple_controls_in_label( $section, $content ) { + $pattern = '%(.+?)%s'; + + if ( preg_match_all( $pattern, $content, $matches ) ) { + $form_tags_manager = WPCF7_FormTagsManager::get_instance(); + + foreach ( $matches[1] as $insidelabel ) { + $tags = $form_tags_manager->scan( $insidelabel ); + $fields_count = 0; + + foreach ( $tags as $tag ) { + $is_multiple_controls_container = wpcf7_form_tag_supports( + $tag->type, 'multiple-controls-container' + ); + + $is_zero_controls_container = wpcf7_form_tag_supports( + $tag->type, 'zero-controls-container' + ); + + if ( $is_multiple_controls_container ) { + $fields_count += count( $tag->values ); + + if ( $tag->has_option( 'free_text' ) ) { + $fields_count += 1; + } + } elseif ( $is_zero_controls_container ) { + $fields_count += 0; + } elseif ( ! empty( $tag->name ) ) { + $fields_count += 1; + } + + if ( 1 < $fields_count ) { + return true; + } + } + } + } + + return false; + } + + + /** + * Detects errors of unavailable form-tag names. + * + * @link https://contactform7.com/configuration-errors/unavailable-names/ + */ + public function detect_unavailable_names( $section, $content ) { + $public_query_vars = array( 'm', 'p', 'posts', 'w', 'cat', + 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', + 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', + 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', + 'name', 'category_name', 'tag', 'feed', 'author_name', 'static', + 'pagename', 'page_id', 'error', 'attachment', 'attachment_id', + 'subpost', 'subpost_id', 'preview', 'robots', 'taxonomy', 'term', + 'cpage', 'post_type', 'embed', + ); + + $form_tags_manager = WPCF7_FormTagsManager::get_instance(); + + $ng_named_tags = $form_tags_manager->filter( $content, array( + 'name' => $public_query_vars, + ) ); + + $ng_names = array(); + + foreach ( $ng_named_tags as $tag ) { + $ng_names[] = sprintf( '"%s"', $tag->name ); + } + + if ( $ng_names ) { + return array_unique( $ng_names ); + } + + return false; + } + + + /** + * Detects errors of unavailable HTML elements. + * + * @link https://contactform7.com/configuration-errors/unavailable-html-elements/ + */ + public function detect_unavailable_html_elements( $section, $content ) { + $pattern = '%(?:]|)%i'; + + if ( preg_match( $pattern, $content ) ) { + return true; + } + + return false; + } + + + /** + * Detects errors of dots in form-tag names. + * + * @link https://contactform7.com/configuration-errors/dots-in-names/ + */ + public function detect_dots_in_names( $section, $content ) { + $form_tags_manager = WPCF7_FormTagsManager::get_instance(); + + $tags = $form_tags_manager->filter( $content, array( + 'feature' => 'name-attr', + ) ); + + foreach ( $tags as $tag ) { + if ( str_contains( $tag->raw_name, '.' ) ) { + return true; + } + } + + return false; + } + + + /** + * Detects errors of colons in form-tag names. + * + * @link https://contactform7.com/configuration-errors/colons-in-names/ + */ + public function detect_colons_in_names( $section, $content ) { + $form_tags_manager = WPCF7_FormTagsManager::get_instance(); + + $tags = $form_tags_manager->filter( $content, array( + 'feature' => 'name-attr', + ) ); + + foreach ( $tags as $tag ) { + if ( str_contains( $tag->raw_name, ':' ) ) { + return true; + } + } + + return false; + } + + + /** + * Detects errors of uploadable file size overlimit. + * + * @link https://contactform7.com/configuration-errors/upload-filesize-overlimit + */ + public function detect_upload_filesize_overlimit( $section, $content ) { + $upload_max_filesize = ini_get( 'upload_max_filesize' ); + + if ( ! $upload_max_filesize ) { + return false; + } + + $upload_max_filesize = strtolower( $upload_max_filesize ); + $upload_max_filesize = trim( $upload_max_filesize ); + + if ( ! preg_match( '/^(\d+)([kmg]?)$/', $upload_max_filesize, $matches ) ) { + return false; + } + + if ( 'k' === $matches[2] ) { + $upload_max_filesize = (int) $matches[1] * KB_IN_BYTES; + } elseif ( 'm' === $matches[2] ) { + $upload_max_filesize = (int) $matches[1] * MB_IN_BYTES; + } elseif ( 'g' === $matches[2] ) { + $upload_max_filesize = (int) $matches[1] * GB_IN_BYTES; + } else { + $upload_max_filesize = (int) $matches[1]; + } + + $form_tags_manager = WPCF7_FormTagsManager::get_instance(); + + $tags = $form_tags_manager->filter( $content, array( + 'basetype' => 'file', + ) ); + + foreach ( $tags as $tag ) { + if ( $upload_max_filesize < $tag->get_limit_option() ) { + return true; + } + } + + return false; + } + +} diff --git a/wp-content/plugins/contact-form-7/includes/config-validator/mail.php b/wp-content/plugins/contact-form-7/includes/config-validator/mail.php new file mode 100644 index 0000000..131810f --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/config-validator/mail.php @@ -0,0 +1,583 @@ + false, + 'callback' => + array( $this, 'replace_mail_tags_with_minimum_input_callback' ), + ) ); + + $content = new WPCF7_MailTaggedText( $content, $options ); + + return $content->replace_tags(); + } + + + /** + * Callback function for WPCF7_MailTaggedText. Replaces mail-tags with + * the most conservative inputs. + */ + public function replace_mail_tags_with_minimum_input_callback( $matches ) { + // allow [[foo]] syntax for escaping a tag + if ( '[' === $matches[1] and ']' === $matches[4] ) { + return substr( $matches[0], 1, -1 ); + } + + $tag = $matches[0]; + $tagname = $matches[2]; + $values = $matches[3]; + + $mail_tag = new WPCF7_MailTag( $tag, $tagname, $values ); + $field_name = $mail_tag->field_name(); + + $example_email = 'example@example.com'; + $example_text = 'example'; + $example_blank = ''; + + // for back-compat + $field_name = preg_replace( '/^wpcf7\./', '_', $field_name ); + + if ( '_site_admin_email' === $field_name ) { + return get_bloginfo( 'admin_email', 'raw' ); + + } elseif ( '_user_agent' === $field_name ) { + return $example_text; + + } elseif ( '_user_email' === $field_name ) { + return $this->contact_form->is_true( 'subscribers_only' ) + ? $example_email + : $example_blank; + + } elseif ( str_starts_with( $field_name, '_user_' ) ) { + return $this->contact_form->is_true( 'subscribers_only' ) + ? $example_text + : $example_blank; + + } elseif ( str_starts_with( $field_name, '_' ) ) { + return str_ends_with( $field_name, '_email' ) + ? $example_email + : $example_text; + + } + + static $opcalcset = array(); + + if ( ! isset( $opcalcset[$this->contact_form->id()] ) ) { + $opcalcset[$this->contact_form->id()] = + new WPCF7_MailTag_OutputCalculator( $this->contact_form ); + } + + $opcalc = $opcalcset[$this->contact_form->id()]; + $op = $opcalc->calc_output( $mail_tag ); + + if ( WPCF7_MailTag_OutputCalculator::email === $op ) { + return $example_email; + } elseif ( ! ( WPCF7_MailTag_OutputCalculator::blank & $op ) ) { + return $example_text; + } else { + return $example_blank; + } + } + + + /** + * Runs error detection for the mail sections. + */ + public function validate_mail( $template = 'mail' ) { + if ( + $this->contact_form->is_true( 'demo_mode' ) or + $this->contact_form->is_true( 'skip_mail' ) + ) { + return; + } + + $components = (array) $this->contact_form->prop( $template ); + + if ( ! $components ) { + return; + } + + if ( 'mail' !== $template and empty( $components['active'] ) ) { + return; + } + + $components = wp_parse_args( $components, array( + 'subject' => '', + 'sender' => '', + 'recipient' => '', + 'additional_headers' => '', + 'body' => '', + 'attachments' => '', + ) ); + + $this->validate_mail_subject( + $template, + $components['subject'] + ); + + $this->validate_mail_sender( + $template, + $components['sender'] + ); + + $this->validate_mail_recipient( + $template, + $components['recipient'] + ); + + $this->validate_mail_additional_headers( + $template, + $components['additional_headers'] + ); + + $this->validate_mail_body( + $template, + $components['body'] + ); + + $this->validate_mail_attachments( + $template, + $components['attachments'] + ); + } + + + /** + * Runs error detection for the mail subject section. + */ + public function validate_mail_subject( $template, $content ) { + $section = sprintf( '%s.subject', $template ); + + if ( $this->supports( 'maybe_empty' ) ) { + if ( $this->detect_maybe_empty( $section, $content ) ) { + $this->add_error( $section, 'maybe_empty', + array( + 'message' => __( 'There is a possible empty field.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'maybe_empty' ); + } + } + } + + + /** + * Runs error detection for the mail sender section. + */ + public function validate_mail_sender( $template, $content ) { + $section = sprintf( '%s.sender', $template ); + + if ( $this->supports( 'invalid_mailbox_syntax' ) ) { + if ( $this->detect_invalid_mailbox_syntax( $section, $content ) ) { + $this->add_error( $section, 'invalid_mailbox_syntax', + array( + 'message' => __( 'Invalid mailbox syntax is used.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'invalid_mailbox_syntax' ); + } + } + + if ( $this->supports( 'email_not_in_site_domain' ) ) { + $this->remove_error( $section, 'email_not_in_site_domain' ); + + if ( ! $this->has_error( $section, 'invalid_mailbox_syntax' ) ) { + $sender = $this->replace_mail_tags( $content ); + $sender = wpcf7_strip_newline( $sender ); + + if ( ! wpcf7_is_email_in_site_domain( $sender ) ) { + $this->add_error( $section, 'email_not_in_site_domain', + array( + 'message' => __( 'Sender email address does not belong to the site domain.', 'contact-form-7' ), + ) + ); + } + } + } + } + + + /** + * Runs error detection for the mail recipient section. + */ + public function validate_mail_recipient( $template, $content ) { + $section = sprintf( '%s.recipient', $template ); + + if ( $this->supports( 'invalid_mailbox_syntax' ) ) { + if ( $this->detect_invalid_mailbox_syntax( $section, $content ) ) { + $this->add_error( $section, 'invalid_mailbox_syntax', + array( + 'message' => __( 'Invalid mailbox syntax is used.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'invalid_mailbox_syntax' ); + } + } + + if ( $this->supports( 'unsafe_email_without_protection' ) ) { + $this->remove_error( $section, 'unsafe_email_without_protection' ); + + if ( ! $this->has_error( $section, 'invalid_mailbox_syntax' ) ) { + if ( + $this->detect_unsafe_email_without_protection( $section, $content ) + ) { + $this->add_error( $section, 'unsafe_email_without_protection', + array( + 'message' => __( 'Unsafe email config is used without sufficient protection.', 'contact-form-7' ), + ) + ); + } + } + } + } + + + /** + * Runs error detection for the mail additional headers section. + */ + public function validate_mail_additional_headers( $template, $content ) { + $section = sprintf( '%s.additional_headers', $template ); + + $invalid_mail_headers = array(); + $invalid_mailbox_fields = array(); + $unsafe_email_fields = array(); + + foreach ( explode( "\n", $content ) as $header ) { + $header = trim( $header ); + + if ( '' === $header ) { + continue; + } + + $is_valid_header = preg_match( + '/^([0-9A-Za-z-]+):(.*)$/', + $header, + $matches + ); + + if ( ! $is_valid_header ) { + $invalid_mail_headers[] = $header; + continue; + } + + $header_name = $matches[1]; + $header_value = trim( $matches[2] ); + + if ( + in_array( + strtolower( $header_name ), array( 'reply-to', 'cc', 'bcc' ), true + ) and + '' !== $header_value and + $this->detect_invalid_mailbox_syntax( $section, $header_value ) + ) { + $invalid_mailbox_fields[] = $header_name; + continue; + } + + if ( + in_array( strtolower( $header_name ), array( 'cc', 'bcc' ), true ) and + $this->detect_unsafe_email_without_protection( $section, $header_value ) + ) { + $unsafe_email_fields[] = $header_name; + } + } + + if ( $this->supports( 'invalid_mail_header' ) ) { + if ( ! empty( $invalid_mail_headers ) ) { + $this->add_error( $section, 'invalid_mail_header', + array( + 'message' => __( 'There are invalid mail header fields.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'invalid_mail_header' ); + } + } + + if ( $this->supports( 'invalid_mailbox_syntax' ) ) { + if ( ! empty( $invalid_mailbox_fields ) ) { + foreach ( $invalid_mailbox_fields as $header_name ) { + $this->add_error( $section, 'invalid_mailbox_syntax', + array( + 'message' => __( 'Invalid mailbox syntax is used in the %name% field.', 'contact-form-7' ), + 'params' => array( 'name' => $header_name ), + ) + ); + } + } else { + $this->remove_error( $section, 'invalid_mailbox_syntax' ); + } + } + + if ( $this->supports( 'unsafe_email_without_protection' ) ) { + if ( ! empty( $unsafe_email_fields ) ) { + $this->add_error( $section, 'unsafe_email_without_protection', + array( + 'message' => __( 'Unsafe email config is used without sufficient protection.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'unsafe_email_without_protection' ); + } + } + } + + + /** + * Runs error detection for the mail body section. + */ + public function validate_mail_body( $template, $content ) { + $section = sprintf( '%s.body', $template ); + + if ( $this->supports( 'maybe_empty' ) ) { + if ( $this->detect_maybe_empty( $section, $content ) ) { + $this->add_error( $section, 'maybe_empty', + array( + 'message' => __( 'There is a possible empty field.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'maybe_empty' ); + } + } + } + + + /** + * Runs error detection for the mail attachments section. + */ + public function validate_mail_attachments( $template, $content ) { + $section = sprintf( '%s.attachments', $template ); + + $total_size = 0; + $files_not_found = array(); + $files_out_of_content = array(); + + if ( '' !== $content ) { + $attachables = array(); + + $tags = $this->contact_form->scan_form_tags( + array( 'type' => array( 'file', 'file*' ) ) + ); + + foreach ( $tags as $tag ) { + $name = $tag->name; + + if ( ! str_contains( $content, "[{$name}]" ) ) { + continue; + } + + $limit = (int) $tag->get_limit_option(); + + if ( empty( $attachables[$name] ) or $attachables[$name] < $limit ) { + $attachables[$name] = $limit; + } + } + + $total_size = array_sum( $attachables ); + + foreach ( explode( "\n", $content ) as $line ) { + $line = trim( $line ); + + if ( '' === $line or str_starts_with( $line, '[' ) ) { + continue; + } + + if ( $this->detect_file_not_found( $section, $line ) ) { + $files_not_found[] = $line; + } elseif ( $this->detect_file_not_in_content_dir( $section, $line ) ) { + $files_out_of_content[] = $line; + } else { + $total_size += (int) @filesize( path_join( WP_CONTENT_DIR, $line ) ); + } + } + } + + if ( $this->supports( 'file_not_found' ) ) { + if ( ! empty( $files_not_found ) ) { + foreach ( $files_not_found as $line ) { + $this->add_error( $section, 'file_not_found', + array( + 'message' => __( 'Attachment file does not exist at %path%.', 'contact-form-7' ), + 'params' => array( 'path' => $line ), + ) + ); + } + } else { + $this->remove_error( $section, 'file_not_found' ); + } + } + + if ( $this->supports( 'file_not_in_content_dir' ) ) { + if ( ! empty( $files_out_of_content ) ) { + $this->add_error( $section, 'file_not_in_content_dir', + array( + 'message' => __( 'It is not allowed to use files outside the wp-content directory.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'file_not_in_content_dir' ); + } + } + + if ( $this->supports( 'attachments_overweight' ) ) { + $max = 25 * MB_IN_BYTES; // 25 MB + + if ( $max < $total_size ) { + $this->add_error( $section, 'attachments_overweight', + array( + 'message' => __( 'The total size of attachment files is too large.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'attachments_overweight' ); + } + } + } + + + /** + * Detects errors of invalid mailbox syntax. + * + * @link https://contactform7.com/configuration-errors/invalid-mailbox-syntax/ + */ + public function detect_invalid_mailbox_syntax( $section, $content ) { + $content = $this->replace_mail_tags( $content ); + $content = wpcf7_strip_newline( $content ); + + if ( ! wpcf7_is_mailbox_list( $content ) ) { + return true; + } + + return false; + } + + + /** + * Detects errors of empty message fields. + * + * @link https://contactform7.com/configuration-errors/maybe-empty/ + */ + public function detect_maybe_empty( $section, $content ) { + $content = $this->replace_mail_tags( $content ); + $content = wpcf7_strip_newline( $content ); + + if ( '' === $content ) { + return true; + } + + return false; + } + + + /** + * Detects errors of nonexistent attachment files. + * + * @link https://contactform7.com/configuration-errors/file-not-found/ + */ + public function detect_file_not_found( $section, $content ) { + $path = path_join( WP_CONTENT_DIR, $content ); + + if ( ! is_readable( $path ) or ! is_file( $path ) ) { + return true; + } + + return false; + } + + + /** + * Detects errors of attachment files out of the content directory. + * + * @link https://contactform7.com/configuration-errors/file-not-in-content-dir/ + */ + public function detect_file_not_in_content_dir( $section, $content ) { + $path = path_join( WP_CONTENT_DIR, $content ); + + if ( ! wpcf7_is_file_path_in_content_dir( $path ) ) { + return true; + } + + return false; + } + + + /** + * Detects errors of that unsafe email config is used without + * sufficient protection. + * + * @link https://contactform7.com/configuration-errors/unsafe-email-without-protection/ + */ + public function detect_unsafe_email_without_protection( $section, $content ) { + if ( $this->contact_form->is_true( 'subscribers_only' ) ) { + return false; + } + + static $is_captcha_active = null; + + if ( null === $is_captcha_active ) { + $is_captcha_active = call_user_func( static function () { + $recaptcha = WPCF7_RECAPTCHA::get_instance(); + $turnstile = WPCF7_Turnstile::get_instance(); + return $recaptcha->is_active() || $turnstile->is_active(); + } ); + } + + if ( $is_captcha_active ) { + return false; + } + + $example_email = 'user-specified@example.com'; + + // Replace mail-tags connected to an email type form-tag first. + $content = $this->replace_mail_tags( $content, array( + 'callback' => function ( $matches ) use ( $example_email ) { + // allow [[foo]] syntax for escaping a tag + if ( '[' === $matches[1] and ']' === $matches[4] ) { + return substr( $matches[0], 1, -1 ); + } + + $tag = $matches[0]; + $tagname = $matches[2]; + $values = $matches[3]; + + $mail_tag = new WPCF7_MailTag( $tag, $tagname, $values ); + $field_name = $mail_tag->field_name(); + + $form_tags = $this->contact_form->scan_form_tags( + array( 'name' => $field_name ) + ); + + if ( $form_tags ) { + $form_tag = new WPCF7_FormTag( $form_tags[0] ); + + if ( 'email' === $form_tag->basetype ) { + return $example_email; + } + } + + return $tag; + }, + ) ); + + // Replace remaining mail-tags. + $content = $this->replace_mail_tags( $content ); + + $content = wpcf7_strip_newline( $content ); + + if ( str_contains( $content, $example_email ) ) { + return true; + } + + return false; + } + +} diff --git a/wp-content/plugins/contact-form-7/includes/config-validator/messages.php b/wp-content/plugins/contact-form-7/includes/config-validator/messages.php new file mode 100644 index 0000000..0194d2c --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/config-validator/messages.php @@ -0,0 +1,55 @@ +contact_form->prop( 'messages' ); + + if ( ! $messages ) { + return; + } + + if ( + isset( $messages['captcha_not_match'] ) and + ! wpcf7_use_really_simple_captcha() + ) { + unset( $messages['captcha_not_match'] ); + } + + foreach ( $messages as $key => $message ) { + $section = sprintf( 'messages.%s', $key ); + + if ( $this->supports( 'html_in_message' ) ) { + if ( $this->detect_html_in_message( $section, $message ) ) { + $this->add_error( $section, 'html_in_message', + array( + 'message' => __( 'HTML tags are used in a message.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'html_in_message' ); + } + } + } + } + + + /** + * Detects errors of HTML uses in a message. + * + * @link https://contactform7.com/configuration-errors/html-in-message/ + */ + public function detect_html_in_message( $section, $content ) { + $stripped = wp_strip_all_tags( $content ); + + if ( $stripped !== $content ) { + return true; + } + + return false; + } + +} diff --git a/wp-content/plugins/contact-form-7/includes/config-validator/validator.php b/wp-content/plugins/contact-form-7/includes/config-validator/validator.php new file mode 100644 index 0000000..cc33294 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/config-validator/validator.php @@ -0,0 +1,386 @@ + null, + 'exclude' => null, + ) ); + + $this->contact_form = $contact_form; + + if ( isset( $options['include'] ) ) { + $this->include = (array) $options['include']; + } + + if ( isset( $options['exclude'] ) ) { + $this->exclude = (array) $options['exclude']; + } + } + + + /** + * Returns the contact form object that is tied to this validator. + */ + public function contact_form() { + return $this->contact_form; + } + + + /** + * Returns true if no error has been detected. + */ + public function is_valid() { + return ! $this->count_errors(); + } + + + /** + * Returns true if the given error code is supported by this instance. + */ + public function supports( $error_code ) { + if ( isset( $this->include ) ) { + $supported_codes = array_intersect( self::error_codes, $this->include ); + } else { + $supported_codes = self::error_codes; + } + + if ( isset( $this->exclude ) ) { + $supported_codes = array_diff( $supported_codes, $this->exclude ); + } + + return in_array( $error_code, $supported_codes, true ); + } + + + /** + * Counts detected errors. + */ + public function count_errors( $options = '' ) { + $options = wp_parse_args( $options, array( + 'section' => '', + 'code' => '', + ) ); + + $count = 0; + + foreach ( $this->errors as $key => $errors ) { + if ( preg_match( '/^mail_[0-9]+\.(.*)$/', $key, $matches ) ) { + $key = sprintf( 'mail.%s', $matches[1] ); + } + + if ( + $options['section'] and + $key !== $options['section'] and + preg_replace( '/\..*$/', '', $key, 1 ) !== $options['section'] + ) { + continue; + } + + foreach ( $errors as $error ) { + if ( empty( $error ) ) { + continue; + } + + if ( $options['code'] and $error['code'] !== $options['code'] ) { + continue; + } + + $count += 1; + } + } + + return $count; + } + + + /** + * Collects messages for detected errors. + */ + public function collect_error_messages( $options = '' ) { + $options = wp_parse_args( $options, array( + 'decodes_html_entities' => false, + ) ); + + $error_messages = array(); + + foreach ( $this->errors as $section => $errors ) { + $error_messages[$section] = array(); + + foreach ( $errors as $error ) { + if ( empty( $error['args']['message'] ) ) { + $message = $this->get_default_message( $error['code'] ); + } elseif ( empty( $error['args']['params'] ) ) { + $message = $error['args']['message']; + } else { + $message = $this->build_message( + $error['args']['message'], + $error['args']['params'] + ); + } + + if ( $options['decodes_html_entities'] ) { + $message = html_entity_decode( $message, ENT_HTML5 ); + } + + $link = ''; + + if ( ! empty( $error['args']['link'] ) ) { + $link = $error['args']['link']; + } + + $error_messages[$section][] = array( + 'message' => $message, + 'link' => esc_url( $link ), + ); + } + } + + return $error_messages; + } + + + /** + * Builds an error message by replacing placeholders. + */ + public function build_message( $message, $params = '' ) { + $params = wp_parse_args( $params, array() ); + + foreach ( $params as $key => $val ) { + if ( ! preg_match( '/^[0-9A-Za-z_]+$/', $key ) ) { // invalid key + continue; + } + + $placeholder = '%' . $key . '%'; + + if ( false !== stripos( $message, $placeholder ) ) { + $message = str_ireplace( $placeholder, $val, $message ); + } + } + + return $message; + } + + + /** + * Returns a default message that is used when the message for the error + * is not specified. + */ + public function get_default_message( $code = '' ) { + return __( 'Configuration error is detected.', 'contact-form-7' ); + } + + + /** + * Returns true if the specified section has the specified error. + * + * @param string $section The section where the error detected. + * @param string $code The unique code of the error. + */ + public function has_error( $section, $code ) { + if ( empty( $this->errors[$section] ) ) { + return false; + } + + foreach ( (array) $this->errors[$section] as $error ) { + if ( isset( $error['code'] ) and $error['code'] === $code ) { + return true; + } + } + + return false; + } + + + /** + * Adds a validation error. + * + * @param string $section The section where the error detected. + * @param string $code The unique code of the error. + * @param string|array $args Optional options for the error. + */ + public function add_error( $section, $code, $args = '' ) { + $args = wp_parse_args( $args, array( + 'message' => '', + 'params' => array(), + ) ); + + $available_error_codes = (array) apply_filters( + 'wpcf7_config_validator_available_error_codes', + self::error_codes, + $this->contact_form + ); + + if ( ! in_array( $code, $available_error_codes, true ) ) { + return false; + } + + if ( ! isset( $args['link'] ) ) { + $args['link'] = self::get_doc_link( $code ); + } + + if ( ! isset( $this->errors[$section] ) ) { + $this->errors[$section] = array(); + } + + $this->errors[$section][] = array( + 'code' => $code, + 'args' => $args, + ); + + return true; + } + + + /** + * Removes an error. + * + * @param string $section The section where the error detected. + * @param string $code The unique code of the error. + */ + public function remove_error( $section, $code ) { + if ( empty( $this->errors[$section] ) ) { + return; + } + + foreach ( (array) $this->errors[$section] as $key => $error ) { + if ( isset( $error['code'] ) and $error['code'] === $code ) { + unset( $this->errors[$section][$key] ); + } + } + + if ( empty( $this->errors[$section] ) ) { + unset( $this->errors[$section] ); + } + } + + + /** + * The main validation runner. + * + * @return bool True if there is no error detected. + */ + public function validate() { + $this->validate_form(); + $this->validate_mail( 'mail' ); + $this->validate_mail( 'mail_2' ); + $this->validate_messages(); + $this->validate_additional_settings(); + + do_action( 'wpcf7_config_validator_validate', $this ); + + return $this->is_valid(); + } + + + /** + * Saves detected errors as a post meta data. + */ + public function save() { + if ( $this->contact_form->initial() ) { + return; + } + + delete_post_meta( $this->contact_form->id(), '_config_validation' ); + + if ( $this->errors ) { + update_post_meta( + $this->contact_form->id(), '_config_validation', $this->errors + ); + } + } + + + /** + * Restore errors from the database. + */ + public function restore() { + $config_errors = get_post_meta( + $this->contact_form->id(), '_config_validation', true + ); + + foreach ( (array) $config_errors as $section => $errors ) { + if ( empty( $errors ) ) { + continue; + } + + foreach ( (array) $errors as $error ) { + if ( ! empty( $error['code'] ) ) { + $code = $error['code']; + $args = isset( $error['args'] ) ? $error['args'] : ''; + $this->add_error( $section, $code, $args ); + } + } + } + } + +} diff --git a/wp-content/plugins/contact-form-7/includes/contact-form-functions.php b/wp-content/plugins/contact-form-7/includes/contact-form-functions.php new file mode 100644 index 0000000..f054faa --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/contact-form-functions.php @@ -0,0 +1,476 @@ + array( + array( + 'key' => '_old_cf7_unit_id', + 'type' => 'DECIMAL', + 'value' => $old_id, + ), + ), + 'posts_per_page' => 1, + ) ); + + if ( $contact_forms ) { + return wpcf7_contact_form( $contact_forms[0] ); + } +} + + +/** + * Searches for a contact form by a hash string. + * + * @param string $hash Part of a hash string. + * @return WPCF7_ContactForm Contact form object. + */ +function wpcf7_get_contact_form_by_hash( $hash ) { + if ( ! preg_match( '/^[0-9a-f]{7,}$/', $hash ) ) { + return null; + } + + $contact_forms = WPCF7_ContactForm::find( array( + 'meta_query' => array( + array( + 'key' => '_hash', + 'compare' => 'REGEXP', + 'value' => '^' . $hash, + ), + ), + 'posts_per_page' => 1, + ) ); + + if ( $contact_forms ) { + return wpcf7_contact_form( $contact_forms[0] ); + } +} + + +/** + * Searches for a contact form by title. + * + * @param string $title Title of contact form. + * @return WPCF7_ContactForm|null Contact form object if found, null otherwise. + */ +function wpcf7_get_contact_form_by_title( $title ) { + if ( ! is_string( $title ) or '' === $title ) { + return null; + } + + $contact_forms = WPCF7_ContactForm::find( array( + 'title' => $title, + 'posts_per_page' => 1, + ) ); + + if ( $contact_forms ) { + return wpcf7_contact_form( $contact_forms[0] ); + } +} + + +/** + * Wrapper function of WPCF7_ContactForm::get_current(). + * + * @return WPCF7_ContactForm Contact form object. + */ +function wpcf7_get_current_contact_form() { + if ( $current = WPCF7_ContactForm::get_current() ) { + return $current; + } +} + + +/** + * Returns true if it is in the state that a non-Ajax submission is accepted. + */ +function wpcf7_is_posted() { + if ( ! $contact_form = wpcf7_get_current_contact_form() ) { + return false; + } + + return $contact_form->is_posted(); +} + + +/** + * Retrieves the user input value through a non-Ajax submission. + * + * @param string $name Name of form control. + * @param string $default_value Optional default value. + * @return string The user input value through the form-control. + */ +function wpcf7_get_hangover( $name, $default_value = null ) { + if ( ! wpcf7_is_posted() ) { + return $default_value; + } + + $submission = WPCF7_Submission::get_instance(); + + if ( ! $submission or $submission->is( 'mail_sent' ) ) { + return $default_value; + } + + return wpcf7_superglobal_post( $name, $default_value ); +} + + +/** + * Retrieves an HTML snippet of validation error on the given form control. + * + * @param string $name Name of form control. + * @return string Validation error message in a form of HTML snippet. + */ +function wpcf7_get_validation_error( $name ) { + if ( ! $contact_form = wpcf7_get_current_contact_form() ) { + return ''; + } + + return $contact_form->validation_error( $name ); +} + + +/** + * Returns a reference key to a validation error message. + * + * @param string $name Name of form control. + * @param string $unit_tag Optional. Unit tag of the contact form. + * @return string Reference key code. + */ +function wpcf7_get_validation_error_reference( $name, $unit_tag = '' ) { + if ( '' === $unit_tag ) { + $contact_form = wpcf7_get_current_contact_form(); + + if ( $contact_form and $contact_form->validation_error( $name ) ) { + $unit_tag = $contact_form->unit_tag(); + } else { + return null; + } + } + + return preg_replace( '/[^0-9a-z_-]+/i', '', + sprintf( + '%1$s-ve-%2$s', + $unit_tag, + $name + ) + ); +} + + +/** + * Retrieves a message for the given status. + */ +function wpcf7_get_message( $status ) { + if ( ! $contact_form = wpcf7_get_current_contact_form() ) { + return ''; + } + + return $contact_form->message( $status ); +} + + +/** + * Returns a class names list for a form-tag of the specified type. + * + * @param string $type Form-tag type. + * @param string $default_classes Optional default classes. + * @return string Whitespace-separated list of class names. + */ +function wpcf7_form_controls_class( $type, $default_classes = '' ) { + $type = trim( $type ); + + if ( is_string( $default_classes ) ) { + $default_classes = explode( ' ', $default_classes ); + } + + $classes = array( + 'wpcf7-form-control', + sprintf( 'wpcf7-%s', rtrim( $type, '*' ) ), + ); + + if ( str_ends_with( $type, '*' ) ) { + $classes[] = 'wpcf7-validates-as-required'; + } + + $classes = array_merge( $classes, $default_classes ); + $classes = array_filter( array_unique( $classes ) ); + + return implode( ' ', $classes ); +} + + +/** + * Callback function for the contact-form-7 shortcode. + */ +function wpcf7_contact_form_tag_func( $atts, $content = null, $code = '' ) { + if ( is_feed() ) { + return '[contact-form-7]'; + } + + if ( 'contact-form-7' === $code ) { + $atts = shortcode_atts( + array( + 'id' => '', + 'title' => '', + 'html_id' => '', + 'html_name' => '', + 'html_title' => '', + 'html_class' => '', + 'output' => 'form', + ), + $atts, 'wpcf7' + ); + + $id = trim( $atts['id'] ); + $title = trim( $atts['title'] ); + + $contact_form = wpcf7_get_contact_form_by_hash( $id ); + + if ( ! $contact_form ) { + $contact_form = wpcf7_contact_form( $id ); + } + + if ( ! $contact_form ) { + $contact_form = wpcf7_get_contact_form_by_title( $title ); + } + + } else { + if ( is_string( $atts ) ) { + $atts = explode( ' ', $atts, 2 ); + } + + $id = (int) array_shift( $atts ); + $contact_form = wpcf7_get_contact_form_by_old_id( $id ); + } + + if ( ! $contact_form ) { + return sprintf( + '

%1$s %2$s

', + esc_html( __( 'Error:', 'contact-form-7' ) ), + esc_html( __( "Contact form not found.", 'contact-form-7' ) ) + ); + } + + $callback = static function ( $contact_form, $atts ) { + return $contact_form->form_html( $atts ); + }; + + $output = wpcf7_switch_locale( + $contact_form->locale(), + $callback, + $contact_form, $atts + ); + + do_action( 'wpcf7_shortcode_callback', $contact_form, $atts ); + + return $output; +} + + +/** + * Saves the contact form data. + */ +function wpcf7_save_contact_form( $data = '', $context = 'save' ) { + $data = wp_parse_args( $data, array( + 'id' => -1, + 'title' => null, + 'locale' => null, + 'form' => null, + 'mail' => null, + 'mail_2' => null, + 'messages' => null, + 'additional_settings' => null, + ) ); + + $data['id'] = (int) $data['id']; + + if ( -1 === $data['id'] ) { + $contact_form = WPCF7_ContactForm::get_template(); + } else { + $contact_form = wpcf7_contact_form( $data['id'] ); + } + + if ( empty( $contact_form ) ) { + return false; + } + + if ( null !== $data['title'] ) { + $contact_form->set_title( $data['title'] ); + } + + if ( null !== $data['locale'] ) { + $contact_form->set_locale( $data['locale'] ); + } + + $properties = array(); + + if ( null !== $data['form'] ) { + $properties['form'] = wpcf7_sanitize_form( $data['form'] ); + } + + if ( null !== $data['mail'] ) { + $properties['mail'] = wpcf7_sanitize_mail( $data['mail'] ); + $properties['mail']['active'] = true; + } + + if ( null !== $data['mail_2'] ) { + $properties['mail_2'] = wpcf7_sanitize_mail( $data['mail_2'] ); + } + + if ( null !== $data['messages'] ) { + $properties['messages'] = wpcf7_sanitize_messages( $data['messages'] ); + } + + if ( null !== $data['additional_settings'] ) { + $properties['additional_settings'] = wpcf7_sanitize_additional_settings( + $data['additional_settings'] + ); + } + + $contact_form->set_properties( $properties ); + + do_action( 'wpcf7_save_contact_form', $contact_form, $data, $context ); + + if ( 'save' === $context ) { + $contact_form->save(); + } + + return $contact_form; +} + + +/** + * Sanitizes the form property data. + */ +function wpcf7_sanitize_form( $input, $default_template = '' ) { + if ( null === $input ) { + return $default_template; + } + + $output = trim( $input ); + + if ( ! current_user_can( 'unfiltered_html' ) ) { + $output = wpcf7_kses( $output, 'form' ); + } + + return $output; +} + + +/** + * Sanitizes the mail property data. + */ +function wpcf7_sanitize_mail( $input, $defaults = array() ) { + $input = wp_parse_args( $input, array( + 'active' => false, + 'subject' => '', + 'sender' => '', + 'recipient' => '', + 'body' => '', + 'additional_headers' => '', + 'attachments' => '', + 'use_html' => false, + 'exclude_blank' => false, + ) ); + + $input = wp_parse_args( $input, $defaults ); + + $output = array(); + $output['active'] = (bool) $input['active']; + $output['subject'] = trim( $input['subject'] ); + $output['sender'] = trim( $input['sender'] ); + $output['recipient'] = trim( $input['recipient'] ); + $output['body'] = trim( $input['body'] ); + + if ( ! current_user_can( 'unfiltered_html' ) ) { + $output['body'] = wpcf7_kses( $output['body'], 'mail' ); + } + + $output['additional_headers'] = ''; + + $headers = str_replace( "\r\n", "\n", $input['additional_headers'] ); + $headers = explode( "\n", $headers ); + + foreach ( $headers as $header ) { + $header = trim( $header ); + + if ( '' !== $header ) { + $output['additional_headers'] .= $header . "\n"; + } + } + + $output['additional_headers'] = trim( $output['additional_headers'] ); + $output['attachments'] = trim( $input['attachments'] ); + $output['use_html'] = (bool) $input['use_html']; + $output['exclude_blank'] = (bool) $input['exclude_blank']; + + return $output; +} + + +/** + * Sanitizes the messages property data. + */ +function wpcf7_sanitize_messages( $input, $defaults = array() ) { + $output = array(); + + foreach ( wpcf7_messages() as $key => $val ) { + if ( isset( $input[$key] ) ) { + $output[$key] = trim( $input[$key] ); + } elseif ( isset( $defaults[$key] ) ) { + $output[$key] = $defaults[$key]; + } + } + + return $output; +} + + +/** + * Sanitizes the additional settings property data. + */ +function wpcf7_sanitize_additional_settings( $input, $default_template = '' ) { + if ( null === $input ) { + return $default_template; + } + + $output = trim( $input ); + return $output; +} + + +/** + * Generates a random hash string for a contact form. + * + * @param int $post_id Post ID. + * @return string SHA-1 hash. + */ +function wpcf7_generate_contact_form_hash( $post_id ) { + return hash( 'sha256', implode( '|', array( + get_current_user_id(), + $post_id, + time(), + home_url(), + ) ) ); +} diff --git a/wp-content/plugins/contact-form-7/includes/contact-form-template.php b/wp-content/plugins/contact-form-7/includes/contact-form-template.php new file mode 100644 index 0000000..528e17f --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/contact-form-template.php @@ -0,0 +1,204 @@ + %2$s + [text* your-name autocomplete:name] + + + + + + + +[submit "%6$s"]', + __( '(optional)', 'contact-form-7' ), + __( 'Your name', 'contact-form-7' ), + __( 'Your email', 'contact-form-7' ), + __( 'Subject', 'contact-form-7' ), + __( 'Your message', 'contact-form-7' ), + __( 'Submit', 'contact-form-7' ) + ); + + return trim( $template ); + } + + public static function mail() { + $template = array( + 'subject' => sprintf( + /* translators: 1: blog name, 2: [your-subject] */ + _x( '%1$s "%2$s"', 'mail subject', 'contact-form-7' ), + '[_site_title]', + '[your-subject]' + ), + 'sender' => sprintf( + '%s <%s>', + '[_site_title]', + self::from_email() + ), + 'body' => + sprintf( + /* translators: %s: [your-name] [your-email] */ + __( 'From: %s', 'contact-form-7' ), + '[your-name] [your-email]' + ) . "\n" + . sprintf( + /* translators: %s: [your-subject] */ + __( 'Subject: %s', 'contact-form-7' ), + '[your-subject]' + ) . "\n\n" + . __( 'Message Body:', 'contact-form-7' ) + . "\n" . '[your-message]' . "\n\n" + . '-- ' . "\n" + . sprintf( + /* translators: 1: blog name, 2: blog URL */ + __( 'This is a notification that a contact form was submitted on your website (%1$s %2$s).', 'contact-form-7' ), + '[_site_title]', + '[_site_url]' + ), + 'recipient' => '[_site_admin_email]', + 'additional_headers' => 'Reply-To: [your-email]', + 'attachments' => '', + 'use_html' => 0, + 'exclude_blank' => 0, + ); + + return $template; + } + + public static function mail_2() { + $template = array( + 'active' => false, + 'subject' => sprintf( + /* translators: 1: blog name, 2: [your-subject] */ + _x( '%1$s "%2$s"', 'mail subject', 'contact-form-7' ), + '[_site_title]', + '[your-subject]' + ), + 'sender' => sprintf( + '%s <%s>', + '[_site_title]', + self::from_email() + ), + 'body' => + __( 'Message Body:', 'contact-form-7' ) + . "\n" . '[your-message]' . "\n\n" + . '-- ' . "\n" + . sprintf( + /* translators: 1: blog name, 2: blog URL */ + __( 'This email is a receipt for your contact form submission on our website (%1$s %2$s) in which your email address was used. If that was not you, please ignore this message.', 'contact-form-7' ), + '[_site_title]', + '[_site_url]' + ), + 'recipient' => '[your-email]', + 'additional_headers' => sprintf( + 'Reply-To: %s', + '[_site_admin_email]' + ), + 'attachments' => '', + 'use_html' => 0, + 'exclude_blank' => 0, + ); + + return $template; + } + + public static function from_email() { + $admin_email = get_option( 'admin_email' ); + + if ( wpcf7_is_localhost() ) { + return $admin_email; + } + + $sitename = wp_parse_url( network_home_url(), PHP_URL_HOST ); + $sitename = strtolower( $sitename ); + + if ( 'www.' === substr( $sitename, 0, 4 ) ) { + $sitename = substr( $sitename, 4 ); + } + + if ( strpbrk( $admin_email, '@' ) === '@' . $sitename ) { + return $admin_email; + } + + return 'wordpress@' . $sitename; + } + + public static function messages() { + $messages = array(); + + foreach ( wpcf7_messages() as $key => $arr ) { + $messages[$key] = $arr['default']; + } + + return $messages; + } +} + +function wpcf7_messages() { + $messages = array( + 'mail_sent_ok' => array( + 'description' => __( 'Sender’s message was sent successfully', 'contact-form-7' ), + 'default' => __( 'Thank you for your message. It has been sent.', 'contact-form-7' ), + ), + + 'mail_sent_ng' => array( + 'description' => __( 'Sender’s message failed to send', 'contact-form-7' ), + 'default' => __( 'There was an error trying to send your message. Please try again later.', 'contact-form-7' ), + ), + + 'validation_error' => array( + 'description' => __( 'Validation errors occurred', 'contact-form-7' ), + 'default' => __( 'One or more fields have an error. Please check and try again.', 'contact-form-7' ), + ), + + 'spam' => array( + 'description' => __( 'Submission was referred to as spam', 'contact-form-7' ), + 'default' => __( 'There was an error trying to send your message. Please try again later.', 'contact-form-7' ), + ), + + 'accept_terms' => array( + 'description' => __( 'There are terms that the sender must accept', 'contact-form-7' ), + 'default' => __( 'You must accept the terms and conditions before sending your message.', 'contact-form-7' ), + ), + + 'invalid_required' => array( + 'description' => __( 'There is a field that the sender must fill in', 'contact-form-7' ), + 'default' => __( 'Please fill out this field.', 'contact-form-7' ), + ), + + 'invalid_too_long' => array( + 'description' => __( 'There is a field with input that is longer than the maximum allowed length', 'contact-form-7' ), + 'default' => __( 'This field has a too long input.', 'contact-form-7' ), + ), + + 'invalid_too_short' => array( + 'description' => __( 'There is a field with input that is shorter than the minimum allowed length', 'contact-form-7' ), + 'default' => __( 'This field has a too short input.', 'contact-form-7' ), + ), + ); + + return apply_filters( 'wpcf7_messages', $messages ); +} diff --git a/wp-content/plugins/contact-form-7/includes/contact-form.php b/wp-content/plugins/contact-form-7/includes/contact-form.php new file mode 100644 index 0000000..cdbb6d6 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/contact-form.php @@ -0,0 +1,1379 @@ + array( + 'name' => __( 'Contact Forms', 'contact-form-7' ), + 'singular_name' => __( 'Contact Form', 'contact-form-7' ), + ), + 'rewrite' => false, + 'query_var' => false, + 'public' => false, + 'capability_type' => 'page', + 'capabilities' => array( + 'edit_post' => 'wpcf7_edit_contact_form', + 'read_post' => 'wpcf7_read_contact_form', + 'delete_post' => 'wpcf7_delete_contact_form', + 'edit_posts' => 'wpcf7_edit_contact_forms', + 'edit_others_posts' => 'wpcf7_edit_contact_forms', + 'publish_posts' => 'wpcf7_edit_contact_forms', + 'read_private_posts' => 'wpcf7_edit_contact_forms', + ), + ) ); + } + + + /** + * Retrieves contact form data that match given conditions. + * + * @param string|array $args Optional. Arguments to be passed to WP_Query. + * @return array Array of WPCF7_ContactForm objects. + */ + public static function find( $args = '' ) { + $defaults = array( + 'post_status' => 'any', + 'posts_per_page' => -1, + 'offset' => 0, + 'orderby' => 'ID', + 'order' => 'ASC', + ); + + $args = wp_parse_args( $args, $defaults ); + + $args['post_type'] = self::post_type; + + $q = new WP_Query(); + $posts = $q->query( $args ); + + self::$found_items = $q->found_posts; + + $objs = array(); + + foreach ( $posts as $post ) { + $objs[] = new self( $post ); + } + + return $objs; + } + + + /** + * Returns a contact form data filled by default template contents. + * + * @param string|array $options Optional. Contact form options. + * @return WPCF7_ContactForm A new contact form object. + */ + public static function get_template( $options = '' ) { + $options = wp_parse_args( $options, array( + 'locale' => null, + 'title' => __( 'Untitled', 'contact-form-7' ), + ) ); + + if ( ! isset( $options['locale'] ) ) { + $options['locale'] = determine_locale(); + } + + $callback = static function ( $options ) { + $contact_form = new self(); + $contact_form->title = $options['title']; + $contact_form->locale = $options['locale']; + + $properties = $contact_form->get_properties(); + + foreach ( $properties as $key => $value ) { + $default_template = WPCF7_ContactFormTemplate::get_default( $key ); + + if ( isset( $default_template ) ) { + $properties[$key] = $default_template; + } + } + + $contact_form->properties = $properties; + + return $contact_form; + }; + + $contact_form = wpcf7_switch_locale( + $options['locale'], + $callback, + $options + ); + + self::$current = apply_filters( 'wpcf7_contact_form_default_pack', + $contact_form, $options + ); + + return self::$current; + } + + + /** + * Creates a WPCF7_ContactForm object and sets it as the current instance. + * + * @param WPCF7_ContactForm|WP_Post|int $post Object or post ID. + * @return WPCF7_ContactForm|null Contact form object. Null if unset. + */ + public static function get_instance( $post ) { + $contact_form = null; + + if ( $post instanceof self ) { + $contact_form = $post; + } elseif ( ! empty( $post ) ) { + $post = get_post( $post ); + + if ( isset( $post ) and self::post_type === get_post_type( $post ) ) { + $contact_form = new self( $post ); + } + } + + return self::$current = $contact_form; + } + + + /** + * Generates a "unit-tag" for the given contact form ID. + * + * @return string Unit-tag. + */ + private static function generate_unit_tag( $id = 0 ) { + static $global_count = 0; + + $global_count += 1; + + if ( in_the_loop() ) { + $unit_tag = sprintf( 'wpcf7-f%1$d-p%2$d-o%3$d', + absint( $id ), + get_the_ID(), + $global_count + ); + } else { + $unit_tag = sprintf( 'wpcf7-f%1$d-o%2$d', + absint( $id ), + $global_count + ); + } + + return $unit_tag; + } + + + /** + * Constructor. + */ + private function __construct( $post = null ) { + $post = get_post( $post ); + + if ( $post and self::post_type === get_post_type( $post ) ) { + $this->id = $post->ID; + $this->name = $post->post_name; + $this->title = $post->post_title; + $this->locale = get_post_meta( $post->ID, '_locale', true ); + $this->hash = get_post_meta( $post->ID, '_hash', true ); + + $this->construct_properties( $post ); + $this->upgrade(); + } else { + $this->construct_properties(); + } + + do_action( 'wpcf7_contact_form', $this ); + } + + + /** + * Magic method for property overloading. + */ + public function __get( $name ) { + /* translators: 1: property name, 2: method name */ + $message = __( '%1$s property of a WPCF7_ContactForm object is no longer accessible. Use %2$s method instead.', 'contact-form-7' ); + + if ( 'id' === $name ) { + wp_trigger_error( + '', + sprintf( $message, 'id', 'id()' ), + E_USER_DEPRECATED + ); + + return $this->id; + } elseif ( 'title' === $name ) { + wp_trigger_error( + '', + sprintf( $message, 'title', 'title()' ), + E_USER_DEPRECATED + ); + + return $this->title; + } elseif ( $prop = $this->prop( $name ) ) { + wp_trigger_error( + '', + sprintf( $message, $name, 'prop(\'' . $name . '\')' ), + E_USER_DEPRECATED + ); + + return $prop; + } + } + + + /** + * Returns true if this contact form is not yet saved to the database. + */ + public function initial() { + return empty( $this->id ); + } + + + /** + * Constructs contact form properties. This is called only once + * from the constructor. + */ + private function construct_properties( $post = null ) { + $builtin_properties = array( + 'form' => '', + 'mail' => array(), + 'mail_2' => array(), + 'messages' => array(), + 'additional_settings' => '', + ); + + $properties = apply_filters( + 'wpcf7_pre_construct_contact_form_properties', + $builtin_properties, $this + ); + + // Filtering out properties with invalid name + $properties = array_filter( + $properties, + static function ( $key ) { + $sanitized_key = sanitize_key( $key ); + return $key === $sanitized_key; + }, + ARRAY_FILTER_USE_KEY + ); + + foreach ( $properties as $name => $val ) { + $prop = $this->retrieve_property( $name ); + + if ( isset( $prop ) ) { + $properties[$name] = $prop; + } + } + + $this->properties = $properties; + + foreach ( $properties as $name => $val ) { + $properties[$name] = apply_filters( + "wpcf7_contact_form_property_{$name}", + $val, $this + ); + } + + $this->properties = $properties; + + $properties = (array) apply_filters( + 'wpcf7_contact_form_properties', + $properties, $this + ); + + $this->properties = $properties; + } + + + /** + * Retrieves contact form property of the specified name from the database. + * + * @param string $name Property name. + * @return array|string|null Property value. Null if property does not exist. + */ + private function retrieve_property( $name ) { + $property = null; + + if ( ! $this->initial() ) { + $post_id = $this->id; + + if ( metadata_exists( 'post', $post_id, '_' . $name ) ) { + $property = get_post_meta( $post_id, '_' . $name, true ); + } elseif ( metadata_exists( 'post', $post_id, $name ) ) { + $property = get_post_meta( $post_id, $name, true ); + } + } + + return $property; + } + + + /** + * Returns the value for the given property name. + * + * @param string $name Property name. + * @return array|string|null Property value. Null if property does not exist. + */ + public function prop( $name ) { + $props = $this->get_properties(); + return isset( $props[$name] ) ? $props[$name] : null; + } + + + /** + * Returns all the properties. + * + * @return array This contact form's properties. + */ + public function get_properties() { + return (array) $this->properties; + } + + + /** + * Updates properties. + * + * @param array $properties New properties. + */ + public function set_properties( $properties ) { + $defaults = $this->get_properties(); + + $properties = wp_parse_args( $properties, $defaults ); + $properties = array_intersect_key( $properties, $defaults ); + + $this->properties = $properties; + } + + + /** + * Returns ID of this contact form. + * + * @return int The ID. + */ + public function id() { + return $this->id; + } + + + /** + * Returns unit-tag for this contact form. + * + * @return string Unit-tag. + */ + public function unit_tag() { + return $this->unit_tag; + } + + + /** + * Returns name (slug) of this contact form. + * + * @return string Name. + */ + public function name() { + return $this->name; + } + + + /** + * Returns title of this contact form. + * + * @return string Title. + */ + public function title() { + return $this->title; + } + + + /** + * Set a title for this contact form. + * + * @param string $title Title. + */ + public function set_title( $title ) { + $title = wp_strip_all_tags( $title, true ); + $title = wpcf7_strip_whitespaces( $title ); + + if ( '' === $title ) { + $title = __( 'Untitled', 'contact-form-7' ); + } + + $this->title = $title; + } + + + /** + * Returns the locale code of this contact form. + * + * @return string Locale code. Empty string if no valid locale is set. + */ + public function locale() { + if ( wpcf7_is_valid_locale( $this->locale ) ) { + return $this->locale; + } else { + return ''; + } + } + + + /** + * Sets a locale for this contact form. + * + * @param string $locale Locale code. + */ + public function set_locale( $locale ) { + $locale = trim( $locale ); + + if ( wpcf7_is_valid_locale( $locale ) ) { + $this->locale = $locale; + } else { + $this->locale = 'en_US'; + } + } + + + /** + * Retrieves the random hash string tied to this contact form. + * + * @param int $length Length of hash string. + * @return string Hash string unique to this contact form. + */ + public function hash( $length = 7 ) { + return substr( $this->hash, 0, absint( $length ) ); + } + + + /** + * Returns the specified shortcode attribute value. + * + * @param string $name Shortcode attribute name. + * @return string|null Attribute value. Null if the attribute does not exist. + */ + public function shortcode_attr( $name ) { + if ( isset( $this->shortcode_atts[$name] ) ) { + return (string) $this->shortcode_atts[$name]; + } + } + + + /** + * Returns true if this contact form is identical to the submitted one. + */ + public function is_posted() { + if ( ! WPCF7_Submission::get_instance() ) { + return false; + } + + $unit_tag = wpcf7_superglobal_post( '_wpcf7_unit_tag' ); + + if ( empty( $unit_tag ) ) { + return false; + } + + return $this->unit_tag() === $unit_tag; + } + + + /** + * Generates HTML that represents a form. + * + * @param string|array $options Optional. Form options. + * @return string HTML output. + */ + public function form_html( $options = '' ) { + $options = wp_parse_args( $options, array( + 'html_id' => '', + 'html_name' => '', + 'html_title' => '', + 'html_class' => '', + 'output' => 'form', + ) ); + + $this->shortcode_atts = $options; + + if ( 'raw_form' === $options['output'] ) { + return sprintf( + '
%s
', + esc_html( $this->prop( 'form' ) ) + ); + } + + if ( + $this->is_true( 'subscribers_only' ) and + ! current_user_can( 'wpcf7_submit', $this->id() ) + ) { + $notice = sprintf( + '

%s

', + wp_kses_data( __( 'This contact form is available only for logged in users.', 'contact-form-7' ) ) + ); + + return apply_filters( 'wpcf7_subscribers_only_notice', $notice, $this ); + } + + $this->unit_tag = self::generate_unit_tag( $this->id ); + + $action_url = wpcf7_get_request_uri(); + + if ( $frag = strstr( $action_url, '#' ) ) { + $action_url = substr( $action_url, 0, -strlen( $frag ) ); + } + + $action_url .= '#' . $this->unit_tag(); + + $action_url = apply_filters( 'wpcf7_form_action_url', $action_url ); + + if ( + str_starts_with( $action_url, '//' ) or + ! str_starts_with( $action_url, '/' ) and + ! str_starts_with( $action_url, home_url() ) + ) { + return sprintf( + '

%1$s %2$s

', + esc_html( __( 'Error:', 'contact-form-7' ) ), + esc_html( __( 'Invalid action URL is detected.', 'contact-form-7' ) ) + ); + } + + $lang_tag = str_replace( '_', '-', $this->locale ); + + if ( preg_match( '/^([a-z]+-[a-z]+)-/i', $lang_tag, $matches ) ) { + $lang_tag = $matches[1]; + } + + $html = "\n" . sprintf( '
', + wpcf7_format_atts( array( + 'class' => 'wpcf7 no-js', + 'id' => $this->unit_tag(), + ( get_option( 'html_type' ) === 'text/html' ) ? 'lang' : 'xml:lang' + => $lang_tag, + 'dir' => wpcf7_is_rtl( $this->locale ) ? 'rtl' : 'ltr', + 'data-wpcf7-id' => $this->id(), + ) ) + ); + + $html .= "\n" . $this->screen_reader_response() . "\n"; + + $id_attr = apply_filters( 'wpcf7_form_id_attr', + preg_replace( '/[^A-Za-z0-9:._-]/', '', $options['html_id'] ) + ); + + $name_attr = apply_filters( 'wpcf7_form_name_attr', + preg_replace( '/[^A-Za-z0-9:._-]/', '', $options['html_name'] ) + ); + + $title_attr = apply_filters( 'wpcf7_form_title_attr', $options['html_title'] ); + + $class = 'wpcf7-form'; + + if ( $this->is_posted() ) { + $submission = WPCF7_Submission::get_instance(); + + $data_status_attr = $this->form_status_class_name( + $submission->get_status() + ); + + $class .= sprintf( ' %s', $data_status_attr ); + } else { + $data_status_attr = 'init'; + $class .= ' init'; + } + + if ( $options['html_class'] ) { + $class .= ' ' . $options['html_class']; + } + + if ( $this->in_demo_mode() ) { + $class .= ' demo'; + } + + $class = explode( ' ', $class ); + $class = array_map( 'sanitize_html_class', $class ); + $class = array_filter( $class ); + $class = array_unique( $class ); + $class = implode( ' ', $class ); + $class = apply_filters( 'wpcf7_form_class_attr', $class ); + + $enctype = wpcf7_enctype_value( apply_filters( 'wpcf7_form_enctype', '' ) ); + $autocomplete = apply_filters( 'wpcf7_form_autocomplete', '' ); + + $atts = array( + 'action' => esc_url( $action_url ), + 'method' => 'post', + 'class' => ( '' !== $class ) ? $class : null, + 'id' => ( '' !== $id_attr ) ? $id_attr : null, + 'name' => ( '' !== $name_attr ) ? $name_attr : null, + 'aria-label' => ( '' !== $title_attr ) + ? $title_attr : __( 'Contact form', 'contact-form-7' ), + 'enctype' => ( '' !== $enctype ) ? $enctype : null, + 'autocomplete' => ( '' !== $autocomplete ) ? $autocomplete : null, + 'novalidate' => true, + 'data-status' => $data_status_attr, + ); + + $atts += (array) apply_filters( 'wpcf7_form_additional_atts', array() ); + + $html .= sprintf( '
', wpcf7_format_atts( $atts ) ) . "\n"; + $html .= $this->form_hidden_fields(); + $html .= $this->form_elements(); + + if ( ! $this->responses_count ) { + $html .= $this->form_response_output(); + } + + $html .= "\n" . '
'; + $html .= "\n" . '
'; + + return $html . "\n"; + } + + + /** + * Returns the class name that matches the given form status. + */ + private function form_status_class_name( $status ) { + switch ( $status ) { + case 'init': + $class = 'init'; + break; + case 'validation_failed': + $class = 'invalid'; + break; + case 'acceptance_missing': + $class = 'unaccepted'; + break; + case 'spam': + $class = 'spam'; + break; + case 'aborted': + $class = 'aborted'; + break; + case 'mail_sent': + $class = 'sent'; + break; + case 'mail_failed': + $class = 'failed'; + break; + default: + $class = sprintf( + 'custom-%s', + preg_replace( '/[^0-9a-z]+/i', '-', $status ) + ); + } + + return $class; + } + + + /** + * Returns a set of hidden fields. + */ + private function form_hidden_fields() { + $hidden_fields = array( + '_wpcf7' => $this->id(), + '_wpcf7_version' => WPCF7_VERSION, + '_wpcf7_locale' => $this->locale(), + '_wpcf7_unit_tag' => $this->unit_tag(), + '_wpcf7_container_post' => 0, + '_wpcf7_posted_data_hash' => '', + ); + + if ( in_the_loop() ) { + $hidden_fields['_wpcf7_container_post'] = (int) get_the_ID(); + } + + if ( $this->nonce_is_active() and is_user_logged_in() ) { + $hidden_fields['_wpnonce'] = wpcf7_create_nonce(); + } + + $hidden_fields += (array) apply_filters( + 'wpcf7_form_hidden_fields', array() + ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'fieldset', array( + 'class' => 'hidden-fields-container', + ) ); + + foreach ( $hidden_fields as $name => $value ) { + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'name' => $name, + 'value' => $value, + ) ); + } + + return $formatter->output() . "\n"; + } + + + /** + * Returns the visible response output for a form submission. + */ + public function form_response_output() { + $status = 'init'; + $class = 'wpcf7-response-output'; + $content = ''; + + if ( $this->is_posted() ) { // Post response output for non-AJAX + $submission = WPCF7_Submission::get_instance(); + $status = $submission->get_status(); + $content = $submission->get_response(); + } + + $atts = array( + 'class' => trim( $class ), + 'aria-hidden' => 'true', + ); + + $output = sprintf( '
%2$s
', + wpcf7_format_atts( $atts ), + esc_html( $content ) + ); + + $output = apply_filters( 'wpcf7_form_response_output', + $output, $class, $content, $this, $status + ); + + $this->responses_count += 1; + + return $output; + } + + + /** + * Returns the response output that is only accessible from screen readers. + */ + public function screen_reader_response() { + $primary_response = ''; + $validation_errors = array(); + + if ( $this->is_posted() ) { // Post response output for non-AJAX + $submission = WPCF7_Submission::get_instance(); + $primary_response = $submission->get_response(); + + if ( $invalid_fields = $submission->get_invalid_fields() ) { + foreach ( (array) $invalid_fields as $name => $field ) { + $list_item = esc_html( $field['reason'] ); + + if ( $field['idref'] ) { + $list_item = sprintf( + '%2$s', + esc_attr( $field['idref'] ), + $list_item + ); + } + + $validation_error_id = wpcf7_get_validation_error_reference( + $name, + $this->unit_tag() + ); + + if ( $validation_error_id ) { + $list_item = sprintf( + '
  • %2$s
  • ', + esc_attr( $validation_error_id ), + $list_item + ); + + $validation_errors[] = $list_item; + } + } + } + } + + $primary_response = sprintf( + '

    %s

    ', + esc_html( $primary_response ) + ); + + $validation_errors = sprintf( + '
      %s
    ', + implode( "\n", $validation_errors ) + ); + + $output = sprintf( + '
    %1$s %2$s
    ', + $primary_response, + $validation_errors + ); + + return $output; + } + + + /** + * Returns a validation error for the specified input field. + * + * @param string $name Input field name. + */ + public function validation_error( $name ) { + $error = ''; + + if ( $this->is_posted() ) { + $submission = WPCF7_Submission::get_instance(); + + if ( $invalid_field = $submission->get_invalid_field( $name ) ) { + $error = trim( $invalid_field['reason'] ); + } + } + + if ( ! $error ) { + return $error; + } + + $atts = array( + 'class' => 'wpcf7-not-valid-tip', + 'aria-hidden' => 'true', + ); + + $error = sprintf( + '%2$s', + wpcf7_format_atts( $atts ), + esc_html( $error ) + ); + + return apply_filters( 'wpcf7_validation_error', $error, $name, $this ); + } + + + /** + * Replaces all form-tags in the form template with corresponding HTML. + * + * @return string Replaced form content. + */ + public function replace_all_form_tags() { + $manager = WPCF7_FormTagsManager::get_instance(); + $form = $this->prop( 'form' ); + + if ( wpcf7_autop_or_not() ) { + $form = $manager->replace_with_placeholders( $form ); + $form = wpcf7_autop( $form ); + $form = $manager->restore_from_placeholders( $form ); + } + + $form = $manager->replace_all( $form ); + $this->scanned_form_tags = $manager->get_scanned_tags(); + + return $form; + } + + + /** + * Replaces all form-tags in the form template with corresponding HTML. + * + * @deprecated 4.6 Use replace_all_form_tags() + * + * @return string Replaced form content. + */ + public function form_do_shortcode() { + wpcf7_deprecated_function( __METHOD__, '4.6', + 'WPCF7_ContactForm::replace_all_form_tags' + ); + + return $this->replace_all_form_tags(); + } + + + /** + * Scans form-tags from the form template. + * + * @param string|array|null $cond Optional. Filters. Default null. + * @return array Form-tags matching the given filter conditions. + */ + public function scan_form_tags( $cond = null ) { + $manager = WPCF7_FormTagsManager::get_instance(); + + if ( empty( $this->scanned_form_tags ) ) { + $this->scanned_form_tags = $manager->scan( $this->prop( 'form' ) ); + } + + $tags = $this->scanned_form_tags; + + return $manager->filter( $tags, $cond ); + } + + + /** + * Scans form-tags from the form template. + * + * @deprecated 4.6 Use scan_form_tags() + * + * @param string|array|null $cond Optional. Filters. Default null. + * @return array Form-tags matching the given filter conditions. + */ + public function form_scan_shortcode( $cond = null ) { + wpcf7_deprecated_function( __METHOD__, '4.6', + 'WPCF7_ContactForm::scan_form_tags' + ); + + return $this->scan_form_tags( $cond ); + } + + + /** + * Replaces all form-tags in the form template with corresponding HTML. + * + * @return string Replaced form content. wpcf7_form_elements filters applied. + */ + public function form_elements() { + return apply_filters( 'wpcf7_form_elements', + $this->replace_all_form_tags() + ); + } + + + /** + * Collects mail-tags available for this contact form. + * + * @param string|array $options Optional. Search options. + * @return array Mail-tag names. + */ + public function collect_mail_tags( $options = '' ) { + $manager = WPCF7_FormTagsManager::get_instance(); + + $options = wp_parse_args( $options, array( + 'include' => array(), + 'exclude' => $manager->collect_tag_types( 'not-for-mail' ), + ) ); + + $tags = $this->scan_form_tags(); + $mailtags = array(); + + foreach ( (array) $tags as $tag ) { + $type = $tag->basetype; + + if ( empty( $type ) ) { + continue; + } elseif ( ! empty( $options['include'] ) ) { + if ( ! in_array( $type, $options['include'], true ) ) { + continue; + } + } elseif ( ! empty( $options['exclude'] ) ) { + if ( in_array( $type, $options['exclude'], true ) ) { + continue; + } + } + + $mailtags[] = $tag->name; + } + + $mailtags = array_unique( $mailtags ); + $mailtags = array_filter( $mailtags ); + $mailtags = array_values( $mailtags ); + + return apply_filters( 'wpcf7_collect_mail_tags', $mailtags, $options, $this ); + } + + + /** + * Prints a mail-tag suggestion list. + * + * @param string $template_name Optional. Mail template name. Default 'mail'. + */ + public function suggest_mail_tags( $template_name = 'mail' ) { + $mail = wp_parse_args( $this->prop( $template_name ), + array( + 'active' => false, + 'recipient' => '', + 'sender' => '', + 'subject' => '', + 'body' => '', + 'additional_headers' => '', + 'attachments' => '', + 'use_html' => false, + 'exclude_blank' => false, + ) + ); + + $mail = array_filter( $mail ); + + foreach ( (array) $this->collect_mail_tags() as $mail_tag ) { + $pattern = sprintf( + '/\[(_[a-z]+_)?%s([ \t]+[^]]+)?\]/', + preg_quote( $mail_tag, '/' ) + ); + + $used = preg_grep( $pattern, $mail ); + + echo sprintf( + '[%2$s]', + 'mailtag code ' . ( $used ? 'used' : 'unused' ), + esc_html( $mail_tag ) + ); + } + } + + + /** + * Submits this contact form. + * + * @param string|array $options Optional. Submission options. Default empty. + * @return array Result of submission. + */ + public function submit( $options = '' ) { + $options = wp_parse_args( $options, array( + 'skip_mail' => ( + $this->in_demo_mode() || + $this->is_true( 'skip_mail' ) || + ! empty( $this->skip_mail ) + ), + ) ); + + if ( + $this->is_true( 'subscribers_only' ) and + ! current_user_can( 'wpcf7_submit', $this->id() ) + ) { + $result = array( + 'contact_form_id' => $this->id(), + 'status' => 'error', + 'message' => __( 'This contact form is available only for logged in users.', 'contact-form-7' ), + ); + + return $result; + } + + $submission = WPCF7_Submission::get_instance( $this, array( + 'skip_mail' => $options['skip_mail'], + ) ); + + $result = array( + 'contact_form_id' => $this->id(), + ); + + $result += $submission->get_result(); + + if ( $this->in_demo_mode() ) { + $result['demo_mode'] = true; + } + + do_action( 'wpcf7_submit', $this, $result ); + + return $result; + } + + + /** + * Returns message used for given status. + * + * @param string $status Status. + * @param bool $filter Optional. Whether filters are applied. Default true. + * @return string Message. + */ + public function message( $status, $filter = true ) { + $messages = $this->prop( 'messages' ); + $message = isset( $messages[$status] ) ? $messages[$status] : ''; + + if ( $filter ) { + $message = $this->filter_message( $message, $status ); + } + + return $message; + } + + + /** + * Filters a message. + * + * @param string $message Message to filter. + * @param string $status Optional. Status. Default empty. + * @return string Filtered message. + */ + public function filter_message( $message, $status = '' ) { + $message = wpcf7_mail_replace_tags( $message ); + $message = apply_filters( 'wpcf7_display_message', $message, $status ); + $message = wp_strip_all_tags( $message ); + + return $message; + } + + + /** + * Returns the additional setting value searched by name. + * + * @param string $name Name of setting. + * @return string Additional setting value. + */ + public function pref( $name ) { + $settings = $this->additional_setting( $name ); + + if ( $settings ) { + return $settings[0]; + } + } + + + /** + * Returns additional setting values searched by name. + * + * @param string $name Name of setting. + * @param int $max Maximum result item count. + * @return array Additional setting values. + */ + public function additional_setting( $name, $max = 1 ) { + $settings = (array) explode( "\n", $this->prop( 'additional_settings' ) ); + + $pattern = '/^([a-zA-Z0-9_]+)[\t ]*:(.*)$/'; + $count = 0; + $values = array(); + + foreach ( $settings as $setting ) { + if ( preg_match( $pattern, $setting, $matches ) ) { + if ( $matches[1] !== $name ) { + continue; + } + + if ( ! $max or $count < (int) $max ) { + $values[] = trim( $matches[2] ); + $count += 1; + } + } + } + + return $values; + } + + + /** + * Returns true if the specified setting has a truthy string value. + * + * @param string $name Name of setting. + * @return bool True if the setting value is 'on', 'true', or '1'. + */ + public function is_true( $name ) { + return in_array( + $this->pref( $name ), + array( 'on', 'true', '1' ), + true + ); + } + + + /** + * Returns true if this contact form is in the demo mode. + */ + public function in_demo_mode() { + return $this->is_true( 'demo_mode' ); + } + + + /** + * Returns true if nonce is active for this contact form. + */ + public function nonce_is_active() { + $is_active = WPCF7_VERIFY_NONCE; + + if ( $this->is_true( 'subscribers_only' ) ) { + $is_active = true; + } + + return (bool) apply_filters( 'wpcf7_verify_nonce', $is_active, $this ); + } + + + /** + * Returns true if the specified setting has a falsey string value. + * + * @param string $name Name of setting. + * @return bool True if the setting value is 'off', 'false', or '0'. + */ + public function is_false( $name ) { + return in_array( + $this->pref( $name ), + array( 'off', 'false', '0' ), + true + ); + } + + + /** + * Upgrades this contact form properties. + */ + private function upgrade() { + $mail = $this->prop( 'mail' ); + + if ( is_array( $mail ) and ! isset( $mail['recipient'] ) ) { + $mail['recipient'] = get_option( 'admin_email' ); + } + + $this->properties['mail'] = $mail; + + $messages = $this->prop( 'messages' ); + + if ( is_array( $messages ) ) { + foreach ( wpcf7_messages() as $key => $arr ) { + if ( ! isset( $messages[$key] ) ) { + $messages[$key] = $arr['default']; + } + } + } + + $this->properties['messages'] = $messages; + } + + + /** + * Stores this contact form properties to the database. + * + * @return int The post ID on success. The value 0 on failure. + */ + public function save() { + $title = wp_slash( $this->title ); + $props = wp_slash( $this->get_properties() ); + + $post_content = implode( "\n", wpcf7_array_flatten( $props ) ); + + if ( $this->initial() ) { + $post_id = wp_insert_post( array( + 'post_type' => self::post_type, + 'post_status' => 'publish', + 'post_title' => $title, + 'post_content' => trim( $post_content ), + ) ); + } else { + $post_id = wp_update_post( array( + 'ID' => (int) $this->id, + 'post_status' => 'publish', + 'post_title' => $title, + 'post_content' => trim( $post_content ), + ) ); + } + + if ( $post_id ) { + foreach ( $props as $prop => $value ) { + update_post_meta( $post_id, '_' . $prop, + wpcf7_normalize_newline_deep( $value ) + ); + } + + if ( wpcf7_is_valid_locale( $this->locale ) ) { + update_post_meta( $post_id, '_locale', $this->locale ); + } + + add_post_meta( $post_id, '_hash', + wpcf7_generate_contact_form_hash( $post_id ), + true // Unique + ); + + if ( $this->initial() ) { + $this->id = $post_id; + do_action( 'wpcf7_after_create', $this ); + } else { + do_action( 'wpcf7_after_update', $this ); + } + + do_action( 'wpcf7_after_save', $this ); + } + + return $post_id; + } + + + /** + * Makes a copy of this contact form. + * + * @return WPCF7_ContactForm New contact form object. + */ + public function copy() { + $new = new self(); + $new->title = $this->title . '_copy'; + $new->locale = $this->locale; + $new->properties = $this->properties; + + return apply_filters( 'wpcf7_copy', $new, $this ); + } + + + /** + * Deletes this contact form. + * + * @return bool True if deletion succeeded, false otherwise. + */ + public function delete() { + if ( $this->initial() ) { + return false; + } + + if ( wp_delete_post( $this->id, true ) ) { + $this->id = 0; + return true; + } + + return false; + } + + + /** + * Returns a WordPress shortcode for this contact form. + */ + public function shortcode( $options = '' ) { + $options = wp_parse_args( $options, array( + 'use_old_format' => false + ) ); + + $title = str_replace( array( '"', '[', ']' ), '', $this->title ); + + if ( $options['use_old_format'] ) { + $old_unit_id = (int) get_post_meta( $this->id, '_old_cf7_unit_id', true ); + + if ( $old_unit_id ) { + $shortcode = sprintf( + '[contact-form %1$d "%2$s"]', + $old_unit_id, + $title + ); + } else { + $shortcode = ''; + } + } else { + $shortcode = sprintf( + '[contact-form-7 id="%1$s" title="%2$s"]', + $this->hash(), + $title + ); + } + + return apply_filters( 'wpcf7_contact_form_shortcode', + $shortcode, $options, $this + ); + } +} diff --git a/wp-content/plugins/contact-form-7/includes/controller.php b/wp-content/plugins/contact-form-7/includes/controller.php new file mode 100644 index 0000000..7d2b876 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/controller.php @@ -0,0 +1,184 @@ +submit(); + } +} + + +/** + * Registers main scripts and styles. + */ +add_action( + 'wp_enqueue_scripts', + static function () { + $assets = include wpcf7_plugin_path( 'includes/js/index.asset.php' ); + + $assets = wp_parse_args( $assets, array( + 'dependencies' => array(), + 'version' => WPCF7_VERSION, + ) ); + + wp_register_script( + 'contact-form-7', + wpcf7_plugin_url( 'includes/js/index.js' ), + array_merge( + $assets['dependencies'], + array( 'swv' ) + ), + $assets['version'], + array( 'in_footer' => true ) + ); + + wp_set_script_translations( 'contact-form-7', 'contact-form-7' ); + + wp_register_script( + 'contact-form-7-html5-fallback', + wpcf7_plugin_url( 'includes/js/html5-fallback.js' ), + array( 'jquery-ui-datepicker' ), + WPCF7_VERSION, + array( 'in_footer' => true ) + ); + + if ( wpcf7_load_js() ) { + wpcf7_enqueue_scripts(); + } + + wp_register_style( + 'contact-form-7', + wpcf7_plugin_url( 'includes/css/styles.css' ), + array(), + WPCF7_VERSION, + 'all' + ); + + wp_register_style( + 'contact-form-7-rtl', + wpcf7_plugin_url( 'includes/css/styles-rtl.css' ), + array( 'contact-form-7' ), + WPCF7_VERSION, + 'all' + ); + + wp_register_style( + 'jquery-ui-smoothness', + wpcf7_plugin_url( + 'includes/js/jquery-ui/themes/smoothness/jquery-ui.min.css' + ), + array(), + '1.12.1', + 'screen' + ); + + if ( wpcf7_load_css() ) { + wpcf7_enqueue_styles(); + } + }, + 10, 0 +); + + +/** + * Enqueues scripts. + */ +function wpcf7_enqueue_scripts() { + wp_enqueue_script( 'contact-form-7' ); + + $wpcf7_obj = array( + 'api' => array( + 'root' => sanitize_url( get_rest_url() ), + 'namespace' => 'contact-form-7/v1', + ), + ); + + if ( defined( 'WP_CACHE' ) and WP_CACHE ) { + $wpcf7_obj = array_merge( $wpcf7_obj, array( + 'cached' => 1, + ) ); + } + + wp_add_inline_script( 'contact-form-7', + sprintf( + 'var wpcf7 = %s;', + wp_json_encode( $wpcf7_obj, JSON_PRETTY_PRINT ) + ), + 'before' + ); + + do_action( 'wpcf7_enqueue_scripts' ); +} + + +/** + * Returns true if the main script is enqueued. + */ +function wpcf7_script_is() { + return wp_script_is( 'contact-form-7' ); +} + + +/** + * Enqueues styles. + */ +function wpcf7_enqueue_styles() { + wp_enqueue_style( 'contact-form-7' ); + + if ( wpcf7_is_rtl() ) { + wp_enqueue_style( 'contact-form-7-rtl' ); + } + + do_action( 'wpcf7_enqueue_styles' ); +} + + +/** + * Returns true if the main stylesheet is enqueued. + */ +function wpcf7_style_is() { + return wp_style_is( 'contact-form-7' ); +} + + +add_action( + 'wp_enqueue_scripts', + 'wpcf7_html5_fallback', + 20, 0 +); + +/** + * Enqueues scripts and styles for the HTML5 fallback. + */ +function wpcf7_html5_fallback() { + if ( ! wpcf7_support_html5_fallback() ) { + return; + } + + if ( wpcf7_script_is() ) { + wp_enqueue_script( 'contact-form-7-html5-fallback' ); + } + + if ( wpcf7_style_is() ) { + wp_enqueue_style( 'jquery-ui-smoothness' ); + } +} diff --git a/wp-content/plugins/contact-form-7/includes/css/styles-rtl.css b/wp-content/plugins/contact-form-7/includes/css/styles-rtl.css new file mode 100644 index 0000000..2ec20fd --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/css/styles-rtl.css @@ -0,0 +1,11 @@ +.wpcf7-not-valid-tip { + direction: rtl; +} + +.use-floating-validation-tip .wpcf7-not-valid-tip { + right: 1em; +} + +.wpcf7-list-item { + margin: 0 1em 0 0; +} diff --git a/wp-content/plugins/contact-form-7/includes/css/styles.css b/wp-content/plugins/contact-form-7/includes/css/styles.css new file mode 100644 index 0000000..e6517e9 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/css/styles.css @@ -0,0 +1,176 @@ +.wpcf7 .screen-reader-response { + position: absolute; + overflow: hidden; + clip: rect(1px, 1px, 1px, 1px); + clip-path: inset(50%); + height: 1px; + width: 1px; + margin: -1px; + padding: 0; + border: 0; + word-wrap: normal !important; +} + +.wpcf7 .hidden-fields-container { + display: none; +} + +.wpcf7 form .wpcf7-response-output { + margin: 2em 0.5em 1em; + padding: 0.2em 1em; + border: 2px solid #00a0d2; /* Blue */ +} + +.wpcf7 form.init .wpcf7-response-output, +.wpcf7 form.resetting .wpcf7-response-output, +.wpcf7 form.submitting .wpcf7-response-output { + display: none; +} + +.wpcf7 form.sent .wpcf7-response-output { + border-color: #46b450; /* Green */ +} + +.wpcf7 form.failed .wpcf7-response-output, +.wpcf7 form.aborted .wpcf7-response-output { + border-color: #dc3232; /* Red */ +} + +.wpcf7 form.spam .wpcf7-response-output { + border-color: #f56e28; /* Orange */ +} + +.wpcf7 form.invalid .wpcf7-response-output, +.wpcf7 form.unaccepted .wpcf7-response-output, +.wpcf7 form.payment-required .wpcf7-response-output { + border-color: #ffb900; /* Yellow */ +} + +.wpcf7-form-control-wrap { + position: relative; +} + +.wpcf7-not-valid-tip { + color: #dc3232; /* Red */ + font-size: 1em; + font-weight: normal; + display: block; +} + +.use-floating-validation-tip .wpcf7-not-valid-tip { + position: relative; + top: -2ex; + left: 1em; + z-index: 100; + border: 1px solid #dc3232; + background: #fff; + padding: .2em .8em; + width: 24em; +} + +.wpcf7-list-item { + display: inline-block; + margin: 0 0 0 1em; +} + +.wpcf7-list-item-label::before, +.wpcf7-list-item-label::after { + content: " "; +} + +.wpcf7-spinner { + visibility: hidden; + display: inline-block; + background-color: #23282d; /* Dark Gray 800 */ + opacity: 0.75; + width: 24px; + height: 24px; + border: none; + border-radius: 100%; + padding: 0; + margin: 0 24px; + position: relative; +} + +form.submitting .wpcf7-spinner { + visibility: visible; +} + +.wpcf7-spinner::before { + content: ''; + position: absolute; + background-color: #fbfbfc; /* Light Gray 100 */ + top: 4px; + left: 4px; + width: 6px; + height: 6px; + border: none; + border-radius: 100%; + transform-origin: 8px 8px; + animation-name: spin; + animation-duration: 1000ms; + animation-timing-function: linear; + animation-iteration-count: infinite; +} + +@media (prefers-reduced-motion: reduce) { + .wpcf7-spinner::before { + animation-name: blink; + animation-duration: 2000ms; + } +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} + +@keyframes blink { + from { + opacity: 0; + } + + 50% { + opacity: 1; + } + + to { + opacity: 0; + } +} + +.wpcf7 [inert] { + opacity: 0.5; +} + +.wpcf7 input[type="file"] { + cursor: pointer; +} + +.wpcf7 input[type="file"]:disabled { + cursor: default; +} + +.wpcf7 .wpcf7-submit:disabled { + cursor: not-allowed; +} + +.wpcf7 input[type="url"], +.wpcf7 input[type="email"], +.wpcf7 input[type="tel"] { + direction: ltr; +} + +.wpcf7-reflection > output { + display: list-item; + list-style: none; +} + +.wpcf7-reflection > output[hidden] { + display: none; +} diff --git a/wp-content/plugins/contact-form-7/includes/file.php b/wp-content/plugins/contact-form-7/includes/file.php new file mode 100644 index 0000000..2db05d1 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/file.php @@ -0,0 +1,440 @@ + false, + 'filetypes' => '', + 'limit' => MB_IN_BYTES, + ) ); + + foreach ( array( 'name', 'size', 'tmp_name', 'error' ) as $key ) { + if ( ! isset( $file[$key] ) ) { + $file[$key] = array(); + } + } + + $names = wpcf7_array_flatten( $file['name'] ); + $sizes = wpcf7_array_flatten( $file['size'] ); + $tmp_names = wpcf7_array_flatten( $file['tmp_name'] ); + $errors = wpcf7_array_flatten( $file['error'] ); + + foreach ( $errors as $error ) { + if ( ! empty( $error ) and UPLOAD_ERR_NO_FILE !== $error ) { + return new WP_Error( 'wpcf7_upload_failed_php_error', + wpcf7_get_message( 'upload_failed_php_error' ) + ); + } + } + + if ( isset( $options['schema'] ) and isset( $options['name'] ) ) { + $context = array( + 'file' => true, + 'field' => $options['name'], + ); + + foreach ( $options['schema']->validate( $context ) as $result ) { + if ( is_wp_error( $result ) ) { + return $result; + } + } + } + + // Move uploaded file to tmp dir + $uploads_dir = wpcf7_upload_tmp_dir(); + $uploads_dir = wpcf7_maybe_add_random_dir( $uploads_dir ); + + $uploaded_files = array(); + + foreach ( $names as $key => $name ) { + $tmp_name = $tmp_names[$key]; + + if ( empty( $tmp_name ) or ! is_uploaded_file( $tmp_name ) ) { + continue; + } + + $filename = $name; + $filename = wpcf7_canonicalize( $filename, array( 'strto' => 'as-is' ) ); + $filename = wpcf7_antiscript_file_name( $filename ); + + $filename = apply_filters( 'wpcf7_upload_file_name', + $filename, $name, $options + ); + + $filename = wp_unique_filename( $uploads_dir, $filename ); + $new_file = path_join( $uploads_dir, $filename ); + + // phpcs:ignore Generic.PHP.ForbiddenFunctions.Found + if ( false === @move_uploaded_file( $tmp_name, $new_file ) ) { + return new WP_Error( 'wpcf7_upload_failed', + wpcf7_get_message( 'upload_failed' ) + ); + } + + // Make sure the uploaded file is only readable for the owner process. + $filesystem->chmod( $new_file, 0400 ); + + $uploaded_files[] = $new_file; + } + + return $uploaded_files; +} + + +add_filter( + 'wpcf7_messages', + 'wpcf7_file_messages', + 10, 1 +); + +/** + * A wpcf7_messages filter callback that adds messages for + * file-uploading fields. + */ +function wpcf7_file_messages( $messages ) { + return array_merge( $messages, array( + 'upload_failed' => array( + 'description' => __( 'Uploading a file fails for any reason', 'contact-form-7' ), + 'default' => __( 'There was an unknown error uploading the file.', 'contact-form-7' ), + ), + + 'upload_file_type_invalid' => array( + 'description' => __( 'Uploaded file is not allowed for file type', 'contact-form-7' ), + 'default' => __( 'You are not allowed to upload files of this type.', 'contact-form-7' ), + ), + + 'upload_file_too_large' => array( + 'description' => __( 'Uploaded file is too large', 'contact-form-7' ), + 'default' => __( 'The uploaded file is too large.', 'contact-form-7' ), + ), + + 'upload_failed_php_error' => array( + 'description' => __( 'Uploading a file fails for PHP error', 'contact-form-7' ), + 'default' => __( 'There was an error uploading the file.', 'contact-form-7' ), + ), + ) ); +} + + +add_filter( + 'wpcf7_form_enctype', + 'wpcf7_file_form_enctype_filter', + 10, 1 +); + +/** + * A wpcf7_form_enctype filter callback that sets the enctype attribute + * to multipart/form-data if the form has file-uploading fields. + */ +function wpcf7_file_form_enctype_filter( $enctype ) { + $multipart = (bool) wpcf7_scan_form_tags( array( + 'feature' => 'file-uploading', + ) ); + + if ( $multipart ) { + $enctype = 'multipart/form-data'; + } + + return $enctype; +} + + +/** + * Converts a MIME type string to an array of corresponding file extensions. + * + * @param string $mime MIME type. + * Wildcard (*) is available for the subtype part. + * @return array Corresponding file extensions. + */ +function wpcf7_convert_mime_to_ext( $mime ) { + static $mime_types = array(); + + $mime_types = wp_get_mime_types(); + + $results = array(); + + if ( preg_match( '%^([a-z]+)/([*]|[a-z0-9.+-]+)$%i', $mime, $matches ) ) { + foreach ( $mime_types as $key => $val ) { + if ( + '*' === $matches[2] and str_starts_with( $val, $matches[1] . '/' ) or + $val === $matches[0] + ) { + $results = array_merge( $results, explode( '|', $key ) ); + } + } + } + + $results = array_unique( $results ); + $results = array_filter( $results ); + $results = array_values( $results ); + + return $results; +} + + +/** + * Returns a formatted list of acceptable filetypes. + * + * @param string|array $types Optional. Array of filetypes. + * @param string $format Optional. Pre-defined format designator. + * @return string Formatted list of acceptable filetypes. + */ +function wpcf7_acceptable_filetypes( $types = 'default', $format = 'regex' ) { + if ( 'default' === $types or empty( $types ) ) { + $types = array( + 'audio/*', + 'video/*', + 'image/*', + ); + } else { + $types = array_map( + static function ( $type ) { + if ( is_string( $type ) ) { + return preg_split( '/[\s|,]+/', strtolower( $type ) ); + } + }, + (array) $types + ); + + $types = wpcf7_array_flatten( $types ); + $types = array_filter( array_unique( $types ) ); + } + + if ( 'attr' === $format or 'attribute' === $format ) { + $types = array_map( + static function ( $type ) { + if ( false === strpos( $type, '/' ) ) { + return sprintf( '.%s', trim( $type, '.' ) ); + } elseif ( preg_match( '%^([a-z]+)/[*]$%i', $type, $matches ) ) { + if ( + in_array( $matches[1], array( 'audio', 'video', 'image' ), true ) + ) { + return $type; + } else { + return ''; + } + } elseif ( wpcf7_convert_mime_to_ext( $type ) ) { + return $type; + } + }, + $types + ); + + $types = array_filter( $types ); + + return implode( ',', $types ); + + } elseif ( 'regex' === $format ) { + $types = array_map( + static function ( $type ) { + if ( false === strpos( $type, '/' ) ) { + return preg_quote( trim( $type, '.' ) ); + } elseif ( $type = wpcf7_convert_mime_to_ext( $type ) ) { + return $type; + } + }, + $types + ); + + $types = wpcf7_array_flatten( $types ); + $types = array_filter( array_unique( $types ) ); + + return implode( '|', $types ); + } + + return ''; +} + + +add_action( + 'wpcf7_init', + 'wpcf7_init_uploads', + 10, 0 +); + +/** + * Initializes the temporary directory for uploaded files. + */ +function wpcf7_init_uploads() { + $dir = wpcf7_upload_tmp_dir(); + + if ( ! is_dir( $dir ) or ! wp_is_writable( $dir ) ) { + return; + } + + $htaccess_file = path_join( $dir, '.htaccess' ); + + if ( file_exists( $htaccess_file ) ) { + list( $first_line_comment ) = (array) file( + $htaccess_file, + FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES + ); + + if ( '# Apache 2.4+' === $first_line_comment ) { + return; + } + } + + $filesystem = WPCF7_Filesystem::get_instance(); + + $htaccess_body = ' +# Apache 2.4+ + + Require all denied + + +# Apache 2.2 + + Deny from all + +'; + + $filesystem->put_contents( $htaccess_file, ltrim( $htaccess_body ) ); +} + + +/** + * Creates a child directory with a randomly generated name. + * + * @param string $dir The parent directory path. + * @return string The child directory path if created, otherwise the parent. + */ +function wpcf7_maybe_add_random_dir( $dir ) { + do { + $dir_new = path_join( $dir, zeroise( wp_rand(), 10 ) ); + } while ( file_exists( $dir_new ) ); + + if ( wp_mkdir_p( $dir_new ) ) { + return $dir_new; + } + + return $dir; +} + + +/** + * Returns the directory path for uploaded files. + * + * @return string Directory path. + */ +function wpcf7_upload_tmp_dir() { + static $output = ''; + + if ( $output ) { + return $output; + } + + if ( defined( 'WPCF7_UPLOADS_TMP_DIR' ) ) { + $dir = path_join( WP_CONTENT_DIR, WPCF7_UPLOADS_TMP_DIR ); + wp_mkdir_p( $dir ); + + if ( wpcf7_is_file_path_in_content_dir( $dir ) ) { + return $output = $dir; + } + } + + $dir = path_join( wpcf7_upload_dir( 'dir' ), 'wpcf7_uploads' ); + wp_mkdir_p( $dir ); + + return $output = $dir; +} + + +add_action( + 'shutdown', + 'wpcf7_cleanup_upload_files', + 20, 0 +); + +/** + * Cleans up files in the temporary directory for uploaded files. + * + * @param int $seconds Files older than this are removed. Default 60. + * @param int $max Maximum number of files to be removed in a function call. + * Default 100. + */ +function wpcf7_cleanup_upload_files( $seconds = 60, $max = 100 ) { + $dir = trailingslashit( wpcf7_upload_tmp_dir() ); + + if ( + ! is_dir( $dir ) or + ! is_readable( $dir ) or + ! wp_is_writable( $dir ) + ) { + return; + } + + $seconds = absint( $seconds ); + $max = absint( $max ); + $count = 0; + + if ( $handle = opendir( $dir ) ) { + while ( false !== ( $file = readdir( $handle ) ) ) { + if ( '.' === $file or '..' === $file or '.htaccess' === $file ) { + continue; + } + + $mtime = @filemtime( path_join( $dir, $file ) ); + + if ( $mtime and time() < $mtime + $seconds ) { // less than $seconds old + continue; + } + + wpcf7_rmdir_p( path_join( $dir, $file ) ); + $count += 1; + + if ( $max <= $count ) { + break; + } + } + + closedir( $handle ); + } +} + + +add_action( + 'wpcf7_admin_warnings', + 'wpcf7_file_display_warning_message', + 10, 3 +); + +/** + * Displays warning messages about file-uploading fields. + */ +function wpcf7_file_display_warning_message( $page, $action, $object ) { + if ( $object instanceof WPCF7_ContactForm ) { + $contact_form = $object; + } else { + return; + } + + $has_tags = (bool) $contact_form->scan_form_tags( array( + 'feature' => 'file-uploading', + ) ); + + if ( ! $has_tags ) { + return; + } + + $uploads_dir = wpcf7_upload_tmp_dir(); + + if ( ! is_dir( $uploads_dir ) or ! wp_is_writable( $uploads_dir ) ) { + wp_admin_notice( + sprintf( + /* translators: %s: the path of the temporary folder */ + __( 'This contact form has file uploading fields, but the temporary folder for the files (%s) does not exist or is not writable. You can create the folder or change its permission manually.', 'contact-form-7' ), + $uploads_dir + ), + array( 'type' => 'warning' ) + ); + } +} diff --git a/wp-content/plugins/contact-form-7/includes/filesystem.php b/wp-content/plugins/contact-form-7/includes/filesystem.php new file mode 100644 index 0000000..6f98101 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/filesystem.php @@ -0,0 +1,127 @@ +connect(); + } + + + /** + * Connects to the filesystem. + * + * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. + */ + private function connect() { + global $wp_filesystem; + + if ( $this->filesystem ) { + return false; + } + + require_once ABSPATH . 'wp-admin/includes/file.php'; + require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php'; + require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php'; + + ob_start(); + $credentials = request_filesystem_credentials( '' ); + ob_end_clean(); + + if ( false === $credentials or ! WP_Filesystem( $credentials ) ) { + wp_trigger_error( + __FUNCTION__, + __( 'Could not access filesystem.', 'contact-form-7' ) + ); + } + + if ( $wp_filesystem instanceof WP_Filesystem_Base ) { + $this->filesystem = $wp_filesystem; + } else { + $this->filesystem = new WP_Filesystem_Direct( 1 ); + } + + if ( ! defined( 'FS_CHMOD_DIR' ) ) { + define( 'FS_CHMOD_DIR', fileperms( ABSPATH ) & 0777 | 0755 ); + } + + if ( ! defined( 'FS_CHMOD_FILE' ) ) { + define( 'FS_CHMOD_FILE', fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 ); + } + } + + + /** + * Changes filesystem permissions. + * + * @param string $file Path to the file. + * @param int|false $mode Optional. The permissions as octal number. + * @param bool $recursive Optional. If set to true, + * changes file permissions recursively. Default false. + * @return bool True on success, false on failure. + */ + public function chmod( $file, $mode = false, $recursive = false ) { + return $this->filesystem->chmod( $file, $mode, $recursive ); + } + + + /** + * Deletes a file or directory. + * + * @param string $file Path to the file or directory. + * @param bool $recursive Optional. If set to true, deletes + * files and folders recursively. Default false. + * @param string|false $type Type of resource. + * 'f' for file, 'd' for directory. Default false. + * @return bool True on success, false on failure. + */ + public function delete( $file, $recursive = false, $type = false ) { + return $this->filesystem->delete( $file, $recursive, $type ); + } + + + /** + * Writes a string to a file. + * + * @param string $file Path to the file where to write the data. + * @param string $contents The data to write. + * @param int $mode The file permissions as octal number. + * @return bool True on success, false on failure. + */ + public function put_contents( $file, $contents, $mode = false ) { + return $this->filesystem->put_contents( $file, $contents, $mode ); + } + +} diff --git a/wp-content/plugins/contact-form-7/includes/form-tag.php b/wp-content/plugins/contact-form-7/includes/form-tag.php new file mode 100644 index 0000000..c816d35 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/form-tag.php @@ -0,0 +1,618 @@ + $value ) { + if ( property_exists( __CLASS__, $key ) ) { + $this->{$key} = $value; + } + } + } + } + + + /** + * Returns true if the type has a trailing asterisk. + */ + public function is_required() { + return str_ends_with( $this->type, '*' ); + } + + + /** + * Returns true if the form-tag has a specified option. + */ + public function has_option( $option_name ) { + $pattern = sprintf( '/^%s(:.+)?$/i', preg_quote( $option_name, '/' ) ); + return (bool) preg_grep( $pattern, $this->options ); + } + + + /** + * Retrieves option values with the specified option name. + * + * @param string $option_name Option name. + * @param string $pattern Optional. A regular expression pattern or one of + * the keys of preset patterns. If specified, only options + * whose value part matches this pattern will be returned. + * @param bool $single Optional. If true, only the first matching option + * will be returned. Default false. + * @return string|array|bool The option value or an array of option values. + * False if there is no option matches the pattern. + */ + public function get_option( $option_name, $pattern = '', $single = false ) { + $preset_patterns = array( + 'date' => '[0-9]{4}-[0-9]{2}-[0-9]{2}', + 'int' => '[0-9]+', + 'signed_int' => '[-]?[0-9]+', + 'num' => '(?:[0-9]+|(?:[0-9]+)?[.][0-9]+)', + 'signed_num' => '[-]?(?:[0-9]+|(?:[0-9]+)?[.][0-9]+)', + 'class' => '[-0-9a-zA-Z_]+', + 'id' => '[-0-9a-zA-Z_]+', + ); + + if ( isset( $preset_patterns[$pattern] ) ) { + $pattern = $preset_patterns[$pattern]; + } + + if ( '' === $pattern ) { + $pattern = '.+'; + } + + $pattern = sprintf( + '/^%s:%s$/i', + preg_quote( $option_name, '/' ), + $pattern + ); + + if ( $single ) { + $matches = $this->get_first_match_option( $pattern ); + + if ( ! $matches ) { + return false; + } + + return substr( $matches[0], strlen( $option_name ) + 1 ); + } else { + $matches_a = $this->get_all_match_options( $pattern ); + + if ( ! $matches_a ) { + return false; + } + + $results = array(); + + foreach ( $matches_a as $matches ) { + $results[] = substr( $matches[0], strlen( $option_name ) + 1 ); + } + + return $results; + } + } + + + /** + * Retrieves the id option value from the form-tag. + */ + public function get_id_option() { + static $used = array(); + + $option = $this->get_option( 'id', 'id', true ); + + if ( + ! $option or + str_starts_with( $option, 'wpcf7' ) or + in_array( $option, $used, true ) + ) { + return false; + } + + $used[] = $option; + + return $option; + } + + + /** + * Retrieves the class option value from the form-tag. + * + * @param string|array $default_classes Optional. Preset classes as an array + * or a whitespace-separated list. Default empty string. + * @return string|bool A whitespace-separated list of classes. + * False if there is no class to return. + */ + public function get_class_option( $default_classes = '' ) { + if ( is_string( $default_classes ) ) { + $default_classes = explode( ' ', $default_classes ); + } + + $options = array_merge( + (array) $default_classes, + (array) $this->get_option( 'class' ) + ); + + $options = array_map( 'sanitize_html_class', $options ); + $options = array_filter( array_unique( $options ) ); + + if ( empty( $options ) ) { + return false; + } + + return implode( ' ', $options ); + } + + + /** + * Retrieves the autocomplete option value from the form-tag. + * + * @return string|bool A whitespace-separated list of tokens. + * False if there is no token to return. + */ + public function get_autocomplete_option() { + $options = (array) $this->get_option( 'autocomplete', '[-0-9a-zA-Z|]+' ); + + $options = array_reduce( $options, static function ( $carry, $item ) { + return array_merge( $carry, + array_map( 'strtolower', explode( '|', $item ) ) + ); + }, array() ); + + $options = array_filter( $options, static function ( $item ) { + return preg_match( '/^[a-z]+(?:-[0-9a-z]+)*$/', $item ); + } ); + + $options = array_unique( $options ); + + if ( empty( $options ) ) { + return false; + } elseif ( in_array( 'off', $options, true ) ) { + return 'off'; + } elseif ( in_array( 'on', $options, true ) ) { + return 'on'; + } else { + return implode( ' ', $options ); + } + } + + + /** + * Retrieves the size option value from the form-tag. + * + * @param string $default_value Optional default value. + * @return string The option value. + */ + public function get_size_option( $default_value = false ) { + $option = $this->get_option( 'size', 'int', true ); + + if ( $option ) { + return $option; + } + + $matches_a = $this->get_all_match_options( '%^([0-9]*)/[0-9]*$%' ); + + foreach ( $matches_a as $matches ) { + if ( isset( $matches[1] ) and '' !== $matches[1] ) { + return $matches[1]; + } + } + + return $default_value; + } + + + /** + * Retrieves the maxlength option value from the form-tag. + * + * @param string $default_value Optional default value. + * @return string The option value. + */ + public function get_maxlength_option( $default_value = false ) { + $option = $this->get_option( 'maxlength', 'int', true ); + + if ( $option ) { + return $option; + } + + $matches_a = $this->get_all_match_options( + '%^(?:[0-9]*x?[0-9]*)?/([0-9]+)$%' + ); + + foreach ( $matches_a as $matches ) { + if ( isset( $matches[1] ) and '' !== $matches[1] ) { + return $matches[1]; + } + } + + return $default_value; + } + + + /** + * Retrieves the minlength option value from the form-tag. + * + * @param string $default_value Optional default value. + * @return string The option value. + */ + public function get_minlength_option( $default_value = false ) { + $option = $this->get_option( 'minlength', 'int', true ); + + if ( $option ) { + return $option; + } else { + return $default_value; + } + } + + + /** + * Retrieves the cols option value from the form-tag. + * + * @param string $default_value Optional default value. + * @return string The option value. + */ + public function get_cols_option( $default_value = false ) { + $option = $this->get_option( 'cols', 'int', true ); + + if ( $option ) { + return $option; + } + + $matches_a = $this->get_all_match_options( + '%^([0-9]*)x([0-9]*)(?:/[0-9]+)?$%' + ); + + foreach ( $matches_a as $matches ) { + if ( isset( $matches[1] ) and '' !== $matches[1] ) { + return $matches[1]; + } + } + + return $default_value; + } + + + /** + * Retrieves the rows option value from the form-tag. + * + * @param string $default_value Optional default value. + * @return string The option value. + */ + public function get_rows_option( $default_value = false ) { + $option = $this->get_option( 'rows', 'int', true ); + + if ( $option ) { + return $option; + } + + $matches_a = $this->get_all_match_options( + '%^([0-9]*)x([0-9]*)(?:/[0-9]+)?$%' + ); + + foreach ( $matches_a as $matches ) { + if ( isset( $matches[2] ) and '' !== $matches[2] ) { + return $matches[2]; + } + } + + return $default_value; + } + + + /** + * Retrieves a date-type option value from the form-tag. + * + * @param string $option_name A date-type option name, such as 'min' or 'max'. + * @return string|bool The option value in YYYY-MM-DD format. False if the + * option does not exist or the date value is invalid. + */ + public function get_date_option( $option_name ) { + $option_value = $this->get_option( $option_name, '', true ); + + if ( empty( $option_value ) ) { + return false; + } + + $date = apply_filters( 'wpcf7_form_tag_date_option', + null, + array( $option_name => $option_value ) + ); + + if ( $date ) { + $date_pattern = '/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/'; + + if ( + preg_match( $date_pattern, $date, $matches ) and + checkdate( $matches[2], $matches[3], $matches[1] ) + ) { + return $date; + } + } else { + $datetime_obj = date_create_immutable( + preg_replace( '/[_]+/', ' ', $option_value ), + wp_timezone() + ); + + if ( $datetime_obj ) { + return $datetime_obj->format( 'Y-m-d' ); + } + } + + return false; + } + + + /** + * Retrieves the default option value from the form-tag. + * + * @param string|array $default_value Optional default value. + * @param string|array $args Optional options for the option value retrieval. + * @return string|array The option value. If the multiple option is enabled, + * an array of option values. + */ + public function get_default_option( $default_value = '', $args = '' ) { + $args = wp_parse_args( $args, array( + 'multiple' => false, + 'shifted' => false, + ) ); + + $options = (array) $this->get_option( 'default' ); + $values = array(); + + if ( empty( $options ) ) { + return $args['multiple'] ? $values : $default_value; + } + + foreach ( $options as $opt ) { + $opt = sanitize_key( $opt ); + + if ( 'user_' === substr( $opt, 0, 5 ) and is_user_logged_in() ) { + $primary_props = array( 'user_login', 'user_email', 'user_url' ); + $opt = in_array( $opt, $primary_props, true ) ? $opt : substr( $opt, 5 ); + + $user = wp_get_current_user(); + $user_prop = $user->get( $opt ); + + if ( ! empty( $user_prop ) ) { + if ( $args['multiple'] ) { + $values[] = $user_prop; + } else { + return $user_prop; + } + } + + } elseif ( 'post_meta' === $opt and in_the_loop() ) { + if ( $args['multiple'] ) { + $values = array_merge( $values, + get_post_meta( get_the_ID(), $this->name ) + ); + } else { + $val = (string) get_post_meta( get_the_ID(), $this->name, true ); + + if ( strlen( $val ) ) { + return $val; + } + } + + } elseif ( + 'get' === $opt and + $vals = wpcf7_superglobal_get( $this->name ) + ) { + $vals = array_map( 'wpcf7_sanitize_query_var', (array) $vals ); + + if ( $args['multiple'] ) { + $values = array_merge( $values, $vals ); + } else { + $val = isset( $vals[0] ) ? (string) $vals[0] : ''; + + if ( strlen( $val ) ) { + return $val; + } + } + + } elseif ( + 'post' === $opt and + $vals = wpcf7_superglobal_post( $this->name ) + ) { + $vals = array_map( 'wpcf7_sanitize_query_var', (array) $vals ); + + if ( $args['multiple'] ) { + $values = array_merge( $values, $vals ); + } else { + $val = isset( $vals[0] ) ? (string) $vals[0] : ''; + + if ( strlen( $val ) ) { + return $val; + } + } + + } elseif ( 'shortcode_attr' === $opt ) { + if ( $contact_form = WPCF7_ContactForm::get_current() ) { + $val = $contact_form->shortcode_attr( $this->name ); + + if ( isset( $val ) and strlen( $val ) ) { + if ( $args['multiple'] ) { + $values[] = $val; + } else { + return $val; + } + } + } + + } elseif ( preg_match( '/^[0-9_]+$/', $opt ) ) { + $nums = explode( '_', $opt ); + + foreach ( $nums as $num ) { + $num = absint( $num ); + $num = $args['shifted'] ? $num : $num - 1; + + if ( isset( $this->values[$num] ) ) { + if ( $args['multiple'] ) { + $values[] = $this->values[$num]; + } else { + return $this->values[$num]; + } + } + } + } + } + + if ( $args['multiple'] ) { + $values = array_unique( $values ); + return $values; + } else { + return $default_value; + } + } + + + /** + * Retrieves the data option value from the form-tag. + * + * @param string|array $args Optional options for the option value retrieval. + * @return mixed The option value. + */ + public function get_data_option( $args = '' ) { + $options = (array) $this->get_option( 'data' ); + + return apply_filters( 'wpcf7_form_tag_data_option', null, $options, $args ); + } + + + /** + * Retrieves the limit option value from the form-tag. + * + * @param int $default_value Optional default value. Default 1048576. + * @return int The option value. + */ + public function get_limit_option( $default_value = MB_IN_BYTES ) { + $pattern = '/^limit:([1-9][0-9]*)([kKmM]?[bB])?$/'; + + $matches = $this->get_first_match_option( $pattern ); + + if ( $matches ) { + $size = (int) $matches[1]; + + if ( ! empty( $matches[2] ) ) { + $kbmb = strtolower( $matches[2] ); + + if ( 'kb' === $kbmb ) { + $size *= KB_IN_BYTES; + } elseif ( 'mb' === $kbmb ) { + $size *= MB_IN_BYTES; + } + } + + return $size; + } + + return (int) $default_value; + } + + + /** + * Retrieves the value of the first option matches the given + * regular expression pattern. + * + * @param string $pattern Regular expression pattern. + * @return array|bool Option value as an array of matched strings. + * False if there is no option matches the pattern. + */ + public function get_first_match_option( $pattern ) { + foreach ( (array) $this->options as $option ) { + if ( preg_match( $pattern, $option, $matches ) ) { + return $matches; + } + } + + return false; + } + + + /** + * Retrieves values of options that match the given + * regular expression pattern. + * + * @param string $pattern Regular expression pattern. + * @return array Array of arrays of strings that match the pattern. + */ + public function get_all_match_options( $pattern ) { + $result = array(); + + foreach ( (array) $this->options as $option ) { + if ( preg_match( $pattern, $option, $matches ) ) { + $result[] = $matches; + } + } + + return $result; + } + + + /** + * Assigns a value to the specified offset. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetset.php + */ + #[ReturnTypeWillChange] + public function offsetSet( $offset, $value ) { + if ( property_exists( __CLASS__, $offset ) ) { + $this->{$offset} = $value; + } + } + + + /** + * Returns the value at specified offset. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetget.php + */ + #[ReturnTypeWillChange] + public function offsetGet( $offset ) { + if ( property_exists( __CLASS__, $offset ) ) { + return $this->{$offset}; + } + + return null; + } + + + /** + * Returns true if the specified offset exists. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetexists.php + */ + #[ReturnTypeWillChange] + public function offsetExists( $offset ) { + return property_exists( __CLASS__, $offset ); + } + + + /** + * Unsets an offset. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetunset.php + */ + #[ReturnTypeWillChange] + public function offsetUnset( $offset ) { + } + +} diff --git a/wp-content/plugins/contact-form-7/includes/form-tags-manager.php b/wp-content/plugins/contact-form-7/includes/form-tags-manager.php new file mode 100644 index 0000000..6088381 --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/form-tags-manager.php @@ -0,0 +1,615 @@ +add( $tag_types, $callback, $features ); +} + + +/** + * Wrapper function of WPCF7_FormTagsManager::remove(). + */ +function wpcf7_remove_form_tag( $tag_type ) { + $manager = WPCF7_FormTagsManager::get_instance(); + + return $manager->remove( $tag_type ); +} + + +/** + * Wrapper function of WPCF7_FormTagsManager::replace_all(). + */ +function wpcf7_replace_all_form_tags( $content ) { + $manager = WPCF7_FormTagsManager::get_instance(); + + return $manager->replace_all( $content ); +} + + +/** + * Wrapper function of WPCF7_ContactForm::scan_form_tags(). + */ +function wpcf7_scan_form_tags( $cond = null ) { + $contact_form = WPCF7_ContactForm::get_current(); + + if ( $contact_form ) { + return $contact_form->scan_form_tags( $cond ); + } + + return array(); +} + + +/** + * Wrapper function of WPCF7_FormTagsManager::tag_type_supports(). + */ +function wpcf7_form_tag_supports( $tag_type, $feature ) { + $manager = WPCF7_FormTagsManager::get_instance(); + + return $manager->tag_type_supports( $tag_type, $feature ); +} + + +/** + * The singleton instance of this class manages the collection of form-tags. + */ +class WPCF7_FormTagsManager { + + private static $instance; + + private $tag_types = array(); + private $scanned_tags = null; // Tags scanned at the last time of scan() + private $placeholders = array(); + + private function __construct() {} + + + /** + * Returns the singleton instance. + * + * @return WPCF7_FormTagsManager The singleton manager. + */ + public static function get_instance() { + if ( empty( self::$instance ) ) { + self::$instance = new self(); + } + + return self::$instance; + } + + + /** + * Returns scanned form-tags. + * + * @return array Array of WPCF7_FormTag objects. + */ + public function get_scanned_tags() { + return $this->scanned_tags; + } + + + /** + * Registers form-tag types to the manager. + * + * @param string|array $tag_types The name of the form-tag type or + * an array of the names. + * @param callable $callback The callback to generates a form control HTML + * for a form-tag in this type. + * @param string|array $features Optional. Features a form-tag + * in this type supports. + */ + public function add( $tag_types, $callback, $features = '' ) { + if ( ! is_callable( $callback ) ) { + return; + } + + if ( true === $features ) { // for back-compat + $features = array( 'name-attr' => true ); + } + + $features = wp_parse_args( $features, array() ); + + $tag_types = array_filter( array_unique( (array) $tag_types ) ); + + foreach ( $tag_types as $tag_type ) { + $tag_type = $this->sanitize_tag_type( $tag_type ); + + if ( ! $this->tag_type_exists( $tag_type ) ) { + $this->tag_types[$tag_type] = array( + 'function' => $callback, + 'features' => $features, + ); + } + } + } + + + /** + * Returns true if the given tag type exists. + */ + public function tag_type_exists( $tag_type ) { + return isset( $this->tag_types[$tag_type] ); + } + + + /** + * Returns true if the tag type supports the features. + * + * @param string $tag_type The name of the form-tag type. + * @param array|string $features The feature to check or an array of features. + * @return bool True if the form-tag type supports at least one of + * the given features, false otherwise. + */ + public function tag_type_supports( $tag_type, $features ) { + $features = array_filter( (array) $features ); + + if ( isset( $this->tag_types[$tag_type]['features'] ) ) { + return (bool) array_intersect( + array_keys( array_filter( $this->tag_types[$tag_type]['features'] ) ), + $features + ); + } + + return false; + } + + + /** + * Returns form-tag types that support the given features. + * + * @param array|string $features Optional. The feature to check or + * an array of features. Default empty array. + * @param bool $invert Optional. If this value is true, returns form-tag + * types that do not support the given features. Default false. + * @return array An array of form-tag types. If the $features param is empty, + * returns all form-tag types that have been registered. + */ + public function collect_tag_types( $features = array(), $invert = false ) { + $tag_types = array_keys( $this->tag_types ); + + if ( empty( $features ) ) { + return $tag_types; + } + + $output = array(); + + foreach ( $tag_types as $tag_type ) { + if ( + ! $invert and $this->tag_type_supports( $tag_type, $features ) or + $invert and ! $this->tag_type_supports( $tag_type, $features ) + ) { + $output[] = $tag_type; + } + } + + return $output; + } + + + /** + * Sanitizes the form-tag type name. + */ + private function sanitize_tag_type( $tag_type ) { + $tag_type = preg_replace( '/[^a-zA-Z0-9_*]+/', '_', $tag_type ); + $tag_type = rtrim( $tag_type, '_' ); + $tag_type = strtolower( $tag_type ); + return $tag_type; + } + + + /** + * Deregisters the form-tag type. + */ + public function remove( $tag_type ) { + unset( $this->tag_types[$tag_type] ); + } + + + /** + * Normalizes the text content that includes form-tags. + */ + public function normalize( $content ) { + if ( empty( $this->tag_types ) ) { + return $content; + } + + $content = preg_replace_callback( + '/' . $this->tag_regex() . '/su', + array( $this, 'normalize_callback' ), + $content + ); + + return $content; + } + + + /** + * The callback function used within normalize(). + */ + private function normalize_callback( $matches ) { + // allow [[foo]] syntax for escaping a tag + if ( '[' === $matches[1] and ']' === $matches[6] ) { + return $matches[0]; + } + + $tag = $matches[2]; + + $attr = trim( preg_replace( '/[\r\n\t ]+/', ' ', $matches[3] ) ); + $attr = strtr( $attr, array( '<' => '<', '>' => '>' ) ); + + $content = trim( $matches[5] ); + $content = str_replace( "\n", '', $content ); + + $result = $matches[1] . '[' . $tag + . ( $attr ? ' ' . $attr : '' ) + . ( $matches[4] ? ' ' . $matches[4] : '' ) + . ']' + . ( $content ? $content . '[/' . $tag . ']' : '' ) + . $matches[6]; + + return $result; + } + + + /** + * Replace all form-tags in the given text with placeholders. + */ + public function replace_with_placeholders( $content ) { + if ( empty( $this->tag_types ) ) { + return $content; + } + + $this->placeholders = array(); + + $callback = function ( $matches ) { + // Allow [[foo]] syntax for escaping a tag. + if ( '[' === $matches[1] and ']' === $matches[6] ) { + return $matches[0]; + } + + $tag = $matches[0]; + $tag_type = $matches[2]; + + $block_or_hidden = $this->tag_type_supports( + $tag_type, + array( 'display-block', 'display-hidden' ) + ); + + if ( $block_or_hidden ) { + $placeholder_tag_name = WPCF7_HTMLFormatter::placeholder_block; + } else { + $placeholder_tag_name = WPCF7_HTMLFormatter::placeholder_inline; + } + + $placeholder = sprintf( + '<%1$s id="%2$s" />', + $placeholder_tag_name, + hash( 'sha256', $tag ) + ); + + list( $placeholder ) = + WPCF7_HTMLFormatter::normalize_start_tag( $placeholder ); + + $this->placeholders[$placeholder] = $tag; + + return $placeholder; + }; + + return preg_replace_callback( + '/' . $this->tag_regex() . '/su', + $callback, + $content + ); + } + + + /** + * Replace placeholders in the given text with original form-tags. + */ + public function restore_from_placeholders( $content ) { + return str_replace( + array_keys( $this->placeholders ), + array_values( $this->placeholders ), + $content + ); + } + + + /** + * Replaces all form-tags in the text content. + * + * @param string $content The text content including form-tags. + * @return string The result of replacements. + */ + public function replace_all( $content ) { + return $this->scan( $content, true ); + } + + + /** + * Scans form-tags in the text content. + * + * @param string $content The text content including form-tags. + * @param bool $replace Optional. Whether scanned form-tags will be + * replaced. Default false. + * @return array|string An array of scanned form-tags if $replace is false. + * Otherwise text that scanned form-tags are replaced. + */ + public function scan( $content, $replace = false ) { + $this->scanned_tags = array(); + + if ( empty( $this->tag_types ) ) { + if ( $replace ) { + return $content; + } else { + return $this->scanned_tags; + } + } + + if ( $replace ) { + $content = preg_replace_callback( + '/' . $this->tag_regex() . '/su', + array( $this, 'replace_callback' ), + $content + ); + + return $content; + } else { + preg_replace_callback( + '/' . $this->tag_regex() . '/su', + array( $this, 'scan_callback' ), + $content + ); + + return $this->scanned_tags; + } + } + + + /** + * Filters form-tags based on a condition array argument. + * + * @param array|string $input The original form-tags collection. + * If it is a string, scans form-tags from it. + * @param array $cond The conditions that filtering will be based on. + * @return array The filtered form-tags collection. + */ + public function filter( $input, $cond ) { + if ( is_array( $input ) ) { + $tags = $input; + } elseif ( is_string( $input ) ) { + $tags = $this->scan( $input ); + } else { + $tags = $this->scanned_tags; + } + + $cond = wp_parse_args( $cond, array( + 'type' => array(), + 'basetype' => array(), + 'name' => array(), + 'feature' => array(), + ) ); + + $cond = array_map( static function ( $c ) { + return array_filter( array_map( 'trim', (array) $c ) ); + }, $cond ); + + $tags = array_filter( + (array) $tags, + function ( $tag ) use ( $cond ) { + $tag = new WPCF7_FormTag( $tag ); + + if ( + $cond['type'] and + ! in_array( $tag->type, $cond['type'], true ) + ) { + return false; + } + + if ( + $cond['basetype'] and + ! in_array( $tag->basetype, $cond['basetype'], true ) + ) { + return false; + } + + if ( + $cond['name'] and + ! in_array( $tag->name, $cond['name'], true ) + ) { + return false; + } + + foreach ( $cond['feature'] as $feature ) { + if ( str_starts_with( $feature, '!' ) ) { // Negation + $feature = trim( substr( $feature, 1 ) ); + + if ( $this->tag_type_supports( $tag->type, $feature ) ) { + return false; + } + } else { + if ( ! $this->tag_type_supports( $tag->type, $feature ) ) { + return false; + } + } + } + + return true; + } + ); + + return array_values( $tags ); + } + + + /** + * Returns the regular expression for a form-tag. + */ + private function tag_regex() { + $tag_types = implode( '|', + array_map( 'preg_quote', array_keys( $this->tag_types ) ) + ); + + $whitespaces = wpcf7_get_unicode_whitespaces(); + + return '(\[?)' + . '\[(' . $tag_types . ')' + . '(?:[' . $whitespaces . ']+(.*?))?' + . '(?:[' . $whitespaces . ']+(\/))?\]' + . '(?:([^[]*?)\[\/\2\])?' + . '(\]?)'; + } + + + /** + * The callback function for the form-tag replacement. + */ + private function replace_callback( $matches ) { + return $this->scan_callback( $matches, true ); + } + + + /** + * The callback function for the form-tag scanning. + */ + private function scan_callback( $matches, $replace = false ) { + // allow [[foo]] syntax for escaping a tag + if ( '[' === $matches[1] and ']' === $matches[6] ) { + return substr( $matches[0], 1, -1 ); + } + + $tag_type = $matches[2]; + $tag_basetype = trim( $tag_type, '*' ); + $attr = $this->parse_atts( $matches[3] ); + + $scanned_tag = array( + 'type' => $tag_type, + 'basetype' => $tag_basetype, + 'raw_name' => '', + 'name' => '', + 'options' => array(), + 'raw_values' => array(), + 'values' => array(), + 'pipes' => null, + 'labels' => array(), + 'attr' => '', + 'content' => '', + ); + + if ( $this->tag_type_supports( $tag_type, 'singular' ) ) { + $tags_in_same_basetype = $this->filter( + $this->scanned_tags, + array( 'basetype' => $tag_basetype ) + ); + + if ( $tags_in_same_basetype ) { + // Another tag in the same base type already exists. Ignore this one. + return $matches[0]; + } + } + + if ( $this->tag_type_supports( $tag_type, 'name-attr' ) ) { + if ( ! is_array( $attr ) ) { + return $matches[0]; // Invalid form-tag. + } + + $scanned_tag['raw_name'] = (string) array_shift( $attr['options'] ); + + if ( ! wpcf7_is_name( $scanned_tag['raw_name'] ) ) { + return $matches[0]; // Invalid name is used. Ignore this tag. + } + + $scanned_tag['name'] = strtr( $scanned_tag['raw_name'], '.', '_' ); + } + + if ( is_array( $attr ) ) { + $scanned_tag['options'] = (array) $attr['options']; + $scanned_tag['raw_values'] = (array) $attr['values']; + + if ( WPCF7_USE_PIPE ) { + $pipes = new WPCF7_Pipes( $scanned_tag['raw_values'] ); + $scanned_tag['values'] = $pipes->collect_befores(); + $scanned_tag['pipes'] = $pipes; + } else { + $scanned_tag['values'] = $scanned_tag['raw_values']; + } + + $scanned_tag['labels'] = $scanned_tag['values']; + + } else { + $scanned_tag['attr'] = $attr; + } + + $scanned_tag['values'] = array_map( 'trim', $scanned_tag['values'] ); + $scanned_tag['labels'] = array_map( 'trim', $scanned_tag['labels'] ); + + $content = trim( $matches[5] ); + $content = preg_replace( "/$/m", '', $content ); + $scanned_tag['content'] = $content; + + $scanned_tag = apply_filters( 'wpcf7_form_tag', $scanned_tag, $replace ); + + $scanned_tag = new WPCF7_FormTag( $scanned_tag ); + + $this->scanned_tags[] = $scanned_tag; + + if ( $replace ) { + $callback = $this->tag_types[$tag_type]['function']; + return $matches[1] . call_user_func( $callback, $scanned_tag ) . $matches[6]; + } else { + return $matches[0]; + } + } + + + /** + * Parses the attributes of a form-tag to extract the name, + * options, and values. + * + * @param string $text Attributes of a form-tag. + * @return array|string An associative array of the options and values + * if the input is in the correct syntax, + * otherwise the input text itself. + */ + private function parse_atts( $text ) { + $atts = array( + 'options' => array(), + 'values' => array(), + ); + + $whitespaces = wpcf7_get_unicode_whitespaces(); + + $text = preg_replace( '/[\x{00a0}\x{200b}]+/u', ' ', $text ); + $text = wpcf7_strip_whitespaces( $text ); + + $pattern = '%^([-+*=0-9a-zA-Z:.!?#$&@_/|\%' . $whitespaces . ']*?)' + . '((?:' + . '[' . $whitespaces . ']*"[^"]*"' + . '|' + . '[' . $whitespaces . ']*\'[^\']*\'' + . ')*)$%u'; + + if ( preg_match( $pattern, $text, $matches ) ) { + if ( ! empty( $matches[1] ) ) { + $atts['options'] = preg_split( + sprintf( '/[%s]+/u', $whitespaces ), + wpcf7_strip_whitespaces( $matches[1] ) + ); + } + + if ( ! empty( $matches[2] ) ) { + preg_match_all( '/"[^"]*"|\'[^\']*\'/', $matches[2], $matched_values ); + $atts['values'] = wpcf7_strip_quote_deep( $matched_values[0] ); + } + } else { + $atts = $text; + } + + return $atts; + } + +} diff --git a/wp-content/plugins/contact-form-7/includes/formatting.php b/wp-content/plugins/contact-form-7/includes/formatting.php new file mode 100644 index 0000000..37210db --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/formatting.php @@ -0,0 +1,653 @@ +/is', + static function ( $matches ) use ( &$placeholders ) { + $placeholder = sprintf( + '<%1$s id="%2$s" />', + WPCF7_HTMLFormatter::placeholder_inline, + hash( 'sha256', $matches[0] ) + ); + + list( $placeholder ) = + WPCF7_HTMLFormatter::normalize_start_tag( $placeholder ); + + $placeholders[$placeholder] = $matches[0]; + + return $placeholder; + }, + $input + ); + + $formatter = new WPCF7_HTMLFormatter( array( + 'auto_br' => $br, + 'allowed_html' => null, + ) ); + + $chunks = $formatter->separate_into_chunks( $input ); + + $output = $formatter->format( $chunks ); + + // Restore from placeholders. + $output = str_replace( + array_keys( $placeholders ), + array_values( $placeholders ), + $output + ); + + return $output; +} + + +/** + * Newline preservation help function for wpcf7_autop(). + * + * @deprecated 5.7 Unnecessary to use any more. + * + * @param array $matches preg_replace_callback() matches array. + * @return string Text including newline placeholders. + */ +function wpcf7_autop_preserve_newline_callback( $matches ) { + return str_replace( "\n", '', $matches[0] ); +} + + +/** + * Sanitizes the query variables. + * + * @param string $text Query variable. + * @return string Text sanitized. + */ +function wpcf7_sanitize_query_var( $text ) { + $text = wp_unslash( $text ); + $text = wp_check_invalid_utf8( $text ); + + if ( false !== strpos( $text, '<' ) ) { + $text = wp_pre_kses_less_than( $text ); + $text = wp_strip_all_tags( $text ); + } + + $text = preg_replace( '/%[a-f0-9]{2}/i', '', $text ); + $text = preg_replace( '/ +/', ' ', $text ); + $text = trim( $text, ' ' ); + + return $text; +} + + +/** + * Strips quote characters surrounding the input. + * + * @param string $text Input text. + * @return string Processed output. + */ +function wpcf7_strip_quote( $text ) { + $text = wpcf7_strip_whitespaces( $text ); + + if ( preg_match( '/^"(.*)"$/s', $text, $matches ) ) { + $text = $matches[1]; + } elseif ( preg_match( "/^'(.*)'$/s", $text, $matches ) ) { + $text = $matches[1]; + } + + return $text; +} + + +/** + * Navigates through an array, object, or scalar, and + * strips quote characters surrounding the each value. + * + * @param mixed $input The array or string to be processed. + * @return mixed Processed value. + */ +function wpcf7_strip_quote_deep( $input ) { + if ( is_string( $input ) ) { + return wpcf7_strip_quote( $input ); + } + + if ( is_array( $input ) ) { + $result = array(); + + foreach ( $input as $key => $text ) { + $result[$key] = wpcf7_strip_quote_deep( $text ); + } + + return $result; + } +} + + +/** + * Normalizes newline characters. + * + * @param string $text Input text. + * @param string $to Optional. The newline character that is used in the output. + * @return string Normalized text. + */ +function wpcf7_normalize_newline( $text, $to = "\n" ) { + if ( ! is_string( $text ) ) { + return $text; + } + + $nls = array( "\r\n", "\r", "\n" ); + + if ( ! in_array( $to, $nls, true ) ) { + return $text; + } + + return str_replace( $nls, $to, $text ); +} + + +/** + * Navigates through an array, object, or scalar, and + * normalizes newline characters in the each value. + * + * @param mixed $input The array or string to be processed. + * @param string $to Optional. The newline character that is used in the output. + * @return mixed Processed value. + */ +function wpcf7_normalize_newline_deep( $input, $to = "\n" ) { + if ( is_array( $input ) ) { + $result = array(); + + foreach ( $input as $key => $text ) { + $result[$key] = wpcf7_normalize_newline_deep( $text, $to ); + } + + return $result; + } + + return wpcf7_normalize_newline( $input, $to ); +} + + +/** + * Strips newline characters. + * + * @param string $text Input text. + * @return string Processed one-line text. + */ +function wpcf7_strip_newline( $text ) { + $text = (string) $text; + $text = str_replace( array( "\r", "\n" ), '', $text ); + return wpcf7_strip_whitespaces( $text ); +} + + +/** + * Canonicalizes text. + * + * @param string $text Input text. + * @param string|array|object $options Options. + * @return string Canonicalized text. + */ +function wpcf7_canonicalize( $text, $options = '' ) { + // for back-compat + if ( + is_string( $options ) and + '' !== $options and + ! str_contains( $options, '=' ) + ) { + $options = array( + 'strto' => $options, + ); + } + + $options = wp_parse_args( $options, array( + 'strto' => 'lower', + 'strip_separators' => false, + ) ); + + static $charset = null; + + if ( ! isset( $charset ) ) { + $charset = get_option( 'blog_charset' ); + + $is_utf8 = in_array( + $charset, + array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ), + true + ); + + if ( $is_utf8 ) { + $charset = 'UTF-8'; + } + } + + $text = html_entity_decode( $text, ENT_QUOTES | ENT_HTML5, $charset ); + + if ( function_exists( 'mb_convert_kana' ) ) { + $text = mb_convert_kana( $text, 'asKV', $charset ); + } + + if ( $options['strip_separators'] ) { + $text = preg_replace( '/[\r\n\t ]+/', '', $text ); + } else { + $text = preg_replace( '/[\r\n\t ]+/', ' ', $text ); + } + + if ( 'lower' === $options['strto'] ) { + if ( function_exists( 'mb_strtolower' ) ) { + $text = mb_strtolower( $text, $charset ); + } else { + $text = strtolower( $text ); + } + } elseif ( 'upper' === $options['strto'] ) { + if ( function_exists( 'mb_strtoupper' ) ) { + $text = mb_strtoupper( $text, $charset ); + } else { + $text = strtoupper( $text ); + } + } + + return wpcf7_strip_whitespaces( $text ); +} + + +/** + * Returns a canonical keyword usable for a name or an ID purposes. + */ +function wpcf7_canonicalize_name( $text ) { + return preg_replace( '/[^0-9a-z]+/i', '-', $text ); +} + + +/** + * Sanitizes Contact Form 7's form unit-tag. + * + * @param string $tag Unit-tag. + * @return string Sanitized unit-tag. + */ +function wpcf7_sanitize_unit_tag( $tag ) { + $tag = preg_replace( '/[^A-Za-z0-9_-]/', '', (string) $tag ); + return $tag; +} + + +/** + * Converts a file name to one that is not executable as a script. + * + * @param string $filename File name. + * @return string Converted file name. + */ +function wpcf7_antiscript_file_name( $filename ) { + $filename = wp_basename( $filename ); + + // Apply part of protection logic from sanitize_file_name(). + $filename = str_replace( + array( + '?', '[', ']', '/', '\\', '=', '<', '>', ':', ';', ',', "'", '"', + '&', '$', '#', '*', '(', ')', '|', '~', '`', '!', '{', '}', + '%', '+', '’', '«', '»', '”', '“', chr( 0 ) + ), + '', + $filename + ); + + $filename = preg_replace( '/[\r\n\t -]+/', '-', $filename ); + $filename = preg_replace( '/[\pC\pZ]+/iu', '', $filename ); + + $parts = explode( '.', $filename ); + + if ( count( $parts ) < 2 ) { + return $filename; + } + + $script_pattern = '/^(php|phtml|pl|py|rb|cgi|asp|aspx)\d?$/i'; + + $filename = array_shift( $parts ); + $extension = array_pop( $parts ); + + foreach ( $parts as $part ) { + if ( preg_match( $script_pattern, $part ) ) { + $filename .= '.' . $part . '_'; + } else { + $filename .= '.' . $part; + } + } + + if ( preg_match( $script_pattern, $extension ) ) { + $filename .= '.' . $extension . '_.txt'; + } else { + $filename .= '.' . $extension; + } + + return $filename; +} + + +/** + * Masks a password with asterisks (*). + * + * @param int $right Length of right-hand unmasked text. Default 0. + * @param int $left Length of left-hand unmasked text. Default 0. + * @return string Text of masked password. + */ +function wpcf7_mask_password( $text, $right = 0, $left = 0 ) { + $length = strlen( $text ); + + $right = absint( $right ); + $left = absint( $left ); + + if ( $length < $right + $left ) { + $right = $left = 0; + } + + if ( $length <= 48 ) { + $masked = str_repeat( '*', $length - ( $right + $left ) ); + } elseif ( $right + $left < 48 ) { + $masked = str_repeat( '*', 48 - ( $right + $left ) ); + } else { + $masked = '****'; + } + + $left_unmasked = $left ? substr( $text, 0, $left ) : ''; + $right_unmasked = $right ? substr( $text, -1 * $right ) : ''; + + $text = $left_unmasked . $masked . $right_unmasked; + + return $text; +} + + +/** + * Returns an array of allowed HTML tags and attributes for a given context. + * + * @param string $context Context used to decide allowed tags and attributes. + * @return array Array of allowed HTML tags and their allowed attributes. + */ +function wpcf7_kses_allowed_html( $context = 'form' ) { + static $allowed_tags = array(); + + if ( isset( $allowed_tags[$context] ) ) { + return apply_filters( + 'wpcf7_kses_allowed_html', + $allowed_tags[$context], + $context + ); + } + + $allowed_tags[$context] = wp_kses_allowed_html( 'post' ); + + if ( 'form' === $context ) { + $additional_tags_for_form = array( + 'button' => array( + 'disabled' => true, + 'name' => true, + 'type' => true, + 'value' => true, + ), + 'datalist' => array(), + 'fieldset' => array( + 'disabled' => true, + 'name' => true, + ), + 'input' => array( + 'accept' => true, + 'alt' => true, + 'autocomplete' => true, + 'capture' => true, + 'checked' => true, + 'disabled' => true, + 'list' => true, + 'max' => true, + 'maxlength' => true, + 'min' => true, + 'minlength' => true, + 'multiple' => true, + 'name' => true, + 'pattern' => true, + 'placeholder' => true, + 'readonly' => true, + 'required' => true, + 'size' => true, + 'step' => true, + 'type' => true, + 'value' => true, + ), + 'label' => array( + 'for' => true, + ), + 'legend' => array(), + 'meter' => array( + 'value' => true, + 'min' => true, + 'max' => true, + 'low' => true, + 'high' => true, + 'optimum' => true, + ), + 'optgroup' => array( + 'disabled' => true, + 'label' => true, + ), + 'option' => array( + 'disabled' => true, + 'label' => true, + 'selected' => true, + 'value' => true, + ), + 'output' => array( + 'for' => true, + 'name' => true, + ), + 'progress' => array( + 'max' => true, + 'value' => true, + ), + 'select' => array( + 'autocomplete' => true, + 'disabled' => true, + 'multiple' => true, + 'name' => true, + 'required' => true, + 'size' => true, + ), + 'textarea' => array( + 'autocomplete' => true, + 'cols' => true, + 'disabled' => true, + 'maxlength' => true, + 'minlength' => true, + 'name' => true, + 'placeholder' => true, + 'readonly' => true, + 'required' => true, + 'rows' => true, + 'wrap' => true, + ), + ); + + $allowed_tags[$context] = array_merge( + $allowed_tags[$context], + $additional_tags_for_form + ); + + $allowed_tags[$context] = array_map( + static function ( $elm ) { + $global_attributes = array( + 'aria-atomic' => true, + 'aria-checked' => true, + 'aria-controls' => true, + 'aria-current' => true, + 'aria-describedby' => true, + 'aria-details' => true, + 'aria-disabled' => true, + 'aria-expanded' => true, + 'aria-hidden' => true, + 'aria-invalid' => true, + 'aria-label' => true, + 'aria-labelledby' => true, + 'aria-live' => true, + 'aria-relevant' => true, + 'aria-required' => true, + 'aria-selected' => true, + 'class' => true, + 'data-*' => true, + 'dir' => true, + 'hidden' => true, + 'id' => true, + 'inputmode' => true, + 'lang' => true, + 'role' => true, + 'spellcheck' => true, + 'style' => true, + 'tabindex' => true, + 'title' => true, + 'xml:lang' => true, + ); + + return array_merge( $global_attributes, (array) $elm ); + }, + $allowed_tags[$context] + ); + } + + return apply_filters( + 'wpcf7_kses_allowed_html', + $allowed_tags[$context], + $context + ); +} + + +/** + * Sanitizes content for allowed HTML tags for the specified context. + * + * @param string $input Content to filter. + * @param string $context Context used to decide allowed tags and attributes. + * @return string Filtered text with allowed HTML tags and attributes intact. + */ +function wpcf7_kses( $input, $context = 'form' ) { + $output = wp_kses( + $input, + wpcf7_kses_allowed_html( $context ) + ); + + return $output; +} + + +/** + * Returns a formatted string of HTML attributes. + * + * @param array $atts Associative array of attribute name and value pairs. + * @return string Formatted HTML attributes. + */ +function wpcf7_format_atts( $atts ) { + $atts_filtered = array(); + + foreach ( $atts as $name => $value ) { + $name = strtolower( trim( $name ) ); + + if ( ! preg_match( '/^[a-z_:][a-z_:.0-9-]*$/', $name ) ) { + continue; + } + + static $boolean_attributes = array( + 'checked', + 'disabled', + 'inert', + 'multiple', + 'readonly', + 'required', + 'selected', + ); + + if ( in_array( $name, $boolean_attributes, true ) and '' === $value ) { + $value = false; + } + + if ( is_numeric( $value ) ) { + $value = (string) $value; + } + + if ( null === $value or false === $value ) { + unset( $atts_filtered[$name] ); + } elseif ( true === $value ) { + $atts_filtered[$name] = $name; // boolean attribute + } elseif ( is_string( $value ) ) { + $atts_filtered[$name] = trim( $value ); + } + } + + $output = ''; + + foreach ( $atts_filtered as $name => $value ) { + $output .= sprintf( ' %1$s="%2$s"', $name, esc_attr( $value ) ); + } + + return trim( $output ); +} + + +/** + * Returns the regular expression pattern that represents + * whitespace characters Unicode defines. + * + * @link https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt + * + * @return string Regular expression pattern. + */ +function wpcf7_get_unicode_whitespaces() { + return '\x09-\x0D\x20\x85\xA0\x{1680}\x{2000}-\x{200A}\x{2028}\x{2029}\x{202F}\x{205F}\x{3000}'; +} + + +/** + * Strips surrounding whitespaces. + * + * @link https://contactform7.com/2024/07/13/consistent-handling-policy-of-surrounding-whitespaces/ + * + * @param string|array $input Input text. + * @param string $side The side from which whitespaces are stripped. + * 'start', 'end', or 'both' (default). + * @return string|array Output text. + */ +function wpcf7_strip_whitespaces( $input, $side = 'both' ) { + if ( is_array( $input ) ) { + return array_map( + static function ( $i ) use ( $side ) { + return wpcf7_strip_whitespaces( $i, $side ); + }, + $input + ); + } + + // https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html + $whitespaces = wpcf7_get_unicode_whitespaces() . '\x{FEFF}'; + + if ( 'end' !== $side ) { + // Strip leading whitespaces + $input = preg_replace( + sprintf( '/^[%s]+/u', $whitespaces ), + '', + $input + ); + } + + if ( 'start' !== $side ) { + // Strip trailing whitespaces + $input = preg_replace( + sprintf( '/[%s]+$/u', $whitespaces ), + '', + $input + ); + } + + return $input; +} diff --git a/wp-content/plugins/contact-form-7/includes/functions.php b/wp-content/plugins/contact-form-7/includes/functions.php new file mode 100644 index 0000000..2ce51cf --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/functions.php @@ -0,0 +1,749 @@ + $uploads['basedir'], + 'url' => $uploads['baseurl'], + ) ); + + if ( 'dir' === $type ) { + return $uploads['dir']; + } if ( 'url' === $type ) { + return $uploads['url']; + } + + return $uploads; +} + + +/** + * Verifies that a correct security nonce was used with time limit. + * + * @param string $nonce Nonce value that was used for verification. + * @param string $action Optional. Context to what is taking place. + * Default 'wp_rest'. + * @return int|bool 1 if the nonce is generated between 0-12 hours ago, + * 2 if the nonce is generated between 12-24 hours ago. + * False if the nonce is invalid. + */ +function wpcf7_verify_nonce( $nonce, $action = 'wp_rest' ) { + return wp_verify_nonce( $nonce, $action ); +} + + +/** + * Creates a cryptographic token tied to a specific action, user, user session, + * and window of time. + * + * @param string $action Optional. Context to what is taking place. + * Default 'wp_rest'. + * @return string The token. + */ +function wpcf7_create_nonce( $action = 'wp_rest' ) { + return wp_create_nonce( $action ); +} + + +/** + * Converts multi-dimensional array to a flat array. + * + * @param mixed $input Array or item of array. + * @return array Flatten array. + */ +function wpcf7_array_flatten( $input ) { + if ( ! is_array( $input ) ) { + return array( $input ); + } + + $output = array(); + + foreach ( $input as $value ) { + $output = array_merge( $output, wpcf7_array_flatten( $value ) ); + } + + return $output; +} + + +/** + * Excludes unset or blank text values from the given array. + * + * @param array $input The array. + * @return array Array without blank text values. + */ +function wpcf7_exclude_blank( $input ) { + $output = array_filter( $input, + static function ( $i ) { + return isset( $i ) && '' !== $i; + } + ); + + return array_values( $output ); +} + + +/** + * Creates a comma-separated list from a multi-dimensional array. + * + * @param mixed $input Array or item of array. + * @param string|array $options Optional. Output options. + * @return string Comma-separated list. + */ +function wpcf7_flat_join( $input, $options = '' ) { + $options = wp_parse_args( $options, array( + 'separator' => ', ', + ) ); + + $input = wpcf7_array_flatten( $input ); + $output = array(); + + foreach ( $input as $value ) { + if ( is_scalar( $value ) ) { + $output[] = trim( (string) $value ); + } + } + + return implode( $options['separator'], $output ); +} + + +/** + * Returns true if HTML5 is supported. + */ +function wpcf7_support_html5() { + return (bool) wpcf7_apply_filters_deprecated( + 'wpcf7_support_html5', + array( true ), + '5.6', + '' + ); +} + + +/** + * Returns true if HTML5 fallback is active. + */ +function wpcf7_support_html5_fallback() { + return (bool) apply_filters( 'wpcf7_support_html5_fallback', false ); +} + + +/** + * Returns true if the Really Simple CAPTCHA plugin is used for contact forms. + */ +function wpcf7_use_really_simple_captcha() { + return apply_filters( 'wpcf7_use_really_simple_captcha', + WPCF7_USE_REALLY_SIMPLE_CAPTCHA + ); +} + + +/** + * Returns true if config validation is active. + */ +function wpcf7_validate_configuration() { + return apply_filters( 'wpcf7_validate_configuration', + WPCF7_VALIDATE_CONFIGURATION + ); +} + + +/** + * Returns true if wpcf7_autop() is applied. + */ +function wpcf7_autop_or_not( $options = '' ) { + $options = wp_parse_args( $options, array( + 'for' => 'form', + ) ); + + return (bool) apply_filters( 'wpcf7_autop_or_not', WPCF7_AUTOP, $options ); +} + + +/** + * Returns true if JavaScript for this plugin is loaded. + */ +function wpcf7_load_js() { + return apply_filters( 'wpcf7_load_js', WPCF7_LOAD_JS ); +} + + +/** + * Returns true if CSS for this plugin is loaded. + */ +function wpcf7_load_css() { + return apply_filters( 'wpcf7_load_css', WPCF7_LOAD_CSS ); +} + + +/** + * Builds an HTML anchor element. + * + * @param string $url Link URL. + * @param string $anchor_text Anchor label text. + * @param string|array $atts Optional. HTML attributes. + * @return string Formatted anchor element. + */ +function wpcf7_link( $url, $anchor_text, $atts = '' ) { + $atts = wp_parse_args( $atts, array( + 'id' => null, + 'class' => null, + ) ); + + $atts = array_merge( $atts, array( + 'href' => esc_url( $url ), + ) ); + + return sprintf( + '%2$s', + wpcf7_format_atts( $atts ), + esc_html( $anchor_text ) + ); +} + + +/** + * Returns the current request URL. + */ +function wpcf7_get_request_uri() { + static $request_uri = ''; + + if ( empty( $request_uri ) ) { + $request_uri = add_query_arg( array() ); + $request_uri = '/' . ltrim( $request_uri, '/' ); + } + + return sanitize_url( $request_uri ); +} + + +/** + * Registers post types used for this plugin. + */ +function wpcf7_register_post_types() { + if ( class_exists( 'WPCF7_ContactForm' ) ) { + WPCF7_ContactForm::register_post_type(); + return true; + } else { + return false; + } +} + + +/** + * Returns the version string of this plugin. + * + * @param string|array $options Optional. Output options. + * @return string Version string. + */ +function wpcf7_version( $options = '' ) { + $options = wp_parse_args( $options, array( + 'limit' => -1, + 'only_major' => false, + ) ); + + if ( $options['only_major'] ) { + $options['limit'] = 2; + } + + $options['limit'] = (int) $options['limit']; + + $ver = WPCF7_VERSION; + $ver = strtr( $ver, '_-+', '...' ); + $ver = preg_replace( '/[^0-9.]+/', '.$0.', $ver ); + $ver = preg_replace( '/[.]+/', '.', $ver ); + $ver = trim( $ver, '.' ); + $ver = explode( '.', $ver ); + + if ( -1 < $options['limit'] ) { + $ver = array_slice( $ver, 0, $options['limit'] ); + } + + $ver = implode( '.', $ver ); + + return $ver; +} + + +/** + * Returns array entries that match the given version. + * + * @param string $version The version to search for. + * @param array $input Search target array. + * @return array|bool Array of matched entries. False on failure. + */ +function wpcf7_version_grep( $version, array $input ) { + $pattern = '/^' . preg_quote( (string) $version, '/' ) . '(?:\.|$)/'; + + return preg_grep( $pattern, $input ); +} + + +/** + * Returns an enctype attribute value. + * + * @param string $enctype Enctype value. + * @return string Enctype value. Empty if not a valid enctype. + */ +function wpcf7_enctype_value( $enctype ) { + $enctype = trim( $enctype ); + + if ( empty( $enctype ) ) { + return ''; + } + + $valid_enctypes = array( + 'application/x-www-form-urlencoded', + 'multipart/form-data', + 'text/plain', + ); + + if ( in_array( $enctype, $valid_enctypes, true ) ) { + return $enctype; + } + + $pattern = '%^enctype="(' . implode( '|', $valid_enctypes ) . ')"$%'; + + if ( preg_match( $pattern, $enctype, $matches ) ) { + return $matches[1]; // for back-compat + } + + return ''; +} + + +/** + * Removes directory recursively. + * + * @param string $dir Directory path. + * @return bool True on success, false on failure. + */ +function wpcf7_rmdir_p( $dir ) { + $filesystem = WPCF7_Filesystem::get_instance(); + + return $filesystem->delete( $dir, true ); +} + + +/** + * Builds a URL-encoded query string. + * + * @link https://developer.wordpress.org/reference/functions/_http_build_query/ + * + * @param array $data URL query parameters. + * @param string $key Optional. If specified, used to prefix key name. + * @return string Query string. + */ +function wpcf7_build_query( $data, $key = '' ) { + $sep = '&'; + $ret = array(); + + foreach ( (array) $data as $k => $v ) { + $k = urlencode( $k ); + + if ( ! empty( $key ) ) { + $k = $key . '%5B' . $k . '%5D'; + } + + if ( null === $v ) { + continue; + } elseif ( false === $v ) { + $v = '0'; + } + + if ( is_array( $v ) or is_object( $v ) ) { + array_push( $ret, wpcf7_build_query( $v, $k ) ); + } else { + array_push( $ret, $k . '=' . urlencode( $v ) ); + } + } + + return implode( $sep, $ret ); +} + + +/** + * Returns the number of code units in a string. + * + * @link http://www.w3.org/TR/html5/infrastructure.html#code-unit-length + * + * @param string $text Input string. + * @return int|false The number of code units, or false if + * mb_convert_encoding is not available. + */ +function wpcf7_count_code_units( $text ) { + static $use_mb = null; + + if ( is_null( $use_mb ) ) { + $use_mb = function_exists( 'mb_convert_encoding' ); + } + + if ( ! $use_mb ) { + return false; + } + + $text = (string) $text; + + if ( '' === $text ) { + return 0; + } + + $text = str_replace( "\r\n", "\n", $text ); + + $text = mb_convert_encoding( + $text, + 'UTF-16', + mb_detect_encoding( $text, mb_detect_order(), true ) ?: 'UTF-8' + ); + + return intdiv( mb_strlen( $text, '8bit' ), 2 ); +} + + +/** + * Returns true if WordPress is running on the localhost. + */ +function wpcf7_is_localhost() { + $sitename = wp_parse_url( network_home_url(), PHP_URL_HOST ); + + return in_array( + strtolower( $sitename ), + array( 'localhost', '127.0.0.1' ), + true + ); +} + + +/** + * Marks a function as deprecated and informs when it has been used. + * + * @param string $function_name The function that was called. + * @param string $version The version of Contact Form 7 that deprecated + * the function. + * @param string $replacement The function that should have been called. + */ +function wpcf7_deprecated_function( $function_name, $version, $replacement ) { + + if ( ! WP_DEBUG ) { + return; + } + + if ( function_exists( '__' ) ) { + /* translators: 1: PHP function name, 2: version number, 3: alternative function name */ + $message = __( 'Function %1$s is deprecated since Contact Form 7 version %2$s! Use %3$s instead.', 'contact-form-7' ); + } else { + $message = 'Function %1$s is deprecated since Contact Form 7 version %2$s! Use %3$s instead.'; + } + + $message = sprintf( $message, $function_name, $version, $replacement ); + + wp_trigger_error( '', $message, E_USER_DEPRECATED ); +} + + +/** + * Fires functions attached to a deprecated filter hook. + * + * @param string $hook_name The name of the filter hook. + * @param array $args Array of additional function arguments to be + * passed to apply_filters(). + * @param string $version The version of Contact Form 7 that deprecated + * the hook. + * @param string $replacement The hook that should have been used. + */ +function wpcf7_apply_filters_deprecated( $hook_name, $args, $version, $replacement = '' ) { + if ( ! has_filter( $hook_name ) ) { + return $args[0]; + } + + if ( WP_DEBUG and apply_filters( 'deprecated_hook_trigger_error', true ) ) { + if ( $replacement ) { + wp_trigger_error( + '', + sprintf( + /* translators: 1: WordPress hook name, 2: version number, 3: alternative hook name */ + __( 'Hook %1$s is deprecated since Contact Form 7 version %2$s! Use %3$s instead.', 'contact-form-7' ), + $hook_name, + $version, + $replacement + ), + E_USER_DEPRECATED + ); + } else { + wp_trigger_error( + '', + sprintf( + /* translators: 1: WordPress hook name, 2: version number */ + __( 'Hook %1$s is deprecated since Contact Form 7 version %2$s with no alternative available.', 'contact-form-7' ), + $hook_name, + $version + ), + E_USER_DEPRECATED + ); + } + } + + return apply_filters_ref_array( $hook_name, $args ); +} + + +/** + * Marks something as being incorrectly called. + * + * @param string $function_name The function that was called. + * @param string $message A message explaining what has been done incorrectly. + * @param string $version The version of Contact Form 7 where the message + * was added. + */ +function wpcf7_doing_it_wrong( $function_name, $message, $version ) { + + if ( ! WP_DEBUG ) { + return; + } + + if ( function_exists( '__' ) ) { + if ( $version ) { + $version = sprintf( + /* translators: %s: Contact Form 7 version number. */ + __( '(This message was added in Contact Form 7 version %s.)', 'contact-form-7' ), + $version + ); + } + + wp_trigger_error( + '', + sprintf( + /* translators: Developer debugging message. 1: PHP function name, 2: Explanatory message, 3: Contact Form 7 version number. */ + __( 'Function %1$s was called incorrectly. %2$s %3$s', 'contact-form-7' ), + $function_name, + $message, + $version + ), + E_USER_NOTICE + ); + } else { + if ( $version ) { + $version = sprintf( + '(This message was added in Contact Form 7 version %s.)', + $version + ); + } + + wp_trigger_error( + '', + sprintf( + 'Function %1$s was called incorrectly. %2$s %3$s', + $function_name, + $message, + $version + ), + E_USER_NOTICE + ); + } +} + + +/** + * Triggers an error about a remote HTTP request and response. + * + * @param string $url The resource URL. + * @param array $request Request arguments. + * @param array|WP_Error $response The response or WP_Error on failure. + */ +function wpcf7_log_remote_request( $url, $request, $response ) { + + if ( ! WP_DEBUG ) { + return; + } + + $log = sprintf( + /* translators: 1: response code, 2: message, 3: body, 4: URL */ + __( 'HTTP Response: %1$s %2$s %3$s from %4$s', 'contact-form-7' ), + (int) wp_remote_retrieve_response_code( $response ), + wp_remote_retrieve_response_message( $response ), + wp_remote_retrieve_body( $response ), + $url + ); + + $log = apply_filters( 'wpcf7_log_remote_request', + $log, $url, $request, $response + ); + + if ( $log ) { + wp_trigger_error( '', $log, E_USER_NOTICE ); + } +} + + +/** + * Anonymizes an IP address by masking local part. + * + * @param string $ip_addr The original IP address. + * @return string|bool Anonymized IP address, or false on failure. + */ +function wpcf7_anonymize_ip_addr( $ip_addr ) { + if ( + ! function_exists( 'inet_ntop' ) or + ! function_exists( 'inet_pton' ) + ) { + return $ip_addr; + } + + $packed = inet_pton( $ip_addr ); + + if ( false === $packed ) { + return $ip_addr; + } + + if ( 4 === strlen( $packed ) ) { // IPv4 + $mask = '255.255.255.0'; + } elseif ( 16 === strlen( $packed ) ) { // IPv6 + $mask = 'ffff:ffff:ffff:0000:0000:0000:0000:0000'; + } else { + return $ip_addr; + } + + return inet_ntop( $packed & inet_pton( $mask ) ); +} + + +/** + * Retrieves a sanitized value from the $_GET superglobal. + * + * @param string $key Array key. + * @param mixed $default The default value returned when + * the specified superglobal is not set. + * @return mixed Sanitized value. + */ +function wpcf7_superglobal_get( $key, $default = '' ) { + return wpcf7_superglobal( 'get', $key ) ?? $default; +} + + +/** + * Retrieves a sanitized value from the $_POST superglobal. + * + * @param string $key Array key. + * @param mixed $default The default value returned when + * the specified superglobal is not set. + * @return mixed Sanitized value. + */ +function wpcf7_superglobal_post( $key, $default = '' ) { + return wpcf7_superglobal( 'post', $key ) ?? $default; +} + + +/** + * Retrieves a sanitized value from the $_REQUEST superglobal. + * + * @param string $key Array key. + * @param mixed $default The default value returned when + * the specified superglobal is not set. + * @return mixed Sanitized value. + */ +function wpcf7_superglobal_request( $key, $default = '' ) { + return wpcf7_superglobal( 'request', $key ) ?? $default; +} + + +/** + * Retrieves a sanitized value from the $_SERVER superglobal. + * + * @param string $key Array key. + * @param mixed $default The default value returned when + * the specified superglobal is not set. + * @return mixed Sanitized value. + */ +function wpcf7_superglobal_server( $key, $default = '' ) { + return wpcf7_superglobal( 'server', $key ) ?? $default; +} + + +/** + * Retrieves a sanitized value from the specified superglobal. + * + * @param string $superglobal A superglobal type. + * @param string $key Array key. + * @return string|array|null Sanitized value. + */ +function wpcf7_superglobal( $superglobal, $key ) { + $superglobals = array( + 'get' => $_GET, + 'post' => $_POST, + 'request' => $_REQUEST, + 'server' => $_SERVER, + ); + + if ( isset( $superglobals[$superglobal][$key] ) ) { + return map_deep( + $superglobals[$superglobal][$key], + static function ( $val ) { + $val = wp_unslash( $val ); + $val = wp_check_invalid_utf8( $val ); + $val = wp_kses_no_null( $val ); + $val = wpcf7_strip_whitespaces( $val ); + return $val; + } + ); + } +} diff --git a/wp-content/plugins/contact-form-7/includes/html-formatter.php b/wp-content/plugins/contact-form-7/includes/html-formatter.php new file mode 100644 index 0000000..5f08d8d --- /dev/null +++ b/wp-content/plugins/contact-form-7/includes/html-formatter.php @@ -0,0 +1,868 @@ +options = wp_parse_args( $options, array( + 'auto_br' => true, + 'auto_indent' => true, + 'allowed_html' => wpcf7_kses_allowed_html(), + ) ); + } + + + /** + * Separates the given text into chunks of HTML. Each chunk must be an + * associative array that includes 'position', 'type', and 'content' keys. + * + * @param string $input Text to be separated into chunks. + * @return iterable Iterable of chunks. + */ + public function separate_into_chunks( $input ) { + $input_bytelength = strlen( $input ); + $position = 0; + + while ( $position < $input_bytelength ) { + $next_tag = preg_match( + '/(?:|<(?:\/?)[a-z].*?>)/is', + $input, + $matches, + PREG_OFFSET_CAPTURE, + $position + ); + + if ( ! $next_tag ) { + yield array( + 'position' => $position, + 'type' => self::text, + 'content' => substr( $input, $position ), + ); + + break; + } + + $next_tag = $matches[0][0]; + $next_tag_position = $matches[0][1]; + + if ( $position < $next_tag_position ) { + yield array( + 'position' => $position, + 'type' => self::text, + 'content' => substr( + $input, + $position, + $next_tag_position - $position + ), + ); + } + + if ( ' $next_tag_position, + 'type' => $next_tag_type, + 'content' => substr( + $input, + $next_tag_position, + strlen( $next_tag ) + ), + ); + + $position = $next_tag_position + strlen( $next_tag ); + } + } + + + /** + * Normalizes content in each chunk. This may change the type and position + * of the chunk. + * + * @param iterable $chunks The original chunks. + * @return iterable Normalized chunks. + */ + public function pre_format( $chunks ) { + $position = 0; + + foreach ( $chunks as $chunk ) { + $chunk['position'] = $position; + + // Standardize newline characters to "\n". + $chunk['content'] = str_replace( + array( "\r\n", "\r" ), "\n", $chunk['content'] + ); + + if ( self::start_tag === $chunk['type'] ) { + list( $chunk['content'] ) = + self::normalize_start_tag( $chunk['content'] ); + + // Replace
    by a line break. + if ( + $this->options['auto_br'] and + preg_match( '/^$/i', $chunk['content'] ) + ) { + $chunk['type'] = self::text; + $chunk['content'] = "\n"; + } + } + + yield $chunk; + $position = self::calc_next_position( $chunk ); + } + } + + + /** + * Concatenates neighboring text chunks to create a single chunk. + * + * @param iterable $chunks The original chunks. + * @return iterable Processed chunks. + */ + public function concatenate_texts( $chunks ) { + $position = 0; + $text_left = null; + + foreach ( $chunks as $chunk ) { + $chunk['position'] = $position; + + if ( self::text === $chunk['type'] ) { + if ( isset( $text_left ) ) { + $text_left['content'] .= $chunk['content']; + } else { + $text_left = $chunk; + } + + continue; + } + + if ( isset( $text_left ) ) { + yield $text_left; + $chunk['position'] = self::calc_next_position( $text_left ); + $text_left = null; + } + + yield $chunk; + $position = self::calc_next_position( $chunk ); + } + + if ( isset( $text_left ) ) { + yield $text_left; + } + } + + + /** + * Outputs formatted HTML based on the given chunks. + * + * @param iterable $chunks The original chunks. + * @return string Formatted HTML. + */ + public function format( $chunks ) { + $chunks = $this->pre_format( $chunks ); + $chunks = $this->concatenate_texts( $chunks ); + + $this->output = ''; + $this->stacked_elements = array(); + + foreach ( $chunks as $chunk ) { + + if ( self::text === $chunk['type'] ) { + $this->append_text( $chunk['content'] ); + } + + if ( self::start_tag === $chunk['type'] ) { + $this->start_tag( $chunk['content'] ); + } + + if ( self::end_tag === $chunk['type'] ) { + $this->end_tag( $chunk['content'] ); + } + + if ( self::comment === $chunk['type'] ) { + $this->append_comment( $chunk['content'] ); + } + } + + return $this->output(); + } + + + /** + * Appends preformatted text to the output property. + */ + public function append_preformatted( $content ) { + $this->output .= $content; + } + + + /** + * Appends whitespace to the output property. + */ + public function append_whitespace() { + $this->append_preformatted( ' ' ); + } + + + /** + * Appends a text node content to the output property. + * + * @param string $content Text node content. + */ + public function append_text( $content ) { + if ( $this->is_inside( array( 'pre', 'template' ) ) ) { + $this->append_preformatted( $content ); + return; + } + + if ( + empty( $this->stacked_elements ) or + $this->has_parent( 'p' ) or + $this->has_parent( self::p_parent_elements ) + ) { + // Close

    if the content starts with multiple line breaks. + if ( preg_match( '/^\s*\n\s*\n\s*/', $content ) ) { + $this->end_tag( 'p' ); + } + + // Split up the contents into paragraphs, separated by double line breaks. + $paragraphs = preg_split( '/\s*\n\s*\n\s*/', $content ); + + $paragraphs = array_filter( $paragraphs, static function ( $paragraph ) { + return '' !== wpcf7_strip_whitespaces( $paragraph ); + } ); + + $paragraphs = array_values( $paragraphs ); + + if ( $paragraphs ) { + if ( $this->is_inside( 'p' ) ) { + $paragraph = array_shift( $paragraphs ); + + $paragraph = self::normalize_paragraph( + $paragraph, + $this->options['auto_br'] + ); + + $this->append_preformatted( $paragraph ); + } + + foreach ( $paragraphs as $paragraph ) { + $this->start_tag( 'p' ); + + $paragraph = wpcf7_strip_whitespaces( $paragraph, 'start' ); + + $paragraph = self::normalize_paragraph( + $paragraph, + $this->options['auto_br'] + ); + + $this->append_preformatted( $paragraph ); + } + } + + // Close

    if the content ends with multiple line breaks. + if ( preg_match( '/\s*\n\s*\n\s*$/', $content ) ) { + $this->end_tag( 'p' ); + } + + // Cases where the content is a single line break. + if ( preg_match( '/^\s*\n\s*$/', $content ) ) { + $auto_br = $this->options['auto_br'] && $this->is_inside( 'p' ); + + $content = self::normalize_paragraph( $content, $auto_br ); + + $this->append_preformatted( $content ); + } + } else { + $auto_br = $this->options['auto_br'] && + $this->has_parent( self::br_parent_elements ); + + $content = self::normalize_paragraph( $content, $auto_br ); + + $this->append_preformatted( $content ); + } + } + + + /** + * Appends a start tag to the output property. + * + * @param string $tag A start tag. + */ + public function start_tag( $tag ) { + list( $tag, $tag_name ) = self::normalize_start_tag( $tag ); + + if ( + in_array( $tag_name, self::p_child_elements, true ) and + ! $this->is_inside( 'p' ) and + ! $this->is_inside( self::p_child_elements ) and + ! $this->has_parent( self::p_nonparent_elements ) + ) { + // Open

    if it does not exist. + $this->start_tag( 'p' ); + } + + $this->append_start_tag( $tag_name, array(), $tag ); + } + + + /** + * Appends a start tag to the output property. + * + * @param string $tag_name Tag name. + * @param array $atts Associative array of attribute name and value pairs. + * @param string $tag A start tag. + */ + public function append_start_tag( $tag_name, $atts = array(), $tag = '' ) { + if ( ! self::validate_tag_name( $tag_name ) ) { + wp_trigger_error( + __METHOD__, + sprintf( + /* translators: %s: Invalid HTML tag name */ + __( 'Invalid tag name (%s) is specified.', 'contact-form-7' ), + $tag_name + ), + E_USER_WARNING + ); + + return false; + } + + if ( WP_DEBUG and ! empty( $this->options['allowed_html'] ) ) { + $html_disallowance = array(); + + if ( ! isset( $this->options['allowed_html'][$tag_name] ) ) { + $html_disallowance = array( + 'element' => $tag_name, + ); + } else { + $atts_allowed = $this->options['allowed_html'][$tag_name]; + + $atts_disallowed = array_diff_ukey( $atts, $atts_allowed, + static function ( $key_1, $key_2 ) use ( $atts_allowed ) { + if ( + str_starts_with( $key_1, 'data-' ) and + ! empty( $atts_allowed['data-*'] ) and + preg_match( '/^data-[a-z0-9_-]+$/', $key_1 ) + ) { + return 0; + } else { + return $key_1 === $key_2 ? 0 : 1; + } + } + ); + + if ( ! empty( $atts_disallowed ) ) { + $html_disallowance = array( + 'element' => $tag_name, + 'attributes' => array_keys( $atts_disallowed ), + ); + } + } + + if ( $html_disallowance ) { + $notice = sprintf( + /* translators: %s: JSON-formatted array of disallowed HTML */ + __( 'HTML Disallowance: %s', 'contact-form-7' ), + wp_json_encode( $html_disallowance, JSON_PRETTY_PRINT ) + ); + + wp_trigger_error( __METHOD__, $notice, E_USER_NOTICE ); + } + } + + if ( + 'p' === $tag_name or + in_array( $tag_name, self::p_parent_elements, true ) or + in_array( $tag_name, self::p_nonparent_elements, true ) + ) { + // Close

    if it exists. + $this->end_tag( 'p' ); + } + + if ( 'dd' === $tag_name or 'dt' === $tag_name ) { + // Close

    and
    if closing tag is omitted. + $this->end_tag( 'dd' ); + $this->end_tag( 'dt' ); + } + + if ( 'li' === $tag_name ) { + // Close
  • if closing tag is omitted. + $this->end_tag( 'li' ); + } + + if ( 'optgroup' === $tag_name ) { + // Close if closing tag is omitted. + $this->end_tag( 'option' ); + $this->end_tag( 'optgroup' ); + } + + if ( 'option' === $tag_name ) { + // Close