Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
TagsDef
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
3 / 3
7
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 validate
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
5
 getEnumValues
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace MediaWiki\ParamValidator\TypeDef;
4
5use ChangeTags;
6use MediaWiki\ChangeTags\ChangeTagsStore;
7use MediaWiki\Message\Converter as MessageConverter;
8use Wikimedia\Message\DataMessageValue;
9use Wikimedia\ParamValidator\Callbacks;
10use Wikimedia\ParamValidator\TypeDef\EnumDef;
11use Wikimedia\ParamValidator\ValidationException;
12
13/**
14 * Type definition for tags type
15 *
16 * A tags type is an enum type for selecting MediaWiki change tags.
17 *
18 * Failure codes:
19 *  - 'badtags': The value was not a valid set of tags. Data:
20 *    - 'disallowedtags': The tags that were disallowed.
21 *
22 * @since 1.35
23 */
24class TagsDef extends EnumDef {
25
26    private ChangeTagsStore $changeTagsStore;
27
28    /** @var MessageConverter */
29    private $messageConverter;
30
31    public function __construct( Callbacks $callbacks, ChangeTagsStore $changeTagsStore ) {
32        parent::__construct( $callbacks );
33        $this->changeTagsStore = $changeTagsStore;
34        $this->messageConverter = new MessageConverter();
35    }
36
37    public function validate( $name, $value, array $settings, array $options ) {
38        // Validate the full list of tags at once, because the caller will
39        // *probably* stop at the first exception thrown.
40        if ( isset( $options['values-list'] ) ) {
41            $ret = $value;
42            $tagsStatus = ChangeTags::canAddTagsAccompanyingChange( $options['values-list'] );
43        } else {
44            // The 'tags' type always returns an array.
45            $ret = [ $value ];
46            $tagsStatus = ChangeTags::canAddTagsAccompanyingChange( $ret );
47        }
48
49        if ( !$tagsStatus->isGood() ) {
50            $msg = $this->messageConverter->convertMessage( $tagsStatus->getMessage() );
51            $data = [];
52            if ( $tagsStatus->value ) {
53                // Specific tags are not allowed.
54                $data['disallowedtags'] = $tagsStatus->value;
55            // @codeCoverageIgnoreStart
56            } else {
57                // All are disallowed, I guess
58                $data['disallowedtags'] = $settings['values-list'] ?? $ret;
59            }
60            // @codeCoverageIgnoreEnd
61
62            // Only throw if $value is among the disallowed tags
63            if ( in_array( $value, $data['disallowedtags'], true ) ) {
64                throw new ValidationException(
65                    DataMessageValue::new( $msg->getKey(), $msg->getParams(), 'badtags', $data ),
66                    $name, $value, $settings
67                );
68            }
69        }
70
71        return $ret;
72    }
73
74    public function getEnumValues( $name, array $settings, array $options ) {
75        return $this->changeTagsStore->listExplicitlyDefinedTags();
76    }
77
78}