public function getExpertQuery(Users $user) { if (!$this->query) { $this->query = $user->getModelsManager()->createBuilder()->columns(['p.categories_id', 'COUNT(*)'])->from(['r' => 'Phosphorum\\Models\\PostsReplies'])->join('Phosphorum\\Models\\Posts', null, 'p')->where('r.users_id = ?0 AND r.accepted = "Y"')->notInWhere('p.categories_id', $this->getNoBountyCategories())->groupBy('p.categories_id')->having('COUNT(*) >= 10')->getQuery(); } return $this->query; }
/** * Check whether the user can have the badge * * @param Users $user * @return boolean */ public function canHave(Users $user) { $noBountyCategories = $this->getNoBountyCategories(); $conditions = 'categories_id NOT IN (' . join(', ', $noBountyCategories) . ') AND accepted_answer = "Y"'; $posts = $user->getPosts(array($conditions, 'order' => 'created_at DESC')); foreach ($posts as $post) { $ownReply = $post->countReplies(array("accepted = 'Y' AND users_id = ?0", 'bind' => array($user->id))); if ($ownReply) { return true; } } return false; }
/** * Check whether the user can have the badge * * @param Users $user * @return boolean */ public function canHave(Users $user) { $ids = []; $noBountyCategories = $this->getNoBountyCategories(); $conditions = 'categories_id NOT IN (' . join(', ', $noBountyCategories) . ') AND number_views >= 10000'; $posts = $user->getPosts([$conditions, 'columns' => 'id', 'order' => 'created_at DESC']); foreach ($posts as $post) { $have = UsersBadges::count(['users_id = ?0 AND badge = ?1 AND type = "P" AND code1 = ?2', 'bind' => [$user->id, $this->getName(), $post->id]]); if (!$have) { $ids[] = $post->id; } } return $ids; }
/** * Check whether the user can have the badge * * @param Users $user * @return boolean */ public function canHave(Users $user) { $ids = []; $noBountyCategories = $this->getNoBountyCategories(); $conditions = '(IF(votes_up IS NULL, 0, votes_up) - IF(votes_down IS NULL, 0, votes_down)) >= 5'; $replies = $user->getReplies([$conditions, 'columns' => 'id, posts_id', 'order' => 'created_at DESC']); foreach ($replies as $reply) { $have = UsersBadges::count(['users_id = ?0 AND badge = ?1 AND type = "C" AND code1 = ?2', 'bind' => [$user->id, $this->getName(), $reply->id]]); if (!$have) { $ids[] = [$reply->posts_id, $reply->id]; } } return $ids; }
/** * Check whether the user can have the badge * * @param Users $user * @return boolean */ public function canHave(Users $user) { $ids = array(); $noBountyCategories = $this->getNoBountyCategories(); $conditions = 'categories_id NOT IN (' . join(', ', $noBountyCategories) . ') AND (IF(votes_up IS NULL, 0, votes_up) - IF(votes_down IS NULL, 0, votes_down)) >= 5'; $posts = $user->getPosts(array($conditions, 'columns' => 'id', 'order' => 'created_at DESC')); foreach ($posts as $post) { $have = UsersBadges::count(array('users_id = ?0 AND badge = ?1 AND type = "P" AND code1 = ?2', 'bind' => array($user->id, $this->getName(), $post->id))); if (!$have) { $ids[] = $post->id; } } return $ids; }
/** * Process users badges */ public function process() { $badges = $this->getBadges(); foreach (Users::find() as $user) { $this->processUserBadges($user, $badges); } }
/** * Sends the digest */ public function send() { $lastMonths = new \DateTime(); $lastMonths->modify('-6 month'); $parameters = array('modified_at >= ?0 AND digest = "Y" AND notifications <> "N"', 'bind' => array($lastMonths->getTimestamp())); $users = array(); foreach (Users::find($parameters) as $user) { if ($user->email && strpos($user->email, '@') !== false && strpos($user->email, '@users.noreply.github.com') === false) { $users[trim($user->email)] = $user->name; } } $fromName = $this->config->mail->fromName; $fromEmail = $this->config->mail->fromEmail; $url = $this->config->site->url; $subject = 'Top Stories from Phosphorum ' . date('d/m/y'); $lastWeek = new \DateTime(); $lastWeek->modify('-1 week'); $order = 'number_views + ' . '((IF(votes_up IS NOT NULL, votes_up, 0) - ' . 'IF(votes_down IS NOT NULL, votes_down, 0)) * 4) + ' . 'number_replies + IF(accepted_answer = "Y", 10, 0) DESC'; $parameters = array('created_at >= ?0 AND deleted != 1 AND categories_id <> 4', 'bind' => array($lastWeek->getTimestamp()), 'order' => $order, 'limit' => 10); $e = $this->escaper; $content = '<html><head></head><body><p><h1 style="font-size:22px;color:#333;letter-spacing:-0.5px;line-height:1.25;font-weight:normal;padding:16px 0;border-bottom:1px solid #e2e2e2">Top Stories from Phosphorum</h1></p>'; foreach (Posts::find($parameters) as $post) { $user = $post->user; if ($user == false) { continue; } $content .= '<p><a style="text-decoration:none;display:block;font-size:20px;color:#333;letter-spacing:-0.5px;line-height:1.25;font-weight:normal;color:#155fad" href="' . $url . '/discussion/' . $post->id . '/' . $post->slug . '">' . $e->escapeHtml($post->title) . '</a></p>'; $content .= '<p><table width="100%"><td><table><tr><td>' . '<img src="https://secure.gravatar.com/avatar/' . $user->gravatar_id . '?s=32&r=pg&d=identicon" width="32" height="32" alt="' . $user->name . ' icon">' . '</td><td><a style="text-decoration:none;color:#155fad" href="' . $url . '/user/' . $user->id . '/' . $user->login . '">' . $user->name . '<br><span style="text-decoration:none;color:#999;text-decoration:none">' . $user->getHumanKarma() . '</span></a></td></tr></table></td><td align="right"><table style="border: 1px solid #dadada;" cellspacing=5>' . '<td align="center"><label style="color:#999;margin:0px;font-weight:normal;">Created</label><br>' . $post->getHumanCreatedAt() . '</td>' . '<td align="center"><label style="color:#999;margin:0px;font-weight:normal;">Replies</label><br>' . $post->number_replies . '</td>' . '<td align="center"><label style="color:#999;margin:0px;font-weight:normal;">Views</label><br>' . $post->number_views . '</td>' . '<td align="center"><label style="color:#999;margin:0px;font-weight:normal;">Votes</label><br>' . ($post->votes_up - $post->votes_down) . '</td>' . '</tr></table></td></tr></table></p>'; $content .= $this->markdown->render($e->escapeHtml($post->content)); $content .= '<p><a style="color:#155fad" href="' . $url . '/discussion/' . $post->id . '/' . $post->slug . '">Read more</a></p>'; $content .= '<hr style="border: 1px solid #dadada">'; } $textContent = strip_tags($content); $htmlContent = $content . '<p style="font-size:small;-webkit-text-size-adjust:none;color:#717171;">'; $htmlContent .= PHP_EOL . 'This email was sent by Phalcon Framework. Change your e-mail preferences <a href="' . $url . '/settings">here</a></p>'; foreach ($users as $email => $name) { try { $message = new \Swift_Message('[Phalcon Forum] ' . $subject); $message->setTo(array($email => $name)); $message->setFrom(array($fromEmail => $fromName)); $bodyMessage = new \Swift_MimePart($htmlContent, 'text/html'); $bodyMessage->setCharset('UTF-8'); $message->attach($bodyMessage); $bodyMessage = new \Swift_MimePart($textContent, 'text/plain'); $bodyMessage->setCharset('UTF-8'); $message->attach($bodyMessage); if (!$this->transport) { $this->transport = \Swift_SmtpTransport::newInstance($this->config->smtp->host, $this->config->smtp->port, $this->config->smtp->security); $this->transport->setUsername($this->config->smtp->username); $this->transport->setPassword($this->config->smtp->password); } if (!$this->mailer) { $this->mailer = \Swift_Mailer::newInstance($this->transport); } $this->mailer->send($message); } catch (\Exception $e) { echo $e->getMessage(), PHP_EOL; } } }
public function onConstruct() { $lastThreads = $this->modelsManager->createBuilder()->from(['p' => 'Phosphorum\\Models\\Posts'])->groupBy("p.id")->join('Phosphorum\\Models\\Categories', "r.id = p.categories_id", 'r')->join('Phosphorum\\Models\\Users', "u.id = p.users_id", 'u')->columns(['p.title as title_post', 'p.id as id_post', 'p.slug as slug_post', 'r.name as name_category', 'u.name as name_user'])->where('p.deleted = 0')->orderBy('p.created_at DESC')->limit(3)->getQuery()->execute(); /** @var Simple $lastMember */ $lastMember = Users::find(['order' => 'created_at DESC', 'limit' => 1, 'columns' => 'login']); $login = null; if ($lastMember->valid()) { $login = $lastMember->getFirst()->login; } $this->view->setVars(['app_name' => $this->config->get('site')->name, 'app_version' => VERSION, 'threads' => Posts::count(), 'last_threads' => $lastThreads, 'users' => Users::count(), 'users_latest' => $login, 'actionName' => $this->dispatcher->getActionName(), 'controllerName' => $this->dispatcher->getControllerName()]); }
public function statsAction() { $this->view->threads = Posts::count(); $this->view->replies = Posts::sum(array('column' => 'number_replies')); $this->view->votes = Posts::sum(array('column' => 'votes_up + votes_down')); $this->view->users = Users::count(); $this->view->karma = Users::sum(array('column' => 'karma')); $this->view->notifications = Notifications::count(); $this->view->unotifications = ActivityNotifications::count(); $this->view->views = Posts::sum(array('column' => 'number_views')); $this->view->irc = IrcLog::count(); }
/** * Votes for a poll option * * @param int $id Post ID * @param int $option Option ID * @return Response */ public function voteAction($id = 0, $option = 0) { $response = new Response(); if (!$this->checkTokenGetJson('post-' . $id)) { $csrfTokenError = ['status' => 'error', 'message' => 'This post is outdated. Please try to vote again.']; return $response->setJsonContent($csrfTokenError); } if (!($post = Posts::findFirstById($id))) { $contentNotExist = ['status' => 'error', 'message' => 'Poll does not exist']; return $response->setJsonContent($contentNotExist); } if (!($user = Users::findFirstById($this->session->get('identity')))) { $contentlogIn = ['status' => 'error', 'message' => 'You must log in first to vote']; return $response->setJsonContent($contentlogIn); } if (!($option = PostsPollOptions::findFirstById($option))) { $optionNotFound = ['status' => 'error', 'message' => 'Please select one option from the list below']; return $response->setJsonContent($optionNotFound); } if ($post->isParticipatedInPoll($user->id)) { $contentAlreadyVote = ['status' => 'error', 'message' => 'You have already voted this post']; return $response->setJsonContent($contentAlreadyVote); } $pollVote = new PostsPollVotes(); $pollVote->posts_id = $post->id; $pollVote->users_id = $user->id; $pollVote->options_id = $option->id; if (!$pollVote->save()) { foreach ($pollVote->getMessages() as $message) { /** @var \Phalcon\Mvc\Model\Message $message */ $contentError = ['status' => 'error', 'message' => $message->getMessage()]; return $response->setJsonContent($contentError); } } if ($post->users_id != $user->id) { $post->user->increaseKarma(Karma::SOMEONE_DID_VOTE_MY_POLL); $user->increaseKarma(Karma::VOTE_ON_SOMEONE_ELSE_POLL); } if (!$post->save()) { foreach ($post->getMessages() as $message) { /** @var \Phalcon\Mvc\Model\Message $message */ $contentErrorSave = ['status' => 'error', 'message' => $message->getMessage()]; return $response->setJsonContent($contentErrorSave); } } $viewCache = $this->getDI()->getShared('viewCache'); $viewCache->delete('post-' . $post->id); $viewCache->delete('poll-votes-' . $post->id); $viewCache->delete('poll-options-' . $post->id); $contentOk = ['status' => 'OK']; return $response->setJsonContent($contentOk); }
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'); $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()) { $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->gravatar->setSize(64); $this->view->setVars(['user' => $user, '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]])]); }
/** * Check whether the user can have the badge * * @param Users $user * @return boolean */ public function canHave(Users $user) { return $user->countPosts('accepted_answer = "Y"') >= 1; }
$title = $faker->company; $category = new Categories(); $category->name = $title; $category->description = $faker->sentence; $category->slug = Tag::friendlyTitle($title); $category->number_posts = 0; $category->no_bounty = 'N'; $category->no_digest = 'N'; if (!$category->save()) { $database->rollback(); die(join(PHP_EOL, $category->getMessages())); } $log->info('Category: ' . $category->name); } for ($i = 0; $i <= 50; $i++) { $user = new Users(); $user->name = $faker->name; $user->login = $faker->userName; $user->email = $faker->email; $user->timezone = $faker->timezone; if (!$user->save()) { $database->rollback(); die(join(PHP_EOL, $user->getMessages())); } $log->info('User: '******'columns' => 'id'])->toArray(); $userIds = Users::find(['columns' => 'id'])->toArray(); $database->begin(); for ($i = 0; $i <= 500; $i++) {
public function afterCreate() { /** * Register a new activity */ if ($this->id > 0) { /** * Register the activity */ $activity = new Activities(); $activity->users_id = $this->users_id; $activity->posts_id = $this->id; $activity->type = Activities::NEW_POST; $activity->save(); /** * Notify users that always want notifications */ $notification = new PostsNotifications(); $notification->users_id = $this->users_id; $notification->posts_id = $this->id; $notification->save(); /** * Notify users that always want notifications */ $toNotify = []; foreach (Users::find(['notifications = "Y"', 'columns' => 'id']) as $user) { if ($this->users_id != $user->id) { $notification = new Notifications(); $notification->users_id = $user->id; $notification->posts_id = $this->id; $notification->type = 'P'; $notification->save(); $toNotify[$user->id] = $notification->id; } } /** * Update the total of posts related to a category */ $this->category->number_posts++; $this->category->save(); /** * Queue notifications to be sent */ $this->getDI()->getQueue()->put($toNotify); } }
/** * Check whether the user can have the badge * * @param Users $user * @return boolean */ public function canHave(Users $user) { return $user->countReplies() >= 10; }
/** * Shows the latest notifications for the current user */ public function notificationsAction($offset = 0) { $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(); } $this->view->user = $user; $this->view->notifications = ActivityNotifications::find(['users_id = ?0', 'bind' => [$usersId], 'limit' => 128, 'order' => 'created_at DESC']); $this->tag->setTitle('Notifications'); }
/** * 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; }
/** * 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); }
public function onConstruct() { $last_threads = $this->modelsManager->createBuilder()->from(array('p' => 'Phosphorum\\Models\\Posts'))->groupBy("p.id")->join('Phosphorum\\Models\\Categories', "r.id = p.categories_id", 'r')->join('Phosphorum\\Models\\Users', "u.id = p.users_id", 'u')->columns(array('p.title as title_post', 'p.id as id_post', 'p.slug as slug_post', 'r.name as name_category', 'u.name as name_user'))->orderBy('p.created_at DESC')->limit(3)->getQuery()->execute(); $users = Users::find()->getLast(); $this->view->setVars(['threads' => Posts::count(), 'last_threads' => $last_threads, 'users' => Users::count(), 'users_latest' => $users->login, 'actionName' => $this->dispatcher->getActionName()]); }
public function afterCreate() { if ($this->id > 0) { $activity = new Activities(); $activity->users_id = $this->users_id; $activity->posts_id = $this->posts_id; $activity->type = Activities::NEW_REPLY; $activity->save(); $toNotify = array(); /** * Notify users that always want notifications */ foreach (Users::find(array('notifications = "Y"', 'columns' => 'id')) as $user) { if ($this->users_id != $user->id) { $notification = new Notifications(); $notification->users_id = $user->id; $notification->posts_id = $this->posts_id; $notification->posts_replies_id = $this->id; $notification->type = 'C'; $notification->save(); $activity = new ActivityNotifications(); $activity->users_id = $user->id; $activity->posts_id = $this->posts_id; $activity->posts_replies_id = $this->id; $activity->users_origin_id = $this->users_id; $activity->type = 'C'; $activity->save(); $toNotify[$user->id] = $notification->id; } } /** * Register users subscribed to the post */ foreach (PostsSubscribers::findByPostsId($this->posts_id) as $subscriber) { if (!isset($toNotify[$subscriber->users_id])) { $notification = new Notifications(); $notification->users_id = $subscriber->users_id; $notification->posts_id = $this->posts_id; $notification->posts_replies_id = $this->id; $notification->type = 'C'; $notification->save(); $activity = new ActivityNotifications(); $activity->users_id = $subscriber->users_id; $activity->posts_id = $this->posts_id; $activity->posts_replies_id = $this->id; $activity->users_origin_id = $this->users_id; $activity->type = 'C'; $activity->save(); $toNotify[$subscriber->users_id] = $notification->id; } } /** * Register the user in the post's notifications */ if (!isset($toNotify[$this->users_id])) { $parameters = array('users_id = ?0 AND posts_id = ?1', 'bind' => array($this->users_id, $this->posts_id)); $hasNotifications = PostsNotifications::count($parameters); if (!$hasNotifications) { $notification = new PostsNotifications(); $notification->users_id = $this->users_id; $notification->posts_id = $this->posts_id; $notification->save(); } } /** * Notify users that have commented in the same post */ $postsNotifications = PostsNotifications::findByPostsId($this->posts_id); foreach ($postsNotifications as $postNotification) { if (!isset($toNotify[$postNotification->users_id])) { if ($postNotification->users_id != $this->users_id) { /** * Generate an e-mail notification */ $notification = new Notifications(); $notification->users_id = $postNotification->users_id; $notification->posts_id = $this->posts_id; $notification->posts_replies_id = $this->id; $notification->type = 'C'; $notification->save(); $activity = new ActivityNotifications(); $activity->users_id = $postNotification->users_id; $activity->posts_id = $this->posts_id; $activity->posts_replies_id = $this->id; $activity->users_origin_id = $this->users_id; $activity->type = 'C'; $activity->save(); $toNotify[$postNotification->users_id] = $notification->id; } } } /** * Queue notifications to be sent */ $this->getDI()->getQueue()->put($toNotify); } }
/** * @return \Phalcon\Http\ResponseInterface */ public function accessTokenAction() { $oauth = new OAuth($this->config->get('github', new Config())); $response = $oauth->accessToken(); if (is_array($response)) { if (isset($response['error'])) { $this->flashSession->error('Github: ' . $response['error']); return $this->indexRedirect(); } $githubUser = new GithubUsers($response['access_token']); if (!$githubUser->isValid()) { $this->flashSession->error('Invalid Github response. Please try again'); return $this->indexRedirect(); } /** * Edit/Create the user */ $user = ForumUsers::findFirstByAccessToken($response['access_token']); if ($user == false) { $user = new ForumUsers(); $user->token_type = $response['token_type']; $user->access_token = $response['access_token']; } if ($user->banned == 'Y') { $this->flashSession->error('You have been banned from the forum.'); return $this->indexRedirect(); } // Update session id session_regenerate_id(true); /** * Update the user information */ $user->name = $githubUser->getName(); $user->login = $githubUser->getLogin(); $email = $githubUser->getEmail(); if (is_string($email)) { $user->email = $email; } elseif (is_array($email) && isset($email['email'])) { $user->email = $email['email']; } // In any case user has Gravatar ID even if he has no email $user->gravatar_id = $this->gravatar->getEmailHash($user->email); $user->increaseKarma(Karma::LOGIN); if (!$user->save()) { foreach ($user->getMessages() as $message) { $this->flashSession->error((string) $message); return $this->indexRedirect(); } } /** * Store the user data in session */ $this->session->set('identity', $user->id); $this->session->set('identity-name', $user->name); $this->session->set('identity-email', $user->email); $this->session->set('identity-gravatar', $user->gravatar_id); $this->session->set('identity-timezone', $user->timezone); $this->session->set('identity-theme', $user->theme); $this->session->set('identity-moderator', $user->moderator); if ($user->getOperationMade() == Model::OP_CREATE) { $this->flashSession->success('Welcome ' . $user->name); } else { $this->flashSession->success('Welcome back ' . $user->name); } if ($user->email) { if (false !== strpos($user->email, '@users.noreply.github.com')) { $messageNotAllow = sprintf('Your current e-mail %s does not allow us to send you e-mail notifications', $this->escaper->escapeHtml($user->email)); $this->flashSession->notice($messageNotAllow); } } else { $messageCantSend = "We weren't able to obtain your e-mail address" . " from Github, we can't send you e-mail notifications"; $this->flashSession->notice($messageCantSend); } if ($user->getOperationMade() != Model::OP_CREATE) { /** * Show a notification to users that have e-mail bounces */ $parametersBounces = ['email = ?0 AND reported = "N"', 'bind' => [$user->email]]; $bounces = NotificationsBounces::find($parametersBounces); if (count($bounces)) { foreach ($bounces as $bounce) { $bounce->reported = 'Y'; $bounce->save(); } $messageFailed = 'We have failed to deliver you some email notifications,' . ' this might be caused by an invalid email associated to your Github account or ' . 'its mail server is rejecting our emails. Your current e-mail is: ' . $this->escaper->escapeHtml($user->email); $this->flashSession->notice($messageFailed); $parametersBouncesMax = ['email = ?0 AND created_at >= ?1', 'bind' => [$user->email, time() - 86400 * 7]]; $bounces = NotificationsBounces::find($parametersBouncesMax); if (count($bounces) >= NotificationsBounces::MAX_BOUNCES) { $messageRepeat = 'Due to a repeated number of email bounces we have disabled email ' . 'notifications for your email. You can re-enable them in your settings'; $this->flashSession->notice($messageRepeat); $user->notifications = 'N'; $user->save(); } } /** * Show a notification to users that haven't spend their votes */ if ($user->votes >= 10 && mt_rand(1, 5) == 3) { $this->flashSession->notice("You have {$user->votes} votes remaining to spend. " . 'If you find something useful in this forum do not hesitate to give others some votes.'); } } return $this->discussionsRedirect(); } $this->flashSession->error('Invalid Github response. Please try again'); return $this->discussionsRedirect(); }
/** * Check whether the user can have the badge * * @param Users $user * @return boolean */ public function canHave(Users $user) { return $user->countReplies('accepted = "Y"') >= 15; }
/** * Sends the digest */ public function send() { $lastMonths = new \DateTime(); $lastMonths->modify('-6 month'); $parameters = ['modified_at >= ?0 AND digest = "Y" AND notifications <> "N"', 'bind' => [$lastMonths->getTimestamp()]]; $users = []; foreach (Users::find($parameters) as $user) { if ($user->email && strpos($user->email, '@') !== false && strpos($user->email, '@users.noreply.github.com') === false) { $users[trim($user->email)] = $user->name; } } $view = new View(); $view->setViewsDir($this->config->application->viewsDir); $fromName = $this->config->mail->fromName; $fromEmail = $this->config->mail->fromEmail; $url = rtrim($this->config->site->url, '/'); $subject = sprintf('Top Stories from Phosphorum %s', date('d/m/y')); $view->setVar('title', $subject); $lastWeek = new \DateTime(); $lastWeek->modify('-1 week'); $order = 'number_views + ' . '((IF(votes_up IS NOT NULL, votes_up, 0) - ' . 'IF(votes_down IS NOT NULL, votes_down, 0)) * 4) + ' . 'number_replies + IF(accepted_answer = "Y", 10, 0) DESC'; $parameters = ['created_at >= ?0 AND deleted != 1 AND categories_id <> 4', 'bind' => [$lastWeek->getTimestamp()], 'order' => $order, 'limit' => 10]; $e = $this->escaper; /** @var \Phalcon\Logger\AdapterInterface $logger */ $logger = $this->getDI()->get('logger', ['mail']); $stories = []; foreach (Posts::find($parameters) as $i => $post) { $user = $post->user; if ($user == false) { continue; } $this->gravatar->setSize(32); $stories[$i]['user_name'] = $user->name; $stories[$i]['user_avatar'] = $this->gravatar->getAvatar($user->email); $stories[$i]['user_url'] = "{$url}/user/{$user->id}/{$user->login}"; $stories[$i]['user_karma'] = $user->getHumanKarma(); $stories[$i]['post_title'] = $e->escapeHtml($post->title); $stories[$i]['post_created'] = $post->getHumanCreatedAt(); $stories[$i]['post_replies'] = (int) $post->number_replies; $stories[$i]['post_views'] = (int) $post->number_views; $stories[$i]['post_votes'] = $post->votes_up - $post->votes_down; $stories[$i]['post_content'] = $this->markdown->render($e->escapeHtml($post->content)); $stories[$i]['post_url'] = "{$url}/discussion/{$post->id}/{$post->slug}"; } if (empty($stories)) { return; } $view->setVar('stories', $stories); $view->setVar('notice', sprintf('This email was sent by %s mail sender. Change your e-mail preferences <a href="%s/settings">here</a>', $this->config->site->name, $url)); $content = $view->render('mail/digest.phtml'); $textContent = preg_replace('#<a[^>]+href="([^"]+)"[^>]*>([^<]+)<\\/a>#', '$2:' . "\n" . '$1', $content); $textContent = str_replace('<span class="foot-line"></span>', "--\n", $textContent); $textContent = trim(strip_tags($textContent)); $textContent = str_replace(' ', ' ', $textContent); $textContent = preg_replace('#\\t+#', '', $textContent); $textContent = preg_replace('# {2,}#', ' ', $textContent); $textContent = preg_split('#(\\r|\\n)#', $textContent); $textContent = join("\n\n", array_filter($textContent, function ($line) { return '' !== trim($line); })); $textContent = preg_replace('#^[ \\t]+#m', '', $textContent); foreach ($users as $email => $name) { try { $message = new \Swift_Message("[{$this->config->site->name} Forum] " . $subject); $message->setTo([$email => $name]); $message->setFrom([$fromEmail => $fromName]); $bodyMessage = new \Swift_MimePart($content, 'text/html'); $bodyMessage->setCharset('UTF-8'); $message->attach($bodyMessage); $bodyMessage = new \Swift_MimePart($textContent, 'text/plain'); $bodyMessage->setCharset('UTF-8'); $message->attach($bodyMessage); if (!$this->transport) { $this->transport = \Swift_SmtpTransport::newInstance($this->config->smtp->host, $this->config->smtp->port, $this->config->smtp->security); $this->transport->setUsername($this->config->smtp->username); $this->transport->setPassword($this->config->smtp->password); } if (!$this->mailer) { $this->mailer = \Swift_Mailer::newInstance($this->transport); } $failedRecipients = []; $this->mailer->send($message, $failedRecipients); if (empty($failedRecipients)) { $logger->info("Sent an email to {$email}"); } else { $logger->error("Unable to sent an email to " . join(', ', $failedRecipients)); } } catch (\Exception $e) { $logger->error($e->getMessage()); throw new \Exception($e->getMessage(), $e->getCode(), $e); } } }
public function statsAction() { $this->breadcrumbs->add('Help', '/help')->add('Statistics', '/help/stats', ['linked' => false]); $this->tag->setTitle("Statistics"); $this->view->setVars(['threads' => Posts::count(), 'replies' => Posts::sum(['column' => 'number_replies']), 'votes' => Posts::sum(['column' => 'votes_up + votes_down']), 'users' => Users::count(), 'karma' => Users::sum(['column' => 'karma']), 'notifications' => Notifications::count(), 'unotifications' => ActivityNotifications::count(), 'views' => Posts::sum(['column' => 'number_views']), 'irc' => IrcLog::count()]); }