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\Exception\PermissionsError;
6use MediaWiki\User\User;
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     * @param array $tags
112     *
113     * @throws \DomainException always
114     * @return never
115     */
116    public function saveRedirect(
117        EntityRedirect $redirect,
118        $summary,
119        User $user,
120        $flags = 0,
121        $baseRevId = false,
122        array $tags = []
123    ) {
124        throw new \DomainException( 'Forms currently don\'t support redirects' );
125    }
126
127    /**
128     * @see EntityStore::deleteEntity
129     *
130     * @param FormId $formId
131     * @param string $reason
132     * @param User $user
133     *
134     * @throws StorageException
135     * @throws PermissionsError
136     */
137    public function deleteEntity( EntityId $formId, $reason, User $user ) {
138        Assert::parameterType( FormId::class, $formId, '$formId' );
139        /** @var Lexeme $lexeme */
140        $lexeme = $this->getLexemeRevision( $formId )->getEntity();
141        '@phan-var Lexeme $lexeme';
142        $lexeme->removeForm( $formId );
143        $this->store->saveEntity( $lexeme, $reason, $user, EDIT_UPDATE );
144    }
145
146    /**
147     * @see EntityStore::userWasLastToEdit
148     *
149     * @param User $user
150     * @param FormId $formId
151     * @param int $lastRevId
152     *
153     * @return bool
154     */
155    public function userWasLastToEdit( User $user, EntityId $formId, $lastRevId ) {
156        Assert::parameterType( FormId::class, $formId, '$formId' );
157
158        return $this->store->userWasLastToEdit( $user, $formId->getLexemeId(), $lastRevId );
159    }
160
161    /**
162     * @see EntityStore::updateWatchlist
163     *
164     * @param User $user
165     * @param FormId $formId
166     * @param bool $watch
167     */
168    public function updateWatchlist( User $user, EntityId $formId, $watch ) {
169        Assert::parameterType( FormId::class, $formId, '$formId' );
170
171        $this->store->updateWatchlist( $user, $formId->getLexemeId(), $watch );
172    }
173
174    /**
175     * @see EntityStore::isWatching
176     *
177     * @param User $user
178     * @param FormId $formId
179     *
180     * @return bool
181     */
182    public function isWatching( User $user, EntityId $formId ) {
183        Assert::parameterType( FormId::class, $formId, '$formId' );
184
185        return $this->store->isWatching( $user, $formId->getLexemeId() );
186    }
187
188    /**
189     * @see EntityStore::canCreateWithCustomId
190     *
191     * @param FormId $formId
192     *
193     * @return bool
194     */
195    public function canCreateWithCustomId( EntityId $formId ) {
196        return false;
197    }
198
199    /**
200     * @param FormId $formId
201     * @param int $revisionId
202     *
203     * @throws StorageException
204     * @return EntityRevision guaranteed to contain a Lexeme
205     */
206    private function getLexemeRevision( FormId $formId, $revisionId = 0 ) {
207
208        if ( !is_int( $revisionId ) ) {
209            throw new UnexpectedValueException(
210                'EntityRevisionLookup does not accept non-int revision ids!'
211            );
212        }
213
214        $revision = $this->lookup->getEntityRevision(
215            $formId->getLexemeId(),
216            $revisionId,
217            LookupConstants::LATEST_FROM_MASTER
218        );
219
220        if ( !$revision || !( $revision->getEntity() instanceof Lexeme ) ) {
221            throw new StorageException( 'Cannot resolve ' . $formId->getSerialization() );
222        }
223
224        return $revision;
225    }
226
227}