/**
  * Adds a post to the database
  * @param Request $request The request object
  */
 public function add($request)
 {
     // The topic id that this post belongs to
     $topic_id = (int) $request->get('topicId');
     $response = new Response();
     // Should never happen legit but just incase
     if (!$topic_id) {
         $response->setStatusCode(400);
         $response->setContent($this->app->trans('UNKNOWN_ERROR'));
         return $response;
     }
     // Get the topic so we can use it later
     $topic = $this->app['topic']->findById($topic_id);
     $forum = $this->app['forum']->findById($topic['forum']);
     if (!$forum) {
         return new Response($this->app->trans('UNKNOWN_ERROR'), 500);
     }
     // get the logged in user
     // @todo make a wrapper for this
     $user = $this->app['session']->get('user');
     if (!$user) {
         $response->setStatusCode(400);
         $response->setContent($this->app->trans('MUST_BE_LOGGED_IN'));
         return $response;
     }
     // Should never happen legit but just incase
     if (!$topic) {
         return new Response($this->app->trans('UNKNOWN_ERROR'), 500);
     }
     // If the topic is locked and user cannot bypass it
     if ($topic['locked'] && !\ASF\Permissions::hasPermission('BYPASS_RESTRICTIONS')) {
         $response->setStatusCode(400);
         $response->setContent($this->app->trans('TOPIC_LOCKED'));
         return $response;
     }
     if (!\ASF\Permissions::hasPermission('CREATE_POST')) {
         $response->setStatusCode(400);
         $response->setContent($this->app->trans('NO_PERMISSION'));
         return $response;
     }
     $name = $request->get('name');
     $content = $request->get('reply');
     $attachments = $request->files->get('attachments');
     if ($attachments[0] != null) {
         if (count($attachments) > 5) {
             $response->setStatusCode(400);
             $response->setContent($this->app->trans('TOO_MANY_ATTACHMENTS'));
             return $response;
         }
         foreach ($attachments as $attachment) {
             $attachment_name = $attachment->getClientOriginalName();
             $size = $attachment->getClientSize();
             $mime = $attachment->getClientMimeType();
             if ($size >= $this->app['files']['maxSize']) {
                 $response->setStatusCode(400);
                 $response->setContent($this->app->trans('FILE_TOO_BIG', array($attachment_name, $this->app['files']['maxSize'] / 1024)));
                 return $response;
             }
             $ext = pathinfo($attachment_name, PATHINFO_EXTENSION);
             if (!in_array($ext, $this->app['files']['types'])) {
                 $response->setStatusCode(400);
                 $response->setContent($this->app->trans('INVALID_FILE_EXT', array($ext, implode(', ', $this->app['files']['types']))));
                 return $response;
             }
         }
     }
     $constraints = new Assert\Collection(array('name' => array(new Assert\NotBlank(array('message' => 'FILL_ALL_FIELDS')), new Assert\Length(array('min' => 6, 'max' => 50, 'minMessage' => $this->app->trans('MIN_LENGTH', array('%field%' => 'body', '%min%' => 6)), 'maxMessage' => $this->app->trans('MAX_LENGTH', array('%field%' => 'title', '%max%' => 25))))), 'content' => array(new Assert\NotBlank(array('message' => 'FILL_ALL_FIELDS')), new Assert\Length(array('min' => 6, 'minMessage' => $this->app->trans('MIN_LENGTH', array('%field%' => 'body', '%min%' => 6)))))));
     // Temp variable which removes html to check actual length
     $content_string_test = strip_tags($content);
     $data = array('name' => $name, 'content' => $content_string_test);
     $errors = $this->app['validator']->validateValue($data, $constraints);
     if (count($errors) > 0) {
         $response->setStatusCode(400);
         $response->setContent($this->app->trans($errors[0]->getMessage()));
         return $response;
     }
     $content = strip_tags($content, implode(',', $this->allowed_html));
     $content = str_replace('href=', 'target="_blank" rel="nofollow" href=', $content);
     $time = date('Y-m-d H:i:s');
     $last = $this->app['db']->fetchAssoc('SELECT * FROM posts WHERE topic=? ORDER BY added DESC LIMIT 1', array($topic_id));
     if ($last['author'] == $user['id']) {
         if ($this->app['board']['doublePost'] === 'merge') {
             preg_match('/<div class="update">(.*)<\\/div>/s', $last['content'], $matches);
             if (count($matches) > 0) {
                 $content = preg_replace('/<div class="update">(.*)<\\/div>/s', '<div class="update">' . "\n" . '$1' . "\n" . $content . '</div>', $last['content']);
             } else {
                 $content = $last['content'] . '<div class="update"><h2>Update</h2>' . "\n" . $content . '</div>';
             }
             $this->app['db']->update('posts', array('content' => $content, 'updated' => $time), array('id' => $last['id']));
             $this->app['db']->update('topics', array('updated' => $time), array('id' => $last['topic']));
             $this->app['db']->update('forums', array('lastTopicId' => $topic['id'], 'lastAuthorId' => $user['id'], 'lastPostTime' => $time, 'lastPostId' => $last['id']), array('id' => $last['forum']));
             $files = [];
             // Upload attachments
             if ($attachments[0] != null) {
                 foreach ($attachments as $attachment) {
                     $attachment_name = $attachment->getClientOriginalName();
                     $file_name = time() . '-' . $attachment_name;
                     try {
                         $attachment->move($upload_dir, $file_name);
                     } catch (\Exception $e) {
                         $response->setStatusCode(500);
                         $response->setContent($this->app->trans('COULDNT_UPLOAD_FILE', array($attachment_name)));
                         return $response;
                     }
                     $this->app['db']->insert('attachments', array('post_id' => $last['id'], 'name' => $attachment_name, 'file_name' => $file_name, 'size' => $attachment->getClientSize(), 'mime' => $attachment->getClientMimeType(), 'added' => $time));
                     $files[] = array('name' => $attachment_name, 'size' => $attachment->getClientSize(), 'mime' => $attachment->getClientMimeType());
                 }
             }
             $response->setContent(json_encode(array('id' => $last['id'], 'content' => $content, 'updated' => true, 'attachments' => json_encode($files))));
             return $response;
         } else {
             if ($this->app['board']['doublePost'] === 'disallow') {
                 $response->setStatusCode(400);
                 $response->setContent($this->app->trans('NO_DOUBLE_POST'));
                 return $response;
             }
         }
     }
     // Format mentions
     $mentions = $this->parseMentions($content);
     if ($mentions['has_mentions']) {
         $content = $mentions['content'];
     }
     $this->app['db']->insert('posts', array('topic' => $topic['id'], 'forum' => $topic['forum'], 'name' => $name, 'content' => $content, 'author' => $user['id'], 'added' => $time, 'updated' => $time));
     $post_id = $this->app['db']->lastInsertId();
     $post_url = '/' . $this->app['board']['base'] . urlencode($forum['name']) . '/' . urlencode($topic['name']) . '-' . $topic['id'] . '/#' . $post_id;
     if ($mentions['has_mentions']) {
         $content = $mentions['content'];
         foreach ($mentions['users'] as $mention) {
             $this->app['notification']->add(new Request(['user_id' => $mention['data']['id'], 'notification' => '<a href="/' . $this->app['board']['base'] . 'user/' . $user['username'] . '/" class="user-link">' . $user['username'] . '</a> mentioned you in a <a href="' . $post_url . '">post</a>']));
         }
     }
     // Upload attachments
     if ($attachments[0] != null) {
         $upload_dir = dirname(dirname(__DIR__)) . '/public/uploads/attachments';
         foreach ($attachments as $attachment) {
             $attachment_name = $attachment->getClientOriginalName();
             $file_name = time() . '-' . $attachment_name;
             $attachment->move($upload_dir, $file_name);
             if ($attachment->getError()) {
                 // Couldnt upload attachment, delete post
                 $this->app['db']->delete('posts', array('id' => $post_id));
                 $response->setStatusCode(500);
                 $response->setContent($this->app->trans('COULDNT_UPLOAD_FILE', array($attachment_name)));
                 return $response;
             }
             $this->app['db']->insert('attachments', array('post_id' => $post_id, 'name' => $attachment_name, 'file_name' => $file_name, 'size' => $attachment->getClientSize(), 'mime' => $attachment->getClientMimeType(), 'added' => time()));
         }
     }
     $this->app['db']->update('topics', array('replies' => $topic['replies'] + 1, 'updated' => $time, 'lastAuthorId' => $user['id'], 'lastPostId' => $post_id), array('id' => $topic_id));
     $this->app['db']->executeQuery('UPDATE forums SET posts=posts+1, lastTopicId=?,lastAuthorId=?, lastPostTime=?, lastPostId=? WHERE id=? LIMIT 1', array($topic['id'], $user['id'], $time, $post_id, $topic['forum']));
     $post_count = $this->app['db']->fetchColumn('SELECT COUNT(id) FROM posts WHERE topic=?', array($topic_id));
     $this->app['cache']->collection = $this->app['cache']->setCollection($this->app['database']['name'], 'posts');
     $this->app['cache']->delete_group('topic-post-count-' . $topic_id);
     $this->app['cache']->delete_group('topic-posts-' . $topic_id);
     $this->app['cache']->collection = $this->app['cache']->setCollection($this->app['database']['name'], 'forums');
     $this->app['cache']->delete_group('forum-' . $topic['forum']);
     $this->app['cache']->collection = $this->app['cache']->setCollection($this->app['database']['name'], 'topics');
     $this->app['cache']->delete('topic-' . $topic_id);
     $page = (int) ceil($post_count / $this->app['board']['postsPerPage']);
     $this->app['db']->executeQuery('UPDATE users SET posts=posts+1 WHERE id=? LIMIT 1', array($user['id']));
     return json_encode(array('id' => $post_id, 'username' => $user['username'], 'userId' => $user['id'], 'userGroup' => $user['group']['name'], 'userPosts' => $user['posts'], 'page' => $page));
 }
 public function deleteComment(Request $request)
 {
     $comment_id = (int) $request->get('commentId');
     $response = new Response();
     if (!$comment_id) {
         $response->setStatusCode(500);
         $response->setContent($this->app->trans('UNKNOWN_ERROR'));
         return $response;
     }
     $comment = $this->app['db']->fetchAssoc('SELECT * FROM profile_comments WHERE id=? LIMIT 1', array($comment_id));
     if (!$comment) {
         $response->setStatusCode(500);
         $response->setContent($this->app->trans('MUST_BE_LOGGED_IN'));
         return $response;
     }
     $user = $this->app['session']->get('user');
     if (!$user) {
         $response->setStatusCode(500);
         $response->setContent($this->app->trans('MUST_BE_LOGGED_IN'));
         return $response;
     }
     if ($user['id'] != $comment['author'] && !\ASF\Permissions::hasPermission('EDIT_POSTS')) {
         $response->setStatusCode(500);
         $response->setContent($this->app->trans('NO_PERMISSION'));
         return $response;
     }
     $this->app['db']->update('profile_comments', array('deleted' => 1), array('id' => $comment_id));
     $this->app['cache']->collection = $this->app['cache']->setCollection($this->app['database']['name'], 'profiles');
     $this->app['cache']->delete('profile-comment-' . $comment_id);
     $this->app['cache']->delete_group('profile-comments-' . $comment['profile']);
     return true;
 }
 public function addTopic(Request $request)
 {
     $user = $this->app['session']->get('user');
     $response = new Response();
     if (!$user) {
         $response->setStatusCode(400);
         $response->setContent($this->app->trans('MUST_BE_LOGGED_IN'));
         return $response;
     }
     if (!\ASF\Permissions::hasPermission('CREATE_TOPIC')) {
         $response->setStatusCode(400);
         $response->setContent($this->app->trans('NO_PERMISSION'));
         return $response;
     }
     $forum_id = (int) $request->get('forumId');
     if (!$forum_id) {
         $response->setStatusCode(500);
         $response->setContent($this->app->trans('UNKNOWN_ERROR'));
         return $response;
     }
     $forum = $this->app['forum']->findById($forum_id);
     if (!$forum) {
         $response->setStatusCode(500);
         $response->setContent($this->app->trans('UNKNOWN_ERROR'));
         return $response;
     }
     $name = $request->get('title');
     $content = $request->get('content');
     $locked = $request->get('locked');
     $sticky = $request->get('sticky');
     if (!$locked) {
         $locked = 0;
     }
     if (!$sticky) {
         $sticky = 0;
     }
     if (!$name || !$content) {
         $response->setStatusCode(400);
         $response->setContent($this->app->trans('FILL_ALL_FIELDS'));
         return $response;
     }
     $name = strip_tags($name);
     $content = strip_tags($content, implode(',', $this->allowed_html));
     $attachments = $request->files->get('attachments');
     if ($attachments[0] != null) {
         if (count($attachments) > 5) {
             $response->setStatusCode(400);
             $response->setContent($this->app->trans('TOO_MANY_ATTACHMENTS'));
             return $response;
         }
         foreach ($attachments as $attachment) {
             $attachment_name = $attachment->getClientOriginalName();
             $size = $attachment->getClientSize();
             $mime = $attachment->getClientMimeType();
             if ($size >= $this->app['files']['maxSize']) {
                 $response->setStatusCode(400);
                 $response->setContent($this->app->trans('FILE_TOO_BIG', array($attachment_name, $this->app['files']['maxSize'] / 1024)));
                 return $response;
             }
             $ext = pathinfo($attachment_name, PATHINFO_EXTENSION);
             if (!in_array($ext, $this->app['files']['types'])) {
                 $response->setStatusCode(400);
                 $response->setContent($this->app->trans('INVALID_FILE_EXT', array($ext, implode(', ', $this->app['files']['types']))));
                 return $response;
             }
         }
     }
     if (!\ASF\Permissions::hasPermission('BYPASS_RESTRICTIONS')) {
         $user_last = $this->app['db']->fetchAssoc('SELECT forum, added FROM topics WHERE author=? AND forum=? ORDER BY added DESC LIMIT 1', array($user['id'], $forum_id));
         $time_since_last = time() - (int) $user_last['added'];
         if ($time_since_last < 300) {
             $seconds = 300 - $time_since_last;
             $minutes = round($seconds / 60);
             $seconds = $seconds % 60;
             $response->setStatusCode(403);
             $response->setContent($this->app->trans('TOPIC_POST_LIMIT', array($minutes, $seconds)));
             return $response;
         }
     }
     $time = date('Y-m-d H:i:s');
     $this->app['db']->insert('topics', array('forum' => $forum_id, 'name' => $name, 'author' => $user['id'], 'locked' => $locked, 'sticky' => $sticky, 'added' => $time, 'updated' => $time, 'lastPostId' => 0, 'lastAuthorId' => $user['id']));
     $topic_id = $this->app['db']->lastInsertId();
     // Format mentions
     $mentions = $this->app['post']->parseMentions($content);
     if ($mentions['has_mentions']) {
         $content = $mentions['content'];
     }
     $this->app['db']->insert('posts', array('topic' => $topic_id, 'forum' => $forum_id, 'name' => $name, 'content' => $content, 'author' => $user['id'], 'added' => $time, 'updated' => $time));
     $post_id = $this->app['db']->lastInsertId();
     $post_url = '/' . $this->app['board']['base'] . urlencode($forum['name']) . '/' . urlencode($name) . '-' . $topic_id . '/#' . $post_id;
     if ($mentions['has_mentions']) {
         $content = $mentions['content'];
         foreach ($mentions['users'] as $mention) {
             $this->app['notification']->add(new Request(['user_id' => $mention['data']['id'], 'notification' => '<a href="/' . $this->app['board']['base'] . 'user/' . $user['username'] . '/" class="user-link">' . $user['username'] . '</a> mentioned you in a <a href="' . $post_url . '">post</a>']));
         }
     }
     // Upload attachments
     if ($attachments[0] != null) {
         $upload_dir = dirname(dirname(__DIR__)) . '/public/uploads/attachments';
         foreach ($attachments as $attachment) {
             $attachment_name = $attachment->getClientOriginalName();
             $file_name = time() . '-' . $attachment_name;
             $attachment->move($upload_dir, $file_name);
             if ($attachment->getError()) {
                 // Couldnt upload attachment, delete post
                 $this->app['db']->delete('posts', array('id' => $post_id));
                 $response->setStatusCode(500);
                 $response->setContent($this->app->trans('COULDNT_UPLOAD_FILE', array($attachment_name)));
                 return $response;
             }
             $this->app['db']->insert('attachments', array('post_id' => $post_id, 'name' => $attachment_name, 'file_name' => $file_name, 'size' => $attachment->getClientSize(), 'mime' => $attachment->getClientMimeType(), 'added' => time()));
         }
     }
     $this->app['db']->update('topics', array('lastPostId' => $post_id), array('id' => $topic_id));
     $this->app['db']->executeQuery('UPDATE forums SET topics=topics+1, posts=posts+1, lastTopicId=?, lastAuthorId=?, lastPostTime=?, lastPostId=?, updated=? WHERE id=? LIMIT 1', array($topic_id, $user['id'], $time, $post_id, $time, $forum_id));
     $this->app['db']->executeQuery('UPDATE users SET topics=topics+1, posts=posts+1 WHERE id=? LIMIT 1', array($user['id']));
     $this->app['cache']->collection = $this->collection;
     $this->app['cache']->delete_group('topics-recent');
     $this->app['cache']->delete_group('topics-forum-' . $forum_id);
     $this->app['cache']->setCollection($this->app['database']['name'], 'forums');
     $this->app['cache']->delete('forum-' . $forum_id);
     $this->app['cache']->delete('forums.all');
     return json_encode(array('id' => $topic_id, 'topic_id' => $topic_id, 'post_id' => $post_id, 'content' => $content, 'author' => $user['username'], 'forum_name' => $forum['name'], 'locked' => $locked, 'sticky' => $sticky));
 }