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