fix: Fixed several issues with the sightings

- Main issue was the expensive and potentially large query used to find all sightings for a list of tags (used on the tag and galaxy cluster index)

potentially fixes #1993
pull/1994/head
Iglocska 2017-02-26 08:12:53 +01:00
parent ac460f16c0
commit 72a326f50f
7 changed files with 40 additions and 26 deletions

View File

@ -31,18 +31,16 @@ class GalaxyClustersController extends AppController {
public function index($id) {
$this->paginate['conditions'] = array('GalaxyCluster.galaxy_id' => $id);
$clusters = $this->paginate();
$sightedEventsToFetch = array();
$tagIds = array();
$sightings = array();
if (!empty($clusters)) {
$galaxyType = $clusters[0]['GalaxyCluster']['type'];
foreach ($clusters as $k => $v) {
$clusters[$k]['event_ids'] = array();
if (!empty($v['Tag']['EventTag'])) {
$tagIds[] = $v['Tag']['id'];
$clusters[$k]['GalaxyCluster']['tags'] = array('tag_id' => $v['Tag']['id'], 'count' => count($v['Tag']['EventTag']));
foreach ($v['Tag']['EventTag'] as $eventTag) {
if (!in_array($eventTag['event_id'], $sightedEventsToFetch)) {
$sightedEventsToFetch[] = $eventTag['event_id'];
}
$clusters[$k]['event_ids'][] = $eventTag['event_id'];
}
} else {
@ -55,7 +53,7 @@ class GalaxyClustersController extends AppController {
}
}
$this->loadModel('Sighting');
$sightings['event'] = $this->Sighting->getSightingsForObjectIds($this->Auth->user(), $sightedEventsToFetch);
$sightings['event'] = $this->Sighting->getSightingsForObjectIds($this->Auth->user(), $tagIds);
foreach ($clusters as $k => $cluster) {
$objects = array('event');
foreach ($objects as $object) {

View File

@ -49,10 +49,10 @@ class TagsController extends AppController {
} else {
$paginated = $this->paginate();
}
$sightedEventsToFetch = array();
$sightedAttributesToFetch = array();
$tagList = array();
$csv = array();
foreach ($paginated as $k => $tag) {
$tagList[] = $tag['Tag']['id'];
if (empty($tag['EventTag'])) {
$paginated[$k]['Tag']['count'] = 0;
} else {
@ -79,16 +79,10 @@ class TagsController extends AppController {
$paginated[$k]['event_ids'] = array();
$paginated[$k]['attribute_ids'] = array();
foreach($paginated[$k]['EventTag'] as $et) {
if (!in_array($et['event_id'], $sightedEventsToFetch)) {
$sightedEventsToFetch[] = $et['event_id'];
}
$paginated[$k]['event_ids'][] = $et['event_id'];
}
unset($paginated[$k]['EventTag']);
foreach($paginated[$k]['AttributeTag'] as $at) {
if (!in_array($at['attribute_id'], $sightedAttributesToFetch)) {
$sightedAttributesToFetch[] = $at['attribute_id'];
}
$paginated[$k]['attribute_ids'][] = $at['attribute_id'];
}
@ -138,8 +132,8 @@ class TagsController extends AppController {
}
}
$this->loadModel('Sighting');
$sightings['event'] = $this->Sighting->getSightingsForObjectIds($this->Auth->user(), $sightedEventsToFetch);
$sightings['attribute'] = $this->Sighting->getSightingsForObjectIds($this->Auth->user(), $sightedAttributesToFetch, 'attribute');
$sightings['event'] = $this->Sighting->getSightingsForObjectIds($this->Auth->user(), $tagList);
$sightings['attribute'] = $this->Sighting->getSightingsForObjectIds($this->Auth->user(), $tagList, 'attribute');
foreach ($paginated as $k => $tag) {
$objects = array('event', 'attribute');
foreach ($objects as $object) {

View File

@ -462,6 +462,10 @@ class Attribute extends AppModel {
public $hasMany = array(
'AttributeTag' => array(
'dependent' => true
),
'Sighting' => array(
'className' => 'Sighting',
'dependent' => true,
)
);

View File

@ -318,6 +318,10 @@ class Event extends AppModel {
'EventTag' => array(
'className' => 'EventTag',
'dependent' => true,
),
'Sighting' => array(
'className' => 'Sighting',
'dependent' => true,
)
);
@ -3239,10 +3243,11 @@ class Event extends AppModel {
}
}
}
return array(
'data' => $sightingsData,
'csv' => $csv
);
}
return array(
'data' => $sightingsData,
'csv' => $csv
);
return array('data' => array(), 'csv' => array());
}
}

View File

@ -198,20 +198,29 @@ class Sighting extends AppModel {
return $id;
}
public function getSightingsForObjectIds($user, $ids, $context = 'event', $type = '0') {
//$attributes = $this->Attribute->listVisibleAttributes($user, array('conditions' => array('Attribute.event_id' => array_values($eventIds))));
public function getSightingsForObjectIds($user, $tagList, $context = 'event', $type = '0') {
$range = (!empty(Configure::read('MISP.Sightings_range')) && is_numeric(Configure::read('MISP.Sightings_range'))) ? Configure::read('MISP.Sightings_range') : 365;
$conditions = array(
'Sighting.' . $context . '_id' => $ids,
'Sighting.date_sighting >' => strtotime("-" . $range . " days")
'Sighting.date_sighting >' => strtotime("-" . $range . " days"),
ucfirst($context) . 'Tag.tag_id' => $tagList
);
$contain = array(
ucfirst($context) => array(
ucfirst($context) . 'Tag' => array(
'Tag'
)
)
);
if ($type !== false) {
$conditions['Sighting.type'] = $type;
}
$this->bindModel(array('hasOne' => array(ucfirst($context) . 'Tag' => array('foreignKey' => false, 'conditions' => ucfirst($context) . 'Tag.' . $context . '_id = Sighting.' . $context . '_id'))));
$sightings = $this->find('all', array(
'recursive' => -1,
'contain' => array(ucfirst($context) . 'Tag'),
'conditions' => $conditions,
'fields' => array('Sighting.id', 'Sighting.' . $context . '_id', 'Sighting.date_sighting')
'fields' => array('Sighting.id', 'Sighting.' . $context . '_id', 'Sighting.date_sighting', ucfirst($context) . 'Tag.tag_id')
));
$sightingsRearranged = array();
foreach ($sightings as $sighting) {

View File

@ -465,7 +465,7 @@
</td>
<td class="short <?php echo $extra; ?>">
<?php
if ($object['objectType'] == 0) {
if ($object['objectType'] == 0 && !empty($temp)) {
echo $this->element('sparkline', array('id' => $object['id'], 'csv' => $temp));
}
?>

View File

@ -175,7 +175,11 @@
<dt>Activity</dt>
<dd>
<?php
echo $this->element('sparkline', array('id' => $event['Event']['id'], 'csv' => $sightingsData['csv']['event']));
if (!empty($sightingsData['data'])) {
echo $this->element('sparkline', array('id' => $event['Event']['id'], 'csv' => $sightingsData['csv']['event']));
} else {
echo '&nbsp';
}
?>
</dd>
<?php