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
SenseStore
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\BlankSense;
12use Wikibase\Lexeme\Domain\Model\Lexeme;
13use Wikibase\Lexeme\Domain\Model\Sense;
14use Wikibase\Lexeme\Domain\Model\SenseId;
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 */
25class SenseStore implements EntityStore {
26
27    /**
28     * @var EntityStore
29     */
30    private $store;
31
32    /**
33     * @var EntityRevisionLookup
34     */
35    private $lookup;
36
37    public function __construct( EntityStore $store, EntityRevisionLookup $lookup ) {
38        $this->store = $store;
39        $this->lookup = $lookup;
40    }
41
42    /**
43     * @see EntityStore::assignFreshId
44     *
45     * @param Sense $sense
46     *
47     * @throws \DomainException
48     */
49    public function assignFreshId( EntityDocument $sense ) {
50        if ( $sense instanceof BlankSense ) {
51            return;
52        }
53
54        throw new \DomainException( 'Sense IDs are currently assigned in Lexeme::addOrUpdateSense()' );
55    }
56
57    /**
58     * @see EntityStore::saveEntity
59     *
60     * @param Sense $sense
61     * @param string $summary
62     * @param User $user
63     * @param int $flags
64     * @param int|bool $baseRevId
65     * @param string[] $tags
66     *
67     * @throws StorageException
68     * @throws PermissionsError
69     * @return EntityRevision
70     */
71    public function saveEntity(
72        EntityDocument $sense,
73        $summary,
74        User $user,
75        $flags = 0,
76        $baseRevId = false,
77        array $tags = []
78    ) {
79        Assert::parameterType( Sense::class, $sense, '$sense' );
80
81        // EntityRevisionLookup and EntityStore have different opinions on valid revId fallbacks
82        $getLexemeRevId = 0;
83        if ( is_int( $baseRevId ) ) {
84            $getLexemeRevId = $baseRevId;
85        }
86
87        $senseId = $sense->getId();
88        $revision = $this->getLexemeRevision( $senseId, $getLexemeRevId );
89        /** @var Lexeme $lexeme */
90        $lexeme = $revision->getEntity();
91        '@phan-var Lexeme $lexeme';
92
93        $lexeme->addOrUpdateSense( $sense );
94
95        // Unset EDIT_NEW flag if present (senses don't have own pages, thus EDIT_NEW is never needed)
96        $flags &= ~EDIT_NEW;
97
98        return $this->store->saveEntity( $lexeme, $summary, $user, $flags, $baseRevId, $tags );
99    }
100
101    /**
102     * @see EntityStore::saveRedirect
103     *
104     * @param EntityRedirect $redirect
105     * @param string $summary
106     * @param User $user
107     * @param int $flags
108     * @param int|bool $baseRevId
109     *
110     * @throws \DomainException always
111     * @return never
112     */
113    public function saveRedirect(
114        EntityRedirect $redirect,
115        $summary,
116        User $user,
117        $flags = 0,
118        $baseRevId = false,
119        array $tags = []
120    ) {
121        throw new \DomainException( 'Senses currently don\'t support redirects' );
122    }
123
124    /**
125     * @see EntityStore::deleteEntity
126     *
127     * @param SenseId $senseId
128     * @param string $reason
129     * @param User $user
130     *
131     * @throws StorageException
132     * @throws PermissionsError
133     */
134    public function deleteEntity( EntityId $senseId, $reason, User $user ) {
135        Assert::parameterType( SenseId::class, $senseId, '$senseId' );
136        /** @var Lexeme $lexeme */
137        $lexeme = $this->getLexemeRevision( $senseId )->getEntity();
138        '@phan-var Lexeme $lexeme';
139        $lexeme->removeSense( $senseId );
140        $this->store->saveEntity( $lexeme, $reason, $user, EDIT_UPDATE );
141    }
142
143    /**
144     * @see EntityStore::userWasLastToEdit
145     *
146     * @param User $user
147     * @param SenseId $senseId
148     * @param int $lastRevId
149     *
150     * @return bool
151     */
152    public function userWasLastToEdit( User $user, EntityId $senseId, $lastRevId ) {
153        Assert::parameterType( SenseId::class, $senseId, '$senseId' );
154
155        return $this->store->userWasLastToEdit( $user, $senseId->getLexemeId(), $lastRevId );
156    }
157
158    /**
159     * @see EntityStore::updateWatchlist
160     *
161     * @param User $user
162     * @param SenseId $senseId
163     * @param bool $watch
164     */
165    public function updateWatchlist( User $user, EntityId $senseId, $watch ) {
166        Assert::parameterType( SenseId::class, $senseId, '$senseId' );
167
168        $this->store->updateWatchlist( $user, $senseId->getLexemeId(), $watch );
169    }
170
171    /**
172     * @see EntityStore::isWatching
173     *
174     * @param User $user
175     * @param SenseId $senseId
176     *
177     * @return bool
178     */
179    public function isWatching( User $user, EntityId $senseId ) {
180        Assert::parameterType( SenseId::class, $senseId, '$senseId' );
181
182        return $this->store->isWatching( $user, $senseId->getLexemeId() );
183    }
184
185    /**
186     * @see EntityStore::canCreateWithCustomId
187     *
188     * @param SenseId $senseId
189     *
190     * @return bool
191     */
192    public function canCreateWithCustomId( EntityId $senseId ) {
193        return false;
194    }
195
196    /**
197     * @param SenseId $senseId
198     * @param int $revisionId
199     *
200     * @throws StorageException
201     * @return EntityRevision guaranteed to contain a Lexeme
202     */
203    private function getLexemeRevision( SenseId $senseId, $revisionId = 0 ) {
204
205        if ( !is_int( $revisionId ) ) {
206            throw new UnexpectedValueException(
207                'EntityRevisionLookup does not accept non-int revision ids!'
208            );
209        }
210
211        $revision = $this->lookup->getEntityRevision(
212            $senseId->getLexemeId(),
213            $revisionId,
214            LookupConstants::LATEST_FROM_MASTER
215        );
216
217        if ( !$revision || !( $revision->getEntity() instanceof Lexeme ) ) {
218            throw new StorageException( 'Cannot resolve ' . $senseId->getSerialization() );
219        }
220
221        return $revision;
222    }
223
224}