예제 #1
0
 /**
  * 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;
 }
예제 #2
0
 /**
  * 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;
 }
 /**
  * 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']);
     }
 }
예제 #4
0
 /**
  * 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;
 }
예제 #5
0
 /**
  * Moving the posts of given category ID, forum ID, thread ID and slug.
  * @param integer $cid
  * @param integer $fid
  * @param integer $id
  * @param string $slug
  * @return string|\yii\web\Response
  */
 public function actionMoveposts($cid = null, $fid = null, $id = null, $slug = null)
 {
     $verify = $this->_verifyThread($cid, $fid, $id, $slug);
     if ($verify === false) {
         $this->error('Sorry! We can not find the thread you are looking for.');
         return $this->redirect(['default/index']);
     }
     list($category, $forum, $thread) = $verify;
     if (Yii::$app->user->can('movePodiumPost', ['item' => $thread])) {
         if (Yii::$app->request->post()) {
             $posts = Yii::$app->request->post('post');
             $newthread = Yii::$app->request->post('newthread');
             $newname = Yii::$app->request->post('newname');
             $newforum = Yii::$app->request->post('newforum');
             if (empty($posts) || !is_array($posts)) {
                 $this->error('You have to select at least one post.');
             } else {
                 if (!is_numeric($newthread) || $newthread < 0) {
                     $this->error('You have to select a thread for this posts to be moved to.');
                 } else {
                     if ($newthread == 0 && (empty($newname) || empty($newforum) || !is_numeric($newforum) || $newforum < 1)) {
                         $this->error('If you want to move posts to a new thread you have to enter its name and select parent forum.');
                     } else {
                         if ($newthread == $thread->id) {
                             $this->error('Are you trying to move posts from this thread to this very same thread?');
                         } else {
                             $transaction = Thread::getDb()->beginTransaction();
                             try {
                                 if ($newthread == 0) {
                                     $parent = Forum::findOne(['id' => $newforum]);
                                     if (!$parent) {
                                         $this->error('We can not find the parent forum with this ID.');
                                     } else {
                                         $nThread = new Thread();
                                         $nThread->name = $newname;
                                         $nThread->posts = 0;
                                         $nThread->views = 0;
                                         $nThread->category_id = $parent->category_id;
                                         $nThread->forum_id = $parent->id;
                                         $nThread->author_id = Yii::$app->user->id;
                                         $nThread->save();
                                     }
                                 } else {
                                     $nThread = Thread::findOne(['id' => $newthread]);
                                     if (!$nThread) {
                                         $this->error('We can not find the thread with this ID.');
                                     }
                                 }
                                 if (!empty($nThread)) {
                                     $error = false;
                                     foreach ($posts as $post) {
                                         if (!is_numeric($post) || $post < 1) {
                                             $this->error('Incorrect post ID.');
                                             $error = true;
                                             break;
                                         } else {
                                             $nPost = Post::findOne(['id' => $post, 'thread_id' => $thread->id, 'forum_id' => $forum->id]);
                                             if (!$nPost) {
                                                 $this->error('We can not find the post with this ID.');
                                                 $error = true;
                                                 break;
                                             } else {
                                                 $nPost->thread_id = $nThread->id;
                                                 $nPost->forum_id = $nThread->forum_id;
                                                 $nPost->save();
                                             }
                                         }
                                     }
                                     if (!$error) {
                                         $wholeThread = false;
                                         if ((new Query())->from(Post::tableName())->where(['thread_id' => $thread->id, 'forum_id' => $forum->id])->count()) {
                                             $thread->updateCounters(['posts' => -count($posts)]);
                                             $forum->updateCounters(['posts' => -count($posts)]);
                                         } else {
                                             $wholeThread = true;
                                             $thread->delete();
                                             $forum->updateCounters(['posts' => -count($posts), 'threads' => -1]);
                                         }
                                         $nThread->updateCounters(['posts' => count($posts)]);
                                         $nThread->forum->updateCounters(['posts' => count($posts)]);
                                         $transaction->commit();
                                         Cache::getInstance()->delete('forum.threadscount');
                                         Cache::getInstance()->delete('forum.postscount');
                                         Cache::getInstance()->delete('user.postscount');
                                         Cache::getInstance()->delete('forum.latestposts');
                                         Log::info('Posts moved', null, __METHOD__);
                                         $this->success('Posts have been moved.');
                                         if ($wholeThread) {
                                             return $this->redirect(['forum', 'cid' => $forum->category_id, 'id' => $forum->id, 'slug' => $forum->slug]);
                                         } else {
                                             return $this->redirect(['thread', 'cid' => $thread->category_id, 'fid' => $thread->forum_id, 'id' => $thread->id, 'slug' => $thread->slug]);
                                         }
                                     }
                                 }
                             } catch (Exception $e) {
                                 $transaction->rollBack();
                                 Log::error($e->getMessage(), null, __METHOD__);
                                 $this->error('Sorry! There was an error while moving the posts.');
                             }
                         }
                     }
                 }
             }
         }
         $categories = Category::find()->orderBy(['name' => SORT_ASC])->all();
         $forums = Forum::find()->orderBy(['name' => SORT_ASC])->all();
         $threads = Thread::find()->orderBy(['name' => SORT_ASC])->all();
         $list = [0 => Yii::t('podium/view', 'Create new thread')];
         $listforum = [];
         $options = [];
         foreach ($categories as $cat) {
             $catlist = [];
             foreach ($forums as $for) {
                 $forlist = [];
                 if ($for->category_id == $cat->id) {
                     $catlist[$for->id] = (Yii::$app->user->can('updatePodiumThread', ['item' => $for]) ? '* ' : '') . Html::encode($cat->name) . ' &raquo; ' . Html::encode($for->name);
                     foreach ($threads as $thr) {
                         if ($thr->category_id == $cat->id && $thr->forum_id == $for->id) {
                             $forlist[$thr->id] = (Yii::$app->user->can('updatePodiumThread', ['item' => $thr]) ? '* ' : '') . Html::encode($cat->name) . ' &raquo; ' . Html::encode($for->name) . ' &raquo; ' . Html::encode($thr->name);
                             if ($thr->id == $thread->id) {
                                 $options[$thr->id] = ['disabled' => true];
                             }
                         }
                     }
                     $list[Html::encode($cat->name) . ' > ' . Html::encode($for->name)] = $forlist;
                 }
             }
             $listforum[Html::encode($cat->name)] = $catlist;
         }
         return $this->render('moveposts', ['category' => $category, 'forum' => $forum, 'thread' => $thread, 'list' => $list, 'options' => $options, 'listforum' => $listforum, 'dataProvider' => (new Post())->search($forum->id, $thread->id)]);
     } else {
         if (Yii::$app->user->isGuest) {
             $this->warning('Please sign in to update the thread.');
             return $this->redirect(['account/login']);
         } else {
             $this->error('Sorry! You do not have the required permission to perform this action.');
             return $this->redirect(['default/index']);
         }
     }
 }
예제 #6
0
 /**
  * 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(Yii::t('podium/flash', 'Sorry! We can not find the post you are looking for.'));
             return $this->redirect(['default/index']);
         }
         $category = Category::findOne((int) $cid);
         if (!$category) {
             $this->error(Yii::t('podium/flash', 'Sorry! We can not find the post you are looking for.'));
             return $this->redirect(['default/index']);
         } else {
             $forum = Forum::find()->where(['id' => (int) $fid, 'category_id' => $category->id])->limit(1)->one();
             if (!$forum) {
                 $this->error(Yii::t('podium/flash', 'Sorry! We can not find the post you are looking for.'));
                 return $this->redirect(['default/index']);
             } else {
                 $thread = Thread::find()->where(['id' => (int) $tid, 'category_id' => $category->id, 'forum_id' => $forum->id, 'slug' => $slug])->limit(1)->one();
                 if (!$thread) {
                     $this->error(Yii::t('podium/flash', 'Sorry! We can not find the post you are looking for.'));
                     return $this->redirect(['default/index']);
                 } else {
                     $post = Post::find()->where(['id' => (int) $pid, 'forum_id' => $forum->id, 'thread_id' => $thread->id])->limit(1)->one();
                     if (!$post) {
                         $this->error(Yii::t('podium/flash', 'Sorry! We can not find the post you are looking for.'));
                         return $this->redirect(['default/index']);
                     } else {
                         if ($post->author_id == User::loggedId()) {
                             $this->info(Yii::t('podium/flash', '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 != User::loggedId()) {
                                                 $package[] = ['sender_id' => User::loggedId(), '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'), ['default/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', $post->id, __METHOD__);
                                             $this->success(Yii::t('podium/flash', 'Thank you for your report. The moderation team will take a look at this post.'));
                                             return $this->redirect(['default/thread', 'cid' => $category->id, 'fid' => $forum->id, 'id' => $thread->id, 'slug' => $thread->slug]);
                                         } else {
                                             $this->warning(Yii::t('podium/flash', '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(Yii::t('podium/flash', '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(Yii::t('podium/flash', 'Please sign in to report the post.'));
         return $this->redirect(['account/login']);
     }
 }
예제 #7
0
 /**
  * Creating the post of given category ID, forum ID and thread ID.
  * This can be reply to selected post of given ID.
  * @param integer $cid category's ID
  * @param integer $fid forum's ID
  * @param integer $tid thread's ID
  * @param integer $pid ID of post to reply to
  * @return string|\yii\web\Response
  */
 public function actionPost($cid = null, $fid = null, $tid = null, $pid = null)
 {
     if (Yii::$app->user->isGuest) {
         $this->warning(Yii::t('podium/flash', 'Please sign in to update the thread.'));
         return $this->redirect(['account/login']);
     }
     $thread = Thread::find()->where(['id' => $tid, 'category_id' => $cid, 'forum_id' => $fid])->limit(1)->one();
     if (empty($thread)) {
         $this->error(Yii::t('podium/flash', 'Sorry! We can not find the thread you are looking for.'));
         return $this->redirect(['default/index']);
     }
     if ($thread->locked == 1 && !User::can(Rbac::PERM_UPDATE_THREAD, ['item' => $thread])) {
         $this->info(Yii::t('podium/flash', 'This thread is locked.'));
         return $this->redirect(['default/thread', 'cid' => $thread->forum->category->id, 'fid' => $thread->forum->id, 'id' => $thread->id, 'slug' => $thread->slug]);
     }
     if (!User::can(Rbac::PERM_CREATE_POST)) {
         $this->error(Yii::t('podium/flash', 'Sorry! You do not have the required permission to perform this action.'));
         return $this->redirect(['default/index']);
     }
     $model = new Post();
     $model->subscribe = 1;
     $postData = Yii::$app->request->post();
     $replyFor = null;
     if (is_numeric($pid) && $pid > 0) {
         $replyFor = Post::find()->where(['id' => $pid])->limit(1)->one();
         if ($replyFor) {
             $model->content = Helper::prepareQuote($replyFor, Yii::$app->request->post('quote'));
         }
     }
     $preview = '';
     $previous = Post::find()->where(['thread_id' => $thread->id])->orderBy(['id' => SORT_DESC])->limit(1)->one();
     if ($model->load($postData)) {
         $model->thread_id = $thread->id;
         $model->forum_id = $thread->forum->id;
         $model->author_id = User::loggedId();
         if ($model->validate()) {
             if (isset($postData['preview-button'])) {
                 $preview = $model->content;
             } else {
                 if ($model->podiumNew($previous)) {
                     $this->success(Yii::t('podium/flash', 'New reply has been added.'));
                     if (!empty($previous) && $previous->author_id == User::loggedId()) {
                         return $this->redirect(['default/show', 'id' => $previous->id]);
                     }
                     return $this->redirect(['default/show', 'id' => $model->id]);
                 } else {
                     $this->error(Yii::t('podium/flash', 'Sorry! There was an error while adding the reply. Contact administrator about this problem.'));
                 }
             }
         }
     }
     return $this->render('post', ['replyFor' => $replyFor, 'preview' => $preview, 'model' => $model, 'thread' => $thread, 'previous' => $previous]);
 }
예제 #8
0
 /**
  * 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;
 }