Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 105 |
|
0.00% |
0 / 14 |
CRAP | |
0.00% |
0 / 1 |
PersistentRootGraphLoader | |
0.00% |
0 / 105 |
|
0.00% |
0 / 14 |
1722 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getLoadedInstances | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
visitRoot | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
visitLanguage | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
visitManuscript | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
visitManuscriptDomain | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
visitManuscriptPrompt | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
visitRecording | |
0.00% |
0 / 79 |
|
0.00% |
0 / 1 |
756 | |||
visitRecordingAnnotations | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
visitRecordingReview | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
visitSkippedManuscriptPrompt | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
visitUser | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
visitUserDialect | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
visitUserLanguageProficiencyLevel | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\WikispeechSpeechDataCollector\Crud; |
4 | |
5 | /** |
6 | * @file |
7 | * @ingroup Extensions |
8 | * @license GPL-2.0-or-later |
9 | */ |
10 | |
11 | use ExternalStoreException; |
12 | use InvalidArgumentException; |
13 | use MediaWiki\WikispeechSpeechDataCollector\Crud\Mcr\RecordingAnnotationsCrud; |
14 | use MediaWiki\WikispeechSpeechDataCollector\Crud\Rdbms\LanguageCrud; |
15 | use MediaWiki\WikispeechSpeechDataCollector\Crud\Rdbms\ManuscriptCrud; |
16 | use MediaWiki\WikispeechSpeechDataCollector\Crud\Rdbms\ManuscriptPromptCrud; |
17 | use MediaWiki\WikispeechSpeechDataCollector\Crud\Rdbms\RecordingReviewCrud; |
18 | use MediaWiki\WikispeechSpeechDataCollector\Crud\Rdbms\UserCrud; |
19 | use MediaWiki\WikispeechSpeechDataCollector\Crud\Rdbms\UserDialectCrud; |
20 | use MediaWiki\WikispeechSpeechDataCollector\Domain\Language; |
21 | use MediaWiki\WikispeechSpeechDataCollector\Domain\Manuscript; |
22 | use MediaWiki\WikispeechSpeechDataCollector\Domain\ManuscriptDomain; |
23 | use MediaWiki\WikispeechSpeechDataCollector\Domain\ManuscriptPrompt; |
24 | use MediaWiki\WikispeechSpeechDataCollector\Domain\Persistent; |
25 | use MediaWiki\WikispeechSpeechDataCollector\Domain\PersistentSet; |
26 | use MediaWiki\WikispeechSpeechDataCollector\Domain\PersistentVisitor; |
27 | use MediaWiki\WikispeechSpeechDataCollector\Domain\Recording; |
28 | use MediaWiki\WikispeechSpeechDataCollector\Domain\RecordingAnnotations; |
29 | use MediaWiki\WikispeechSpeechDataCollector\Domain\RecordingReview; |
30 | use MediaWiki\WikispeechSpeechDataCollector\Domain\SkippedManuscriptPrompt; |
31 | use MediaWiki\WikispeechSpeechDataCollector\Domain\User; |
32 | use MediaWiki\WikispeechSpeechDataCollector\Domain\UserDialect; |
33 | use MediaWiki\WikispeechSpeechDataCollector\Domain\UserLanguageProficiencyLevel; |
34 | |
35 | /** |
36 | * Loads a graph of associated aggregated persistent objects per persistent class |
37 | * as defined by the code of this visitor. |
38 | * |
39 | * @since 0.1.0 |
40 | */ |
41 | class PersistentRootGraphLoader implements PersistentVisitor { |
42 | |
43 | /** @var PersistentSet */ |
44 | private $loadedInstances; |
45 | |
46 | /** @var CrudContext */ |
47 | private $context; |
48 | |
49 | /** |
50 | * @param CrudContext $context |
51 | * @param PersistentSet|null $loadedInstances |
52 | * @since 0.1.0 |
53 | */ |
54 | public function __construct( |
55 | CrudContext $context, |
56 | ?PersistentSet $loadedInstances = null |
57 | ) { |
58 | $this->context = $context; |
59 | $this->loadedInstances = $loadedInstances ?? new PersistentSet(); |
60 | } |
61 | |
62 | /** |
63 | * @return PersistentSet |
64 | * @since 0.1.0 |
65 | */ |
66 | public function getLoadedInstances(): PersistentSet { |
67 | return $this->loadedInstances; |
68 | } |
69 | |
70 | /** |
71 | * @param Persistent $instance |
72 | * @throws InvalidArgumentException If identity is not set. |
73 | * @since 0.1.0 |
74 | */ |
75 | private function visitRoot( Persistent $instance ) { |
76 | if ( $instance->getIdentity() === null ) { |
77 | throw new InvalidArgumentException( 'Instance must be loaded.' ); |
78 | } |
79 | $this->loadedInstances->add( $instance ); |
80 | } |
81 | |
82 | /** |
83 | * @param Language $language |
84 | * @return null |
85 | * @since 0.1.0 |
86 | */ |
87 | public function visitLanguage( |
88 | Language $language |
89 | ) { |
90 | $this->visitRoot( $language ); |
91 | return null; |
92 | } |
93 | |
94 | /** |
95 | * @param Manuscript $manuscript |
96 | * @return null |
97 | * @since 0.1.0 |
98 | */ |
99 | public function visitManuscript( |
100 | Manuscript $manuscript |
101 | ) { |
102 | $this->visitRoot( $manuscript ); |
103 | return null; |
104 | } |
105 | |
106 | /** |
107 | * @param ManuscriptDomain $manuscriptDomain |
108 | * @return null |
109 | * @since 0.1.0 |
110 | */ |
111 | public function visitManuscriptDomain( |
112 | ManuscriptDomain $manuscriptDomain |
113 | ) { |
114 | $this->visitRoot( $manuscriptDomain ); |
115 | return null; |
116 | } |
117 | |
118 | /** |
119 | * @param ManuscriptPrompt $manuscriptPrompt |
120 | * @return null |
121 | * @since 0.1.0 |
122 | */ |
123 | public function visitManuscriptPrompt( |
124 | ManuscriptPrompt $manuscriptPrompt |
125 | ) { |
126 | $this->visitRoot( $manuscriptPrompt ); |
127 | return null; |
128 | } |
129 | |
130 | /** |
131 | * Loads user voice of. |
132 | * Loads spoken dialect. |
133 | * Loads spoken dialect language |
134 | * Loads all reviews (but not the reviewer user). |
135 | * Loads annotations and annotation stereotypes. |
136 | * Loads manuscript prompt. |
137 | * Loads manuscript. |
138 | * Loads manuscript language. |
139 | * Loads manuscript domains recursive to manuscript domain root. |
140 | * |
141 | * @param Recording $recording |
142 | * @return null |
143 | * @throws ExternalStoreException If unable to load an aggregated instance. |
144 | * @since 0.1.0 |
145 | */ |
146 | public function visitRecording( |
147 | Recording $recording |
148 | ) { |
149 | $this->visitRoot( $recording ); |
150 | |
151 | if ( $recording->getSpokenDialect() ) { |
152 | $spokenDialect = new UserDialect(); |
153 | $spokenDialect->setIdentity( $recording->getSpokenDialect() ); |
154 | if ( !$this->loadedInstances->contains( $spokenDialect ) ) { |
155 | $userDialectCrud = new UserDialectCrud( $this->context ); |
156 | if ( !$userDialectCrud->load( $spokenDialect ) ) { |
157 | throw new ExternalStoreException( 'Unable to load ' . $spokenDialect ); |
158 | } |
159 | $this->loadedInstances->add( $spokenDialect ); |
160 | } else { |
161 | $spokenDialect = $this->loadedInstances->get( $spokenDialect ); |
162 | } |
163 | |
164 | if ( $spokenDialect->getLanguage() ) { |
165 | $language = new Language(); |
166 | $language->setIdentity( $spokenDialect->getLanguage() ); |
167 | if ( !$this->loadedInstances->contains( $language ) ) { |
168 | $languageCrud = new LanguageCrud( $this->context ); |
169 | if ( !$languageCrud->load( $language ) ) { |
170 | throw new ExternalStoreException( 'Unable to load ' . $language ); |
171 | } |
172 | $this->loadedInstances->add( $language ); |
173 | } |
174 | } |
175 | } |
176 | |
177 | if ( $recording->getVoiceOf() ) { |
178 | $voiceOf = new User(); |
179 | $voiceOf->setIdentity( $recording->getVoiceOf() ); |
180 | if ( !$this->loadedInstances->contains( $voiceOf ) ) { |
181 | $userCrud = new UserCrud( $this->context ); |
182 | if ( !$userCrud->load( $voiceOf ) ) { |
183 | throw new ExternalStoreException( 'Unable to load ' . $voiceOf ); |
184 | } |
185 | $this->loadedInstances->add( $voiceOf ); |
186 | } else { |
187 | $voiceOf = $this->loadedInstances->get( $voiceOf ); |
188 | } |
189 | |
190 | // @todo load UserDialects and UserLanguageProficiencyLevels + languages |
191 | // that are matching the recorded manuscript prompt manuscript language |
192 | } |
193 | |
194 | $reviewCrud = new RecordingReviewCrud( $this->context ); |
195 | // @phan-suppress-next-line PhanTypeMismatchArgumentNullable |
196 | $reviews = $reviewCrud->listByRecording( $recording->getIdentity() ); |
197 | if ( $reviews ) { |
198 | $this->loadedInstances->addAll( $reviews ); |
199 | } |
200 | |
201 | $recordingAnnotationsCrud = new RecordingAnnotationsCrud( $this->context ); |
202 | $recordingAnnotations = $recordingAnnotationsCrud->read( $recording->getIdentity() ); |
203 | if ( $recordingAnnotations !== null ) { |
204 | $this->loadedInstances->add( $recordingAnnotations ); |
205 | } |
206 | |
207 | if ( $recording->getManuscriptPrompt() ) { |
208 | $manuscriptPrompt = new ManuscriptPrompt(); |
209 | $manuscriptPrompt->setIdentity( $recording->getManuscriptPrompt() ); |
210 | if ( !$this->loadedInstances->contains( $manuscriptPrompt ) ) { |
211 | $manuscriptPromptCrud = new ManuscriptPromptCrud( $this->context ); |
212 | if ( !$manuscriptPromptCrud->load( $manuscriptPrompt ) ) { |
213 | throw new ExternalStoreException( 'Unable to load ' . $manuscriptPrompt ); |
214 | } |
215 | $this->loadedInstances->add( $manuscriptPrompt ); |
216 | } else { |
217 | $manuscriptPrompt = $this->loadedInstances->get( $manuscriptPrompt ); |
218 | } |
219 | |
220 | if ( $manuscriptPrompt->getManuscript() ) { |
221 | $manuscript = new Manuscript(); |
222 | $manuscript->setIdentity( $manuscriptPrompt->getManuscript() ); |
223 | if ( !$this->loadedInstances->contains( $manuscript ) ) { |
224 | $manuscriptCrud = new ManuscriptCrud( $this->context ); |
225 | if ( !$manuscriptCrud->load( $manuscript ) ) { |
226 | throw new ExternalStoreException( 'Unable to load ' . $manuscript ); |
227 | } |
228 | $this->loadedInstances->add( $manuscript ); |
229 | } |
230 | |
231 | if ( $manuscript->getDomain() ) { |
232 | $manuscriptDomain = new ManuscriptDomain(); |
233 | $manuscriptDomain->setIdentity( $manuscript->getDomain() ); |
234 | if ( !$this->loadedInstances->contains( $manuscriptDomain ) ) { |
235 | $manuscriptDomainCrud = new ManuscriptCrud( $this->context ); |
236 | if ( !$manuscriptDomainCrud->load( $manuscriptDomain ) ) { |
237 | throw new ExternalStoreException( 'Unable to load ' . $manuscriptDomain ); |
238 | } |
239 | $this->loadedInstances->add( $manuscriptDomain ); |
240 | } |
241 | |
242 | // load parents to root |
243 | while ( $manuscriptDomain->getParent() ) { |
244 | $parentManuscriptDomain = new ManuscriptDomain(); |
245 | $parentManuscriptDomain->setIdentity( $manuscriptDomain->getParent() ); |
246 | if ( !$this->loadedInstances->contains( $parentManuscriptDomain ) ) { |
247 | $manuscriptDomainCrud = new ManuscriptCrud( $this->context ); |
248 | if ( !$manuscriptDomainCrud->load( $parentManuscriptDomain ) ) { |
249 | throw new ExternalStoreException( 'Unable to load ' . $parentManuscriptDomain ); |
250 | } |
251 | $this->loadedInstances->add( $manuscriptDomain ); |
252 | $manuscriptDomain = $parentManuscriptDomain; |
253 | } else { |
254 | $manuscriptDomain = $this->loadedInstances->get( $parentManuscriptDomain ); |
255 | } |
256 | } |
257 | } |
258 | |
259 | if ( $manuscript->getLanguage() ) { |
260 | $language = new Language(); |
261 | $language->setIdentity( $manuscript->getLanguage() ); |
262 | if ( !$this->loadedInstances->contains( $language ) ) { |
263 | $languageCrud = new LanguageCrud( $this->context ); |
264 | if ( !$languageCrud->load( $language ) ) { |
265 | throw new ExternalStoreException( 'Unable to load ' . $language ); |
266 | } |
267 | $this->loadedInstances->add( $language ); |
268 | } |
269 | } |
270 | } |
271 | } |
272 | |
273 | return null; |
274 | } |
275 | |
276 | /** |
277 | * @param RecordingAnnotations $recordingAnnotations |
278 | * @return null |
279 | * @since 0.1.0 |
280 | */ |
281 | public function visitRecordingAnnotations( |
282 | RecordingAnnotations $recordingAnnotations |
283 | ) { |
284 | $this->visitRoot( $recordingAnnotations ); |
285 | return null; |
286 | } |
287 | |
288 | /** |
289 | * @param RecordingReview $recordingReview |
290 | * @return null |
291 | * @since 0.1.0 |
292 | */ |
293 | public function visitRecordingReview( |
294 | RecordingReview $recordingReview |
295 | ) { |
296 | $this->visitRoot( $recordingReview ); |
297 | return null; |
298 | } |
299 | |
300 | /** |
301 | * @param SkippedManuscriptPrompt $skippedManuscriptPrompt |
302 | * @return null |
303 | * @since 0.1.0 |
304 | */ |
305 | public function visitSkippedManuscriptPrompt( |
306 | SkippedManuscriptPrompt $skippedManuscriptPrompt |
307 | ) { |
308 | $this->visitRoot( $skippedManuscriptPrompt ); |
309 | return null; |
310 | } |
311 | |
312 | /** |
313 | * @param User $user |
314 | * @return null |
315 | * @since 0.1.0 |
316 | */ |
317 | public function visitUser( |
318 | User $user |
319 | ) { |
320 | $this->visitRoot( $user ); |
321 | return null; |
322 | } |
323 | |
324 | /** |
325 | * @param UserDialect $userDialect |
326 | * @return null |
327 | * @since 0.1.0 |
328 | */ |
329 | public function visitUserDialect( |
330 | UserDialect $userDialect |
331 | ) { |
332 | $this->visitRoot( $userDialect ); |
333 | return null; |
334 | } |
335 | |
336 | /** |
337 | * @param UserLanguageProficiencyLevel $languageProficiencyLevel |
338 | * @return null |
339 | * @since 0.1.0 |
340 | */ |
341 | public function visitUserLanguageProficiencyLevel( |
342 | UserLanguageProficiencyLevel $languageProficiencyLevel |
343 | ) { |
344 | $this->visitRoot( $languageProficiencyLevel ); |
345 | return null; |
346 | } |
347 | |
348 | } |