/** * Renders the list of posts. * @return string */ public function run() { $out = Html::beginTag('div', ['class' => 'panel panel-default']) . "\n"; $out .= Html::tag('div', Yii::t('podium/view', 'Latest posts'), ['class' => 'panel-heading']) . "\n"; $latest = Post::getLatest(is_numeric($this->posts) && $this->posts > 0 ? $this->posts : 5); if ($latest) { $out .= Html::beginTag('table', ['class' => 'table table-hover']) . "\n"; foreach ($latest as $post) { $out .= Html::beginTag('tr'); $out .= Html::beginTag('td'); $out .= Html::a($post['title'], ['default/show', 'id' => $post['id']], ['class' => 'center-block']) . "\n"; $out .= Html::tag('small', Yii::$app->formatter->asRelativeTime($post['created']) . "\n" . $post['author']) . "\n"; $out .= Html::endTag('td'); $out .= Html::endTag('tr'); } $out .= Html::endTag('table') . "\n"; } else { $out .= Html::beginTag('div', ['class' => 'panel-body']) . "\n"; $out .= Html::tag('small', Yii::t('podium/view', 'No posts have been added yet.')) . "\n"; $out .= Html::endTag('div') . "\n"; } $out .= Html::endTag('div') . "\n"; return $out; }
/** * Advanced search. * @return ActiveDataProvider */ public function searchAdvanced() { if ($this->type == 'topics') { $query = Thread::find(); if (Yii::$app->user->isGuest) { $query->joinWith(['category' => function ($q) { $q->andWhere([Category::tableName() . '.visible' => 1]); }, 'forum' => function ($q) { $q->andWhere([Forum::tableName() . '.visible' => 1]); }]); } if (!empty($this->query)) { $words = explode(' ', preg_replace('/\\s+/', ' ', $this->query)); foreach ($words as $word) { if ($this->match == 'all') { $query->andWhere(['like', 'name', $word]); } else { $query->orWhere(['like', 'name', $word]); } } } if (!empty($this->author)) { $query->andWhere(['like', 'username', $this->author])->joinWith(['author']); } if (!empty($this->date_from) && empty($this->date_to)) { $query->andWhere(['>=', Thread::tableName() . '.created_at', $this->date_from]); } elseif (!empty($this->date_to) && empty($this->date_from)) { $this->date_to += 23 * 3600 + 59 * 60 + 59; // 23:59:59 $query->andWhere(['<=', Thread::tableName() . '.created_at', $this->date_to]); } elseif (!empty($this->date_to) && !empty($this->date_from)) { if ($this->date_from > $this->date_to) { $tmp = $this->date_to; $this->date_to = $this->date_from; $this->date_from = $tmp; } $this->date_to += 23 * 3600 + 59 * 60 + 59; // 23:59:59 $query->andWhere(['<=', Thread::tableName() . '.created_at', $this->date_to]); $query->andWhere(['>=', Thread::tableName() . '.created_at', $this->date_from]); } if (!empty($this->forums)) { if (is_array($this->forums)) { $forums = []; foreach ($this->forums as $f) { if (is_numeric($f)) { $forums[] = (int) $f; } } if (!empty($forums)) { $query->andWhere(['forum_id' => $forums]); } } } $sort = ['defaultOrder' => [Thread::tableName() . '.id' => SORT_DESC], 'attributes' => [Thread::tableName() . '.id' => ['asc' => [Thread::tableName() . '.id' => SORT_ASC], 'desc' => [Thread::tableName() . '.id' => SORT_DESC], 'default' => SORT_DESC]]]; } else { $query = Vocabulary::find()->select('post_id, thread_id'); if (Yii::$app->user->isGuest) { $query->joinWith(['posts' => function ($q) { $q->joinWith(['forum' => function ($qu) { $qu->andWhere([Forum::tableName() . '.visible' => 1])->joinWith(['category' => function ($que) { $que->andWhere([Category::tableName() . '.visible' => 1]); }]); }]); }]); } else { $query->joinWith(['posts']); } if (!empty($this->query)) { $words = explode(' ', preg_replace('/\\s+/', ' ', $this->query)); $countWords = 0; foreach ($words as $word) { $query->orWhere(['like', 'word', $word]); $countWords++; } $query->groupBy('post_id'); if ($this->match == 'all' && $countWords > 1) { $query->select(['post_id', 'thread_id', 'COUNT(post_id) AS c'])->having(['>', 'c', $countWords - 1]); } } if (!empty($this->author)) { $query->andWhere(['like', 'username', $this->author])->joinWith(['posts' => function ($q) { $q->joinWith(['user']); }]); } if (!empty($this->date_from) && empty($this->date_to)) { $query->andWhere(['>=', Post::tableName() . '.updated_at', $this->date_from]); } elseif (!empty($this->date_to) && empty($this->date_from)) { $this->date_to += 23 * 3600 + 59 * 60 + 59; // 23:59:59 $query->andWhere(['<=', Post::tableName() . '.updated_at', $this->date_to]); } elseif (!empty($this->date_to) && !empty($this->date_from)) { if ($this->date_from > $this->date_to) { $tmp = $this->date_to; $this->date_to = $this->date_from; $this->date_from = $tmp; } $this->date_to += 23 * 3600 + 59 * 60 + 59; // 23:59:59 $query->andWhere(['<=', Post::tableName() . '.updated_at', $this->date_to]); $query->andWhere(['>=', Post::tableName() . '.updated_at', $this->date_from]); } if (!empty($this->forums)) { if (is_array($this->forums)) { $forums = []; foreach ($this->forums as $f) { if (is_numeric($f)) { $forums[] = (int) $f; } } if (!empty($forums)) { $query->andWhere(['forum_id' => $forums]); } } } $sort = ['defaultOrder' => ['post_id' => SORT_DESC], 'attributes' => ['post_id' => ['asc' => ['post_id' => SORT_ASC], 'desc' => ['post_id' => SORT_DESC], 'default' => SORT_DESC]]]; } $dataProvider = new ActiveDataProvider(['query' => $query, 'sort' => $sort]); return $dataProvider; }
/** * Gets number of active posts added by user of given ID. * @param integer $id * @return integer */ public static function findPostsCount($id) { $cache = Cache::getInstance()->getElement('user.postscount', $id); if ($cache === false) { $cache = (new Query())->from(Post::tableName())->where(['author_id' => $id])->count(); Cache::getInstance()->setElement('user.postscount', $id, $cache); } return $cache; }
/** * Performs new post creation and subscription. * If previous post in thread has got the same author posts are merged. * @param Post $previous previous post * @return boolean * @throws Exception * @since 0.2 */ public function podiumNew($previous = null) { $transaction = static::getDb()->beginTransaction(); try { $id = null; if (!empty($previous) && $previous->author_id == User::loggedId()) { $previous->content .= '<hr>' . $this->content; $previous->edited = 1; $previous->touch('edited_at'); if ($previous->save()) { $previous->markSeen(); $previous->thread->touch('edited_post_at'); $id = $previous->id; $thread = $previous->thread; } } else { if ($this->save()) { $this->markSeen(); $this->forum->updateCounters(['posts' => 1]); $this->thread->updateCounters(['posts' => 1]); $this->thread->touch('new_post_at'); $this->thread->touch('edited_post_at'); $id = $this->id; $thread = $this->thread; } } if (empty($id)) { throw new Exception('Saved Post ID missing'); } Subscription::notify($thread->id); if ($this->subscribe && !$thread->subscription) { $subscription = new Subscription(); $subscription->user_id = User::loggedId(); $subscription->thread_id = $thread->id; $subscription->post_seen = Subscription::POST_SEEN; $subscription->save(); } $transaction->commit(); Cache::clearAfter('newPost'); Log::info('Post added', $id, __METHOD__); return true; } catch (Exception $e) { $transaction->rollBack(); Log::error($e->getMessage(), null, __METHOD__); } return false; }
/** * Voting on the post. * @return string|\yii\web\Response */ public function actionThumb() { if (Yii::$app->request->isAjax) { $data = ['error' => 1, 'msg' => Html::tag('span', Html::tag('span', '', ['class' => 'glyphicon glyphicon-warning-sign']) . ' ' . Yii::t('podium/view', 'Error while voting on this post!'), ['class' => 'text-danger'])]; if (!Yii::$app->user->isGuest) { $postId = Yii::$app->request->post('post'); $thumb = Yii::$app->request->post('thumb'); if (is_numeric($postId) && $postId > 0 && in_array($thumb, ['up', 'down'])) { $post = Post::findOne((int) $postId); if ($post) { if ($post->thread->locked) { $data = ['error' => 1, 'msg' => Html::tag('span', Html::tag('span', '', ['class' => 'glyphicon glyphicon-warning-sign']) . ' ' . Yii::t('podium/view', 'This thread is locked.'), ['class' => 'text-info'])]; } else { if ($post->author_id == User::loggedId()) { return Json::encode(['error' => 1, 'msg' => Html::tag('span', Html::tag('span', '', ['class' => 'glyphicon glyphicon-warning-sign']) . ' ' . Yii::t('podium/view', 'You can not vote on your own post!'), ['class' => 'text-info'])]); } $count = 0; $votes = Cache::getInstance()->get('user.votes.' . User::loggedId()); if ($votes !== false) { if ($votes['expire'] < time()) { $votes = false; } elseif ($votes['count'] >= 10) { return Json::encode(['error' => 1, 'msg' => Html::tag('span', Html::tag('span', '', ['class' => 'glyphicon glyphicon-warning-sign']) . ' ' . Yii::t('podium/view', '{max} votes per hour limit reached!', ['max' => 10]), ['class' => 'text-danger'])]); } else { $count = $votes['count']; } } if ($post->thumb) { if ($post->thumb->thumb == 1 && $thumb == 'down') { $post->thumb->thumb = -1; if ($post->thumb->save()) { $post->updateCounters(['likes' => -1, 'dislikes' => 1]); } } elseif ($post->thumb->thumb == -1 && $thumb == 'up') { $post->thumb->thumb = 1; if ($post->thumb->save()) { $post->updateCounters(['likes' => 1, 'dislikes' => -1]); } } } else { $postThumb = new PostThumb(); $postThumb->post_id = $post->id; $postThumb->user_id = User::loggedId(); $postThumb->thumb = $thumb == 'up' ? 1 : -1; if ($postThumb->save()) { if ($thumb == 'up') { $post->updateCounters(['likes' => 1]); } else { $post->updateCounters(['dislikes' => 1]); } } } $data = ['error' => 0, 'likes' => '+' . $post->likes, 'dislikes' => '-' . $post->dislikes, 'summ' => $post->likes - $post->dislikes, 'msg' => Html::tag('span', Html::tag('span', '', ['class' => 'glyphicon glyphicon-ok-circle']) . ' ' . Yii::t('podium/view', 'Your vote has been saved!'), ['class' => 'text-success'])]; if ($count == 0) { Cache::getInstance()->set('user.votes.' . User::loggedId(), ['count' => 1, 'expire' => time() + 3600]); } else { Cache::getInstance()->setElement('user.votes.' . User::loggedId(), 'count', $count + 1); } } } } } else { $data = ['error' => 1, 'msg' => Html::tag('span', Html::tag('span', '', ['class' => 'glyphicon glyphicon-warning-sign']) . ' ' . Yii::t('podium/view', 'Please sign in to vote on this post'), ['class' => 'text-info'])]; } return Json::encode($data); } else { return $this->redirect(['default/index']); } }
/** * Dashboard. * @return string */ public function actionIndex() { return $this->render('index', ['members' => User::find()->orderBy(['id' => SORT_DESC])->limit(10)->all(), 'posts' => Post::find()->orderBy(['id' => SORT_DESC])->limit(10)->all()]); }
public function getLatest() { return $this->hasOne(Post::className(), ['forum_id' => 'id'])->orderBy(['id' => SORT_DESC]); }
/** * Counts number of created posts. * @return integer */ public static function totalPosts() { $posts = Cache::getInstance()->get('forum.postscount'); if ($posts === false) { $posts = Post::find()->count(); Cache::getInstance()->set('forum.postscount', $posts); } return $posts; }
public function getPosts() { return $this->hasMany(Post::className(), ['id' => 'post_id'])->viaTable('{{%podium_vocabulary_junction}}', ['word_id' => 'id']); }
/** * Performs new thread with first post creation and subscription. * @return boolean * @since 0.2 */ public function podiumNew() { $transaction = static::getDb()->beginTransaction(); try { if ($this->save()) { $this->forum->updateCounters(['threads' => 1]); $post = new Post(); $post->content = $this->post; $post->thread_id = $this->id; $post->forum_id = $this->forum_id; $post->author_id = User::loggedId(); $post->likes = 0; $post->dislikes = 0; if ($post->save()) { $post->markSeen(); $this->forum->updateCounters(['posts' => 1]); $this->updateCounters(['posts' => 1]); $this->touch('new_post_at'); $this->touch('edited_post_at'); if ($this->subscribe) { $subscription = new Subscription(); $subscription->user_id = User::loggedId(); $subscription->thread_id = $this->id; $subscription->post_seen = Subscription::POST_SEEN; $subscription->save(); } } } $transaction->commit(); Cache::clearAfter('newThread'); Log::info('Thread added', $this->id, __METHOD__); return true; } catch (Exception $e) { $transaction->rollBack(); Log::error($e->getMessage(), null, __METHOD__); } return false; }
/** * First edited not seen post relation. * @return Post */ public function getFirstEditedNotSeen() { return $this->hasOne(Post::className(), ['thread_id' => 'id'])->where(['>', 'edited_at', $this->view ? $this->view->edited_last_seen : 0])->orderBy(['id' => SORT_ASC]); }
/** * Gets number of active posts added by user. * @return integer */ public function getPostsCount($id = null) { $cache = Cache::getInstance()->getElement('user.postscount', empty($id) ? $this->getId() : $id); if ($cache === false) { $cache = (new Query())->from(Post::tableName())->where(['author_id' => empty($id) ? $this->getId() : $id])->count(); Cache::getInstance()->setElement('user.postscount', empty($id) ? $this->getId() : $id, $cache); } return $cache; }