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 hours
pull/1886/head
iglocska 2017-02-01 15:32:22 +01:00
parent 91209dde66
commit ee80ecfce7
7 changed files with 140 additions and 89 deletions

View File

@ -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);
}

View File

@ -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');

View File

@ -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']) {

View File

@ -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.',

View File

@ -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']) : ''; ?>&nbsp;
</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>&nbsp;
</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']); ?>&nbsp;

View File

@ -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>

View File

@ -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