|
36 | 36 |
|
37 | 37 | use CommonDBTM; |
38 | 38 | use Entity; |
| 39 | +use Glpi\Asset\AssetDefinitionManager; |
| 40 | +use Glpi\Dropdown\DropdownDefinitionManager; |
39 | 41 | use Glpi\Form\AccessControl\FormAccessControl; |
40 | 42 | use Glpi\Form\Category; |
41 | 43 | use Glpi\Form\Comment; |
|
54 | 56 | use Glpi\Form\Export\Specification\CommentContentSpecification; |
55 | 57 | use Glpi\Form\Export\Specification\ConditionDataSpecification; |
56 | 58 | use Glpi\Form\Export\Specification\CustomIllustrationContentSpecification; |
| 59 | +use Glpi\Form\Export\Specification\CustomTypeRequirementSpecification; |
57 | 60 | use Glpi\Form\Export\Specification\DataRequirementSpecification; |
58 | 61 | use Glpi\Form\Export\Specification\DestinationContentSpecification; |
59 | 62 | use Glpi\Form\Export\Specification\ExportContentSpecification; |
|
65 | 68 | use Glpi\Form\FormTranslation; |
66 | 69 | use Glpi\Form\Question; |
67 | 70 | use Glpi\Form\QuestionType\QuestionTypeInterface; |
| 71 | +use Glpi\Form\QuestionType\QuestionTypeItem; |
| 72 | +use Glpi\Form\QuestionType\QuestionTypeItemExtraDataConfig; |
68 | 73 | use Glpi\Form\Section; |
69 | 74 | use Glpi\UI\IllustrationManager; |
70 | 75 | use InvalidArgumentException; |
| 76 | +use LogicException; |
71 | 77 | use RuntimeException; |
72 | 78 | use Session; |
73 | 79 | use Throwable; |
@@ -120,17 +126,32 @@ public function previewImport( |
120 | 126 | // Validate each forms |
121 | 127 | $results = new ImportResultPreview(); |
122 | 128 | foreach ($export_specification->forms as $form_spec) { |
123 | | - $requirements = $form_spec->data_requirements; |
124 | | - $mapper->mapExistingItemsForRequirements($requirements); |
125 | | - |
| 129 | + // Skip ignored forms |
126 | 130 | $form_id = $form_spec->id; |
127 | 131 | $form_name = $form_spec->name; |
128 | 132 | if (in_array($form_id, $skipped_forms)) { |
129 | 133 | $results->addSkippedForm($form_id, $form_name); |
130 | 134 | continue; |
131 | 135 | } |
132 | 136 |
|
133 | | - if ($mapper->validateRequirements($requirements)) { |
| 137 | + // Validate custom types requirements |
| 138 | + $types_requirements = $form_spec->custom_types_requirements; |
| 139 | + $missing_types = $this->getMissingCustomTypes($types_requirements); |
| 140 | + foreach ($missing_types as $missing_type) { |
| 141 | + $message = sprintf(__('Unknown custom type: %s'), $missing_type); |
| 142 | + $results->addFatalErrorForForm($form_id, $form_name, $message); |
| 143 | + } |
| 144 | + |
| 145 | + // Do not process others requirements if we reached a fatal error |
| 146 | + if ($results->hasFatalErrorForForm($form_id)) { |
| 147 | + continue; |
| 148 | + } |
| 149 | + |
| 150 | + // Validate data requirements |
| 151 | + $data_requirements = $form_spec->data_requirements; |
| 152 | + $mapper->mapExistingItemsForRequirements($data_requirements); |
| 153 | + |
| 154 | + if ($mapper->validateRequirements($data_requirements)) { |
134 | 155 | $results->addValidForm($form_id, $form_name); |
135 | 156 | } else { |
136 | 157 | $results->addInvalidForm($form_id, $form_name); |
@@ -180,15 +201,27 @@ public function importFormsFromJson( |
180 | 201 | // Import each forms |
181 | 202 | $result = new ImportResult(); |
182 | 203 | foreach ($export_specification->forms as $form_spec) { |
183 | | - $requirements = $form_spec->data_requirements; |
184 | | - $mapper->mapExistingItemsForRequirements($requirements); |
185 | | - |
| 204 | + // Skip form if needed |
186 | 205 | $form_id = $form_spec->id; |
187 | 206 | if (in_array($form_id, $skipped_forms)) { |
188 | 207 | continue; |
189 | 208 | } |
190 | 209 |
|
191 | | - if (!$mapper->validateRequirements($requirements)) { |
| 210 | + // Validate custom types |
| 211 | + $types_requirements = $form_spec->custom_types_requirements; |
| 212 | + if (!$this->validateCustomTypesRequirements($types_requirements)) { |
| 213 | + $result->addFailedFormImport( |
| 214 | + $form_spec->name, |
| 215 | + ImportError::MISSING_CUSTOM_TYPE_REQUIREMENT, |
| 216 | + ); |
| 217 | + continue; |
| 218 | + } |
| 219 | + |
| 220 | + // Validate data requirements |
| 221 | + $data_requirements = $form_spec->data_requirements; |
| 222 | + $mapper->mapExistingItemsForRequirements($data_requirements); |
| 223 | + |
| 224 | + if (!$mapper->validateRequirements($data_requirements)) { |
192 | 225 | $result->addFailedFormImport( |
193 | 226 | $form_spec->name, |
194 | 227 | ImportError::MISSING_DATA_REQUIREMENT |
@@ -235,6 +268,7 @@ private function exportFormToSpec(Form $form): FormContentSpecification |
235 | 268 | $form_spec = $this->exportAccesControlPolicies($form, $form_spec); |
236 | 269 | $form_spec = $this->exportDestinations($form, $form_spec); |
237 | 270 | $form_spec = $this->exportTranslations($form, $form_spec); |
| 271 | + $form_spec = $this->addCustomTypesRequirements($form, $form_spec); |
238 | 272 |
|
239 | 273 | return $form_spec; |
240 | 274 | } |
@@ -1108,4 +1142,62 @@ private function prepareIllustrationDataForImport( |
1108 | 1142 |
|
1109 | 1143 | return $prefix . $illustration->key; |
1110 | 1144 | } |
| 1145 | + |
| 1146 | + private function addCustomTypesRequirements( |
| 1147 | + Form $form, |
| 1148 | + FormContentSpecification $form_spec, |
| 1149 | + ): FormContentSpecification { |
| 1150 | + $asset_manager = AssetDefinitionManager::getInstance(); |
| 1151 | + $dropdown_manager = DropdownDefinitionManager::getInstance(); |
| 1152 | + |
| 1153 | + // Look for item question on custom assets types |
| 1154 | + foreach ($form->getQuestions() as $question) { |
| 1155 | + $type = $question->getQuestionType(); |
| 1156 | + if (!$type instanceof QuestionTypeItem) { |
| 1157 | + continue; |
| 1158 | + } |
| 1159 | + |
| 1160 | + $config = $question->getExtraDataConfig(); |
| 1161 | + if (!$config instanceof QuestionTypeItemExtraDataConfig) { |
| 1162 | + throw new LogicException(); // Impossible |
| 1163 | + } |
| 1164 | + |
| 1165 | + $itemtype = $config->getItemtype(); |
| 1166 | + if ( |
| 1167 | + $asset_manager->isCustomAsset($itemtype) |
| 1168 | + || $dropdown_manager->isCustomDropdown($itemtype) |
| 1169 | + ) { |
| 1170 | + $form_spec->addCustomTypeRequirement( |
| 1171 | + new CustomTypeRequirementSpecification($itemtype) |
| 1172 | + ); |
| 1173 | + } |
| 1174 | + } |
| 1175 | + |
| 1176 | + return $form_spec; |
| 1177 | + } |
| 1178 | + |
| 1179 | + /** @param CustomTypeRequirementSpecification[] $requirements */ |
| 1180 | + private function validateCustomTypesRequirements(array $requirements): bool |
| 1181 | + { |
| 1182 | + foreach ($requirements as $requirement) { |
| 1183 | + if (!class_exists($requirement->itemtype)) { |
| 1184 | + return false; |
| 1185 | + } |
| 1186 | + } |
| 1187 | + |
| 1188 | + return true; |
| 1189 | + } |
| 1190 | + |
| 1191 | + /** @param CustomTypeRequirementSpecification[] $requirements */ |
| 1192 | + private function getMissingCustomTypes(array $requirements): array |
| 1193 | + { |
| 1194 | + $missing_types = []; |
| 1195 | + foreach ($requirements as $requirement) { |
| 1196 | + if (!class_exists($requirement->itemtype)) { |
| 1197 | + $missing_types[] = $requirement->itemtype; |
| 1198 | + } |
| 1199 | + } |
| 1200 | + |
| 1201 | + return $missing_types; |
| 1202 | + } |
1111 | 1203 | } |
0 commit comments