Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 77 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
SpecialDiscussionToolsDebug | |
0.00% |
0 / 77 |
|
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 / 33 |
|
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 | $status = $this->parserOutputAccess->getParserOutput( |
88 | $title->toPageRecord(), |
89 | ParserOptions::newFromAnon() |
90 | ); |
91 | if ( !$status->isOK() ) { |
92 | return $status; |
93 | } |
94 | |
95 | $parserOutput = $status->getValue(); |
96 | $html = $parserOutput->getText(); |
97 | |
98 | $doc = DOMUtils::parseHTML( $html ); |
99 | $container = DOMCompat::getBody( $doc ); |
100 | $threadItemSet = $this->commentParser->parse( $container, $title->getTitleValue() ); |
101 | |
102 | $out = $this->getOutput(); |
103 | |
104 | $out->addHTML( $this->msg( |
105 | 'discussiontoolsdebug-intro', |
106 | $title->getPrefixedText(), |
107 | SpecialPage::getTitleFor( |
108 | 'ApiSandbox', |
109 | false, |
110 | 'action=discussiontoolspageinfo&prop=threaditemshtml&excludesignatures=1&page=' |
111 | . urlencode( $title->getPrefixedText() ) |
112 | )->getFullText() |
113 | )->parseAsBlock() ); |
114 | |
115 | $pageLang = $this->languageFactory->getLanguage( $parserOutput->getLanguage() ); |
116 | $pageLangAttribs = [ |
117 | 'lang' => $pageLang->getHtmlCode(), |
118 | 'dir' => $pageLang->getDir(), |
119 | 'class' => 'mw-content-' . $pageLang->getDir(), |
120 | ]; |
121 | |
122 | foreach ( $threadItemSet->getThreadsStructured() as $thread ) { |
123 | $out->addHTML( $this->formatComments( $thread, $pageLangAttribs ) ); |
124 | } |
125 | |
126 | $out->addModuleStyles( 'ext.discussionTools.debug.styles' ); |
127 | |
128 | return true; |
129 | } |
130 | |
131 | /** |
132 | * Format a thread item with replies. |
133 | * |
134 | * @param ContentThreadItem $comment |
135 | * @param array $pageLangAttribs |
136 | * @return string HTML |
137 | */ |
138 | private function formatComments( ContentThreadItem $comment, array $pageLangAttribs ) { |
139 | if ( $comment instanceof ContentHeadingItem ) { |
140 | $contents = '<span class="mw-dt-heading">' . $comment->getHTML() . '</span>'; |
141 | } else { |
142 | Assert::precondition( $comment instanceof ContentCommentItem, 'Must be ContentCommentItem' ); |
143 | $contents = |
144 | '<span class="mw-dt-comment-signature">' . |
145 | '<span class="mw-dt-comment-author">' . |
146 | Linker::userLink( 0, $comment->getAuthor() ) . |
147 | '</span>' . ' ' . |
148 | '(' . Linker::userTalkLink( 0, $comment->getAuthor() ) . ') ' . |
149 | '<span class="mw-dt-comment-timestamp">' . |
150 | htmlspecialchars( $this->getLanguage()->getHumanTimestamp( |
151 | new MWTimestamp( $comment->getTimestamp()->getTimestamp() ) |
152 | ) ) . |
153 | '</span>' . |
154 | '</span>' . |
155 | Html::rawElement( 'div', $pageLangAttribs, |
156 | '<div class="mw-dt-comment-body mw-parser-output">' . $comment->getBodyHTML( true ) . '</div>' |
157 | ); |
158 | } |
159 | $level = $comment->getLevel(); |
160 | |
161 | $replies = ''; |
162 | foreach ( $comment->getReplies() as $reply ) { |
163 | $replies .= $this->formatComments( $reply, $pageLangAttribs ); |
164 | } |
165 | |
166 | return Html::rawElement( $replies ? 'details' : 'div', [ |
167 | 'open' => (bool)$replies, |
168 | 'class' => 'mw-dt-comment', |
169 | 'data-level' => $level, |
170 | ], ( $replies ? Html::rawElement( 'summary', [], $contents ) : $contents ) . $replies ); |
171 | } |
172 | |
173 | } |