chg: [internal] Simplify ObjectTemplate::checkTemplateConformityBasedOnTypes method

pull/8613/head
Jakub Onderka 2022-10-01 13:52:43 +02:00
parent 5262a40cb9
commit fba49a5a04
3 changed files with 78 additions and 80 deletions

View File

@ -1141,23 +1141,8 @@ class ObjectsController extends AppController
$selectedAttributes = $this->_jsonDecode($selectedAttributes);
$res = $this->MispObject->validObjectsFromAttributeTypes($this->Auth->user(), $eventId, $selectedAttributes);
$potentialTemplates = $res['templates'];
$attributeTypes = $res['types'];
usort($potentialTemplates, function($a, $b) {
if ($a['ObjectTemplate']['id'] == $b['ObjectTemplate']['id']) {
return 0;
} else if (is_array($a['ObjectTemplate']['compatibility']) && is_array($b['ObjectTemplate']['compatibility'])) {
return count($a['ObjectTemplate']['compatibility']) > count($b['ObjectTemplate']['compatibility']) ? 1 : -1;
} else if (is_array($a['ObjectTemplate']['compatibility']) && !is_array($b['ObjectTemplate']['compatibility'])) {
return 1;
} else if (!is_array($a['ObjectTemplate']['compatibility']) && is_array($b['ObjectTemplate']['compatibility'])) {
return -1;
} else { // sort based on invalidTypes count
return count($a['ObjectTemplate']['invalidTypes']) > count($b['ObjectTemplate']['invalidTypes']) ? 1 : -1;
}
});
$this->set('potential_templates', $potentialTemplates);
$this->set('selected_types', $attributeTypes);
$this->set('potential_templates', $res['templates']);
$this->set('selected_types', $res['types']);
$this->set('event_id', $eventId);
}
@ -1234,7 +1219,8 @@ class ObjectsController extends AppController
if (empty($template)) {
throw new NotFoundException(__('Invalid template.'));
}
$conformity_result = $this->MispObject->ObjectTemplate->checkTemplateConformityBasedOnTypes($template, $selected_attributes);
$attributeTypes = array_column(array_column($selected_attributes, 'Attribute'), 'type');
$conformity_result = $this->MispObject->ObjectTemplate->checkTemplateConformityBasedOnTypes($template, $attributeTypes);
$skipped_attributes = 0;
foreach ($selected_attributes as $i => $attribute) {
if (in_array($attribute['Attribute']['type'], $conformity_result['invalidTypes'], true)) {

View File

@ -1235,51 +1235,14 @@ class MispObject extends AppModel
'Attribute.event_id' => $eventId,
'Attribute.object_id' => 0,
],
'fields' => ['Attribute.type'],
]);
if (empty($attributes)) {
return array('templates' => array(), 'types' => array());
}
$attributeTypes = array();
foreach ($attributes as $i => $attribute) {
$attributeTypes[$attribute['Attribute']['type']] = true;
$attributes[$i]['Attribute']['object_relation'] = $attribute['Attribute']['type'];
}
$attributeTypes = array_keys($attributeTypes);
$potentialTemplateIds = $this->ObjectTemplate->find('column', array(
'recursive' => -1,
'fields' => array(
'ObjectTemplate.id',
),
'conditions' => array(
'ObjectTemplate.active' => true,
'ObjectTemplateElement.type' => $attributeTypes,
),
'joins' => array(
array(
'table' => 'object_template_elements',
'alias' => 'ObjectTemplateElement',
'type' => 'RIGHT',
'fields' => array('ObjectTemplateElement.object_relation', 'ObjectTemplateElement.type'),
'conditions' => array('ObjectTemplate.id = ObjectTemplateElement.object_template_id')
)
),
'group' => 'ObjectTemplate.id',
));
$templates = $this->ObjectTemplate->find('all', [
'recursive' => -1,
'conditions' => ['id' => $potentialTemplateIds],
'contain' => ['ObjectTemplateElement' => ['fields' => ['object_relation', 'type', 'multiple']]]
]);
foreach ($templates as $i => $template) {
$res = $this->ObjectTemplate->checkTemplateConformityBasedOnTypes($template, $attributes);
$templates[$i]['ObjectTemplate']['compatibility'] = $res['valid'] ? true : $res['missingTypes'];
$templates[$i]['ObjectTemplate']['invalidTypes'] = $res['invalidTypes'];
$templates[$i]['ObjectTemplate']['invalidTypesMultiple'] = $res['invalidTypesMultiple'];
}
return array('templates' => $templates, 'types' => $attributeTypes);
$attributeTypes = array_column(array_column($attributes, 'Attribute'), 'type');
return $this->ObjectTemplate->fetchPossibleTemplatesBasedOnTypes($attributeTypes);
}
public function groupAttributesIntoObject(array $user, $event_id, array $object, $template, array $selected_attribute_ids, array $selected_object_relation_mapping, $hard_delete_attribute)

View File

@ -207,11 +207,69 @@ class ObjectTemplate extends AppModel
}
/**
* @param array $template
* @param array $attributes
* @param array $attributeTypes
* @return array
*/
public function checkTemplateConformityBasedOnTypes(array $template, array $attributes)
public function fetchPossibleTemplatesBasedOnTypes(array $attributeTypes)
{
$uniqueAttributeTypes = array_unique($attributeTypes, SORT_REGULAR);
$potentialTemplateIds = $this->find('column', array(
'recursive' => -1,
'fields' => array(
'ObjectTemplate.id',
),
'conditions' => array(
'ObjectTemplate.active' => true,
'ObjectTemplateElement.type' => $uniqueAttributeTypes,
),
'joins' => array(
array(
'table' => 'object_template_elements',
'alias' => 'ObjectTemplateElement',
'type' => 'RIGHT',
'fields' => array('ObjectTemplateElement.object_relation', 'ObjectTemplateElement.type'),
'conditions' => array('ObjectTemplate.id = ObjectTemplateElement.object_template_id')
)
),
'group' => 'ObjectTemplate.id',
));
$templates = $this->find('all', [
'recursive' => -1,
'conditions' => ['id' => $potentialTemplateIds],
'contain' => ['ObjectTemplateElement' => ['fields' => ['object_relation', 'type', 'multiple']]]
]);
foreach ($templates as $i => $template) {
$res = $this->checkTemplateConformityBasedOnTypes($template, $attributeTypes);
$templates[$i]['ObjectTemplate']['compatibility'] = $res['valid'] ? true : $res['missingTypes'];
$templates[$i]['ObjectTemplate']['invalidTypes'] = $res['invalidTypes'];
$templates[$i]['ObjectTemplate']['invalidTypesMultiple'] = $res['invalidTypesMultiple'];
}
usort($templates, function($a, $b) {
if ($a['ObjectTemplate']['id'] == $b['ObjectTemplate']['id']) {
return 0;
} else if (is_array($a['ObjectTemplate']['compatibility']) && is_array($b['ObjectTemplate']['compatibility'])) {
return count($a['ObjectTemplate']['compatibility']) > count($b['ObjectTemplate']['compatibility']) ? 1 : -1;
} else if (is_array($a['ObjectTemplate']['compatibility']) && !is_array($b['ObjectTemplate']['compatibility'])) {
return 1;
} else if (!is_array($a['ObjectTemplate']['compatibility']) && is_array($b['ObjectTemplate']['compatibility'])) {
return -1;
} else { // sort based on invalidTypes count
return count($a['ObjectTemplate']['invalidTypes']) > count($b['ObjectTemplate']['invalidTypes']) ? 1 : -1;
}
});
return array('templates' => $templates, 'types' => $uniqueAttributeTypes);
}
/**
* @param array $template
* @param array $attributeTypes Array of attribute types to check, can contains multiple types
* @return array
*/
public function checkTemplateConformityBasedOnTypes(array $template, array $attributeTypes)
{
$to_return = array('valid' => true, 'missingTypes' => array());
if (!empty($template['ObjectTemplate']['requirements'])) {
@ -222,13 +280,7 @@ class ObjectTemplate extends AppModel
if (!empty($template['ObjectTemplate']['requirements']['required'])) {
foreach ($template['ObjectTemplate']['requirements']['required'] as $requiredField) {
$requiredType = $elementsByObjectRelationName[$requiredField]['type'];
$found = false;
foreach ($attributes as $attribute) {
if ($attribute['Attribute']['type'] === $requiredType) {
$found = true;
break;
}
}
$found = in_array($requiredType, $attributeTypes, true);
if (!$found) {
$to_return = array('valid' => false, 'missingTypes' => array($requiredType));
}
@ -241,11 +293,8 @@ class ObjectTemplate extends AppModel
foreach ($template['ObjectTemplate']['requirements']['requiredOneOf'] as $requiredField) {
$requiredType = $elementsByObjectRelationName[$requiredField]['type'] ?? null;
$allRequiredTypes[] = $requiredType;
foreach ($attributes as $attribute) {
if ($attribute['Attribute']['type'] === $requiredType) {
$found = true;
break;
}
if (!$found) {
$found = in_array($requiredType, $attributeTypes, true);
}
}
if (!$found) {
@ -262,17 +311,17 @@ class ObjectTemplate extends AppModel
$valid_types[$templateElement['type']] = $templateElement['multiple'];
}
$check_for_multiple_type = array();
foreach ($attributes as $attribute) {
if (isset($valid_types[$attribute['Attribute']['type']])) {
if (!$valid_types[$attribute['Attribute']['type']]) { // is not multiple
if (isset($check_for_multiple_type[$attribute['Attribute']['type']])) {
$to_return['invalidTypesMultiple'][] = $attribute['Attribute']['type'];
foreach ($attributeTypes as $attributeType) {
if (isset($valid_types[$attributeType])) {
if (!$valid_types[$attributeType]) { // is not multiple
if (isset($check_for_multiple_type[$attributeType])) {
$to_return['invalidTypesMultiple'][] = $attributeType;
} else {
$check_for_multiple_type[$attribute['Attribute']['type']] = 1;
$check_for_multiple_type[$attributeType] = 1;
}
}
} else {
$to_return['invalidTypes'][] = $attribute['Attribute']['type'];
$to_return['invalidTypes'][] = $attributeType;
}
}
$to_return['invalidTypes'] = array_unique($to_return['invalidTypes'], SORT_REGULAR);