Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 116
0.00% covered (danger)
0.00%
0 / 17
CRAP
0.00% covered (danger)
0.00%
0 / 1
PersistentMWAssociateArrayDeserializer
0.00% covered (danger)
0.00%
0 / 116
0.00% covered (danger)
0.00%
0 / 17
1482
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
 get
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 visitLanguage
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 visitManuscript
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 visitManuscriptDomain
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 visitManuscriptPrompt
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 visitRecording
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 visitRecordingAnnotation
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 visitRecordingAnnotations
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
42
 visitRecordingReview
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 visitSkippedManuscriptPrompt
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 visitUser
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 visitUserDialect
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 visitUserLanguageProficiencyLevel
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 deserializeUuid
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 deserializeTimestamp
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 deserializeJsonObject
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace MediaWiki\WikispeechSpeechDataCollector\Domain;
4
5/**
6 * @file
7 * @ingroup Extensions
8 * @license GPL-2.0-or-later
9 */
10
11use FormatJson;
12use MediaWiki\WikispeechSpeechDataCollector\Uuid;
13use MWException;
14use MWTimestamp;
15use Wikimedia\Timestamp\TimestampException;
16
17/**
18 * A {@link PersistentVisitor} that populates the instance with data
19 * within an associative array produced from MW API request.
20 *
21 * The visitor methods will return the passed down instance, or null
22 * if the associative array is null. Hence common usage looks like this:
23 *
24 * $persistent = $persistent->accept( new PersistentMWAssociateArrayDeserializer( $array ) );
25 *
26 * @since 0.1.0
27 */
28class PersistentMWAssociateArrayDeserializer implements PersistentVisitor {
29
30    /**
31     * @var array|null Associative array produced from MW API request.
32     */
33    private $array;
34
35    /**
36     * @param array|null $array Associative array produced from MW API request.
37     */
38    public function __construct( ?array $array ) {
39        $this->array = $array;
40    }
41
42    /**
43     * @param string $key
44     * @return mixed|null
45     */
46    private function get( string $key ) {
47        return array_key_exists( $key, $this->array ) ? $this->array[$key] : null;
48    }
49
50    /**
51     * @param Language $language
52     * @return Language|null
53     */
54    public function visitLanguage(
55        Language $language
56    ): ?Language {
57        if ( $this->array === null ) {
58            return null;
59        }
60        $language->setIdentity( $this->deserializeUuid( $this->get( 'identity' ) ) );
61        $language->setNativeName( $this->get( 'nativeName' ) );
62        $language->setIso639a1( $this->get( 'iso639a1' ) );
63        $language->setIso639a2b( $this->get( 'iso639a2b' ) );
64        $language->setIso639a2t( $this->get( 'iso639a2t' ) );
65        $language->setIso639a3( $this->get( 'iso639a3' ) );
66        return $language;
67    }
68
69    /**
70     * @param Manuscript $manuscript
71     * @return Manuscript|null
72     */
73    public function visitManuscript(
74        Manuscript $manuscript
75    ): ?Manuscript {
76        if ( $this->array === null ) {
77            return null;
78        }
79        $manuscript->setIdentity( $this->deserializeUuid( $this->get( 'identity' ) ) );
80        $manuscript->setName( $this->get( 'name' ) );
81        $manuscript->setCreated( $this->deserializeTimestamp( $this->get( 'created' ) ) );
82        $manuscript->setDisabled( $this->deserializeTimestamp( $this->get( 'disabled' ) ) );
83        $manuscript->setLanguage( $this->deserializeUuid( $this->get( 'language' ) ) );
84        $manuscript->setDomain( $this->deserializeUuid( $this->get( 'domain' ) ) );
85        return $manuscript;
86    }
87
88    /**
89     * @param ManuscriptDomain $manuscriptDomain
90     * @return ManuscriptDomain|null
91     */
92    public function visitManuscriptDomain(
93        ManuscriptDomain $manuscriptDomain
94    ): ?ManuscriptDomain {
95        if ( $this->array === null ) {
96            return null;
97        }
98        $manuscriptDomain->setIdentity( $this->deserializeUuid( $this->get( 'identity' ) ) );
99        $manuscriptDomain->setName( $this->get( 'name' ) );
100        $manuscriptDomain->setParent( $this->deserializeUuid( $this->get( 'parent' ) ) );
101        return $manuscriptDomain;
102    }
103
104    /**
105     * @param ManuscriptPrompt $manuscriptPrompt
106     * @return ManuscriptPrompt|null
107     */
108    public function visitManuscriptPrompt(
109        ManuscriptPrompt $manuscriptPrompt
110    ): ?ManuscriptPrompt {
111        if ( $this->array === null ) {
112            return null;
113        }
114        $manuscriptPrompt->setIdentity( $this->deserializeUuid( $this->get( 'identity' ) ) );
115        $manuscriptPrompt->setManuscript( $this->deserializeUuid( $this->get( 'manuscript' ) ) );
116        $manuscriptPrompt->setIndex( $this->get( 'index' ) );
117        $manuscriptPrompt->setContent( $this->get( 'content' ) );
118        return $manuscriptPrompt;
119    }
120
121    /**
122     * @param Recording $recording
123     * @return Recording|null
124     */
125    public function visitRecording(
126        Recording $recording
127    ): ?Recording {
128        if ( $this->array === null ) {
129            return null;
130        }
131        $recording->setIdentity( $this->deserializeUuid( $this->get( 'identity' ) ) );
132        $recording->setRecorded( $this->deserializeTimestamp( $this->get( 'recorded' ) ) );
133        $recording->setVoiceOf( $this->deserializeUuid( $this->get( 'voiceOf' ) ) );
134        $recording->setSpokenDialect( $this->deserializeUuid( $this->get( 'spokenDialect' ) ) );
135        $recording->setManuscriptPrompt( $this->deserializeUuid( $this->get( 'manuscriptPrompt' ) ) );
136        $recording->setAudioFileWikiPageIdentity( $this->get( 'audioFileWikiPageIdentity' ) );
137        return $recording;
138    }
139
140    /**
141     * @param RecordingAnnotation $recordingAnnotation
142     * @return RecordingAnnotation|null
143     */
144    public function visitRecordingAnnotation(
145        RecordingAnnotation $recordingAnnotation
146    ): ?RecordingAnnotation {
147        if ( $this->array === null ) {
148            return null;
149        }
150        $recordingAnnotation->setStart( $this->get( 'start' ) );
151        $recordingAnnotation->setEnd( $this->get( 'end' ) );
152        $recordingAnnotation->setStereotype( $this->get( 'stereotype' ) );
153        $recordingAnnotation->setValue( $this->get( 'value' ) );
154        return $recordingAnnotation;
155    }
156
157    /**
158     * @param RecordingAnnotations $recordingAnnotations
159     * @return RecordingAnnotations|null
160     * @throws MWException In case of annotations list contains null entries.
161     */
162    public function visitRecordingAnnotations(
163        RecordingAnnotations $recordingAnnotations
164    ): ?RecordingAnnotations {
165        if ( $this->array === null ) {
166            return null;
167        }
168        $recordingAnnotations->setIdentity( $this->deserializeUuid( $this->get( 'identity' ) ) );
169        $serializedItems = $this->get( 'items' );
170        if ( $serializedItems === null || count( $serializedItems ) === 0 ) {
171            $recordingAnnotations->setItems( null );
172        } else {
173            $items = [];
174            foreach ( $serializedItems as $serializedItem ) {
175                $recordingAnnotation = new RecordingAnnotation();
176                $this->array = $serializedItem;
177                $recordingAnnotation = $this->visitRecordingAnnotation( $recordingAnnotation );
178                if ( $recordingAnnotation === null ) {
179                    throw new MWException( 'Unexpected null entry in list of annotations.' );
180                }
181                $items[] = $recordingAnnotation;
182            }
183            $recordingAnnotations->setItems( $items );
184        }
185        return $recordingAnnotations;
186    }
187
188    /**
189     * @param RecordingReview $recordingReview
190     * @return RecordingReview|null
191     */
192    public function visitRecordingReview(
193        RecordingReview $recordingReview
194    ): ?RecordingReview {
195        if ( $this->array === null ) {
196            return null;
197        }
198        $recordingReview->setIdentity( $this->deserializeUuid( $this->get( 'identity' ) ) );
199        $recordingReview->setCreated( $this->deserializeTimestamp( $this->get( 'created' ) ) );
200        $recordingReview->setValue( $this->get( 'value' ) );
201        $recordingReview->setReviewer( $this->deserializeUuid( $this->get( 'reviewer' ) ) );
202        $recordingReview->setRecording( $this->deserializeUuid( $this->get( 'recording' ) ) );
203        return $recordingReview;
204    }
205
206    /**
207     * @param SkippedManuscriptPrompt $skippedManuscriptPrompt
208     * @return SkippedManuscriptPrompt|null
209     */
210    public function visitSkippedManuscriptPrompt(
211        SkippedManuscriptPrompt $skippedManuscriptPrompt
212    ): ?SkippedManuscriptPrompt {
213        if ( $this->array === null ) {
214            return null;
215        }
216        $skippedManuscriptPrompt->setIdentity( $this->deserializeUuid( $this->get( 'identity' ) ) );
217        $skippedManuscriptPrompt->setManuscriptPrompt(
218            $this->deserializeUuid( $this->get( 'manuscriptPrompt' ) ) );
219        $skippedManuscriptPrompt->setUser( $this->deserializeUuid( $this->get( 'user' ) ) );
220        $skippedManuscriptPrompt->setSkipped( $this->deserializeTimestamp( $this->get( 'skipped' ) ) );
221        return $skippedManuscriptPrompt;
222    }
223
224    /**
225     * @param User $user
226     * @return User|null
227     */
228    public function visitUser(
229        User $user
230    ): ?User {
231        if ( $this->array === null ) {
232            return null;
233        }
234        $user->setIdentity( $this->deserializeUuid( $this->array[ 'identity' ] ) );
235        $user->setMediaWikiUser( $this->get( 'mediaWikiUser' ) );
236        $user->setYearBorn( $this->get( 'yearBorn' ) );
237        return $user;
238    }
239
240    /**
241     * @param UserDialect $userDialect
242     * @return UserDialect|null
243     */
244    public function visitUserDialect(
245        UserDialect $userDialect
246    ): ?UserDialect {
247        if ( $this->array === null ) {
248            return null;
249        }
250        $userDialect->setIdentity( $this->deserializeUuid( $this->get( 'identity' ) ) );
251        $userDialect->setUser( $this->deserializeUuid( $this->get( 'user' ) ) );
252        $userDialect->setLanguage( $this->deserializeUuid( $this->get( 'language' ) ) );
253        $userDialect->setSpokenProficiencyLevel( $this->get( 'spokenProficiencyLevel' ) );
254        $userDialect->setLocation( $this->deserializeJsonObject( $this->get( 'location' ) ) );
255        return $userDialect;
256    }
257
258    /**
259     * @param UserLanguageProficiencyLevel $languageProficiencyLevel
260     * @return UserLanguageProficiencyLevel|null
261     */
262    public function visitUserLanguageProficiencyLevel(
263        UserLanguageProficiencyLevel $languageProficiencyLevel
264    ): ?UserLanguageProficiencyLevel {
265        if ( $this->array === null ) {
266            return null;
267        }
268        $languageProficiencyLevel->setIdentity( $this->deserializeUuid( $this->get( 'identity' ) ) );
269        $languageProficiencyLevel->setUser( $this->deserializeUuid( $this->get( 'user' ) ) );
270        $languageProficiencyLevel->setLanguage( $this->deserializeUuid( $this->get( 'language' ) ) );
271        $languageProficiencyLevel->setProficiencyLevel( $this->get( 'proficiencyLevel' ) );
272        return $languageProficiencyLevel;
273    }
274
275    /**
276     * @param string|null $value
277     * @return string|null
278     */
279    private function deserializeUuid(
280        ?string $value
281    ): ?string {
282        if ( $value === null ) {
283            return null;
284        }
285        return Uuid::asBytes( $value );
286    }
287
288    /**
289     * @param mixed|null $value
290     * @return MWTimestamp|null
291     * @throws TimestampException
292     */
293    private function deserializeTimestamp(
294        $value
295    ): ?MWTimestamp {
296        if ( $value === null ) {
297            return null;
298        }
299        $timestamp = new MWTimestamp();
300        $timestamp->setTimestamp( $value );
301        return $timestamp;
302    }
303
304    /**
305     * @param string|null $value
306     * @return string|null
307     * @throws MWException
308     */
309    private function deserializeJsonObject(
310        $value
311    ): ?string {
312        if ( $value === null ) {
313            return null;
314        }
315        $json = FormatJson::encode( $value );
316        if ( $json === false ) {
317            throw new MWException( 'Failed to encode to JSON.' );
318        }
319        return $json;
320    }
321
322}