Skip to content

fix: correctness and hygiene pass (0.7.0-beta) - #26

Merged
navidkashani merged 1 commit into
mainfrom
improve/0.7
Oct 1, 2026
Merged

navidkashani merged 1 commit into
mainfrom
improve/0.7

Conversation

@navidkashani

Copy link
Copy Markdown
Contributor

What & why

A correctness and hygiene pass for 0.7.0-beta, with no API removals. It fixes wrong lookup data, input-cleaning and formatting bugs, outdated docs and packaging gaps. Each bug below has a regression test that failed before its fix.

# Bug Fix
B1 The plate city-code table was mostly wrong (77 → Khuzestan) and covered 47 codes Rebuilt from the persian-tools numberplate dataset and cross-checked against fa.wikipedia; it now covers 88 codes and lives in src/Data/PlateCodes.php
B2 Plate letter categories were wrong (الف → private) Corrected; PlateType::TEMPORARY added; GOVERNMENT_CIV / RENTAL deprecated
B3 IBAN 070 never resolved to Bank::RESALAT Table name fixed, plus an alias; a new test checks that every name in src/Data resolves through its enum's fromPersian()
B4 IDs pasted with RLM / NBSP / Unicode dashes were rejected ErrorInput::digits() strips this noise (with the /u flag); Iban / LegalId now use it
B5 NumberFormatter rejected Currency's own output (50،000) Accepts ، ٬ ٫, a leading + and space grouping
B6 convertContent() corrupted &#8204; and rewrote <code> / <pre> / <textarea> Character references and raw-text elements are protected; PCRE failures now throw instead of passing silently
B7 WordsToNumber threw a TypeError past PHP_INT_MAX and summed دو سه into 5 Overflow returns null; rank-order rules reject sequences that aren't numbers
B8 Slugs kept ، / ؟ / kashida / tashkeel All stripped; ZWNJ becomes -
B9 Plates typed with Arabic ي / ك were rejected Folded to Persian before the lookup
B10 Docs: currency example off by 10×, eramhq/daynum (a Packagist 404), stale pins Fixed

Also in this PR:

  • Province::ALBORZ; area code 026 and Karaj-area national-ID prefixes now map to Alborz; the کهگیلویه spelling is fixed, with the old spelling kept as an alias.
  • Missing CHANGELOG entry added for the post-0.6 Amount API (times / percentOf / compareTo).
  • .gitattributes export-ignore list completed; .gitignore gains var/ and .phpbench/.
  • CI: PHP 8.5 added, one job without ext-intl, composer validate --strict, read-only token permissions, a concurrency group, and a composer cache keyed on composer.lock.

Checklist

  • composer test passes: 661 tests, also run on PHP 8.1 in Docker.
  • composer phpstan is clean at level 8.
  • composer cs-check (php-cs-fixer) is clean.
  • Added / updated tests covering the change.
  • Updated CHANGELOG.md; the section is titled [0.7.0-beta] so tagging this commit works with release.yml.
  • Documentation (README.md / docs/en/*) updated.

Type of change

  • Bug fix
  • Data-table update (city codes, bank BINs, operator prefixes, IBAN issuers)
  • Documentation

Notes for reviewers

  • Plate data: this mostly follows upstream persian-tools. It deviates in two places, based on the Wikipedia cross-check: 45 maps to Kerman (upstream says Yazd; the two look swapped, since Yazd also has 64 and Kerman has 65 / 75), and codes 39/50/54/60/70 are added. The header of src/Data/PlateCodes.php documents both.
  • Shared plate codes: codes issued before a province split (21 → Tehran + Alborz) are listed in the new PlateNumberDetails::$provinces.
  • CI changes take effect when this PR runs: the new 8.5 job, the no-intl job and the validate --strict step first run on this PR.

Followed by the 0.8 PR (stacked on this branch).

Data
- Plate city codes rebuilt from the persian-tools numberplate dataset,
  cross-checked against fa.wikipedia (77 → Tehran, not Khuzestan; 88
  codes vs 47). Codes issued before a province split list every
  successor via the new PlateNumberDetails::$provinces.
- Plate letters corrected (الف government, پ police, ث/ز/ش/ف military,
  گ temporary…); Arabic ي/ك folded before lookup. Tables moved to
  src/Data/PlateCodes.php / PlateLetters.php behind DataSources.
- Province::ALBORZ; 026 and Karaj-area national-ID prefixes → Alborz;
  کهگیلویه spelling fixed with a fromPersian alias for the old one.
- IBAN 070 now resolves to Bank::RESALAT. New test asserts every name
  in src/Data resolves through its enum's fromPersian().

Input / formatting
- ErrorInput::digits() strips NBSP, ZWNJ, bidi marks, BOM and Unicode
  dashes under /u, escapes $extraCharClass; Iban and LegalId use it.
- NumberFormatter accepts ، ٬ ٫, leading + and space grouping.
- WordsToNumber guards int overflow (null, not TypeError) and rejects
  rank-violating sequences such as "دو سه".
- HtmlSegmenter protects entities and pre/code/textarea; PCRE errors
  raise FormatException (HTML_SEGMENTATION_FAILED).
- Slug strips Persian punctuation, kashida and tashkeel.

Docs, packaging, CI: currency example values, eram/daynum name, ^0.7
pins, CHANGELOG, CONTRIBUTING, async cache list, export-ignore list,
PHP 8.5 + no-intl job + validate --strict in CI, full ErrorCode
snapshot coverage.
@navidkashani navidkashani mentioned this pull request Oct 1, 2026
8 tasks done
@navidkashani
navidkashani merged commit d7da3dd into main Oct 1, 2026
9 checks passed
@navidkashani
navidkashani deleted the improve/0.7 branch October 1, 2026 06:44
@navidkashani
navidkashani restored the improve/0.7 branch October 1, 2026 06:44
@navidkashani
navidkashani deleted the improve/0.7 branch October 1, 2026 06:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant