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