Besides the scopes themselves, a listener says:
- the actions checked under a scope ([`addAction`](https://mmoframework.fr/fr/documentation/mmo.oauth/php/events/ScopesList.md#scopeslist-addaction)): `data.main.orders#edit` only means something because
the data api checks `#edit` under `data`. A listed scope holding a `#` declares its action too (`dev.boards#write`);
- the scopes whose children are ids, not listed one by one ([`openScope`](https://mmoframework.fr/fr/documentation/mmo.oauth/php/events/ScopesList.md#scopeslist-openscope)): `data.main.orders.{id}`;
- the scopes a page needs besides its own ([`addNeeds`](https://mmoframework.fr/fr/documentation/mmo.oauth/php/events/ScopesList.md#scopeslist-addneeds)): `pages.settings` needs `admin`.
ScopesList::AddListener(function (ScopesList $request) {
$request->addScope('shop', 'Access to the shop');
$request->addAction('shop', 'refund', 'Refund an order'); // shop.orders#refund is checked by the shop
});
Collect every listener for this class, including those registered on its parent classes (so a subclass event is also caught by listeners of its parent event), sorted by ascending $order (ties keep …
Send this signal, but only the FIRST time it's ever called: subsequent calls (with any, even different, $args) just return the same already-dispatched instance, unchanged.
Change the order of an already-registered listener, whether added directly via AddListener or indirectly via ConnectListeners (which also stores its [$obj, $methodName] callables here).