getMessage(), 'error' ); return; } $percent = isset( $_POST['global_assumed_cost_percent'] ) ? sanitize_text_field( wp_unslash( $_POST['global_assumed_cost_percent'] ) ) : ''; if ( '' !== $percent ) { if ( ! preg_match( '/^\d+(\.\d{1,2})?$/', $percent ) ) { add_settings_error( 'aksmb', 'percent', __( 'Assumed cost percentage must be a number between 0 and 100.', 'marginbeacon' ), 'error' ); return; } $in_range = bccomp( $percent, '0', 6 ) >= 0 && bccomp( $percent, '100', 6 ) <= 0; if ( ! $in_range ) { add_settings_error( 'aksmb', 'percent', __( 'Assumed cost percentage must be between 0 and 100.', 'marginbeacon' ), 'error' ); return; } } $assumed_cost_raw = isset( $_POST['global_assumed_cost'] ) ? sanitize_text_field( wp_unslash( $_POST['global_assumed_cost'] ) ) : ''; if ( '' !== $assumed_cost_raw && ! preg_match( '/^\d+(\.\d+)?$/', $assumed_cost_raw ) ) { add_settings_error( 'aksmb', 'cost', __( 'Global assumed cost must be a valid decimal amount.', 'marginbeacon' ), 'error' ); return; } $settings = get_option( Constants::OPTION_SETTINGS, array() ); if ( ! is_array( $settings ) ) { $settings = array(); } $prev_thresholds = isset( $settings['thresholds'] ) && is_array( $settings['thresholds'] ) ? $settings['thresholds'] : Constants::default_thresholds(); $new_thresholds = $profile->to_array(); $thresholds_changed = wp_json_encode( $prev_thresholds ) !== wp_json_encode( $new_thresholds ); $settings['thresholds'] = $new_thresholds; $settings['disclaimer_accepted'] = ! empty( $_POST['disclaimer_accepted'] ); update_option( Constants::OPTION_SETTINGS, $settings, true ); $cost = get_option( Constants::OPTION_COST_SETTINGS, array() ); if ( ! is_array( $cost ) ) { $cost = array(); } $prev_cost = $cost; $source = isset( $_POST['canonical_cost_source'] ) ? sanitize_key( wp_unslash( $_POST['canonical_cost_source'] ) ) : ''; if ( ! ( new CanonicalCostSource() )->is_valid( $source ) ) { $source = ( new CanonicalCostSource() )->get(); } $cost['canonical_cost_source'] = $source; $cost['prefer_native_cogs'] = ( CanonicalCostSource::WOOCOMMERCE === $source ); $cost['fallback_enabled'] = ! empty( $_POST['fallback_enabled'] ); $cost['global_assumed_cost'] = '' !== $assumed_cost_raw ? $assumed_cost_raw : null; if ( '' !== $percent ) { $cost['global_assumed_cost_percent'] = $percent; } else { $cost['global_assumed_cost_percent'] = null; } $cost['custom_meta_key'] = isset( $_POST['custom_meta_key'] ) ? sanitize_text_field( wp_unslash( $_POST['custom_meta_key'] ) ) : ''; $cost['cogs_tax_basis'] = isset( $_POST['cogs_tax_basis'] ) && 'inclusive' === $_POST['cogs_tax_basis'] ? 'inclusive' : 'exclusive'; $cost['needs_cogs_correction'] = ( 'inclusive' === $cost['cogs_tax_basis'] ); update_option( Constants::OPTION_COST_SETTINGS, $cost, true ); // Explicit Settings choice marks migration decision complete (no silent switch). ( new CanonicalCostSource() )->set( $source ); $cost_changed = wp_json_encode( $prev_cost ) !== wp_json_encode( get_option( Constants::OPTION_COST_SETTINGS, array() ) ); // PRD 17.6 — uninstall retention choice (default keep). $delete_on_uninstall = ! empty( $_POST['uninstall_delete_data'] ); update_option( Constants::OPTION_UNINSTALL_DELETE_DATA, $delete_on_uninstall ? 1 : 0, true ); $message = __( 'Settings saved.', 'marginbeacon' ); if ( $thresholds_changed || $cost_changed ) { ( new \Kayvandra\MarginBeacon\Application\Freshness\FreshnessService() )->on_global_threshold_change(); $message = __( 'Settings saved. Related preflight findings were marked stale — re-run preflight to refresh.', 'marginbeacon' ); } add_settings_error( 'aksmb', 'saved', $message, 'updated' ); } /** * Render settings form. * * @return void */ public function render() { if ( ! Capabilities::current_user_can_manage() ) { wp_die( esc_html__( 'You do not have permission to access MarginBeacon.', 'marginbeacon' ) ); } settings_errors( 'aksmb' ); $settings = get_option( Constants::OPTION_SETTINGS, array() ); $cost = get_option( Constants::OPTION_COST_SETTINGS, array() ); $t = isset( $settings['thresholds'] ) ? $settings['thresholds'] : Constants::default_thresholds(); $fmt = static function ( $scaled ) { return number_format( ( (int) $scaled ) / Constants::THRESHOLD_SCALE, 4, '.', '' ); }; ?>

get(); ?>