Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
OutputTransformStageHookTrait
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 2
20
0.00% covered (danger)
0.00%
0 / 1
 onOutputTransformFirstStage
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 onOutputTransformLastStage
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\OutputTransform;
5
6use MediaWiki\Parser\ParserOptions;
7use MediaWiki\Parser\ParserOutput;
8
9/**
10 * This trait can be used to implement OutputTransformFirstStageHook or
11 * OutputTransformLastStageHook in any subclass of OutputTransformStage,
12 * which will allow that stage class to be used directly as a hook handler.
13 *
14 * This is optional, but can be useful for transformations that wish to
15 * extend ContentTextTransformStage, ContentDomTransformStage,
16 * ContentHolderTransformStage, or some existing transform.
17 *
18 * For example, a simple text transformation can be defined in an extension
19 * like:
20 * ```php
21 * class SampleTransform
22 *     extends ContentTextTransformStage
23 *     implements OutputTransformFirstStageHook {
24 *   use OutputTransformStageHookTrait;
25 *
26 *   public function __construct(
27 *     Config $mainConfig,
28 *     private readonly MyService $myService,
29 *   ) {
30 *     parent::__construct(
31 *       new ServiceOptions( static::CONSTRUCTOR_OPTIONS, $mainConfig ),
32 *       LoggerFactory::getInstance( 'SampleTransform' )
33 *     );
34 *   }
35 *
36 *   public function shouldRun( ParserOutput $po, ParserOptions $popts, array $options = [] ): bool {
37 *      return $po->getTitle()?->inNamespace( NS_TALK );
38 *   }
39 *
40 *   protected function transformText( string $text, ...) {
41 *     return $text . "<!-- sample talk page transform -->";
42 *   }
43 * }
44 * ```
45 *
46 * And then this would be used as a hook handler by including the following
47 * in `extension.json`:
48 * ```json
49 * {
50 *   "HookHandlers": {
51 *     "transform": {
52 *       "class": "MyExtension\\SampleTransform",
53 *       "services": [
54 *         "MainConfig",
55 *         "MyService",
56 *       ]
57 *     }
58 *   },
59 *   "Hooks": {
60 *     "OutputTransformFirstStage": "transform"
61 *   }
62 * }
63 * ```
64 *
65 * This trait allows extensions to implement OutputTransformStages in the same
66 * way that they are implemented in core. This can be helpful when moving
67 * code from extensions to core or vice-versa and provides a natural
68 * way to provide service objects to your transform.  For very simple
69 * transforms, however, directly implementing the hook (not using this
70 * trait) may be preferable.
71 *
72 * You can see more examples of the use of the trait in the test cases
73 * `ExecuteFirstStageTransformHooksTest` and
74 * `ExecuteLastStageTransformHooksTest`.
75 */
76trait OutputTransformStageHookTrait {
77
78    /** @inheritDoc */
79    public function onOutputTransformFirstStage(
80        ParserOutput &$parserOutput, ParserOptions $parserOptions
81    ): void {
82        '@phan-var OutputTransformStage $this';
83        if ( $this->shouldRun( $parserOutput, $parserOptions ) ) {
84            $ignore = [];
85            $parserOutput = $this->transform(
86                $parserOutput, $parserOptions, $ignore
87            );
88        }
89    }
90
91    /** @inheritDoc */
92    public function onOutputTransformLastStage(
93        ParserOutput &$parserOutput, ParserOptions $parserOptions
94    ): void {
95        '@phan-var OutputTransformStage $this';
96        if ( $this->shouldRun( $parserOutput, $parserOptions ) ) {
97            $ignore = [];
98            $parserOutput = $this->transform(
99                $parserOutput, $parserOptions, $ignore
100            );
101        }
102    }
103}