Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 69 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
ApiDiscussionToolsThank | |
0.00% |
0 / 69 |
|
0.00% |
0 / 3 |
182 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 52 |
|
0.00% |
0 / 1 |
132 | |||
getAllowedParams | |
0.00% |
0 / 14 |
|
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\Hooks\HookUtils; |
9 | use MediaWiki\Extension\DiscussionTools\ThreadItem\ContentCommentItem; |
10 | use MediaWiki\Extension\Notifications\Model\Event; |
11 | use MediaWiki\Extension\Thanks\Api\ApiThank; |
12 | use MediaWiki\Extension\Thanks\Storage\LogStore; |
13 | use MediaWiki\Extension\VisualEditor\ApiParsoidTrait; |
14 | use MediaWiki\Permissions\PermissionManager; |
15 | use MediaWiki\Revision\RevisionLookup; |
16 | use MediaWiki\Title\Title; |
17 | use MediaWiki\User\UserFactory; |
18 | use Wikimedia\ParamValidator\ParamValidator; |
19 | |
20 | /** |
21 | * API module to send DiscussionTools comment thanks notifications |
22 | * |
23 | * @ingroup API |
24 | * @ingroup Extensions |
25 | */ |
26 | |
27 | class ApiDiscussionToolsThank extends ApiThank { |
28 | |
29 | use ApiDiscussionToolsTrait; |
30 | use ApiParsoidTrait; |
31 | |
32 | private RevisionLookup $revisionLookup; |
33 | private UserFactory $userFactory; |
34 | |
35 | public function __construct( |
36 | ApiMain $main, |
37 | string $action, |
38 | PermissionManager $permissionManager, |
39 | LogStore $storage, |
40 | RevisionLookup $revisionLookup, |
41 | UserFactory $userFactory |
42 | ) { |
43 | parent::__construct( $main, $action, $permissionManager, $storage ); |
44 | $this->revisionLookup = $revisionLookup; |
45 | $this->userFactory = $userFactory; |
46 | } |
47 | |
48 | /** |
49 | * @inheritDoc |
50 | * @throws ApiUsageException |
51 | */ |
52 | public function execute() { |
53 | $user = $this->getUser(); |
54 | $this->dieOnBadUser( $user ); |
55 | $this->dieOnUserBlockedFromThanks( $user ); |
56 | |
57 | $params = $this->extractRequestParams(); |
58 | |
59 | $title = Title::newFromText( $params['page'] ); |
60 | $commentId = $params['commentid']; |
61 | |
62 | if ( !$title ) { |
63 | $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['page'] ) ] ); |
64 | } |
65 | |
66 | // TODO: Using the data in the permalinks database would be much |
67 | // faster, we just wouldn't have the comment content. |
68 | |
69 | // Support oldid? |
70 | $revision = $this->revisionLookup->getRevisionByTitle( $title ); |
71 | if ( !$revision ) { |
72 | throw ApiUsageException::newWithMessage( |
73 | $this, |
74 | [ 'apierror-missingrev-title', wfEscapeWikiText( $title->getPrefixedText() ) ], |
75 | 'nosuchrevid' |
76 | ); |
77 | } |
78 | $status = HookUtils::parseRevisionParsoidHtml( $revision, __METHOD__ ); |
79 | if ( !$status->isOK() ) { |
80 | $this->dieStatus( $status ); |
81 | } |
82 | $threadItemSet = $status->getValueOrThrow(); |
83 | |
84 | $comment = $threadItemSet->findCommentById( $commentId ); |
85 | |
86 | if ( !$comment || !( $comment instanceof ContentCommentItem ) ) { |
87 | $this->dieWithError( [ 'apierror-discussiontools-commentid-notfound', $commentId ] ); |
88 | } |
89 | |
90 | if ( $user->getRequest()->getSessionData( "discussiontools-thanked-{$comment->getId()}" ) ) { |
91 | $this->markResultSuccess( $comment->getAuthor() ); |
92 | return; |
93 | } |
94 | |
95 | $uniqueId = "discussiontools-{$comment->getId()}"; |
96 | // Do one last check to make sure we haven't sent Thanks before |
97 | if ( $this->haveAlreadyThanked( $user, $uniqueId ) ) { |
98 | // Pretend the thanks were sent |
99 | $this->markResultSuccess( $comment->getAuthor() ); |
100 | return; |
101 | } |
102 | |
103 | $recipient = $this->userFactory->newFromName( $comment->getAuthor() ); |
104 | if ( !$recipient || !$recipient->getId() ) { |
105 | $this->dieWithError( 'thanks-error-invalidrecipient', 'invalidrecipient' ); |
106 | } |
107 | |
108 | $this->dieOnBadRecipient( $user, $recipient ); |
109 | |
110 | $heading = $comment->getSubscribableHeading(); |
111 | if ( !$heading ) { |
112 | $heading = $comment->getHeading(); |
113 | } |
114 | |
115 | // Create the notification via Echo extension |
116 | Event::create( [ |
117 | 'type' => 'dt-thank', |
118 | 'title' => $title, |
119 | 'extra' => [ |
120 | 'comment-id' => $comment->getId(), |
121 | 'comment-name' => $comment->getName(), |
122 | 'content' => $comment->getBodyText( true ), |
123 | 'section-title' => $heading->getLinkableTitle(), |
124 | 'thanked-user-id' => $recipient->getId(), |
125 | 'revid' => $revision->getId(), |
126 | ], |
127 | 'agent' => $user, |
128 | ] ); |
129 | |
130 | // And mark the thank in session for a cheaper check to prevent duplicates (T48690). |
131 | $user->getRequest()->setSessionData( "discussiontools-thanked-{$comment->getId()}", true ); |
132 | // Set success message. |
133 | $this->markResultSuccess( $recipient->getName() ); |
134 | $this->logThanks( $user, $recipient, $uniqueId ); |
135 | } |
136 | |
137 | /** |
138 | * @inheritDoc |
139 | */ |
140 | public function getAllowedParams() { |
141 | return [ |
142 | 'page' => [ |
143 | ParamValidator::PARAM_REQUIRED => true, |
144 | // Message will exist if DiscussionTools is installed as VE is a dependency |
145 | ApiBase::PARAM_HELP_MSG => 'apihelp-visualeditoredit-param-page', |
146 | ], |
147 | 'commentid' => [ |
148 | ParamValidator::PARAM_REQUIRED => true, |
149 | ParamValidator::PARAM_TYPE => 'string', |
150 | ], |
151 | 'token' => [ |
152 | ParamValidator::PARAM_REQUIRED => true, |
153 | ParamValidator::PARAM_TYPE => 'string', |
154 | ], |
155 | ]; |
156 | } |
157 | } |