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