Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 63 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
ApiDiscussionToolsFindComment | |
0.00% |
0 / 63 |
|
0.00% |
0 / 6 |
420 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 38 |
|
0.00% |
0 / 1 |
210 | |||
getValue | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
6 | |||
getAllowedParams | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
2 | |||
needsToken | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isWriteMode | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\DiscussionTools; |
4 | |
5 | use MediaWiki\Api\ApiBase; |
6 | use MediaWiki\Api\ApiMain; |
7 | use MediaWiki\Api\ApiUsageException; |
8 | use MediaWiki\Extension\DiscussionTools\ThreadItem\DatabaseThreadItem; |
9 | use MediaWiki\Title\Title; |
10 | use MediaWiki\Title\TitleFormatter; |
11 | use Wikimedia\ParamValidator\ParamValidator; |
12 | |
13 | class ApiDiscussionToolsFindComment extends ApiBase { |
14 | |
15 | private ThreadItemStore $threadItemStore; |
16 | private TitleFormatter $titleFormatter; |
17 | |
18 | public function __construct( |
19 | ApiMain $main, |
20 | string $name, |
21 | ThreadItemStore $threadItemStore, |
22 | TitleFormatter $titleFormatter |
23 | ) { |
24 | parent::__construct( $main, $name ); |
25 | $this->threadItemStore = $threadItemStore; |
26 | $this->titleFormatter = $titleFormatter; |
27 | } |
28 | |
29 | /** |
30 | * @inheritDoc |
31 | * @throws ApiUsageException |
32 | */ |
33 | public function execute() { |
34 | $params = $this->extractRequestParams(); |
35 | |
36 | $values = []; |
37 | |
38 | $this->requireAtLeastOneParameter( $params, 'idorname', 'heading', 'page' ); |
39 | |
40 | if ( $params['idorname'] ) { |
41 | $idOrName = $params['idorname']; |
42 | |
43 | $byId = $this->threadItemStore->findNewestRevisionsById( $idOrName ); |
44 | foreach ( $byId as $item ) { |
45 | $values[] = $this->getValue( $item, 'id' ); |
46 | } |
47 | |
48 | $byName = $this->threadItemStore->findNewestRevisionsByName( $idOrName ); |
49 | foreach ( $byName as $item ) { |
50 | $values[] = $this->getValue( $item, 'name' ); |
51 | } |
52 | } else { |
53 | $this->requireAtLeastOneParameter( $params, 'heading' ); |
54 | $this->requireAtLeastOneParameter( $params, 'page' ); |
55 | |
56 | $heading = $params['heading']; |
57 | $page = $params['page']; |
58 | |
59 | $title = Title::newFromText( $page ); |
60 | if ( $title ) { |
61 | $articleId = $title->getArticleId(); |
62 | |
63 | if ( $articleId ) { |
64 | try { |
65 | $byHeading = $this->threadItemStore->findNewestRevisionsByHeading( |
66 | $heading, $articleId, $title->getTitleValue() |
67 | ); |
68 | } catch ( PageNeverHadThreadsException $e ) { |
69 | $this->dieWithError( [ 'apierror-discussiontools-findcomment-pagenevertalk' ] ); |
70 | } |
71 | foreach ( $byHeading as $item ) { |
72 | $values[] = $this->getValue( $item, 'heading' ); |
73 | } |
74 | } else { |
75 | // TODO: Consider if we should still search if the article ID is not found |
76 | $this->dieWithError( [ 'apierror-discussiontools-findcomment-pagenevertalk' ] ); |
77 | } |
78 | } else { |
79 | // TODO: Consider if we should still search if the title is invalid |
80 | $this->dieWithError( [ 'apierror-discussiontools-findcomment-pagenevertalk' ] ); |
81 | } |
82 | } |
83 | |
84 | $redirects = 0; |
85 | foreach ( $values as $value ) { |
86 | if ( $value['couldredirect'] ) { |
87 | $redirects++; |
88 | if ( $redirects > 1 ) { |
89 | break; |
90 | } |
91 | } |
92 | } |
93 | foreach ( $values as $value ) { |
94 | if ( $redirects === 1 && $value['couldredirect'] ) { |
95 | $value['shouldredirect'] = true; |
96 | } |
97 | $this->getResult()->addValue( $this->getModuleName(), null, $value ); |
98 | } |
99 | } |
100 | |
101 | /** |
102 | * Get a value to add to the results |
103 | * |
104 | * @param DatabaseThreadItem $item Thread item |
105 | * @param string $matchedBy How the thread item was matched (id, name or heading) |
106 | * @return array |
107 | */ |
108 | private function getValue( DatabaseThreadItem $item, string $matchedBy ): array { |
109 | $title = Title::castFromPageReference( $item->getPage() ); |
110 | |
111 | return [ |
112 | 'id' => $item->getId(), |
113 | 'name' => $item->getName(), |
114 | 'title' => $this->titleFormatter->getPrefixedText( $item->getPage() ), |
115 | 'oldid' => !$item->getRevision()->isCurrent() ? $item->getRevision()->getId() : null, |
116 | 'matchedby' => $matchedBy, |
117 | // Could this be an automatic redirect? Will be converted to 'shouldredirect' |
118 | // if there is only one of these in the result set. |
119 | 'couldredirect' => $item->isCanonicalPermalink(), |
120 | ]; |
121 | } |
122 | |
123 | /** |
124 | * @inheritDoc |
125 | */ |
126 | public function getAllowedParams() { |
127 | return [ |
128 | 'idorname' => [ |
129 | ParamValidator::PARAM_TYPE => 'string', |
130 | ], |
131 | 'heading' => [ |
132 | ParamValidator::PARAM_TYPE => 'string', |
133 | ], |
134 | 'page' => [ |
135 | ParamValidator::PARAM_TYPE => 'string', |
136 | ], |
137 | ]; |
138 | } |
139 | |
140 | /** |
141 | * @inheritDoc |
142 | */ |
143 | public function needsToken() { |
144 | return false; |
145 | } |
146 | |
147 | /** |
148 | * @inheritDoc |
149 | */ |
150 | public function isWriteMode() { |
151 | return false; |
152 | } |
153 | } |