Les circonstances d’une question

Le quatrième champ d’une question est celui dont personne ne parle : ce qui n’appartient ni au demandeur, ni au sujet, ni à l’attribut. Une adresse IP, une heure, une requête, une commande.

$environment = new AccessEnvironment(['ip' => '10.0.0.1', 'hour' => 22]);

$environment->get('ip');              // '10.0.0.1'
$environment->get('country', 'FR');   // the default, the key being absent
$environment->has('country');         // false
count($environment);                  // 2

Quatre clés, et ce sont les seules

Chaque point d’entrée remplit ce qu’il connaît, et le composant sème exactement quatre noms. Tout le reste du sac est à vous.

  • request, semée par tous les points d’entrée web : l’écouteur de politiques d’accès, l’écouteur de règles d’URL, la passerelle #[IsGranted].
  • command, input et output, semées par le point d’entrée console.

Elles sont publiées en constantes, et AccessEnvironment::SEEDED_KEYS contient les quatre, de sorte qu’une application peut les distinguer des siennes. Ce sont elles que nomme une condition When : request.isMethod("POST") sur le web, input.getOption("force") sur la console.

Chaque point d’entrée épingle son propre jeu par un test. Une clé perdue ou renommée en silence est une garde qui cesse de s’appliquer, pas une garde qui casse, et ce sont celles-là dont vous apprenez l’existence par quelqu’un d’autre.

has, pas get, quand la règle a besoin de la clé

L’environnement ne passe délibérément pas sous silence une clé manquante quand une règle en dépend. Une règle qui s’abstient parce qu’une clé est absente tombe en position ouverte, et aucun point d’entrée ne devrait pouvoir désactiver une règle par omission.

Lisez-le donc avec has() et décidez de ce que signifie l’absence, au lieu de laisser get() vous tendre une valeur par défaut à laquelle vous n’avez pas pensé. Un votant qui refuse parce qu’il ne peut pas savoir d’où vient une requête fait son travail ; un votant qui hausse les épaules, non.

Pourquoi le sac reste ouvert

Un tableau à clés de chaînes, dans un composant aussi soigneux sur les types, est une décision qu’il fallait argumenter plutôt que laisser en suspens. Elle l’a été, et mesurée plutôt que supposée.

Rien dans le composant ne lit jamais une clé. L’environnement est transporté jusqu’au votant d’expression, qui le publie en variable, jusqu’au votant de fermeture, et jusqu’au panneau du profileur. Ses consommateurs travaillent tous à clés de chaînes, donc un type PHP ne leur apporterait rien et coûterait à la bibliothèque son indépendance vis-à-vis d’HttpFoundation et de Console, qu’elle n’exige aujourd’hui pas du tout.

Et l’erreur qu’un typage attraperait est déjà bruyante là où cela compte : une expression qui nomme une variable que rien n’a semée lève à la compilation. Ce qui reste silencieux, c’est $environment->get('typo') à l’intérieur d’un de vos votants, et typer quatre clés du framework n’aurait pas couvert cela non plus, vos clés étant les vôtres.

Ajouter les vôtres

Une politique d’accès prend un tableau environment, fusionné dans ce que le point d’entrée a semé, et c’est la voie déclarative. Par programme, remettez un AccessEnvironment à la requête que vous construisez.

Une mise en garde, apprise de la politique d’heures ouvrables de l’application de démonstration : ce qu’un gestionnaire peut obtenir par lui-même, une horloge étant le cas évident, vaut mieux injecté que passé par le sac. Ce que seul le point d’entrée connaît a sa place dans l’environnement. Ce que n’importe qui peut demander, non.