mirror of https://github.com/MISP/MISP
new: small rework of the thread functionalities
- API get /threads/view/<thread_id> and /threads/viewEvent/<event_id> - Added new setting to show post count on the event index including a notification if it has a post newer than 24 hourspull/1886/head
parent
91209dde66
commit
ee80ecfce7
|
@ -571,6 +571,7 @@ class EventsController extends AppController {
|
|||
if (Configure::read('MISP.showCorrelationsOnIndex')) $events = $this->Event->attachCorrelationCountToEvents($this->Auth->user(), $events);
|
||||
if (Configure::read('MISP.showSightingsCountOnIndex') && Configure::read('MISP.Plugin.Sightings_enable') !== false) $events = $this->Event->attachSightingsCountToEvents($this->Auth->user(), $events);
|
||||
if (Configure::read('MISP.showProposalsCountOnIndex')) $events = $this->Event->attachProposalsCountToEvents($this->Auth->user(), $events);
|
||||
if (Configure::read('MISP.showDiscussionsCountOnIndex')) $events = $this->Event->attachDiscussionsCountToEvents($this->Auth->user(), $events);
|
||||
$events = $this->GalaxyCluster->attachClustersToEventIndex($events, true);
|
||||
$this->set('events', $events);
|
||||
}
|
||||
|
|
|
@ -19,68 +19,40 @@ class ThreadsController extends AppController {
|
|||
public function viewEvent($id) {
|
||||
$this->loadModel('Event');
|
||||
$result = $this->Event->fetchEvent($this->Auth->user(), array('eventid' => $id));
|
||||
if (empty($result)) throw new MethodNotAllowedException('You are not authorised to see that.');
|
||||
$result = $result[0];
|
||||
// Show the discussion
|
||||
|
||||
$this->Thread->Behaviors->unload('SysLogLogable.SysLogLogable');
|
||||
$params = array('conditions' => array('event_id' => $id),
|
||||
'recursive' => -1,
|
||||
'fields' => array('id', 'event_id', 'distribution', 'title', 'sharing_group_id')
|
||||
);
|
||||
$thread = $this->Thread->find('first', $params);
|
||||
if (empty($thread)) {
|
||||
$newThread = array(
|
||||
'date_created' => date('Y/m/d H:i:s'),
|
||||
'date_modified' => date('Y/m/d H:i:s'),
|
||||
'user_id' => $this->Auth->user('id'),
|
||||
'event_id' => $id,
|
||||
'title' => 'Discussion about Event #' . $result['Event']['id'] . ' (' . $result['Event']['info'] . ')',
|
||||
'distribution' => $result['Event']['distribution'],
|
||||
'sharing_group_id' => $result['Event']['sharing_group_id'],
|
||||
'post_count' => 0,
|
||||
'org_id' => $result['Event']['orgc_id']
|
||||
);
|
||||
$this->Thread->save($newThread);
|
||||
$thread = ($this->Thread->read());
|
||||
} else {
|
||||
if ($thread['Thread']['distribution'] != $result['Event']['distribution']) {
|
||||
$thread['Thread']['distribution'] = $result['Event']['distribution'];
|
||||
$this->Thread->save($thread);
|
||||
}
|
||||
if ($thread['Thread']['sharing_group_id'] != $result['Event']['sharing_group_id']) {
|
||||
$thread['Thread']['sharing_group_id'] = $result['Event']['sharing_group_id'];
|
||||
$this->Thread->save($thread);
|
||||
}
|
||||
}
|
||||
$this->loadModel('Post');
|
||||
$this->paginate['Post'] = array(
|
||||
'limit' => 5,
|
||||
'conditions' => array('Post.thread_id' => $thread['Thread']['id']),
|
||||
'contain' => array('User' => array('Organisation' => array('fields' => array('id', 'name')))),
|
||||
);
|
||||
$posts = $this->paginate('Post');
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
foreach ($posts as $key => $post) {
|
||||
if ($post['User']['org_id'] != $this->Auth->user('org_id')) {
|
||||
$posts[$key]['User']['email'] = 'User ' . $post['User']['id'] . ' (' . $post['User']['org_id'] . ')';
|
||||
$thread_id = false;
|
||||
if ($result) {
|
||||
$thread_id = $this->Thread->find('first', array('recursive' => -1, 'conditions' => array('Thread.event_id' => $id), 'fields' => array('Thread.id')));
|
||||
if ($thread_id) {
|
||||
$thread_id = $thread_id['Thread']['id'];
|
||||
} else {
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->viewData($array(), $this->response->type());
|
||||
}
|
||||
$thread_id = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Show the discussion
|
||||
$this->set('posts', $posts);
|
||||
$this->set('thread_id', $thread['Thread']['id']);
|
||||
$this->set('myuserid', $this->Auth->user('id'));
|
||||
$this->set('thread_title', $thread['Thread']['title']);
|
||||
$this->disableCache();
|
||||
$this->layout = 'ajax';
|
||||
$this->render('/Elements/eventdiscussion');
|
||||
if ($thread_id) {
|
||||
$post_id = false;
|
||||
if (isset($this->passedArgs['post_id'])) $post_id = $this->passedArgs['post_id'];
|
||||
$response = $this->__view($thread_id, false, $post_id);
|
||||
if ($this->_isRest()) {
|
||||
return $response;
|
||||
}
|
||||
} else {
|
||||
throw new NotFoundException('Invalid Thread.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function view($thread_id, $eventView = false) {
|
||||
$post_id = false;
|
||||
if (isset($this->passedArgs['post_id'])) $post_id = $this->passedArgs['post_id'];
|
||||
$response = $this->__view($thread_id, $eventView, $post_id);
|
||||
if ($this->_isRest()) {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
private function __view($thread_id, $eventView, $post_id) {
|
||||
if ($eventView) {
|
||||
$id = $thread_id;
|
||||
// Show the discussion
|
||||
|
@ -144,24 +116,41 @@ class ThreadsController extends AppController {
|
|||
'conditions' => array('Post.thread_id' => $thread_id),
|
||||
'contain' => array(
|
||||
'User' => array(
|
||||
'fields' => array('User.email', 'User.id'),
|
||||
'Organisation' => array(
|
||||
'fields' => array('id', 'name')
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
$posts = $this->paginate('Post');
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
foreach ($posts as $key => $post) {
|
||||
if ($post['User']['org_id'] != $this->Auth->user('org_id')) {
|
||||
$posts[$key]['User']['email'] = 'User ' . $post['User']['id'] . ' (' . $post['User']['org_id'] . ')';
|
||||
if ($this->_isRest()) {
|
||||
$posts = $this->Thread->Post->find('all', array(
|
||||
'contain' => $this->paginate['contain'],
|
||||
'conditions' => $this->paginate['conditions']
|
||||
));
|
||||
} else {
|
||||
$posts = $this->paginate('Post');
|
||||
}
|
||||
foreach ($posts as $k => $post) {
|
||||
if (!empty($post['User'])) {
|
||||
$posts[$k]['Post']['org_name'] = $post['User']['Organisation']['name'];
|
||||
if ($this->_isSiteAdmin() || $this->Auth->user('org_id') == $post['User']['org_id']) {
|
||||
$posts[$k]['Post']['user_email'] = $post['User']['email'];
|
||||
}
|
||||
$posts[$k]['Post']['user_id'] = $post['User']['id'];
|
||||
$posts[$k] = $posts[$k]['Post'];
|
||||
}
|
||||
}
|
||||
$this->set('posts', $posts);
|
||||
$this->set('post_id', $post_id);
|
||||
$this->set('thread_id', $thread_id);
|
||||
$this->set('thread_title', $thread['Thread']['title']);
|
||||
if ($this->_isRest()) {
|
||||
if (!empty($posts)) {
|
||||
$thread['Thread']['Post'] = $posts;
|
||||
}
|
||||
return $this->RestResponse->viewData($thread, $this->response->type());
|
||||
} else {
|
||||
$this->set('posts', $posts);
|
||||
$this->set('post_id', $post_id);
|
||||
$this->set('thread', $thread);
|
||||
}
|
||||
}
|
||||
if ($eventView) {
|
||||
$this->set('context', 'event');
|
||||
|
|
|
@ -461,6 +461,38 @@ class Event extends AppModel {
|
|||
return $events;
|
||||
}
|
||||
|
||||
public function attachDiscussionsCountToEvents($user, $events) {
|
||||
$eventIds = Set::extract('/Event/id', $events);
|
||||
$this->Thread = ClassRegistry::init('Thread');
|
||||
$threads = $this->Thread->find('list', array(
|
||||
'conditions' => array('Thread.event_id' => $eventIds),
|
||||
'fields' => array('Thread.event_id', 'Thread.id')
|
||||
));
|
||||
$posts = $this->Thread->Post->find('all', array(
|
||||
'conditions' => array('Post.thread_id' => $threads),
|
||||
'recursive' => -1,
|
||||
'fields' => array('Count(id) AS post_count', 'thread_id', 'max(date_modified) as last_post'),
|
||||
'group' => array('Post.thread_id')
|
||||
));
|
||||
$event_threads = array();
|
||||
foreach ($posts as $k => $v) {
|
||||
foreach ($threads as $k2 => $v2) {
|
||||
if ($v2 == $v['Post']['thread_id']) {
|
||||
$event_threads[$k2] = array(
|
||||
'post_count' => $v[0]['post_count'],
|
||||
'last_post' => strtotime($v[0]['last_post'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($events as $k => $v) {
|
||||
$events[$k]['Event']['post_count'] = !empty($event_threads[$events[$k]['Event']['id']]) ? $event_threads[$events[$k]['Event']['id']]['post_count'] : 0;
|
||||
$events[$k]['Event']['last_post'] = !empty($event_threads[$events[$k]['Event']['id']]) ? $event_threads[$events[$k]['Event']['id']]['last_post'] : 0;
|
||||
|
||||
}
|
||||
return $events;
|
||||
}
|
||||
|
||||
private function __buildEventConditionsCorrelation($user, $eventIds, $sgids) {
|
||||
if (!is_array($eventIds)) $eventIds = array($eventIds);
|
||||
if (!$user['Role']['perm_site_admin']) {
|
||||
|
|
|
@ -598,6 +598,15 @@ class Server extends AppModel {
|
|||
'type' => 'boolean',
|
||||
'null' => true
|
||||
),
|
||||
'showDiscussionsCountOnIndex' => array(
|
||||
'level' => 1,
|
||||
'description' => 'When enabled, the aggregate number of discussion posts for the event becomes visible to the currently logged in user on the event index UI.',
|
||||
'value' => false,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
'type' => 'boolean',
|
||||
'null' => true
|
||||
),
|
||||
'disableUserSelfManagement' => array(
|
||||
'level' => 1,
|
||||
'description' => 'When enabled only Org and Site admins can edit a user\'s profile.',
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
<?php
|
||||
endif;
|
||||
endif;
|
||||
$date = time();
|
||||
$day = 86400;
|
||||
?>
|
||||
<th><?php echo $this->Paginator->sort('id');?></th>
|
||||
<th>Clusters</th>
|
||||
|
@ -37,6 +39,9 @@
|
|||
<?php if (Configure::read('MISP.showProposalsOnIndex')):?>
|
||||
<th title="Proposal Count">#Prop</th>
|
||||
<?php endif; ?>
|
||||
<?php if (Configure::read('MISP.showDiscussionsCountOnIndex')):?>
|
||||
<th title="Post Count">#Posts</th>
|
||||
<?php endif; ?>
|
||||
<?php if ($isSiteAdmin): ?>
|
||||
<th><?php echo $this->Paginator->sort('user_id', 'Email');?></th>
|
||||
<?php endif; ?>
|
||||
|
@ -163,6 +168,21 @@
|
|||
<?php echo !empty($event['Event']['proposals_count']) ? h($event['Event']['proposals_count']) : ''; ?>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
<?php if (Configure::read('MISP.showDiscussionsCountOnIndex')): ?>
|
||||
<td class = "bold" style="width:30px;" ondblclick="location.href ='<?php echo $baseurl."/events/view/".$event['Event']['id'];?>'" title="<?php echo (!empty($event['Event']['proposals_count']) ? h($event['Event']['proposals_count']) : '0') . ' proposal(s)';?>">
|
||||
<?php
|
||||
if (!empty($event['Event']['post_count'])) {
|
||||
$post_count = h($event['Event']['post_count']);
|
||||
if (($date - $event['Event']['last_post']) < $day) {
|
||||
$post_count .= ' (<span class="red bold">NEW</span>)';
|
||||
}
|
||||
} else {
|
||||
$post_count = '';
|
||||
}
|
||||
?>
|
||||
<span style=" white-space: nowrap;"><?php echo $post_count?></span>
|
||||
</td>
|
||||
<?php endif;?>
|
||||
<?php if ('true' == $isSiteAdmin): ?>
|
||||
<td class="short" ondblclick="location.href ='<?php echo $baseurl."/events/view/".$event['Event']['id'];?>'">
|
||||
<?php echo h($event['User']['email']); ?>
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
<?php
|
||||
foreach ($posts as $post) {
|
||||
?>
|
||||
<a name="message_<?php echo h($post['Post']['id']);?>"></a>
|
||||
<table class="discussionBox" id=<?php echo '"' . h($post['Post']['id']) . '"';?> >
|
||||
<a name="message_<?php echo h($post['id']);?>"></a>
|
||||
<table class="discussionBox" id=<?php echo '"' . h($post['id']) . '"';?> >
|
||||
<tr>
|
||||
<td class="discussionBoxTD discussionBoxTDtop" colspan="2">
|
||||
<div>
|
||||
|
@ -31,12 +31,12 @@
|
|||
<tr>
|
||||
<td>
|
||||
<?php
|
||||
echo 'Date: ' . h($post['Post']['date_created']);
|
||||
echo 'Date: ' . h($post['date_created']);
|
||||
?>
|
||||
</td>
|
||||
<td style="text-align:right">
|
||||
<a href="#top" class="whitelink">Top</a> |
|
||||
<a href="<?php echo "#".$post['Post']['id']; ?>" class="whitelink">#<?php echo h($post['Post']['id'])?></a>
|
||||
<a href="<?php echo "#".$post['id']; ?>" class="whitelink">#<?php echo h($post['id'])?></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -46,10 +46,10 @@
|
|||
<tr>
|
||||
<td class="discussionBoxTD discussionBoxTDMid discussionBoxTDMidLeft">
|
||||
<?php
|
||||
if (isset($post['User']['Organisation'])) {
|
||||
$imgAbsolutePath = APP . WEBROOT_DIR . DS . 'img' . DS . 'orgs' . DS . h($post['User']['Organisation']['name']) . '.png';
|
||||
if (file_exists($imgAbsolutePath)) echo $this->Html->image('orgs/' . h($post['User']['Organisation']['name']) . '.png', array('alt' => h($post['User']['Organisation']['name']), 'title' => h($post['User']['Organisation']['name']), 'style' => 'width:48px; height:48px'));
|
||||
else echo $this->Html->tag('span', h($post['User']['Organisation']['name']), array('class' => 'welcome', 'style' => 'float:center;'));
|
||||
if (isset($post['org_name'])) {
|
||||
$imgAbsolutePath = APP . WEBROOT_DIR . DS . 'img' . DS . 'orgs' . DS . h($post['org_name']) . '.png';
|
||||
if (file_exists($imgAbsolutePath)) echo $this->Html->image('orgs/' . h($post['org_name']) . '.png', array('alt' => h($post['org_name']), 'title' => h($post['User']['Organisation']['name']), 'style' => 'width:48px; height:48px'));
|
||||
else echo $this->Html->tag('span', h($post['org_name']), array('class' => 'welcome', 'style' => 'float:center;'));
|
||||
} else {
|
||||
echo 'Deactivated user';
|
||||
}
|
||||
|
@ -57,22 +57,22 @@
|
|||
</td>
|
||||
<td class="discussionBoxTD discussionBoxTDMid discussionBoxTDMidRight">
|
||||
<?php
|
||||
echo $this->Command->convertQuotes(nl2br(h($post['Post']['contents'])));
|
||||
if ($post['Post']['post_id'] !=0 || ($post['Post']['date_created'] != $post['Post']['date_modified'])) {
|
||||
echo $this->Command->convertQuotes(nl2br(h($post['contents'])));
|
||||
if ($post['post_id'] !=0 || ($post['date_created'] != $post['date_modified'])) {
|
||||
?>
|
||||
<br /><br />
|
||||
<?php
|
||||
}
|
||||
if ($post['Post']['post_id'] != 0) {
|
||||
if ($post['post_id'] != 0) {
|
||||
?>
|
||||
<span style="font-style:italic">
|
||||
In reply to post
|
||||
<a href="<?php echo "#".h($post['Post']['post_id']); ?>">#<?php echo h($post['Post']['post_id'])?></a>
|
||||
<a href="<?php echo "#".h($post['post_id']); ?>">#<?php echo h($post['post_id'])?></a>
|
||||
</span>
|
||||
<?php
|
||||
}
|
||||
if ($post['Post']['date_created'] != $post['Post']['date_modified']) {
|
||||
echo '<span style="font-style:italic">Message edited at ' . h($post['Post']['date_modified']) . '<span>';
|
||||
if ($post['date_created'] != $post['date_modified']) {
|
||||
echo '<span style="font-style:italic">Message edited at ' . h($post['date_modified']) . '<span>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
|
@ -82,24 +82,24 @@
|
|||
<table style="width:100%">
|
||||
<tr>
|
||||
<td>
|
||||
<?php echo h($post['User']['email']); ?>
|
||||
<?php echo !empty($post['user_email']) ? h($post['user_email']) : 'User ' . h($post['user_id']) . ' (' . (h($post['org_name'])) . ')'; ?>
|
||||
</td>
|
||||
<td style="text-align:right">
|
||||
<?php
|
||||
if (!$isSiteAdmin) {
|
||||
if ($post['Post']['user_id'] == $myuserid) {
|
||||
echo $this->Html->link('', array('controller' => 'posts', 'action' => 'edit', h($post['Post']['id']), h($context)), array('class' => 'icon-edit', 'title' => 'Edit'));
|
||||
echo $this->Form->postLink('', array('controller' => 'posts', 'action' => 'delete', h($post['Post']['id']), h($context)), array('class' => 'icon-trash', 'title' => 'Delete'), __('Are you sure you want to delete this post?'));
|
||||
if ($post['user_id'] == $myuserid) {
|
||||
echo $this->Html->link('', array('controller' => 'posts', 'action' => 'edit', h($post['id']), h($context)), array('class' => 'icon-edit', 'title' => 'Edit'));
|
||||
echo $this->Form->postLink('', array('controller' => 'posts', 'action' => 'delete', h($post['id']), h($context)), array('class' => 'icon-trash', 'title' => 'Delete'), __('Are you sure you want to delete this post?'));
|
||||
} else {
|
||||
?>
|
||||
<a href="<?php echo $baseurl.'/posts/add/post/'.h($post['Post']['id']); ?>" class="icon-comment" title = "Reply"></a>
|
||||
<a href="<?php echo $baseurl.'/posts/add/post/'.h($post['id']); ?>" class="icon-comment" title = "Reply"></a>
|
||||
<?php
|
||||
}
|
||||
} else {
|
||||
echo $this->Html->link('', array('controller' => 'posts', 'action' => 'edit', h($post['Post']['id']), h($context)), array('class' => 'icon-edit', 'title' => 'Edit'));
|
||||
echo $this->Form->postLink('', array('controller' => 'posts', 'action' => 'delete', h($post['Post']['id']), h($context)), array('class' => 'icon-trash', 'title' => 'Delete'), __('Are you sure you want to delete this post?'));
|
||||
echo $this->Html->link('', array('controller' => 'posts', 'action' => 'edit', h($post['id']), h($context)), array('class' => 'icon-edit', 'title' => 'Edit'));
|
||||
echo $this->Form->postLink('', array('controller' => 'posts', 'action' => 'delete', h($post['id']), h($context)), array('class' => 'icon-trash', 'title' => 'Delete'), __('Are you sure you want to delete this post?'));
|
||||
?>
|
||||
<a href = "<?php echo $baseurl.'/posts/add/post/'.h($post['Post']['id']); ?>" class="icon-comment" title = "Reply"></a>
|
||||
<a href = "<?php echo $baseurl.'/posts/add/post/'.h($post['id']); ?>" class="icon-comment" title = "Reply"></a>
|
||||
<?php
|
||||
|
||||
}
|
||||
|
@ -135,7 +135,7 @@
|
|||
<div class="comment">
|
||||
<?php
|
||||
if (isset($currentEvent)) $url = '/posts/add/event/' . $currentEvent;
|
||||
else $url = '/posts/add/thread/' . $thread_id;
|
||||
else $url = '/posts/add/thread/' . $thread['Thread']['id'];
|
||||
echo $this->Form->create('Post', array('url' => $url));
|
||||
?>
|
||||
<fieldset>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<div class="threads view">
|
||||
<h3><?php
|
||||
if (isset($event_id)) {
|
||||
echo '<a href="' . $baseurl . '/events/view/' . $event_id . '">' . h($thread_title) . '</a>';
|
||||
echo '<a href="' . $baseurl . '/events/view/' . $event_id . '">' . h($thread['Thread']['title']) . '</a>';
|
||||
} else {
|
||||
echo h($thread_title);
|
||||
echo h($thread['Thread']['title']);
|
||||
}
|
||||
?></h3>
|
||||
<?php
|
||||
|
|
Loading…
Reference in New Issue