Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
78.95% covered (warning)
78.95%
45 / 57
77.78% covered (warning)
77.78%
7 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
EditConstraintFactory
78.95% covered (warning)
78.95%
45 / 57
77.78% covered (warning)
77.78%
7 / 9
9.76
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 newEditFilterMergedContentHookConstraint
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 newPageSizeConstraint
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 newReadOnlyConstraint
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 newUserRateLimitConstraint
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 newSimpleAntiSpamConstraint
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 newSpamRegexConstraint
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 newUserBlockConstraint
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 newEditRightConstraint
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
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\Config\ServiceOptions;
24use MediaWiki\Content\Content;
25use MediaWiki\Context\IContextSource;
26use MediaWiki\EditPage\SpamChecker;
27use MediaWiki\HookContainer\HookContainer;
28use MediaWiki\Language\Language;
29use MediaWiki\Linker\LinkTarget;
30use MediaWiki\Logger\Spi;
31use MediaWiki\MainConfigNames;
32use MediaWiki\Permissions\PermissionManager;
33use MediaWiki\Permissions\RateLimiter;
34use MediaWiki\Permissions\RateLimitSubject;
35use MediaWiki\Title\Title;
36use MediaWiki\User\User;
37use MediaWiki\User\UserIdentity;
38use Wikimedia\Rdbms\ReadOnlyMode;
39
40/**
41 * Constraints reflect possible errors that need to be checked
42 *
43 * @since 1.36
44 * @internal
45 * @author DannyS712
46 */
47class EditConstraintFactory {
48
49    /** @internal */
50    public const CONSTRUCTOR_OPTIONS = [
51        // PageSizeConstraint
52        MainConfigNames::MaxArticleSize,
53    ];
54
55    private ServiceOptions $options;
56    private Spi $loggerFactory;
57    private PermissionManager $permissionManager;
58    private HookContainer $hookContainer;
59    private ReadOnlyMode $readOnlyMode;
60    private SpamChecker $spamRegexChecker;
61    private RateLimiter $rateLimiter;
62
63    /**
64     * Some constraints have dependencies that need to be injected,
65     * this class serves as a factory for all of the different constraints
66     * that need dependencies injected.
67     *
68     * The checks in EditPage use wfDebugLog and logged to different channels, hence the need
69     * for multiple loggers retrieved from the Spi. The channels used are:
70     * - SimpleAntiSpam (in SimpleAntiSpamConstraint)
71     * - SpamRegex (in SpamRegexConstraint)
72     *
73     * TODO can they be combined into the same channel?
74     *
75     * @param ServiceOptions $options
76     * @param Spi $loggerFactory
77     * @param PermissionManager $permissionManager
78     * @param HookContainer $hookContainer
79     * @param ReadOnlyMode $readOnlyMode
80     * @param SpamChecker $spamRegexChecker
81     * @param RateLimiter $rateLimiter
82     */
83    public function __construct(
84        ServiceOptions $options,
85        Spi $loggerFactory,
86        PermissionManager $permissionManager,
87        HookContainer $hookContainer,
88        ReadOnlyMode $readOnlyMode,
89        SpamChecker $spamRegexChecker,
90        RateLimiter $rateLimiter
91    ) {
92        $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
93
94        // Multiple
95        $this->options = $options;
96        $this->loggerFactory = $loggerFactory;
97
98        // UserBlockConstraint
99        $this->permissionManager = $permissionManager;
100
101        // EditFilterMergedContentHookConstraint
102        $this->hookContainer = $hookContainer;
103
104        // ReadOnlyConstraint
105        $this->readOnlyMode = $readOnlyMode;
106
107        // SpamRegexConstraint
108        $this->spamRegexChecker = $spamRegexChecker;
109
110        // UserRateLimitConstraint
111        $this->rateLimiter = $rateLimiter;
112    }
113
114    /**
115     * @param Content $content
116     * @param IContextSource $context
117     * @param string $summary
118     * @param bool $minorEdit
119     * @param Language $language
120     * @param User $user
121     * @return EditFilterMergedContentHookConstraint
122     */
123    public function newEditFilterMergedContentHookConstraint(
124        Content $content,
125        IContextSource $context,
126        string $summary,
127        bool $minorEdit,
128        Language $language,
129        User $user
130    ): EditFilterMergedContentHookConstraint {
131        return new EditFilterMergedContentHookConstraint(
132            $this->hookContainer,
133            $content,
134            $context,
135            $summary,
136            $minorEdit,
137            $language,
138            $user
139        );
140    }
141
142    /**
143     * @param int $contentSize
144     * @param string $type
145     * @return PageSizeConstraint
146     */
147    public function newPageSizeConstraint(
148        int $contentSize,
149        string $type
150    ): PageSizeConstraint {
151        return new PageSizeConstraint(
152            $this->options->get( MainConfigNames::MaxArticleSize ),
153            $contentSize,
154            $type
155        );
156    }
157
158    /**
159     * @return ReadOnlyConstraint
160     */
161    public function newReadOnlyConstraint(): ReadOnlyConstraint {
162        return new ReadOnlyConstraint(
163            $this->readOnlyMode
164        );
165    }
166
167    /**
168     * @param RateLimitSubject $subject
169     * @param string $oldModel
170     * @param string $newModel
171     *
172     * @return UserRateLimitConstraint
173     */
174    public function newUserRateLimitConstraint(
175        RateLimitSubject $subject,
176        string $oldModel,
177        string $newModel
178    ): UserRateLimitConstraint {
179        return new UserRateLimitConstraint(
180            $this->rateLimiter,
181            $subject,
182            $oldModel,
183            $newModel
184        );
185    }
186
187    /**
188     * @param string $input
189     * @param UserIdentity $user
190     * @param Title $title
191     * @return SimpleAntiSpamConstraint
192     */
193    public function newSimpleAntiSpamConstraint(
194        string $input,
195        UserIdentity $user,
196        Title $title
197    ): SimpleAntiSpamConstraint {
198        return new SimpleAntiSpamConstraint(
199            $this->loggerFactory->getLogger( 'SimpleAntiSpam' ),
200            $input,
201            $user,
202            $title
203        );
204    }
205
206    /**
207     * @param string $summary
208     * @param ?string $sectionHeading
209     * @param string $text
210     * @param string $reqIP
211     * @param Title $title
212     * @return SpamRegexConstraint
213     */
214    public function newSpamRegexConstraint(
215        string $summary,
216        ?string $sectionHeading,
217        string $text,
218        string $reqIP,
219        Title $title
220    ): SpamRegexConstraint {
221        return new SpamRegexConstraint(
222            $this->loggerFactory->getLogger( 'SpamRegex' ),
223            $this->spamRegexChecker,
224            $summary,
225            $sectionHeading,
226            $text,
227            $reqIP,
228            $title
229        );
230    }
231
232    /**
233     * @param LinkTarget $title
234     * @param User $user
235     * @return UserBlockConstraint
236     */
237    public function newUserBlockConstraint(
238        LinkTarget $title,
239        User $user
240    ): UserBlockConstraint {
241        return new UserBlockConstraint(
242            $this->permissionManager,
243            $title,
244            $user
245        );
246    }
247
248    /**
249     * @param User $performer
250     * @param Title $title
251     * @param bool $new
252     * @return EditRightConstraint
253     */
254    public function newEditRightConstraint(
255        User $performer,
256        Title $title,
257        bool $new
258    ): EditRightConstraint {
259        return new EditRightConstraint(
260            $performer,
261            $this->permissionManager,
262            $title,
263            $new
264        );
265    }
266
267}