true,
'status' => 'active',
'mode' => 'agency_client_seat',
'setup_pack_id' => $setup_pack_id,
'agency_id' => $agency_id,
'assigned_bundle_id' => $assigned_bundle_id,
'seat_status' => '' !== $seat_status ? $seat_status : 'assigned',
'licence_status' => sanitize_key((string) ($explicit['licence_status'] ?? ($seat['licence_status'] ?? 'agency_managed'))),
'renews_at' => sanitize_text_field((string) ($explicit['renews_at'] ?? ($seat['renews_at'] ?? ''))),
'expires_at' => sanitize_text_field((string) ($explicit['expires_at'] ?? ($seat['expires_at'] ?? ''))),
'agency_admin_email' => '',
'agency_support_email' => '',
'client_licence_key_included' => false,
'master_licence_exported' => false,
'source' => 'agency_client_setup_pack_import',
'updated_at' => time(),
);
}
}
// AGENCYCLIENTPRIVACYFIX1:
// Client sites do not need the agency owner's personal/admin email in the
// entitlement record. Remove legacy copies on admin load without touching the
// client business, routing or imported setup values.
add_action('admin_init', function () {
if (!defined('MATEWA_AGENCY_CLIENT_ENTITLEMENT_OPTION')) {
return;
}
$entitlement = get_option(MATEWA_AGENCY_CLIENT_ENTITLEMENT_OPTION, array());
if (!is_array($entitlement)) {
return;
}
$changed = false;
foreach (array('agency_admin_email', 'agency_support_email') as $field) {
if (!empty($entitlement[$field])) {
$entitlement[$field] = '';
$changed = true;
}
}
if ($changed) {
update_option(MATEWA_AGENCY_CLIENT_ENTITLEMENT_OPTION, $entitlement, false);
}
}, 6);
add_filter('matewa_force_license_mode', function ($mode) {
if (function_exists('matewa_agency_client_entitlement_is_active') && matewa_agency_client_entitlement_is_active()) {
return defined('MATEWA_MODE_PRO') ? MATEWA_MODE_PRO : 'pro';
}
return $mode;
}, 20);
if (!function_exists('matewa_agency_client_import_redirect_url')) {
function matewa_agency_client_import_redirect_url($notice = '', $extra_args = array()) {
$args = array_merge(
array(
'page' => '247chatmate',
'matewa_saved_section' => 'agency',
),
is_array($extra_args) ? $extra_args : array()
);
if ('' !== (string) $notice) {
$args['matewa_agency_import_notice'] = sanitize_key((string) $notice);
}
return add_query_arg($args, admin_url('admin.php')) . '#matewa-agency-client-import-panel';
}
}
if (!function_exists('matewa_agency_client_import_redirect')) {
function matewa_agency_client_import_redirect($notice, $extra_args = array()) {
wp_safe_redirect(matewa_agency_client_import_redirect_url($notice, $extra_args));
exit;
}
}
if (!function_exists('matewa_agency_client_import_clean_chip_label')) {
function matewa_agency_client_import_clean_chip_label($value) {
if (function_exists('matewa_agency_client_pack_clean_chip_label')) {
return matewa_agency_client_pack_clean_chip_label($value);
}
$label = sanitize_text_field((string) $value);
$label = preg_replace('/\s+/', ' ', $label);
$label = trim((string) $label);
if (function_exists('mb_substr')) {
return mb_substr($label, 0, 34);
}
return substr($label, 0, 34);
}
}
if (!function_exists('matewa_agency_client_import_clean_phone')) {
function matewa_agency_client_import_clean_phone($value) {
if (function_exists('matewa_agency_client_pack_clean_phone')) {
return matewa_agency_client_pack_clean_phone($value);
}
return preg_replace('/[^0-9\+]/', '', (string) $value);
}
}
if (!function_exists('matewa_agency_client_import_payload_hash')) {
function matewa_agency_client_import_payload_hash($payload) {
$json = wp_json_encode($payload);
return hash('sha256', is_string($json) ? $json : maybe_serialize($payload));
}
}
if (!function_exists('matewa_agency_client_import_allowed_widget_display_mode')) {
function matewa_agency_client_import_allowed_widget_display_mode($value) {
$mode = sanitize_key((string) $value);
if ('homepage' === $mode) {
return 'selected';
}
return in_array($mode, array('all', 'selected', 'excluded'), true) ? $mode : 'all';
}
}
if (!function_exists('matewa_agency_client_import_clean_page_url')) {
function matewa_agency_client_import_clean_page_url($value, $payload_domain = '') {
$value = trim((string) $value);
if ('' === $value) {
return '';
}
$url = esc_url_raw($value);
if ('' === $url) {
return '';
}
$parts = wp_parse_url($url);
if (!is_array($parts) || empty($parts['host'])) {
return '';
}
$scheme = isset($parts['scheme']) ? strtolower((string) $parts['scheme']) : 'https';
if (!in_array($scheme, array('http', 'https'), true)) {
return '';
}
$host = strtolower((string) $parts['host']);
$host = preg_replace('/^www\./', '', $host);
$payload_domain = strtolower(trim((string) $payload_domain));
$payload_domain = preg_replace('/^https?:\/\//', '', $payload_domain);
$payload_domain = preg_replace('/\/.*$/', '', (string) $payload_domain);
$payload_domain = preg_replace('/^www\./', '', (string) $payload_domain);
if ('' !== $payload_domain && $host !== $payload_domain) {
return '';
}
$path = isset($parts['path']) ? (string) $parts['path'] : '/';
$path = '/' . ltrim($path, '/');
$path = preg_replace('#/+#', '/', $path);
$path = untrailingslashit($path);
if ('' === $path) {
$path = '/';
}
return esc_url_raw($scheme . '://' . $host . ('/' === $path ? '/' : trailingslashit($path)));
}
}
if (!function_exists('matewa_agency_client_import_clean_pending_page_urls')) {
function matewa_agency_client_import_clean_pending_page_urls($value, $payload_domain = '') {
$urls = array();
if (is_array($value)) {
foreach ($value as $item) {
if (is_array($item)) {
$urls[] = $item['url'] ?? '';
} else {
$urls[] = $item;
}
}
}
$out = array();
$seen = array();
foreach ($urls as $url) {
$clean_url = matewa_agency_client_import_clean_page_url($url, $payload_domain);
if ('' === $clean_url) {
continue;
}
$key = strtolower((string) $clean_url);
if (isset($seen[$key])) {
continue;
}
$seen[$key] = true;
$out[] = $clean_url;
if (count($out) >= 30) {
break;
}
}
return $out;
}
}
if (!function_exists('matewa_agency_client_import_path_from_url')) {
function matewa_agency_client_import_path_from_url($url) {
$path = wp_parse_url((string) $url, PHP_URL_PATH);
$path = '/' . ltrim((string) $path, '/');
$path = untrailingslashit($path);
return '' === $path ? '/' : $path;
}
}
if (!function_exists('matewa_agency_client_import_resolve_page_targets')) {
function matewa_agency_client_import_resolve_page_targets($pending_urls) {
$pending_urls = is_array($pending_urls) ? array_values($pending_urls) : array();
$page_ids = array();
$include_homepage = '0';
if (empty($pending_urls)) {
return array('page_ids' => array(), 'include_homepage' => '0', 'matched_count' => 0, 'pending_urls' => array());
}
$wanted_paths = array();
foreach ($pending_urls as $url) {
$path = matewa_agency_client_import_path_from_url($url);
$wanted_paths[$path] = true;
if ('/' === $path) {
$include_homepage = '1';
}
}
$pages = get_pages(array('post_status' => 'publish', 'sort_column' => 'post_title', 'number' => 200));
foreach ($pages as $page) {
if (!is_object($page) || empty($page->ID)) {
continue;
}
$permalink = get_permalink((int) $page->ID);
if (!$permalink) {
continue;
}
$path = matewa_agency_client_import_path_from_url($permalink);
if (isset($wanted_paths[$path])) {
$page_ids[] = absint($page->ID);
}
}
return array(
'page_ids' => array_values(array_unique(array_filter($page_ids))),
'include_homepage' => $include_homepage,
'matched_count' => count(array_values(array_unique(array_filter($page_ids)))) + ('1' === $include_homepage ? 1 : 0),
'pending_urls' => array_values(array_unique($pending_urls)),
);
}
}
if (!function_exists('matewa_agency_client_import_domain_warning')) {
function matewa_agency_client_import_domain_warning($payload_domain) {
$payload_domain = sanitize_text_field((string) $payload_domain);
if ('' === $payload_domain) {
return '';
}
$payload_domain = strtolower(preg_replace('/^https?:\/\//', '', $payload_domain));
$payload_domain = preg_replace('/\/.*$/', '', (string) $payload_domain);
$payload_domain = preg_replace('/^www\./', '', (string) $payload_domain);
$home_host = wp_parse_url(home_url('/'), PHP_URL_HOST);
$home_host = is_string($home_host) ? strtolower(preg_replace('/^www\./', '', $home_host)) : '';
if ('' !== $home_host && '' !== $payload_domain && $home_host !== $payload_domain) {
return sprintf('The setup pack was prepared for %1$s, but this WordPress site appears to be %2$s. Review before applying.', $payload_domain, $home_host);
}
return '';
}
}
if (!function_exists('matewa_agency_client_import_get_intent_keys_for_vertical')) {
function matewa_agency_client_import_get_intent_keys_for_vertical($vertical_key) {
$vertical_key = sanitize_key((string) $vertical_key);
$intent_keys = array();
if ('' !== $vertical_key && function_exists('matewa_get_vertical_config')) {
$config = matewa_get_vertical_config($vertical_key);
$chips = isset($config['chips']) && is_array($config['chips']) ? array_values($config['chips']) : array();
foreach ($chips as $intent_key) {
$intent_key = is_string($intent_key) ? trim($intent_key) : '';
if ('' !== $intent_key) {
$intent_keys[] = $intent_key;
}
}
}
return array_values(array_unique(array_filter($intent_keys)));
}
}
if (!function_exists('matewa_agency_client_import_map_chip_labels_to_intents')) {
function matewa_agency_client_import_map_chip_labels_to_intents($vertical_key, $labels) {
$vertical_key = sanitize_key((string) $vertical_key);
$labels = is_array($labels) ? $labels : array();
$intent_keys = matewa_agency_client_import_get_intent_keys_for_vertical($vertical_key);
$mapped = array();
foreach (array_values($labels) as $index => $label) {
if ($index >= 6) {
break;
}
$intent_key = isset($intent_keys[$index]) ? (string) $intent_keys[$index] : '';
$clean = matewa_agency_client_import_clean_chip_label($label);
if ('' !== $intent_key && '' !== $clean) {
$mapped[$intent_key] = $clean;
}
}
return $mapped;
}
}
if (!function_exists('matewa_agency_client_import_normalise_chip_override_labels')) {
function matewa_agency_client_import_normalise_chip_override_labels($vertical_key, $labels) {
$vertical_key = sanitize_key((string) $vertical_key);
$labels = is_array($labels) ? $labels : array();
$clean = array();
foreach ($labels as $intent_key => $label) {
if (is_int($intent_key) || ctype_digit((string) $intent_key)) {
continue;
}
$intent_key = trim((string) $intent_key);
$label = matewa_agency_client_import_clean_chip_label($label);
if ('' !== $intent_key && '' !== $label) {
$clean[$intent_key] = $label;
}
}
if (!empty($clean)) {
return $clean;
}
return matewa_agency_client_import_map_chip_labels_to_intents($vertical_key, $labels);
}
}
if (!function_exists('matewa_agency_client_import_normalise_chip_overrides')) {
function matewa_agency_client_import_normalise_chip_overrides($value, $vertical_key = '') {
$vertical_key = sanitize_key((string) $vertical_key);
$overrides = array();
if (is_array($value)) {
foreach ($value as $key => $labels) {
$safe_key = sanitize_key((string) $key);
if ('' === $safe_key || !is_array($labels)) {
continue;
}
$clean_labels = matewa_agency_client_import_normalise_chip_override_labels($safe_key, $labels);
if (!empty($clean_labels)) {
$overrides[$safe_key] = $clean_labels;
}
}
}
if (empty($overrides) && '' !== $vertical_key && isset($GLOBALS['matewa_agency_import_current_payload_buttons']) && is_array($GLOBALS['matewa_agency_import_current_payload_buttons'])) {
$labels = array();
$button_intent_labels = array();
foreach (array_slice($GLOBALS['matewa_agency_import_current_payload_buttons'], 0, 6) as $button) {
if (!is_array($button)) {
continue;
}
$clean = matewa_agency_client_import_clean_chip_label($button['label'] ?? '');
if ('' === $clean) {
continue;
}
$intent_key = isset($button['intent_key']) ? trim((string) $button['intent_key']) : '';
if ('' !== $intent_key) {
$button_intent_labels[$intent_key] = $clean;
}
$labels[] = $clean;
}
if (!empty($button_intent_labels)) {
$overrides[$vertical_key] = $button_intent_labels;
} else {
$mapped = matewa_agency_client_import_map_chip_labels_to_intents($vertical_key, $labels);
if (!empty($mapped)) {
$overrides[$vertical_key] = $mapped;
}
}
}
return $overrides;
}
}
if (!function_exists('matewa_agency_client_import_sanitise_payload')) {
function matewa_agency_client_import_sanitise_payload($payload) {
$payload = is_array($payload) ? $payload : array();
$errors = array();
$warnings = array();
$export_type = sanitize_key((string) ($payload['export_type'] ?? ''));
if ('247chatmate_agency_client_setup_pack' !== $export_type) {
$errors[] = 'This file does not look like a 247ChatMate agency client setup JSON export.';
}
$schema_version = sanitize_text_field((string) ($payload['schema_version'] ?? ''));
if ('' === $schema_version) {
$warnings[] = 'Schema version is missing. Import will only use recognised fields.';
}
$client_target = isset($payload['client_target']) && is_array($payload['client_target']) ? $payload['client_target'] : array();
$routing = isset($payload['routing']) && is_array($payload['routing']) ? $payload['routing'] : array();
$business_profile = isset($payload['business_profile']) && is_array($payload['business_profile']) ? $payload['business_profile'] : array();
$visitor_buttons = isset($payload['visitor_buttons']) && is_array($payload['visitor_buttons']) ? $payload['visitor_buttons'] : array();
$remote_sending = isset($payload['remote_sending']) && is_array($payload['remote_sending']) ? $payload['remote_sending'] : array();
$remote_scope = isset($remote_sending['client_widget_scope']) && is_array($remote_sending['client_widget_scope']) ? $remote_sending['client_widget_scope'] : array();
$option_map = isset($payload['client_option_map']) && is_array($payload['client_option_map']) ? $payload['client_option_map'] : array();
$GLOBALS['matewa_agency_import_current_payload_buttons'] = isset($visitor_buttons['buttons']) && is_array($visitor_buttons['buttons']) ? $visitor_buttons['buttons'] : array();
$payload_domain = sanitize_text_field((string) ($client_target['domain'] ?? ''));
$business_name = sanitize_text_field((string) ($option_map['matewa_business_name'] ?? ($client_target['business_name'] ?? '')));
$number = matewa_agency_client_import_clean_phone($option_map['matewa_number'] ?? ($routing['whatsapp_number'] ?? ''));
$marketing_email = sanitize_email((string) ($option_map['matewa_marketing_email'] ?? ($routing['client_admin_email'] ?? '')));
$leads_email = sanitize_email((string) ($option_map['matewa_leads_email'] ?? ($routing['client_leads_email'] ?? '')));
$industry = sanitize_text_field((string) ($option_map['matewa_industry'] ?? ($business_profile['industry'] ?? '')));
$category_key = sanitize_key((string) ($option_map['matewa_vertical_category_selected'] ?? ($business_profile['business_category_key'] ?? 'general')));
$vertical_key = sanitize_key((string) ($option_map['matewa_vertical_selected'] ?? ($business_profile['business_type_key'] ?? 'general')));
if ('' === $category_key) {
$category_key = 'general';
}
if ('' === $vertical_key) {
$vertical_key = 'general';
}
$chip_overrides = matewa_agency_client_import_normalise_chip_overrides($option_map['matewa_chip_label_overrides'] ?? array(), $vertical_key);
$widget_input = isset($option_map['matewa_widget_settings']) && is_array($option_map['matewa_widget_settings']) ? $option_map['matewa_widget_settings'] : array();
if (!empty($remote_scope)) {
$widget_input = array_merge($widget_input, array(
'display_mode' => $remote_scope['display_mode'] ?? ($widget_input['display_mode'] ?? 'all'),
'include_homepage' => $remote_scope['include_homepage'] ?? ($widget_input['include_homepage'] ?? '0'),
'pending_page_urls' => $remote_scope['pending_page_urls'] ?? ($remote_scope['specific_pages'] ?? ($widget_input['pending_page_urls'] ?? array())),
'agency_page_mode' => $remote_scope['page_mode'] ?? ($widget_input['agency_page_mode'] ?? 'all_pages'),
'agency_placement_note' => $remote_scope['note'] ?? ($widget_input['agency_placement_note'] ?? ''),
'remote_sending_scope_imported' => true,
));
}
$placement = isset($payload['placement']) && is_array($payload['placement']) ? $payload['placement'] : array();
$pending_page_urls = matewa_agency_client_import_clean_pending_page_urls($widget_input['pending_page_urls'] ?? ($widget_input['pending_page_targets'] ?? ($placement['specific_pages'] ?? array())), $payload_domain);
$agency_page_mode = sanitize_key((string) ($widget_input['agency_page_mode'] ?? ($placement['page_mode'] ?? 'all_pages')));
if (!in_array($agency_page_mode, array('all_pages', 'homepage', 'specific_pages'), true)) {
$agency_page_mode = 'all_pages';
}
$agency_placement_pending = !empty($widget_input['agency_placement_pending']) || !empty($placement['pending']) || ('specific_pages' === $agency_page_mode && empty($pending_page_urls));
$widget_settings = array(
'display_mode' => matewa_agency_client_import_allowed_widget_display_mode($widget_input['display_mode'] ?? 'all'),
'include_homepage' => !empty($widget_input['include_homepage']) ? '1' : '0',
'pending_page_urls' => $pending_page_urls,
'agency_page_mode' => $agency_page_mode,
'agency_placement_pending' => $agency_placement_pending,
'agency_placement_note' => sanitize_text_field((string) ($widget_input['agency_placement_note'] ?? ($placement['note'] ?? ''))),
'remote_sending_scope_imported' => !empty($widget_input['remote_sending_scope_imported']),
);
if ('homepage' === $agency_page_mode) {
$widget_settings['display_mode'] = 'selected';
$widget_settings['include_homepage'] = '1';
$widget_settings['agency_placement_pending'] = false;
} elseif ('specific_pages' === $agency_page_mode) {
$widget_settings['display_mode'] = 'selected';
$widget_settings['include_homepage'] = '0';
if (empty($pending_page_urls)) {
$warnings[] = 'Specific page placement is pending. No pages will be auto-selected until pages are scanned/selected by the agency or chosen on this client site.';
}
}
$domain_warning = matewa_agency_client_import_domain_warning($payload_domain);
if ('' !== $domain_warning) {
$warnings[] = $domain_warning;
}
if ('' === $business_name) {
$warnings[] = 'Business name is empty in this setup pack.';
}
if ('' === $number) {
$warnings[] = 'WhatsApp number is empty in this setup pack.';
}
if ('' === $leads_email) {
$warnings[] = 'Lead destination inbox is empty in this setup pack.';
}
$setup_pack_id = sanitize_key((string) ($client_target['setup_pack_id'] ?? ''));
$agency_source = isset($payload['agency_source']) && is_array($payload['agency_source']) ? $payload['agency_source'] : array();
$agency_id = sanitize_key((string) ($agency_source['agency_id'] ?? ''));
$client_entitlement = matewa_agency_client_import_normalise_entitlement($payload, array(
'setup_pack_id' => $setup_pack_id,
'agency_id' => $agency_id,
));
$sanitised = array(
'export_type' => $export_type,
'schema_version' => $schema_version,
'setup_pack_id' => $setup_pack_id,
'agency_id' => $agency_id,
'client_domain' => $payload_domain,
'options' => array(
'matewa_business_name' => $business_name,
'matewa_number' => $number,
'matewa_marketing_email' => $marketing_email,
'matewa_leads_email' => $leads_email,
'matewa_industry' => $industry,
'matewa_vertical_category_selected' => $category_key,
'matewa_vertical_selected' => $vertical_key,
'matewa_chip_label_overrides' => $chip_overrides,
'matewa_widget_settings' => $widget_settings,
),
'client_entitlement' => $client_entitlement,
'preview' => array(
'Business name' => $business_name,
'WhatsApp number' => $number,
'Account/admin email' => $marketing_email,
'Lead destination inbox' => $leads_email,
'Industry' => $industry,
'Business category key' => $category_key,
'Business type key' => $vertical_key,
'Custom visitor buttons' => !empty($chip_overrides[$vertical_key]) ? implode(', ', $chip_overrides[$vertical_key]) : 'Use default buttons',
'Client plan route' => !empty($client_entitlement['agency_managed']) ? 'Agency-managed client seat' : 'No agency client entitlement in payload',
'Widget placement' => ('specific_pages' === $widget_settings['agency_page_mode'] && empty($pending_page_urls)) ? 'Specific pages pending — no auto-placement yet' : (('selected' === $widget_settings['display_mode'] && !empty($pending_page_urls)) ? ('Specific pages selected: ' . count($pending_page_urls)) : (('selected' === $widget_settings['display_mode'] && '1' === $widget_settings['include_homepage']) ? 'Homepage only' : 'All pages')),
),
'warnings' => array_values(array_unique(array_filter(array_map('sanitize_text_field', $warnings)))),
);
unset($GLOBALS['matewa_agency_import_current_payload_buttons']);
return array(
'ok' => empty($errors),
'errors' => $errors,
'warnings' => $sanitised['warnings'],
'sanitised' => $sanitised,
'payload' => $payload,
);
}
}
if (!function_exists('matewa_agency_client_import_get_pending')) {
function matewa_agency_client_import_get_pending() {
$pending = get_option(MATEWA_AGENCY_CLIENT_IMPORT_PENDING_OPTION, array());
return is_array($pending) ? $pending : array();
}
}
if (!function_exists('matewa_agency_client_import_get_last_meta')) {
function matewa_agency_client_import_get_last_meta() {
$meta = get_option(MATEWA_AGENCY_CLIENT_IMPORTED_META_OPTION, array());
return is_array($meta) ? $meta : array();
}
}
if (!function_exists('matewa_agency_client_import_save_option')) {
function matewa_agency_client_import_save_option($option_name, $value) {
if (function_exists('matewa_direct_save_option_value')) {
return matewa_direct_save_option_value($option_name, $value);
}
return update_option($option_name, $value, false);
}
}
if (!function_exists('matewa_agency_client_import_merge_widget_settings')) {
function matewa_agency_client_import_merge_widget_settings($incoming) {
$existing = get_option('matewa_widget_settings', array());
$existing = is_array($existing) ? $existing : array();
$incoming = is_array($incoming) ? $incoming : array();
$display_mode = matewa_agency_client_import_allowed_widget_display_mode($incoming['display_mode'] ?? ($existing['display_mode'] ?? 'all'));
$include_homepage = !empty($incoming['include_homepage']) ? '1' : (!empty($existing['include_homepage']) ? '1' : '0');
$existing_page_ids = isset($existing['page_ids']) && is_array($existing['page_ids']) ? array_values(array_unique(array_filter(array_map('absint', $existing['page_ids'])))) : array();
$pending_urls = isset($incoming['pending_page_urls']) && is_array($incoming['pending_page_urls']) ? $incoming['pending_page_urls'] : array();
$agency_page_mode = sanitize_key((string) ($incoming['agency_page_mode'] ?? ($existing['agency_page_mode'] ?? 'all_pages')));
if (!in_array($agency_page_mode, array('all_pages', 'homepage', 'specific_pages'), true)) {
$agency_page_mode = 'all_pages';
}
$agency_placement_pending = !empty($incoming['agency_placement_pending']);
$resolved_targets = matewa_agency_client_import_resolve_page_targets($pending_urls);
$resolved_page_ids = isset($resolved_targets['page_ids']) && is_array($resolved_targets['page_ids']) ? array_values(array_unique(array_filter(array_map('absint', $resolved_targets['page_ids'])))) : array();
if ('homepage' === $agency_page_mode) {
$display_mode = 'selected';
$include_homepage = '1';
$existing_page_ids = array();
$agency_placement_pending = false;
} elseif ('specific_pages' === $agency_page_mode) {
$display_mode = 'selected';
$include_homepage = !empty($resolved_targets['include_homepage']) ? '1' : '0';
$existing_page_ids = $resolved_page_ids;
$agency_placement_pending = empty($pending_urls);
} elseif (!empty($pending_urls)) {
$display_mode = 'selected';
$include_homepage = !empty($resolved_targets['include_homepage']) ? '1' : '0';
$existing_page_ids = $resolved_page_ids;
}
return array(
'enabled' => !empty($existing['enabled']) ? '1' : '1',
'display_mode' => $display_mode,
'page_ids' => $existing_page_ids,
'include_homepage' => $include_homepage,
'show_country_selector' => array_key_exists('show_country_selector', $existing) ? (!empty($existing['show_country_selector']) ? '1' : '0') : '1',
'agency_page_mode' => $agency_page_mode,
'agency_placement_pending' => $agency_placement_pending,
'agency_placement_note' => sanitize_text_field((string) ($incoming['agency_placement_note'] ?? '')),
'agency_pending_page_urls' => array_values(array_unique(array_filter(array_map('esc_url_raw', $pending_urls)))),
'agency_page_match_count' => isset($resolved_targets['matched_count']) ? absint($resolved_targets['matched_count']) : 0,
'remote_sending_scope_imported' => !empty($incoming['remote_sending_scope_imported']) ? '1' : (array_key_exists('remote_sending_scope_imported', $existing) ? (!empty($existing['remote_sending_scope_imported']) ? '1' : '0') : '0'),
);
}
}
if (!function_exists('matewa_agency_client_import_apply_payload')) {
function matewa_agency_client_import_apply_payload($pending) {
$pending = is_array($pending) ? $pending : array();
$sanitised = isset($pending['sanitised']) && is_array($pending['sanitised']) ? $pending['sanitised'] : array();
$options = isset($sanitised['options']) && is_array($sanitised['options']) ? $sanitised['options'] : array();
$payload = isset($pending['payload']) && is_array($pending['payload']) ? $pending['payload'] : array();
if (empty($options)) {
return array('ok' => false, 'message' => 'No recognised setup options were found in the pending import.');
}
$applied = array();
$text_options = array(
'matewa_business_name',
'matewa_number',
'matewa_marketing_email',
'matewa_leads_email',
'matewa_industry',
'matewa_vertical_category_selected',
'matewa_vertical_selected',
);
foreach ($text_options as $option_name) {
if (!array_key_exists($option_name, $options)) {
continue;
}
$value = $options[$option_name];
if ('' === (string) $value) {
continue;
}
matewa_agency_client_import_save_option($option_name, $value);
$applied[] = $option_name;
}
if (isset($options['matewa_chip_label_overrides']) && is_array($options['matewa_chip_label_overrides']) && !empty($options['matewa_chip_label_overrides'])) {
matewa_agency_client_import_save_option('matewa_chip_label_overrides', $options['matewa_chip_label_overrides']);
$applied[] = 'matewa_chip_label_overrides';
}
if (isset($options['matewa_widget_settings']) && is_array($options['matewa_widget_settings'])) {
matewa_agency_client_import_save_option('matewa_widget_settings', matewa_agency_client_import_merge_widget_settings($options['matewa_widget_settings']));
$applied[] = 'matewa_widget_settings';
}
$client_entitlement = isset($sanitised['client_entitlement']) && is_array($sanitised['client_entitlement']) ? $sanitised['client_entitlement'] : array();
if (!empty($client_entitlement['agency_managed'])) {
matewa_agency_client_import_save_option(MATEWA_AGENCY_CLIENT_ENTITLEMENT_OPTION, $client_entitlement);
if (function_exists('matewa_clear_verticals_cache')) {
matewa_clear_verticals_cache();
}
if (function_exists('wp_cache_delete')) {
wp_cache_delete(MATEWA_AGENCY_CLIENT_ENTITLEMENT_OPTION, 'options');
}
$applied[] = MATEWA_AGENCY_CLIENT_ENTITLEMENT_OPTION;
}
$meta = array(
'checkpoint' => 'AGENCYCLIENTFREEMIUMOVERRIDEFIX1',
'import_route' => isset($pending['import_route']) ? sanitize_key((string) $pending['import_route']) : 'manual_json_upload',
'imported_at' => time(),
'setup_pack_id' => sanitize_key((string) ($sanitised['setup_pack_id'] ?? '')),
'agency_id' => sanitize_key((string) ($sanitised['agency_id'] ?? '')),
'client_domain' => sanitize_text_field((string) ($sanitised['client_domain'] ?? '')),
'payload_hash' => sanitize_text_field((string) ($pending['hash'] ?? '')),
'applied_options' => $applied,
'warnings' => isset($sanitised['warnings']) && is_array($sanitised['warnings']) ? array_values($sanitised['warnings']) : array(),
'source_of_truth' => 'client_site_plugin_options',
'central_dependency_required' => false,
'agency_client_entitlement_active' => !empty($client_entitlement['agency_managed']),
);
matewa_agency_client_import_save_option(MATEWA_AGENCY_CLIENT_IMPORTED_META_OPTION, $meta);
matewa_agency_client_import_save_option(MATEWA_AGENCY_CLIENT_IMPORTED_PAYLOAD_OPTION, $payload);
delete_option(MATEWA_AGENCY_CLIENT_IMPORT_PENDING_OPTION);
return array('ok' => true, 'message' => 'Setup imported into this WordPress site.', 'applied' => $applied);
}
}
if (!function_exists('matewa_agency_client_import_handle_review')) {
function matewa_agency_client_import_handle_review() {
if (!is_admin() || !current_user_can('manage_options')) {
wp_die(esc_html__('You do not have permission to import setup packs.', '247chatmate'));
}
check_admin_referer('matewa_agency_client_import_review', 'matewa_agency_client_import_nonce');
if (empty($_FILES['matewa_agency_client_setup_json']) || !is_array($_FILES['matewa_agency_client_setup_json'])) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- File arrays are validated by the WordPress upload handler below.
matewa_agency_client_import_redirect('missing_file');
}
$file = $_FILES['matewa_agency_client_setup_json']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- File arrays are validated by the WordPress upload handler below.
$upload_error = isset($file['error']) ? (int) $file['error'] : UPLOAD_ERR_NO_FILE;
if (UPLOAD_ERR_OK !== $upload_error) {
matewa_agency_client_import_redirect('upload_failed');
}
$size = isset($file['size']) ? (int) $file['size'] : 0;
if ($size <= 0 || $size > 1048576) {
matewa_agency_client_import_redirect('file_too_large');
}
$tmp_name = isset($file['tmp_name']) ? (string) $file['tmp_name'] : '';
if ('' === $tmp_name || !is_uploaded_file($tmp_name)) {
matewa_agency_client_import_redirect('upload_failed');
}
$raw = file_get_contents($tmp_name);
if (!is_string($raw) || '' === trim($raw)) {
matewa_agency_client_import_redirect('empty_file');
}
$payload = json_decode($raw, true);
if (!is_array($payload) || JSON_ERROR_NONE !== json_last_error()) {
matewa_agency_client_import_redirect('invalid_json');
}
$result = matewa_agency_client_import_sanitise_payload($payload);
if (empty($result['ok'])) {
matewa_agency_client_import_redirect('invalid_payload');
}
$pending = array(
'checkpoint' => 'AGENCYREMOTESENDINGWIDGETSCOPE1',
'reviewed_at' => time(),
'import_route' => 'manual_json_upload',
'hash' => matewa_agency_client_import_payload_hash($result['sanitised']),
'sanitised' => $result['sanitised'],
'payload' => $result['payload'],
);
update_option(MATEWA_AGENCY_CLIENT_IMPORT_PENDING_OPTION, $pending, false);
matewa_agency_client_import_redirect('review_ready');
}
}
add_action('admin_post_matewa_agency_client_import_review', 'matewa_agency_client_import_handle_review');
if (!function_exists('matewa_agency_client_import_handle_apply')) {
function matewa_agency_client_import_handle_apply() {
if (!is_admin() || !current_user_can('manage_options')) {
wp_die(esc_html__('You do not have permission to apply setup packs.', '247chatmate'));
}
check_admin_referer('matewa_agency_client_import_apply', 'matewa_agency_client_import_apply_nonce');
$pending = matewa_agency_client_import_get_pending();
if (empty($pending)) {
matewa_agency_client_import_redirect('no_pending');
}
$posted_hash = isset($_POST['matewa_agency_client_import_hash']) ? sanitize_text_field(wp_unslash($_POST['matewa_agency_client_import_hash'])) : '';
$pending_hash = isset($pending['hash']) ? sanitize_text_field((string) $pending['hash']) : '';
if ('' === $posted_hash || '' === $pending_hash || !hash_equals($pending_hash, $posted_hash)) {
matewa_agency_client_import_redirect('hash_mismatch');
}
$result = matewa_agency_client_import_apply_payload($pending);
matewa_agency_client_import_redirect(!empty($result['ok']) ? 'imported' : 'apply_failed');
}
}
add_action('admin_post_matewa_agency_client_import_apply', 'matewa_agency_client_import_handle_apply');
if (!function_exists('matewa_agency_client_import_handle_cancel')) {
function matewa_agency_client_import_handle_cancel() {
if (!is_admin() || !current_user_can('manage_options')) {
wp_die(esc_html__('You do not have permission to cancel setup imports.', '247chatmate'));
}
check_admin_referer('matewa_agency_client_import_cancel', 'matewa_agency_client_import_cancel_nonce');
delete_option(MATEWA_AGENCY_CLIENT_IMPORT_PENDING_OPTION);
matewa_agency_client_import_redirect('cancelled');
}
}
add_action('admin_post_matewa_agency_client_import_cancel', 'matewa_agency_client_import_handle_cancel');
if (!function_exists('matewa_agency_client_import_notice_message')) {
function matewa_agency_client_import_notice_message($notice) {
$notice = sanitize_key((string) $notice);
$messages = array(
'review_ready' => array('type' => 'success', 'message' => 'Setup JSON loaded. Review the mapped fields below before applying it to this site.'),
'imported' => array('type' => 'success', 'message' => 'Setup imported into this client WordPress site. The local plugin options are now the source of truth.'),
'cancelled' => array('type' => 'warning', 'message' => 'Pending setup import was cancelled. No settings were changed.'),
'missing_file' => array('type' => 'warning', 'message' => 'Choose a setup JSON file before importing.'),
'upload_failed' => array('type' => 'warning', 'message' => 'The setup JSON upload failed. Try exporting the client pack again.'),
'file_too_large' => array('type' => 'warning', 'message' => 'The setup JSON file is too large. Use the exported client setup JSON only.'),
'empty_file' => array('type' => 'warning', 'message' => 'The uploaded setup JSON file was empty.'),
'invalid_json' => array('type' => 'warning', 'message' => 'The uploaded file is not valid JSON.'),
'invalid_payload' => array('type' => 'warning', 'message' => 'This JSON does not match the expected 247ChatMate agency client setup format.'),
'no_pending' => array('type' => 'warning', 'message' => 'There is no pending setup import to apply.'),
'hash_mismatch' => array('type' => 'warning', 'message' => 'The pending setup import changed before confirmation. Upload and review it again.'),
'apply_failed' => array('type' => 'warning', 'message' => 'The setup import could not be applied. Review the JSON and try again.'),
);
return isset($messages[$notice]) ? $messages[$notice] : array('type' => '', 'message' => '');
}
}
if (!function_exists('matewa_agency_client_import_render_setup_panel')) {
function matewa_agency_client_import_render_setup_panel() {
$notice = isset($_GET['matewa_agency_import_notice']) ? sanitize_key(wp_unslash($_GET['matewa_agency_import_notice'])) : '';
$notice_data = matewa_agency_client_import_notice_message($notice);
$pending = matewa_agency_client_import_get_pending();
$sanitised = isset($pending['sanitised']) && is_array($pending['sanitised']) ? $pending['sanitised'] : array();
$preview = isset($sanitised['preview']) && is_array($sanitised['preview']) ? $sanitised['preview'] : array();
$warnings = isset($sanitised['warnings']) && is_array($sanitised['warnings']) ? $sanitised['warnings'] : array();
$last_meta = matewa_agency_client_import_get_last_meta();
?>
Upload an agency-exported client setup pack, review the mapped fields, then apply them into this WordPress site’s local plugin settings. This import stores the setup locally on the client WordPress site. It does not import agency master licence keys or require central JSON storage.Import client setup JSON
$value) : ?>