new: [UI] Show similar objects when creating object from freetext

pull/8613/head
Jakub Onderka 2022-10-03 17:28:43 +02:00
parent 9153234885
commit dac0feb164
5 changed files with 91 additions and 28 deletions

View File

@ -60,13 +60,6 @@ class ObjectsController extends AppController
$sgs = $this->MispObject->SharingGroup->fetchAllAuthorised($this->Auth->user(), 'name', false, array_keys($sharing_groups));
$this->set('sharing_groups', $sgs);
}
$multiple_template_elements = Hash::extract($template['ObjectTemplateElement'],'{n}[multiple=true]');
$multiple_attribute_allowed = array();
foreach ($multiple_template_elements as $template_element) {
$relation_type = $template_element['object_relation'] . ':' . $template_element['type'];
$multiple_attribute_allowed[$relation_type] = true;
}
$this->set('multiple_attribute_allowed', $multiple_attribute_allowed);
if (isset($this->request->data['Attribute'])) {
foreach ($this->request->data['Attribute'] as &$attribute) {
@ -95,7 +88,7 @@ class ObjectsController extends AppController
));
if ($action === 'add') {
list($similar_objects_count, $similar_objects) = $this->MispObject->findSimilarObjects(
list($similar_objects_count, $similar_objects, $simple_flattened_attribute, $simple_flattened_attribute_noval) = $this->MispObject->findSimilarObjects(
$this->Auth->user(),
$event_id,
$this->request->data['Attribute'],
@ -106,6 +99,16 @@ class ObjectsController extends AppController
$this->set('similar_objects_count', $similar_objects_count);
$this->set('similar_objects', $similar_objects);
$this->set('similar_objects_display_threshold', $similar_objects_display_threshold);
$this->set('simple_flattened_attribute', $simple_flattened_attribute);
$this->set('simple_flattened_attribute_noval', $simple_flattened_attribute_noval);
$multiple_template_elements = Hash::extract($template['ObjectTemplateElement'],'{n}[multiple=true]');
$multiple_attribute_allowed = array();
foreach ($multiple_template_elements as $template_element) {
$relation_type = $template_element['object_relation'] . ':' . $template_element['type'];
$multiple_attribute_allowed[$relation_type] = true;
}
$this->set('multiple_attribute_allowed', $multiple_attribute_allowed);
}
}
}
@ -1348,6 +1351,11 @@ class ObjectsController extends AppController
$objectRelations[$templateElement['type']][] = $templateElement;
}
// Attach first object_relation according to attribute type that will be considered as default
foreach ($processedAttributes as &$attribute) {
$attribute['object_relation'] = $objectRelations[$attribute['type']][0]['object_relation'];
}
$distributionData = $this->MispObject->Event->Attribute->fetchDistributionData($this->Auth->user());
$this->set('event', $event);
$this->set('distributionData', $distributionData);
@ -1355,6 +1363,28 @@ class ObjectsController extends AppController
$this->set('template', $template);
$this->set('objectRelations', $objectRelations);
$this->set('attributes', $processedAttributes);
list($similar_objects_count, $similar_objects, $simple_flattened_attribute, $simple_flattened_attribute_noval) = $this->MispObject->findSimilarObjects(
$this->Auth->user(),
$eventId,
$processedAttributes,
$template
);
if ($similar_objects_count) {
$this->set('similar_objects_count', $similar_objects_count);
$this->set('similar_objects', $similar_objects);
$this->set('similar_objects_display_threshold', 15);
$this->set('simple_flattened_attribute', $simple_flattened_attribute);
$this->set('simple_flattened_attribute_noval', $simple_flattened_attribute_noval);
$multiple_template_elements = Hash::extract($template['ObjectTemplateElement'],'{n}[multiple=true]');
$multiple_attribute_allowed = array();
foreach ($multiple_template_elements as $template_element) {
$relation_type = $template_element['object_relation'] . ':' . $template_element['type'];
$multiple_attribute_allowed[$relation_type] = true;
}
$this->set('multiple_attribute_allowed', $multiple_attribute_allowed);
}
}
}

View File

@ -864,14 +864,14 @@ class MispObject extends AppModel
));
if (empty($similarObjects)) {
return [0, []];
return [0, [], [], []];
}
$similar_object_ids = array();
$similar_object_similarity_amount = array();
foreach ($similarObjects as $obj) {
$similar_object_ids[] = $obj['Attribute']['object_id'];
$similar_object_similarity_amount[$obj['Attribute']['object_id']] = $obj[0]['similarity_amount'];
$similar_object_similarity_amount[$obj['Attribute']['object_id']] = (int)$obj[0]['similarity_amount'];
}
$similar_objects_count = count($similar_object_ids);
$similar_object_ids = array_slice($similar_object_ids, 0, $threshold); // slice to honor the threshold
@ -891,7 +891,16 @@ class MispObject extends AppModel
return ($a['Object']['similarity_amount'] > $b['Object']['similarity_amount']) ? -1 : 1;
});
return [$similar_objects_count, $similar_objects];
$simple_flattened_attribute = [];
$simple_flattened_attribute_noval = [];
foreach ($attributes as $k => $attribute) {
$curFlat = $attribute['object_relation'] . '.' . $attribute['type'] . '.' .$attribute['value'];
$simple_flattened_attribute[$curFlat] = $k;
$curFlatNoval = $attribute['object_relation'] . '.' . $attribute['type'];
$simple_flattened_attribute_noval[$curFlatNoval] = $k;
}
return [$similar_objects_count, $similar_objects, $simple_flattened_attribute, $simple_flattened_attribute_noval];
}
// Set Object's *-seen (and ObjectAttribute's *-seen and ObjectAttribute's value if requested) to the provided *-seen value

View File

@ -4,6 +4,7 @@
Required Args:
- object => The object to be drawed
- attributes
Optional Args:
- template => The template used to compare the object with
@ -45,8 +46,8 @@ if (!isset($simple_flattened_attribute_noval) || !isset($simple_flattened_attrib
$simple_flattened_attribute_noval = array();
$simple_flattened_attribute = array();
foreach ($target_comparison_object['Attribute'] as $id => $attribute) {
$cur_flat = h($attribute['object_relation']) . '.' . h($attribute['type']) . '.' .h($attribute['value']);
$cur_flat_noval = h($attribute['object_relation']) . '.' . h($attribute['type']);
$cur_flat = $attribute['object_relation'] . '.' . $attribute['type'] . '.' .$attribute['value'];
$cur_flat_noval = $attribute['object_relation'] . '.' . $attribute['type'];
$simple_flattened_attribute[$cur_flat] = $id;
$simple_flattened_attribute_noval[$cur_flat_noval] = $id;
}
@ -87,7 +88,7 @@ if (!isset($simple_flattened_attribute_noval) || !isset($simple_flattened_attrib
<input type="button" class="btn <?php echo $btn_style; ?>" onclick="<?php echo h($merge_button_functionname); ?>(this)" data-objectid="<?php echo h($object['Object']['id']) ?>" data-updatetemplate="<?php echo $temp_comparison == 'below' ? 'true' : 'false'; ?>" value="<?php echo $temp_text; ?>" <?php echo $temp_comparison == 'above' ? 'disabled' : ''; ?>>
<?php endif; ?>
<span class="badge badge-inverse" style="position: absolute; right: 0;" title="<?php echo __('Similarity amount') ?>">
<?php echo number_format(intval($object['Object']['similarity_amount']) / count($data['Attribute']), 2)*100 . '%'; ?>
<?php echo number_format(intval($object['Object']['similarity_amount']) / count($attributes), 2)*100 . '%'; ?>
</span>
</div>
<?php foreach ($meta_fields as $field): ?>
@ -143,8 +144,8 @@ if (!isset($simple_flattened_attribute_noval) || !isset($simple_flattened_attrib
$classname = '';
$title = '';
if ($flag_comparison_enabled) { // Comparison enabled
$simple_flattened_similar_attribute = h($attribute['object_relation']) . '.' . h($attribute['type']) . '.' .h($attribute['value']);
$simple_flattened_similar_attribute_noval = h($attribute['object_relation']) . '.' . h($attribute['type']);
$simple_flattened_similar_attribute = $attribute['object_relation'] . '.' . $attribute['type'] . '.' .$attribute['value'];
$simple_flattened_similar_attribute_noval = $attribute['object_relation'] . '.' . $attribute['type'];
$flattened_ids_in_similar_object[$simple_flattened_similar_attribute_noval] = $attribute['id'];
if (
isset($simple_flattened_attribute_noval[$simple_flattened_similar_attribute_noval])
@ -195,7 +196,7 @@ if (!isset($simple_flattened_attribute_noval) || !isset($simple_flattened_attrib
?>
<?php if (!empty($attribute_ids_to_inject)): ?>
<?php foreach ($attribute_ids_to_inject as $i => $attribute_id): ?>
<?php $attribute = $data['Attribute'][$attribute_id]; ?>
<?php $attribute = $attributes[$attribute_id]; ?>
<tr class="success" title="<?php echo __('This attribute will be added to this similar object during the merge.'); ?>" style="<?php echo $i == 0 ? 'border-top: 2px dashed #3465a4' : ''; ?>">
<?php foreach ($attribute_fields as $field): ?>
<?php if (isset($attribute[$field])): ?>

View File

@ -1,5 +1,5 @@
<div class="index">
<h3><?php echo __('Create object');?></h3>
<h2><?php echo __('Create object');?></h2>
<?= $this->Form->create('Object', array('url' => $baseurl . '/objects/createFromFreetext/' . $event['Event']['id'])); ?>
<dl style="margin-top: 10px;">
<dt><?php echo __('Object Template');?></dt>
@ -64,7 +64,7 @@
<tr>
<td>
<span style="display: block;">
<select class="attributeMapping" style="margin-bottom: 5px;">
<select class="attributeMapping" style="margin-bottom: 5px;"<?= count($objectRelations[$attribute['type']]) === 1 ? ' disabled' : '' ?>>
<?php foreach ($objectRelations[$attribute['type']] as $object_relation): ?>
<option title="<?= h($object_relation['description']); ?>"><?= h($object_relation['object_relation']); ?></option>
<?php endforeach; ?>
@ -85,9 +85,35 @@
</table>
</div>
<div style="margin-top: 15px; text-align: center;">
<div style="margin-top: 15px">
<button class="btn btn-primary" onclick="submitCreateFromFreetext();"><?= __('Create Object'); ?></button>
</div>
<?php if (!empty($similar_objects)): ?>
<h3 style="margin-top: 20px;"><?= __('This event already contains similar objects') ?></h3>
<div class="row" style="margin-bottom: 20px;">
<?php foreach ($similar_objects as $object): ?>
<?php
echo $this->element('Objects/object_similarities', array(
'object' => $object,
'attributes' => $attributes,
'template' => $template,
'simple_flattened_attribute_noval' => $simple_flattened_attribute_noval,
'simple_flattened_attribute' => $simple_flattened_attribute,
// 'merge_button_functionname' => 'setMergeObject'
));
?>
<?php endforeach; ?>
<?php if ($similar_objects_count > $similar_objects_display_threshold): ?>
<div class="span5" style="margin-top: 20px;display: inline-block;float: unset;">
<div class="alert alert-info">
<h4><?php echo __('All similar objects not displayed...'); ?></h4>
<?php echo __('%s Similar objects found. %s not displayed', $similar_objects_count, $similar_objects_count-$similar_objects_display_threshold); ?>
</div>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<script>

View File

@ -61,15 +61,11 @@ $tableData = [
</thead>
<tbody>
<?php
$simple_flattened_attribute = array();
$simple_flattened_attribute_noval = array();
$attributeFields = array('category', 'type', 'value', 'to_ids' , 'comment', 'uuid', 'distribution');
if (!empty($data['Attribute'])):
foreach ($data['Attribute'] as $id => $attribute):
$cur_flat = h($attribute['object_relation']) . '.' . h($attribute['type']) . '.' .h($attribute['value']);
$cur_flat_noval = h($attribute['object_relation']) . '.' . h($attribute['type']);
$simple_flattened_attribute[$cur_flat] = $id;
$simple_flattened_attribute_noval[$cur_flat_noval] = $id;
$cur_flat = $simple_flattened_attribute[$id] ?? '';
$cur_flat_noval = $simple_flattened_attribute_noval[$id] ?? '';
echo sprintf('<tr data-curflat="%s" data-curflatnoval="%s">', h($cur_flat), h($cur_flat_noval));
echo '<td>' . h($attribute['object_relation']) . '</td>';
foreach ($attributeFields as $field) {
@ -104,13 +100,14 @@ $tableData = [
<a href="#" style="margin-left:10px;" class="btn btn-inverse" onclick="window.history.back();"><?php echo __('Back to review');?></a>
<a href="<?php echo $baseurl . '/events/view/' . h($event['Event']['id']); ?>" style="margin-left:10px;" class="btn btn-inverse"><?php echo __('Cancel');?></a>
<?php if (!empty($similar_objects)): ?>
<?php echo '<h3 style="margin-top: 20px;">' . __('This event contains similar objects.') . '</h3>'; ?>
<?php echo '<h5>' . __('Instead of creating a new object, would you like to merge your new object into one of the following?') . '</h5>'; ?>
<h3 style="margin-top: 20px;"><?= __('This event contains similar objects.') ?></h3>
<h5><?= __('Instead of creating a new object, would you like to merge your new object into one of the following?') ?></h5>
<div class="row" style="margin-bottom: 20px;">
<?php foreach ($similar_objects as $object): ?>
<?php
echo $this->element('Objects/object_similarities', array(
'object' => $object,
'attributes' => $data['Attribute'],
'template' => $template,
'simple_flattened_attribute_noval' => $simple_flattened_attribute_noval,
'simple_flattened_attribute' => $simple_flattened_attribute,