Manuel:RequestContext.php

From MediaWiki.org
Jump to navigation Jump to search
This page is a translated version of the page Manual:RequestContext.php and the translation is 100% complete.
Other languages:
English • ‎français • ‎português do Brasil • ‎русский • ‎中文 • ‎日本語
Version de MediaWiki : 1.18

Depuis MediaWiki 1.18 le contexte d'une requête est encapsulé dans une instance RequestContext qui implémente l'interface IContextSource. Les extensions doivent appeler getContext() puis getSomeObject() plutôt que de s'appuyer sur les variables globales d'état.

RequestContext: les accesseurs

Un RequestContext ou IContextSource fournit les accesseurs suivants :

  • $context->getRequest() - instance WebRequest de laquelle récupérer les variables demandées.
  • $context->getTitle() - instance Title pour la page devant être produite.
  • $context->getOutput() - instance OutputPage liée à RequestContext, et vers laquelle sera envoyée la page produite.
  • $context->getSkin() - instance de la classe Skin à utiliser pour générer la page.
  • $context->getUser() - instance de User de l'utilisateur pour lequel la page est générée.
  • $context->getLanguage() - (ajouté en 1.19 pour remplacer $context->getLang() dorénavant obsolète) instance Language de la langue de l'utilisateur dans laquelle la page est générée.
  • $context->getWikiPage() (introduit dans 1.19) - instance WikiPage à produire (mais voir ci-dessous).
  • $context->canUseWikiPage() (introduit dans 1.19) - vérifie si getWikiPage() peut être appelé, sinon lève une exception.
  • $context->msg() - retourne un objet Message dont le contexte est initialisé comme le contexte à appeler. possède les mêmes paramètres que wfMessage() .
  • $context->getConfig() (introduit dans 1.23) - objet Config principal

La sortie (output) et la langue (language) sont en lecture seule, le reste de RequestContext peut être initialisé en utilisant les méthodes telles que $context->setTitle( Title::newMainPage() )).

Travailler avec les contextes de requête

Vous pouvez accéder au contexte principal de la requête en utilisant RequestContext::getMain(); néanmoins ceci doit être fait en dernier recours. La plupart des endroits où vous devez faire quelque chose avec les données du contexte de requête doivent fournir un accès à une source IContextData et vous devez utiliser celle-ci et non pas l'instance principale RequestContext ni les variables globales $wg.

Lorsque vous écrivez une SpecialPage

  • Vous pouvez accéder au contexte avec $this->getContext();
  • SpecialPage implémente aussi un nombre d'assistants :
    • $this->getRequest();
    • $this->getUser();
    • $this->getOutput();
    • $this->getSkin();
  • Vous pouvez utiliser $this->getPageTitle(); pour le titre de SpecialPage et $this->getFullTitle(); pour le titre de la page spéciale ainsi que pour toute donnée $par .
  • Les SpecialPage sont faites pour être exécutées dans les contextes alternatifs afin que les extensions puissent démarrer sans avoir besoin d'utiliser les $wg . Il est probable que nous allons arrêter le support aux alentours de la version MediaWiki 1.20, pour les pages spéciales pouvant être incluses en utilisant les variables $wg relatives au contextes des requêtes.

Lorsque vous écrivez du code d'habillage

  • Vous accédez au contexte par $this→getContext();
  • Skin implémente aussi un nombre d'assistants :
    • $this→getUser();
    • $this→getTitle();
  • Le contexte de l'habilage est passé par Skin::outputPage( $out ); qui est appelé par OutputPage::output(); ; l'accès extérieur aux appels des méthodes sensibles du contexte doit être évité.

Lorsque vous utilisez des accroches

  • Si votre accroche fournit un OutputPage en tant qu'argument, alors utilisez le contexte qu'il fournit.
  • Si votre accroche s'exécute dans le contexte de sortie de la page Skin::outputPage( $out ); , et qu'elle fournit une instance Skin d'habillage, utilisez le contexte qu'elle fournit.
  • Si votre accroche fournit une instance de Title, utilisez la de préférence par rapport aux autres contextes.
  • Le même principe est valable pour toutes les instances de WebRequest passées comme argument aux accroches.
  • Assurez-vous d'utiliser la bonne accroche; si vous founissez un contexte qui n'est pas le bon, alors vous utilisez probablement une accroche à tord et vous pouvez créer des bogues incohérents.
  • Néanmoins certaines accroches peuvent être obsolètes et doivent être appelées avec un nouveau contexte dans leur arguments.

Lorsque vous écrivez des fonctions d'analyseur syntaxique et des accroches

  • Les fonctions de l'analyseur syntaxique ainsi que les accroches ne doivent pas accéder aux données des contextes de requête. Les autres informations contextuelles peuvent être accédées à partir de l'objet analyseur syntaxique local.
    Par exemple : $parser->getOutput()->addModules( 'ext.my.module' );
  • Utilisez ParserOptions pour tout ce dont vous avez besoin comme par exemple la langue de l'utilisateur.
  • Utilisez la classe Linker:: en statique au lieu d'accéder à l'habillage.
  • Si vous devez ajouter quelquechose à la page fournie, en dehors de la zone de contenu, la classe ParserOutput doit avoir les méthodes pour faire ce que vous voulez.
    • Si les méthodes de ParserOutput ne sont pas assez flexibles pour ce que vous devez faire, il est possible d'enregistrer avec ParserOutput, une procédure de rappel (callback) qui sera appelée ultérieurement à un endroit où vous pourrez utiliser librement les contexte de la requête.

Créer de nouveaux contextes de requête

Il existe encore du code qui utilise les variables globales $wgOut, $wgTitle, et $wgUser. Tant que ceux-ci n'auront pas été supprimés, il ne faut pas s'attendre à ce que les contextes personnalisés fonctionnent parfaitement et nous aurons encore besoin des solutions de contournement, néanmoins si nous corrigeons le code pour ne plus utiliser ces variables globales, alors quelque chose de similaire à ce qui suit devrait être possible :

$context = new RequestContext();
$context->setRequest( new FauxRequest( [...] ) );
$context->setTitle( Title::newFromText( [...] ) );
$context->setUser( User::newFromName( 'Dantman' ) );
$context->setSkin( new OfflineDummySkin() );

// [...]
$html = $context->getOutput()->capture();

Utiliser DerivativeContext

Version de MediaWiki : 1.19

MediaWiki 1.19 a ajouté la classe DerivativeContext. DerivativeContext est utile si vous voulez passer un contexte à quelque chose qui est basé sur le contexte avec lequel vous êtes mais un peu différent. Par exemple un contexte qui possède tous les contextes actuels, mais a un titre différent.

$newContext = new DerivativeContext( $currentContext );
$newContext->setTitle( Title::newFromText( 'Asdf' ) );

Lorsque vous concevez l'API d'une classe il est préférable de n'utiliser qu'une seule source de contexte et de ne pas recourir comme argument à un titre séparé (ou par extension, une WikiPage). Comme il est préférable que l'API appelante utilise DerivativeContext si elle doit passer un contexte différent à votre API de classe.

Utiliser IContextSource et ContextSource

La base de RequestContext est l'interface IContextSource. Il définit l'API d'un service à partir duquel vous pouvez obtenir des éléments du contexte de requête. Si vous écrivez une API qui utilise des type hinting dans les arguments, ou qui fait des contrôles instanceof vous devez utiliser IContextSoure, et non pas RequestContext.

if ( $arg instanceof IContextSource ) {
  // Treat $arg as a context object
}
function foo( IContextSource $context ) {
  // Use $context as the request context
}

Additionnellement nous fournissons une classe d'assistant ContextSource. En faisant en sorte que votre classe soit une extension de la classe ContextSource, elle contiendra directement déja, les différents assistants getOutput, getSkin, getLanguage, etc... et sera implements IContextSource. Néanmoins, et parce que malheureusement nous ne pouvons pas utiliser les traits[1] cependant si vous devez étendre votre classe à partir d'une autre classe, vous devrez implements IContextSource et implémenter le squelette de l'assistant directement dans la classe.

A partir d'une classe ContextSource vous pouvez utiliser la méthode setContext pour initialiser le contexte dans lequel se trouve votre classe. Par exemple, un constructeur qui a besoin d'un contexte peut s'écrire ainsi :

class SomeClass extends ContextSource {
  public function __constructor( IContextSource $context ) {
    $this->setContext( $context );
  }
}

Encore une fois, si vous ne pouvez pas étendre ContextSource vous devrez implémenter le squelette de l'assistant directement dans votre classe. Comme nous ne pouvons pas malheureusement utiliser les traits[1] pour permettre quelque chose comme :

class SomeClass extends SomeOtherClass implements IContextSource {
  use TContextSource;
  public function __constructor( IContextSource $context ) {
    $this->setContext( $context );
  }
}

Compatibilité arrière pour les extensions

Utiliser l'édition de liens seule

Si votre extension nécessite la compatibilité 1.18 et que vous voulez utiliser les méthodes de l'éditeur de liens, cette astuce peut vous fournir une instance viable de l'éditeur :

$linker = class_exists( 'DummyLinker' ) ? new DummyLinker() : new Linker();

Maintenant, au lieu d'utiliser une instance de l'habillage pour accéder à l'éditeur de liens, utilisez simplement $linker→ et vous pourrez mettre à jour vers Linker:: lorsque vous supprimez la compatibilité pré-1.18.

References

  1. 1.0 1.1 Les traits sont apparus avec PHP 5.4 et permettent de réduire les limitations de l'héritage unique dans PHP, en vous autorisant de déclarer des méthodes (éventuellement abstraites) avec leur modificateur d'accès (public, private, protected) que vous pouvez utiliser dans des classes distinctes.