diff --git a/app/Controller/EventsController.php b/app/Controller/EventsController.php index 723b5db78..30bf98097 100755 --- a/app/Controller/EventsController.php +++ b/app/Controller/EventsController.php @@ -1,7 +1,6 @@ set('allPivots', $this->Session->read('pivot_thread')); // Show the discussion $this->loadModel('Thread'); - $thread = $this->Thread->find('first', array('conditions' => array('event_id' => $id))); + $params = array('conditions' => array('event_id' => $id), + 'contain' => array( + 'Post' => array( + 'User', + ), + ) + ); + $thread = $this->Thread->find('first', $params); + if (empty($thread)) { + $thread['Post'] = array(); + } $this->set('posts', $thread['Post']); $this->set('myuserid', $this->Auth->user('id')); } diff --git a/app/Controller/PostsController.php b/app/Controller/PostsController.php new file mode 100644 index 000000000..71f7ae53c --- /dev/null +++ b/app/Controller/PostsController.php @@ -0,0 +1,261 @@ + 60, + ); + + public function beforeFilter() { + parent::beforeFilter(); + } + + // Find the thread_id and post_id in advance. If a user clicks post comment on the event view, send the event's related thread's ID + // Usage: + // /posts/add : Creates new thread with the added post as the first post. Title set by user + // /posts/add/event/id : Checks if the event already has a thread, if no it creates one. The post is added to the event's thread + // /posts/add/thread/id : Adds a post to the thread specified + // /posts/add/post/id : Adds a post as a reply to another post. The system finds the appropriate thread, adds the post to the thread and links to the post that is being replied to. + public function add($target_type = null, $target_id = null) { + $this->loadModel('Thread'); + $this->Thread->recursive = -1; + $distribution = 1; + $event_id = 0; + $post_id = 0; + // we have a target type and a target id. The target id defines what type of object we want to attach this event to (is it a reply to another post, + // did someone add a post to a thread, does a thread for the event exist already, etc. + switch ($target_type) { + case 'event' : + $this->loadModel('Event'); + $this->Event->recursive = -1; + $this->Event->read(null, $target_id); + $eventDiscussionTitle = 'Discussion about Event #' . $this->Event->data['Event']['id'] . ' (' . $this->Event->data['Event']['info'] . ')'; + if (!$this->Event->exists()) { + throw new NotFoundException(__('Invalid event')); + } + if (!$this->_isSiteAdmin()) { + if ($this->Event->data['Event']['distribution'] == 0 && $this->Event->data['Event']['org'] != $this->Auth->user('org')) { + throw new MethodNotAllowedException('You don\'t have permission to do that.'); + } + } + $thread = $this->Thread->find('first', array('conditions' => array('event_id' => $target_id))); + $title = $eventDiscussionTitle; + if (isset($thread['Thread']['id'])) { + $target_thread_id = $thread['Thread']['id']; + } else { + $target_thread_id = null; + } + $distribution = $this->Event->data['Event']['distribution']; + $org = $this->Event->data['Event']['org']; + break; + case 'thread' : + $target_thread_id = $target_id; + if ($target_id != null) { + $thread = $this->Thread->read(null, $target_thread_id); + if ($thread == null) { + throw new NotFoundException(__('Invalid thread')); + } + if (!$this->_isSiteAdmin()) { + if ($thread['Thread']['distribution'] == 0 && $this->Auth->user('org') != $thread['Thread']['org']) { + throw new MethodNotAllowedException('You don\'t have permission to do that.'); + } + } + $title = $this->Thread->data['Thread']['title']; + } + break; + case 'post' : + $this->Post->read(null, $target_id); + $target_thread_id = $this->Post->data['Post']['thread_id']; + $thread = $this->Thread->read(null, $target_thread_id); + if (!$this->_isSiteAdmin()) { + if ($thread['Thread']['distribution'] == 0 && $this->Auth->user('org') != $thread['Thread']['org']) { + throw new MethodNotAllowedException('You don\'t have permission to do that.'); + } + } + $title = $this->Thread->data['Thread']['title']; + $previousPost = $this->_grabPreviousPost($target_id); + $distribution = $previousPost['Thread']['distribution']; + $event_id = $previousPost['Thread']['event_id']; + $post_id = $target_id; + $target_thread_id = $previousPost['Thread']['id']; + break; + default: + $target_thread_id = null; + break; + } + + if ($this->request->is('post')) { + // Set the default values that we'll alter before actually saving data. These are the default values unless specifically modified. + // By default, all discussions will be visibile to everyone on the platform + $org = $this->Auth->user('org'); + // Set the title if it is setable in the add view. + if (empty($thread_id) && empty($target_type)) { + $title = $this->request->data['Post']['title']; + } + + if ($target_thread_id == null) { + // We have a post that was posted in a new thread. This could also mean that someone created the first post related to an event! + $this->Thread->create(); + // Take the title from above and the id of the event as event_id if we are adding a post to an event. + debug($this->request->data); + if ($target_type === 'event') { + $title = $eventDiscussionTitle; + $event_id = $this->Event->data['Event']['id']; + } + $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' => $event_id, + 'title' => $title, + 'distribution' => $distribution, + 'post_count' => 1, + 'org' => $org + ); + $this->Thread->save($newThread); + $target_thread_id = $this->Thread->getId(); + } else { + // In this case, we have a post that was posted in an already existing thread. Update the thread! + $this->Thread->read(null, $target_thread_id); + $this->Thread->data['Thread']['date_modified'] = date('Y/m/d h:i:s'); + $this->Thread->save(); + } + + + // Time to create our post! + $this->Post->create(); + $newPost = 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'), + 'contents' => $this->request->data['Post']['message'], + 'post_id' => $post_id, + 'thread_id' => $target_thread_id, + ); + if ($this->Post->save($newPost)) { + $this->Thread->recursive = 0; + $this->Thread->contain('Post'); + $this->Thread->read(null, $target_thread_id); + $this->Thread->updateAfterPostChange(true); + $this->Session->setFlash(__('Post added')); + $this->redirect(array('action' => 'view', $this->Post->getId())); + } else { + $this->Session->setFlash('The post could not be added.'); + } + } + if ($target_type === 'post') { + $this->set('previous', $previousPost['Post']['contents']); + } + $this->set('thread_id', $target_thread_id); + $this->set('target_type', $target_type); + $this->set('target_id', $target_id); + if (isset($title)) { + $this->set('title', $title); + } + } + + public function edit($post_id) { + $this->Post->id = $post_id; + if (!$this->Post->exists()) { + throw new NotFoundException(__('Invalid post')); + } + $this->Post->recursive = 1; + $this->Post->read(null, $post_id); + if (!$this->_isSiteAdmin() && $this->Auth->user('id') != $this->Post->data['Post']['user_id']) { + throw new MethodNotAllowedException('This is not your event.'); + } + if ($this->request->is('post') || $this->request->is('put')) { + $this->request->data['Post']['date_modified'] = date('Y/m/d h:i:s'); + $fieldList = array('date_modified', 'contents'); + if ($this->Post->save($this->request->data, true, $fieldList)) { + $this->Session->setFlash('Post edited'); + $this->loadModel('Thread'); + $this->Thread->recursive = 0; + $this->Thread->contain('Post'); + $this->Thread->read(null, $this->Post->data['Post']['thread_id']); + $this->Thread->updateAfterPostChange(); + $this->redirect(array('action' => 'view', $post_id)); + } else { + $this->Session->setFlash('The Post could not be edited. Please, try again.'); + } + } + $this->set('title', $this->Post->data['Thread']['title']); + $this->set('contents', $this->Post->data['Post']['contents']); + $this->set('id', $post_id); + } + + public function delete($post_id) { + if (!$this->request->is('post')) { + throw new MethodNotAllowedException(); + } + $this->Post->id = $post_id; + if (!$this->Post->exists()) { + throw new NotFoundException(__('Invalid post')); + } + $this->Post->read(); + $temp = $this->Post->data; + if ($this->Auth->user('id') != $this->Post->data['Post']['user_id'] && !$this->_isSiteAdmin()) { + throw new MethodNotAllowedException('This post doesn\'t belong to you, so you cannot delete it.'); + } + if ($this->Post->delete()) { + $this->loadModel('Thread'); + $this->Thread->recursive = 0; + $this->Thread->contain('Post'); + $this->Thread->read(null, $this->Post->data['Thread']['id']); + $thread = $this->Thread->data['Thread']['id']; + if (!$this->Thread->updateAfterPostChange()) { + $this->Session->setFlash('Post and thread deleted'); + $this->redirect(array('controller' => 'threads', 'action' => 'index')); + } else { + $this->Session->setFlash('Post deleted'); + } + } + $this->redirect(array('controller' => 'threads', 'action' => 'view', $thread)); + + } + + public function index($thread_id) { + $this->loadModel('Thread'); + $this->Thread->id = $thread_id; + if (!$this->Thread->exists()) { + throw new NotFoundException(__('Invalid thread')); + } + } + + // Views the proper context for the post + public function view($post_id) { + $this->Post->id = $post_id; + if (!$this->Post->exists()) { + throw new NotFoundException(__('Invalid post')); + } + $this->Post->read(); + // We don't know what the context was, so let's try to guess what the user wants to see! + // If the post belongs to an event's discussion thread, redirect the user to the event's view + if ($this->Post->data['Thread']['event_id'] != 0) { + $this->redirect(array('controller' => 'events', 'action' => 'view', $this->Post->data['Thread']['event_id'])); + } else { + //Otherwise send the user to the thread's index. + $this->redirect(array('controller' => 'threads', 'action' => 'view', $this->Post->data['Thread']['id'])); + } + } + + private function _grabPreviousPost($post_id) { + $this->Post->id = $post_id; + $this->Post->read(); + return $this->Post->data; + } + +} +?> + \ No newline at end of file diff --git a/app/Controller/ThreadsController.php b/app/Controller/ThreadsController.php new file mode 100644 index 000000000..f0fbe5c85 --- /dev/null +++ b/app/Controller/ThreadsController.php @@ -0,0 +1,76 @@ + 60, + ); + + public function beforeFilter() { + parent::beforeFilter(); + } + + + public function view($thread_id = null) { + if ($thread_id != null) { + $this->Thread->id = $thread_id; + if (!$this->Thread->exists()) { + throw new NotFoundException(__('Invalid thread')); + } + $params = array('conditions' => array('id' => $thread_id), + 'contain' => array( + 'Post' => array( + 'User', + ), + ) + ); + $thread = $this->Thread->find('first', $params); + $this->set('thread_id', $thread_id); + $this->set('posts', $thread['Post']); + $this->set('myuserid', $this->Auth->user('id')); + $this->set('context', 'threads'); + $this->set('thread_title', $thread['Thread']['title']); + } + } + + public function index() { + $conditions = null; + + //if (!$this->_isSiteAdmin()) { + $conditions['OR'] = array( + 'Thread.distribution >' => 0, + 'Thread.org' => $this->Auth->user('org'), + ); + //$conditions[] = array('Thread.event_id' => 0); + //} + $this->paginate = array( + 'conditions' => array($conditions), + 'fields' => array('date_modified', 'date_created', 'org', 'distribution', 'title', 'post_count'), + 'contain' => array( + 'Post' =>array( + 'fields' => array(), + 'User' => array( + 'fields' => array('email', 'org') + ) + ), + ), + 'order' => array('Thread.date_modified' => 'desc'), + 'recursive' => 1 + ); + $this->set('threads', $this->paginate()); + $this->loadModel('Event'); + $this->set('distributionLevels', $this->Event->distributionLevels); + } +} +?> diff --git a/app/Model/Post.php b/app/Model/Post.php new file mode 100644 index 000000000..6da910676 --- /dev/null +++ b/app/Model/Post.php @@ -0,0 +1,19 @@ + array( + 'fields' => array('email', 'org'), + + ) + ); +} diff --git a/app/Model/Thread.php b/app/Model/Thread.php new file mode 100644 index 000000000..dd0fe591c --- /dev/null +++ b/app/Model/Thread.php @@ -0,0 +1,29 @@ +data['Post']); + // If we have 0 posts left, delete the thread! + if ($count == 0) { + $this->delete(); + return false; + } else { + $this->data['Thread']['post_count'] = $count; + if ($add) { + $this->data['Thread']['date_modified'] = date('Y/m/d h:i:s'); + } + $this->save($this->data); + return true; + } + } +} diff --git a/app/Model/User.php b/app/Model/User.php index 487baf314..852c49d2d 100755 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -227,6 +227,8 @@ class User extends AppModel { 'exclusive' => '', 'finderQuery' => '', 'counterQuery' => '' + ), + 'Post' => array( ) ); diff --git a/app/View/Elements/eventdiscussion.ctp b/app/View/Elements/eventdiscussion.ctp new file mode 100644 index 000000000..bd8aac56d --- /dev/null +++ b/app/View/Elements/eventdiscussion.ctp @@ -0,0 +1,90 @@ +
+
+
+
|
+ |||
+ Html->image('orgs/' . h($post['User']['org']) . '.png', array('alt' => h($post['User']['org']), 'title' => h($post['User']['org']), 'style' => 'width:48px; height:48px')); + ?> + | +
+ Command->convertQuotes(nl2br(h($post['contents'])));
+ if ($post['post_id'] !=0 || ($post['date_created'] != $post['date_modified'])) {
+ ?>
+ + + + In reply to post + ># + + Message edited at ' . h($post['date_modified']) . ''; + } + ?> + |
+ ||
+ | +
Paginator->sort('org');?> | +Title | +Paginator->sort('date_modified', 'Last Post On');?> | +Last Post By | +Paginator->sort('date_created', 'Thread started On');?> | +Posts | +Distribution | +
---|---|---|---|---|---|---|
+ Html->image('orgs/' . h($thread['Thread']['org']) . '.png', array('alt' => h($thread['Thread']['org']), 'title' => h($thread['Thread']['org']), 'style' => 'width:24px; height:24px')); + else echo $this->Html->tag('span', h($thread['Thread']['org']), array('class' => 'welcome', 'style' => 'float:left;')); + ?> + + | ++ + | ++ + + | ++ + + | ++ + | ++ + | ++ + | +
+ Paginator->counter(array( + 'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}') + )); + ?> +
+