DaSourcerer/yii2-yiiboard

View on GitHub
controllers/ModeratorController.php

Summary

Maintainability
F
4 days
Test Coverage
<?php

namespace app\modules\yboard\controllers;

use app\modules\yboard\YBoard;
use app\modules\yboard\components\DateTimeCalculation;


use app\modules\yboard\models\YBoardBanSearch;
use app\modules\yboard\models\YBoardTopic;
use app\modules\yboard\models\YBoardPost;
use app\modules\yboard\models\YBoardForum;
use app\modules\yboard\models\YBoardMessage;
use app\modules\yboard\models\YBoardMember;
use app\modules\yboard\models\YBoardBan;
use yii\web\NotFoundHttpException;
use yii\web\ForbiddenHttpException;

use Yii;
use yii\data\ActiveDataProvider;

class ModeratorController extends \yii\web\Controller
{
    public $layout = "admin";
    /**
     * Lists all YBoardBan models.
     * @return mixed
     */
    public function actionIndex()
    { 
        if(!Yii::$app->user->can('app.forum.moderator.index'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        $pendingTopics = YBoardTopic::find()->where(['approved'=>0])->count();        
        $pendingPosts = YBoardPost::find()->where(['approved'=>0])->count();
        
        $bannedUsers = YBoardBan::find()->activeScope()->userScope()->count();
        $bannedEmails = YBoardBan::find()->activeScope()->emailScope()->count();
        $bannedIps = YBoardBan::find()->activeScope()->ipScope()->count();
        
        return $this->render('index', [ 
            'pendingTopics'=>$pendingTopics,
            'pendingPosts'=>$pendingPosts,
            'bannedUsers'=>$bannedUsers,
            'bannedEmails'=>$bannedEmails,
            'bannedIps'=>$bannedIps,
        ]);
    } 

    //approve pending posts and topics
    public function actionApprove()
    {
        if(!Yii::$app->user->can('app.forum.moderator.approve'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        $topics = new ActiveDataProvider([
            'query' => YBoardTopic::find()->where(['approved'=>0]),
            'pagination' => [
                'pageSize' => 5,
            ],
        ]);
        
        $posts = new ActiveDataProvider([
            'query' => YBoardPost::find()->where(['approved'=>0]),
            'pagination' => [
                'pageSize' => 5,
            ],
        ]);
        
        return $this->render('approve', [
            'topicsProvider' => $topics,
            'postsProvider' => $posts,
        ]);
    } 
    
    /** Approve Topic
     */
    public function actionApproveTopic($id)
    {
        if(!Yii::$app->user->can('app.forum.moderator.approve-topic'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        if(!Yii::$app->request->isAjax)
            Yii::$app->end();
             
        $json = [];
        $post = YBoardTopic::findOne($id);
        if($post==null)
        {
            $json['success'] = 'no';
            $json['error'] = YBoard::t('yboard', 'Could not approve Topic');
        } 
        else
        { 
            $post->approved =1;
            if($post->save())
            {
                $json['success'] = 'yes';            
            }
            else
            {
                $json['success'] = 'no';
                $json['error'] = YBoard::t('yboard', 'Could not approve Topic!');
            }
        }
        echo json_encode($json);
        Yii::$app->end();
    }
    
    /** Approve Post
     */
    public function actionApprovePost($id)
    {
        if(!Yii::$app->user->can('app.forum.moderator.approve-post'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        if(!Yii::$app->request->isAjax)
            Yii::$app->end();
             
        $json = [];
        $post = YBoardPost::findOne($id);
        if($post==null)
        {
            $json['success'] = 'no';
            $json['error'] = YBoard::t('yboard', 'Could not approve Post');
        } 
        else
        { 
            $post->approved =1;
            if($post->save())
            {
                $json['success'] = 'yes';            
            }
            else
            {
                $json['success'] = 'no';
                $json['error'] = YBoard::t('yboard', 'Could not approve Post!');
            }
        }
        echo json_encode($json);
        Yii::$app->end();
    }
    
    /**
     * Lists all YBoardBan models.
     * @return mixed
     */
    public function actionBans()
    {
        if(!Yii::$app->user->can('app.forum.moderator.bans'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        $searchModel = new YBoardBanSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render('ban', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }
    
    /** Ban Specific User 
     */
    public function actionBanUser($id)
    {
        if(!Yii::$app->user->can('app.forum.moderator.ban-user'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        if(!Yii::$app->request->isAjax)
            Yii::$app->end();
             
        $json = [];
        $user = YBoardBan::find()->where(['user_id'=>$id])->one();
        if($user==null) 
             $user = new YBoardBan; 
        
        $attribs = $_POST;
        $attribs['expires'] = strtotime($attribs['expires']);
        $attribs['user_id'] = $id;
         
        $user->attributes= $attribs;
        
        if($user->save())
        {
            $json['success'] = 'yes';            
        }
        else
        {
            $json['success'] = 'no';
            $json['message'] = YBoard::t('yboard', 'Could Not Ban User!');
        }
        echo json_encode($json);
        Yii::$app->end();
        
    }
    
    /** Change Ban Time
     */
    public function actionChangeBanPeriod($id)
    {
        if(!Yii::$app->user->can('app.forum.moderator.change-ban-period'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        if(!Yii::$app->request->isAjax)
            Yii::$app->end(); 
        
        if(isset($_POST['hasEditable']) && isset($_POST['expires'])) { 
            
            $attrib = $_POST['expires'];
            $attrib = strtotime($attrib);   
                           
            $model = YBoardBan::findOne($id); 
            if($model==null)
            {
                echo json_encode(['output'=>'', 'message'=>'Could Not Update Field']);
                Yii::$app->end(); 
            }
            
            $model->expires = $attrib;
            
            if (!$model->save()) {
                // validation error
                echo json_encode(['output'=>'', 'message'=>'Could Not Update Field']);
            }
            // else if nothing to do always return an empty JSON encoded output
            else { 
                // read or convert your posted information
                $value = DateTimeCalculation::short($model->expires);
                echo json_encode(['output'=>$value, 'message'=>'']);
            }
        }
        else
        {
            throw new ForbiddenHttpException(YBoard::t('yboard','This Action is forbidden!'));
        }
    }

    /** Lift Ban
     */
    public function actionBanLift($id)
    {
        if(!Yii::$app->user->can('app.forum.moderator.ban-lift'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        if(!Yii::$app->request->isAjax)
            Yii::$app->end();
             
        $json = [];
        $ban = YBoardBan::findOne($id);
        $ban->setAttribute('expires', time()-60);//expired one minute ago
        if($ban!=null && $ban->save())  
        {
            $json['success'] = 'yes';  
        }
        else
        {
            $json['success'] = 'no';
            $json['error'] = YBoard::t('yboard', 'Could Not Lift the Ban!');
        } 
        echo json_encode($json);
        Yii::$app->end();
        
    }

    /**
     * Ajax call for change, move or merge topic
     */
    public function actionChangeTopic()
    {
        if(!Yii::$app->user->can('app.forum.moderator.change-topic'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        $json = []; 
        if(isset($_POST['YBoardTopic'])) {
            $model = YBoardTopic::findOne($_POST['YBoardTopic']['id']);
            $move = false;
            $merge = false;
            $sourceTopicId = $_POST['YBoardTopic']['id'];
            $sourceForumId = $model->forum_id;
            if($model->forum_id != $_POST['YBoardTopic']['forum_id']) {
                $move = true;
                $targetForumId = $_POST['YBoardTopic']['forum_id'];
            }
            if(!empty($_POST['YBoardTopic']['merge']) && $_POST['YBoardTopic']['id'] != $_POST['YBoardTopic']['merge']) {
                $merge = true;
                $targetTopicId = $_POST['YBoardTopic']['merge'];
            }
            $model->attributes=$_POST['YBoardTopic'];
            if($model->validate()) {
                $json['success'] = 'yes';
                if($merge || $move) {               
                    $criteria = "topic_id = $sourceTopicId";
                    $numberOfPosts = YBoardPost::find()->approvedScope()->count();
                    if($move) {     
                        YBoardPost::updateAll(['forum_id'=>$targetForumId], $criteria);
                        
                        $forum = YBoardForum::findOne($sourceForumId);
                        $forum->updateAllCounters(['num_topics'=>-1]);
                        $forum->updateAllCounters(['num_posts'=>-$numberOfPosts]);
                        
                        $forum = YBoardForum::findOne($targetForumId);
                        $forum->updateAllCounters(['num_topics'=>1]);
                        $forum->updateAllCounters(['num_posts'=>$numberOfPosts]);
                        
                        $this->resetLastForumPost($sourceForumId);
                        $this->resetLastForumPost($targetForumId);
                    }
                    if($merge) {
                        YBoardPost::updateAll(['topic_id'=>$targetTopicId], $criteria);
                        if($move) {
                            $forum = YBoardForum::findOne($targetForumId);
                        } else {
                            $forum = YBoardForum::findOne($sourceForumId);
                        }
                        $forum->updateCounters(array('num_topics'=>-1));
                        $topic = YBoardTopic::findOne($targetTopicId);
                        $topic->updateCounters(array('num_replies'=>$numberOfPosts));
                        $model->delete();
                    } else {
                        $model->save();
                    }
                } else {    // no move or merge involved
                    $model->save();
                }
            } else {
                if(!$model->validate())
                    $json['error'] = $model->errors;
            }
        }
        echo json_encode($json);
        Yii::$app->end();
    }

    /**
     * Delete a post
     */
    public function actionDelete($id) {
        if(!Yii::$app->user->can('app.forum.moderator.delete-post'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        if(isset($_GET['id']))
            $id = $_GET['id'];
            
        $post = YBoardPost::findOne($id);
        if($post === null) {
            throw new NotFoundHttpException(YBoard::t('yboard', 'The requested post does not exist.'));
        }
        $forum = YBoardForum::findOne(YBoardTopic::findOne($post->topic_id)->forum_id);
        
        if($post->original_post==1) //main topic, delete all including replies
        {
            $postDeleted = 0;
            $modelsToDelete = YBoardPost::find()->where(['topic_id'=>$post->topic_id])->all();
            foreach($modelsToDelete as $modelDel)
            {
                $pid = $modelDel->post_id; 
                
                if($modelDel->delete())
                {
                    $postDeleted = $postDeleted-1;
                    YBoardMessage::deleteAll(['post_id'=>$pid]); //delete all reports
                }
            }
            //decrement counts
            $forum->updateCounters(['num_topics'=>$postDeleted]);                
            YBoardLogTopic::deleteAll(['topic_id'=>$post->topic_id]);  //delete record in log
            $topic = YBoardTopic::findOne($post->topic_id)->delete();
        }
        else 
        {
            $forum->updateCounters(['num_posts'=>-1]);  
            $post->delete();           
            //Delete reports on the deleted post 
            YBoardMessage::deleteAll(['post_id'=>$id]);
        }
         
        
        // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
        if(!isset($_GET['ajax']))
            $this->redirect(isset($_POST['returnUrl'])? $_POST['returnUrl'] : ['approval']);
        else
            echo  json_encode(['success'=>true]);
    }  
 
    /**
     * Disapprove a post
     */
    public function actionDisapprove($id) {
        if(!Yii::$app->user->can('app.forum.moderator.delete-post'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        if(isset($_GET['id']))
            $id = $_GET['id'];
            
        $post = YBoardPost::findOne($id);
        if($post === null) {
            throw new NotFoundHttpException(YBoard::t('yboard', 'The requested post does not exist.'));
        }     
        $post->approved = 0;   
        $post->save();  
         
        
        // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
        if(!isset($_GET['ajax']))
            $this->redirect(isset($_POST['returnUrl'])? $_POST['returnUrl'] : ['approval']);
        else
            echo  json_encode(['success'=>true]);
    }  
 

    public function actionReported()
    {
        if(!Yii::$app->user->can('app.forum.moderator.reported'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
 
        $count = [];
        
        
        $query = YBoardMessage::find()
            ->inboxScope() 
            ->reportMsgScope();
          
        $count['reported'] = $query->count();  

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);
        
        return $this->render('report', [
            //'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
            'count'=>$count
        ]);      
    } 

    public function actionTopic() {
        if(!Yii::$app->user->can('app.forum.moderator.topic'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        $json = [];
        if(isset($_POST['id'])) {
            $model = YBoardTopic::findOne($_POST['id']);
            if($model === null) {
                $json['success'] = 'no';
                $json['message'] = YBoard::t('yboard', 'Topic not found.');
            } else {
                $json['success'] = 'yes';
                $json['forum_id'] = $model->forum_id;
                $json['title'] = $model->title;
                $json['locked'] = $model->locked;
                $json['sticky'] = $model->sticky;
                $json['global'] = $model->global;
                $json['approved'] = $model->approved;
                $json['option'] = '<option value=""></option>';
                foreach(YBoardTopic::find()
                ->where(['forum_id' => $model->forum_id])
                ->all() as $topic) {
                    $json['option'] .= '<option value="' . $topic->id. '">' . $topic->title . '</option>';
                }
            }
        } else {
            $json['success'] = 'no';
            $json['message'] = YBoard::t('yboard', 'Topic not found.');
        }
    
        echo json_encode($json);
        Yii::$app->end();
    }

    public function actionGetPost($id)
    {
        if(!Yii::$app->user->can('app.forum.moderator.get-post'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        if(!Yii::$app->user->can('app.forum.moderator.delete-post'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        $json = [];
        $model = YBoardPost::findOne($id);
        if($model==null)
        {
            $json['success'] = 'no';
            $json['error'] = YBoard::t('yboard', 'Post not found.');
        }
        else
        {
            $html = $this->renderAjax('_post', ['post'=>$model]);
            $json['success'] = 'yes';
            $json['html'] = $html;
        }
        echo json_encode($json);
        Yii::$app->end();
    } 
    
    public function actionChangePost()
    {
        if(!Yii::$app->user->can('app.forum.moderator.change-post'))
            throw new ForbiddenHttpException(YBoard::t('yboard', 'You have no enough permission to access this page! If you think its a mistake, please consider reporting to us.'));
        
        $json = [];
        $id = $_POST['YBoardPost']['id']; 
        
        $model = YBoardPost::findOne($id);
        
        if($model==null)
        {
            $json['success'] = 'no';
            $json['error'] = YBoard::t('yboard', 'Post not found.');
        }
        else
        {
            $model->attributes = $_POST['YBoardPost'];
            $model->change_reason = YBoard::t('yboard', 'Post modearated by {user}', ['user'=>YBoardMember::findOne(Yii::$app->user->id)->profile->username]);
            
            if($model->save())
            {
                $json['success'] = 'yes'; 
            }
            else
            {
                $json['success'] = 'no';
                $json['error'] = YBoard::t('yboard', 'Post was not updated.');
            }
        }
        echo json_encode($json);
        Yii::$app->end();
    } 
    
    /* 
     * Reset the last post of a forum
     */
    private function resetLastForumPost($id) {
        $model = YBoardForum::findOne($id); 
        $criteria = "forum_id = $id and approved = 1"; 
        $post = YBoardPost::find()
            ->where($criteria)
            ->orderBy('id DESC')
            ->one();
            
        if($post !== null) {
            $model->last_post_id = $post->id;
        } else {
            $model->last_post_id = null;
        }
        $model->save();
    } 
}