Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 57 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
StoryContentHandler | |
0.00% |
0 / 57 |
|
0.00% |
0 / 9 |
272 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
getContentClass | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getActionOverrides | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
2 | |||
fillParserOutput | |
0.00% |
0 / 23 |
|
0.00% |
0 / 1 |
56 | |||
isParserCacheSupported | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSlotDiffRendererWithOptions | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
preloadTransform | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
preSaveTransform | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
validateSave | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\Wikistories; |
4 | |
5 | use MediaWiki\Category\TrackingCategories; |
6 | use MediaWiki\Content\Content; |
7 | use MediaWiki\Content\JsonContentHandler; |
8 | use MediaWiki\Content\Renderer\ContentParseParams; |
9 | use MediaWiki\Content\Transform\PreloadTransformParams; |
10 | use MediaWiki\Content\Transform\PreSaveTransformParams; |
11 | use MediaWiki\Content\ValidationParams; |
12 | use MediaWiki\Context\IContextSource; |
13 | use MediaWiki\JobQueue\JobQueueGroup; |
14 | use MediaWiki\JobQueue\Jobs\RefreshLinksJob; |
15 | use MediaWiki\Parser\ParserOutput; |
16 | use MediaWiki\Title\Title; |
17 | use MediaWiki\Title\TitleFactory; |
18 | use MediaWiki\Title\TitleValue; |
19 | |
20 | class StoryContentHandler extends JsonContentHandler { |
21 | |
22 | /** @var StoryConverter */ |
23 | private $storyConverter; |
24 | |
25 | /** @var StoryValidator */ |
26 | private $storyValidator; |
27 | |
28 | /** @var StoryRenderer */ |
29 | private $storyRenderer; |
30 | |
31 | /** @var StoryTrackingCategories */ |
32 | private $storyTrackingCategories; |
33 | |
34 | /** @var TrackingCategories */ |
35 | private $trackingCategories; |
36 | |
37 | /** @var JobQueueGroup */ |
38 | private $jobQueueGroup; |
39 | |
40 | /** @var TitleFactory */ |
41 | private $titleFactory; |
42 | |
43 | /** |
44 | * @param string $modelId |
45 | * @param StoryConverter $storyConverter |
46 | * @param StoryValidator $storyValidator |
47 | * @param StoryRenderer $storyRenderer |
48 | * @param StoryTrackingCategories $storyTrackingCategories |
49 | * @param TrackingCategories $trackingCategories |
50 | * @param JobQueueGroup $jobQueueGroup |
51 | * @param TitleFactory $titleFactory |
52 | */ |
53 | public function __construct( |
54 | $modelId, |
55 | StoryConverter $storyConverter, |
56 | StoryValidator $storyValidator, |
57 | StoryRenderer $storyRenderer, |
58 | StoryTrackingCategories $storyTrackingCategories, |
59 | TrackingCategories $trackingCategories, |
60 | JobQueueGroup $jobQueueGroup, |
61 | TitleFactory $titleFactory |
62 | ) { |
63 | parent::__construct( $modelId ); |
64 | $this->storyConverter = $storyConverter; |
65 | $this->storyValidator = $storyValidator; |
66 | $this->storyRenderer = $storyRenderer; |
67 | $this->storyTrackingCategories = $storyTrackingCategories; |
68 | $this->trackingCategories = $trackingCategories; |
69 | $this->jobQueueGroup = $jobQueueGroup; |
70 | $this->titleFactory = $titleFactory; |
71 | } |
72 | |
73 | /** |
74 | * @return string |
75 | */ |
76 | protected function getContentClass() { |
77 | return StoryContent::class; |
78 | } |
79 | |
80 | /** |
81 | * @return array |
82 | */ |
83 | public function getActionOverrides() { |
84 | return [ |
85 | 'edit' => StoryEditAction::class, |
86 | 'submit' => StorySubmitAction::class, |
87 | 'storyview' => [ |
88 | 'class' => StoryViewAction::class, |
89 | 'services' => [ |
90 | 'Wikistories.Cache', |
91 | 'UrlUtils', |
92 | ] |
93 | ], |
94 | ]; |
95 | } |
96 | |
97 | /** |
98 | * Outputs the plain html version of a story. |
99 | * |
100 | * @param Content $content |
101 | * @param ContentParseParams $cpoParams |
102 | * @param ParserOutput &$parserOutput |
103 | */ |
104 | public function fillParserOutput( |
105 | Content $content, |
106 | ContentParseParams $cpoParams, |
107 | ParserOutput &$parserOutput |
108 | ) { |
109 | '@phan-var StoryContent $content'; |
110 | /** @var StoryContent $story */ |
111 | $story = $this->storyConverter->toLatest( $content ); |
112 | $storyPage = $cpoParams->getPage(); |
113 | $storyTitle = Title::newFromPageReference( $storyPage ); |
114 | $storyData = $this->storyRenderer->getStoryData( $story, $storyTitle ); |
115 | |
116 | // Links |
117 | $parserOutput->addLink( new TitleValue( NS_MAIN, $storyData[ 'articleTitle' ] ) ); |
118 | foreach ( $storyData[ 'frames' ] as $frame ) { |
119 | $parserOutput->addImage( strtr( $frame[ 'filename' ], ' ', '_' ) ); |
120 | } |
121 | |
122 | // Categories |
123 | foreach ( $story->getCategories() as $categoryName ) { |
124 | $categoryTitle = $this->titleFactory->makeTitleSafe( NS_CATEGORY, $categoryName ); |
125 | if ( $categoryTitle ) { |
126 | $parserOutput->addCategory( $categoryTitle, $storyPage->getDBkey() ); |
127 | } |
128 | } |
129 | |
130 | // Tracking categories |
131 | foreach ( $storyData[ 'trackingCategories' ] as $trackingCategory ) { |
132 | $this->trackingCategories->addTrackingCategory( |
133 | $parserOutput, $trackingCategory, $storyPage |
134 | ); |
135 | } |
136 | |
137 | // refresh links job when there are changes of tracking categories |
138 | if ( $this->storyTrackingCategories->hasDiff( $storyData[ 'trackingCategories' ], $storyTitle ) ) { |
139 | $this->jobQueueGroup->push( |
140 | RefreshLinksJob::newPrioritized( $storyTitle, [] ) |
141 | ); |
142 | } |
143 | |
144 | // HTML version |
145 | if ( $cpoParams->getGenerateHtml() ) { |
146 | $parts = $this->storyRenderer->renderNoJS( $storyData ); |
147 | $parserOutput->addModuleStyles( [ $parts['style'] ] ); |
148 | $parserOutput->setText( $parts['html'] ); |
149 | } |
150 | } |
151 | |
152 | /** |
153 | * @inheritDoc |
154 | */ |
155 | public function isParserCacheSupported() { |
156 | return true; |
157 | } |
158 | |
159 | /** |
160 | * @param IContextSource $context |
161 | * @param array $options |
162 | * @return StorySlotDiffRenderer |
163 | */ |
164 | public function getSlotDiffRendererWithOptions( IContextSource $context, $options = [] ) { |
165 | return new StorySlotDiffRenderer( |
166 | $this->storyConverter, |
167 | $this->createTextSlotDiffRenderer( $options ) |
168 | ); |
169 | } |
170 | |
171 | /** |
172 | * @inheritDoc |
173 | */ |
174 | public function preloadTransform( Content $content, PreloadTransformParams $pltParams ): Content { |
175 | '@phan-var StoryContent $content'; |
176 | /** @var StoryContent $story */ |
177 | $story = $content; |
178 | return $this->storyConverter->toLatest( $story ); |
179 | } |
180 | |
181 | /** |
182 | * @inheritDoc |
183 | */ |
184 | public function preSaveTransform( Content $content, PreSaveTransformParams $pstParams ): Content { |
185 | '@phan-var StoryContent $content'; |
186 | /** @var StoryContent $story */ |
187 | $story = $content; |
188 | return $this->storyConverter->withSchemaVersion( $story ); |
189 | } |
190 | |
191 | /** |
192 | * @inheritDoc |
193 | */ |
194 | public function validateSave( Content $content, ValidationParams $validationParams ) { |
195 | '@phan-var StoryContent $content'; |
196 | $status = parent::validateSave( $content, $validationParams ); |
197 | if ( !$status->isGood() ) { |
198 | return $status; |
199 | } |
200 | /** @var StoryContent $story */ |
201 | $story = $content; |
202 | return $this->storyValidator->isValid( $story ); |
203 | } |
204 | |
205 | } |