Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 59
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
MarkpatrolledAction
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 11
420
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDescription
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRestriction
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 usesOOUI
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRecentChange
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
 preText
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
2
 alterForm
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 onSubmit
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
56
 onSuccess
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 doesWrites
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Copyright © 2011 Alexandre Emsenhuber
4 *
5 * @license GPL-2.0-or-later
6 * @file
7 * @ingroup Actions
8 */
9
10namespace MediaWiki\Actions;
11
12use MediaWiki\Context\IContextSource;
13use MediaWiki\Exception\ErrorPageError;
14use MediaWiki\Exception\PermissionsError;
15use MediaWiki\HTMLForm\HTMLForm;
16use MediaWiki\Linker\LinkRenderer;
17use MediaWiki\Message\Message;
18use MediaWiki\Page\Article;
19use MediaWiki\RecentChanges\PatrolManager;
20use MediaWiki\RecentChanges\RecentChange;
21use MediaWiki\RecentChanges\RecentChangeLookup;
22use MediaWiki\SpecialPage\SpecialPage;
23use StatusValue;
24
25/**
26 * Mark a revision as patrolled on a page
27 *
28 * @ingroup Actions
29 */
30class MarkpatrolledAction extends FormAction {
31
32    private LinkRenderer $linkRenderer;
33    private PatrolManager $patrolManager;
34    private RecentChangeLookup $recentChangeLookup;
35
36    /**
37     * @param Article $article
38     * @param IContextSource $context
39     * @param LinkRenderer $linkRenderer
40     * @param PatrolManager $patrolManager
41     * @param RecentChangeLookup $recentChangeLookup
42     */
43    public function __construct(
44        Article $article,
45        IContextSource $context,
46        LinkRenderer $linkRenderer,
47        PatrolManager $patrolManager,
48        RecentChangeLookup $recentChangeLookup
49    ) {
50        parent::__construct( $article, $context );
51
52        $this->linkRenderer = $linkRenderer;
53        $this->patrolManager = $patrolManager;
54        $this->recentChangeLookup = $recentChangeLookup;
55    }
56
57    /** @inheritDoc */
58    public function getName() {
59        return 'markpatrolled';
60    }
61
62    /** @inheritDoc */
63    protected function getDescription() {
64        // Disable default header "subtitle"
65        return '';
66    }
67
68    /** @inheritDoc */
69    public function getRestriction() {
70        return 'patrol';
71    }
72
73    /** @inheritDoc */
74    protected function usesOOUI() {
75        return true;
76    }
77
78    /**
79     * @param array|null $data
80     * @return RecentChange
81     */
82    protected function getRecentChange( $data = null ) {
83        $rc = null;
84        // Note: This works both on initial GET url and after submitting the form
85        $rcId = $data ? intval( $data['rcid'] ) : $this->getRequest()->getInt( 'rcid' );
86        if ( $rcId ) {
87            $rc = $this->recentChangeLookup->getRecentChangeById( $rcId );
88        }
89        if ( !$rc ) {
90            throw new ErrorPageError( 'markedaspatrollederror', 'markedaspatrollederrortext' );
91        }
92        return $rc;
93    }
94
95    /** @inheritDoc */
96    protected function preText() {
97        $rc = $this->getRecentChange();
98        $title = $rc->getTitle();
99
100        // Based on logentry-patrol-patrol (see PatrolLogFormatter)
101        $revId = $rc->getAttribute( 'rc_this_oldid' );
102        $query = [
103            'curid' => $rc->getAttribute( 'rc_cur_id' ),
104            'diff' => $revId,
105            'oldid' => $rc->getAttribute( 'rc_last_oldid' )
106        ];
107        $revlink = $this->linkRenderer->makeLink( $title, $revId, [], $query );
108        $pagelink = $this->linkRenderer->makeLink( $title, $title->getPrefixedText() );
109
110        return $this->msg( 'confirm-markpatrolled-top' )->params(
111            $title->getPrefixedText(),
112            // Provide pre-rendered link as parser would render [[:$1]] as bold non-link
113            Message::rawParam( $pagelink ),
114            Message::rawParam( $revlink )
115        )->parse();
116    }
117
118    protected function alterForm( HTMLForm $form ) {
119        $form->addHiddenField( 'rcid', $this->getRequest()->getInt( 'rcid' ) );
120        $form->setTokenSalt( 'patrol' );
121        $form->setSubmitTextMsg( 'confirm-markpatrolled-button' );
122    }
123
124    /**
125     * @param array $data
126     * @return bool|StatusValue True for success, false for didn't-try, StatusValue on failure
127     */
128    public function onSubmit( $data ) {
129        $rc = $this->getRecentChange( $data );
130        $status = $this->patrolManager->markPatrolled( $rc, $this->getAuthority() );
131
132        if ( $status->hasMessage( 'rcpatroldisabled' ) ) {
133            throw new ErrorPageError( 'rcpatroldisabled', 'rcpatroldisabledtext' );
134        }
135
136        // Guess where the user came from
137        // TODO: Would be nice to see where the user actually came from
138        if ( $rc->getAttribute( 'rc_source' ) === RecentChange::SRC_NEW ) {
139            $returnTo = 'Newpages';
140        } elseif ( $rc->getAttribute( 'rc_log_type' ) == 'upload' ) {
141            $returnTo = 'Newfiles';
142        } else {
143            $returnTo = 'Recentchanges';
144        }
145        $return = SpecialPage::getTitleFor( $returnTo );
146
147        if ( $status->hasMessage( 'markedaspatrollederror-noautopatrol' ) ) {
148            $this->getOutput()->setPageTitleMsg( $this->msg( 'markedaspatrollederror' ) );
149            $this->getOutput()->addWikiMsg( 'markedaspatrollederror-noautopatrol' );
150            $this->getOutput()->returnToMain( null, $return );
151            return true;
152        }
153
154        if ( !$status->isGood() ) {
155            if ( !$status->hasMessage( 'hookaborted' ) ) {
156                throw new PermissionsError( 'patrol', $status );
157            }
158            // The MarkPatrolled hook itself has handled any output
159            return $status;
160        }
161
162        $this->getOutput()->setPageTitleMsg( $this->msg( 'markedaspatrolled' ) );
163        $this->getOutput()->addWikiMsg( 'markedaspatrolledtext', $rc->getTitle()->getPrefixedText() );
164        $this->getOutput()->returnToMain( null, $return );
165        return true;
166    }
167
168    /** @inheritDoc */
169    public function onSuccess() {
170        // Required by parent class. Redundant as our onSubmit handles output already.
171    }
172
173    /** @inheritDoc */
174    public function doesWrites() {
175        return true;
176    }
177}
178
179/** @deprecated class alias since 1.44 */
180class_alias( MarkpatrolledAction::class, 'MarkpatrolledAction' );