array('label' => __( 'Messages', 'ai-eshop-optimizer' ), 'icon' => 'inbox'), 'settings' => array( 'label' => __( 'Settings', 'ai-eshop-optimizer' ), 'icon' => 'settings', 'query' => array( 'cf_section' => 'settings' ), 'align' => 'right', ), ); } public function register_hooks() { self::load_shared(); add_action( 'plugins_loaded', array( $this, 'maybe_install' ), 20 ); add_action( 'wp_ajax_aieo_dmm_contact_form_save', array( $this, 'ajax_save_settings' ) ); add_action( 'wp_ajax_aieo_dmm_contact_form_status', array( $this, 'ajax_set_status' ) ); add_action( 'wp_ajax_aieo_dmm_contact_form_delete', array( $this, 'ajax_delete' ) ); add_action( 'admin_init', array( $this, 'maybe_handle_contact_page' ) ); add_action( 'after_switch_theme', array( __CLASS__, 'on_theme_switch' ) ); add_action( 'wp_ajax_aieo_dmm_contact_form_create_page', array( $this, 'ajax_create_page' ) ); add_action( 'wp_ajax_aieo_dmm_contact_form_add_form', array( $this, 'ajax_add_form' ) ); add_action( 'wp_ajax_aieo_dmm_contact_form_dismiss_page_notice', array( $this, 'ajax_dismiss_page_notice' ) ); add_filter( 'woocommerce_email_classes', array( 'AIEO_Contact_Form_Mailer', 'register_wc_emails' ) ); add_action( 'enqueue_block_editor_assets', array( $this, 'editor_data' ) ); add_action( 'enqueue_block_assets', array( $this, 'editor_style' ) ); add_filter( 'wp_privacy_personal_data_exporters', array( 'AIEO_Contact_Form_Store', 'register_exporter' ) ); add_filter( 'wp_privacy_personal_data_erasers', array( 'AIEO_Contact_Form_Store', 'register_eraser' ) ); if ( function_exists( 'pll_register_string' ) ) { add_action( 'admin_init', static function () { AIEO_Contact_Form_Settings::register_strings( AIEO_Contact_Form_Settings::get( true ) ); } ); } if ( class_exists( 'AIEO_Contact_Form_Ajax' ) ) { AIEO_Contact_Form_Ajax::register_worker(); } if ( ! defined( 'AIEO_RUNTIME_OWNS_CONTACT_FORM' ) && class_exists( 'AIEO_Contact_Form' ) ) { AIEO_Contact_Form_Ajax::register(); AIEO_Contact_Form::register_cache_compat(); add_action( 'init', array( 'AIEO_Contact_Form', 'register_frontend' ), 9 ); } } public static function load_shared() { $dir = defined( 'AIEO_DIR' ) ? AIEO_DIR : trailingslashit( dirname( __FILE__, 4 ) ); foreach ( array( 'AIEO_Contact_Form_Settings' => 'includes/dmm/contact-form/class-aieo-contact-form-settings.php', 'AIEO_Contact_Form_Store' => 'includes/dmm/contact-form/class-aieo-contact-form-store.php', 'AIEO_Contact_Form' => 'includes/dmm/contact-form/class-aieo-contact-form.php', 'AIEO_Contact_Form_Ajax' => 'includes/dmm/contact-form/class-aieo-contact-form-ajax.php', 'AIEO_Contact_Form_Mailer' => 'includes/dmm/contact-form/class-aieo-contact-form-mailer.php', ) as $class => $rel ) { if ( class_exists( $class ) ) { continue; } if ( is_readable( $dir . $rel ) ) { require_once $dir . $rel; } } } public function editor_data() { self::load_shared(); if ( ! class_exists( 'AIEO_Contact_Form_Settings' ) ) { return; } $s = AIEO_Contact_Form_Settings::get(); $cfg = AIEO_Contact_Form_Settings::placement( $s ); $l = AIEO_Contact_Form::labels( $s ); unset( $l['email'] ); $data = array( 'show' => $cfg['show'], 'req' => $cfg['req'], 'names' => $cfg['names'], 'rows' => $cfg['rows'], 'labels' => $l, 'companyLabel' => (string) $s['company_label'], 'button' => (string) $s['button_text'], ); wp_add_inline_script( 'aieo-contact-form-editor-script', 'window.aieoContactFormEditor = ' . wp_json_encode( $data ) . ';', 'before' ); } public function editor_style() { if ( ! is_admin() || ! defined( 'AIEO_FILE' ) || ! defined( 'AIEO_DIR' ) ) { return; } $rel = 'assets/css/aieo-contact-form.css'; if ( ! file_exists( AIEO_DIR . $rel ) ) { return; } wp_enqueue_style( 'aieo-contact-form-editor', plugins_url( $rel, AIEO_FILE ), array(), (string) filemtime( AIEO_DIR . $rel ) ); } public function maybe_install() { $schema = defined( 'AIEO_DIR' ) ? AIEO_DIR . 'includes/dmm/contact-form/sql/contact-form-schema.php' : ''; if ( '' === $schema || ! is_readable( $schema ) ) { return; } require_once $schema; if ( function_exists( 'aieo_install_schema_once' ) ) { aieo_install_schema_once( self::SCHEMA_OPTION, self::SCHEMA_VERSION, 'aieo_contact_form_install_schema' ); return; } if ( get_option( self::SCHEMA_OPTION, '' ) !== self::SCHEMA_VERSION ) { aieo_contact_form_install_schema(); update_option( self::SCHEMA_OPTION, self::SCHEMA_VERSION, false ); } } public function render_subtab() { self::load_shared(); $tabs = $this->get_tabs(); $section = isset( $_GET['cf_section'] ) ? sanitize_key( (string) $_GET['cf_section'] ) : 'messages'; if ( ! isset( $tabs[ $section ] ) ) { $section = 'messages'; } AIEO_DMM_UI::tab_strip( $this->get_id(), $tabs, $section, array( 'arg' => $this->get_tab_arg(), 'wrapper' => 'div', 'margin' => '14px', 'counts' => array( 'messages' => AIEO_Contact_Form_Store::count_new() ), ) ); $recipients = AIEO_Contact_Form_Mailer::recipients(); if ( 'settings' === $section ) { $this->render_template( 'contact-form-settings.php', array( 'settings' => AIEO_Contact_Form_Settings::get( true ), 'i18n_defaults' => AIEO_Contact_Form_Settings::i18n_labels(), 'recipients' => $recipients, 'countries' => AIEO_Contact_Form::countries(), 'base_country' => AIEO_Contact_Form::default_country( array( 'default_country' => '' ) ), ) ); return; } $id = isset( $_GET['message_id'] ) ? (int) $_GET['message_id'] : 0; if ( $id > 0 ) { $msg = AIEO_Contact_Form_Store::get( $id ); if ( $msg ) { if ( AIEO_Contact_Form_Store::mark_read_if_new( $id ) ) { $msg = AIEO_Contact_Form_Store::get( $id ); } $this->render_template( 'contact-form-detail.php', array( 'msg' => $msg ) ); return; } } $per_page = 50; $filters = array( 'status' => isset( $_GET['cf_status'] ) ? sanitize_key( wp_unslash( (string) $_GET['cf_status'] ) ) : '', 'search' => isset( $_GET['cf_s'] ) ? sanitize_text_field( wp_unslash( (string) $_GET['cf_s'] ) ) : '', 'per_page' => $per_page, 'paged' => max( 1, isset( $_GET['cf_paged'] ) ? (int) $_GET['cf_paged'] : 1 ), ); $listing = AIEO_Contact_Form_Store::list_messages( $filters ); $this->render_template( 'contact-form.php', array( 'rows' => $listing['rows'], 'total' => $listing['total'], 'per_page' => $per_page, 'filters' => $filters, 'status_counts' => AIEO_Contact_Form_Store::status_counts(), 'recipients' => $recipients, 'table_ready' => AIEO_Contact_Form_Store::ready(), 'contact_page' => self::contact_page(), ) ); } const PAGE_META = '_aieo_contact_page'; const PAGE_OPTION = 'aieo_contact_page_id'; const PAGE_TODO = 'aieo_contact_page_todo'; const PAGE_NOTICE_DISMISSED = 'aieo_contact_page_notice_dismissed'; public static function contact_page() { foreach ( array( 'contact', 'contact-us' ) as $slug ) { $page = get_page_by_path( $slug, OBJECT, 'page' ); if ( $page instanceof WP_Post && 'trash' !== $page->post_status ) { return $page; } } return null; } public static function page_has_form( $page ) { $content = (string) $page->post_content; if ( has_block( 'aieo/contact-form', $content ) || has_shortcode( $content, 'aieo_contact_form' ) ) { return true; } $patterns = class_exists( 'WP_Block_Patterns_Registry' ) ? WP_Block_Patterns_Registry::get_instance() : null; foreach ( array( 'rooster/page-contact', 'rooster/contact' ) as $slug ) { if ( $patterns && $patterns->is_registered( $slug ) && false !== strpos( $content, '"slug":"' . $slug . '"' ) ) { return true; } } return false; } public static function page_content() { if ( class_exists( 'WP_Block_Patterns_Registry' ) && WP_Block_Patterns_Registry::get_instance()->is_registered( 'rooster/page-contact' ) ) { return ''; } $switched = function_exists( 'switch_to_locale' ) && get_locale() !== determine_locale() && switch_to_locale( get_locale() ); $content = '' . "\n" . '
' . esc_html__( 'We answer as soon as we can.', 'ai-eshop-optimizer' ) . '
' . "\n" . '' . "\n\n" . ''; if ( $switched ) { restore_previous_locale(); } return $content; } public static function create_contact_page() { $existing = self::contact_page(); if ( $existing ) { return (int) $existing->ID; } $content = self::page_content(); $id = wp_insert_post( array( 'post_title' => _x( 'Contact', 'the page', 'ai-eshop-optimizer' ), 'post_name' => 'contact', 'post_content' => $content, 'post_status' => 'publish', 'post_type' => 'page', ) ); if ( is_wp_error( $id ) || ! $id ) { return 0; } update_post_meta( (int) $id, self::PAGE_META, md5( $content ) ); update_option( self::PAGE_OPTION, (int) $id, false ); return (int) $id; } public static function page_is_ours_unedited( $page ) { $hash = (string) get_post_meta( $page->ID, self::PAGE_META, true ); return '' !== $hash && md5( (string) $page->post_content ) === $hash; } public static function on_theme_switch() { if ( get_option( self::PAGE_OPTION ) ) { update_option( self::PAGE_TODO, 'rebuild', false ); } } public function maybe_handle_contact_page() { $todo = (string) get_option( self::PAGE_TODO, '' ); if ( '' === $todo ) { return; } delete_option( self::PAGE_TODO ); if ( 'create' === $todo ) { self::create_contact_page(); return; } $page = get_post( (int) get_option( self::PAGE_OPTION, 0 ) ); if ( $page instanceof WP_Post && 'page' === $page->post_type && self::page_is_ours_unedited( $page ) ) { $content = self::page_content(); if ( $content !== $page->post_content ) { wp_update_post( array( 'ID' => $page->ID, 'post_content' => $content ) ); update_post_meta( $page->ID, self::PAGE_META, md5( $content ) ); } } } public function ajax_create_page() { AIEO_DMM::verify_ajax_request(); $id = self::create_contact_page(); if ( ! $id ) { wp_send_json_error( array( 'message' => __( 'Could not create the page.', 'ai-eshop-optimizer' ) ), 500 ); } wp_send_json_success( array( 'page_id' => $id ) ); } public function ajax_add_form() { AIEO_DMM::verify_ajax_request(); $page = self::contact_page(); if ( ! $page || self::page_has_form( $page ) ) { wp_send_json_success(); } $done = wp_update_post( array( 'ID' => $page->ID, 'post_content' => rtrim( (string) $page->post_content ) . "\n\n" . '' ), true ); if ( is_wp_error( $done ) ) { wp_send_json_error( array( 'message' => __( 'Could not change the page.', 'ai-eshop-optimizer' ) ), 500 ); } wp_send_json_success(); } public function ajax_dismiss_page_notice() { AIEO_DMM::verify_ajax_request(); update_option( self::PAGE_NOTICE_DISMISSED, 1, false ); wp_send_json_success(); } public static function status_labels() { return array( 'new' => __( 'New', 'ai-eshop-optimizer' ), 'read' => _x( 'Read', 'contact message status', 'ai-eshop-optimizer' ), 'replied' => __( 'Replied', 'ai-eshop-optimizer' ), 'spam' => __( 'Spam', 'ai-eshop-optimizer' ), ); } public function ajax_save_settings() { AIEO_DMM::verify_ajax_request(); self::load_shared(); $existing = get_option( AIEO_Contact_Form_Settings::OPTION_KEY, array() ); if ( ! is_array( $existing ) ) { $existing = array(); } $data = array(); $checks = array( 'enabled', 'ack_enabled', 'consent_enabled' ); foreach ( AIEO_Contact_Form_Settings::FIELDS as $f ) { if ( 'email' === $f ) { continue; } $checks[] = 'show_' . $f; $checks[] = 'req_' . $f; } foreach ( $checks as $k ) { if ( isset( $_POST[ 'has_' . $k ] ) ) { $data[ $k ] = ! empty( $_POST[ $k ] ) ? 'yes' : 'no'; } } foreach ( array( 'recipients', 'staff_subject', 'ack_subject', 'form_title', 'form_intro', 'button_text', 'company_label', 'consent_text', 'consent_link_text', ) as $k ) { if ( isset( $_POST[ $k ] ) ) { $data[ $k ] = sanitize_text_field( wp_unslash( (string) $_POST[ $k ] ) ); } } foreach ( array( 'ack_body', 'success_message' ) as $k ) { if ( isset( $_POST[ $k ] ) ) { $data[ $k ] = sanitize_textarea_field( wp_unslash( (string) $_POST[ $k ] ) ); } } foreach ( array( 'redirect_url', 'consent_url' ) as $k ) { if ( isset( $_POST[ $k ] ) ) { $data[ $k ] = esc_url_raw( trim( wp_unslash( (string) $_POST[ $k ] ) ) ); } } if ( isset( $_POST['name_layout'] ) ) { $data['name_layout'] = ( 'stacked' === sanitize_key( wp_unslash( (string) $_POST['name_layout'] ) ) ) ? 'stacked' : 'inline'; } if ( isset( $_POST['message_rows'] ) ) { $data['message_rows'] = max( AIEO_Contact_Form_Settings::ROWS_MIN, min( AIEO_Contact_Form_Settings::ROWS_MAX, (int) $_POST['message_rows'] ) ); } if ( isset( $_POST['default_country'] ) ) { $c = strtoupper( preg_replace( '/[^A-Za-z]/', '', wp_unslash( (string) $_POST['default_country'] ) ) ); $data['default_country'] = ( 2 === strlen( $c ) ) ? $c : ''; } $merged = array_merge( $existing, $data ); update_option( AIEO_Contact_Form_Settings::OPTION_KEY, $merged, false ); AIEO_Contact_Form_Settings::register_strings( array_merge( AIEO_Contact_Form_Settings::defaults(), $merged ) ); do_action( 'aieo_contact_form_settings_saved' ); wp_send_json_success( array( 'message' => __( 'Contact form settings saved.', 'ai-eshop-optimizer' ) ) ); } public function ajax_set_status() { AIEO_DMM::verify_ajax_request(); self::load_shared(); $ids = isset( $_POST['ids'] ) ? AIEO_Contact_Form_Store::clean_ids( wp_unslash( (array) $_POST['ids'] ) ) : array(); $status = isset( $_POST['status'] ) ? sanitize_key( wp_unslash( (string) $_POST['status'] ) ) : ''; if ( ! $ids || ! in_array( $status, AIEO_Contact_Form_Store::STATUSES, true ) ) { wp_send_json_error( array( 'message' => __( 'Invalid request.', 'ai-eshop-optimizer' ) ) ); } $n = AIEO_Contact_Form_Store::set_status( $ids, $status ); wp_send_json_success( array( 'updated' => $n, 'message' => __( 'Saved.', 'ai-eshop-optimizer' ) ) ); } public function ajax_delete() { AIEO_DMM::verify_ajax_request(); self::load_shared(); $ids = isset( $_POST['ids'] ) ? AIEO_Contact_Form_Store::clean_ids( wp_unslash( (array) $_POST['ids'] ) ) : array(); if ( ! $ids ) { wp_send_json_error( array( 'message' => __( 'Invalid request.', 'ai-eshop-optimizer' ) ) ); } wp_send_json_success( array( 'deleted' => AIEO_Contact_Form_Store::delete( $ids ) ) ); } }