Skip to content

Prepare 1.1.0: slugify() and hash() - #7

Closed
mohaelmrabet wants to merge 2 commits into
mainfrom
feat/v1.1.0-slugify-hash
Closed

Prepare 1.1.0: slugify() and hash()#7
mohaelmrabet wants to merge 2 commits into
mainfrom
feat/v1.1.0-slugify-hash

Conversation

@mohaelmrabet

Copy link
Copy Markdown
Contributor

Two methods that were already being written by hand on top of tokenize() at call sites — which is how two callers end up with different answers for the same string.

slugify(string $text, string $separator = '-')

Joins the tokens tokenize() already produces, so a slug can never disagree with the rest of the package about where a word ends. Text that normalizes to nothing yields an empty string.

It is not an ASCII slugger. Non-Latin input stays in its own script, folded but not transliterated — the same distinction the README already draws against cocur/slugify, so that table gained a row rather than being contradicted:

$normalizer->slugify("L'adresse email de l'utilisateur"); // "l-adresse-email-de-l-utilisateur"
$normalizer->slugify('Météo à Rabat', '_');               // "meteo_a_rabat"

hash(string $text, string $algo = 'sha256')

Digests the slug. Two strings this package considers equivalent — casing, typographic apostrophes, collapsed spacing, trailing punctuation — always produce the same digest, which is what makes it usable as a deduplication or lookup key:

$normalizer->hash("L'adresse email") === $normalizer->hash('L’ADRESSE   email.'); // true

Documented as a fingerprint and not a secret: unsalted and deterministic by design, never a password hash. An unsalted digest invites the wrong reading, so both the PHPDoc and the README say so plainly.

Scope

No behaviour changed. normalize(), tokenize() and analyze() are untouched, and both additions are pure functions of normalize() — nothing folds text a second way.

52 tests green, PHPStan clean at max level.

Release

Prepares v1.1.0 (additive, minor). CHANGELOG.md is written for it; tag after merge.

Both were being written by hand at call sites, on top of tokenize(), which is
how two callers end up with different answers for the same string. slugify()
joins the tokens the normalizer already produces; hash() digests that slug, so
two strings this package considers equivalent — casing, typographic
apostrophes, collapsed spacing, trailing punctuation — always hash alike. That
equivalence is the point: it makes the hash usable as a deduplication or
lookup key.
The README pointed readers at cocur/slugify for slugs, so the new method needed
that table to say what it does differently: it folds in the original script
rather than forcing ASCII. The hash is documented as a fingerprint and not a
secret, since an unsalted digest invites the wrong reading.
@mohaelmrabet

Copy link
Copy Markdown
Contributor Author

Fermée sans merge : le package n'est pas un générateur de slug.

Cette frontière est déjà écrite dans son README — il produit une clé de comparaison dans le script d'origine, et renvoie à cocur/slugify pour un slug d'URL. Joindre les tokens qu'il produit est l'affaire de son consommateur, qui le fait déjà.

L'origine de la demande, ADR-0042 §4 côté Concio, a été corrigée en conséquence.

@mohaelmrabet
mohaelmrabet deleted the feat/v1.1.0-slugify-hash branch August 17, 2026 11:23
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