'Edge', 'Firefox' => 'Firefox', 'Chrome' => 'Chrome', 'Version' => 'Safari'] as $token => $label) { if (preg_match('~(?:^|[ /])' . preg_quote($token, '~') . '/([0-9]{1,3})(?:[. ]|$)~', $raw, $match)) { if ($token === 'Version' && !str_contains($raw, 'Safari/')) continue; return $label . ' ' . $match[1]; } } return __('Not detected', 'mkb-glossar'); } function mkb_glossar_support_diagnostics() { return [ __('MKB Glossar version', 'mkb-glossar') => MKB_GLOSSAR_VERSION, __('WordPress version', 'mkb-glossar') => (string) get_bloginfo('version'), __('PHP version', 'mkb-glossar') => PHP_VERSION, __('Browser', 'mkb-glossar') => mkb_glossar_support_browser(), ]; } /** Defined results allow an honest message, without leaking mail configuration details. */ function mkb_glossar_support_process_request($post) { if (!current_user_can('manage_options')) return 'forbidden'; if (!is_array($post)) return 'invalid'; $nonce = $post['mkb_glossar_support_nonce'] ?? null; if (!is_string($nonce) || !wp_verify_nonce(sanitize_text_field(wp_unslash($nonce)), 'mkb_glossar_support_send')) return 'invalid'; $raw_email = $post['mkb_support_email'] ?? null; $raw_topic = $post['mkb_support_topic'] ?? null; $raw_message = $post['mkb_support_message'] ?? null; if (!is_string($raw_email) || !is_string($raw_topic) || !is_string($raw_message)) return 'invalid'; $email = sanitize_email(wp_unslash($raw_email)); $topic = sanitize_key(wp_unslash($raw_topic)); $message = sanitize_textarea_field(wp_unslash($raw_message)); $topics = ['question', 'linking', 'display', 'language', 'other']; if (!is_email($email) || !in_array($topic, $topics, true) || (function_exists('mb_strlen') ? mb_strlen($message) : strlen($message)) < 10 || (function_exists('mb_strlen') ? mb_strlen($message) : strlen($message)) > 4000) return 'invalid'; $opt_in = isset($post['mkb_support_diagnostics']) && $post['mkb_support_diagnostics'] === '1'; $cooldown = 'mkb_glossar_support_cooldown_' . get_current_user_id(); if (get_transient($cooldown)) return 'limited'; $labels = [ 'question' => __('General question', 'mkb-glossar'), 'linking' => __('Automatic links and exclusions', 'mkb-glossar'), 'display' => __('Glossary overview and tooltips', 'mkb-glossar'), 'language' => __('Languages and translations', 'mkb-glossar'), 'other' => __('Something else', 'mkb-glossar'), ]; $subject = '[MKB Glossar] ' . $labels[$topic]; $body = "MKB Glossar support request\n\n"; $body .= 'Topic: ' . $labels[$topic] . "\n"; $body .= 'Contact email: ' . $email . "\n\n"; $body .= "Message:\n" . $message . "\n\n"; $body .= 'Diagnostic information: ' . ($opt_in ? 'Included by consent' : 'Not included') . "\n"; if ($opt_in) { foreach (mkb_glossar_support_diagnostics() as $key => $value) { $body .= $key . ': ' . $value . "\n"; } } // Let WordPress and the site's configured mail transport choose the From identity. // Never build arbitrary custom mail headers from visitor-supplied strings. $headers = ['Content-Type: text/plain; charset=UTF-8', 'Reply-To: ' . $email]; try { $accepted = wp_mail(MKB_GLOSSAR_SUPPORT_RECIPIENT, $subject, $body, $headers); } catch (Throwable $error) { $accepted = false; } if ($accepted !== true) return 'failed'; set_transient($cooldown, 1, MINUTE_IN_SECONDS); return 'accepted'; } /** WordPress's logged-in admin-post endpoint; never register a nopriv action. */ add_action('admin_post_mkb_glossar_support_send', static function () { if (!current_user_can('manage_options')) { wp_die(esc_html__('You do not have permission to send a support request.', 'mkb-glossar'), '', ['response' => 403]); } // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Restricted WordPress admin-post/classic-editor code; caller verifies nonce, capability and request shape before accessing POST. $result = mkb_glossar_support_process_request($_POST); set_transient('mkb_glossar_support_result_' . get_current_user_id(), $result, MINUTE_IN_SECONDS); $url = mkb_glossar_help_url(); wp_safe_redirect($url . '#mkb-help-support-form'); exit; }); function mkb_glossar_render_support_form() { if (!current_user_can('manage_options')) { echo '

' . esc_html__('Only website administrators can send this form. If you need help, please ask an administrator of your website.', 'mkb-glossar') . '

'; return; } $result_key = 'mkb_glossar_support_result_' . get_current_user_id(); $result = get_transient($result_key); if ($result !== false) delete_transient($result_key); $messages = [ 'accepted' => __('Your request was handed to the WordPress mail system. This does not guarantee delivery. If you receive no reply, you can contact us by email.', 'mkb-glossar'), 'failed' => __('WordPress could not hand over the email. Please check your website’s mail settings or use the direct email address below.', 'mkb-glossar'), 'invalid' => __('Please check your email, choose a topic and describe your question in at least 10 characters. Then try again.', 'mkb-glossar'), 'limited' => __('You have just sent a request. Please wait a moment before sending another.', 'mkb-glossar'), ]; echo '
'; echo '

' . esc_html__('Contact MKB Glossar support', 'mkb-glossar') . '

'; echo '

' . esc_html__('Tell us what you were trying to do and what happened instead. You can send a question directly from WordPress.', 'mkb-glossar') . '

'; if (is_string($result) && isset($messages[$result])) { echo '
' . esc_html($messages[$result]) . '
'; } echo '
'; echo ''; wp_nonce_field('mkb_glossar_support_send', 'mkb_glossar_support_nonce'); echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo '

' . esc_html__('Only include information needed to answer your question. Do not send passwords, API keys, private website content or personal information about other people.', 'mkb-glossar') . '

'; echo '
'; echo '

' . esc_html__('Optional technical details – review before sharing', 'mkb-glossar') . '

'; echo '
'; foreach (mkb_glossar_support_diagnostics() as $key => $value) { echo '
' . esc_html($key) . '
' . esc_html($value) . '
'; } echo '
'; echo ''; echo '

' . esc_html__('These details are not sent unless you tick the box and submit the form. Your message and contact email are always sent when you submit.', 'mkb-glossar') . '

'; echo '
'; echo ''; echo '
'; echo '

' . esc_html__('Prefer email? Write to', 'mkb-glossar') . ' ' . esc_html(MKB_GLOSSAR_SUPPORT_RECIPIENT) . '.

'; echo '
'; }