new: [object:fromAttribute] Started dev on merging selected attributes

into an object - WiP
pull/4672/head
mokaddem 2019-05-08 16:56:19 +02:00
parent f36947416a
commit c325f1728c
6 changed files with 123 additions and 0 deletions

View File

@ -992,4 +992,13 @@ class ObjectsController extends AppController
$this->set('captured', $capturedObjects);
$this->set('unmapped', $unmappedAttributes);
}
function proposeObjectsFromAttributes($event_id, $selected='[]')
{
$selected = json_decode($selected, true);
$potential_templates = $this->MispObject->validObjectsFromAttributeTypes($this->Auth->user(), $event_id, $selected);
// sort based on compatibility (# item in array)
$this->set('potential_templates', $potential_templates);
}
}

View File

@ -725,4 +725,42 @@ class MispObject extends AppModel
}
return count($orphans);
}
public function validObjectsFromAttributeTypes($user, $event_id, $selected)
{
$attributes = $this->Attribute->fetchAttributesSimple($user,
array(
'conditions' => array(
'id' => $selected,
'event_id' => $event_id
),
)
);
// $attribute_types = array_keys(Hash::combine($attributes, '{n}.Attribute.type'));
$attribute_types = array();
foreach ($attributes as $i => $attribute) {
$attribute_types[$attribute['Attribute']['type']] = 1;
$attributes[$i]['Attribute']['object_relation'] = $attribute['Attribute']['type'];
}
$attribute_types = array_keys($attribute_types);
array_walk($attribute_types, function(&$value) { $value = '"' . $value . '"'; });
$db = $this->getDataSource();
$potential_templates = $db->fetchAll(
'SELECT object_templates.id, object_templates.name, count(object_template_elements.type) as type_count FROM object_templates '
.'RIGHT JOIN object_template_elements ON object_templates.id = object_template_elements.object_template_id '
.'WHERE object_templates.active=1 AND object_template_elements.type IN (' . implode(',', $attribute_types) . ') '
.'GROUP BY object_templates.name ORDER BY type_count DESC;'
);
$potential_template_ids = Hash::extract($potential_templates, '{n}.object_templates.id');
$templates = $this->ObjectTemplate->find('all', array(
'recursive' => -1,
'conditions' => array('id' => $potential_template_ids),
'contain' => 'ObjectTemplateElement'
));
foreach ($templates as $i => $template) {
$templates[$i]['ObjectTemplate']['compatibility'] = $this->ObjectTemplate->checkTemplateConformityBasedOnTypes($template, $attributes);
}
return $templates;
}
}

View File

@ -204,6 +204,46 @@ class ObjectTemplate extends AppModel
return true;
}
public function checkTemplateConformityBasedOnTypes($template, $attributes)
{
if (!empty($template['ObjectTemplate']['requirements'])) {
// check for all required attributes
if (!empty($template['ObjectTemplate']['requirements']['required'])) {
foreach ($template['ObjectTemplate']['requirements']['required'] as $requiredField) {
$requiredType = Hash::extract($template['ObjectTemplateElement'], sprintf('{n}[object_relation=%s].type', $requiredField))[0];
$found = false;
foreach ($attributes as $attribute) {
if ($attribute['Attribute']['type'] == $requiredType) {
$found = true;
}
}
if (!$found) {
return array($requiredType);
}
}
}
// check for all required one of attributes
if (!empty($template['ObjectTemplate']['requirements']['requiredOneOf'])) {
$found = false;
$all_required_type = array();
foreach ($template['ObjectTemplate']['requirements']['requiredOneOf'] as $requiredField) {
$requiredType = Hash::extract($template['ObjectTemplateElement'], sprintf('{n}[object_relation=%s].type', $requiredField))[0];
$all_required_type[] = $requiredType;
foreach ($attributes as $attribute) {
if ($attribute['Attribute']['type'] == $requiredType) {
$found = true;
}
}
}
if (!$found) {
return $all_required_type;
}
}
}
// multiple flag ignored. Will be taken care of in client view. For now?
return true;
}
// simple test to see if there are any object templates - if not trigger update
public function populateIfEmpty($user)
{

View File

@ -79,6 +79,15 @@
'onClick' => 'popoverPopup',
'onClickParams' => array('this', 'selected/attribute', 'galaxies', 'selectGalaxyNamespace')
),
array(
'id' => 'group-into-object-button',
'title' => __('Group selected Attributes into an Object'),
'class' => 'mass-select hidden',
'fa-icon' => 'object-group',
'fa-source' => 'fa',
'onClick' => 'proposeObjectsFromSelectedAttributes',
'onClickParams' => array('this', $event['Event']['id'])
),
array(
'id' => 'multi-delete-button',
'title' => __('Delete selected Attributes'),

View File

@ -0,0 +1,22 @@
<table class="table table-condensed">
<thead>
<tr>
<th><?php echo __('Template ID'); ?></th>
<th><?php echo __('Object name'); ?></th>
<th><?php echo __('Compatiblity or missing attribute type'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($potential_templates as $i => $potential_template): ?>
<tr>
<td><?php echo h($potential_template['ObjectTemplate']['id']) ?></td>
<td><?php echo h($potential_template['ObjectTemplate']['name']) ?></td>
<?php if ($potential_template['ObjectTemplate']['compatibility'] === true): ?>
<td><i class="fa fa-check"></i></td>
<?php else: ?>
<td><?php echo h(implode(', ', $potential_template['ObjectTemplate']['compatibility'])); ?></td>
<?php endif; ?>
</tr>
<?php endforeach; ?>
</tbody>
<table>

View File

@ -913,6 +913,11 @@ function addSelectedTaxonomies(taxonomy) {
});
}
function proposeObjectsFromSelectedAttributes(clicked, event_id) {
var selectedAttributeIds = getSelected();
popoverPopup(clicked, event_id + '/' + selectedAttributeIds, 'objects', 'proposeObjectsFromAttributes');
}
function hideSelectedTags(taxonomy) {
$.get("/taxonomies/taxonomyMassHide/"+taxonomy, function(data) {
$("#confirmation_box").html(data);