public function karmaAction() { foreach (Users::find() as $user) { if ($user->karma === null) { $parametersNumbersPost = array('users_id = ?0', 'bind' => array($user->id)); $numberPosts = Posts::count($parametersNumbersPost); $parametersNumberReplies = array('users_id = ?0', 'bind' => array($user->id)); $numberReplies = PostsReplies::count($parametersNumberReplies); $user->karma = $numberReplies * 10 + $numberPosts * 5; $user->votes = intval($user->karma / 50); $user->save(); } } }
/** * Allow to change your user settings */ public function settingsAction() { $usersId = $this->session->get('identity'); if (!$usersId) { $this->flashSession->error('You must be logged first'); return $this->response->redirect(); } $user = Users::findFirstById($usersId); if (!$user) { $this->flashSession->error('The user does not exist'); return $this->response->redirect(); } if ($this->request->isPost()) { if (!$this->checkTokenPost()) { return $this->response->redirect(); } $user->timezone = $this->request->getPost('timezone'); $user->notifications = $this->request->getPost('notifications'); $user->theme = $this->request->getPost('theme'); $user->digest = $this->request->getPost('digest'); if ($user->save()) { $this->session->set('identity-theme', $user->theme); $this->session->get('identity-timezone', $user->timezone); $this->flashSession->success('Settings were successfully updated'); return $this->response->redirect(); } } else { $this->tag->displayTo('timezone', $user->timezone); $this->tag->displayTo('notifications', $user->notifications); $this->tag->displayTo('theme', $user->theme); $this->tag->displayTo('digest', $user->digest); } $this->tag->setTitle('My Settings'); $this->tag->setAutoEscape(false); $this->view->user = $user; $this->view->timezones = (require APP_PATH . '/app/config/timezones.php'); $parametersNumberPosts = ['users_id = ?0 AND deleted = 0', 'bind' => [$user->id]]; $this->view->numberPosts = Posts::count($parametersNumberPosts); $parametersNumberReplies = ['users_id = ?0', 'bind' => [$user->id]]; $this->gravatar->setSize(64); $this->view->numberReplies = PostsReplies::count($parametersNumberReplies); }
/** * Accepts a reply as correct answer */ public function acceptAction($id = 0) { $response = new Response(); /** * Find the post using get */ $postReply = PostsReplies::findFirstById($id); if (!$postReply) { $contentNotExist = array('status' => 'error', 'message' => 'Post reply does not exist'); return $response->setJsonContent($contentNotExist); } $user = Users::findFirstById($this->session->get('identity')); if (!$user) { $contentLogIn = array('status' => 'error', 'message' => 'You must log in first to vote'); return $response->setJsonContent($contentLogIn); } if ($postReply->accepted == 'Y') { $contentAlready = array('status' => 'error', 'message' => 'This reply is already accepted as answer'); return $response->setJsonContent($contentAlready); } if ($postReply->post->deleted) { $contentDeleted = array('status' => 'error', 'message' => 'Post associated to the reply is deleted'); return $response->setJsonContent($contentDeleted); } if ($postReply->post->accepted_answer == 'Y') { $contentAlreadyAnswer = array('status' => 'error', 'message' => 'This post already has an accepted answer'); return $response->setJsonContent($contentAlreadyAnswer); } if ($postReply->post->users_id != $user->id && $user->moderator != 'Y') { $contentCorrect = array('status' => 'error', 'message' => 'You can\'t accept this answer as correct'); return $response->setJsonContent($contentCorrect); } if ($postReply->post->users_id != $postReply->users_id) { $postReply->post->user->karma += Karma::SOMEONE_ELSE_ACCEPT_YOUR_REPLY; $postReply->post->user->votes_points += Karma::SOMEONE_ELSE_ACCEPT_YOUR_REPLY; $points = 30 + intval(abs($user->karma - $postReply->user->karma) / 1000); $parametersBounty = array('users_id = ?0 AND posts_replies_id = ?1', 'bind' => array($postReply->users_id, $postReply->id)); $postBounty = PostsBounties::findFirst($parametersBounty); if ($postBounty) { $points += $postBounty->points; } $postReply->user->karma += $points; $postReply->user->votes_points += $points; if ($postReply->users_id != $user->id && $postReply->post->users_id != $user->id) { $user->karma += Karma::SOMEONE_ELSE_ACCEPT_YOUR_REPLY; $user->votes_points += Karma::SOMEONE_ELSE_ACCEPT_YOUR_REPLY; } } $postReply->accepted = 'Y'; $postReply->post->accepted_answer = 'Y'; if ($postReply->save()) { if (!$user->save()) { foreach ($user->getMessages() as $message) { $contentError = array('status' => 'error', 'message' => $message->getMessage()); return $response->setJsonContent($contentError); } } } if ($user->id != $postReply->users_id) { $activity = new ActivityNotifications(); $activity->users_id = $postReply->users_id; $activity->posts_id = $postReply->post->id; $activity->posts_replies_id = $postReply->id; $activity->users_origin_id = $user->id; $activity->type = 'A'; $activity->save(); } $contentOk = array('status' => 'OK'); return $response->setJsonContent($contentOk); }
/** * This implements an inbound webhook from MandrillApp to reply to posts using emails * */ public function mailReplyAction() { $response = new Response(); if ($this->request->isPost()) { if (!isset($this->config->mandrillapp->secret)) { return $response; } if ($this->config->mandrillapp->secret != $this->request->getQuery('secret')) { return $response; } $events = @json_decode($this->request->getPost('mandrill_events'), true); if (!is_array($events)) { return $response; } foreach ($events as $event) { if (!isset($event['event'])) { continue; } $type = $event['event']; if ($type != 'inbound') { continue; } if (!isset($event['msg'])) { continue; } $msg = $event['msg']; if (!isset($msg['dkim'])) { continue; } if (!isset($msg['from_email'])) { continue; } if (!isset($msg['email'])) { continue; } if (!isset($msg['text'])) { continue; } $content = $msg['text']; if (!trim($content)) { continue; } $user = Users::findFirstByEmail($msg['from_email']); if (!$user) { continue; } $email = $msg['email']; if (!preg_match('#^reply-i([0-9]+)-([0-9]+)@phosphorum.com$#', $email, $matches)) { continue; } $post = Posts::findFirst($matches[1]); if (!$post) { continue; } if ($post->deleted) { continue; } /** * Process replies to remove the base message */ $str = array(); $firstNoBaseReplyLine = false; foreach (array_reverse(preg_split('/\\r\\n|\\n/', trim($content))) as $line) { if (!$firstNoBaseReplyLine) { if (substr($line, 0, 1) == '>') { continue; } else { $firstNoBaseReplyLine = true; } } if (preg_match('/^[0-9]{4}\\-[0-9]{2}\\-[0-9]{2} [0-9]{2}:[0-9]{2} GMT([\\-\\+][0-9]{2}:[0-9]{2})? ([^:]*):$/u', $line)) { continue; } if (preg_match('/^On [A-Za-z]{3} [0-9]{1,2}, [0-9]{4} [0-9]{1,2}:[0-9]{2} [AP]M, ([^:]*):$/u', $line)) { continue; } $str[] = $line; } $content = join("\r\n", array_reverse($str)); /** * Check if the question can have a bounty before add the reply */ $canHaveBounty = $post->canHaveBounty(); /** * Only update the number of replies if the user that commented isn't the same that posted */ if ($post->users_id != $user->id) { $post->number_replies++; $post->modified_at = time(); $post->user->increaseKarma(Karma::SOMEONE_REPLIED_TO_MY_POST); $user->increaseKarma(Karma::REPLY_ON_SOMEONE_ELSE_POST); $user->save(); } $postReply = new PostsReplies(); $postReply->post = $post; $postReply->users_id = $user->id; $postReply->content = $content; if ($postReply->save()) { if ($post->users_id != $user->id && $canHaveBounty) { $bounty = $post->getBounty(); $postBounty = new PostsBounties(); $postBounty->posts_id = $post->id; $postBounty->users_id = $users->id; $postBounty->posts_replies_id = $postReply->id; $postBounty->points = $bounty['value']; if (!$postBounty->save()) { foreach ($postBounty->getMessages() as $message) { $this->flash->error($message); } } } } } } return $response; }
$option->title = htmlspecialchars($opt, ENT_QUOTES); if (!$option->save()) { echo join(PHP_EOL, $option->getMessages()), PHP_EOL; $database->rollback(); die; } $log->info('Option: ' . $option->title); } } $log->info('Post: ' . $post->title); } $database->commit(); $postIds = Posts::find(['columns' => 'id'])->toArray(); $database->begin(); for ($i = 0; $i <= 1000; $i++) { $reply = new PostsReplies(); $reply->content = $faker->paragraph(); $postRandId = array_rand($postIds); $reply->posts_id = $postIds[$postRandId]['id']; $userRandId = array_rand($userIds); $reply->users_id = $userIds[$userRandId]['id']; if (!$reply->save()) { $database->rollback(); die(join(PHP_EOL, $reply->getMessages())); } $reply->post->number_replies++; $reply->post->modified_at = time(); $reply->save(); $log->info('Reply to post: ' . $reply->posts_id); } $database->commit();
/** * Displays a post and its comments * * @param int $id Post ID * @param string $slug Post slug [Optional] */ public function viewAction($id, $slug = '') { $id = (int) $id; // Check read / unread topic if ($usersId = $this->session->get('identity')) { $check_topic = new TopicTracking(); $check_topic->user_id = $usersId; $check_topic->topic_id = $id; if ($check_topic->create() == false) { $check_topic->updateTracking($id, $usersId); } } $this->gravatar->setSize(48); if (!$this->request->isPost()) { // Find the post using get if (!($post = Posts::findFirstById($id))) { $this->flashSession->error('The discussion does not exist'); $this->response->redirect(); return; } if ($post->deleted) { $this->flashSession->error('The discussion is deleted'); $this->response->redirect(); return; } $ipAddress = $this->request->getClientAddress(); $parameters = ['posts_id = ?0 AND ipaddress = ?1', 'bind' => [$id, $ipAddress]]; // A view is stored by ip address if (!($viewed = PostsViews::count($parameters))) { // Increase the number of views in the post $post->number_views++; if ($post->users_id != $usersId) { $post->user->increaseKarma(Karma::VISIT_ON_MY_POST); if ($user = Users::findFirstById($usersId)) { $user->increaseKarma($user->moderator == 'Y' ? Karma::MODERATE_VISIT_POST : Karma::VISIT_POST); $user->save(); } } $postView = new PostsViews(); $postView->post = $post; $postView->ipaddress = $ipAddress; if (!$postView->save()) { $this->flash->error(join('<br>', $postView->getMessages())); } } if (!$usersId) { // Enable cache $this->view->cache(['key' => 'post-' . $id]); // Check for a cache if ($this->viewCache->exists('post-' . $id)) { return; } } // Generate canonical meta $this->view->setVars(['canonical' => "discussion/{$post->id}/{$post->slug}", 'author' => $post->user]); } else { if (!$this->checkTokenPost()) { $this->response->redirect(); return; } if (!$usersId) { $this->flashSession->error('You must be logged in first to add a comment'); $this->response->redirect(); return; } // Find the post using POST if (!($post = Posts::findFirstById($this->request->getPost('id')))) { $this->flashSession->error('The discussion does not exist'); $this->response->redirect(); return; } if ($post->deleted) { $this->flashSession->error('The discussion is deleted'); $this->response->redirect(); return; } if ($content = $this->request->getPost('content', 'trim')) { // Check if the question can have a bounty before add the reply $canHaveBounty = $post->canHaveBounty(); if (!($user = Users::findFirstById($usersId))) { $this->flashSession->error('You must be logged in first to add a comment'); $this->response->redirect(); return; } // Only update the number of replies if the user that commented isn't the same that posted if ($post->users_id != $usersId) { $post->number_replies++; $post->modified_at = time(); $post->user->increaseKarma(Karma::SOMEONE_REPLIED_TO_MY_POST); $user->increaseKarma(Karma::REPLY_ON_SOMEONE_ELSE_POST); $user->save(); } $postReply = new PostsReplies(); $postReply->post = $post; $postReply->in_reply_to_id = $this->request->getPost('reply-id', 'int'); $postReply->users_id = $usersId; $postReply->content = $content; if ($postReply->save()) { if ($post->users_id != $usersId && $canHaveBounty) { $bounty = $post->getBounty(); $postBounty = new PostsBounties(); $postBounty->posts_id = $post->id; $postBounty->users_id = $usersId; $postBounty->posts_replies_id = $postReply->id; $postBounty->points = $bounty['value']; if (!$postBounty->save()) { $this->flash->error(join('<br>', $postBounty->getMessages())); } } $this->response->redirect("discussion/{$post->id}/{$post->slug}#C{$postReply->id}"); return; } $this->flash->error(join('<br>', $postReply->getMessages())); } } $voting = []; if ($post->hasPoll()) { $totalVotes = $post->getPollVotes()->count(); $votesCount = PostsPollVotes::count(['posts_id = ?0', 'group' => 'options_id', 'bind' => [$post->id]]); foreach ($votesCount as $row) { /** @var \Phalcon\Mvc\Model\Row $row */ $voting[$row->offsetGet('options_id')] = round($row->offsetGet('rowcount') * 100 / $totalVotes, 1); } } // Set the post name as title - escaping it first $this->tag->setTitle($this->escaper->escapeHtml($post->title) . ' - Discussion'); $this->view->setVars(['post' => $post, 'voted' => $post->isParticipatedInPoll($usersId), 'voting' => $voting]); }
/** * Allow to change your user settings */ public function settingsAction() { $usersId = $this->session->get('identity'); if (!$usersId) { $this->flashSession->error('You must be logged first'); $this->response->redirect(); return; } $user = Users::findFirstById($usersId); if (!$user) { $this->flashSession->error('The user does not exist'); $this->response->redirect(); return; } if ($this->request->isPost()) { if (!$this->checkTokenPost('settings')) { $this->response->redirect(); return; } $user->timezone = $this->request->getPost('timezone'); $user->notifications = $this->request->getPost('notifications'); $user->theme = $this->request->getPost('theme'); $user->digest = $this->request->getPost('digest'); if ($user->save()) { $this->session->set('identity-theme', $user->theme); $this->session->get('identity-timezone', $user->timezone); $this->flashSession->success('Settings were successfully updated'); $this->response->redirect(); return; } } else { $this->tag->displayTo('timezone', $user->timezone); $this->tag->displayTo('notifications', $user->notifications); $this->tag->displayTo('theme', $user->theme); $this->tag->displayTo('digest', $user->digest); } $this->tag->setTitle('My Settings'); $this->tag->setAutoescape(false); $this->view->setVars(['avatar' => $this->gravatar->getAvatar($user->email), 'user' => $user, 'subscribed' => $user->digest == 'Y', 'timezones' => $this->di->getShared('timezones'), 'numberPosts' => Posts::count(['users_id = ?0 AND deleted = 0', 'bind' => [$user->id]]), 'numberReplies' => PostsReplies::count(['users_id = ?0', 'bind' => [$user->id]])]); }