Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.00% covered (success)
95.00%
19 / 20
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ContentModelChangeConstraint
95.00% covered (success)
95.00%
19 / 20
66.67% covered (warning)
66.67%
2 / 3
9
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 checkConstraint
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
5
 getLegacyStatus
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
3.04
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 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21namespace MediaWiki\EditPage\Constraint;
22
23use MediaWiki\Permissions\Authority;
24use MediaWiki\Permissions\PermissionStatus;
25use MediaWiki\Title\Title;
26use StatusValue;
27
28/**
29 * Verify user permissions if changing content model:
30 *    Must have editcontentmodel rights
31 *    Must be able to edit under the new content model
32 *    Must not have exceeded the rate limit
33 *
34 * @since 1.36
35 * @internal
36 * @author DannyS712
37 */
38class ContentModelChangeConstraint implements IEditConstraint {
39
40    private PermissionStatus $status;
41
42    private Authority $performer;
43    private Title $title;
44    private string $newContentModel;
45
46    /**
47     * @param Authority $performer
48     * @param Title $title
49     * @param string $newContentModel
50     */
51    public function __construct(
52        Authority $performer,
53        Title $title,
54        string $newContentModel
55    ) {
56        $this->performer = $performer;
57        $this->title = $title;
58        $this->newContentModel = $newContentModel;
59    }
60
61    public function checkConstraint(): string {
62        $this->status = PermissionStatus::newEmpty();
63
64        if ( $this->newContentModel === $this->title->getContentModel() ) {
65            // No change
66            return self::CONSTRAINT_PASSED;
67        }
68
69        if ( !$this->performer->authorizeWrite( 'editcontentmodel', $this->title, $this->status ) ) {
70            return self::CONSTRAINT_FAILED;
71        }
72
73        // Make sure the user can edit the page under the new content model too.
74        // We rely on caching in UserAuthority to avoid bumping the rate limit counter twice.
75        $titleWithNewContentModel = clone $this->title;
76        $titleWithNewContentModel->setContentModel( $this->newContentModel );
77        if (
78            !$this->performer->authorizeWrite( 'editcontentmodel', $titleWithNewContentModel, $this->status )
79            || !$this->performer->authorizeWrite( 'edit', $titleWithNewContentModel, $this->status )
80        ) {
81            return self::CONSTRAINT_FAILED;
82        }
83
84        return self::CONSTRAINT_PASSED;
85    }
86
87    public function getLegacyStatus(): StatusValue {
88        $statusValue = StatusValue::newGood();
89
90        if ( !$this->status->isGood() ) {
91            if ( $this->status->isRateLimitExceeded() ) {
92                $statusValue->setResult( false, self::AS_RATE_LIMITED );
93            } else {
94                $statusValue->setResult( false, self::AS_NO_CHANGE_CONTENT_MODEL );
95            }
96        }
97
98        // TODO: Use error messages from the PermissionStatus ($this->status) here - T384399
99        return $statusValue;
100    }
101
102}