Šílené rekvizity @Dave Redfernovi na Slacku, který poukázal na můj problém. Při předávání nenulového indexovaného pole je interperováno jako objekt.
dump(json_encode([
0 => "ROLE_SITE_DIRECTOR", 2 => "ROLE_TRANSLATOR", 1 => "ROLE_DATA_ENTRY",
]));
dump(json_encode(array_values([
0 => "ROLE_SITE_DIRECTOR", 2 => "ROLE_TRANSLATOR", 1 => "ROLE_DATA_ENTRY",
])));
výstup bude:
"{"0":"ROLE_SITE_DIRECTOR","2":"ROLE_TRANSLATOR","1":"ROLE_DATA_ENTRY"}"
"["ROLE_SITE_DIRECTOR","ROLE_TRANSLATOR","ROLE_DATA_ENTRY"]"
Takže oprava je jednoduchá, můj setter:
$this->roles = array_values($roles);
V budoucnu je také lepší používat databázové vztahy k rolím. Vyhledávání podle dat JSON není zábavné, ale ve spojení je standardní postup.