Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 80 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
SpecialDiscussionToolsDebug | |
0.00% |
0 / 80 |
|
0.00% |
0 / 8 |
210 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
getDescription | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFormFields | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
getSubpageField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDisplayFormat | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
requiresPost | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
onSubmit | |
0.00% |
0 / 36 |
|
0.00% |
0 / 1 |
12 | |||
formatComments | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
30 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\DiscussionTools; |
4 | |
5 | use MediaWiki\Extension\DiscussionTools\ThreadItem\ContentCommentItem; |
6 | use MediaWiki\Extension\DiscussionTools\ThreadItem\ContentHeadingItem; |
7 | use MediaWiki\Extension\DiscussionTools\ThreadItem\ContentThreadItem; |
8 | use MediaWiki\Html\Html; |
9 | use MediaWiki\Languages\LanguageFactory; |
10 | use MediaWiki\Linker\Linker; |
11 | use MediaWiki\Page\ParserOutputAccess; |
12 | use MediaWiki\Parser\ParserOptions; |
13 | use MediaWiki\SpecialPage\FormSpecialPage; |
14 | use MediaWiki\SpecialPage\SpecialPage; |
15 | use MediaWiki\Title\Title; |
16 | use MediaWiki\Utils\MWTimestamp; |
17 | use Wikimedia\Assert\Assert; |
18 | use Wikimedia\Parsoid\Utils\DOMCompat; |
19 | use Wikimedia\Parsoid\Utils\DOMUtils; |
20 | |
21 | class SpecialDiscussionToolsDebug extends FormSpecialPage { |
22 | |
23 | private LanguageFactory $languageFactory; |
24 | private ParserOutputAccess $parserOutputAccess; |
25 | private CommentParser $commentParser; |
26 | |
27 | public function __construct( |
28 | LanguageFactory $languageFactory, |
29 | ParserOutputAccess $parserOutputAccess, |
30 | CommentParser $commentParser |
31 | ) { |
32 | parent::__construct( 'DiscussionToolsDebug' ); |
33 | $this->languageFactory = $languageFactory; |
34 | $this->parserOutputAccess = $parserOutputAccess; |
35 | $this->commentParser = $commentParser; |
36 | } |
37 | |
38 | /** |
39 | * @inheritDoc |
40 | */ |
41 | public function getDescription() { |
42 | return $this->msg( 'discussiontoolsdebug-title' ); |
43 | } |
44 | |
45 | /** |
46 | * @inheritDoc |
47 | */ |
48 | protected function getFormFields() { |
49 | return [ |
50 | 'pagetitle' => [ |
51 | 'label-message' => 'discussiontoolsdebug-pagetitle', |
52 | 'name' => 'pagetitle', |
53 | 'type' => 'title', |
54 | 'required' => true, |
55 | 'exists' => true, |
56 | ], |
57 | ]; |
58 | } |
59 | |
60 | /** |
61 | * @inheritDoc |
62 | */ |
63 | protected function getSubpageField() { |
64 | return 'pagetitle'; |
65 | } |
66 | |
67 | /** |
68 | * @inheritDoc |
69 | */ |
70 | protected function getDisplayFormat() { |
71 | return 'ooui'; |
72 | } |
73 | |
74 | /** |
75 | * @inheritDoc |
76 | */ |
77 | public function requiresPost() { |
78 | return false; |
79 | } |
80 | |
81 | /** |
82 | * @inheritDoc |
83 | */ |
84 | public function onSubmit( array $data ) { |
85 | $title = Title::newFromText( $data['pagetitle'] ); |
86 | |
87 | $parserOptions = ParserOptions::newFromAnon(); |
88 | $status = $this->parserOutputAccess->getParserOutput( |
89 | $title->toPageRecord(), |
90 | $parserOptions |
91 | ); |
92 | if ( !$status->isOK() ) { |
93 | return $status; |
94 | } |
95 | |
96 | $parserOutput = $status->getValue(); |
97 | $html = $parserOutput->runOutputPipeline( $parserOptions, [ |
98 | 'enableSectionEditLinks' => false, |
99 | ] )->getContentHolderText(); |
100 | |
101 | $doc = DOMUtils::parseHTML( $html ); |
102 | $container = DOMCompat::getBody( $doc ); |
103 | $threadItemSet = $this->commentParser->parse( $container, $title->getTitleValue() ); |
104 | |
105 | $out = $this->getOutput(); |
106 | |
107 | $out->addHTML( $this->msg( |
108 | 'discussiontoolsdebug-intro', |
109 | $title->getPrefixedText(), |
110 | SpecialPage::getTitleFor( |
111 | 'ApiSandbox', |
112 | false, |
113 | 'action=discussiontoolspageinfo&prop=threaditemshtml&excludesignatures=1&page=' |
114 | . urlencode( $title->getPrefixedText() ) |
115 | )->getFullText() |
116 | )->parseAsBlock() ); |
117 | |
118 | $pageLang = $this->languageFactory->getLanguage( $parserOutput->getLanguage() ); |
119 | $pageLangAttribs = [ |
120 | 'lang' => $pageLang->getHtmlCode(), |
121 | 'dir' => $pageLang->getDir(), |
122 | 'class' => 'mw-content-' . $pageLang->getDir(), |
123 | ]; |
124 | |
125 | foreach ( $threadItemSet->getThreadsStructured() as $thread ) { |
126 | $out->addHTML( $this->formatComments( $thread, $pageLangAttribs ) ); |
127 | } |
128 | |
129 | $out->addModuleStyles( 'ext.discussionTools.debug.styles' ); |
130 | |
131 | return true; |
132 | } |
133 | |
134 | /** |
135 | * Format a thread item with replies. |
136 | * |
137 | * @param ContentThreadItem $comment |
138 | * @param array $pageLangAttribs |
139 | * @return string HTML |
140 | */ |
141 | private function formatComments( ContentThreadItem $comment, array $pageLangAttribs ) { |
142 | if ( $comment instanceof ContentHeadingItem ) { |
143 | $contents = '<span class="mw-dt-heading">' . $comment->getHTML() . '</span>'; |
144 | } else { |
145 | Assert::precondition( $comment instanceof ContentCommentItem, 'Must be ContentCommentItem' ); |
146 | $contents = |
147 | '<span class="mw-dt-comment-signature">' . |
148 | '<span class="mw-dt-comment-author">' . |
149 | Linker::userLink( 0, $comment->getAuthor() ) . |
150 | '</span>' . ' ' . |
151 | '(' . Linker::userTalkLink( 0, $comment->getAuthor() ) . ') ' . |
152 | '<span class="mw-dt-comment-timestamp">' . |
153 | htmlspecialchars( $this->getLanguage()->getHumanTimestamp( |
154 | new MWTimestamp( $comment->getTimestamp()->getTimestamp() ) |
155 | ) ) . |
156 | '</span>' . |
157 | '</span>' . |
158 | Html::rawElement( 'div', $pageLangAttribs, |
159 | '<div class="mw-dt-comment-body mw-parser-output">' . $comment->getBodyHTML( true ) . '</div>' |
160 | ); |
161 | } |
162 | $level = $comment->getLevel(); |
163 | |
164 | $replies = ''; |
165 | foreach ( $comment->getReplies() as $reply ) { |
166 | $replies .= $this->formatComments( $reply, $pageLangAttribs ); |
167 | } |
168 | |
169 | return Html::rawElement( $replies ? 'details' : 'div', [ |
170 | 'open' => (bool)$replies, |
171 | 'class' => 'mw-dt-comment', |
172 | 'data-level' => $level, |
173 | ], ( $replies ? Html::rawElement( 'summary', [], $contents ) : $contents ) . $replies ); |
174 | } |
175 | |
176 | } |