Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
83.33% covered (warning)
83.33%
70 / 84
66.67% covered (warning)
66.67%
4 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiClient
83.33% covered (warning)
83.33%
70 / 84
66.67% covered (warning)
66.67%
4 / 6
11.56
0.00% covered (danger)
0.00%
0 / 1
 findComment
94.74% covered (success)
94.74%
18 / 19
0.00% covered (danger)
0.00%
0 / 1
3.00
 getUserTalkPageInfo
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 addFollowUpComment
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
1
 addTopic
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
1
 executeApiQuery
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
2
 checkCommentRedirects
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * @file
18 */
19
20namespace AutoModerator;
21
22use MediaWiki\Api\ApiMain;
23use MediaWiki\Api\ApiUsageException;
24use MediaWiki\Context\DerivativeContext;
25use MediaWiki\Context\RequestContext;
26use MediaWiki\Request\DerivativeRequest;
27use MediaWiki\Title\Title;
28use MediaWiki\User\User;
29
30class ApiClient {
31
32    /**
33     * Make a single call to MediaWiki API discussiontoolsfindcomment and return the decoded result.
34     *
35     * @param string $commentHeader
36     * @param Title $userTalkPageTitle
37     *
38     * @return array Decoded response
39     */
40    public function findComment( string $commentHeader, Title $userTalkPageTitle ) {
41        try {
42            $context = new DerivativeContext( RequestContext::getMain() );
43            $headerNoEqualsSymbol = trim( str_replace( "==", "", $commentHeader ) );
44            $headerWithoutSpaces = str_replace( " ", "_", $headerNoEqualsSymbol );
45            $userTalkPageString = str_replace( "_", " ", $userTalkPageTitle->getTalkNsText() ) .
46                ':' . $userTalkPageTitle->getText();
47            $queryParams = [
48                "action" => "discussiontoolsfindcomment",
49                "format" => "json",
50                "heading" => $headerWithoutSpaces,
51                "page" => $userTalkPageString,
52                "formatversion" => "2"
53            ];
54            $data = $this->executeApiQuery( $context, $queryParams );
55        } catch ( ApiUsageException $e ) {
56            return [];
57        }
58
59        if ( array_key_exists( "discussiontoolsfindcomment", $data ) ) {
60            // From findcomment, we only need the comment id and couldredirect
61            return $this->checkCommentRedirects( $data[ "discussiontoolsfindcomment" ],
62                $userTalkPageString );
63        } else {
64            return [];
65        }
66    }
67
68    /**
69     * @param Title $userTalkPageTitle
70     *
71     * @return array Decoded response
72     */
73    public function getUserTalkPageInfo( Title $userTalkPageTitle ) {
74        $context = new DerivativeContext( RequestContext::getMain() );
75        $queryParams = [
76            "action" => "discussiontoolspageinfo",
77            "format" => "json",
78            "page" => $userTalkPageTitle->getTalkNsText() . ':' . $userTalkPageTitle->getText(),
79            "prop" => "threaditemshtml",
80            "formatversion" => "2"
81        ];
82
83        $data = $this->executeApiQuery( $context, $queryParams );
84
85        return $data;
86    }
87
88    /**
89     * Make a single call to MediaWiki API discussiontoolsfindcomment and return the decoded result.
90     *
91     * @param string $commentId
92     * @param Title $userTalkPageTitle
93     * @param string $followUpComment
94     * @param User $autoModeratorUser
95     *
96     * @return array Decoded response
97     */
98    public function addFollowUpComment( string $commentId, Title $userTalkPageTitle, string $followUpComment,
99        User $autoModeratorUser ) {
100        $requestContext = RequestContext::getMain();
101        $requestContext->setUser( $autoModeratorUser );
102        $context = new DerivativeContext( $requestContext );
103        $context->setUser( $autoModeratorUser );
104        $token = $autoModeratorUser->getEditTokenObject( '', $context->getRequest() )->toString();
105        $queryParams = [
106            "action" => "discussiontoolsedit",
107            "format" => "json",
108            "paction" => "addcomment",
109            "page" => $userTalkPageTitle->getTalkNsText() . ':' . $userTalkPageTitle->getText(),
110            "commentid" => $commentId,
111            "wikitext" => $followUpComment,
112            "token" => $token,
113            "formatversion" => "2"
114        ];
115
116        $data = $this->executeApiQuery( $context, $queryParams );
117
118        return $data;
119    }
120
121    /**
122     * Make a single call to MediaWiki API discussiontoolsfindcomment and return the decoded result.
123     *
124     * @param string $commentHeader
125     * @param Title $userTalkPageTitle
126     * @param string $talkPageMessage
127     * @param string $editSummary
128     * @param User $autoModeratorUser
129     *
130     * @return array Decoded response
131     */
132    public function addTopic( string $commentHeader, Title $userTalkPageTitle, string $talkPageMessage,
133        string $editSummary, User $autoModeratorUser ) {
134        $requestContext = RequestContext::getMain();
135        $requestContext->setUser( $autoModeratorUser );
136        $context = new DerivativeContext( $requestContext );
137        $context->setUser( $autoModeratorUser );
138        $token = $autoModeratorUser->getEditTokenObject( '', $context->getRequest() )->toString();
139        $queryParams = [
140            "action" => "discussiontoolsedit",
141            "format" => "json",
142            "paction" => "addtopic",
143            "page" => $userTalkPageTitle->getTalkNsText() . ':' . $userTalkPageTitle->getText(),
144            "wikitext" => $talkPageMessage,
145            "sectiontitle" => $commentHeader,
146            "summary" => $editSummary,
147            "token" => $token,
148            "formatversion" => "2"
149        ];
150
151        $data = $this->executeApiQuery( $context, $queryParams );
152
153        return $data;
154    }
155
156    /**
157     * @param DerivativeContext $context
158     * @param array $queryParams
159     *
160     * @return array $data
161     */
162    private function executeApiQuery( DerivativeContext $context, array $queryParams ) {
163        $context->setRequest(
164            new DerivativeRequest(
165                $context->getRequest(),
166                $queryParams
167            )
168        );
169        $api = new ApiMain(
170            $context,
171            true
172        );
173        $api->execute();
174        $data = $api->getResult()->getResultData();
175        return $data;
176    }
177
178    /**
179     * Parses the discussiontoolsfindcomment API response array to check if there are any comments
180     * where we can append a follow-up message. If one exists, it returns true and the id
181     * @param array $comments
182     * @param string $userTalkPageString
183     * @return array
184     */
185    private function checkCommentRedirects( array $comments, string $userTalkPageString ) {
186        $couldRedirect = false;
187        $commentId = "";
188        foreach ( $comments as $comment ) {
189            if ( $comment[ "couldredirect" ] && $comment[ "title" ] === $userTalkPageString ) {
190                $couldRedirect = true;
191                $commentId = $comment[ "id" ];
192            }
193        }
194        return [ "couldredirect" => $couldRedirect, "id" => $commentId ];
195    }
196}