Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
89.74% covered (warning)
89.74%
35 / 39
90.00% covered (success)
90.00%
9 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
FormStore
89.74% covered (warning)
89.74%
35 / 39
90.00% covered (success)
90.00%
9 / 10
15.24
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 assignFreshId
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 saveEntity
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
2
 saveRedirect
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 deleteEntity
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 userWasLastToEdit
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 updateWatchlist
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 isWatching
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 canCreateWithCustomId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLexemeRevision
66.67% covered (warning)
66.67%
8 / 12
0.00% covered (danger)
0.00%
0 / 1
4.59
1<?php
2
3namespace Wikibase\Lexeme\DataAccess\Store;
4
5use MediaWiki\User\User;
6use PermissionsError;
7use UnexpectedValueException;
8use Wikibase\DataModel\Entity\EntityDocument;
9use Wikibase\DataModel\Entity\EntityId;
10use Wikibase\DataModel\Entity\EntityRedirect;
11use Wikibase\Lexeme\Domain\DummyObjects\BlankForm;
12use Wikibase\Lexeme\Domain\Model\Form;
13use Wikibase\Lexeme\Domain\Model\FormId;
14use Wikibase\Lexeme\Domain\Model\Lexeme;
15use Wikibase\Lib\Store\EntityRevision;
16use Wikibase\Lib\Store\EntityRevisionLookup;
17use Wikibase\Lib\Store\EntityStore;
18use Wikibase\Lib\Store\LookupConstants;
19use Wikibase\Lib\Store\StorageException;
20use Wikimedia\Assert\Assert;
21
22/**
23 * @license GPL-2.0-or-later
24 * @author Daniel Kinzler
25 * @author Thiemo Kreuz
26 */
27class FormStore implements EntityStore {
28
29    /**
30     * @var EntityStore
31     */
32    private $store;
33
34    /**
35     * @var EntityRevisionLookup
36     */
37    private $lookup;
38
39    public function __construct( EntityStore $store, EntityRevisionLookup $lookup ) {
40        $this->store = $store;
41        $this->lookup = $lookup;
42    }
43
44    /**
45     * @see EntityStore::assignFreshId
46     *
47     * @param Form $form
48     *
49     * @throws \DomainException
50     */
51    public function assignFreshId( EntityDocument $form ) {
52        if ( $form instanceof BlankForm ) {
53            return;
54        }
55
56        throw new \DomainException( 'Form IDs are currently assigned in Lexeme::addOrUpdateForm()' );
57    }
58
59    /**
60     * @see EntityStore::saveEntity
61     *
62     * @param Form $form
63     * @param string $summary
64     * @param User $user
65     * @param int $flags
66     * @param int|bool $baseRevId
67     * @param string[] $tags
68     *
69     * @throws StorageException
70     * @throws PermissionsError
71     * @return EntityRevision
72     */
73    public function saveEntity(
74        EntityDocument $form,
75        $summary,
76        User $user,
77        $flags = 0,
78        $baseRevId = false,
79        array $tags = []
80    ) {
81        Assert::parameterType( Form::class, $form, '$form' );
82
83        // EntityRevisionLookup and EntityStore have different opinions on valid revId fallbacks
84        $getLexemeRevId = 0;
85        if ( is_int( $baseRevId ) ) {
86            $getLexemeRevId = $baseRevId;
87        }
88
89        $formId = $form->getId();
90        $revision = $this->getLexemeRevision( $formId, $getLexemeRevId );
91        /** @var Lexeme $lexeme */
92        $lexeme = $revision->getEntity();
93        '@phan-var Lexeme $lexeme';
94
95        $lexeme->addOrUpdateForm( $form );
96
97        // Unset EDIT_NEW flag if present (forms don't have their own pages, thus EDIT_NEW is never needed)
98        $flags &= ~EDIT_NEW;
99
100        return $this->store->saveEntity( $lexeme, $summary, $user, $flags, $baseRevId, $tags );
101    }
102
103    /**
104     * @see EntityStore::saveRedirect
105     *
106     * @param EntityRedirect $redirect
107     * @param string $summary
108     * @param User $user
109     * @param int $flags
110     * @param int|bool $baseRevId
111     *
112     * @throws \DomainException always
113     * @return never
114     */
115    public function saveRedirect(
116        EntityRedirect $redirect,
117        $summary,
118        User $user,
119        $flags = 0,
120        $baseRevId = false,
121        array $tags = []
122    ) {
123        throw new \DomainException( 'Forms currently don\'t support redirects' );
124    }
125
126    /**
127     * @see EntityStore::deleteEntity
128     *
129     * @param FormId $formId
130     * @param string $reason
131     * @param User $user
132     *
133     * @throws StorageException
134     * @throws PermissionsError
135     */
136    public function deleteEntity( EntityId $formId, $reason, User $user ) {
137        Assert::parameterType( FormId::class, $formId, '$formId' );
138        /** @var Lexeme $lexeme */
139        $lexeme = $this->getLexemeRevision( $formId )->getEntity();
140        '@phan-var Lexeme $lexeme';
141        $lexeme->removeForm( $formId );
142        $this->store->saveEntity( $lexeme, $reason, $user, EDIT_UPDATE );
143    }
144
145    /**
146     * @see EntityStore::userWasLastToEdit
147     *
148     * @param User $user
149     * @param FormId $formId
150     * @param int $lastRevId
151     *
152     * @return bool
153     */
154    public function userWasLastToEdit( User $user, EntityId $formId, $lastRevId ) {
155        Assert::parameterType( FormId::class, $formId, '$formId' );
156
157        return $this->store->userWasLastToEdit( $user, $formId->getLexemeId(), $lastRevId );
158    }
159
160    /**
161     * @see EntityStore::updateWatchlist
162     *
163     * @param User $user
164     * @param FormId $formId
165     * @param bool $watch
166     */
167    public function updateWatchlist( User $user, EntityId $formId, $watch ) {
168        Assert::parameterType( FormId::class, $formId, '$formId' );
169
170        $this->store->updateWatchlist( $user, $formId->getLexemeId(), $watch );
171    }
172
173    /**
174     * @see EntityStore::isWatching
175     *
176     * @param User $user
177     * @param FormId $formId
178     *
179     * @return bool
180     */
181    public function isWatching( User $user, EntityId $formId ) {
182        Assert::parameterType( FormId::class, $formId, '$formId' );
183
184        return $this->store->isWatching( $user, $formId->getLexemeId() );
185    }
186
187    /**
188     * @see EntityStore::canCreateWithCustomId
189     *
190     * @param FormId $formId
191     *
192     * @return bool
193     */
194    public function canCreateWithCustomId( EntityId $formId ) {
195        return false;
196    }
197
198    /**
199     * @param FormId $formId
200     * @param int $revisionId
201     *
202     * @throws StorageException
203     * @return EntityRevision guaranteed to contain a Lexeme
204     */
205    private function getLexemeRevision( FormId $formId, $revisionId = 0 ) {
206
207        if ( !is_int( $revisionId ) ) {
208            throw new UnexpectedValueException(
209                'EntityRevisionLookup does not accept non-int revision ids!'
210            );
211        }
212
213        $revision = $this->lookup->getEntityRevision(
214            $formId->getLexemeId(),
215            $revisionId,
216            LookupConstants::LATEST_FROM_MASTER
217        );
218
219        if ( !$revision || !( $revision->getEntity() instanceof Lexeme ) ) {
220            throw new StorageException( 'Cannot resolve ' . $formId->getSerialization() );
221        }
222
223        return $revision;
224    }
225
226}