/** * Searches for threads with unread posts. * @param array $params * @return ActiveDataProvider */ public function search() { $loggedId = User::loggedId(); $query = Thread::find()->joinWith('threadView')->where(['or', ['and', ['user_id' => $loggedId], new Expression('`new_last_seen` < `new_post_at`')], ['and', ['user_id' => $loggedId], new Expression('`edited_last_seen` < `edited_post_at`')], ['user_id' => null]]); $dataProvider = new ActiveDataProvider(['query' => $query, 'pagination' => ['defaultPageSize' => 10, 'forcePageParam' => false]]); $dataProvider->sort->defaultOrder = ['edited_post_at' => SORT_ASC, 'id' => SORT_ASC]; $dataProvider->pagination->pageSize = Yii::$app->session->get('per-page', 20); return $dataProvider; }
/** * Subscribing the thread of given ID. * @param integer $id * @return \yii\web\Response */ public function actionAdd($id = null) { 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 adding this subscription!'), ['class' => 'text-danger'])]; if (!Yii::$app->user->isGuest) { if (is_numeric($id) && $id > 0) { $thread = Thread::findOne((int) $id); if ($thread) { $subscription = Subscription::findOne(['thread_id' => $thread->id, 'user_id' => User::loggedId()]); if ($subscription) { $data = ['error' => 1, 'msg' => Html::tag('span', Html::tag('span', '', ['class' => 'glyphicon glyphicon-warning-sign']) . ' ' . Yii::t('podium/view', 'You are already subscribed to this thread.'), ['class' => 'text-info'])]; } else { $sub = new Subscription(); $sub->thread_id = $thread->id; $sub->user_id = User::loggedId(); $sub->post_seen = Subscription::POST_SEEN; if ($sub->save()) { $data = ['error' => 0, 'msg' => Html::tag('span', Html::tag('span', '', ['class' => 'glyphicon glyphicon-ok-circle']) . ' ' . Yii::t('podium/view', 'You have subscribed to this thread!'), ['class' => 'text-success'])]; } } } } } else { $data = ['error' => 1, 'msg' => Html::tag('span', Html::tag('span', '', ['class' => 'glyphicon glyphicon-warning-sign']) . ' ' . Yii::t('podium/view', 'Please sign in to subscribe to this thread'), ['class' => 'text-info'])]; } return Json::encode($data); } else { return $this->redirect(['default/index']); } }
/** * Thread relation. * @return Thread */ public function getThread() { return $this->hasOne(Thread::className(), ['id' => 'thread_id']); }
/** * 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 threads added by user of given ID. * @param integer $id * @return integer */ public static function findThreadsCount($id) { $cache = Cache::getInstance()->getElement('user.threadscount', $id); if ($cache === false) { $cache = (new Query())->from(Thread::tableName())->where(['author_id' => $id])->count(); Cache::getInstance()->setElement('user.threadscount', $id, $cache); } return $cache; }
/** * Marking all unread posts as seen. * @return string|\yii\web\Response */ public function actionMarkSeen() { if (Yii::$app->user->isGuest) { $this->info(Yii::t('podium/flash', 'This action is available for registered users only.')); return $this->redirect(['account/login']); } try { $loggedId = User::loggedId(); $batch = []; $threadsPrevMarked = Thread::find()->joinWith('threadView')->where(['and', ['user_id' => User::loggedId()], ['or', new Expression('`new_last_seen` < `new_post_at`'), new Expression('`edited_last_seen` < `edited_post_at`')]]); $time = time(); foreach ($threadsPrevMarked->each() as $thread) { $batch[] = $thread->id; } if (!empty($batch)) { Yii::$app->db->createCommand()->update(ThreadView::tableName(), ['new_last_seen' => $time, 'edited_last_seen' => $time], ['thread_id' => $batch, 'user_id' => $loggedId])->execute(); } $batch = []; $threadsNew = Thread::find()->joinWith('threadView')->where(['user_id' => null]); foreach ($threadsNew->each() as $thread) { $batch[] = [$loggedId, $thread->id, $time, $time]; } if (!empty($batch)) { Yii::$app->db->createCommand()->batchInsert(ThreadView::tableName(), ['user_id', 'thread_id', 'new_last_seen', 'edited_last_seen'], $batch)->execute(); } $this->success(Yii::t('podium/flash', 'All unread threads have been marked as seen.')); return $this->redirect(['default/index']); } catch (Exception $e) { Log::error($e->getMessage(), null, __METHOD__); $this->error(Yii::t('podium/flash', 'Sorry! There was an error while marking threads as seen. Contact administrator about this problem.')); return $this->redirect(['default/unread-posts']); } }
/** * Counts number of created threads. * @return integer */ public static function totalThreads() { $threads = Cache::getInstance()->get('forum.threadscount'); if ($threads === false) { $threads = Thread::find()->count(); Cache::getInstance()->set('forum.threadscount', $threads); } return $threads; }
/** * Reporting the post of given category ID, forum ID, thread ID, own ID and slug. * @param integer $cid * @param integer $fid * @param integer $tid * @param integer $pid * @param string $slug * @return string|\yii\web\Response */ public function actionReport($cid = null, $fid = null, $tid = null, $pid = null, $slug = null) { if (!Yii::$app->user->isGuest) { if (!is_numeric($cid) || $cid < 1 || !is_numeric($fid) || $fid < 1 || !is_numeric($tid) || $tid < 1 || !is_numeric($pid) || $pid < 1 || empty($slug)) { $this->error('Sorry! We can not find the post you are looking for.'); return $this->redirect(['default/index']); } $category = Category::findOne(['id' => (int) $cid]); if (!$category) { $this->error('Sorry! We can not find the post you are looking for.'); return $this->redirect(['default/index']); } else { $forum = Forum::findOne(['id' => (int) $fid, 'category_id' => $category->id]); if (!$forum) { $this->error('Sorry! We can not find the post you are looking for.'); return $this->redirect(['default/index']); } else { $thread = Thread::findOne(['id' => (int) $tid, 'category_id' => $category->id, 'forum_id' => $forum->id, 'slug' => $slug]); if (!$thread) { $this->error('Sorry! We can not find the post you are looking for.'); return $this->redirect(['default/index']); } else { $post = Post::findOne(['id' => (int) $pid, 'forum_id' => $forum->id, 'thread_id' => $thread->id]); if (!$post) { $this->error('Sorry! We can not find the post you are looking for.'); return $this->redirect(['default/index']); } else { if ($post->author_id == Yii::$app->user->id) { $this->info('You can not report your own post. Please contact the administrator or moderators if you have got any concerns regarding your post.'); return $this->redirect(['default/thread', 'cid' => $category->id, 'fid' => $forum->id, 'id' => $thread->id, 'slug' => $thread->slug]); } else { $model = new Message(); $model->setScenario('report'); if ($model->load(Yii::$app->request->post())) { if ($model->validate()) { try { $mods = $forum->getMods(); $package = []; foreach ($mods as $mod) { if ($mod != Yii::$app->user->id) { $package[] = ['sender_id' => Yii::$app->user->id, 'receiver_id' => $mod, 'topic' => Yii::t('podium/view', 'Complaint about the post #{id}', ['id' => $post->id]), 'content' => $model->content . '<hr>' . Html::a(Yii::t('podium/view', 'Direct link to the post'), ['show', 'id' => $post->id]) . '<hr>' . '<strong>' . Yii::t('podium/view', 'Post contents') . '</strong><br><blockquote>' . $post->content . '</blockquote>', 'sender_status' => Message::STATUS_REMOVED, 'receiver_status' => Message::STATUS_NEW, 'created_at' => time(), 'updated_at' => time()]; } } if (!empty($package)) { Yii::$app->db->createCommand()->batchInsert(Message::tableName(), ['sender_id', 'receiver_id', 'topic', 'content', 'sender_status', 'receiver_status', 'created_at', 'updated_at'], array_values($package))->execute(); Cache::getInstance()->delete('user.newmessages'); Log::info('Post reported', !empty($post->id) ? $post->id : '', __METHOD__); $this->success('Thank you for your report. The moderation team will take a look at this post.'); return $this->redirect(['thread', 'cid' => $category->id, 'fid' => $forum->id, 'id' => $thread->id, 'slug' => $thread->slug]); } else { $this->warning('Apparently there is no one we can send this report to except you and you already reporting it so...'); } } catch (Exception $e) { Log::error($e->getMessage(), null, __METHOD__); $this->error('Sorry! There was an error while notifying the moderation team. Contact administrator about this problem.'); } } } return $this->render('report', ['model' => $model, 'category' => $category, 'forum' => $forum, 'thread' => $thread, 'post' => $post]); } } } } } } else { $this->warning('Please sign in to report the post.'); return $this->redirect(['account/login']); } }
/** * Marking all unread posts as seen. * @return \yii\web\Response */ public function actionMarkSeen() { if (Yii::$app->user->isGuest) { $this->info(Yii::t('podium/flash', 'This action is available for registered users only.')); return $this->redirect(['account/login']); } if (Thread::podiumMarkAllSeen()) { $this->success(Yii::t('podium/flash', 'All unread threads have been marked as seen.')); return $this->redirect(['default/index']); } $this->error(Yii::t('podium/flash', 'Sorry! There was an error while marking threads as seen. Contact administrator about this problem.')); return $this->redirect(['default/unread-posts']); }
/** * Performs marking all unread threads as seen for user. * @return boolean * @throws Exception * @since 0.2 */ public static function podiumMarkAllSeen() { try { $loggedId = User::loggedId(); if (empty($loggedId)) { throw new Exception('User ID missing'); } $batch = []; $threadsPrevMarked = Thread::find()->joinWith('threadView')->where(['and', ['user_id' => $loggedId], ['or', new Expression('`new_last_seen` < `new_post_at`'), new Expression('`edited_last_seen` < `edited_post_at`')]]); $time = time(); foreach ($threadsPrevMarked->each() as $thread) { $batch[] = $thread->id; } if (!empty($batch)) { Yii::$app->db->createCommand()->update(ThreadView::tableName(), ['new_last_seen' => $time, 'edited_last_seen' => $time], ['thread_id' => $batch, 'user_id' => $loggedId])->execute(); } $batch = []; $threadsNew = Thread::find()->joinWith('threadView')->where(['user_id' => null]); foreach ($threadsNew->each() as $thread) { $batch[] = [$loggedId, $thread->id, $time, $time]; } if (!empty($batch)) { Yii::$app->db->createCommand()->batchInsert(ThreadView::tableName(), ['user_id', 'thread_id', 'new_last_seen', 'edited_last_seen'], $batch)->execute(); } return true; } catch (Exception $e) { Log::error($e->getMessage(), null, __METHOD__); } return false; }
/** * Gets number of active threads added by user. * @return integer */ public function getThreadsCount($id = null) { $cache = Cache::getInstance()->getElement('user.threadscount', empty($id) ? $this->getId() : $id); if ($cache === false) { $cache = (new Query())->from(Thread::tableName())->where(['author_id' => empty($id) ? $this->getId() : $id])->count(); Cache::getInstance()->setElement('user.threadscount', empty($id) ? $this->getId() : $id, $cache); } return $cache; }