Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
72.13% |
44 / 61 |
|
50.00% |
1 / 2 |
CRAP | |
0.00% |
0 / 1 |
ZObjectSecondaryDataUpdate | |
72.13% |
44 / 61 |
|
50.00% |
1 / 2 |
26.81 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
doUpdate | |
71.19% |
42 / 59 |
|
0.00% |
0 / 1 |
25.75 |
1 | <?php |
2 | /** |
3 | * WikiLambda ZObject secondary data updater for when ZObjects are edited |
4 | * |
5 | * @file |
6 | * @ingroup Extensions |
7 | * @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt |
8 | * @license MIT |
9 | */ |
10 | |
11 | namespace MediaWiki\Extension\WikiLambda; |
12 | |
13 | use Content; |
14 | use MediaWiki\Deferred\DataUpdate; |
15 | use MediaWiki\Extension\WikiLambda\Registry\ZTypeRegistry; |
16 | use MediaWiki\Extension\WikiLambda\ZObjects\ZReference; |
17 | use MediaWiki\Title\Title; |
18 | |
19 | class ZObjectSecondaryDataUpdate extends DataUpdate { |
20 | |
21 | private Title $title; |
22 | private ZObjectContent $zObject; |
23 | |
24 | /** |
25 | * @param Title $title |
26 | * @param Content $zObject |
27 | */ |
28 | public function __construct( Title $title, $zObject ) { |
29 | $this->title = $title; |
30 | $this->zObject = $zObject; |
31 | } |
32 | |
33 | public function doUpdate() { |
34 | // Given this title, gets ZID |
35 | // Given this zObject, gets ZType |
36 | // 1. Delete labels from wikilambda_zobject_labels for this ZID |
37 | // 2. Delete labels from wikilambda_zobject_label_conflicts for this ZID |
38 | // 3. Gets labels from this zObject (Z2K3 of the ZObjectContent) |
39 | // 4. Finds conflicting labels, e.g. existing labels from other ZIDs that have same language-value |
40 | // 5. Saves conflicting labels in wikilambda_zobject_label_conflicts and |
41 | // 6. Saves non-conflicting labels in wikilambda_zobject_labels |
42 | // 7. If appropriate, clear wikilambda_ztester_results for this ZID |
43 | // 8. If appropriate, add entry to wikilambda_zlanguages for this ZID |
44 | |
45 | // TODO (T300522): Only re-write the labels if they've changed. |
46 | // TODO (T300522): Use a single fancy upsert to remove/update/insert instead? |
47 | |
48 | $zid = $this->title->getDBkey(); |
49 | |
50 | $zObjectStore = WikiLambdaServices::getZObjectStore(); |
51 | |
52 | // Delete all labels: primary ones and aliases |
53 | $zObjectStore->deleteZObjectLabelsByZid( $zid ); |
54 | $zObjectStore->deleteZObjectLabelConflictsByZid( $zid ); |
55 | |
56 | // Delete language entries, if appropriate |
57 | $zObjectStore->deleteZLanguageFromLanguagesCache( $zid ); |
58 | |
59 | $labels = $this->zObject->getLabels()->getValueAsList(); |
60 | |
61 | // TODO (T357552): This should write the shortform, encoded type (e.g. `Z881(Z6)`) |
62 | $ztype = $this->zObject->getZType(); |
63 | |
64 | $innerZObject = $this->zObject->getInnerZObject(); |
65 | |
66 | // (T262089) Save output type in labels table for function and function call |
67 | $returnType = null; |
68 | // Get Z_FUNCTION_RETURN_TYPE if the ZObject is a Z8 Function |
69 | if ( $ztype === ZTypeRegistry::Z_FUNCTION ) { |
70 | $returnRef = $innerZObject->getValueByKey( ZTypeRegistry::Z_FUNCTION_RETURN_TYPE ); |
71 | if ( $returnRef instanceof ZReference ) { |
72 | $returnType = $returnRef->getZValue(); |
73 | } |
74 | } |
75 | // Get saved Z_FUNCTION_RETURN_TYPE of the Z_FUNCTIONCALL_FUNCTION if it's a Z7 |
76 | if ( $ztype === ZTypeRegistry::Z_FUNCTIONCALL ) { |
77 | $functionRef = $innerZObject->getValueByKey( ZTypeRegistry::Z_FUNCTIONCALL_FUNCTION ); |
78 | if ( $functionRef instanceof ZReference ) { |
79 | $returnType = $zObjectStore->fetchZFunctionReturnType( $functionRef->getZValue() ); |
80 | } |
81 | } |
82 | |
83 | $conflicts = $zObjectStore->findZObjectLabelConflicts( $zid, $ztype, $labels ); |
84 | $newLabels = array_filter( $labels, static function ( $value, $lang ) use ( $conflicts ) { |
85 | return !isset( $conflicts[$lang] ); |
86 | }, ARRAY_FILTER_USE_BOTH ); |
87 | |
88 | $zObjectStore->insertZObjectLabels( $zid, $ztype, $newLabels, $returnType ); |
89 | $zObjectStore->insertZObjectLabelConflicts( $zid, $conflicts ); |
90 | |
91 | // (T285368) Write aliases in the labels table |
92 | $aliases = $this->zObject->getAliases()->getValueAsList(); |
93 | if ( count( $aliases ) > 0 ) { |
94 | $zObjectStore->insertZObjectAliases( $zid, $ztype, $aliases, $returnType ); |
95 | } |
96 | |
97 | // Save function information in function table, if appropriate |
98 | // TODO (T362248): Have insertZFunctionReference do an update, and only delete if changing the type/target? |
99 | $zObjectStore->deleteZFunctionReference( $zid ); |
100 | switch ( $ztype ) { |
101 | case ZTypeRegistry::Z_IMPLEMENTATION: |
102 | $zFunction = $innerZObject->getValueByKey( ZTypeRegistry::Z_IMPLEMENTATION_FUNCTION ); |
103 | break; |
104 | |
105 | case ZTypeRegistry::Z_TESTER: |
106 | $zFunction = $innerZObject->getValueByKey( ZTypeRegistry::Z_TESTER_FUNCTION ); |
107 | break; |
108 | |
109 | default: |
110 | $zFunction = null; |
111 | break; |
112 | } |
113 | |
114 | if ( $zFunction && $zFunction->getZValue() ) { |
115 | $zObjectStore->insertZFunctionReference( $zid, $zFunction->getZValue(), $ztype ); |
116 | } |
117 | |
118 | // If appropriate, clear wikilambda_ztester_results for this ZID |
119 | // TODO (T338247): Only do this for the old revision not the new one. |
120 | switch ( $ztype ) { |
121 | case ZTypeRegistry::Z_FUNCTION: |
122 | $zObjectStore->deleteZFunctionFromZTesterResultsCache( $zid ); |
123 | break; |
124 | |
125 | case ZTypeRegistry::Z_IMPLEMENTATION: |
126 | $zObjectStore->deleteZImplementationFromZTesterResultsCache( $zid ); |
127 | break; |
128 | |
129 | case ZTypeRegistry::Z_TESTER: |
130 | $zObjectStore->deleteZTesterFromZTesterResultsCache( $zid ); |
131 | break; |
132 | |
133 | default: |
134 | // No action. |
135 | } |
136 | |
137 | // If appropriate, add entry to wikilambda_zlanguages for this ZID |
138 | if ( $ztype === ZTypeRegistry::Z_LANGUAGE ) { |
139 | // Clear old values, if any |
140 | $zObjectStore->deleteZLanguageFromLanguagesCache( $zid ); |
141 | |
142 | // Set primary language code |
143 | $targetLanguage = $innerZObject->getValueByKey( ZTypeRegistry::Z_LANGUAGE_CODE )->getZValue(); |
144 | $languageCodes = [ $targetLanguage ]; |
145 | $zObjectStore->insertZLanguageToLanguagesCache( $zid, $targetLanguage ); |
146 | |
147 | // Set secondary language codes, if any |
148 | $secondaryLanguagesObject = $innerZObject->getValueByKey( ZTypeRegistry::Z_LANGUAGE_SECONDARYCODES ); |
149 | if ( $secondaryLanguagesObject !== null ) { |
150 | '@phan-var \MediaWiki\Extension\WikiLambda\ZObjects\ZTypedList $secondaryLanguagesObject'; |
151 | $secondaryLanguages = $secondaryLanguagesObject->getAsArray(); |
152 | |
153 | foreach ( $secondaryLanguages as $key => $secondaryLanguage ) { |
154 | // $secondaryLanguage is a ZString but we want the actual string |
155 | $secondaryLanguageString = $secondaryLanguage->getZValue(); |
156 | $languageCodes[] = $secondaryLanguageString; |
157 | $zObjectStore->insertZLanguageToLanguagesCache( $zid, $secondaryLanguageString ); |
158 | } |
159 | } |
160 | |
161 | // (T343465) Add the language codes as fake aliases under Z1360/MUL (multi-lingual value) |
162 | $zObjectStore->insertZObjectAliases( |
163 | $zid, |
164 | $ztype, |
165 | [ 'Z1360' => $languageCodes ], |
166 | $returnType |
167 | ); |
168 | } |
169 | } |
170 | } |