false, 'code' => sanitize_key( (string) $code ), 'status' => sanitize_key( (string) $status ), 'message' => sanitize_text_field( (string) $message ), 'lifecycle_only' => true, 'advisory_only' => true, 'entitlement_decision' => 'unchanged', 'source' => 'paid_lifecycle_status_client', 'checked_at' => time(), 'checked_utc' => gmdate( 'c' ), 'last_lifecycle_event' => '', 'terminal_event' => '', 'event_category' => '', 'stored_lifecycle_status' => '', 'current_state_updated' => null, 'requires_fresh_validation' => true, 'terminal' => false, 'grace_warning' => false, 'subscription_status' => '', 'last_received_utc' => '', 'last_event_utc' => '', 'updated_utc' => '', 'privacy_note' => 'No IP address, visitor data, chat content, lead content, raw WhatsApp number, raw admin email, raw Founder Beta invite code, raw webhook payload, or full raw licence key is collected by this advisory client.', ); if ( is_array( $extra ) && ! empty( $extra ) ) { $result = array_merge( $result, $extra ); } $result['lifecycle_only'] = true; $result['advisory_only'] = true; $result['entitlement_decision'] = 'unchanged'; return $result; } } if ( ! function_exists( 'matewa_paid_lifecycle_status_build_payload' ) ) { function matewa_paid_lifecycle_status_build_payload() { $license_key = function_exists( 'matewa_get_license_key' ) ? matewa_get_license_key() : trim( (string) get_option( 'matewa_license_key', '' ) ); $is_founder_beta_key = function_exists( 'matewa_license_key_is_founder_beta_access' ) ? matewa_license_key_is_founder_beta_access( $license_key ) : false; $paid_licence_key_for_hash = $is_founder_beta_key ? '' : $license_key; $domain = matewa_paid_lifecycle_status_get_domain(); $install_uuid = matewa_paid_lifecycle_status_get_install_uuid(); return array( 'action' => 'paid_lifecycle_status_read', 'plugin' => '247chatmate', 'plugin_version' => defined( 'MATEWA_VERSION' ) ? (string) MATEWA_VERSION : '', 'site_hash' => matewa_paid_lifecycle_status_hash_value( home_url( '/' ) ), 'domain_hash' => matewa_paid_lifecycle_status_hash_value( $domain ), 'install_uuid_hash' => matewa_paid_lifecycle_status_hash_value( $install_uuid ), 'licence_key_hash' => matewa_paid_lifecycle_status_hash_value( $paid_licence_key_for_hash ), 'entitlement_decision' => 'unchanged', 'advisory_only' => true, 'lifecycle_only' => true, 'request_created' => time(), ); } } if ( ! function_exists( 'matewa_paid_lifecycle_status_sanitise_result' ) ) { function matewa_paid_lifecycle_status_sanitise_result( $result ) { if ( ! is_array( $result ) ) { $result = array(); } $current_state_updated = null; if ( array_key_exists( 'current_state_updated', $result ) && null !== $result['current_state_updated'] ) { $current_state_updated = ! empty( $result['current_state_updated'] ); } $last_lifecycle_event = sanitize_key( (string) ( $result['last_lifecycle_event'] ?? '' ) ); if ( '' === $last_lifecycle_event ) { $last_lifecycle_event = sanitize_key( (string) ( $result['event_name'] ?? '' ) ); } $terminal_event = sanitize_key( (string) ( $result['terminal_event'] ?? '' ) ); if ( '' === $terminal_event && ! empty( $result['terminal'] ) ) { $terminal_event = $last_lifecycle_event; } $stored_lifecycle_status = sanitize_key( (string) ( $result['stored_lifecycle_status'] ?? '' ) ); if ( '' === $stored_lifecycle_status ) { $stored_lifecycle_status = sanitize_key( (string) ( $result['stored_status'] ?? '' ) ); } return array( 'ok' => ! empty( $result['ok'] ), 'code' => sanitize_key( (string) ( $result['code'] ?? 'unknown' ) ), 'status' => sanitize_key( (string) ( $result['status'] ?? '' ) ), 'message' => sanitize_text_field( (string) ( $result['message'] ?? '' ) ), 'lifecycle_only' => true, 'advisory_only' => true, 'entitlement_decision' => 'unchanged', 'source' => sanitize_key( (string) ( $result['source'] ?? 'paid_lifecycle_status_client' ) ), 'checked_at' => isset( $result['checked_at'] ) ? (int) $result['checked_at'] : time(), 'checked_utc' => sanitize_text_field( (string) ( $result['checked_utc'] ?? gmdate( 'c' ) ) ), 'last_lifecycle_event' => $last_lifecycle_event, 'terminal_event' => $terminal_event, 'event_category' => sanitize_key( (string) ( $result['event_category'] ?? '' ) ), 'stored_lifecycle_status' => $stored_lifecycle_status, 'current_state_updated' => $current_state_updated, 'requires_fresh_validation' => array_key_exists( 'requires_fresh_validation', $result ) ? ! empty( $result['requires_fresh_validation'] ) : true, 'terminal' => ! empty( $result['terminal'] ), 'grace_warning' => ! empty( $result['grace_warning'] ), 'subscription_status' => sanitize_key( (string) ( $result['subscription_status'] ?? '' ) ), 'last_received_utc' => sanitize_text_field( (string) ( $result['last_received_utc'] ?? '' ) ), 'last_event_utc' => sanitize_text_field( (string) ( $result['last_event_utc'] ?? '' ) ), 'updated_utc' => sanitize_text_field( (string) ( $result['updated_utc'] ?? '' ) ), 'privacy_note' => 'No IP address, visitor data, chat content, lead content, raw WhatsApp number, raw admin email, raw Founder Beta invite code, raw webhook payload, or full raw licence key is collected by this advisory client.', ); } } if ( ! function_exists( 'matewa_paid_lifecycle_status_store_result' ) ) { function matewa_paid_lifecycle_status_store_result( $result ) { $safe = matewa_paid_lifecycle_status_sanitise_result( $result ); update_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_RESULT_OPTION, $safe, false ); update_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_REFRESH_OPTION, time(), false ); return $safe; } } if ( ! function_exists( 'matewa_paid_lifecycle_status_store_error' ) ) { function matewa_paid_lifecycle_status_store_error( $result ) { $safe = matewa_paid_lifecycle_status_sanitise_result( $result ); update_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_ERROR_OPTION, $safe, false ); update_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_REFRESH_OPTION, time(), false ); return $safe; } } if ( ! function_exists( 'matewa_paid_lifecycle_status_get_last_result' ) ) { function matewa_paid_lifecycle_status_get_last_result() { $result = get_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_RESULT_OPTION, array() ); return is_array( $result ) ? matewa_paid_lifecycle_status_sanitise_result( $result ) : array(); } } if ( ! function_exists( 'matewa_paid_lifecycle_status_get_last_error' ) ) { function matewa_paid_lifecycle_status_get_last_error() { $result = get_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_ERROR_OPTION, array() ); return is_array( $result ) ? matewa_paid_lifecycle_status_sanitise_result( $result ) : array(); } } if ( ! function_exists( 'matewa_paid_lifecycle_status_get_last_refresh' ) ) { function matewa_paid_lifecycle_status_get_last_refresh() { return (int) get_option( MATEWA_PAID_LIFECYCLE_STATUS_LAST_REFRESH_OPTION, 0 ); } } if ( ! function_exists( 'matewa_paid_lifecycle_status_manual_admin_refresh' ) ) { function matewa_paid_lifecycle_status_manual_admin_refresh() { if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) { return matewa_paid_lifecycle_status_store_error( matewa_paid_lifecycle_status_advisory_result( 'admin_required', 'Paid lifecycle status refresh requires an authorised WordPress admin.', 'blocked' ) ); } if ( matewa_paid_lifecycle_status_is_cron_request() ) { return matewa_paid_lifecycle_status_store_error( matewa_paid_lifecycle_status_advisory_result( 'cron_blocked', 'Paid lifecycle status refresh is not available to cron in this phase.', 'blocked' ) ); } if ( get_transient( MATEWA_PAID_LIFECYCLE_STATUS_REFRESH_LOCK_TRANSIENT ) ) { return matewa_paid_lifecycle_status_store_error( matewa_paid_lifecycle_status_advisory_result( 'refresh_locked', 'Paid lifecycle status refresh is already running. Try again shortly.', 'locked' ) ); } $lock_ttl = defined( 'MINUTE_IN_SECONDS' ) ? MINUTE_IN_SECONDS : 60; set_transient( MATEWA_PAID_LIFECYCLE_STATUS_REFRESH_LOCK_TRANSIENT, 1, $lock_ttl ); $result = matewa_paid_lifecycle_status_post( matewa_paid_lifecycle_status_build_payload(), true ); delete_transient( MATEWA_PAID_LIFECYCLE_STATUS_REFRESH_LOCK_TRANSIENT ); return $result; } } if ( ! function_exists( 'matewa_paid_lifecycle_status_post' ) ) { function matewa_paid_lifecycle_status_post( $payload = array(), $store_result = false ) { if ( ! matewa_paid_lifecycle_status_can_request() ) { $result = matewa_paid_lifecycle_status_advisory_result( 'frontend_blocked', 'Paid lifecycle status refresh is blocked on frontend, widget, cron, and background requests.', 'blocked' ); return $store_result ? matewa_paid_lifecycle_status_store_error( $result ) : $result; } if ( ! matewa_paid_lifecycle_status_is_configured() ) { $result = matewa_paid_lifecycle_status_advisory_result( 'status_not_configured', 'Paid lifecycle status client is not configured.', 'not_configured' ); return $store_result ? matewa_paid_lifecycle_status_store_error( $result ) : $result; } if ( empty( $payload ) || ! is_array( $payload ) ) { $payload = matewa_paid_lifecycle_status_build_payload(); } $payload['entitlement_decision'] = 'unchanged'; $payload['advisory_only'] = true; $payload['lifecycle_only'] = true; $body = wp_json_encode( $payload, JSON_UNESCAPED_SLASHES ); if ( ! is_string( $body ) || '' === $body ) { $result = matewa_paid_lifecycle_status_advisory_result( 'invalid_payload', 'Paid lifecycle status payload could not be created.', 'invalid' ); return $store_result ? matewa_paid_lifecycle_status_store_error( $result ) : $result; } $timestamp = (string) time(); $signature = hash_hmac( 'sha256', $timestamp . '.' . $body, matewa_paid_lifecycle_status_get_secret() ); $response = wp_remote_post( matewa_paid_lifecycle_status_get_endpoint(), array( 'timeout' => MATEWA_PAID_LIFECYCLE_STATUS_TIMEOUT, 'headers' => array( 'Content-Type' => 'application/json; charset=utf-8', 'X-Matewa-Timestamp' => $timestamp, 'X-Matewa-Signature' => $signature, 'X-Matewa-Lifecycle' => 'paid-lifecycle-status-v1', ), 'body' => $body, ) ); if ( is_wp_error( $response ) ) { $result = matewa_paid_lifecycle_status_advisory_result( 'status_unavailable', 'Paid lifecycle status endpoint could not be reached.', 'unavailable' ); return $store_result ? matewa_paid_lifecycle_status_store_error( $result ) : $result; } $status_code = (int) wp_remote_retrieve_response_code( $response ); $response_body = (string) wp_remote_retrieve_body( $response ); $data = json_decode( $response_body, true ); if ( $status_code < 200 || $status_code >= 300 || ! is_array( $data ) ) { $result = matewa_paid_lifecycle_status_advisory_result( 'invalid_status_response', 'Paid lifecycle status endpoint returned an invalid response.', 'invalid' ); return $store_result ? matewa_paid_lifecycle_status_store_error( $result ) : $result; } $data['source'] = 'paid_lifecycle_status'; $data['entitlement_decision'] = 'unchanged'; $data['advisory_only'] = true; $data['lifecycle_only'] = true; $data['checked_at'] = time(); $result = matewa_paid_lifecycle_status_sanitise_result( $data ); return $store_result ? matewa_paid_lifecycle_status_store_result( $result ) : $result; } } if ( ! function_exists( 'matewa_paid_lifecycle_status_get_warning_bridge' ) ) { function matewa_paid_lifecycle_status_get_warning_bridge() { $source_of_truth = 'LemonSqueezy/local paid validation remains the source of truth.'; $default_recommended_action = 'Run fresh LemonSqueezy/local licence validation before relying on paid entitlement.'; $bridge = array( 'advisory_only' => true, 'lifecycle_only' => true, 'entitlement_decision' => 'unchanged', 'source' => 'paid_lifecycle_warning_bridge', 'code' => 'lifecycle_warning_unavailable', 'severity' => 'info', 'warning_level' => 'info', 'message' => 'Lifecycle warning bridge is available for admin display only.', 'source_of_truth' => $source_of_truth, 'recommended_action' => $default_recommended_action, 'fresh_validation_required' => false, 'terminal_guard_active' => false, 'terminal_guard_reason' => '', 'local_plan_status' => '', 'local_paid_valid' => false, 'local_paid_code' => '', 'local_paid_source' => '', 'paid_registry_code' => '', 'paid_registry_status' => '', 'lifecycle_code' => '', 'lifecycle_status' => '', 'lifecycle_event' => '', 'lifecycle_event_category' => '', 'lifecycle_terminal_event' => '', 'lifecycle_subscription_status' => '', 'lifecycle_terminal' => false, 'lifecycle_grace_warning' => false, 'lifecycle_checked_at' => 0, 'lifecycle_stale' => false, 'privacy_note' => 'No IP address, visitor data, chat content, lead content, raw WhatsApp number, raw admin email, raw Founder Beta invite code, raw webhook payload, or full raw licence key is collected, stored, or displayed by this advisory warning bridge.', ); if ( ! is_admin() ) { return $bridge; } $licence_key = function_exists( 'matewa_get_license_key' ) ? matewa_get_license_key() : trim( (string) get_option( 'matewa_license_key', '' ) ); $is_founder_beta_key = function_exists( 'matewa_license_key_is_founder_beta_access' ) ? matewa_license_key_is_founder_beta_access( $licence_key ) : false; $stored_paid = array(); if ( '' !== $licence_key && ! $is_founder_beta_key && function_exists( 'matewa_get_stored_license_validation_result' ) ) { $stored_paid = matewa_get_stored_license_validation_result( $licence_key ); $stored_paid = is_array( $stored_paid ) ? $stored_paid : array(); } $bridge['local_plan_status'] = function_exists( 'matewa_license_status' ) ? sanitize_key( (string) matewa_license_status() ) : ''; $bridge['local_paid_valid'] = ! empty( $stored_paid['valid'] ); $bridge['local_paid_code'] = sanitize_key( (string) ( $stored_paid['code'] ?? '' ) ); $bridge['local_paid_source'] = sanitize_key( (string) ( $stored_paid['source'] ?? '' ) ); $paid_registry = array(); if ( function_exists( 'matewa_paid_licence_registry_get_last_result' ) ) { $paid_registry = matewa_paid_licence_registry_get_last_result(); } if ( empty( $paid_registry ) && function_exists( 'matewa_paid_licence_registry_get_last_error' ) ) { $paid_registry = matewa_paid_licence_registry_get_last_error(); } $paid_registry = is_array( $paid_registry ) ? $paid_registry : array(); $bridge['paid_registry_code'] = sanitize_key( (string) ( $paid_registry['code'] ?? '' ) ); $bridge['paid_registry_status'] = sanitize_key( (string) ( $paid_registry['status'] ?? '' ) ); $lifecycle = matewa_paid_lifecycle_status_get_last_result(); if ( empty( $lifecycle ) ) { $lifecycle = matewa_paid_lifecycle_status_get_last_error(); } $lifecycle = is_array( $lifecycle ) ? $lifecycle : array(); if ( empty( $lifecycle ) ) { $bridge['code'] = 'no_lifecycle_data'; $bridge['severity'] = 'warning'; $bridge['warning_level'] = 'warning'; $bridge['fresh_validation_required'] = true; $bridge['message'] = 'No lifecycle data is available yet. This is an advisory warning only; paid access is still controlled by LemonSqueezy/local validation.'; return $bridge; } $lifecycle_code = sanitize_key( (string) ( $lifecycle['code'] ?? '' ) ); $lifecycle_status = sanitize_key( (string) ( $lifecycle['stored_lifecycle_status'] ?? '' ) ); if ( '' === $lifecycle_status ) { $lifecycle_status = sanitize_key( (string) ( $lifecycle['stored_status'] ?? '' ) ); } if ( '' === $lifecycle_status ) { $lifecycle_status = sanitize_key( (string) ( $lifecycle['status'] ?? '' ) ); } $bridge['lifecycle_code'] = $lifecycle_code; $bridge['lifecycle_status'] = $lifecycle_status; $bridge['lifecycle_event'] = sanitize_key( (string) ( $lifecycle['last_lifecycle_event'] ?? '' ) ); $bridge['lifecycle_event_category'] = sanitize_key( (string) ( $lifecycle['event_category'] ?? '' ) ); $bridge['lifecycle_terminal_event'] = sanitize_key( (string) ( $lifecycle['terminal_event'] ?? '' ) ); $bridge['lifecycle_subscription_status'] = sanitize_key( (string) ( $lifecycle['subscription_status'] ?? '' ) ); $bridge['lifecycle_terminal'] = ! empty( $lifecycle['terminal'] ); $bridge['lifecycle_grace_warning'] = ! empty( $lifecycle['grace_warning'] ); $bridge['lifecycle_checked_at'] = isset( $lifecycle['checked_at'] ) ? (int) $lifecycle['checked_at'] : 0; $bridge['fresh_validation_required'] = ! empty( $lifecycle['requires_fresh_validation'] ); $terminal_statuses = array( 'cancelled', 'canceled', 'refunded', 'refund', 'expired', 'disabled', 'deactivated', 'terminal', 'terminal_candidate', 'cancelled_candidate', 'canceled_candidate', 'refunded_candidate', 'refund_candidate', 'expired_candidate', 'disabled_candidate', 'deactivated_candidate', 'chargeback', 'chargebacked', 'dispute_lost', 'disputed', ); $terminal_events = array( 'subscription_cancelled', 'subscription_canceled', 'subscription_expired', 'subscription_refunded', 'subscription_chargeback', 'subscription_chargebacked', 'order_refunded', 'order_chargeback', 'order_chargebacked', 'license_disabled', 'licence_disabled', 'license_deactivated', 'licence_deactivated', ); $active_statuses = array( 'active', 'active_candidate', 'valid', 'valid_candidate' ); $warning_statuses = array( 'grace', 'grace_warning', 'grace_warning_candidate', 'past_due', 'past_due_candidate', 'unpaid', 'unpaid_candidate', 'payment_failed', 'payment_failed_candidate', 'failed_payment', 'failed_payment_candidate', 'on_grace_period', 'paused', 'paused_candidate', ); $warning_events = array( 'subscription_payment_failed', 'subscription_payment_retry', 'subscription_paused', 'subscription_unpaid', 'subscription_past_due', ); $terminal_categories = array( 'terminal', 'negative', 'blocked', 'cancelled', 'canceled', 'refunded', 'chargeback', 'expired' ); $warning_categories = array( 'warning', 'grace', 'risk', 'payment_warning', 'payment_failed', 'requires_validation' ); $lifecycle_values = array_filter( array( $lifecycle_status, $bridge['lifecycle_subscription_status'], $bridge['lifecycle_event_category'], ), 'strlen' ); $lifecycle_event_values = array_filter( array( $bridge['lifecycle_event'], $bridge['lifecycle_terminal_event'], ), 'strlen' ); $now = time(); $stale_after = 7 * ( defined( 'DAY_IN_SECONDS' ) ? (int) DAY_IN_SECONDS : 86400 ); $is_stale = $bridge['lifecycle_checked_at'] > 0 && ( $now - $bridge['lifecycle_checked_at'] ) > $stale_after; $is_terminal = $bridge['lifecycle_terminal']; $is_warning = $bridge['lifecycle_grace_warning']; foreach ( $lifecycle_values as $lifecycle_value ) { if ( in_array( $lifecycle_value, $terminal_statuses, true ) || in_array( $lifecycle_value, $terminal_categories, true ) ) { $is_terminal = true; } if ( in_array( $lifecycle_value, $warning_statuses, true ) || in_array( $lifecycle_value, $warning_categories, true ) ) { $is_warning = true; } } foreach ( $lifecycle_event_values as $lifecycle_event_value ) { if ( in_array( $lifecycle_event_value, $terminal_events, true ) ) { $is_terminal = true; } if ( in_array( $lifecycle_event_value, $warning_events, true ) ) { $is_warning = true; } } $is_active = in_array( $lifecycle_status, $active_statuses, true ); $registry_terminal = in_array( $bridge['paid_registry_status'], $terminal_statuses, true ); $registry_active = in_array( $bridge['paid_registry_status'], $active_statuses, true ); $bridge['lifecycle_stale'] = $is_stale; $bridge['terminal_guard_active'] = $is_terminal || $is_warning; if ( $is_terminal ) { $bridge['code'] = 'lifecycle_terminal_block_active'; $bridge['severity'] = 'critical'; $bridge['warning_level'] = 'guarded_terminal'; $bridge['fresh_validation_required'] = true; $bridge['terminal_guard_reason'] = 'Stored lifecycle advisory data indicates a terminal paid lifecycle candidate.'; $bridge['recommended_action'] = $default_recommended_action; $bridge['message'] = 'Guarded terminal lifecycle warning active. Stored lifecycle advisory data indicates a possible terminal paid lifecycle state. This is admin-only and advisory only; it does not activate, restore, remove, downgrade, or extend Pro.'; } elseif ( $is_warning ) { $bridge['code'] = 'lifecycle_grace_warning_detected'; $bridge['severity'] = 'warning'; $bridge['warning_level'] = 'guarded_grace_risk'; $bridge['fresh_validation_required'] = true; $bridge['terminal_guard_reason'] = 'Stored lifecycle advisory data indicates a grace, payment, or review-risk candidate.'; $bridge['recommended_action'] = $default_recommended_action; $bridge['message'] = 'Guarded lifecycle warning active. Stored lifecycle advisory data indicates a possible grace, payment, or review-risk state. This is admin-only and advisory only; it does not change Pro access.'; } elseif ( '' === $lifecycle_status ) { $bridge['code'] = 'no_matching_lifecycle_status'; $bridge['severity'] = 'warning'; $bridge['warning_level'] = 'warning'; $bridge['fresh_validation_required'] = true; $bridge['message'] = 'Lifecycle data was found, but no matching lifecycle status is available for comparison. This warning does not change entitlement.'; } elseif ( $is_stale ) { $bridge['code'] = 'stale_lifecycle_data'; $bridge['severity'] = 'warning'; $bridge['warning_level'] = 'warning'; $bridge['fresh_validation_required'] = true; $bridge['message'] = 'Lifecycle data appears stale. Run the manual lifecycle refresh if needed. This warning does not change entitlement.'; } elseif ( ( $registry_active && $is_terminal ) || ( $registry_terminal && $is_active ) ) { $bridge['code'] = 'lifecycle_paid_registry_disagreement'; $bridge['severity'] = 'warning'; $bridge['warning_level'] = 'warning'; $bridge['fresh_validation_required'] = true; $bridge['message'] = 'Lifecycle advisory status and paid registry mirror status appear to disagree. LemonSqueezy/local validation remains the source of truth.'; } elseif ( ( $bridge['local_paid_valid'] && $is_terminal ) || ( ! $bridge['local_paid_valid'] && $is_active && 'pro' !== $bridge['local_plan_status'] && 'master' !== $bridge['local_plan_status'] ) ) { $bridge['code'] = 'lifecycle_local_paid_disagreement'; $bridge['severity'] = 'warning'; $bridge['warning_level'] = 'warning'; $bridge['fresh_validation_required'] = true; $bridge['message'] = 'Lifecycle advisory status and local paid validation appear to disagree. LemonSqueezy/local validation remains the source of truth.'; } else { $bridge['code'] = 'lifecycle_status_ok'; $bridge['severity'] = 'ok'; $bridge['warning_level'] = 'ok'; $bridge['fresh_validation_required'] = ! empty( $lifecycle['requires_fresh_validation'] ); $bridge['recommended_action'] = 'No guarded terminal action is required from lifecycle data. Paid access still depends on LemonSqueezy/local validation.'; $bridge['message'] = 'No lifecycle entitlement warning detected. LemonSqueezy/local validation remains the source of truth.'; } $bridge['advisory_only'] = true; $bridge['lifecycle_only'] = true; $bridge['entitlement_decision'] = 'unchanged'; return $bridge; } }