Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 59
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
LexiconWanCacheStorage
0.00% covered (danger)
0.00%
0 / 59
0.00% covered (danger)
0.00%
0 / 8
552
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 cacheKeyFactory
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEntry
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 putEntry
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 entryItemExists
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 createEntryItem
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
30
 updateEntryItem
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
20
 deleteEntryItem
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace MediaWiki\Wikispeech\Lexicon;
4
5/**
6 * @file
7 * @ingroup Extensions
8 * @license GPL-2.0-or-later
9 */
10
11use InvalidArgumentException;
12use MWException;
13use WANObjectCache;
14
15/**
16 * A local lexicon storage implemented using {@link WANObjectCache}.
17 * It is created as an initial test storage for use at development time only.
18 *
19 * @since 0.1.8
20 */
21class LexiconWanCacheStorage implements LexiconLocalStorage {
22
23    /** @var string */
24    private const CACHE_CLASS = 'Wikispeech.LexiconWanCacheStorage';
25
26    /** @var WANObjectCache */
27    private $wanObjectCache;
28
29    /**
30     * @since 0.1.8
31     * @param WANObjectCache $wanObjectCache
32     */
33    public function __construct( WANObjectCache $wanObjectCache ) {
34        $this->wanObjectCache = $wanObjectCache;
35    }
36
37    /**
38     * @since 0.1.8
39     * @param string $language
40     * @param string $key
41     * @return string
42     */
43    private function cacheKeyFactory(
44        string $language,
45        string $key
46    ): string {
47        return $this->wanObjectCache->makeKey( self::CACHE_CLASS, $language, $key );
48    }
49
50    /**
51     * @since 0.1.8
52     * @param string $language
53     * @param string $key
54     * @return LexiconEntry|null
55     */
56    public function getEntry(
57        string $language,
58        string $key
59    ): ?LexiconEntry {
60        $entry = $this->wanObjectCache->get( $this->cacheKeyFactory( $language, $key ) );
61        if ( $entry === false ) {
62            return null;
63        }
64        return $entry;
65    }
66
67    /**
68     * @since 0.1.8
69     * @param LexiconEntry $entry
70     * @throws InvalidArgumentException If $entry->language or ->key is null.
71     */
72    private function putEntry( LexiconEntry $entry ): void {
73        $language = $entry->getLanguage();
74        if ( $language === null ) {
75            throw new InvalidArgumentException( '$entry->language must not be null.' );
76        }
77        $key = $entry->getKey();
78        if ( $key === null ) {
79            throw new InvalidArgumentException( '$entry->key must not be null.' );
80        }
81        $this->wanObjectCache->set(
82            $this->cacheKeyFactory( $language, $key ),
83            $entry,
84            WANObjectCache::TTL_INDEFINITE
85        );
86    }
87
88    /**
89     * @since 0.1.8
90     * @param string $language
91     * @param string $key
92     * @param LexiconEntryItem $item
93     * @return bool
94     * @throws InvalidArgumentException If $item has no Speechoid identity.
95     */
96    public function entryItemExists(
97        string $language,
98        string $key,
99        LexiconEntryItem $item
100    ): bool {
101        $itemSpeechoidIdentity = $item->getSpeechoidIdentity();
102        if ( $itemSpeechoidIdentity === null ) {
103            throw new InvalidArgumentException( 'Speechoid identity is missing.' );
104        }
105        $entry = $this->getEntry( $language, $key );
106        if ( $entry === null ) {
107            return false;
108        }
109        return $entry->findItemBySpeechoidIdentity( $itemSpeechoidIdentity ) !== null;
110    }
111
112    /**
113     * @since 0.1.8
114     * @param string $language
115     * @param string $key
116     * @param LexiconEntryItem $item
117     * @throws InvalidArgumentException If $item->properties is null.
118     *  If Speechoid identity is not set.
119     */
120    public function createEntryItem(
121        string $language,
122        string $key,
123        LexiconEntryItem $item
124    ): void {
125        if ( $item->getProperties() === null ) {
126            // @todo Better sanity check, ensure that required values (IPA, etc) are set.
127            throw new InvalidArgumentException( '$item->properties must not be null.' );
128        }
129        $itemSpeechoidIdentity = $item->getSpeechoidIdentity();
130        if ( $itemSpeechoidIdentity === null ) {
131            throw new InvalidArgumentException( 'Speechoid identity not set' );
132        }
133        $entry = $this->getEntry( $language, $key );
134        if ( $entry === null ) {
135            $entry = new LexiconEntry();
136            $entry->setKey( $key );
137            $entry->setLanguage( $language );
138            $entry->setItems( [ $item ] );
139        } else {
140            if ( $entry->findItemBySpeechoidIdentity( $itemSpeechoidIdentity ) !== null ) {
141                throw new MWException( 'Attempting to create an entry item that already exists.' );
142            }
143            $entry->addItem( $item );
144        }
145        $this->putEntry( $entry );
146    }
147
148    /**
149     * @since 0.1.8
150     * @param string $language
151     * @param string $key
152     * @param LexiconEntryItem $item
153     * @throws InvalidArgumentException If $item->item is null.
154     *  If Speechoid identity is not set.
155     * @throws MWException If attempting to update a non existing entry or entry item.
156     */
157    public function updateEntryItem(
158        string $language,
159        string $key,
160        LexiconEntryItem $item
161    ): void {
162        if ( $item->getProperties() === null ) {
163            // @todo Better sanity check, ensure that required values (IPA, etc) are set.
164            throw new InvalidArgumentException( '$item->item must not be null.' );
165        }
166        $itemSpeechoidIdentity = $item->getSpeechoidIdentity();
167        if ( $itemSpeechoidIdentity === null ) {
168            throw new InvalidArgumentException( 'Speechoid identity not set.' );
169        }
170        $entry = $this->getEntry( $language, $key );
171        if ( $entry === null ) {
172            throw new MWException( 'Attempting to update a non existing entry.' );
173        }
174        $entry->replaceItem( $item );
175        $this->putEntry( $entry );
176    }
177
178    /**
179     * @since 0.1.8
180     * @param string $language
181     * @param string $key
182     * @param LexiconEntryItem $item
183     * @throws InvalidArgumentException If $item->item is null.
184     *  If Speechoid identity is not set.
185     * @throws MWException If attempting to delete a non existing entry or item.
186     */
187    public function deleteEntryItem(
188        string $language,
189        string $key,
190        LexiconEntryItem $item
191    ): void {
192        if ( $item->getProperties() === null ) {
193            // @todo Better sanity check, ensure that required values (IPA, etc) are set.
194            throw new InvalidArgumentException( '$item->item must not be null.' );
195        }
196        $itemSpeechoidIdentity = $item->getSpeechoidIdentity();
197        if ( $itemSpeechoidIdentity === null ) {
198            throw new InvalidArgumentException( 'Speechoid identity not set.' );
199        }
200        $entry = $this->getEntry( $language, $key );
201        if ( $entry === null ) {
202            throw new MWException( 'Attempting to delete a non existing entry.' );
203        }
204        $entry->deleteItem( $item );
205        $this->putEntry( $entry );
206    }
207
208}