v0.3.3 — Admin-UI tax-class mapper
What's new
Configure tax-class mappings without leaving the browser. The CLI commands from v0.2.0 still work, but now there's a UI for the same thing under WC > Settings > Tax > OpenSalesTax → Tax class → OST category mapping.
What it looks like
| WC tax class | OST category | Status |
|---|---|---|
Standard (empty slug) |
[general ▾] | Default |
reduced-rate |
[general ▾] | Default |
zero-rate |
[— Skip — ▾] | Default |
clothing |
[clothing ▾] | Custom |
gift-cards |
[— Skip — ▾] | Custom |
The dropdown shows the 6 OST categories plus "— Skip (non-taxable) —" so a merchant can mark anything from a custom class to a single product line as non-taxable. The Status column flags which rows are merchant overrides vs. plugin defaults.
A "Reset all to defaults" checkbox clears every override on save.
Auto-discovery
The mapper finds every WC tax class to show a row for, automatically:
- WC's 4 built-in slugs (`''`, `standard`, `reduced-rate`, `zero-rate`)
- Any user-defined classes (read from `woocommerce_tax_classes` and slugified via `sanitize_title` the same way WC does)
- Anything already present in the merchant's existing override map
So if you've got a "Clothing" class defined in WC > Settings > Tax > Tax options, it shows up in the OpenSalesTax mapper automatically.
Security
- Capability check: `current_user_can('manage_woocommerce')` runs before any state change. Both reset and persist paths gated.
- Server-side validation: posted categories pass through `wp_unslash` + `sanitize_text_field` and validate against the `VALID_CATEGORIES` allow-list. Invalid values are silently dropped — the dropdown shouldn't produce them, but defense-in-depth catches a tampered-form submission.
- Verified live on VM 907: admin user's POST persists, a 3-entry round-trips correctly, reset clears, an unprivileged user's POST is no-op'd.
Quality gate
- 91/91 unit tests pass (6 new in `SettingsTaxClassSaveTest`: capability rejects / reset path / no-op when no map / valid persist / invalid silent-drop / all 6 valid categories accepted)
- PHPStan level=max clean
- PHP-CS-Fixer (PSR-12 + risky) clean
Upgrade
Drop-in upgrade from v0.3.2 — no configuration required. Existing override maps from prior CLI configuration carry through unchanged.
```bash
cd wp-content/plugins/opensalestax-woocommerce
git pull
composer install --no-dev
```
Full changelog
See CHANGELOG.md.