/** * 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); }
/** * Search documents in ElasticSearch by the specified criteria * * @param array $fields * @param int $limit * @param bool $returnPosts * @return array */ public function search(array $fields, $limit = 10, $returnPosts = false) { try { $client = new Client(); $searchParams['index'] = 'phosphorum'; $searchParams['type'] = 'post'; $searchParams['body']['fields'] = array('id', 'karma'); if (count($fields) == 1) { $searchParams['body']['query']['match'] = $fields; } else { $terms = array(); foreach ($fields as $field => $value) { $terms[] = array('term' => array($field => $value)); } $searchParams['body']['query']['bool']['must'] = $terms; } $searchParams['body']['from'] = 0; $searchParams['body']['size'] = $limit; $queryResponse = $client->search($searchParams); $results = array(); if (is_array($queryResponse['hits'])) { $d = 0.5; foreach ($queryResponse['hits']['hits'] as $hit) { $post = Posts::findFirstById($hit['fields']['id'][0]); if ($post) { if ($hit['fields']['karma'][0] > 0 && ($post->hasReplies() || $post->hasAcceptedAnswer())) { $score = $hit['_score'] * 250 + $hit['fields']['karma'][0] + $d; if (!$returnPosts) { $results[$score] = array('slug' => 'discussion/' . $post->id . '/' . $post->slug, 'title' => $post->title, 'created' => $post->getHumanCreatedAt()); } else { $results[$score] = $post; } $d += 0.05; } } } } krsort($results); return array_values($results); } catch (\Exception $e) { return array(); } }
/** * Search documents in ElasticSearch by the specified criteria * * @param array $fields * @param int $limit * @param bool $returnPosts * @return array */ public function search(array $fields, $limit = 10, $returnPosts = false) { $results = []; $searchParams = ['index' => $this->config->get('index', 'phosphorum'), 'type' => 'post', 'body' => ['fields' => ['id', 'karma'], 'query' => [], 'from' => 0, 'size' => intval($limit)]]; if (count($fields) == 1) { $searchParams['body']['query']['match'] = $fields; } else { $terms = []; foreach ($fields as $field => $value) { $terms[] = ['term' => [$field => $value]]; } $searchParams['body']['query']['bool'] = ['must' => $terms]; } try { $queryResponse = $this->client->search($searchParams); $queryResponse = $this->parseElasticResponse($queryResponse); $d = 0.5; foreach ($queryResponse as $hit) { if (!isset($hit['fields']['id'][0])) { continue; } $id = $hit['fields']['id'][0]; $post = Posts::findFirstById($id); if (!$post || $post->deleted == Posts::IS_DELETED) { continue; } if ($hit['fields']['karma'][0] > 0 && ($post->hasReplies() || $post->hasAcceptedAnswer())) { $score = $hit['_score'] * 250 + $hit['fields']['karma'][0] + $d; if (!$returnPosts) { $results[$score] = $this->createPostArray($post); } else { $results[$score] = $post; } $d += 0.05; } } } catch (\Exception $e) { $this->logger->error("Indexer: {$e->getMessage()}. {$e->getFile()}:{$e->getLine()}"); } krsort($results); return array_values($results); }
/** * Search documents in ElasticSearch by the specified criteria * * @param array $fields * @param int $limit * @param boolean $returnPosts */ public function search(array $fields, $limit = 10, $returnPosts = false) { try { $client = new Client(); $searchParams['index'] = 'phosphorum'; $searchParams['type'] = 'post'; // I'm not sure, but this code makes search result empty. So I commented out. //$searchParams['body']['fields'] = array('id', 'karma'); if (count($fields) == 1) { $searchParams['body']['query']['match'] = $fields; } else { $terms = array(); foreach ($fields as $field => $value) { $terms[] = array('match' => array($field => array('query' => $value, 'operator' => 'and'))); } $searchParams['body']['query']['bool']['should'] = $terms; } $searchParams['body']['from'] = 0; $searchParams['body']['size'] = $limit; $queryResponse = $client->search($searchParams); $results = array(); if (is_array($queryResponse['hits'])) { $d = 0.5; foreach ($queryResponse['hits']['hits'] as $hit) { $post = Posts::findFirstById($hit['_source']['id']); if ($post) { $score = $hit['_score'] * 250 + $hit['_source']['karma'] + $d; if (!$returnPosts) { $results[$score] = array('slug' => 'discussion/' . $post->id . '/' . $post->slug, 'title' => $post->title, 'created' => $post->getHumanCreatedAt()); } else { $results[$score] = $post; } $d += 0.05; } } } krsort($results); return array_values($results); } catch (\Exception $e) { return array(); } }
/** * Finds related posts */ public function showRelatedAction() { $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW); $post = Posts::findFirstById($this->request->getPost('id')); if ($post) { $indexer = new Indexer(); $posts = $indexer->search(['title' => $post->title, 'category' => $post->categories_id], 5, true); if (count($posts) == 0) { $posts = $indexer->search(['title' => $post->title], 5, true); } $this->view->setVar('posts', $posts); } else { $this->view->setVar('posts', []); } }