Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.74% covered (success)
94.74%
36 / 38
85.71% covered (warning)
85.71%
12 / 14
CRAP
0.00% covered (danger)
0.00%
0 / 1
Form
94.74% covered (success)
94.74%
36 / 38
85.71% covered (warning)
85.71%
12 / 14
25.09
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setId
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 getRepresentations
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRepresentations
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getGrammaticalFeatures
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setGrammaticalFeatures
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 getStatements
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isEmpty
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 equals
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 copy
100.00% covered (success)
100.00%
1 / 1
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
 clear
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Wikibase\Lexeme\Domain\Model;
4
5use InvalidArgumentException;
6use LogicException;
7use Wikibase\DataModel\Entity\ClearableEntity;
8use Wikibase\DataModel\Entity\ItemId;
9use Wikibase\DataModel\Entity\StatementListProvidingEntity;
10use Wikibase\DataModel\Statement\StatementList;
11use Wikibase\DataModel\Term\TermList;
12use Wikibase\Lexeme\Domain\DummyObjects\DummyFormId;
13use Wikibase\Lexeme\Domain\DummyObjects\NullFormId;
14use Wikimedia\Assert\Assert;
15
16/**
17 * Mutable (e.g. the provided StatementList can be changed) implementation of a Lexeme's form in the
18 * lexicographical data model.
19 *
20 * @see https://www.mediawiki.org/wiki/Extension:WikibaseLexeme/Data_Model#Form
21 *
22 * @license GPL-2.0-or-later
23 */
24class Form implements StatementListProvidingEntity, ClearableEntity {
25
26    public const ENTITY_TYPE = 'form';
27
28    /**
29     * @var FormId
30     */
31    protected $id;
32
33    /**
34     * @var TermList
35     */
36    protected $representations;
37
38    /**
39     * @var ItemId[]
40     */
41    protected $grammaticalFeatures;
42
43    /**
44     * @var StatementList
45     */
46    protected $statementList;
47
48    /**
49     * @param FormId $id
50     * @param TermList $representations
51     * @param ItemId[] $grammaticalFeatures
52     * @param StatementList|null $statementList
53     *
54     * @throws InvalidArgumentException
55     */
56    public function __construct(
57        FormId $id,
58        TermList $representations,
59        array $grammaticalFeatures,
60        StatementList $statementList = null
61    ) {
62        $this->id = $id;
63        $this->representations = $representations;
64        $this->setGrammaticalFeatures( $grammaticalFeatures );
65        $this->statementList = $statementList ?: new StatementList();
66    }
67
68    /**
69     * @return string
70     */
71    public function getType() {
72        return self::ENTITY_TYPE;
73    }
74
75    /**
76     * @return FormId
77     */
78    public function getId() {
79        return $this->id;
80    }
81
82    /**
83     * @param FormId $id
84     */
85    public function setId( $id ) {
86        Assert::parameterType( FormId::class, $id, '$id' );
87
88        // all dummy FormIds are also FormIds that's why this check looks overly complicated
89        if ( !( $this->id instanceof NullFormId || $this->id instanceof DummyFormId ) ) {
90            throw new LogicException( 'Cannot override a real FormId' );
91        }
92
93        $this->id = $id;
94    }
95
96    /**
97     * The representations of the Form as list of terms.
98     *
99     * Note that in some places "representation" means just the text of a representation and the
100     * language code is called "spelling variant".
101     *
102     * @return TermList
103     */
104    public function getRepresentations() {
105        return $this->representations;
106    }
107
108    public function setRepresentations( TermList $representations ) {
109        $this->representations = $representations;
110    }
111
112    /**
113     * @return ItemId[]
114     */
115    public function getGrammaticalFeatures() {
116        return $this->grammaticalFeatures;
117    }
118
119    public function setGrammaticalFeatures( array $grammaticalFeatures ) {
120        Assert::parameterElementType( ItemId::class, $grammaticalFeatures, '$grammaticalFeatures' );
121
122        $result = [];
123        foreach ( $grammaticalFeatures as $grammaticalFeature ) {
124            if ( !in_array( $grammaticalFeature, $result ) ) {
125                $result[] = $grammaticalFeature;
126            }
127        }
128
129        usort( $result, static function ( ItemId $a, ItemId $b ) {
130            return strcmp( $a->getSerialization(), $b->getSerialization() );
131        } );
132
133        $this->grammaticalFeatures = $result;
134    }
135
136    /** @inheritDoc */
137    public function getStatements() {
138        return $this->statementList;
139    }
140
141    /**
142     * @see EntityDocument::isEmpty
143     *
144     * @return bool
145     */
146    public function isEmpty() {
147        return $this->representations->isEmpty()
148            && $this->grammaticalFeatures === []
149            && $this->statementList->isEmpty();
150    }
151
152    /**
153     * @see EntityDocument::equals
154     *
155     * @param mixed $target
156     *
157     * @return bool True if the forms contents are equal. Does not consider the ID.
158     */
159    public function equals( $target ) {
160        if ( $this === $target ) {
161            return true;
162        }
163
164        return $target instanceof self
165            && $this->representations->equals( $target->representations )
166            && $this->grammaticalFeatures == $target->grammaticalFeatures
167            && $this->statementList->equals( $target->statementList );
168    }
169
170    /**
171     * @see EntityDocument::copy
172     *
173     * @return self
174     */
175    public function copy() {
176        return clone $this;
177    }
178
179    /**
180     * The forms ID and grammatical features (a set of ItemIds) are immutable and don't need
181     * individual cloning.
182     */
183    public function __clone() {
184        $this->representations = clone $this->representations;
185        $this->statementList = clone $this->statementList;
186    }
187
188    /**
189     * Clears the representations, grammatical features and statements of a form.
190     * Note that this leaves the form in an insufficiently initialized state.
191     */
192    public function clear() {
193        $this->representations = new TermList();
194        $this->grammaticalFeatures = [];
195        $this->statementList = new StatementList();
196    }
197
198}