Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
81.88% covered (warning)
81.88%
113 / 138
53.85% covered (warning)
53.85%
7 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
EntitySchemaConverter
81.88% covered (warning)
81.88%
113 / 138
53.85% covered (warning)
53.85%
7 / 13
74.64
0.00% covered (danger)
0.00%
0 / 1
 getFullViewSchemaData
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 getMonolingualNameBadgeData
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getFullArraySchemaData
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
5
 getPersistenceSchemaData
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
5
 getSchemaID
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIdFromSchema
60.00% covered (warning)
60.00%
6 / 10
0.00% covered (danger)
0.00%
0 / 1
8.30
 getSchemaText
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getSchemaTextFromSchema
63.64% covered (warning)
63.64%
7 / 11
0.00% covered (danger)
0.00%
0 / 1
7.73
 getNameBadgesFromSchema
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
 getSchemaLanguages
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
4
 getLabelFromSchema
66.67% covered (warning)
66.67%
10 / 15
0.00% covered (danger)
0.00%
0 / 1
10.37
 getDescriptionFromSchema
66.67% covered (warning)
66.67%
10 / 15
0.00% covered (danger)
0.00%
0 / 1
10.37
 getAliasGroupFromSchema
66.67% covered (warning)
66.67%
10 / 15
0.00% covered (danger)
0.00%
0 / 1
10.37
1<?php
2
3declare( strict_types = 1 );
4
5namespace EntitySchema\Services\Converter;
6
7use DomainException;
8use LogicException;
9
10/**
11 * Convert schema data for different uses from the persistence format
12 *
13 * @license GPL-2.0-or-later
14 */
15class EntitySchemaConverter {
16
17    /**
18     * @param string $schemaJSON
19     * @param string[] $preferredLanguages Name badges for these language codes will always be present,
20     * even if there is no data for them, and they will also be ordered before other languages.
21     *
22     * @return FullViewEntitySchemaData
23     *
24     * @throws LogicException
25     */
26    public function getFullViewSchemaData(
27        string $schemaJSON,
28        array $preferredLanguages
29    ): FullViewEntitySchemaData {
30        $schema = json_decode( $schemaJSON, true );
31
32        return new FullViewEntitySchemaData(
33            $this->getNameBadgesFromSchema( $schema, $preferredLanguages ),
34            $this->getSchemaTextFromSchema( $schema )
35        );
36    }
37
38    public function getMonolingualNameBadgeData( string $schemaData, string $langCode ): NameBadge {
39        $schema = json_decode( $schemaData, true );
40
41        return new NameBadge(
42            $this->getLabelFromSchema( $schema, $langCode ),
43            $this->getDescriptionFromSchema( $schema, $langCode ),
44            $this->getAliasGroupFromSchema( $schema, $langCode )
45        );
46    }
47
48    public function getFullArraySchemaData( string $schemaJSON ): FullArrayEntitySchemaData {
49        $schema = json_decode( $schemaJSON, true );
50
51        $data = [
52            'labels' => [],
53            'descriptions' => [],
54            'aliases' => [],
55            'schemaText' => $this->getSchemaTextFromSchema( $schema ),
56        ];
57
58        foreach ( $this->getSchemaLanguages( $schema ) as $languageCode ) {
59            $label = $this->getLabelFromSchema( $schema, $languageCode );
60            if ( $label ) {
61                $data['labels'][$languageCode] = $label;
62            }
63            $description = $this->getDescriptionFromSchema( $schema, $languageCode );
64            if ( $description ) {
65                $data['descriptions'][$languageCode] = $description;
66            }
67            $aliases = $this->getAliasGroupFromSchema( $schema, $languageCode );
68            if ( $aliases ) {
69                $data['aliases'][$languageCode] = $aliases;
70            }
71        }
72
73        return new FullArrayEntitySchemaData( $data );
74    }
75
76    public function getPersistenceSchemaData( string $schemaJSON ): PersistenceEntitySchemaData {
77        $schema = json_decode( $schemaJSON, true );
78        $persistenceSchemaData = new PersistenceEntitySchemaData();
79        $persistenceSchemaData->schemaText = $this->getSchemaTextFromSchema( $schema );
80
81        foreach ( $this->getSchemaLanguages( $schema ) as $languageCode ) {
82            $label = $this->getLabelFromSchema( $schema, $languageCode );
83            if ( $label ) {
84                $persistenceSchemaData->labels[$languageCode] = $label;
85            }
86            $description = $this->getDescriptionFromSchema( $schema, $languageCode );
87            if ( $description ) {
88                $persistenceSchemaData->descriptions[$languageCode] = $description;
89            }
90            $aliases = $this->getAliasGroupFromSchema( $schema, $languageCode );
91            if ( $aliases ) {
92                $persistenceSchemaData->aliases[$languageCode] = $aliases;
93            }
94        }
95
96        return $persistenceSchemaData;
97    }
98
99    public function getSchemaID( string $schemaJSON ) {
100        return $this->getIdFromSchema( json_decode( $schemaJSON, true ) );
101    }
102
103    private function getIdFromSchema( array $schema ) {
104        if ( !isset( $schema['serializationVersion'] ) ) {
105            return null;
106        }
107
108        switch ( $schema['serializationVersion'] ) {
109            case '1.0':
110            case '2.0':
111            case '3.0':
112                return $schema['id'] ?? null;
113            default:
114                throw new DomainException(
115                    'Unknown schema serialization version ' . $schema['serializationVersion']
116                );
117        }
118    }
119
120    public function getSchemaText( string $schemaJSON ): string {
121        $schema = json_decode( $schemaJSON, true );
122        return $this->getSchemaTextFromSchema( $schema );
123    }
124
125    private function getSchemaTextFromSchema( array $schema ): string {
126        if ( !isset( $schema['serializationVersion'] ) ) {
127            return '';
128        }
129
130        switch ( $schema['serializationVersion'] ) {
131            case '1.0':
132            case '2.0':
133                return $schema['schema'] ?? '';
134            case '3.0':
135                return $schema['schemaText'] ?? '';
136            default:
137                throw new DomainException(
138                    'Unknown schema serialization version ' . $schema['serializationVersion']
139                );
140        }
141    }
142
143    /**
144     * @param array $schema
145     * @param string[] $preferredLanguages
146     *
147     * @return NameBadge[]
148     *
149     * @throws DomainException
150     */
151    private function getNameBadgesFromSchema( array $schema, array $preferredLanguages ): array {
152        $langs = $this->getSchemaLanguages( $schema, $preferredLanguages );
153        $nameBadges = [];
154        foreach ( $langs as $langCode ) {
155            $nameBadges[$langCode] = new NameBadge(
156                $this->getLabelFromSchema( $schema, $langCode ),
157                $this->getDescriptionFromSchema( $schema, $langCode ),
158                $this->getAliasGroupFromSchema( $schema, $langCode )
159            );
160        }
161        return $nameBadges;
162    }
163
164    /**
165     * @param array $schema
166     * @param string[] $preferredLanguages
167     *
168     * @return string[]
169     */
170    private function getSchemaLanguages( array $schema, array $preferredLanguages = [] ): array {
171        $langs = $preferredLanguages;
172        if ( !empty( $schema['labels'] ) ) {
173            $langs = array_merge(
174                $langs,
175                array_keys( $schema['labels'] )
176            );
177        }
178        if ( !empty( $schema['descriptions'] ) ) {
179            $langs = array_merge(
180                $langs,
181                array_keys( $schema['descriptions'] )
182            );
183        }
184        if ( !empty( $schema['aliases'] ) ) {
185            $langs = array_merge(
186                $langs,
187                array_keys( $schema['aliases'] )
188            );
189        }
190        return array_unique( $langs );
191    }
192
193    /**
194     * @param array $schema
195     * @param string $langCode
196     *
197     * @return string
198     *
199     * @throws DomainException
200     */
201    private function getLabelFromSchema( array $schema, $langCode ): string {
202        if ( empty( $schema['labels'] ) ) {
203            return '';
204        }
205
206        if ( !isset( $schema['serializationVersion'] ) ) {
207            return '';
208        }
209
210        switch ( $schema['serializationVersion'] ) {
211            case '1.0':
212                if ( isset( $schema['labels'][$langCode] ) ) {
213                    return $schema['labels'][$langCode]['value'];
214                }
215                return '';
216            case '2.0':
217            case '3.0':
218                return $schema['labels'][$langCode] ?? '';
219            default:
220                throw new DomainException(
221                    'Unknown schema serialization version ' . $schema['serializationVersion']
222                );
223        }
224    }
225
226    /**
227     * @param array $schema
228     * @param string $langCode
229     *
230     * @return string
231     *
232     * @throws DomainException
233     */
234    private function getDescriptionFromSchema( array $schema, $langCode ): string {
235        if ( empty( $schema['descriptions'] ) ) {
236            return '';
237        }
238
239        if ( !isset( $schema['serializationVersion'] ) ) {
240            return '';
241        }
242
243        switch ( $schema['serializationVersion'] ) {
244            case '1.0':
245                if ( isset( $schema['descriptions'][$langCode] ) ) {
246                    return $schema['descriptions'][$langCode]['value'];
247                }
248                return '';
249            case '2.0':
250            case '3.0':
251                return $schema['descriptions'][$langCode] ?? '';
252            default:
253                throw new DomainException(
254                    'Unknown schema serialization version ' . $schema['serializationVersion']
255                );
256        }
257    }
258
259    /**
260     * @param array $schema
261     * @param string $langCode
262     *
263     * @return array
264     *
265     * @throws DomainException
266     */
267    private function getAliasGroupFromSchema( array $schema, $langCode ): array {
268        if ( empty( $schema['aliases'] ) ) {
269            return [];
270        }
271
272        if ( !isset( $schema['serializationVersion'] ) ) {
273            return [];
274        }
275
276        switch ( $schema['serializationVersion'] ) {
277            case '1.0':
278                if ( isset( $schema['aliases'][$langCode] ) ) {
279                    return array_column( $schema['aliases'][$langCode], 'value' );
280                }
281                return [];
282            case '2.0':
283            case '3.0':
284                return $schema['aliases'][$langCode] ?? [];
285            default:
286                throw new DomainException(
287                    'Unknown schema serialization version ' . $schema['serializationVersion']
288                );
289        }
290    }
291
292}