Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
ExistingSectionEditConstraint
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
3 / 3
11
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 checkConstraint
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
7
 getLegacyStatus
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
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\Content\Content;
24use StatusValue;
25
26/**
27 * To simplify the logic in EditPage, this constraint may be created even if the section being
28 * edited does not currently exist, in which case $section will be 'new' and this constraint
29 * will just short-circuit to CONSTRAINT_PASSED since the checks are not applicable.
30 *
31 * This constraint will only be used if the editor is trying to edit an existing page; if there
32 * is no content, then the user has lost access to the revision after it was loaded. (T301947)
33 *
34 * For an edit to an existing page but not with a new section, do not allow the user to post with
35 * a summary that matches the automatic summary if
36 *   - the content has changed (to allow null edits without a summary, see T7365),
37 *   - the new content is not a redirect (since redirecting a page has an informative automatic
38 *       edit summary, see T9889), and
39 *   - the user has not explicitly chosen to allow the automatic summary to be used
40 *
41 * For most edits, the automatic summary is blank, so checking against the automatic summary means
42 * checking that any summary was given.
43 *
44 * @since 1.36
45 * @internal
46 * @author DannyS712
47 */
48class ExistingSectionEditConstraint implements IEditConstraint {
49
50    private string $section;
51    private string $userSummary;
52    private string $autoSummary;
53    private bool $allowBlankSummary;
54    private Content $newContent;
55    private ?Content $originalContent;
56    private string $result;
57
58    /**
59     * @param string $section
60     * @param string $userSummary
61     * @param string $autoSummary
62     * @param bool $allowBlankSummary
63     * @param Content $newContent
64     * @param ?Content $originalContent
65     */
66    public function __construct(
67        string $section,
68        string $userSummary,
69        string $autoSummary,
70        bool $allowBlankSummary,
71        Content $newContent,
72        ?Content $originalContent
73    ) {
74        $this->section = $section;
75        $this->userSummary = $userSummary;
76        $this->autoSummary = $autoSummary;
77        $this->allowBlankSummary = $allowBlankSummary;
78        $this->newContent = $newContent;
79        $this->originalContent = $originalContent;
80    }
81
82    public function checkConstraint(): string {
83        if ( $this->section === 'new' ) {
84            // Constraint is not applicable
85            $this->result = self::CONSTRAINT_PASSED;
86            return self::CONSTRAINT_PASSED;
87        }
88        if ( $this->originalContent === null ) {
89            // T301947: User loses access to revision after loading
90            $this->result = self::CONSTRAINT_FAILED;
91            return self::CONSTRAINT_FAILED;
92        }
93        if (
94            !$this->allowBlankSummary &&
95            !$this->newContent->equals( $this->originalContent ) &&
96            !$this->newContent->isRedirect() &&
97            md5( $this->userSummary ) === $this->autoSummary
98        ) {
99            $this->result = self::CONSTRAINT_FAILED;
100        } else {
101            $this->result = self::CONSTRAINT_PASSED;
102        }
103        return $this->result;
104    }
105
106    public function getLegacyStatus(): StatusValue {
107        $statusValue = StatusValue::newGood();
108        if ( $this->result === self::CONSTRAINT_FAILED ) {
109            if ( $this->originalContent === null ) {
110                // T301947: User loses access to revision after loading
111                // The error message, rev-deleted-text-permission, is not
112                // really in use currently. It's added for completeness and in
113                // case any code path wants to know the error.
114                $statusValue->fatal( 'rev-deleted-text-permission' );
115                $statusValue->value = self::AS_REVISION_WAS_DELETED;
116            } else {
117                $statusValue->fatal( 'missingsummary' );
118                $statusValue->value = self::AS_SUMMARY_NEEDED;
119            }
120        }
121        return $statusValue;
122    }
123
124}