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