Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 65 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
ApiDiscussionToolsTrait | |
0.00% |
0 / 65 |
|
0.00% |
0 / 4 |
240 | |
0.00% |
0 / 1 |
previewMessage | |
0.00% |
0 / 55 |
|
0.00% |
0 / 1 |
156 | |||
getUserForPreview | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
getParsoidClient | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
requestRestbasePageHtml | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
transformHTML | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
0 | |||
getContext | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
getUser | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
getRequest | n/a |
0 / 0 |
n/a |
0 / 0 |
0 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\DiscussionTools; |
4 | |
5 | use ApiMain; |
6 | use ApiResult; |
7 | use MediaWiki\Context\DerivativeContext; |
8 | use MediaWiki\Context\IContextSource; |
9 | use MediaWiki\Extension\VisualEditor\ParsoidClient; |
10 | use MediaWiki\Extension\VisualEditor\VisualEditorParsoidClientFactory; |
11 | use MediaWiki\Request\DerivativeRequest; |
12 | use MediaWiki\Request\WebRequest; |
13 | use MediaWiki\Revision\RevisionRecord; |
14 | use MediaWiki\Title\Title; |
15 | use MediaWiki\User\TempUser\TempUserCreator; |
16 | use MediaWiki\User\User; |
17 | use MediaWiki\User\UserFactory; |
18 | use Wikimedia\Parsoid\Utils\DOMCompat; |
19 | use Wikimedia\Parsoid\Utils\DOMUtils; |
20 | |
21 | /** |
22 | * Random methods we want to share between API modules. |
23 | * |
24 | * @property VisualEditorParsoidClientFactory $parsoidClientFactory |
25 | * @property CommentParser $commentParser |
26 | * @property TempUserCreator $tempUserCreator |
27 | * @property UserFactory $userFactory |
28 | */ |
29 | trait ApiDiscussionToolsTrait { |
30 | |
31 | /** |
32 | * Given parameters describing a reply or new topic, transform them into wikitext using Parsoid, |
33 | * then preview the wikitext using the legacy parser. |
34 | * |
35 | * @param string $type 'topic' or 'reply' |
36 | * @param Title $title Context title for wikitext transformations |
37 | * @param array $params Associative array with the following keys: |
38 | * - `wikitext` (string|null) Content of the message, mutually exclusive with `html` |
39 | * - `html` (string|null) Content of the message, mutually exclusive with `wikitext` |
40 | * - `sectiontitle` (string) Content of the title, when `type` is 'topic' |
41 | * - `signature` (string|null) Wikitext signature to add to the message |
42 | * @param array $originalParams Original params from the source API call |
43 | * @return ApiResult action=parse API result |
44 | */ |
45 | protected function previewMessage( |
46 | string $type, Title $title, array $params, array $originalParams = [] |
47 | ): ApiResult { |
48 | $wikitext = $params['wikitext'] ?? null; |
49 | $html = $params['html'] ?? null; |
50 | $signature = $params['signature'] ?? null; |
51 | |
52 | switch ( $type ) { |
53 | case 'topic': |
54 | if ( $wikitext !== null ) { |
55 | if ( $signature !== null ) { |
56 | $wikitext = CommentModifier::appendSignatureWikitext( $wikitext, $signature ); |
57 | } |
58 | } else { |
59 | $doc = DOMUtils::parseHTML( '' ); |
60 | $container = DOMUtils::parseHTMLToFragment( $doc, $html ); |
61 | if ( $signature !== null ) { |
62 | CommentModifier::appendSignature( $container, $signature ); |
63 | } |
64 | $html = DOMUtils::getFragmentInnerHTML( $container ); |
65 | $wikitext = $this->transformHTML( $title, $html )[ 'body' ]; |
66 | } |
67 | |
68 | if ( $params['sectiontitle'] ) { |
69 | $wikitext = "== " . $params['sectiontitle'] . " ==\n" . $wikitext; |
70 | } |
71 | |
72 | break; |
73 | |
74 | case 'reply': |
75 | $doc = DOMUtils::parseHTML( '' ); |
76 | |
77 | if ( $wikitext !== null ) { |
78 | $container = CommentModifier::prepareWikitextReply( $doc, $wikitext ); |
79 | } else { |
80 | $container = CommentModifier::prepareHtmlReply( $doc, $html ); |
81 | } |
82 | |
83 | if ( $signature !== null ) { |
84 | CommentModifier::appendSignature( $container, $signature ); |
85 | } |
86 | $list = CommentModifier::transferReply( $container ); |
87 | $html = DOMCompat::getOuterHTML( $list ); |
88 | |
89 | $wikitext = $this->transformHTML( $title, $html )[ 'body' ]; |
90 | |
91 | break; |
92 | } |
93 | |
94 | $apiParams = [ |
95 | 'action' => 'parse', |
96 | 'title' => $title->getPrefixedText(), |
97 | 'text' => $wikitext, |
98 | 'pst' => '1', |
99 | 'preview' => '1', |
100 | 'disableeditsection' => '1', |
101 | 'prop' => 'text|modules|jsconfigvars', |
102 | ]; |
103 | if ( isset( $originalParams['useskin'] ) ) { |
104 | $apiParams['useskin'] = $originalParams['useskin']; |
105 | } |
106 | if ( isset( $originalParams['mobileformat'] ) && $originalParams['mobileformat'] ) { |
107 | $apiParams['mobileformat'] = '1'; |
108 | } |
109 | |
110 | $context = new DerivativeContext( $this->getContext() ); |
111 | $context->setRequest( |
112 | new DerivativeRequest( |
113 | $context->getRequest(), |
114 | $apiParams, |
115 | /* was posted? */ true |
116 | ) |
117 | ); |
118 | $api = new ApiMain( |
119 | $context, |
120 | /* enable write? */ false |
121 | ); |
122 | |
123 | $api->execute(); |
124 | return $api->getResult(); |
125 | } |
126 | |
127 | /** |
128 | * @see ApiParse::getUserForPreview |
129 | * @return User |
130 | */ |
131 | private function getUserForPreview() { |
132 | $user = $this->getUser(); |
133 | if ( $this->tempUserCreator->shouldAutoCreate( $user, 'edit' ) ) { |
134 | return $this->userFactory->newUnsavedTempUser( |
135 | $this->tempUserCreator->getStashedName( $this->getRequest()->getSession() ) |
136 | ); |
137 | } |
138 | return $user; |
139 | } |
140 | |
141 | /** |
142 | * @see VisualEditorParsoidClientFactory |
143 | * @return ParsoidClient |
144 | */ |
145 | protected function getParsoidClient(): ParsoidClient { |
146 | return $this->parsoidClientFactory->createParsoidClient( |
147 | $this->getContext()->getRequest()->getHeader( 'Cookie' ) |
148 | ); |
149 | } |
150 | |
151 | /** |
152 | * @warning (T323357) - Calling this method writes to stash, so it should be called |
153 | * only when we are fetching page HTML for editing. |
154 | */ |
155 | abstract protected function requestRestbasePageHtml( RevisionRecord $revision ): array; |
156 | |
157 | abstract protected function transformHTML( |
158 | Title $title, string $html, int $oldid = null, string $etag = null |
159 | ): array; |
160 | |
161 | /** |
162 | * @return IContextSource |
163 | */ |
164 | abstract public function getContext(); |
165 | |
166 | /** |
167 | * @return User |
168 | */ |
169 | abstract public function getUser(); |
170 | |
171 | /** |
172 | * @return WebRequest |
173 | */ |
174 | abstract public function getRequest(); |
175 | |
176 | } |