Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
17 / 17
CRAP
100.00% covered (success)
100.00%
1 / 1
AbstractFilter
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
17 / 17
20
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 getSpecs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFlags
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRules
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getComments
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActionsNames
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGroup
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isEnabled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isDeleted
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isHidden
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isProtected
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPrivacyLevel
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isGlobal
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActions
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 setActions
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 __clone
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace MediaWiki\Extension\AbuseFilter\Filter;
4
5use Wikimedia\Assert\Assert;
6
7/**
8 * Immutable value object that represents a single filter. This object can be used to represent
9 * filters that do not necessarily exist in the database. You'll usually want to use subclasses.
10 */
11class AbstractFilter {
12    /** @var Specs */
13    protected $specs;
14    /** @var Flags */
15    protected $flags;
16    /**
17     * @var array[]|null Actions and parameters, can be lazy-loaded with $actionsCallback
18     */
19    protected $actions;
20    /**
21     * @var callable|null
22     * @todo Evaluate whether this can be avoided, e.g. by using a JOIN. This property also makes
23     *   the class not serializable.
24     */
25    protected $actionsCallback;
26
27    /**
28     * @param Specs $specs
29     * @param Flags $flags
30     * @param callable|array[] $actions Array with params or callable that will return them
31     * @phan-param array[]|callable():array[] $actions
32     */
33    public function __construct(
34        Specs $specs,
35        Flags $flags,
36        $actions
37    ) {
38        $this->specs = clone $specs;
39        $this->flags = clone $flags;
40        Assert::parameterType( 'callable|array', $actions, '$actions' );
41        if ( is_callable( $actions ) ) {
42            $this->actionsCallback = $actions;
43        } elseif ( is_array( $actions ) ) {
44            $this->setActions( $actions );
45        }
46    }
47
48    /**
49     * @return Specs
50     */
51    public function getSpecs(): Specs {
52        return clone $this->specs;
53    }
54
55    /**
56     * @return Flags
57     */
58    public function getFlags(): Flags {
59        return clone $this->flags;
60    }
61
62    /**
63     * @return string
64     */
65    public function getRules(): string {
66        return $this->specs->getRules();
67    }
68
69    /**
70     * @return string
71     */
72    public function getComments(): string {
73        return $this->specs->getComments();
74    }
75
76    /**
77     * @return string
78     */
79    public function getName(): string {
80        return $this->specs->getName();
81    }
82
83    /**
84     * @note Callers should not rely on the order, because it's nondeterministic.
85     * @return string[]
86     */
87    public function getActionsNames(): array {
88        return $this->specs->getActionsNames();
89    }
90
91    /**
92     * @return string
93     */
94    public function getGroup(): string {
95        return $this->specs->getGroup();
96    }
97
98    /**
99     * @return bool
100     */
101    public function isEnabled(): bool {
102        return $this->flags->getEnabled();
103    }
104
105    /**
106     * @return bool
107     */
108    public function isDeleted(): bool {
109        return $this->flags->getDeleted();
110    }
111
112    /**
113     * @return bool
114     */
115    public function isHidden(): bool {
116        return $this->flags->getHidden();
117    }
118
119    /**
120     * @return bool
121     */
122    public function isProtected(): bool {
123        return $this->flags->getProtected();
124    }
125
126    /**
127     * @return int
128     */
129    public function getPrivacyLevel(): int {
130        return $this->flags->getPrivacyLevel();
131    }
132
133    /**
134     * @return bool
135     */
136    public function isGlobal(): bool {
137        return $this->flags->getGlobal();
138    }
139
140    /**
141     * @return array[]
142     */
143    public function getActions(): array {
144        if ( $this->actions === null ) {
145            $this->setActions( call_user_func( $this->actionsCallback ) );
146            // This is to ease testing
147            $this->actionsCallback = null;
148        }
149        return $this->actions;
150    }
151
152    /**
153     * @param array $actions
154     */
155    protected function setActions( array $actions ): void {
156        $this->actions = $actions;
157        $this->specs->setActionsNames( array_keys( $actions ) );
158    }
159
160    /**
161     * Make sure we don't leave any (writeable) reference
162     */
163    public function __clone() {
164        $this->specs = clone $this->specs;
165        $this->flags = clone $this->flags;
166    }
167
168}