`OE`, `ß`->`SS`) ne sont PAS gerees * par `translate()` (mapping 1->1 uniquement) ; elles n'apparaissent pas dans * les noms de categories CLIENT et le backfill ne s'execute de toute facon que * sur des bases dev deja peuplees (en prod la table `category` est vide). */ final class CategoryCodeSql { /** Longueur maximale de la colonne `category.code` (cf. CategoryCodeGenerator). */ private const int MAX_LENGTH = 50; /** * Accents Latin-1 (minuscules puis majuscules) translitteres vers leur * equivalent ASCII minuscule — `UPPER()` repasse tout en majuscule ensuite. * `translate()` mappe caractere a caractere : `ACCENT_FROM` et `ACCENT_TO` * doivent avoir EXACTEMENT le meme nombre de caracteres. */ private const string ACCENT_FROM = 'àâäáãåçéèêëíìîïñóòôöõúùûüýÿÀÂÄÁÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸ'; private const string ACCENT_TO = 'aaaaaaceeeeiiiinooooouuuuyyaaaaaaceeeeiiiinooooouuuuyy'; /** * Expression SQL produisant le slug du `$column` donne (ex: `name`, `c.name`). * Reproduit fidelement `CategoryCodeGenerator::slugify` : translitteration des * accents, separateurs non alphanumeriques reduits a `_`, MAJUSCULE, borne a * 50, `_` de bord retires, fallback `CATEGORY` si vide. */ public static function slugExpression(string $column): string { return sprintf( "COALESCE(NULLIF(TRIM(BOTH '_' FROM " ."LEFT(UPPER(REGEXP_REPLACE(translate(%s, '%s', '%s'), '[^A-Za-z0-9]+', '_', 'g')), %d)" ."), ''), 'CATEGORY')", $column, self::ACCENT_FROM, self::ACCENT_TO, self::MAX_LENGTH, ); } }