', '
', '
'), "\n", (string) $html_message))); } add_filter('wp_mail_from_name', 'matewa_agency_mail_from_name_filter', 99); $sent = wp_mail($to, $subject, $plain_message, matewa_agency_email_plain_headers($reply_to)); remove_filter('wp_mail_from_name', 'matewa_agency_mail_from_name_filter', 99); return (bool) $sent; } } if (!function_exists('matewa_agency_send_branded_email_result')) { function matewa_agency_send_branded_email_result($to, $subject, $html_message, $reply_to = '', $plain_message = '') { $to = sanitize_email((string) $to); $result = array( 'to' => $to, 'sent' => false, 'method' => 'not_sent', 'error' => '', ); if (!is_email($to)) { $result['error'] = 'Invalid recipient email.'; return $result; } $subject = sanitize_text_field((string) $subject); $reply_to = sanitize_email((string) $reply_to); $plain_message = trim((string) $plain_message); if ('' === $plain_message) { $plain_message = trim(wp_strip_all_tags(str_replace(array('
', '
', '
'), "\n", (string) $html_message))); } $last_mail_error = ''; $failure_hook = function($wp_error) use (&$last_mail_error) { if (is_wp_error($wp_error)) { $last_mail_error = $wp_error->get_error_message(); } }; add_action('wp_mail_failed', $failure_hook, 10, 1); add_filter('wp_mail_from_name', 'matewa_agency_mail_from_name_filter', 99); $sent = wp_mail($to, $subject, $plain_message, matewa_agency_email_plain_headers($reply_to)); remove_filter('wp_mail_from_name', 'matewa_agency_mail_from_name_filter', 99); remove_action('wp_mail_failed', $failure_hook, 10); if ($sent) { $result['sent'] = true; $result['method'] = 'plain_default_sender_name_only'; return $result; } $result['error'] = '' !== $last_mail_error ? $last_mail_error : 'wp_mail returned false.'; return $result; } } if (!function_exists('matewa_agency_email_logo_url')) { function matewa_agency_email_logo_url() { if (defined('MATEWA_PLUGIN_URL')) { return MATEWA_PLUGIN_URL . 'admin/assets/247trademate-logo.png'; } return ''; } } if (!function_exists('matewa_agency_wrap_html_email')) { function matewa_agency_wrap_html_email($heading, $intro, $rows = array(), $footer_note = '') { $logo_url = matewa_agency_email_logo_url(); $heading = sanitize_text_field((string) $heading); $intro = wp_kses_post((string) $intro); $footer_note = wp_kses_post((string) $footer_note); $row_html = ''; if (is_array($rows)) { foreach ($rows as $label => $value) { $row_html .= ''; $row_html .= '' . esc_html((string) $label) . ''; $row_html .= '' . wp_kses_post((string) $value) . ''; $row_html .= ''; } } $logo_html = ''; if ('' !== $logo_url) { $logo_html = '247ChatMate'; } return '' . '
' . '
' . '
' . $logo_html . '
Agency Hub
' . '

' . esc_html($heading) . '

' . '
' . $intro . '
' . '
' . '
' . ('' !== $row_html ? '' . $row_html . '
' : '') . ('' !== $footer_note ? '
' . $footer_note . '
' : '') . '

Thanks,
247ChatMate

' . '
'; } } if (!function_exists('matewa_agency_build_plain_email')) { function matewa_agency_build_plain_email($heading, $intro, $rows = array(), $footer_note = '') { $lines = array(); $heading = trim(wp_strip_all_tags((string) $heading)); $intro = trim(wp_strip_all_tags(str_replace(array('
', '
', '
'), "\n", (string) $intro))); $footer_note = trim(wp_strip_all_tags(str_replace(array('
', '
', '
'), "\n", (string) $footer_note))); if ('' !== $heading) { $lines[] = $heading; $lines[] = ''; } if ('' !== $intro) { $lines[] = $intro; $lines[] = ''; } if (is_array($rows)) { foreach ($rows as $label => $value) { $clean_label = trim(wp_strip_all_tags((string) $label)); $clean_value = trim(wp_strip_all_tags((string) $value)); if ('' !== $clean_label || '' !== $clean_value) { $lines[] = $clean_label . ('' !== $clean_value ? ': ' . $clean_value : ''); } } $lines[] = ''; } if ('' !== $footer_note) { $lines[] = $footer_note; $lines[] = ''; } $lines[] = 'Thanks,'; $lines[] = '247ChatMate'; return implode("\n", $lines); } } /* ========================================================== CHIP OVERRIDE HELPERS (NARROW PASS) ========================================================== */ if (!defined('MATEWA_CHIP_MAX_LINES')) { define('MATEWA_CHIP_MAX_LINES', 2); } if (!defined('MATEWA_CHIP_MAX_LINE_CHARS')) { define('MATEWA_CHIP_MAX_LINE_CHARS', 20); } if (!defined('MATEWA_CHIP_MAX_TOTAL_CHARS')) { define('MATEWA_CHIP_MAX_TOTAL_CHARS', 34); } if (!function_exists('matewa_normalise_chip_label_for_widget')) { function matewa_normalise_chip_label_for_widget($label) { $max_lines = (int) MATEWA_CHIP_MAX_LINES; $max_line_chars = (int) MATEWA_CHIP_MAX_LINE_CHARS; $max_total_chars = (int) MATEWA_CHIP_MAX_TOTAL_CHARS; $label = wp_strip_all_tags((string) $label); $label = html_entity_decode($label, ENT_QUOTES, 'UTF-8'); $label = str_replace(["\r\n", "\r"], "\n", $label); $label = str_replace("\t", ' ', $label); $raw_lines = preg_split("/\n/u", $label); if (!is_array($raw_lines)) { $raw_lines = []; } $clean_lines = []; foreach ($raw_lines as $line) { if (count($clean_lines) >= $max_lines) { break; } $line = (string) $line; $line = preg_replace('/^[ ]+/u', '', $line); $line = preg_replace('/[ ]+$/u', '', $line); if ('' === $line) { continue; } if (function_exists('mb_substr') && function_exists('mb_strlen')) { if (mb_strlen($line, 'UTF-8') > $max_line_chars) { $line = mb_substr($line, 0, $max_line_chars, 'UTF-8'); } } elseif (strlen($line) > $max_line_chars) { $line = substr($line, 0, $max_line_chars); } $clean_lines[] = $line; } $normalised = implode("\n", $clean_lines); if (function_exists('mb_substr') && function_exists('mb_strlen')) { if (mb_strlen($normalised, 'UTF-8') > $max_total_chars) { $normalised = mb_substr($normalised, 0, $max_total_chars, 'UTF-8'); } } elseif (strlen($normalised) > $max_total_chars) { $normalised = substr($normalised, 0, $max_total_chars); } return $normalised; } } if (!function_exists('matewa_sanitise_chip_label_overrides')) { function matewa_sanitise_chip_label_overrides($value) { if (!is_array($value)) { return []; } $clean = []; foreach ($value as $vertical_key => $vertical_labels) { $vertical_key = sanitize_key((string) $vertical_key); if ('' === $vertical_key || !is_array($vertical_labels)) { continue; } $clean[$vertical_key] = []; foreach ($vertical_labels as $intent_key => $label) { $intent_key = trim((string) $intent_key); $label = matewa_normalise_chip_label_for_widget($label); if ('' === $intent_key || '' === $label) { continue; } $clean[$vertical_key][$intent_key] = $label; } if (empty($clean[$vertical_key])) { unset($clean[$vertical_key]); } } return $clean; } } /* ========================================================== VERTICAL / CATEGORY HELPERS ========================================================== */ if (!function_exists('matewa_format_vertical_key_label')) { function matewa_format_vertical_key_label($vertical_key) { $vertical_key = (string) $vertical_key; if ('' === trim($vertical_key)) { return 'General'; } $vertical_key = str_replace(['_', '-'], ' ', $vertical_key); $vertical_key = preg_replace('/\s+/u', ' ', $vertical_key); $vertical_key = trim((string) $vertical_key); if ('' === $vertical_key) { return 'General'; } $words = preg_split('/\s+/u', strtolower($vertical_key)); if (!is_array($words)) { $words = []; } $upper_words = ['HGV', 'MOT', 'CBT', 'DAS', 'CPC', 'SEO', 'PPC', 'VAT', 'EV']; $out = []; foreach ($words as $word) { $word = trim((string) $word); if ('' === $word) { continue; } $upper = strtoupper($word); if (in_array($upper, $upper_words, true)) { $out[] = $upper; continue; } $out[] = ucfirst($word); } $label = trim(implode(' ', $out)); return '' !== $label ? $label : 'General'; } } if (!function_exists('matewa_safe_scalar_text')) { function matewa_safe_scalar_text($value, $fallback = '') { if (is_string($value) || is_numeric($value)) { $value = trim((string) $value); return '' !== $value ? $value : (string) $fallback; } if (is_bool($value)) { return $value ? '1' : '0'; } return (string) $fallback; } } if (!function_exists('matewa_safe_key')) { function matewa_safe_key($value, $fallback = '') { $value = matewa_safe_scalar_text($value, $fallback); return sanitize_key($value); } } if (!function_exists('matewa_resolve_vertical_display_label')) { function matewa_resolve_vertical_display_label($vertical_key, $vertical_config = []) { $vertical_key = matewa_safe_key($vertical_key); $vertical_config = is_array($vertical_config) ? $vertical_config : []; if (!empty($vertical_config['display_label']) && is_string($vertical_config['display_label'])) { $display_label = trim((string) $vertical_config['display_label']); if ('' !== $display_label) { $display_label = str_replace('_', ' ', $display_label); $display_label = preg_replace('/\s+/u', ' ', $display_label); return trim((string) $display_label); } } if (function_exists('matewa_get_vertical_display_label')) { $resolved = (string) matewa_get_vertical_display_label($vertical_key); $resolved = str_replace('_', ' ', $resolved); $resolved = preg_replace('/\s+/u', ' ', $resolved); $resolved = trim((string) $resolved); if ('' !== $resolved) { return $resolved; } } $label_key = !empty($vertical_config['label_key']) && is_string($vertical_config['label_key']) ? (string) $vertical_config['label_key'] : 'vertical.' . $vertical_key; if (function_exists('matewa_catalog_resolve_vertical_label')) { $resolved = (string) matewa_catalog_resolve_vertical_label($vertical_key, $label_key); $resolved = str_replace('_', ' ', $resolved); $resolved = preg_replace('/\s+/u', ' ', $resolved); $resolved = trim((string) $resolved); if ('' !== $resolved) { return $resolved; } } if (function_exists('matewa_get_i18n_label')) { $resolved = (string) matewa_get_i18n_label($label_key); $resolved = str_replace('_', ' ', $resolved); $resolved = preg_replace('/\s+/u', ' ', $resolved); $resolved = trim((string) $resolved); if ('' !== $resolved && $resolved !== $label_key) { return $resolved; } } return matewa_format_vertical_key_label($vertical_key); } } if (!function_exists('matewa_get_vertical_catalog_data')) { function matewa_get_vertical_catalog_data() { $data = function_exists('matewa_get_verticals') ? (array) matewa_get_verticals() : []; $verticals = is_array($data['verticals'] ?? null) ? $data['verticals'] : []; $categories = is_array($data['categories'] ?? null) ? $data['categories'] : []; $default_vertical = matewa_safe_key($data['default_vertical'] ?? 'general', 'general'); return [ 'default_vertical' => $default_vertical, 'verticals' => $verticals, 'categories' => $categories, ]; } } if (!function_exists('matewa_get_full_vertical_catalog_for_admin_preview')) { /** * Return the same complete merged remote catalogue used by Trial/Pro. * Free permissions are enforced separately; this function changes visibility only. */ function matewa_get_full_vertical_catalog_for_admin_preview() { return matewa_get_vertical_catalog_data(); } } if (!function_exists('matewa_admin_preview_labels_from_vertical_config')) { function matewa_admin_preview_labels_from_vertical_config($vertical_config) { $vertical_config = is_array($vertical_config) ? $vertical_config : []; $chip_keys = is_array($vertical_config['chips'] ?? null) ? array_values($vertical_config['chips']) : []; $labels = []; foreach ($chip_keys as $intent_key) { $intent_key = trim((string) $intent_key); if ('' === $intent_key) { continue; } $label = function_exists('matewa_catalog_resolve_intent_label') ? trim((string) matewa_catalog_resolve_intent_label($intent_key)) : ''; if ('' === $label || $label === $intent_key) { $label = ucwords(str_replace(['intent.', '.', '_', '-'], ['', ' ', ' ', ' '], $intent_key)); } if ('' !== trim($label)) { $labels[] = $label; } } return $labels; } } if (!function_exists('matewa_get_vertical_category_overrides')) { function matewa_get_vertical_category_overrides() { return []; } } if (!function_exists('matewa_merge_vertical_categories')) { function matewa_merge_vertical_categories($base_categories, $vertical_definitions) { $base_categories = is_array($base_categories) ? $base_categories : []; $vertical_definitions = is_array($vertical_definitions) ? $vertical_definitions : []; $clean_categories = []; foreach ($base_categories as $category_key => $category_config) { $category_key = matewa_safe_key($category_key); $category_config = is_array($category_config) ? $category_config : []; if ('' === $category_key) { continue; } $label = !empty($category_config['label']) && is_string($category_config['label']) ? trim((string) $category_config['label']) : matewa_format_vertical_key_label($category_key); $verticals = is_array($category_config['verticals'] ?? null) ? array_values($category_config['verticals']) : []; $valid_verticals = []; foreach ($verticals as $vertical_key) { $vertical_key = matewa_safe_key($vertical_key); if ('' === $vertical_key) { continue; } if (!isset($vertical_definitions[$vertical_key])) { continue; } $valid_verticals[$vertical_key] = $vertical_key; } $clean_categories[$category_key] = [ 'label' => '' !== $label ? $label : matewa_format_vertical_key_label($category_key), 'verticals' => array_values($valid_verticals), ]; } if (empty($clean_categories) && !empty($vertical_definitions)) { $fallback_verticals = []; foreach ($vertical_definitions as $vertical_key => $vertical_config) { $vertical_key = matewa_safe_key($vertical_key); if ('' === $vertical_key) { continue; } $fallback_verticals[$vertical_key] = $vertical_key; } $clean_categories['general'] = [ 'label' => 'General', 'verticals' => array_values($fallback_verticals), ]; } return $clean_categories; } } if (!function_exists('matewa_compare_vertical_selector_items_general_first')) { function matewa_compare_vertical_selector_items_general_first($a, $b) { $a_key = matewa_safe_key($a['key'] ?? ''); $b_key = matewa_safe_key($b['key'] ?? ''); $a_label = matewa_safe_scalar_text($a['display_label'] ?? ($a['label'] ?? '')); $b_label = matewa_safe_scalar_text($b['display_label'] ?? ($b['label'] ?? '')); $a_is_general = ('general' === $a_key || 0 === strcasecmp($a_label, 'General')); $b_is_general = ('general' === $b_key || 0 === strcasecmp($b_label, 'General')); if ($a_is_general && !$b_is_general) { return -1; } if ($b_is_general && !$a_is_general) { return 1; } $label_compare = strcasecmp($a_label, $b_label); if (0 !== $label_compare) { return $label_compare; } return strcasecmp($a_key, $b_key); } } if (!function_exists('matewa_build_vertical_selector_data')) { function matewa_build_vertical_selector_data($vertical_definitions, $categories) { $vertical_definitions = is_array($vertical_definitions) ? $vertical_definitions : []; $categories = is_array($categories) ? $categories : []; $categories = matewa_merge_vertical_categories($categories, $vertical_definitions); $vertical_options = []; foreach ($vertical_definitions as $vertical_key => $vertical_config) { $vertical_key = matewa_safe_key($vertical_key); if ('' === $vertical_key) { continue; } $vertical_options[$vertical_key] = [ 'key' => $vertical_key, 'display_label' => matewa_safe_scalar_text( matewa_resolve_vertical_display_label($vertical_key, $vertical_config), matewa_format_vertical_key_label($vertical_key) ), ]; } uasort($vertical_options, 'matewa_compare_vertical_selector_items_general_first'); $categories_out = []; $vertical_to_category = []; $assigned_keys = []; foreach ($categories as $category_key => $category_config) { $category_key = matewa_safe_key($category_key); $category_config = is_array($category_config) ? $category_config : []; if ('' === $category_key) { continue; } $category_label = matewa_safe_scalar_text( $category_config['label'] ?? '', matewa_format_vertical_key_label($category_key) ); $category_verticals = is_array($category_config['verticals'] ?? null) ? array_values($category_config['verticals']) : []; $options = []; foreach ($category_verticals as $vertical_key) { $vertical_key = matewa_safe_key($vertical_key); if ('' === $vertical_key || !isset($vertical_options[$vertical_key])) { continue; } $options[$vertical_key] = [ 'key' => $vertical_key, 'display_label' => matewa_safe_scalar_text( $vertical_options[$vertical_key]['display_label'] ?? '', matewa_format_vertical_key_label($vertical_key) ), ]; $vertical_to_category[$vertical_key] = $category_key; $assigned_keys[$vertical_key] = true; } if (!empty($options)) { uasort($options, 'matewa_compare_vertical_selector_items_general_first'); $categories_out[$category_key] = [ 'key' => $category_key, 'label' => $category_label, 'options' => $options, ]; } } $ungrouped = []; foreach ($vertical_options as $vertical_key => $vertical_data) { if (!isset($assigned_keys[$vertical_key])) { $ungrouped[$vertical_key] = [ 'key' => matewa_safe_key($vertical_data['key'] ?? $vertical_key, $vertical_key), 'display_label' => matewa_safe_scalar_text( $vertical_data['display_label'] ?? '', matewa_format_vertical_key_label($vertical_key) ), ]; } } if (!empty($ungrouped)) { uasort($ungrouped, function ($a, $b) { return strcasecmp( matewa_safe_scalar_text($a['display_label'] ?? ''), matewa_safe_scalar_text($b['display_label'] ?? '') ); }); $categories_out['other'] = [ 'key' => 'other', 'label' => 'Other', 'options' => $ungrouped, ]; foreach ($ungrouped as $vertical_key => $vertical_data) { $vertical_to_category[$vertical_key] = 'other'; } } uasort($categories_out, 'matewa_compare_vertical_selector_items_general_first'); return [ 'categories' => $categories_out, 'vertical_to_category' => $vertical_to_category, 'flat' => $vertical_options, ]; } } /* ========================================================== 5-A-26D BUSINESS TYPE DEFAULT / CONFIRMATION STATE ========================================================== */ if (!function_exists('matewa_maybe_reset_unconfirmed_business_type_default')) { function matewa_maybe_reset_unconfirmed_business_type_default() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page) { return; } /* * If an older test install left a remembered business type in wp_options * before the new Confirm business type flow existed, treat that selection * as unconfirmed and return the selector to General once. This keeps a * newly installed/reinstalled build from opening on the last tested trade. */ if ('' !== (string) get_option('matewa_business_type_confirmed', '')) { return; } if ('' !== (string) get_option('matewa_5a26d_default_general_repaired', '')) { return; } if (function_exists('matewa_direct_save_option_value')) { matewa_direct_save_option_value('matewa_vertical_category_selected', 'general'); matewa_direct_save_option_value('matewa_vertical_selected', 'general'); matewa_direct_save_option_value('matewa_chip_label_overrides', []); matewa_direct_save_option_value('matewa_5a26d_default_general_repaired', '1'); } else { update_option('matewa_vertical_category_selected', 'general', false); update_option('matewa_vertical_selected', 'general', false); update_option('matewa_chip_label_overrides', [], false); update_option('matewa_5a26d_default_general_repaired', '1', false); } } } add_action('admin_init', 'matewa_maybe_reset_unconfirmed_business_type_default', 5); if (!function_exists('matewa_sanitise_vertical_category_selected')) { function matewa_sanitise_vertical_category_selected($value) { $selected = matewa_safe_key($value); $catalog = matewa_get_vertical_catalog_data(); $selector_data = matewa_build_vertical_selector_data($catalog['verticals'], $catalog['categories']); $categories = is_array($selector_data['categories'] ?? null) ? $selector_data['categories'] : []; if ('' !== $selected && isset($categories[$selected])) { return $selected; } if ( '' !== $selected && function_exists('matewa_is_admin_settings_vertical_guard_context') && matewa_is_admin_settings_vertical_guard_context() ) { return $selected; } $current_saved = matewa_safe_key(get_option('matewa_vertical_category_selected', '')); if ('' !== $current_saved && isset($categories[$current_saved])) { return $current_saved; } if (isset($categories['general'])) { return 'general'; } $keys = array_keys($categories); if (!empty($keys)) { return matewa_safe_key($keys[0]); } return 'general'; } } if (!function_exists('matewa_resolve_valid_vertical_for_category')) { function matewa_resolve_valid_vertical_for_category($category_key, $vertical_key) { $category_key = matewa_safe_key($category_key); $vertical_key = matewa_safe_key($vertical_key); $catalog = matewa_get_vertical_catalog_data(); $selector_data = matewa_build_vertical_selector_data($catalog['verticals'], $catalog['categories']); $categories = is_array($selector_data['categories'] ?? null) ? $selector_data['categories'] : []; $flat = is_array($selector_data['flat'] ?? null) ? $selector_data['flat'] : []; $default = matewa_safe_key($catalog['default_vertical'] ?? 'general', 'general'); if (isset($categories[$category_key])) { $options = is_array($categories[$category_key]['options'] ?? null) ? $categories[$category_key]['options'] : []; if ('' !== $vertical_key && isset($options[$vertical_key])) { return $vertical_key; } if (isset($options['general'])) { return 'general'; } $option_keys = array_keys($options); if (!empty($option_keys)) { return matewa_safe_key($option_keys[0]); } } if ('' !== $vertical_key && isset($flat[$vertical_key])) { return $vertical_key; } if ( '' !== $vertical_key && function_exists('matewa_is_admin_settings_vertical_guard_context') && matewa_is_admin_settings_vertical_guard_context() ) { return $vertical_key; } $current_saved = matewa_safe_key(get_option('matewa_vertical_selected', '')); if ('' !== $current_saved && isset($flat[$current_saved])) { return $current_saved; } if ('' !== $default && isset($flat[$default])) { return $default; } if (isset($flat['general'])) { return 'general'; } $keys = array_keys($flat); if (!empty($keys)) { return matewa_safe_key($keys[0]); } return 'general'; } } if (!function_exists('matewa_sanitise_vertical_selected')) { function matewa_sanitise_vertical_selected($value) { $selected = matewa_safe_key($value); $posted_category = isset($_POST['matewa_vertical_category_selected']) ? matewa_safe_key(sanitize_key(wp_unslash($_POST['matewa_vertical_category_selected']))) : ''; $saved_category = matewa_safe_key(get_option('matewa_vertical_category_selected', '')); $category_key = '' !== $posted_category ? $posted_category : $saved_category; return matewa_resolve_valid_vertical_for_category($category_key, $selected); } } if (!function_exists('matewa_sync_vertical_category_after_save')) { function matewa_sync_vertical_category_after_save($old_value, $value, $option) { if ('matewa_vertical_selected' !== matewa_safe_scalar_text($option)) { return; } static $matewa_vertical_category_sync_running = false; if ($matewa_vertical_category_sync_running) { return; } $matewa_vertical_category_sync_running = true; $value = matewa_safe_key($value); $catalog = matewa_get_vertical_catalog_data(); $selector_data = matewa_build_vertical_selector_data($catalog['verticals'], $catalog['categories']); $vertical_to_category = is_array($selector_data['vertical_to_category'] ?? null) ? $selector_data['vertical_to_category'] : []; if ('' !== $value && isset($vertical_to_category[$value])) { $new_category = matewa_safe_key($vertical_to_category[$value]); $current_category = matewa_safe_key(get_option('matewa_vertical_category_selected', '')); if ('' !== $new_category && $current_category !== $new_category) { update_option('matewa_vertical_category_selected', $new_category, false); } } $matewa_vertical_category_sync_running = false; } } add_action('updated_option', 'matewa_sync_vertical_category_after_save', 10, 3); if (!function_exists('matewa_get_default_chip_label_for_intent')) { function matewa_get_default_chip_label_for_intent($intent_key) { $intent_key = trim((string) $intent_key); if ('' === $intent_key) { return ''; } if (function_exists('matewa_catalog_resolve_intent_label')) { $label = (string) matewa_catalog_resolve_intent_label($intent_key); if ('' !== trim($label)) { return $label; } } if (function_exists('matewa_get_i18n_label')) { $label = (string) matewa_get_i18n_label($intent_key); if ('' !== trim($label) && $label !== $intent_key) { return $label; } } return ucwords(str_replace(['intent.', '.'], ['', ' '], $intent_key)); } } if (!function_exists('matewa_get_current_chip_editor_vertical_key')) { function matewa_get_current_chip_editor_vertical_key() { if (function_exists('matewa_get_active_vertical_key')) { return matewa_safe_key(matewa_get_active_vertical_key(), 'general'); } $selected = matewa_safe_key(get_option('matewa_vertical_selected', ''), 'general'); return '' !== $selected ? $selected : 'general'; } } if (!function_exists('matewa_get_current_chip_editor_map')) { function matewa_get_current_chip_editor_map() { $vertical_key = function_exists('matewa_get_active_vertical_key') ? matewa_safe_key(matewa_get_active_vertical_key(), 'general') : 'general'; $vertical = function_exists('matewa_get_active_vertical') ? (array) matewa_get_active_vertical() : []; $chip_keys = is_array($vertical['chips'] ?? null) ? array_values($vertical['chips']) : []; if (empty($chip_keys)) { $chip_keys = ['intent.other']; } $resolved_labels = function_exists('matewa_get_vertical_chip_labels') ? (array) matewa_get_vertical_chip_labels($vertical_key) : []; $items = []; foreach ($chip_keys as $index => $intent_key) { $intent_key = trim((string) $intent_key); if ('' === $intent_key) { continue; } $default_label = isset($resolved_labels[$index]) && '' !== trim((string) $resolved_labels[$index]) ? (string) $resolved_labels[$index] : ( function_exists('matewa_catalog_resolve_intent_label') ? (string) matewa_catalog_resolve_intent_label($intent_key) : ucwords(str_replace(['intent.', '.'], ['', ' '], $intent_key)) ); $items[] = [ 'position' => (int) $index + 1, 'intent_key' => $intent_key, 'default_label' => $default_label, 'is_other' => ('intent.other' === $intent_key), ]; } return $items; } } if (!function_exists('matewa_get_chip_items_for_vertical_key')) { function matewa_get_chip_items_for_vertical_key($vertical_key) { $vertical_key = matewa_safe_key($vertical_key); $catalog = matewa_get_vertical_catalog_data(); $verticals = is_array($catalog['verticals'] ?? null) ? $catalog['verticals'] : []; $vertical_config = isset($verticals[$vertical_key]) && is_array($verticals[$vertical_key]) ? $verticals[$vertical_key] : []; $chip_keys = is_array($vertical_config['chips'] ?? null) ? array_values($vertical_config['chips']) : []; if (empty($chip_keys)) { $chip_keys = ['intent.other']; } $resolved_labels = function_exists('matewa_get_vertical_chip_labels') ? (array) matewa_get_vertical_chip_labels($vertical_key) : []; $items = []; foreach ($chip_keys as $index => $intent_key) { $intent_key = trim((string) $intent_key); if ('' === $intent_key) { continue; } $default_label = isset($resolved_labels[$index]) && '' !== trim((string) $resolved_labels[$index]) ? (string) $resolved_labels[$index] : ( function_exists('matewa_catalog_resolve_intent_label') ? (string) matewa_catalog_resolve_intent_label($intent_key) : ucwords(str_replace(['intent.', '.'], ['', ' '], $intent_key)) ); $items[] = [ 'position' => (int) $index + 1, 'intent_key' => $intent_key, 'default_label' => $default_label, 'is_other' => ('intent.other' === $intent_key), ]; } return $items; } } /* ========================================================== OPTION AUTOLOAD STABILISER (NARROW RECOVERY PASS) ========================================================== */ if (!function_exists('matewa_stabilise_admin_option_autoload_flags')) { function matewa_stabilise_admin_option_autoload_flags() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page) { return; } global $wpdb; if (!isset($wpdb->options)) { return; } // Keep 247ChatMate settings out of the alloptions autoload blob. // This does not change option values; it only prevents small settings saves // from forcing WordPress to rebuild a large autoload cache. $wpdb->query( "UPDATE {$wpdb->options} SET autoload = 'no' WHERE option_name LIKE 'matewa\\_%' OR option_name LIKE '\\_transient\\_matewa\\_%' OR option_name LIKE '\\_transient\\_timeout\\_matewa\\_%'" ); } } add_action('admin_init', 'matewa_stabilise_admin_option_autoload_flags', 0); /* ========================================================== REGISTER SETTINGS (EARLY + SAFE) ========================================================== */ add_action('admin_init', function () { register_setting('matewa_settings', 'matewa_number', [ 'type' => 'string', 'sanitize_callback' => function ($v) { return preg_replace('/[^0-9\+]/', '', (string) $v); }, 'default' => '' ]); register_setting('matewa_settings', 'matewa_business_name', [ 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ]); register_setting('matewa_settings', 'matewa_marketing_email', [ 'type' => 'string', 'sanitize_callback' => 'sanitize_email', 'default' => '' ]); register_setting('matewa_settings', 'matewa_leads_email', [ 'type' => 'string', 'sanitize_callback' => 'sanitize_email', 'default' => '' ]); register_setting('matewa_settings', 'matewa_industry', [ 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ]); register_setting('matewa_settings', 'matewa_email_profile_normal', [ 'type' => 'array', 'sanitize_callback' => function ($v) { return function_exists('matewa_email_profile_sanitise') ? matewa_email_profile_sanitise('normal', is_array($v) ? $v : []) : (is_array($v) ? $v : []); }, 'default' => [] ]); register_setting('matewa_settings', 'matewa_email_profile_agency', [ 'type' => 'array', 'sanitize_callback' => function ($v) { return function_exists('matewa_email_profile_sanitise') ? matewa_email_profile_sanitise('agency', is_array($v) ? $v : []) : (is_array($v) ? $v : []); }, 'default' => [] ]); register_setting('matewa_settings', 'matewa_client_mail_delivery_options', [ 'type' => 'array', 'sanitize_callback' => function ($v) { return function_exists('matewa_client_mail_delivery_sanitise_for_save') ? matewa_client_mail_delivery_sanitise_for_save(is_array($v) ? $v : []) : (is_array($v) ? $v : []); }, 'default' => [] ]); register_setting('matewa_settings', 'matewa_license_key', [ 'type' => 'string', 'sanitize_callback' => function ($v) { return sanitize_text_field((string) $v); }, 'default' => '' ]); register_setting('matewa_settings', 'matewa_vertical_category_selected', [ 'type' => 'string', 'sanitize_callback' => 'matewa_sanitise_vertical_category_selected', 'default' => 'general' ]); register_setting('matewa_settings', 'matewa_vertical_selected', [ 'type' => 'string', 'sanitize_callback' => 'matewa_sanitise_vertical_selected', 'default' => 'general' ]); register_setting('matewa_settings', 'matewa_lead_language_mode', [ 'type' => 'string', 'sanitize_callback' => function ($v) { return 'english'; }, 'default' => 'english' ]); register_setting('matewa_settings', 'matewa_lang_switch', [ 'type' => 'string', 'sanitize_callback' => function ($v) { return 'yes'; }, 'default' => 'yes' ]); register_setting('matewa_settings', 'matewa_widget_settings', [ 'type' => 'array', 'sanitize_callback' => function ($v) { $v = is_array($v) ? $v : []; $display_mode = function_exists('matewa_normalise_widget_display_mode') ? matewa_normalise_widget_display_mode($v['display_mode'] ?? 'all') : sanitize_key((string) ($v['display_mode'] ?? 'all')); if (!in_array($display_mode, ['all', 'selected', 'excluded', 'homepage'], true)) { $display_mode = 'all'; } $page_ids = function_exists('matewa_normalise_widget_page_ids') ? matewa_normalise_widget_page_ids($v['page_ids'] ?? []) : array_values(array_unique(array_filter(array_map('absint', (array) ($v['page_ids'] ?? []))))); $include_homepage = !empty($v['include_homepage']) ? '1' : '0'; if ('homepage' === $display_mode) { $display_mode = 'selected'; $include_homepage = '1'; } return [ 'enabled' => !empty($v['enabled']) ? '1' : '0', 'display_mode' => $display_mode, 'page_ids' => $page_ids, 'include_homepage' => $include_homepage, 'show_country_selector' => array_key_exists('show_country_selector', $v) ? (!empty($v['show_country_selector']) ? '1' : '0') : '1', 'show_language_selector' => array_key_exists('show_language_selector', $v) ? (!empty($v['show_language_selector']) ? '1' : '0') : '1', 'default_language' => isset($v['default_language']) ? sanitize_text_field((string) $v['default_language']) : 'auto', 'visible_languages' => isset($v['visible_languages']) ? matewa_sanitise_language_code_list($v['visible_languages']) : '', ]; }, 'default' => [ 'enabled' => '1', 'display_mode' => 'all', 'page_ids' => [], 'include_homepage' => '0', 'show_country_selector' => '1', 'show_language_selector' => '1', 'default_language' => 'auto', 'visible_languages' => '', ] ]); register_setting('matewa_settings', 'matewa_chip_label_overrides', [ 'type' => 'array', 'sanitize_callback' => 'matewa_sanitise_chip_label_overrides', 'default' => [] ]); }, 0); /* ========================================================== ADMIN RETURN SECTION HELPERS (PHASE 5-A-12G) ========================================================== */ if (!function_exists('matewa_admin_return_section_map')) { function matewa_admin_return_section_map() { return [ 'dashboard' => '#matewa-dashboard-top', 'setup' => '#matewa-core-settings-section', 'agency' => '#matewa-agency-hub-section', 'display' => '#matewa-display-settings-section', 'buttons' => '#matewa-chip-labels-section', ]; } } if (!function_exists('matewa_admin_sanitise_return_section')) { function matewa_admin_sanitise_return_section($value, $fallback = 'dashboard') { $section = sanitize_key((string) $value); $map = matewa_admin_return_section_map(); if (isset($map[$section])) { return $section; } $fallback = sanitize_key((string) $fallback); return isset($map[$fallback]) ? $fallback : 'dashboard'; } } if (!function_exists('matewa_admin_get_posted_return_section')) { function matewa_admin_get_posted_return_section($fallback = 'setup') { $posted = isset($_POST['matewa_return_section']) ? sanitize_key(wp_unslash($_POST['matewa_return_section'])) : ''; return matewa_admin_sanitise_return_section($posted, $fallback); } } if (!function_exists('matewa_admin_redirect_url')) { function matewa_admin_redirect_url(array $args = [], $return_section = 'dashboard') { $section = matewa_admin_sanitise_return_section($return_section, 'dashboard'); $map = matewa_admin_return_section_map(); $anchor = isset($map[$section]) ? (string) $map[$section] : '#matewa-dashboard-top'; $args = array_merge(['page' => '247chatmate'], $args); $url = add_query_arg($args, admin_url('admin.php')); return $url . $anchor; } } /* ========================================================== DIRECT SETTINGS SAVE HANDLER (RECOVERY PASS) ========================================================== */ if (!function_exists('matewa_direct_save_option_value')) { function matewa_direct_save_option_value($option_name, $value) { global $wpdb; $option_name = sanitize_key((string) $option_name); if ('' === $option_name || !isset($wpdb->options)) { return false; } $serialized_value = maybe_serialize($value); $exists = $wpdb->get_var( $wpdb->prepare( "SELECT option_id FROM {$wpdb->options} WHERE option_name = %s LIMIT 1", $option_name ) ); if (null === $exists) { $result = $wpdb->insert( $wpdb->options, [ 'option_name' => $option_name, 'option_value' => $serialized_value, 'autoload' => 'no', ], ['%s', '%s', '%s'] ); } else { $result = $wpdb->update( $wpdb->options, [ 'option_value' => $serialized_value, 'autoload' => 'no', ], ['option_name' => $option_name], ['%s', '%s'], ['%s'] ); } wp_cache_delete($option_name, 'options'); wp_cache_delete('alloptions', 'options'); wp_cache_delete('notoptions', 'options'); return false !== $result; } } if (!function_exists('matewa_get_posted_chip_editor_loaded_vertical')) { function matewa_get_posted_chip_editor_loaded_vertical($post) { if (!is_array($post) || !isset($post['matewa_chip_editor_loaded_vertical'])) { return ''; } return matewa_safe_key($post['matewa_chip_editor_loaded_vertical']); } } if (!function_exists('matewa_filter_chip_overrides_for_selected_vertical')) { function matewa_filter_chip_overrides_for_selected_vertical($posted_overrides, $selected_vertical, $editor_loaded_vertical = '') { $selected_vertical = matewa_safe_key($selected_vertical); $editor_loaded_vertical = matewa_safe_key($editor_loaded_vertical); $posted_overrides = is_array($posted_overrides) ? $posted_overrides : []; if ('' === $selected_vertical) { return []; } /* * When the business type/category has changed, the visible textarea fields * still belong to the previously loaded editor. Ignore those stale labels * so General/custom test values cannot be merged into the wrong setup. */ if ('' !== $editor_loaded_vertical && $editor_loaded_vertical !== $selected_vertical) { return []; } if (!isset($posted_overrides[$selected_vertical]) || !is_array($posted_overrides[$selected_vertical])) { return []; } return [ $selected_vertical => $posted_overrides[$selected_vertical], ]; } } if (!function_exists('matewa_handle_direct_settings_save')) { function matewa_handle_direct_settings_save() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page || empty($_POST['matewa_direct_settings_save'])) { return; } check_admin_referer('matewa_direct_settings_save', 'matewa_direct_settings_nonce'); $post = wp_unslash($_POST); $number = isset($post['matewa_number']) ? preg_replace('/[^0-9\+]/', '', (string) $post['matewa_number']) : (string) get_option('matewa_number', ''); $business = isset($post['matewa_business_name']) ? sanitize_text_field((string) $post['matewa_business_name']) : (string) get_option('matewa_business_name', ''); $marketing_email = isset($post['matewa_marketing_email']) ? sanitize_email((string) $post['matewa_marketing_email']) : (string) get_option('matewa_marketing_email', ''); $leads_email = isset($post['matewa_leads_email']) ? sanitize_email((string) $post['matewa_leads_email']) : (string) get_option('matewa_leads_email', ''); $industry = isset($post['matewa_industry']) ? sanitize_text_field((string) $post['matewa_industry']) : (string) get_option('matewa_industry', ''); $previous_license_key = (string) get_option('matewa_license_key', ''); $posted_license_key = isset($post['matewa_license_key']) ? trim(sanitize_text_field((string) $post['matewa_license_key'])) : ''; $license_key = '' !== $posted_license_key ? $posted_license_key : $previous_license_key; $save_and_refresh_license = !empty($post['matewa_save_and_refresh_license']); $previous_vertical_category = matewa_safe_key(get_option('matewa_vertical_category_selected', 'general'), 'general'); $previous_vertical_selected = matewa_safe_key(get_option('matewa_vertical_selected', 'general'), 'general'); $vertical_category = isset($post['matewa_vertical_category_selected']) ? matewa_safe_key($post['matewa_vertical_category_selected'], 'general') : $previous_vertical_category; $vertical_selected = isset($post['matewa_vertical_selected']) ? matewa_safe_key($post['matewa_vertical_selected'], 'general') : $previous_vertical_selected; if ('' === $vertical_category) { $vertical_category = 'general'; } if ('' === $vertical_selected) { $vertical_selected = 'general'; } $editor_loaded_vertical = matewa_get_posted_chip_editor_loaded_vertical($post); $chip_context_changed = ( $previous_vertical_category !== $vertical_category || $previous_vertical_selected !== $vertical_selected || ('' !== $editor_loaded_vertical && $editor_loaded_vertical !== $vertical_selected) ); $widget_post = isset($post['matewa_widget_settings']) && is_array($post['matewa_widget_settings']) ? $post['matewa_widget_settings'] : []; $display_mode = function_exists('matewa_normalise_widget_display_mode') ? matewa_normalise_widget_display_mode($widget_post['display_mode'] ?? 'all') : sanitize_key((string) ($widget_post['display_mode'] ?? 'all')); if (!in_array($display_mode, ['all', 'selected', 'excluded', 'homepage'], true)) { $display_mode = 'all'; } $page_ids = function_exists('matewa_normalise_widget_page_ids') ? matewa_normalise_widget_page_ids($widget_post['page_ids'] ?? []) : array_values(array_unique(array_filter(array_map('absint', (array) ($widget_post['page_ids'] ?? []))))); $include_homepage = !empty($widget_post['include_homepage']) ? '1' : '0'; if ('homepage' === $display_mode) { $display_mode = 'selected'; $include_homepage = '1'; } // Free / expired trial always runs sitewide. Page targeting is Pro. $effective_mode_for_save = function_exists('matewa_get_mode') ? matewa_get_mode() : 'free'; if (in_array($effective_mode_for_save, ['free', 'trial_expired'], true)) { $display_mode = 'all'; $page_ids = []; $include_homepage = '0'; } $widget_settings = [ 'enabled' => !empty($widget_post['enabled']) ? '1' : '0', 'display_mode' => $display_mode, 'page_ids' => $page_ids, 'include_homepage' => $include_homepage, 'show_country_selector' => array_key_exists('show_country_selector', $widget_post) ? (!empty($widget_post['show_country_selector']) ? '1' : '0') : '1', 'show_language_selector' => array_key_exists('show_language_selector', $widget_post) ? (!empty($widget_post['show_language_selector']) ? '1' : '0') : '1', 'default_language' => isset($widget_post['default_language']) ? sanitize_text_field((string) $widget_post['default_language']) : 'auto', 'visible_languages' => isset($widget_post['visible_languages']) ? matewa_sanitise_language_code_list($widget_post['visible_languages']) : '', ]; matewa_direct_save_option_value('matewa_number', $number); matewa_direct_save_option_value('matewa_business_name', $business); matewa_direct_save_option_value('matewa_marketing_email', $marketing_email); matewa_direct_save_option_value('matewa_leads_email', $leads_email); matewa_direct_save_option_value('matewa_industry', $industry); if (isset($post['matewa_email_profile_normal']) && function_exists('matewa_email_profile_save')) { matewa_email_profile_save('normal', is_array($post['matewa_email_profile_normal']) ? $post['matewa_email_profile_normal'] : []); } if (isset($post['matewa_client_mail_delivery']) && function_exists('matewa_client_mail_delivery_save_from_post')) { matewa_client_mail_delivery_save_from_post(is_array($post['matewa_client_mail_delivery']) ? $post['matewa_client_mail_delivery'] : []); } if (function_exists('matewa_clear_paid_license_validation_state')) { matewa_clear_paid_license_validation_state($previous_license_key, $license_key); } if (function_exists('matewa_clear_founder_beta_validation_state')) { matewa_clear_founder_beta_validation_state($previous_license_key, $license_key); } if (function_exists('matewa_clear_agency_registry_validation_state')) { matewa_clear_agency_registry_validation_state($previous_license_key, $license_key); } matewa_direct_save_option_value('matewa_license_key', $license_key); // LICENCEAGENCYEXITFIX1: // Replacing/entering a standalone key is an explicit move away from an // imported agency-client seat. Clear that old entitlement so it cannot // reappear later and leave the dashboard in a mixed Free/Agency state. if ('' !== $posted_license_key && function_exists('matewa_agency_client_entitlement_clear')) { matewa_agency_client_entitlement_clear(); } matewa_direct_save_option_value('matewa_vertical_category_selected', $vertical_category); matewa_direct_save_option_value('matewa_vertical_selected', $vertical_selected); if (!empty($post['matewa_business_type_confirmed'])) { matewa_direct_save_option_value('matewa_business_type_confirmed', '1'); } matewa_direct_save_option_value('matewa_lead_language_mode', 'english'); matewa_direct_save_option_value('matewa_lang_switch', 'yes'); matewa_direct_save_option_value('matewa_widget_settings', $widget_settings); if (array_key_exists('matewa_agency_admin_email', $post)) { $agency_admin_email = sanitize_email((string) wp_unslash($post['matewa_agency_admin_email'])); matewa_direct_save_option_value('matewa_agency_admin_email', is_email($agency_admin_email) ? $agency_admin_email : ''); } if (array_key_exists('matewa_agency_roundup_email', $post)) { $agency_roundup_email = sanitize_email((string) wp_unslash($post['matewa_agency_roundup_email'])); matewa_direct_save_option_value('matewa_agency_roundup_email', is_email($agency_roundup_email) ? $agency_roundup_email : ''); } if (isset($post['matewa_email_profile_agency']) && function_exists('matewa_email_profile_save')) { matewa_email_profile_save('agency', is_array($post['matewa_email_profile_agency']) ? $post['matewa_email_profile_agency'] : []); } $founder_beta_save_notice = ''; $agency_access_save_notice = ''; $agency_bundle_notice = ''; $agency_client_pack_notice = ''; $agency_bundle_action = isset($post['matewa_agency_bundle_action']) ? sanitize_key((string) $post['matewa_agency_bundle_action']) : ''; $agency_client_pack_action = isset($post['matewa_agency_client_pack_action']) ? sanitize_key((string) $post['matewa_agency_client_pack_action']) : ''; $agency_setup_request_action = isset($post['matewa_agency_setup_request_action']) ? sanitize_key((string) $post['matewa_agency_setup_request_action']) : ''; $agency_routing_action = isset($post['matewa_agency_routing_action']) ? sanitize_key((string) $post['matewa_agency_routing_action']) : ''; if ('' === $agency_client_pack_action && isset($post['matewa_agency_client_pack_delete_id'])) { $agency_client_pack_action = 'delete'; } $license_key_is_founder_beta = function_exists('matewa_founder_beta_is_access_code') ? matewa_founder_beta_is_access_code($license_key) : (0 === strpos(strtoupper(trim((string) $license_key)), 'FBETA-')); $license_key_is_agency_access = function_exists('matewa_agency_registry_is_access_code') ? matewa_agency_registry_is_access_code($license_key) : (0 === strpos(strtoupper(trim((string) $license_key)), 'AGENCY-')); if ($license_key_is_agency_access && function_exists('matewa_agency_registry_validate_access')) { $agency_already_active = function_exists('matewa_agency_own_site_access_is_active') ? matewa_agency_own_site_access_is_active() : false; if (!$agency_already_active) { $agency_access_save_result = matewa_agency_registry_validate_access($license_key); if (is_array($agency_access_save_result)) { $agency_access_save_notice = sanitize_key((string) ($agency_access_save_result['code'] ?? ($agency_access_save_result['message'] ?? 'unknown'))); } } } if (!$license_key_is_agency_access && $license_key_is_founder_beta && function_exists('matewa_founder_beta_register_activation')) { $founder_beta_already_active = function_exists('matewa_founder_beta_is_active') ? matewa_founder_beta_is_active() : false; if (!$founder_beta_already_active) { $founder_beta_save_result = matewa_founder_beta_register_activation($license_key); if (is_array($founder_beta_save_result)) { $founder_beta_save_notice = sanitize_key((string) ($founder_beta_save_result['code'] ?? ($founder_beta_save_result['message'] ?? 'unknown'))); } } } if ('' !== $agency_bundle_action && function_exists('matewa_agency_bundle_handle_admin_action')) { $agency_bundle_result = matewa_agency_bundle_handle_admin_action($post); if (is_array($agency_bundle_result)) { $agency_bundle_notice = sanitize_key((string) ($agency_bundle_result['code'] ?? 'unknown')); } } if ('' !== $agency_client_pack_action && function_exists('matewa_agency_client_pack_handle_admin_action')) { $agency_client_pack_result = matewa_agency_client_pack_handle_admin_action($post); if (is_array($agency_client_pack_result)) { $agency_client_pack_notice = sanitize_key((string) ($agency_client_pack_result['code'] ?? 'unknown')); } } $agency_routing_notice = ''; if ('clear_last_test' === $agency_routing_action) { delete_option('matewa_agency_last_routing_send'); $agency_routing_notice = 'agency_routing_cleared'; } if ('send_roundup_now' === $agency_routing_action) { $agency_admin_target_email = isset($post['matewa_agency_admin_email']) ? sanitize_email((string) wp_unslash($post['matewa_agency_admin_email'])) : sanitize_email((string) get_option('matewa_agency_admin_email', '')); $agency_roundup_target_email = isset($post['matewa_agency_roundup_email']) ? sanitize_email((string) wp_unslash($post['matewa_agency_roundup_email'])) : sanitize_email((string) get_option('matewa_agency_roundup_email', '')); $agency_routing_routes = array(); if (is_email($agency_admin_target_email)) { $agency_routing_routes[] = array( 'role' => 'admin', 'label' => 'Agency admin inbox', 'email' => $agency_admin_target_email, 'subject' => '247ChatMate agency admin inbox test', 'title' => 'Agency admin inbox test', ); } if (is_email($agency_roundup_target_email)) { $agency_routing_routes[] = array( 'role' => 'roundup', 'label' => 'Agency roundup inbox', 'email' => $agency_roundup_target_email, 'subject' => '247ChatMate agency roundup inbox test', 'title' => 'Agency roundup inbox test', ); } if (empty($agency_routing_routes)) { $agency_routing_notice = 'agency_routing_missing_email'; update_option('matewa_agency_last_routing_send', array( 'time' => time(), 'notice' => $agency_routing_notice, 'results'=> array(), ), false); } else { $agency_display_name = '' !== trim((string) get_option('matewa_business_name', '')) ? sanitize_text_field((string) get_option('matewa_business_name', '')) : 'your agency'; $matewa_agency_routing_test_id = 'AGENCY-' . wp_date('Ymd-His') . '-' . strtoupper(wp_generate_password(4, false, false)); $routing_intro_base = 'This confirms the 247ChatMate Agency Hub can send to the saved agency routing inbox. Test ID: ' . $matewa_agency_routing_test_id . '.'; $routing_footer = 'Weekly scheduled agency roundups remain parked until the later locked email automation checkpoint.'; $reply_to_email = is_email($agency_admin_target_email) ? $agency_admin_target_email : get_option('admin_email'); $agency_routing_results = array(); $sent_to_admin = false; $sent_to_roundup = false; foreach ($agency_routing_routes as $route) { $routing_rows = array( 'Agency' => esc_html($agency_display_name), 'Test ID' => esc_html($matewa_agency_routing_test_id), 'Route tested' => esc_html($route['label']), 'Recipient' => '' . esc_html($route['email']) . '', 'Agency admin inbox' => is_email($agency_admin_target_email) ? '' . esc_html($agency_admin_target_email) . '' : 'Not set', 'Agency roundup inbox' => is_email($agency_roundup_target_email) ? '' . esc_html($agency_roundup_target_email) . '' : 'Not set', 'Send type' => 'Manual Send now test only', ); $message = matewa_agency_wrap_html_email( $route['title'], $routing_intro_base, $routing_rows, $routing_footer ); $plain_message = matewa_agency_build_plain_email($route['title'], $routing_intro_base, $routing_rows, $routing_footer); $route_subject = sanitize_text_field((string) $route['subject'] . ' - ' . $matewa_agency_routing_test_id); $send_result = function_exists('matewa_agency_send_branded_email_result') ? matewa_agency_send_branded_email_result($route['email'], $route_subject, $message, $reply_to_email, $plain_message) : array('sent' => matewa_agency_send_branded_email($route['email'], $route_subject, $message, $reply_to_email, $plain_message), 'method' => 'legacy', 'error' => ''); $route_sent = !empty($send_result['sent']); if ('admin' === $route['role']) { $sent_to_admin = $route_sent; } if ('roundup' === $route['role']) { $sent_to_roundup = $route_sent; } $agency_routing_results[] = array( 'role' => sanitize_key((string) $route['role']), 'label' => sanitize_text_field((string) $route['label']), 'email' => sanitize_email((string) $route['email']), 'sent' => $route_sent ? 1 : 0, 'method' => isset($send_result['method']) ? sanitize_key((string) $send_result['method']) : '', 'error' => isset($send_result['error']) ? sanitize_text_field((string) $send_result['error']) : '', ); } if ($sent_to_admin && $sent_to_roundup) { $agency_routing_notice = 'agency_routing_sent_both'; } elseif ($sent_to_admin) { $agency_routing_notice = 'agency_routing_sent_admin'; } elseif ($sent_to_roundup) { $agency_routing_notice = 'agency_routing_sent_roundup'; } else { $agency_routing_notice = 'agency_routing_failed'; } update_option('matewa_agency_last_routing_send', array( 'time' => time(), 'notice' => $agency_routing_notice, 'admin_email' => $agency_admin_target_email, 'roundup_email' => $agency_roundup_target_email, 'test_id' => $matewa_agency_routing_test_id, 'results' => $agency_routing_results, ), false); } } $agency_setup_request_notice = ''; $agency_setup_request_client_name = isset($post['matewa_setup_request_client_name']) ? sanitize_text_field((string) wp_unslash($post['matewa_setup_request_client_name'])) : ''; $agency_setup_request_client_email = isset($post['matewa_setup_request_client_email']) ? sanitize_email((string) wp_unslash($post['matewa_setup_request_client_email'])) : ''; $agency_setup_request_client_domain = isset($post['matewa_setup_request_client_domain']) ? sanitize_text_field((string) wp_unslash($post['matewa_setup_request_client_domain'])) : ''; if ('send_request' === $agency_setup_request_action) { if (!is_email($agency_setup_request_client_email)) { $agency_setup_request_notice = 'setup_request_missing_email'; } else { $agency_display_name = '' !== trim((string) get_option('matewa_business_name', '')) ? sanitize_text_field((string) get_option('matewa_business_name', '')) : 'your agency'; $subject_client_name = '' !== $agency_setup_request_client_name ? $agency_setup_request_client_name : 'your business'; $subject = sprintf('247ChatMate setup details needed for %s', $subject_client_name); $greeting_name = '' !== $agency_setup_request_client_name ? esc_html($agency_setup_request_client_name) : ''; $domain_text = '' !== $agency_setup_request_client_domain ? ' for ' . esc_html($agency_setup_request_client_domain) . '' : ''; $request_intro = 'Hi' . ('' !== $greeting_name ? ' ' . $greeting_name : '') . ',

'; $request_intro .= 'We are setting up your 247ChatMate WhatsApp lead capture on your website' . $domain_text . '. Please reply with the details below so we can prepare your setup pack.'; $setup_rows = array( '1. Business name' => 'Your trading/business name', '2. Website/domain' => 'Your website domain', '3. WhatsApp mobile/cell number' => 'Mobile/cell number for customer enquiries', '4. Main admin email' => 'Main admin/contact inbox', '5. Leads email' => 'Inbox for enquiry alerts', '6. Website pages' => 'Where the widget should appear', '7. Business type/category' => 'The closest service category', '8. Visitor buttons' => 'Preferred buttons or common customer questions', '9. Review/social links' => 'Google Business Profile, Instagram or review links you want included later', ); $setup_footer = 'Once we have this, we will create your client setup pack and confirm anything unclear before installation.

Agency: ' . esc_html($agency_display_name); $message = matewa_agency_wrap_html_email( '247ChatMate setup details needed', $request_intro, $setup_rows, $setup_footer ); $agency_admin_reply_to = sanitize_email((string) get_option('matewa_agency_admin_email', '')); $plain_message = matewa_agency_build_plain_email('247ChatMate setup details needed', $request_intro, $setup_rows, $setup_footer); $sent = matewa_agency_send_branded_email( $agency_setup_request_client_email, $subject, $message, is_email($agency_admin_reply_to) ? $agency_admin_reply_to : get_option('admin_email'), $plain_message ); $agency_setup_request_notice = $sent ? 'setup_request_sent' : 'setup_request_failed'; } } if ($chip_context_changed) { /* * 5-A-14J: Changing category/business type must return every altered * chip JSON/label override back to the selected vertical defaults. * Do not carry General, previous business type, or older edited labels * into the newly selected set. */ matewa_direct_save_option_value('matewa_chip_label_overrides', []); } elseif (isset($post['matewa_chip_label_overrides']) && is_array($post['matewa_chip_label_overrides'])) { $posted_overrides = matewa_sanitise_chip_label_overrides($post['matewa_chip_label_overrides']); $posted_overrides = matewa_filter_chip_overrides_for_selected_vertical( $posted_overrides, $vertical_selected, $editor_loaded_vertical ); $next_overrides = []; foreach ($posted_overrides as $vertical_key => $labels) { if (is_array($labels) && !empty($labels)) { $next_overrides[$vertical_key] = $labels; } } matewa_direct_save_option_value('matewa_chip_label_overrides', $next_overrides); } $direct_trial_start_result = []; if ( function_exists('matewa_distribution_has_pro_trial') && matewa_distribution_has_pro_trial() && '' === trim((string) $license_key) && is_email($marketing_email) && '' !== preg_replace('/[^0-9]/', '', (string) $number) && (!function_exists('matewa_trial_has_started') || !matewa_trial_has_started()) && function_exists('matewa_start_trial_if_allowed') ) { $direct_trial_start_result = matewa_start_trial_if_allowed(); } $return_section = matewa_admin_get_posted_return_section('setup'); $redirect_args = [ 'matewa_settings_saved' => '1', 'matewa_saved_section' => $return_section, ]; if (!empty($direct_trial_start_result) && !empty($direct_trial_start_result['code'])) { $redirect_args['matewa_trial_notice'] = sanitize_key((string) $direct_trial_start_result['code']); } if ('' !== $agency_routing_notice) { $redirect_args['matewa_agency_routing_notice'] = $agency_routing_notice; $return_section = 'agency'; } elseif ('' !== $agency_setup_request_notice) { $redirect_args['matewa_agency_setup_request_notice'] = $agency_setup_request_notice; if ('' !== $agency_setup_request_client_name) { $redirect_args['matewa_setup_request_client_name'] = $agency_setup_request_client_name; } if ('' !== $agency_setup_request_client_email) { $redirect_args['matewa_setup_request_client_email'] = $agency_setup_request_client_email; } if ('' !== $agency_setup_request_client_domain) { $redirect_args['matewa_setup_request_client_domain'] = $agency_setup_request_client_domain; } $return_section = 'agency'; } elseif ('' !== $agency_client_pack_notice) { $redirect_args['matewa_agency_client_pack_notice'] = $agency_client_pack_notice; $return_section = 'agency'; } elseif ('' !== $agency_bundle_notice) { $redirect_args['matewa_agency_bundle_notice'] = $agency_bundle_notice; $return_section = 'agency'; } elseif ($save_and_refresh_license) { $return_section = 'setup'; if ('' === trim((string) $license_key)) { $redirect_args['matewa_license_notice'] = 'missing_key'; } elseif ($license_key_is_agency_access) { if ('' !== $agency_access_save_notice) { $redirect_args['matewa_agency_notice'] = $agency_access_save_notice; } elseif (function_exists('matewa_agency_registry_validate_access')) { $agency_access_refresh_result = matewa_agency_registry_validate_access($license_key); $redirect_args['matewa_agency_notice'] = sanitize_key((string) ($agency_access_refresh_result['code'] ?? ($agency_access_refresh_result['message'] ?? 'unknown'))); } else { $redirect_args['matewa_agency_notice'] = 'missing_handler'; } } elseif ($license_key_is_founder_beta) { if ('' !== $founder_beta_save_notice) { $redirect_args['matewa_founder_beta_notice'] = $founder_beta_save_notice; } elseif (function_exists('matewa_founder_beta_register_activation')) { $founder_beta_refresh_result = matewa_founder_beta_register_activation($license_key); $redirect_args['matewa_founder_beta_notice'] = sanitize_key((string) ($founder_beta_refresh_result['code'] ?? ($founder_beta_refresh_result['message'] ?? 'unknown'))); } else { $redirect_args['matewa_founder_beta_notice'] = 'missing_handler'; } } elseif (function_exists('matewa_get_license_validation_result')) { $license_refresh_result = matewa_get_license_validation_result($license_key, true); $redirect_args['matewa_license_notice'] = sanitize_key((string) ($license_refresh_result['code'] ?? 'unknown')); } else { $redirect_args['matewa_license_notice'] = 'missing_handler'; } } elseif ('' !== $agency_access_save_notice) { $redirect_args['matewa_agency_notice'] = $agency_access_save_notice; $return_section = 'setup'; } elseif ('' !== $founder_beta_save_notice) { $redirect_args['matewa_founder_beta_notice'] = $founder_beta_save_notice; $return_section = 'plan'; } $matewa_redirect_url = matewa_admin_redirect_url( $redirect_args, $return_section ); if ('delete' === $agency_client_pack_action && '' !== $agency_client_pack_notice) { /* * Agency Hub client-pack delete should return to the client packs area. * Do not rely on the posted return section here because row actions can be * submitted while the hidden panel value is stale after browser restore/cache. */ $redirect_args['matewa_saved_section'] = 'agency'; $matewa_redirect_url = add_query_arg($redirect_args, admin_url('admin.php')) . '#matewa-agency-client-packs'; } wp_safe_redirect($matewa_redirect_url); exit; } } add_action('admin_init', 'matewa_handle_direct_settings_save', 1); /* ========================================================== DASHBOARD LEAD HISTORY EXPORT / RESET CONTROLS (PHASE 5-A-14F) ========================================================== */ if (!function_exists('matewa_lead_history_current_month_key')) { function matewa_lead_history_current_month_key() { return (string) date_i18n('Y-m', current_time('timestamp')); } } if (!function_exists('matewa_lead_history_empty_month_row')) { function matewa_lead_history_empty_month_row() { return [ 'completed_leads' => 0, 'whatsapp_handoffs' => 0, 'lead_emails_sent' => 0, 'phone_only_leads' => 0, 'last_activity' => '', ]; } } if (!function_exists('matewa_lead_history_normalise_month_row')) { function matewa_lead_history_normalise_month_row($row) { $row = is_array($row) ? $row : []; return [ 'completed_leads' => absint($row['completed_leads'] ?? $row['leads'] ?? 0), 'whatsapp_handoffs' => absint($row['whatsapp_handoffs'] ?? $row['whatsapp'] ?? 0), 'lead_emails_sent' => absint($row['lead_emails_sent'] ?? $row['emails'] ?? 0), 'phone_only_leads' => absint($row['phone_only_leads'] ?? $row['phone_only'] ?? 0), 'last_activity' => !empty($row['last_activity']) ? sanitize_text_field((string) $row['last_activity']) : '', ]; } } if (!function_exists('matewa_lead_history_empty_aggregates')) { function matewa_lead_history_empty_aggregates() { return [ 'yearly_total' => 0, 'month_total' => 0, 'week_total' => 0, 'whatsapp_handoffs' => 0, 'lead_emails_sent' => 0, 'phone_only_leads' => 0, 'last_activity' => '', 'monthly' => [], ]; } } if (!function_exists('matewa_get_lead_history_aggregates')) { function matewa_get_lead_history_aggregates() { $raw = get_option('matewa_lead_history_aggregates', []); $raw = is_array($raw) ? $raw : []; $history = matewa_lead_history_empty_aggregates(); $history['yearly_total'] = absint($raw['yearly_total'] ?? 0); $history['month_total'] = absint($raw['month_total'] ?? 0); $history['week_total'] = absint($raw['week_total'] ?? 0); $history['whatsapp_handoffs'] = absint($raw['whatsapp_handoffs'] ?? 0); $history['lead_emails_sent'] = absint($raw['lead_emails_sent'] ?? 0); $history['phone_only_leads'] = absint($raw['phone_only_leads'] ?? 0); $history['last_activity'] = !empty($raw['last_activity']) ? sanitize_text_field((string) $raw['last_activity']) : ''; $monthly = is_array($raw['monthly'] ?? null) ? $raw['monthly'] : []; foreach ($monthly as $month_key => $month_row) { $month_key = preg_match('/^\d{4}-\d{2}$/', (string) $month_key) ? (string) $month_key : ''; if ('' === $month_key) { continue; } $history['monthly'][$month_key] = matewa_lead_history_normalise_month_row($month_row); } return $history; } } if (!function_exists('matewa_save_lead_history_aggregates')) { function matewa_save_lead_history_aggregates(array $history) { if (function_exists('matewa_direct_save_option_value')) { return matewa_direct_save_option_value('matewa_lead_history_aggregates', $history); } return update_option('matewa_lead_history_aggregates', $history, false); } } if (!function_exists('matewa_lead_history_latest_activity')) { function matewa_lead_history_latest_activity(array $history) { $latest_ts = 0; $latest = ''; $monthly = is_array($history['monthly'] ?? null) ? $history['monthly'] : []; foreach ($monthly as $row) { $activity = !empty($row['last_activity']) ? sanitize_text_field((string) $row['last_activity']) : ''; $ts = '' !== $activity ? strtotime($activity) : false; if (false !== $ts && $ts > $latest_ts) { $latest_ts = (int) $ts; $latest = $activity; } } return $latest; } } if (!function_exists('matewa_lead_history_month_label')) { function matewa_lead_history_month_label($month_key, $format = 'M Y') { $month_key = preg_match('/^\d{4}-\d{2}$/', (string) $month_key) ? (string) $month_key : matewa_lead_history_current_month_key(); $ts = strtotime($month_key . '-01 00:00:00'); return false !== $ts ? date_i18n($format, $ts) : $month_key; } } if (!function_exists('matewa_prepare_lead_history_month_rows')) { function matewa_prepare_lead_history_month_rows(array $history, $limit = 6) { $rows = []; $current_month_key = matewa_lead_history_current_month_key(); $monthly = is_array($history['monthly'] ?? null) ? $history['monthly'] : []; if (!isset($monthly[$current_month_key])) { $monthly[$current_month_key] = [ 'completed_leads' => absint($history['month_total'] ?? 0), 'whatsapp_handoffs' => absint($history['whatsapp_handoffs'] ?? 0), 'lead_emails_sent' => absint($history['lead_emails_sent'] ?? 0), 'last_activity' => sanitize_text_field((string) ($history['last_activity'] ?? '')), ]; } krsort($monthly); foreach ($monthly as $month_key => $month_row) { $month_key = preg_match('/^\d{4}-\d{2}$/', (string) $month_key) ? (string) $month_key : ''; if ('' === $month_key) { continue; } $month_row = matewa_lead_history_normalise_month_row($month_row); $activity = ''; if ('' !== $month_row['last_activity']) { $activity_ts = strtotime($month_row['last_activity']); if (false !== $activity_ts) { $activity = date_i18n(get_option('date_format', 'j M Y'), $activity_ts); } } $rows[] = [ 'month_key' => $month_key, 'month_label' => matewa_lead_history_month_label($month_key, 'M Y'), 'completed_leads' => absint($month_row['completed_leads']), 'whatsapp_handoffs' => absint($month_row['whatsapp_handoffs']), 'lead_emails_sent' => absint($month_row['lead_emails_sent']), 'phone_only_leads' => absint($month_row['phone_only_leads'] ?? 0), 'last_activity' => '' !== $activity ? $activity : 'None recorded', ]; if (count($rows) >= absint($limit)) { break; } } return $rows; } } if (!function_exists('matewa_handle_lead_history_controls_request')) { function matewa_handle_lead_history_controls_request() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page || empty($_POST['matewa_history_action'])) { return; } check_admin_referer('matewa_history_controls_nonce', 'matewa_history_controls_nonce'); $action = sanitize_key(wp_unslash($_POST['matewa_history_action'])); $history = matewa_get_lead_history_aggregates(); if ('download_csv' === $action) { $rows = matewa_prepare_lead_history_month_rows($history, 60); nocache_headers(); header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename="247chatmate-lead-history-' . gmdate('Y-m-d') . '.csv"'); header('X-Content-Type-Options: nosniff'); echo "\xEF\xBB\xBF"; $output = fopen('php://output', 'w'); if (false !== $output) { fputcsv($output, ['Month', 'Leads', 'Phone leads', 'Widget opens', 'WA handoffs', 'Handoff rate', 'Emails sent', 'Last date']); foreach ($rows as $row) { $row_opens = absint($row['widget_opens'] ?? 0); $row_handoffs = absint($row['whatsapp_handoffs'] ?? 0); $row_rate = 'Waiting'; if (0 < $row_opens) { $row_rate = $row_handoffs > $row_opens ? 'Calibrating' : (string) (int) round(($row_handoffs / max(1, $row_opens)) * 100) . '%'; } fputcsv($output, [ $row['month_label'], absint($row['completed_leads']), absint($row['phone_only_leads'] ?? 0), $row_opens, $row_handoffs, $row_rate, absint($row['lead_emails_sent']), $row['last_activity'], ]); } } exit; } if ('save_retention' === $action) { $retention_days = isset($_POST['matewa_history_retention_days']) ? absint(wp_unslash($_POST['matewa_history_retention_days'])) : 28; if (function_exists('matewa_save_lead_history_retention_days')) { matewa_save_lead_history_retention_days($retention_days); } else { update_option('matewa_lead_history_retention_days', $retention_days, false); } if (function_exists('matewa_prune_lead_history_raw_records')) { matewa_prune_lead_history_raw_records(); } wp_safe_redirect(matewa_admin_redirect_url(['matewa_history_notice' => 'retention_saved'], 'setup')); exit; } if ('reset_month' === $action) { if (empty($_POST['matewa_history_confirm_reset_month'])) { wp_safe_redirect(matewa_admin_redirect_url(['matewa_history_notice' => 'confirm_required'], 'setup')); exit; } $current_month_key = matewa_lead_history_current_month_key(); if (!is_array($history['monthly'] ?? null)) { $history['monthly'] = []; } $history['monthly'][$current_month_key] = matewa_lead_history_empty_month_row(); $history['month_total'] = 0; $history['week_total'] = 0; $history['last_activity'] = matewa_lead_history_latest_activity($history); matewa_save_lead_history_aggregates($history); wp_safe_redirect(matewa_admin_redirect_url(['matewa_history_notice' => 'month_reset'], 'setup')); exit; } if ('reset_history' === $action) { $confirm_text = isset($_POST['matewa_history_confirm_text']) ? strtoupper(trim((string) sanitize_text_field(wp_unslash($_POST['matewa_history_confirm_text'])))) : ''; if ('RESET HISTORY' !== $confirm_text) { wp_safe_redirect(matewa_admin_redirect_url(['matewa_history_notice' => 'confirm_required'], 'setup')); exit; } matewa_save_lead_history_aggregates(matewa_lead_history_empty_aggregates()); if (function_exists('matewa_reset_lead_history_page_activity')) { matewa_reset_lead_history_page_activity(); } wp_safe_redirect(matewa_admin_redirect_url(['matewa_history_notice' => 'history_reset'], 'setup')); exit; } if ('hard_reset' === $action) { $confirm_text = isset($_POST['matewa_history_confirm_text']) ? strtoupper(trim((string) sanitize_text_field(wp_unslash($_POST['matewa_history_confirm_text'])))) : ''; if ('RESET' !== $confirm_text) { wp_safe_redirect(matewa_admin_redirect_url(['matewa_history_notice' => 'confirm_required'], 'setup')); exit; } delete_option('matewa_lead_history_aggregates'); matewa_save_lead_history_aggregates(matewa_lead_history_empty_aggregates()); if (function_exists('matewa_reset_lead_history_page_activity')) { matewa_reset_lead_history_page_activity(); } wp_safe_redirect(matewa_admin_redirect_url(['matewa_history_notice' => 'hard_reset'], 'setup')); exit; } wp_safe_redirect(matewa_admin_redirect_url(['matewa_history_notice' => 'unknown_action'], 'setup')); exit; } } add_action('admin_init', 'matewa_handle_lead_history_controls_request', 3); /* ========================================================== FORCE WORDPRESS TO ALLOW THIS OPTIONS PAGE ========================================================== */ add_filter('allowed_options', function ($allowed) { $required = [ 'matewa_number', 'matewa_business_name', 'matewa_marketing_email', 'matewa_leads_email', 'matewa_industry', 'matewa_license_key', 'matewa_vertical_category_selected', 'matewa_vertical_selected', 'matewa_lead_language_mode', 'matewa_lang_switch', 'matewa_widget_settings', 'matewa_chip_label_overrides', ]; $existing = isset($allowed['matewa_settings']) && is_array($allowed['matewa_settings']) ? $allowed['matewa_settings'] : []; $allowed['matewa_settings'] = array_values(array_unique(array_merge($existing, $required))); return $allowed; }); /* ========================================================== TRIAL ACTIVATION (EXPLICIT ONLY) ========================================================== */ if (!function_exists('matewa_handle_trial_start_request')) { function matewa_handle_trial_start_request() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page) { return; } if (!isset($_POST['matewa_start_trial_action'])) { return; } check_admin_referer('matewa_start_trial_nonce', 'matewa_start_trial_nonce'); $result = function_exists('matewa_start_trial_if_allowed') ? matewa_start_trial_if_allowed() : [ 'ok' => false, 'code' => 'missing_handler', ]; $redirect_url = matewa_admin_redirect_url( [ 'matewa_trial_notice' => sanitize_key((string) ($result['code'] ?? 'unknown')), ], 'plan' ); wp_safe_redirect($redirect_url); exit; } } add_action('admin_init', 'matewa_handle_trial_start_request', 5); /* ========================================================== FOUNDER BETA REGISTRATION (EXPLICIT ADMIN ACTION ONLY) ========================================================== */ if (!function_exists('matewa_handle_founder_beta_request')) { function matewa_handle_founder_beta_request() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page) { return; } if (!isset($_POST['matewa_founder_beta_action'])) { return; } check_admin_referer('matewa_founder_beta_nonce', 'matewa_founder_beta_nonce'); $result = function_exists('matewa_founder_beta_register_activation') ? matewa_founder_beta_register_activation() : [ 'success' => false, 'code' => 'missing_handler', 'message' => 'Founder Beta registration handler is not available in this build.', ]; $notice_code = sanitize_key((string) ($result['code'] ?? ($result['message'] ?? 'unknown'))); wp_safe_redirect( matewa_admin_redirect_url( [ 'matewa_founder_beta_notice' => $notice_code, ], 'plan' ) ); exit; } } add_action('admin_init', 'matewa_handle_founder_beta_request', 6); /* ========================================================== MANUAL LICENCE CHECK (CONTROLLED REMOTE VALIDATION) ========================================================== */ if (!function_exists('matewa_handle_license_check_request')) { function matewa_handle_license_check_request() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page) { return; } if (!isset($_POST['matewa_check_license_action'])) { return; } check_admin_referer('matewa_check_license_nonce', 'matewa_check_license_nonce'); $license_key = function_exists('matewa_get_license_key') ? matewa_get_license_key() : trim((string) get_option('matewa_license_key', '')); $redirect_args = [ 'page' => '247chatmate', ]; if ('' === $license_key) { $redirect_args['matewa_license_notice'] = 'missing_key'; } elseif (function_exists('matewa_agency_registry_is_access_code') && matewa_agency_registry_is_access_code($license_key)) { $result = function_exists('matewa_agency_registry_validate_access') ? matewa_agency_registry_validate_access($license_key) : [ 'success' => false, 'code' => 'missing_handler', 'message' => 'Agency access validation handler is not available in this build.', ]; $redirect_args['matewa_agency_notice'] = sanitize_key((string) ($result['code'] ?? ($result['message'] ?? 'unknown'))); } elseif (function_exists('matewa_founder_beta_is_access_code') && matewa_founder_beta_is_access_code($license_key)) { $result = function_exists('matewa_founder_beta_register_activation') ? matewa_founder_beta_register_activation($license_key) : [ 'success' => false, 'code' => 'missing_handler', 'message' => 'Private access key activation handler is not available in this build.', ]; $redirect_args['matewa_founder_beta_notice'] = sanitize_key((string) ($result['code'] ?? ($result['message'] ?? 'unknown'))); } elseif (!function_exists('matewa_get_license_validation_result')) { $redirect_args['matewa_license_notice'] = 'missing_handler'; } else { $result = matewa_get_license_validation_result($license_key, true); $redirect_args['matewa_license_notice'] = sanitize_key((string) ($result['code'] ?? 'unknown')); } wp_safe_redirect( matewa_admin_redirect_url( $redirect_args, 'plan' ) ); exit; } } add_action('admin_init', 'matewa_handle_license_check_request', 7); /* ========================================================== PAID LICENCE REGISTRY MANUAL SYNC (ADVISORY ADMIN ACTION) ========================================================== */ if (!function_exists('matewa_handle_paid_licence_registry_manual_sync_request')) { function matewa_handle_paid_licence_registry_manual_sync_request() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page) { return; } if (!isset($_POST['matewa_paid_licence_registry_manual_sync_action'])) { return; } check_admin_referer('matewa_paid_licence_registry_manual_sync_nonce', 'matewa_paid_licence_registry_manual_sync_nonce'); $result = function_exists('matewa_paid_licence_registry_manual_admin_sync') ? matewa_paid_licence_registry_manual_admin_sync() : [ 'ok' => false, 'code' => 'missing_handler', 'message' => 'Paid licence registry manual sync handler is not available in this build.', ]; wp_safe_redirect( matewa_admin_redirect_url( [ 'matewa_paid_registry_notice' => sanitize_key((string) ($result['code'] ?? 'unknown')), ], 'plan' ) ); exit; } } add_action('admin_init', 'matewa_handle_paid_licence_registry_manual_sync_request', 8); /* ========================================================== PAID LIFECYCLE STATUS REFRESH (READ-ONLY ADMIN ACTION) ========================================================== */ if (!function_exists('matewa_handle_paid_lifecycle_status_refresh_request')) { function matewa_handle_paid_lifecycle_status_refresh_request() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page) { return; } if (!isset($_POST['matewa_paid_lifecycle_status_refresh_action'])) { return; } check_admin_referer('matewa_paid_lifecycle_status_refresh_nonce', 'matewa_paid_lifecycle_status_refresh_nonce'); $result = function_exists('matewa_paid_lifecycle_status_manual_admin_refresh') ? matewa_paid_lifecycle_status_manual_admin_refresh() : [ 'ok' => false, 'code' => 'missing_handler', 'message' => 'Paid lifecycle status refresh handler is not available in this build.', ]; wp_safe_redirect( matewa_admin_redirect_url( [ 'matewa_paid_lifecycle_notice' => sanitize_key((string) ($result['code'] ?? 'unknown')), ], 'plan' ) ); exit; } } add_action('admin_init', 'matewa_handle_paid_lifecycle_status_refresh_request', 9); /* ========================================================== CHIP LABEL RESET (CURRENT SETUP ONLY) ========================================================== */ if (!function_exists('matewa_handle_chip_label_reset_request')) { function matewa_handle_chip_label_reset_request() { if (!is_admin() || !current_user_can('manage_options')) { return; } $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page) { return; } if (!isset($_POST['matewa_reset_chip_labels_action'])) { return; } check_admin_referer('matewa_reset_chip_labels_nonce', 'matewa_reset_chip_labels_nonce'); $vertical_key = matewa_get_current_chip_editor_vertical_key(); $overrides = get_option('matewa_chip_label_overrides', []); if (!is_array($overrides)) { $overrides = []; } if (isset($overrides[$vertical_key])) { unset($overrides[$vertical_key]); if (function_exists('matewa_direct_save_option_value')) { matewa_direct_save_option_value('matewa_chip_label_overrides', $overrides); } else { update_option('matewa_chip_label_overrides', $overrides, false); } } $redirect_url = matewa_admin_redirect_url( [ 'matewa_chip_notice' => 'defaults_restored', ], 'buttons' ); wp_safe_redirect($redirect_url); exit; } } add_action('admin_init', 'matewa_handle_chip_label_reset_request', 6); /* ========================================================== SETUP PROFILE HELPERS (NARROW PASS) ========================================================== */ if (!function_exists('matewa_setup_profile_domain_from_url')) { function matewa_setup_profile_domain_from_url($url) { $url = esc_url_raw((string) $url); $host = wp_parse_url($url, PHP_URL_HOST); if (!is_string($host) || '' === $host) { return ''; } return strtolower(preg_replace('/^www\./i', '', $host)); } } if (!function_exists('matewa_setup_profile_country_from_meta')) { function matewa_setup_profile_country_from_meta($site_domain = '') { $locale = get_locale(); $locale = is_string($locale) ? strtoupper(trim($locale)) : ''; if (preg_match('/[_-]([A-Z]{2})$/', $locale, $matches)) { return $matches[1]; } $site_domain = strtolower((string) $site_domain); $tld_map = [ '.co.uk' => 'GB', '.uk' => 'GB', '.ie' => 'IE', '.com.au' => 'AU', '.au' => 'AU', '.co.nz' => 'NZ', '.nz' => 'NZ', '.ca' => 'CA', '.us' => 'US', '.de' => 'DE', '.fr' => 'FR', '.es' => 'ES', '.it' => 'IT', '.nl' => 'NL', ]; foreach ($tld_map as $suffix => $country_code) { if (substr($site_domain, -strlen($suffix)) === $suffix) { return $country_code; } } return 'unknown'; } } if (!function_exists('matewa_setup_profile_build_payload')) { function matewa_setup_profile_build_payload() { $admin_email = sanitize_email((string) get_option('matewa_marketing_email', '')); $industry = sanitize_text_field((string) get_option('matewa_industry', '')); if ('' === $admin_email || !is_email($admin_email) || '' === $industry) { return []; } $site_url = trailingslashit(home_url('/')); $site_domain = matewa_setup_profile_domain_from_url($site_url); $country = matewa_setup_profile_country_from_meta($site_domain); return [ 'event' => 'plugin_setup_profile', 'admin_email' => $admin_email, 'vertical' => $industry, 'country_code' => $country, 'site_url' => esc_url_raw($site_url), 'site_domain' => $site_domain, 'plugin_version' => defined('MATEWA_VERSION') ? MATEWA_VERSION : '', 'captured_at' => gmdate('c'), ]; } } if (!function_exists('matewa_setup_profile_hash')) { function matewa_setup_profile_hash(array $payload) { $parts = [ strtolower((string) ($payload['admin_email'] ?? '')), strtolower((string) ($payload['vertical'] ?? '')), strtoupper((string) ($payload['country_code'] ?? '')), strtolower((string) ($payload['site_domain'] ?? '')), ]; return hash('sha256', implode('|', $parts)); } } if (!function_exists('matewa_maybe_send_setup_profile_after_settings_save')) { function matewa_maybe_send_setup_profile_after_settings_save() { // Recovery guard: do not perform remote setup-profile calls or option writes // during the admin settings save/reload path. return; if (!is_admin() || !current_user_can('manage_options')) { return; } $page_raw = filter_input(INPUT_GET, 'page', FILTER_DEFAULT); $settings_updated_raw = filter_input(INPUT_GET, 'settings-updated', FILTER_DEFAULT); $page = is_string($page_raw) ? sanitize_key(wp_unslash($page_raw)) : ''; $updated = is_string($settings_updated_raw) ? sanitize_text_field(wp_unslash($settings_updated_raw)) : ''; if ('247chatmate' !== $page || 'true' !== strtolower($updated)) { return; } $payload = matewa_setup_profile_build_payload(); if (empty($payload)) { return; } $current_hash = matewa_setup_profile_hash($payload); $stored_hash = sanitize_text_field((string) get_option('matewa_setup_profile_hash', '')); if ('' !== $stored_hash && hash_equals($stored_hash, $current_hash)) { return; } $response = wp_remote_post( MATEWA_SETUP_PROFILE_ENDPOINT, [ 'timeout' => 2, 'blocking' => true, 'sslverify' => true, 'body' => $payload, ] ); if (is_wp_error($response)) { return; } $status_code = (int) wp_remote_retrieve_response_code($response); if ($status_code >= 200 && $status_code < 300) { update_option('matewa_setup_profile_hash', $current_hash, false); update_option('matewa_setup_profile_last_sent_at', gmdate('c'), false); } } } add_action('admin_init', 'matewa_maybe_send_setup_profile_after_settings_save', 20); /* ========================================================== ADMIN ASSETS (CSS + JS — STRUCTURAL PASS) ========================================================== */ if (!function_exists('matewa_enqueue_settings_ui_assets')) { function matewa_enqueue_settings_ui_assets($hook_suffix) { $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : ''; if ('247chatmate' !== $page) { return; } $matewa_admin_css_version = defined('MATEWA_VERSION') ? MATEWA_VERSION : null; $matewa_admin_css_file = defined('MATEWA_PLUGIN_DIR') ? MATEWA_PLUGIN_DIR . 'admin/assets/admin.css' : ''; $matewa_admin_js_version = defined('MATEWA_VERSION') ? MATEWA_VERSION : null; $matewa_admin_js_file = defined('MATEWA_PLUGIN_DIR') ? MATEWA_PLUGIN_DIR . 'admin/assets/admin.js' : ''; $matewa_plan_access_css_version = defined('MATEWA_VERSION') ? MATEWA_VERSION : null; $matewa_plan_access_css_file = defined('MATEWA_PLUGIN_DIR') ? MATEWA_PLUGIN_DIR . 'admin/assets/plan-access.css' : ''; $matewa_admin_shell_css_version = defined('MATEWA_VERSION') ? MATEWA_VERSION : null; $matewa_admin_shell_css_file = defined('MATEWA_PLUGIN_DIR') ? MATEWA_PLUGIN_DIR . 'admin/assets/admin-shell.css' : ''; $matewa_client_view_css_version = defined('MATEWA_VERSION') ? MATEWA_VERSION : null; $matewa_client_view_css_file = defined('MATEWA_PLUGIN_DIR') ? MATEWA_PLUGIN_DIR . 'admin/assets/client-view.css' : ''; $matewa_dashboard_layout_css_version = defined('MATEWA_VERSION') ? MATEWA_VERSION : null; $matewa_dashboard_layout_css_file = defined('MATEWA_PLUGIN_DIR') ? MATEWA_PLUGIN_DIR . 'admin/assets/dashboard-layout.css' : ''; $matewa_admin_page_gaps_css_version = defined('MATEWA_VERSION') ? MATEWA_VERSION : null; $matewa_admin_page_gaps_css_file = defined('MATEWA_PLUGIN_DIR') ? MATEWA_PLUGIN_DIR . 'admin/assets/admin-page-gaps.css' : ''; $matewa_expert_visual_css_version = defined('MATEWA_VERSION') ? MATEWA_VERSION : null; $matewa_expert_visual_css_file = defined('MATEWA_PLUGIN_DIR') ? MATEWA_PLUGIN_DIR . 'admin/assets/expert-visual-polish.css' : ''; $matewa_language_controls_css_version = defined('MATEWA_VERSION') ? MATEWA_VERSION : null; $matewa_language_controls_css_file = defined('MATEWA_PLUGIN_DIR') ? MATEWA_PLUGIN_DIR . 'admin/assets/language-controls.css' : ''; $matewa_language_controls_js_version = defined('MATEWA_VERSION') ? MATEWA_VERSION : null; $matewa_language_controls_js_file = defined('MATEWA_PLUGIN_DIR') ? MATEWA_PLUGIN_DIR . 'admin/assets/language-controls.js' : ''; if (!empty($matewa_admin_css_file) && is_readable($matewa_admin_css_file)) { $matewa_admin_css_version = (defined('MATEWA_VERSION') ? MATEWA_VERSION : '1') . '-' . filemtime($matewa_admin_css_file); } if (!empty($matewa_admin_js_file) && is_readable($matewa_admin_js_file)) { $matewa_admin_js_version = (defined('MATEWA_VERSION') ? MATEWA_VERSION : '1') . '-' . filemtime($matewa_admin_js_file); } if (!empty($matewa_plan_access_css_file) && is_readable($matewa_plan_access_css_file)) { $matewa_plan_access_css_version = (defined('MATEWA_VERSION') ? MATEWA_VERSION : '1') . '-' . filemtime($matewa_plan_access_css_file); } if (!empty($matewa_admin_shell_css_file) && is_readable($matewa_admin_shell_css_file)) { $matewa_admin_shell_css_version = (defined('MATEWA_VERSION') ? MATEWA_VERSION : '1') . '-' . filemtime($matewa_admin_shell_css_file); } if (!empty($matewa_client_view_css_file) && is_readable($matewa_client_view_css_file)) { $matewa_client_view_css_version = (defined('MATEWA_VERSION') ? MATEWA_VERSION : '1') . '-' . filemtime($matewa_client_view_css_file); } if (!empty($matewa_dashboard_layout_css_file) && is_readable($matewa_dashboard_layout_css_file)) { $matewa_dashboard_layout_css_version = (defined('MATEWA_VERSION') ? MATEWA_VERSION : '1') . '-' . filemtime($matewa_dashboard_layout_css_file); } if (!empty($matewa_admin_page_gaps_css_file) && is_readable($matewa_admin_page_gaps_css_file)) { $matewa_admin_page_gaps_css_version = (defined('MATEWA_VERSION') ? MATEWA_VERSION : '1') . '-' . filemtime($matewa_admin_page_gaps_css_file); } if (!empty($matewa_expert_visual_css_file) && is_readable($matewa_expert_visual_css_file)) { $matewa_expert_visual_css_version = (defined('MATEWA_VERSION') ? MATEWA_VERSION : '1') . '-' . filemtime($matewa_expert_visual_css_file); } if (!empty($matewa_language_controls_css_file) && is_readable($matewa_language_controls_css_file)) { $matewa_language_controls_css_version = (defined('MATEWA_VERSION') ? MATEWA_VERSION : '1') . '-' . filemtime($matewa_language_controls_css_file); } if (!empty($matewa_language_controls_js_file) && is_readable($matewa_language_controls_js_file)) { $matewa_language_controls_js_version = (defined('MATEWA_VERSION') ? MATEWA_VERSION : '1') . '-' . filemtime($matewa_language_controls_js_file); } wp_enqueue_style( 'matewa-plan-access', MATEWA_PLUGIN_URL . 'admin/assets/plan-access.css', [], $matewa_plan_access_css_version ); wp_enqueue_style( 'matewa-admin-settings-ui', MATEWA_PLUGIN_URL . 'admin/assets/admin.css', ['matewa-plan-access'], $matewa_admin_css_version ); wp_enqueue_style( 'matewa-admin-shell', MATEWA_PLUGIN_URL . 'admin/assets/admin-shell.css', ['matewa-admin-settings-ui'], $matewa_admin_shell_css_version ); wp_enqueue_style( 'matewa-client-view', MATEWA_PLUGIN_URL . 'admin/assets/client-view.css', ['matewa-admin-shell'], $matewa_client_view_css_version ); wp_enqueue_style( 'matewa-dashboard-layout', MATEWA_PLUGIN_URL . 'admin/assets/dashboard-layout.css', ['matewa-client-view'], $matewa_dashboard_layout_css_version ); wp_enqueue_style( 'matewa-expert-visual-polish', MATEWA_PLUGIN_URL . 'admin/assets/expert-visual-polish.css', ['matewa-dashboard-layout'], $matewa_expert_visual_css_version ); wp_enqueue_style( 'matewa-admin-page-gaps', MATEWA_PLUGIN_URL . 'admin/assets/admin-page-gaps.css', ['matewa-expert-visual-polish'], $matewa_admin_page_gaps_css_version ); wp_enqueue_style( 'matewa-language-controls', MATEWA_PLUGIN_URL . 'admin/assets/language-controls.css', ['matewa-admin-page-gaps'], $matewa_language_controls_css_version ); wp_enqueue_script( 'matewa-admin-settings-ui', MATEWA_PLUGIN_URL . 'admin/assets/admin.js', [], $matewa_admin_js_version, true ); wp_enqueue_script( 'matewa-language-controls', MATEWA_PLUGIN_URL . 'admin/assets/language-controls.js', ['matewa-admin-settings-ui'], $matewa_language_controls_js_version, true ); } } add_action('admin_enqueue_scripts', 'matewa_enqueue_settings_ui_assets'); /* ========================================================== SETTINGS PAGE RENDER ========================================================== */ if (!function_exists('matewa_render_settings_ui')) { function matewa_render_settings_ui() { if (!current_user_can('manage_options')) { return; } $mode = function_exists('matewa_license_status') ? matewa_license_status() : 'free'; $widget = get_option('matewa_widget_settings', [ 'enabled' => '1', 'display_mode' => 'all', 'page_ids' => [], 'include_homepage' => '0', 'show_country_selector' => '1', ]); $widget = is_array($widget) ? $widget : ['enabled' => '1', 'display_mode' => 'all', 'page_ids' => [], 'include_homepage' => '0', 'show_country_selector' => '1', 'show_language_selector' => '1', 'default_language' => 'auto', 'visible_languages' => '']; $widget_show_country_selector = array_key_exists('show_country_selector', $widget) ? ((string) $widget['show_country_selector'] === '1') : true; $widget_show_language_selector = array_key_exists('show_language_selector', $widget) ? ((string) $widget['show_language_selector'] === '1') : true; $widget_default_language = isset($widget['default_language']) ? (string) $widget['default_language'] : 'auto'; $widget_visible_languages = isset($widget['visible_languages']) ? (string) $widget['visible_languages'] : ''; $widget_display_mode = function_exists('matewa_normalise_widget_display_mode') ? matewa_normalise_widget_display_mode($widget['display_mode'] ?? 'all') : 'all'; $widget_page_ids = function_exists('matewa_normalise_widget_page_ids') ? matewa_normalise_widget_page_ids($widget['page_ids'] ?? []) : array_values(array_unique(array_filter(array_map('absint', (array) ($widget['page_ids'] ?? []))))); $widget_include_homepage = !empty($widget['include_homepage']) ? '1' : '0'; if ('homepage' === $widget_display_mode) { $widget_display_mode = 'selected'; $widget_include_homepage = '1'; } $available_pages = get_pages([ 'sort_column' => 'post_title', 'sort_order' => 'ASC', 'post_status' => ['publish', 'private'], ]); $number = get_option('matewa_number', ''); $business = get_option('matewa_business_name', ''); $marketing_email = get_option('matewa_marketing_email', ''); $leads_email = get_option('matewa_leads_email', ''); $industry = get_option('matewa_industry', ''); $license_key = get_option('matewa_license_key', ''); $vertical_category = get_option('matewa_vertical_category_selected', 'general'); $vertical = get_option('matewa_vertical_selected', ''); $langMode = get_option('matewa_lead_language_mode', 'english'); $langSwitch = get_option('matewa_lang_switch', 'yes'); $trial_notice = isset($_GET['matewa_trial_notice']) ? sanitize_key(wp_unslash($_GET['matewa_trial_notice'])) : ''; $trial_registry_last = function_exists('matewa_pro_trial_registry_get_last_result') ? matewa_pro_trial_registry_get_last_result() : []; $trial_registry_last = is_array($trial_registry_last) ? $trial_registry_last : []; $trial_registry_configured = function_exists('matewa_pro_trial_registry_is_configured') ? matewa_pro_trial_registry_is_configured() : false; $trial_registry_endpoint = function_exists('matewa_pro_trial_registry_get_endpoint') ? matewa_pro_trial_registry_get_endpoint() : ''; $trial_registry_message = isset($trial_registry_last['message']) ? sanitize_text_field((string) $trial_registry_last['message']) : ''; $founder_beta_notice = isset($_GET['matewa_founder_beta_notice']) ? sanitize_key(wp_unslash($_GET['matewa_founder_beta_notice'])) : ''; $agency_notice = isset($_GET['matewa_agency_notice']) ? sanitize_key(wp_unslash($_GET['matewa_agency_notice'])) : ''; $agency_last = function_exists('matewa_agency_registry_get_last_result') ? matewa_agency_registry_get_last_result() : []; $agency_last = is_array($agency_last) ? $agency_last : []; $agency_configured = function_exists('matewa_agency_registry_is_configured') ? matewa_agency_registry_is_configured() : false; $agency_endpoint = function_exists('matewa_agency_registry_get_endpoint') ? matewa_agency_registry_get_endpoint() : ''; $agency_message = isset($agency_last['message']) ? sanitize_text_field((string) $agency_last['message']) : ''; $agency_runtime_active = function_exists('matewa_agency_own_site_access_is_active') ? matewa_agency_own_site_access_is_active() : false; $agency_hub_runtime_active = function_exists('matewa_agency_hub_is_active') ? matewa_agency_hub_is_active() : false; $founder_beta_last = function_exists('matewa_founder_beta_get_last_result') ? matewa_founder_beta_get_last_result() : []; $founder_beta_last = is_array($founder_beta_last) ? $founder_beta_last : []; $founder_beta_configured = function_exists('matewa_founder_beta_is_configured') ? matewa_founder_beta_is_configured() : false; $founder_beta_endpoint = function_exists('matewa_founder_beta_get_endpoint') ? matewa_founder_beta_get_endpoint() : ''; $founder_beta_message = isset($founder_beta_last['message']) ? sanitize_text_field((string) $founder_beta_last['message']) : ''; $chip_notice = isset($_GET['matewa_chip_notice']) ? sanitize_key(wp_unslash($_GET['matewa_chip_notice'])) : ''; $license_notice = isset($_GET['matewa_license_notice']) ? sanitize_key(wp_unslash($_GET['matewa_license_notice'])) : ''; $paid_registry_notice = isset($_GET['matewa_paid_registry_notice']) ? sanitize_key(wp_unslash($_GET['matewa_paid_registry_notice'])) : ''; $paid_registry_last = function_exists('matewa_paid_licence_registry_get_last_result') ? matewa_paid_licence_registry_get_last_result() : []; $paid_registry_last = is_array($paid_registry_last) ? $paid_registry_last : []; $paid_registry_error = function_exists('matewa_paid_licence_registry_get_last_error') ? matewa_paid_licence_registry_get_last_error() : []; $paid_registry_error = is_array($paid_registry_error) ? $paid_registry_error : []; $paid_registry_configured = function_exists('matewa_paid_licence_registry_is_configured') ? matewa_paid_licence_registry_is_configured() : false; $paid_registry_endpoint = function_exists('matewa_paid_licence_registry_get_endpoint') ? matewa_paid_licence_registry_get_endpoint() : ''; $paid_registry_last_sync = function_exists('matewa_paid_licence_registry_get_last_sync') ? matewa_paid_licence_registry_get_last_sync() : (int) get_option('matewa_paid_licence_registry_last_sync', 0); $paid_lifecycle_notice = isset($_GET['matewa_paid_lifecycle_notice']) ? sanitize_key(wp_unslash($_GET['matewa_paid_lifecycle_notice'])) : ''; $paid_lifecycle_last = function_exists('matewa_paid_lifecycle_status_get_last_result') ? matewa_paid_lifecycle_status_get_last_result() : []; $paid_lifecycle_last = is_array($paid_lifecycle_last) ? $paid_lifecycle_last : []; $paid_lifecycle_error = function_exists('matewa_paid_lifecycle_status_get_last_error') ? matewa_paid_lifecycle_status_get_last_error() : []; $paid_lifecycle_error = is_array($paid_lifecycle_error) ? $paid_lifecycle_error : []; $paid_lifecycle_configured = function_exists('matewa_paid_lifecycle_status_is_configured') ? matewa_paid_lifecycle_status_is_configured() : false; $paid_lifecycle_endpoint = function_exists('matewa_paid_lifecycle_status_get_endpoint') ? matewa_paid_lifecycle_status_get_endpoint() : ''; $paid_lifecycle_last_refresh = function_exists('matewa_paid_lifecycle_status_get_last_refresh') ? matewa_paid_lifecycle_status_get_last_refresh() : (int) get_option('matewa_paid_lifecycle_status_last_refresh', 0); $settings_updated = ( isset($_GET['settings-updated']) && 'true' === strtolower((string) sanitize_text_field(wp_unslash($_GET['settings-updated']))) ) || ( isset($_GET['matewa_settings_saved']) && '1' === (string) sanitize_text_field(wp_unslash($_GET['matewa_settings_saved'])) ); $masked_license = ''; if (is_string($license_key) && '' !== $license_key) { $len = strlen($license_key); if ($len <= 8) { $masked_license = str_repeat('•', $len); } else { $masked_license = substr($license_key, 0, 4) . str_repeat('•', max(0, $len - 8)) . substr($license_key, -4); } } $supported_languages = function_exists('matewa_get_supported_languages') ? matewa_get_supported_languages() : ['en' => 'English']; $supported_language_count = is_array($supported_languages) ? count($supported_languages) : 1; $language_preview_names = []; if (is_array($supported_languages)) { $preview_keys = ['en', 'es', 'fr', 'de', 'ar', 'hi', 'ja', 'zh-cn']; foreach ($preview_keys as $preview_key) { if (isset($supported_languages[$preview_key])) { $language_preview_names[] = $supported_languages[$preview_key]; } } } $language_preview_text = !empty($language_preview_names) ? implode(', ', $language_preview_names) : 'English'; $free_chips = [ 'Get a quote', 'Pricing', 'Availability', 'Something else', ]; $license_diag = function_exists('matewa_get_license_diagnostics') ? matewa_get_license_diagnostics() : [ 'entitlement_state' => $mode, 'has_license_key' => ('' !== trim((string) $license_key)), 'is_master' => false, 'is_dev_forced' => false, 'license' => [ 'valid' => false, 'code' => 'not_available', 'message' => 'Detailed licence diagnostics are not available in this build.', 'source' => 'runtime', 'checked_at' => time(), ], 'trial' => [ 'has_started' => function_exists('matewa_trial_has_started') ? matewa_trial_has_started() : false, 'started_at' => function_exists('matewa_get_trial_started') ? (int) matewa_get_trial_started() : 0, 'active' => function_exists('matewa_trial_active') ? matewa_trial_active() : false, 'expired' => function_exists('matewa_trial_expired') ? matewa_trial_expired() : false, ], ]; $license_info = is_array($license_diag['license'] ?? null) ? $license_diag['license'] : []; $license_code = sanitize_key((string) ($license_info['code'] ?? 'unknown')); $license_msg = (string) ($license_info['message'] ?? ''); $license_valid = !empty($license_info['valid']); $license_source = sanitize_key((string) ($license_info['source'] ?? 'runtime')); $license_checked_at = isset($license_info['checked_at']) ? (int) $license_info['checked_at'] : 0; $license_last_checked_text = $license_checked_at > 0 ? gmdate('Y-m-d H:i:s', $license_checked_at) . ' UTC' : 'Not checked'; $trial_info = is_array($license_diag['trial'] ?? null) ? $license_diag['trial'] : []; $agency_diag = is_array($license_diag['agency'] ?? null) ? $license_diag['agency'] : []; $is_master = !empty($license_diag['is_master']); $is_dev_forced = !empty($license_diag['is_dev_forced']); $has_key = !empty($license_diag['has_license_key']); $saved_key_is_founder_beta = function_exists('matewa_founder_beta_is_access_code') ? matewa_founder_beta_is_access_code($license_key) : (0 === strpos(strtoupper(trim((string) $license_key)), 'FBETA-')); $saved_key_is_agency_access = function_exists('matewa_agency_registry_is_access_code') ? matewa_agency_registry_is_access_code($license_key) : (0 === strpos(strtoupper(trim((string) $license_key)), 'AGENCY-')); $founder_beta_runtime_active = function_exists('matewa_founder_beta_is_active') ? matewa_founder_beta_is_active() : false; $dashboard_founder_beta_active = 'pro' === $mode && ( $founder_beta_runtime_active || 'founder_beta_registry' === $license_source || 'founder_beta_active' === $license_code ); $dashboard_agency_active = 'pro' === $mode && ( $agency_runtime_active || 'agency_registry' === $license_source || 'agency_own_site_active' === $license_code ); $dashboard_agency_hub_visible = $dashboard_agency_active || !empty($agency_hub_runtime_active); $chip_override_enabled = in_array($mode, ['trial_active', 'pro', 'master'], true); $catalog = in_array($mode, ['free', 'trial_expired'], true) ? matewa_get_full_vertical_catalog_for_admin_preview() : matewa_get_vertical_catalog_data(); $vertical_definitions = is_array($catalog['verticals'] ?? null) ? $catalog['verticals'] : []; $vertical_categories = is_array($catalog['categories'] ?? null) ? $catalog['categories'] : []; $selector_data = matewa_build_vertical_selector_data($vertical_definitions, $vertical_categories); $vertical_selector_categories = is_array($selector_data['categories'] ?? null) ? $selector_data['categories'] : []; $vertical_selector_flat = is_array($selector_data['flat'] ?? null) ? $selector_data['flat'] : []; $vertical_to_category = is_array($selector_data['vertical_to_category'] ?? null) ? $selector_data['vertical_to_category'] : []; $default_vertical_key = matewa_safe_key($catalog['default_vertical'] ?? 'general', 'general'); $active_vertical_key = matewa_safe_key( get_option('matewa_vertical_selected', ''), $default_vertical_key ); if ('' === $active_vertical_key) { $active_vertical_key = $default_vertical_key; } if (!isset($vertical_selector_flat[$active_vertical_key]) && !empty($vertical_selector_flat)) { $flat_keys = array_keys($vertical_selector_flat); $active_vertical_key = matewa_safe_key($flat_keys[0] ?? $default_vertical_key, $default_vertical_key); } if (empty($vertical_selector_categories)) { $vertical_selector_categories = [ 'general' => [ 'key' => 'general', 'label' => 'General', 'options' => [ $active_vertical_key => [ 'key' => $active_vertical_key, 'display_label' => matewa_format_vertical_key_label($active_vertical_key), ], ], ], ]; } $saved_category_key = matewa_safe_key( get_option('matewa_vertical_category_selected', ''), '' ); if ('' === $saved_category_key || !isset($vertical_selector_categories[$saved_category_key])) { $saved_category_key = isset($vertical_to_category[$active_vertical_key]) ? matewa_safe_key($vertical_to_category[$active_vertical_key], 'general') : 'general'; if (!isset($vertical_selector_categories[$saved_category_key])) { $category_keys = array_keys($vertical_selector_categories); $saved_category_key = !empty($category_keys) ? matewa_safe_key($category_keys[0], 'general') : 'general'; } } $current_category_options = is_array($vertical_selector_categories[$saved_category_key]['options'] ?? null) ? $vertical_selector_categories[$saved_category_key]['options'] : []; if (!isset($current_category_options[$active_vertical_key])) { $owner_category_key = isset($vertical_to_category[$active_vertical_key]) ? matewa_safe_key($vertical_to_category[$active_vertical_key], '') : ''; if ('' !== $owner_category_key && isset($vertical_selector_categories[$owner_category_key])) { $saved_category_key = $owner_category_key; $current_category_options = is_array($vertical_selector_categories[$saved_category_key]['options'] ?? null) ? $vertical_selector_categories[$saved_category_key]['options'] : []; } } if (empty($current_category_options)) { foreach ($vertical_selector_categories as $fallback_category_key => $fallback_category_data) { $fallback_options = is_array($fallback_category_data['options'] ?? null) ? $fallback_category_data['options'] : []; if (!empty($fallback_options)) { $saved_category_key = matewa_safe_key($fallback_category_key, 'general'); $current_category_options = $fallback_options; break; } } } if (!isset($current_category_options[$active_vertical_key])) { $active_vertical_key = matewa_resolve_valid_vertical_for_category($saved_category_key, $active_vertical_key); } if (!isset($current_category_options[$active_vertical_key]) && !empty($current_category_options)) { $option_keys = array_keys($current_category_options); $active_vertical_key = matewa_safe_key($option_keys[0] ?? $default_vertical_key, $default_vertical_key); } $active_vertical_label = matewa_safe_scalar_text( matewa_resolve_vertical_display_label( $active_vertical_key, isset($vertical_definitions[$active_vertical_key]) && is_array($vertical_definitions[$active_vertical_key]) ? $vertical_definitions[$active_vertical_key] : [] ), matewa_format_vertical_key_label($active_vertical_key) ); $chip_items = matewa_get_chip_items_for_vertical_key($active_vertical_key); $preview_chip_items = $chip_items; $chip_overrides = get_option('matewa_chip_label_overrides', []); $chip_overrides = is_array($chip_overrides) ? $chip_overrides : []; $current_chip_overrides = isset($chip_overrides[$active_vertical_key]) && is_array($chip_overrides[$active_vertical_key]) ? $chip_overrides[$active_vertical_key] : []; $show_vertical_selector = $chip_override_enabled && !empty($vertical_selector_flat); $status_badge_text = 'Free'; $status_badge_class = 'is-neutral'; if ('trial_active' === $mode) { $status_badge_text = 'Trial Active'; $status_badge_class = 'is-trial'; } elseif ('trial_expired' === $mode) { $status_badge_text = 'Trial Expired'; $status_badge_class = 'is-warning'; } elseif ($dashboard_agency_active) { $status_badge_text = 'Agency Active'; $status_badge_class = 'is-success'; } elseif ($dashboard_founder_beta_active) { $status_badge_text = 'Founder Beta Active'; $status_badge_class = 'is-success'; } elseif ('pro' === $mode) { $status_badge_text = 'Pro Active'; $status_badge_class = 'is-success'; } elseif ('master' === $mode) { $status_badge_text = 'Master Active'; $status_badge_class = 'is-master'; } $license_status_heading = 'Licence status unavailable'; $license_status_class = 'is-neutral'; if ($is_dev_forced) { $license_status_heading = 'Pro active via development override'; $license_status_class = 'is-info'; } elseif ($is_master) { $license_status_heading = 'Master access active'; $license_status_class = 'is-success'; } elseif ($dashboard_agency_active) { $license_status_heading = 'Agency own-site access verified'; $license_status_class = 'is-success'; } elseif ($dashboard_founder_beta_active) { $license_status_heading = 'Founder Beta is active on this site'; $license_status_class = 'is-success'; } elseif ($license_valid && 'pro' === $mode) { $license_status_heading = 'Pro is active on this site'; $license_status_class = 'is-success'; } elseif ('missing_key' === $license_code) { $license_status_heading = 'No licence key saved'; $license_status_class = 'is-neutral'; } elseif ('not_configured' === $license_code) { $license_status_heading = 'Licence validation not configured'; $license_status_class = 'is-warning'; } elseif ('deferred_admin_request' === $license_code) { $license_status_heading = 'Licence key saved but not checked yet'; $license_status_class = 'is-warning'; } elseif (in_array($license_code, ['invalid', 'invalid_cached'], true)) { $license_status_heading = 'Licence validation failed'; $license_status_class = 'is-error'; } elseif (in_array($license_code, ['request_error', 'invalid_response'], true)) { $license_status_heading = 'Licence server could not be confirmed'; $license_status_class = 'is-warning'; } $activation_reason = 'Free plan is currently active.'; if ($is_dev_forced) { $activation_reason = 'This site is running Pro through the development override.'; } elseif ($is_master) { $activation_reason = 'This site is running with master access.'; } elseif ($dashboard_agency_active) { $activation_reason = 'This site is running through approved agency own-site access. No client seats are granted by this free agency access key.'; } elseif ($dashboard_founder_beta_active) { $activation_reason = 'This site is running through active Founder Beta access.'; } elseif ('pro' === $mode && $license_valid) { $activation_reason = 'This site is running Pro because the saved licence validated successfully.'; } elseif ('trial_active' === $mode) { $activation_reason = 'This site is running on an active 28-day trial.'; } elseif ('trial_expired' === $mode) { $activation_reason = 'This site has an expired trial. Saved settings remain intact.'; } $settings_heading = 'Free Plan Settings'; $settings_description = (function_exists('matewa_distribution_has_pro_trial') && matewa_distribution_has_pro_trial()) ? 'Configure your core widget settings here. Your 28-day Pro trial starts automatically once onboarding details are saved.' : 'Configure your core widget settings here. Add a valid licence key whenever you are ready to unlock Pro features on this site.'; if ('trial_active' === $mode) { $settings_heading = 'Trial Plan Settings'; $settings_description = 'Your trial is active. You can continue configuring your widget while evaluating Pro features. Your saved settings will remain in place.'; } elseif ('trial_expired' === $mode) { $settings_heading = 'Saved Plan Settings'; $settings_description = 'Your trial has ended, but your saved settings have been retained. Add a valid licence key and save to move this site cleanly into Pro.'; } elseif ($dashboard_agency_active) { $settings_heading = 'Agency Own-Site Settings'; $settings_description = 'Agency own-site access is active. Manage this agency website here. Client seats will be handled separately through paid agency bundles.'; } elseif ($dashboard_founder_beta_active) { $settings_heading = 'Founder Beta Settings'; $settings_description = 'Founder Beta access is active. Manage your widget settings here and continue building from your saved setup.'; } elseif ('pro' === $mode) { $settings_heading = 'Pro Plan Settings'; $settings_description = 'Your Pro licence is active. Manage your widget settings here and continue building from your saved setup.'; } elseif ('master' === $mode) { $settings_heading = 'Master Plan Settings'; $settings_description = 'Master access is active on this site. All saved settings remain available from this control panel.'; } $trial_started_text = 'Not started'; if (!empty($trial_info['started_at'])) { $trial_started_text = gmdate('Y-m-d H:i:s', (int) $trial_info['started_at']) . ' UTC'; } $save_notice_type = ''; $save_notice_message = ''; $save_button_state = 'clean'; if ('defaults_restored' === $chip_notice) { $save_notice_type = 'success'; $save_notice_message = 'Saved'; } elseif ($settings_updated) { if ($is_dev_forced) { $save_notice_type = 'info'; } elseif (($has_key && 'deferred_admin_request' === $license_code) || ($has_key && !$license_valid && !$dashboard_founder_beta_active)) { $save_notice_type = 'warning'; } else { $save_notice_type = 'success'; } // Keep the top-bar confirmation deliberately short so it never // crowds the Preview widget / Save changes buttons. Detailed // licence and plan state remains shown in Setup and the Dashboard countdown card. $save_notice_message = 'Saved'; } if ('' !== $save_notice_message) { $save_button_state = 'saved'; } $dashboard_widget_enabled = '1' === (string) ($widget['enabled'] ?? '0'); $dashboard_widget_status_text = $dashboard_widget_enabled ? 'Live' : 'Off'; $dashboard_widget_status_class = $dashboard_widget_enabled ? 'is-live' : 'is-off'; $dashboard_plan_text = $status_badge_text; if ('trial_active' === $mode) { $dashboard_plan_text = 'Trial'; } elseif ('trial_expired' === $mode) { $dashboard_plan_text = 'Trial expired'; } elseif ($dashboard_agency_active) { $dashboard_plan_text = 'Agency'; } elseif ($dashboard_founder_beta_active) { $dashboard_plan_text = 'Founder Beta'; } elseif ('pro' === $mode) { $dashboard_plan_text = 'Pro'; } elseif ('master' === $mode) { $dashboard_plan_text = 'Founder / Master'; } elseif ('free' === $mode || '' === $mode) { $dashboard_plan_text = 'Free'; } /* Dashboard plan countdown / upgrade nudge (display-only). */ $dashboard_plan_upgrade_url = 'https://247chatmate.lemonsqueezy.com/checkout/buy/654461de-2eae-4715-a249-a2ac7e032678'; $dashboard_plan_nudge_new_tab = true; $dashboard_plan_nudge_label = 'Upgrade to Pro'; $dashboard_plan_nudge_title = 'Upgrade to Pro'; $dashboard_plan_nudge_value = 'Unlock all Pro features'; $dashboard_plan_nudge_detail = 'Get full business-type access, page targeting and Pro lead tools.'; $dashboard_plan_nudge_tone = 'is-free'; if ('trial_active' === $mode) { $dashboard_trial_days = defined('MATEWA_TRIAL_DAYS') ? max(0, (int) MATEWA_TRIAL_DAYS) : 28; $dashboard_trial_day_seconds = defined('DAY_IN_SECONDS') ? (int) DAY_IN_SECONDS : 86400; $dashboard_trial_started_at = isset($trial_info['started_at']) ? (int) $trial_info['started_at'] : 0; $dashboard_trial_end_at = ($dashboard_trial_started_at > 0 && $dashboard_trial_days > 0) ? $dashboard_trial_started_at + ($dashboard_trial_days * $dashboard_trial_day_seconds) : 0; $dashboard_trial_remaining_days = ($dashboard_trial_end_at > 0) ? max(0, (int) ceil(($dashboard_trial_end_at - time()) / $dashboard_trial_day_seconds)) : 0; $dashboard_plan_nudge_title = 'Trial countdown'; $dashboard_plan_nudge_value = 1 === $dashboard_trial_remaining_days ? '1 day left' : $dashboard_trial_remaining_days . ' days left'; $dashboard_plan_nudge_detail = $dashboard_trial_end_at > 0 ? 'Upgrade before ' . wp_date((string) get_option('date_format', 'Y-m-d'), $dashboard_trial_end_at) : 'Upgrade before the trial ends.'; $dashboard_plan_nudge_label = 'Upgrade'; $dashboard_plan_nudge_tone = $dashboard_trial_remaining_days <= 7 ? 'is-warning' : 'is-trial'; } elseif ('trial_expired' === $mode) { $dashboard_plan_nudge_title = 'Trial ended'; $dashboard_plan_nudge_value = 'Upgrade needed'; $dashboard_plan_nudge_detail = 'Reactivate Pro access.'; $dashboard_plan_nudge_label = 'Reactivate'; $dashboard_plan_nudge_tone = 'is-expired'; } elseif ($dashboard_agency_active) { $dashboard_plan_upgrade_url = '#matewa-agency-hub-section'; $dashboard_plan_nudge_new_tab = false; $dashboard_plan_nudge_title = 'Agency active'; $dashboard_plan_nudge_value = 'Agency plan live'; $dashboard_plan_nudge_detail = 'Your agency site is unlocked. Add client licences when you’re ready to roll this out to customers.'; $dashboard_plan_nudge_label = 'Manage agency'; $dashboard_plan_nudge_tone = 'is-agency'; } elseif ($dashboard_founder_beta_active) { $dashboard_founder_beta_days = null; $dashboard_founder_beta_expiry_label = ''; $dashboard_founder_beta_last = function_exists('matewa_founder_beta_get_last_result') ? matewa_founder_beta_get_last_result() : []; $dashboard_founder_beta_last = is_array($dashboard_founder_beta_last) ? $dashboard_founder_beta_last : []; $dashboard_founder_beta_expiry = isset($dashboard_founder_beta_last['beta_expiry']) ? trim((string) $dashboard_founder_beta_last['beta_expiry']) : ''; if ('' !== $dashboard_founder_beta_expiry) { $dashboard_founder_beta_expiry_ts = strtotime($dashboard_founder_beta_expiry . ' 23:59:59'); if ($dashboard_founder_beta_expiry_ts) { $dashboard_founder_beta_days = max(0, (int) ceil(($dashboard_founder_beta_expiry_ts - time()) / (defined('DAY_IN_SECONDS') ? (int) DAY_IN_SECONDS : 86400))); $dashboard_founder_beta_expiry_label = $dashboard_founder_beta_expiry; } } $dashboard_plan_nudge_title = 'Founder Beta'; $dashboard_plan_nudge_value = null !== $dashboard_founder_beta_days ? (1 === $dashboard_founder_beta_days ? '1 day left' : $dashboard_founder_beta_days . ' days left') : 'Active'; $dashboard_plan_nudge_detail = '' !== $dashboard_founder_beta_expiry_label ? 'Founder Beta expires ' . $dashboard_founder_beta_expiry_label : 'Upgrade when you are ready.'; $dashboard_plan_nudge_label = 'Convert'; $dashboard_plan_nudge_tone = (null !== $dashboard_founder_beta_days && $dashboard_founder_beta_days <= 30) ? 'is-warning' : 'is-founder'; } elseif ('pro' === $mode) { $dashboard_plan_nudge_title = 'Pro active'; $dashboard_plan_nudge_value = 'Plan live'; $dashboard_plan_nudge_detail = 'Manage your Pro plan.'; $dashboard_plan_nudge_label = 'Manage'; $dashboard_plan_nudge_tone = 'is-pro'; } elseif ('master' === $mode) { $dashboard_plan_nudge_title = 'Founder access'; $dashboard_plan_nudge_value = 'Active'; $dashboard_plan_nudge_detail = 'Master access is enabled.'; $dashboard_plan_nudge_label = 'Open billing'; $dashboard_plan_nudge_tone = 'is-master'; } $dashboard_business_ready = '' !== trim((string) $business); $dashboard_whatsapp_ready = '' !== trim((string) $number); $dashboard_inbox_ready = '' !== trim((string) $leads_email) && is_email($leads_email); $dashboard_email_routing_required = !in_array($mode, ['free', 'trial_expired'], true); $dashboard_selected_pages_count = count($widget_page_ids) + ('1' === $widget_include_homepage ? 1 : 0); $dashboard_pages_ready = 'selected' !== $widget_display_mode || $dashboard_selected_pages_count > 0; if ('selected' === $widget_display_mode) { if ($dashboard_selected_pages_count > 0) { $dashboard_display_pages_text = sprintf( '%d selected %s', $dashboard_selected_pages_count, 1 === $dashboard_selected_pages_count ? 'page' : 'pages' ); } else { $dashboard_display_pages_text = 'No selected pages'; } } else { $dashboard_display_pages_text = 'All pages'; } $dashboard_language_text = 'yes' === (string) $langSwitch ? 'Language assist on' : 'English baseline'; $dashboard_industry_text = '' !== trim((string) $active_vertical_label) ? $active_vertical_label : 'General'; $dashboard_brand_name = '' !== trim((string) $business) ? trim((string) $business) : 'Plumber Co.'; $dashboard_setup_items = [ [ 'label' => 'Widget is live', 'ready' => $dashboard_widget_enabled, 'href' => '#matewa-display-settings-section', ], [ 'label' => 'WhatsApp connected', 'ready' => $dashboard_whatsapp_ready, 'href' => '#matewa_number', ], [ 'label' => 'Visitor buttons configured', 'ready' => true, 'href' => '#matewa-chip-labels-section', ], [ 'label' => 'Pages selected', 'ready' => $dashboard_pages_ready, 'href' => '#matewa-display-settings-section', ], [ 'label' => $dashboard_email_routing_required ? 'Lead inbox ready' : 'Email leads (Pro)', 'ready' => $dashboard_email_routing_required ? $dashboard_inbox_ready : true, 'href' => $dashboard_email_routing_required ? '#matewa_leads_email' : '#matewa-lead-routing-heading', ], ]; $dashboard_ready_count = 0; foreach ($dashboard_setup_items as $dashboard_setup_item) { if (!empty($dashboard_setup_item['ready'])) { $dashboard_ready_count++; } } $dashboard_setup_total = max(1, count($dashboard_setup_items)); $dashboard_setup_percent = (int) round(($dashboard_ready_count / $dashboard_setup_total) * 100); $dashboard_setup_complete = $dashboard_ready_count >= $dashboard_setup_total; $dashboard_setup_status_title = $dashboard_setup_complete ? 'All set up!' : 'Finish setup'; $dashboard_setup_status_copy = $dashboard_setup_complete ? 'Your widget is fully configured and live.' : 'Finish the remaining setup steps to go live.'; $dashboard_headline = $dashboard_widget_enabled ? 'Your widget is live and working hard for you.' : 'Your widget is nearly ready to work for you.'; $dashboard_intro_copy = $dashboard_widget_enabled ? 'Keep it up! You are capturing leads and starting conversations on WhatsApp.' : 'Turn the widget on when you are ready to capture more leads from your site.'; $dashboard_benefits = [ [ 'icon' => 'dashicons-groups', 'label' => 'Capture more leads', ], [ 'icon' => 'dashicons-phone', 'label' => 'Start WhatsApp chats', ], [ 'icon' => 'dashicons-admin-page', 'label' => 'Works on every page', ], [ 'icon' => 'dashicons-yes-alt', 'label' => 'Easy to manage', ], ]; $dashboard_country_selector_text = $widget_show_country_selector ? 'On' : 'Off'; $dashboard_country_selector_copy = $widget_show_country_selector ? 'Visitors can choose their country code before opening WhatsApp.' : 'Hidden on the widget. The saved default country code is still used.'; $dashboard_plan_copy = 'Free plan status is shown here.'; if ('trial_active' === $mode) { $dashboard_plan_copy = 'Trial access is active on this site.'; } elseif ('trial_expired' === $mode) { $dashboard_plan_copy = 'Trial has ended. Add a valid licence to move into Pro.'; } elseif ('pro' === $mode) { $dashboard_plan_copy = 'Pro access is active on this site.'; } elseif ('master' === $mode) { $dashboard_plan_copy = 'Founder or master access is active on this site.'; } $dashboard_next_action_label = 'Review visitor buttons'; $dashboard_next_action_copy = 'Your setup looks healthy. Check the buttons visitors will use next.'; $dashboard_next_action_href = '#matewa-chip-labels-section'; if (!$dashboard_widget_enabled) { $dashboard_next_action_label = 'Turn widget on'; $dashboard_next_action_copy = 'Switch the widget on when you are ready for it to appear on the website.'; $dashboard_next_action_href = '#matewa-display-settings-section'; } elseif (!$dashboard_whatsapp_ready) { $dashboard_next_action_label = 'Add WhatsApp number'; $dashboard_next_action_copy = 'Add the number visitors should be sent to when they tap a button.'; $dashboard_next_action_href = '#matewa_number'; } elseif ($dashboard_email_routing_required && !$dashboard_inbox_ready) { $dashboard_next_action_label = 'Add lead inbox'; $dashboard_next_action_copy = 'Add the inbox where new lead notifications should arrive.'; $dashboard_next_action_href = '#matewa_leads_email'; } elseif (!$dashboard_pages_ready) { $dashboard_next_action_label = 'Choose widget pages'; $dashboard_next_action_copy = 'Pick at least one page or set the widget to show more widely.'; $dashboard_next_action_href = '#matewa-display-settings-section'; } $dashboard_status_cards = [ [ 'label' => 'Widget status', 'value' => $dashboard_widget_status_text, 'copy' => $dashboard_widget_enabled ? 'The website widget is switched on.' : 'The website widget is switched off.', 'ready' => $dashboard_widget_enabled, 'href' => '#matewa-display-settings-section', 'icon' => 'dashicons-visibility', ], [ 'label' => 'WhatsApp setup', 'value' => $dashboard_whatsapp_ready ? 'Ready' : 'Needed', 'copy' => $dashboard_whatsapp_ready ? 'A WhatsApp number is saved.' : 'Add the WhatsApp number for visitor handoff.', 'ready' => $dashboard_whatsapp_ready, 'href' => '#matewa_number', 'icon' => 'dashicons-phone', ], [ 'label' => $dashboard_email_routing_required ? 'Lead inbox' : 'Email leads', 'value' => $dashboard_email_routing_required ? ($dashboard_inbox_ready ? 'Ready' : 'Needed') : 'PRO', 'copy' => $dashboard_email_routing_required ? ($dashboard_inbox_ready ? 'Lead notifications have a destination inbox.' : 'Add a valid lead destination inbox.') : 'Email lead delivery is available with Pro.', 'ready' => $dashboard_email_routing_required ? $dashboard_inbox_ready : true, 'href' => $dashboard_email_routing_required ? '#matewa_leads_email' : '#matewa-lead-routing-heading', 'icon' => 'dashicons-email-alt', ], [ 'label' => 'Plan access', 'value' => $dashboard_plan_text, 'copy' => $dashboard_plan_copy, 'ready' => true, 'href' => '#matewa_license_key', 'icon' => 'dashicons-star-filled', ], [ 'label' => 'Country selector', 'value' => $dashboard_country_selector_text, 'copy' => $dashboard_country_selector_copy, 'ready' => true, 'href' => '#matewa-display-settings-section', 'icon' => 'dashicons-admin-site-alt3', ], [ 'label' => 'Next action', 'value' => $dashboard_next_action_label, 'copy' => $dashboard_next_action_copy, 'ready' => $dashboard_setup_complete, 'href' => $dashboard_next_action_href, 'icon' => 'dashicons-lightbulb', ], ]; $dashboard_quick_actions = [ [ 'label' => 'Edit widget display', 'copy' => 'Choose where the widget appears.', 'href' => '#matewa-display-settings-section', 'icon' => 'dashicons-admin-page', 'ready' => true, ], [ 'label' => 'Edit widget labels', 'copy' => 'Update the six visitor buttons.', 'href' => '#matewa-chip-labels-section', 'icon' => 'dashicons-format-chat', 'ready' => true, ], [ 'label' => 'Check WhatsApp setup', 'copy' => $dashboard_whatsapp_ready ? 'WhatsApp number saved.' : 'WhatsApp number still needed.', 'href' => '#matewa_number', 'icon' => 'dashicons-phone', 'ready' => $dashboard_whatsapp_ready, ], [ 'label' => 'Check lead inbox', 'copy' => $dashboard_inbox_ready ? 'Lead inbox saved.' : 'Lead inbox still needed.', 'href' => '#matewa_leads_email', 'icon' => 'dashicons-email-alt', 'ready' => $dashboard_inbox_ready, ], [ 'label' => 'Check plan access', 'copy' => $dashboard_plan_text . ' plan shown.', 'href' => '#matewa_license_key', 'icon' => 'dashicons-star-filled', 'ready' => true, ], ]; $dashboard_plan_orbit_text = 'Founder / Master' === $dashboard_plan_text ? 'Founder' : $dashboard_plan_text; if ('Founder Beta' === $dashboard_plan_text) { $dashboard_plan_orbit_text = 'Beta'; } $dashboard_pages_orbit_text = 'All pages' === $dashboard_display_pages_text ? 'All pages' : 'Selected'; /* * Phase 5-A-14E Client View Leads/Status circle toggle. * Phase 5-A-14F adds local aggregate export/reset controls in the right rail. * It does not store raw chats, IPs, visitor IDs, send remote data, * change lead routing, change frontend behaviour or alter entitlement logic. */ $dashboard_lead_history = function_exists('matewa_get_lead_history_aggregates') ? matewa_get_lead_history_aggregates() : []; $dashboard_lead_history = is_array($dashboard_lead_history) ? $dashboard_lead_history : []; $dashboard_history_rows = function_exists('matewa_prepare_lead_history_month_rows') ? matewa_prepare_lead_history_month_rows($dashboard_lead_history, 4) : []; $dashboard_history_current_month_key = function_exists('matewa_lead_history_current_month_key') ? matewa_lead_history_current_month_key() : date_i18n('Y-m', current_time('timestamp')); $dashboard_page_rows = function_exists('matewa_prepare_lead_history_page_rows') ? matewa_prepare_lead_history_page_rows(4) : []; $dashboard_history_current_month_label = function_exists('matewa_lead_history_month_label') ? matewa_lead_history_month_label($dashboard_history_current_month_key, 'F Y') : $dashboard_history_current_month_key; $dashboard_history_retention_options = function_exists('matewa_lead_history_retention_options') ? matewa_lead_history_retention_options() : [28 => '28 days']; $dashboard_history_retention_days = function_exists('matewa_get_lead_history_retention_days') ? matewa_get_lead_history_retention_days() : absint(get_option('matewa_lead_history_retention_days', 28)); $dashboard_history_retention_label = function_exists('matewa_lead_history_retention_label') ? matewa_lead_history_retention_label($dashboard_history_retention_days) : ((0 === $dashboard_history_retention_days) ? 'Manual-only' : (string) $dashboard_history_retention_days . ' days'); $dashboard_history_notice_key = isset($_GET['matewa_history_notice']) ? sanitize_key(wp_unslash($_GET['matewa_history_notice'])) : ''; $dashboard_history_notice_messages = [ 'month_reset' => 'Current month history was reset.', 'history_reset' => 'Lead history was reset.', 'hard_reset' => 'Hard reset completed. Lead reporting is back to a clean state.', 'retention_saved' => 'Lead history retention setting was saved.', 'confirm_required' => 'Confirmation was missing or did not match. No history was reset.', 'unknown_action' => 'History action was not recognised. No changes were made.', ]; $dashboard_history_notice_message = $dashboard_history_notice_messages[$dashboard_history_notice_key] ?? ''; $dashboard_history_notice_type = in_array($dashboard_history_notice_key, ['confirm_required', 'unknown_action'], true) ? 'warning' : 'success'; $dashboard_lead_yearly_total = absint($dashboard_lead_history['yearly_total'] ?? 0); $dashboard_lead_month_total = absint($dashboard_lead_history['month_total'] ?? 0); $dashboard_lead_week_total = absint($dashboard_lead_history['week_total'] ?? 0); $dashboard_whatsapp_handoff_total = absint($dashboard_lead_history['whatsapp_handoffs'] ?? 0); $dashboard_lead_email_total = absint($dashboard_lead_history['lead_emails_sent'] ?? 0); $dashboard_phone_only_total = absint($dashboard_lead_history['phone_only_leads'] ?? 0); $dashboard_widget_open_total = absint($dashboard_lead_history['widget_opens'] ?? 0); $dashboard_handoff_rate = 0; $dashboard_handoff_rate_state = 'waiting'; $dashboard_handoff_rate_label = '—'; $dashboard_handoff_summary = 'Waiting for opens'; if ($dashboard_widget_open_total > 0) { if ($dashboard_whatsapp_handoff_total > $dashboard_widget_open_total) { $dashboard_handoff_rate_state = 'calibrating'; $dashboard_handoff_rate_label = 'Calibrating'; $dashboard_handoff_summary = 'Open data settling'; } else { $dashboard_handoff_rate = (int) round(($dashboard_whatsapp_handoff_total / max(1, $dashboard_widget_open_total)) * 100); $dashboard_handoff_rate_state = 'ready'; $dashboard_handoff_rate_label = (string) $dashboard_handoff_rate . '%'; $dashboard_handoff_summary = sprintf('%2$d chat%3$s from %1$d open%4$s', $dashboard_widget_open_total, $dashboard_whatsapp_handoff_total, 1 === $dashboard_whatsapp_handoff_total ? '' : 's', 1 === $dashboard_widget_open_total ? '' : 's'); } } $dashboard_last_lead_label = 'None yet'; if (!empty($dashboard_lead_history['last_activity'])) { $dashboard_last_activity_raw = sanitize_text_field((string) $dashboard_lead_history['last_activity']); $dashboard_last_activity_ts = strtotime($dashboard_last_activity_raw); if (false !== $dashboard_last_activity_ts) { $dashboard_last_lead_label = date_i18n(get_option('date_format', 'j M Y'), $dashboard_last_activity_ts); } } /* * Phase 5-A-18 Lead inbox value panel polish. * Display-only dashboard copy/status values for the configured lead * destination inbox. No wp_mail, routing, storage or save-handler change. */ $dashboard_inbox_display = $dashboard_inbox_ready ? sanitize_email((string) $leads_email) : 'Not set'; $dashboard_inbox_value_state = $dashboard_inbox_ready ? 'Ready' : 'Needed'; $dashboard_inbox_value_copy = $dashboard_inbox_ready ? 'Website leads and weekly summaries are sent to this inbox.' : 'Add a sales or enquiries inbox so new website leads have somewhere to arrive.'; $dashboard_inbox_activity_copy = $dashboard_lead_email_total > 0 ? sprintf( '%1$d lead email%2$s sent. Latest local lead activity: %3$s.', $dashboard_lead_email_total, 1 === $dashboard_lead_email_total ? '' : 's', $dashboard_last_lead_label ) : 'No lead emails sent yet. Test or live leads will appear here once delivery starts.'; $dashboard_has_lead_activity = $dashboard_lead_yearly_total > 0 || $dashboard_lead_month_total > 0 || $dashboard_lead_week_total > 0 || $dashboard_whatsapp_handoff_total > 0 || $dashboard_widget_open_total > 0 || $dashboard_lead_email_total > 0 || $dashboard_phone_only_total > 0; /* * Phase 5-A-16A Lead activity snapshot simplification. * Summary-strip copy removed; stat cards now carry the local value snapshot. */ $dashboard_default_circle_view = ($dashboard_setup_complete || $dashboard_has_lead_activity) ? 'leads' : 'status'; $dashboard_leads_centre_metric = [ 'value' => (string) $dashboard_lead_yearly_total, 'label' => 'Leads this year', 'trend' => $dashboard_has_lead_activity ? 'Local lead activity' : 'Waiting for first lead', 'tone' => $dashboard_has_lead_activity ? 'ready' : 'waiting', 'icon' => 'dashicons-chart-line', ]; $dashboard_leads_orbit_metrics = [ [ 'value' => (string) $dashboard_lead_month_total, 'label' => 'This month', 'trend' => $dashboard_lead_month_total > 0 ? 'Lead activity' : 'Clean month', 'tone' => $dashboard_lead_month_total > 0 ? 'ready' : 'waiting', ], [ 'value' => (string) $dashboard_lead_week_total, 'label' => 'This week', 'trend' => $dashboard_lead_week_total > 0 ? 'Recent leads' : 'No leads yet', 'tone' => $dashboard_lead_week_total > 0 ? 'ready' : 'waiting', ], [ 'value' => (string) $dashboard_widget_open_total, 'label' => 'Website chats opened', 'trend' => $dashboard_widget_open_total > 0 ? 'Visitor engagement' : 'Waiting for opens', 'tone' => $dashboard_widget_open_total > 0 ? 'ready' : 'waiting', ], [ 'value' => $dashboard_handoff_rate_label, 'label' => 'WhatsApp rate', 'trend' => $dashboard_handoff_summary, 'tone' => ('calibrating' === $dashboard_handoff_rate_state) ? 'calibrating' : (('ready' === $dashboard_handoff_rate_state && $dashboard_whatsapp_handoff_total > 0) ? 'ready' : 'waiting'), ], [ 'value' => (string) $dashboard_lead_email_total, 'label' => 'Leads emailed', 'trend' => $dashboard_lead_email_total > 0 ? 'Sent to inbox' : 'None sent yet', 'tone' => $dashboard_lead_email_total > 0 ? 'ready' : 'waiting', ], [ 'value' => $dashboard_last_lead_label, 'label' => 'Last lead', 'trend' => $dashboard_has_lead_activity ? 'Latest activity' : 'Not recorded yet', 'tone' => $dashboard_has_lead_activity ? 'ready' : 'waiting', ], ]; $dashboard_plan_centre_trend = 'Free plan active'; $dashboard_plan_centre_tone = 'ready'; if ('trial_active' === $mode) { $dashboard_plan_centre_trend = 'Trial active'; } elseif ('trial_expired' === $mode) { $dashboard_plan_centre_trend = 'Licence needed'; $dashboard_plan_centre_tone = 'needed'; } elseif ($dashboard_agency_active) { $dashboard_plan_centre_trend = 'Agency own-site access active'; } elseif ($dashboard_founder_beta_active) { $dashboard_plan_centre_trend = 'Beta access active'; } elseif ('pro' === $mode) { $dashboard_plan_centre_trend = 'Pro access active'; } elseif ('master' === $mode) { $dashboard_plan_centre_trend = 'Founder access'; } elseif ($saved_key_is_founder_beta && $has_key && !$dashboard_founder_beta_active) { $dashboard_plan_centre_trend = 'Check beta'; $dashboard_plan_centre_tone = 'needed'; } elseif ($has_key && !$license_valid && in_array($license_code, ['deferred_admin_request', 'invalid', 'invalid_cached', 'request_error', 'invalid_response', 'not_configured'], true)) { $dashboard_plan_centre_trend = 'Check licence'; $dashboard_plan_centre_tone = 'needed'; } $dashboard_status_centre_metric = [ 'value' => $dashboard_plan_orbit_text, 'label' => 'Plan status', 'trend' => $dashboard_plan_centre_trend, 'tone' => $dashboard_plan_centre_tone, 'icon' => 'dashicons-star-filled', 'class' => 'is-plan-centre', ]; $dashboard_status_orbit_metrics = [ [ 'value' => (string) $dashboard_setup_percent . '%', 'label' => 'Setup', 'trend' => $dashboard_setup_complete ? 'Ready for beta' : 'Needs attention', 'tone' => $dashboard_setup_complete ? 'ready' : 'needed', ], [ 'value' => $dashboard_widget_status_text, 'label' => 'Widget', 'trend' => $dashboard_widget_enabled ? 'Active' : 'Off', 'tone' => $dashboard_widget_enabled ? 'ready' : 'needed', ], [ 'value' => $dashboard_whatsapp_ready ? 'Ready' : 'Needed', 'label' => 'WhatsApp', 'trend' => $dashboard_whatsapp_ready ? 'Saved' : 'Add number', 'tone' => $dashboard_whatsapp_ready ? 'ready' : 'needed', ], [ 'value' => $dashboard_inbox_ready ? 'Ready' : 'Needed', 'label' => 'Lead inbox', 'trend' => $dashboard_inbox_ready ? 'Saved' : 'Add inbox', 'tone' => $dashboard_inbox_ready ? 'ready' : 'needed', ], [ 'value' => $dashboard_country_selector_text, 'label' => 'Country code', 'trend' => $widget_show_country_selector ? 'Visible' : 'Hidden', 'tone' => 'ready', ], [ 'value' => $dashboard_pages_orbit_text, 'label' => 'Pages', 'trend' => $dashboard_pages_ready ? $dashboard_display_pages_text : 'Choose pages', 'tone' => $dashboard_pages_ready ? 'ready' : 'needed', ], ]; /* * Phase 5-A-15 Setup health and status panel. * Read-only dashboard values only: no duplicated save forms, no new storage, * no entitlement change and no frontend/widget behaviour change. */ $dashboard_plan_health_ready = 'needed' !== $dashboard_plan_centre_tone; $dashboard_setup_health_cards = [ [ 'label' => 'Widget active', 'value' => $dashboard_widget_enabled ? 'Yes' : 'No', 'copy' => $dashboard_widget_enabled ? 'The website widget is switched on.' : 'Turn the widget on before beta testing.', 'tone' => $dashboard_widget_enabled ? 'ready' : 'needed', 'icon' => 'dashicons-visibility', ], [ 'label' => 'WhatsApp number set', 'value' => $dashboard_whatsapp_ready ? 'Yes' : 'No', 'copy' => $dashboard_whatsapp_ready ? 'Visitor handoff has a saved WhatsApp number.' : 'Add the business WhatsApp number.', 'tone' => $dashboard_whatsapp_ready ? 'ready' : 'needed', 'icon' => 'dashicons-phone', ], [ 'label' => 'Lead destination inbox set', 'value' => $dashboard_inbox_ready ? 'Yes' : 'No', 'copy' => $dashboard_inbox_ready ? 'Lead emails have a valid destination inbox.' : 'Add a valid lead destination inbox.', 'tone' => $dashboard_inbox_ready ? 'ready' : 'needed', 'icon' => 'dashicons-email-alt', ], [ 'label' => 'Plan / trial status', 'value' => $dashboard_plan_text, 'copy' => $dashboard_plan_centre_trend, 'tone' => $dashboard_plan_health_ready ? 'ready' : 'needed', 'icon' => 'dashicons-star-filled', ], [ 'label' => 'Country selector state', 'value' => $widget_show_country_selector ? 'Visible' : 'Hidden', 'copy' => $dashboard_country_selector_copy, 'tone' => 'ready', 'icon' => 'dashicons-admin-site-alt3', ], [ 'label' => 'Last lead activity', 'value' => $dashboard_last_lead_label, 'copy' => $dashboard_has_lead_activity ? 'Latest local lead activity.' : 'No local lead activity recorded yet.', 'tone' => $dashboard_has_lead_activity ? 'ready' : 'waiting', 'icon' => 'dashicons-clock', ], ]; /* * AGENCYOVERVIEWREADONLYLOCK1 — agency client-health circle. * Read-only placeholders only. Real client seat counting, setup packs, * expiry alerts and aggregate chip/industry analytics are later checkpoints. */ $dashboard_agency_client_total = 0; $dashboard_agency_client_used = 0; $dashboard_agency_client_available = 0; $dashboard_agency_setup_pack_count = 0; $dashboard_agency_expiring_count = 0; $dashboard_agency_needs_attention_count = 0; if ($dashboard_agency_active) { if (function_exists('matewa_agency_bundle_get_seat_summary')) { $dashboard_agency_bundle_summary = matewa_agency_bundle_get_seat_summary(); $dashboard_agency_bundle_summary = is_array($dashboard_agency_bundle_summary) ? $dashboard_agency_bundle_summary : []; $dashboard_agency_client_total = isset($dashboard_agency_bundle_summary['total']) ? absint($dashboard_agency_bundle_summary['total']) : 0; $dashboard_agency_client_used = isset($dashboard_agency_bundle_summary['used']) ? absint($dashboard_agency_bundle_summary['used']) : 0; $dashboard_agency_client_available = isset($dashboard_agency_bundle_summary['available']) ? absint($dashboard_agency_bundle_summary['available']) : max(0, $dashboard_agency_client_total - $dashboard_agency_client_used); $dashboard_agency_expiring_count = isset($dashboard_agency_bundle_summary['expiring_soon']) ? absint($dashboard_agency_bundle_summary['expiring_soon']) : 0; $dashboard_agency_needs_attention_count = isset($dashboard_agency_bundle_summary['needs_attention']) ? absint($dashboard_agency_bundle_summary['needs_attention']) : 0; if (function_exists('matewa_agency_client_pack_get_summary')) { $dashboard_agency_pack_summary = matewa_agency_client_pack_get_summary(); $dashboard_agency_pack_summary = is_array($dashboard_agency_pack_summary) ? $dashboard_agency_pack_summary : []; $dashboard_agency_setup_pack_count = isset($dashboard_agency_pack_summary['total']) ? absint($dashboard_agency_pack_summary['total']) : 0; $dashboard_agency_needs_attention_count += isset($dashboard_agency_pack_summary['needs_attention']) ? absint($dashboard_agency_pack_summary['needs_attention']) : 0; $dashboard_agency_expiring_count += isset($dashboard_agency_pack_summary['expiring_soon']) ? absint($dashboard_agency_pack_summary['expiring_soon']) : 0; } } elseif (function_exists('matewa_agency_entitlement_get_summary')) { $dashboard_agency_summary = matewa_agency_entitlement_get_summary(); $dashboard_agency_summary = is_array($dashboard_agency_summary) ? $dashboard_agency_summary : []; $dashboard_agency_client_total = isset($dashboard_agency_summary['client_seats']) ? absint($dashboard_agency_summary['client_seats']) : 0; $dashboard_agency_client_used = 0; $dashboard_agency_client_available = max(0, $dashboard_agency_client_total - $dashboard_agency_client_used); $dashboard_agency_needs_attention_count = $dashboard_agency_client_total > 0 ? 0 : 1; } } $dashboard_agency_clients_centre_metric = [ 'value' => (string) $dashboard_agency_client_used . ' / ' . (string) $dashboard_agency_client_total, 'label' => 'Client seats', 'trend' => $dashboard_agency_client_total > 0 ? ((string) $dashboard_agency_client_available . ' available') : 'Buy client licences', 'tone' => $dashboard_agency_client_total > 0 ? 'ready' : 'waiting', 'icon' => 'dashicons-groups', 'class' => 'is-agency-centre', ]; $dashboard_agency_clients_orbit_metrics = [ [ 'value' => (string) $dashboard_agency_client_used, 'label' => 'Live clients', 'trend' => $dashboard_agency_client_used > 0 ? 'Client sites live' : 'None yet', 'tone' => $dashboard_agency_client_used > 0 ? 'ready' : 'waiting', ], [ 'value' => (string) $dashboard_agency_setup_pack_count, 'label' => 'Setup packs', 'trend' => $dashboard_agency_setup_pack_count > 0 ? 'Manual packs saved' : 'Manual packs next', 'tone' => 'waiting', ], [ 'value' => (string) $dashboard_agency_expiring_count, 'label' => 'Expiring soon', 'trend' => 'Expiry model next', 'tone' => 'waiting', ], [ 'value' => (string) $dashboard_agency_needs_attention_count, 'label' => 'Needs setup', 'trend' => $dashboard_agency_needs_attention_count > 0 ? 'Review client packs' : ($dashboard_agency_client_total > 0 ? 'Ready for clients' : 'Add bundle seats'), 'tone' => $dashboard_agency_client_total > 0 ? 'ready' : 'needed', ], [ 'value' => 'Waiting', 'label' => 'Top industry', 'trend' => 'Analytics later', 'tone' => 'waiting', ], [ 'value' => 'Waiting', 'label' => 'Top chip', 'trend' => 'Chip analytics later', 'tone' => 'waiting', ], ]; $dashboard_circle_views = [ 'leads' => [ 'label' => 'Leads', 'heading' => 'Lead activity', 'aria' => 'Lead activity overview', 'centre' => $dashboard_leads_centre_metric, 'orbit' => $dashboard_leads_orbit_metrics, ], 'status' => [ 'label' => 'Status', 'heading' => 'Setup health', 'aria' => 'Setup health metrics', 'centre' => $dashboard_status_centre_metric, 'orbit' => $dashboard_status_orbit_metrics, 'sidebar' => 'matewa-circle-sidebar-status', ], ]; if ($dashboard_agency_active) { $dashboard_circle_views['clients'] = [ 'label' => 'Clients', 'heading' => 'Client health', 'aria' => 'Agency client health overview', 'centre' => $dashboard_agency_clients_centre_metric, 'orbit' => $dashboard_agency_clients_orbit_metrics, 'sidebar' => 'matewa-circle-sidebar-clients', ]; } /* Legacy variable names retained for any future fallback partial usage. */ $dashboard_centre_metric = $dashboard_status_centre_metric; $dashboard_orbit_metrics = $dashboard_status_orbit_metrics; $dashboard_admin_page_copy = [ 'dashboard' => [ 'title' => 'Dashboard', 'description' => '', ], 'setup' => [ 'title' => 'Setup', 'description' => '', ], 'agency' => [ 'title' => 'Agency Hub', 'description' => 'Manage agency access, client seats and setup packs.', ], 'display' => [ 'title' => 'Appearance & pages', 'description' => '', ], 'buttons' => [ 'title' => 'Visitor buttons', 'description' => '', ], ]; $dashboard_saved_section = (isset($_GET['matewa_saved_section']) && is_scalar($_GET['matewa_saved_section'])) ? sanitize_key(wp_unslash($_GET['matewa_saved_section'])) : ''; $dashboard_initial_panel = matewa_admin_sanitise_return_section($dashboard_saved_section, 'dashboard'); if ('agency' === $dashboard_initial_panel && empty($dashboard_agency_hub_visible)) { $dashboard_initial_panel = 'dashboard'; } $dashboard_initial_page_copy = $dashboard_admin_page_copy[$dashboard_initial_panel] ?? $dashboard_admin_page_copy['dashboard']; $dashboard_nav_items = [ [ 'label' => 'Dashboard', 'icon' => 'dashicons-dashboard', 'href' => '#matewa-admin-panel-dashboard', 'panel' => 'dashboard', 'active' => 'dashboard' === $dashboard_initial_panel, ], [ 'label' => 'Setup', 'icon' => 'dashicons-admin-settings', 'href' => '#matewa-core-settings-section', 'panel' => 'setup', 'active' => 'setup' === $dashboard_initial_panel, ], ]; if (!empty($dashboard_agency_hub_visible)) { $dashboard_nav_items[] = [ 'label' => 'Agency Hub', 'icon' => 'dashicons-groups', 'href' => '#matewa-agency-hub-section', 'panel' => 'agency', 'active' => 'agency' === $dashboard_initial_panel, ]; } $dashboard_nav_items = array_merge($dashboard_nav_items, [ [ 'label' => 'Appearance & pages', 'icon' => 'dashicons-admin-page', 'href' => '#matewa-display-settings-section', 'panel' => 'display', 'active' => 'display' === $dashboard_initial_panel, 'pro_locked' => in_array($mode, ['free', 'trial_expired'], true), ], [ 'label' => 'Visitor buttons', 'icon' => 'dashicons-format-chat', 'href' => '#matewa-chip-labels-section', 'panel' => 'buttons', 'active' => 'buttons' === $dashboard_initial_panel, ], ]); ?>

247ChatMate settings

Preview widget
Setup

Business and widget basics

Set the details your widget needs. Keep it simple, then save your changes.

Agency Hub

Agency access and client rollout

Your own-site agency access is live. Client seats and setup packs stay separate from this free agency key.

Visitor buttons

Choose the buttons visitors see