user controller

<?php
namespace api\modules\v1\controllers;

use common\models\BlockUser;
use common\models\Contest;
use common\models\Followers;
use common\models\Likes;
use common\models\User;
use common\models\Video;
use Yii;
use yii\base\Exception;
use yii\db\Query;
use yii\helpers\ArrayHelper;
use yii\web\UploadedFile;

$url = Yii::$app->request->baseUrl;
/** @var User $user */
/** @var Video $video */

/** @var Contest $contest */
class UserController extends BaseApiController
{
    public function actionTestApi()
    {

        // Response params - start
        $response = [];
        $message = "";
        $this->_sendResponse($response, $message);
        // Response params - end

        // to send logical errors - status code will be always 200 but errorCode will be provided at last
        $this->_sendErrorResponse(200, "No input parameters are given", 101);
    }
    /**
     *  This will be called on Social Signup & Social Login - It will return User Object.
     */
    /**
     * @api {post} /user/social-login/ Social login
     * @apiName SocialLogin
     * @apiGroup user
     * @apiDescription This is the action for user SocialLogin.
     * @apiVersion 0.2.0
     *
     * @apiParam {String} loginType.
     * @apiParam {String} fbID.
     * @apiParam {String} fbToken.
     * @apiParam {String} instaID.
     * @apiParam {String} instaToken.
     * @apiParam {String} email.
     *
     * @apiSuccess {String} Social login successful
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *      "errorStatus": false,
     *      "message" : "Social login successful",
     *      "timestamp": 1474968230,
     *       "data" : {
     *           "token":"$2a$13$ii3izsYSz4T\/GjaEyDl8QeLdiDqOYEjP2rd0XER7la3Tfxs8Gwq4u",
     *           "user":{
     *               ....
     *           }
     *       }
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code": error code,
     *       "message": "error message"
     *     }
     */
    public function actionSocialLogin()
    {
        $loginType = Yii::$app->request->post('loginType');
        $fbID = Yii::$app->request->post('fbID');
        $fbToken = Yii::$app->request->post('fbToken');
        $instaID = Yii::$app->request->post('instaID');
        $instaToken = Yii::$app->request->post('instaToken');
        $email = strtolower(Yii::$app->request->post('email'));


        if ($loginType === null || ($fbID === null && $instaID === null) || ($fbID != null && $email === null)) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }

        /** @var User $user */
        if ($loginType == User::LOGIN_TYPE_FACEBOOK) {
            $user = User::findByFbId($fbID);
        } elseif ($loginType == User::LOGIN_TYPE_INSTAGRAM) {
            $user = User::findByInstaId($instaID);
        }

        if ($user) {    // if user exists then send response with user-data.
            $token = $user->getAccessToken();
            $response = ['token' => $token, 'user' => $this->_userData($user)];
            $message = "Social Login Successful";
            $this->_sendResponse($response, $message);
        } else {    // if user doesn't exists then create new user record.
            $user = new User();
            $user->generateAccessToken();
            $user->status = User::STATUS_VERIFICATION_PENDING;

            $user->loginType = $loginType;
            if ($loginType == User::LOGIN_TYPE_FACEBOOK) {
                $user->fb_id = $fbID;
                $user->fb_token = $fbToken;
                $user->email = $email;
                /** @var User $tmpUser */
                $tmpUser = User::findByEmail($email);
                if ($tmpUser != null) {
                    $tmpUser->fb_id = $user->fb_id;
                    $tmpUser->fb_token = $user->fb_token;
                    $user->delete();
                    unset($user);
                    $user = $tmpUser;
                    unset($tmpUser);
                    // get AuthKey
                    $token = $user->getAccessToken();
                    $response = ['token' => $token, 'user' => $this->_userData($user),
                        'code' => 604, 'info' => 'facebook - user has been merged with previous record.'
                    ];
                    $message = "User Updated Successfully";
                    $this->_sendResponse($response, $message);
                }
            } elseif ($loginType == User::LOGIN_TYPE_INSTAGRAM) {
                $user->insta_id = $instaID;
                $user->insta_token = $instaToken;

            }
            if ($user->save(false)) {
                $userData = User::findByPk($user->Id);
                $token = $user->getAccessToken();
                $response = ['token' => $token, 'user' => $this->_userData($userData)];
                $message = "Social login successful";
                $this->_sendResponse($response, $message);
            } else {
                $login_error_msg = "there was a problem with your request please try again";
                $this->_sendErrorResponse(200, $login_error_msg, 501);
            }
        }
    }

    /**
     * @api {post} /user/login/ Login
     * @apiName Login
     * @apiGroup user
     * @apiDescription This is the action for user login.
     * @apiVersion 0.2.0
     *
     * @apiParam {String} loginType.
     * @apiParam {String} fbID.
     * @apiParam {String} fbToken.
     * @apiParam {String} instaID.
     * @apiParam {String} instaToken.
     * @apiParam {String} email.
     *
     * @apiSuccess {String} Successfully logged in
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus": false,
     *       "message" : "Successfully logged in",
     *       "data" : {
     *           "token":"$2a$13$ii3izsYSz4T\/GjaEyDl8QeLdiDqOYEjP2rd0XER7la3Tfxs8Gwq4u",
     *           "user":{
     *               ....
     *           }
     *       }
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *        "code": error code,
     *       "message": "error message"
     *     }
     */

    public function actionLogin()
    {
        $email = strtolower(Yii::$app->request->post('email'));
        $password = Yii::$app->request->post('password');

        if ($email === null || $password === null) {
            $this->_sendErrorResponse(200, "No input parameters are given", 101);
        }
        /** @var User $user */
        $user = User::findByEmail($email);
        $login_error_msg = "The information entered does not match our records. Please double-check your information";
        if ($user === null) {
            // Error: Unauthorized
            $this->_sendErrorResponse(200, $login_error_msg, 102);

        } elseif ($user->password_hash == null && $user->fb_id != null) {
            $login_error_msg = "you have already created your account with us using Facebook, please try to sign-in using Facebook!";
            $this->_sendErrorResponse(200, $login_error_msg, 601);
        } elseif ($user->password_hash == null && $user->insta_id != null) {
            $login_error_msg = "you have already created your account with us using Instagram, please try to sign-in using Instagram!";
            $this->_sendErrorResponse(200, $login_error_msg, 602); // instagram login
        } elseif (!$user->validatePassword($password)) {
            // Error: Password doesn't match
            $login_error_msg = "Sorry, password is wrong!";
            $this->_sendErrorResponse(200, $login_error_msg, 103);

        }
        /*  // To enable User activation & for re-sending active token again
        elseif (!($user->isActive())) {
            $user->sendEmailValidationLink();
            $message = "Please verify your account to proceed. Another verification email has been sent to $user->email.";
            $this->_sendErrorResponse(200, $message, 104);
        }
        */

        // Response params - start
        $token = $user->getAccessToken();
        $response = ['token' => $token, 'user' => $this->_userData($user)];
        $message = "Successfully logged in";
        $this->_sendResponse($response, $message);
        // Response params - end
    }

    /**
     * @api {post} /user/signup/  User sign Up
     * @apiName Signup
     * @apiGroup user
     *
     * @apiParam {String} loginType
     * @apiParam {String} email
     * @apiParam {String} password
     * @apiVersion 0.2.0
     * @apiSuccess {String} User Successfully registered
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus" : "false",
     *       "message" : "User Successfully registered",
     *       "data" : {
     *           "token":"$2a$13$ii3izsYSz4T\/GjaEyDl8QeLdiDqOYEjP2rd0XER7la3Tfxs8Gwq4u",
     *           "user":{
     *              ...
     *           }
     *       }
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionSignup()
    {
        $loginType = Yii::$app->request->post('loginType');
        $email = strtolower(Yii::$app->request->Post('email'));
        $password = Yii::$app->request->post('password');

        if ($email === null || $password === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }

        /** @var User $user */
        $user = User::findByEmail($email);

        if ($user == null) {
            $user = new User();
            $user->generateAccessToken();
            $user->email = $email;
            $user->status = User::STATUS_REGISTRATION_INCOMPLETE;
            $user->loginType = $loginType;
            $user->setPassword($password);

            if ($user->save(false)) {
                $user->sendEmailValidationLink();

                // when user is found - in db
                $token = $user->getAccessToken();
                $userData = $user->findByPk($user->id);
                $response = ['token' => $token, 'user' => $this->_userData($userData)];
                $message = "User Successfully registered";
                $this->_sendResponse($response, $message);
                // Response end
            } else {
                $login_error_msg = "there was a problem with your request please try again";
                $this->_sendErrorResponse(200, $login_error_msg, 501);
            }
        } else {
            if ($user->password_hash == null && $user->fb_id != null) {
                $login_error_msg = "you have already created your account with us using Facebook, please try to sign-in using Facebook!";
                $this->_sendErrorResponse(200, $login_error_msg, 601); // facebook login
            } elseif ($user->password_hash == null && $user->insta_id != null) {
                $login_error_msg = "you have already created your account with us using Instagram, please try to sign-in using Instagram!";
                $this->_sendErrorResponse(200, $login_error_msg, 602); // instagram login
            } elseif ($user->password_hash != null) {
                $login_error_msg = "email is already in use";
                $this->_sendErrorResponse(200, $login_error_msg, 603); // email is already exists
            }
        }
    }

    /**
     * @api {post} /user/signup-step2/ Sign Up Step2
     * @apiName SignupStep2
     * @apiGroup user
     *
     * @apiParam {String} loginType
     * @apiParam {String} email
     * @apiParam {String} username
     * @apiParam {String} name
     * @apiParam {String} password
     * @apiVersion 0.2.0
     * @apiSuccess {String} User updated successfully
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus" : "false",
     *       "message" : "User updated successfully",
     *       "data" : {
     *           "token":"$2a$13$ii3izsYSz4T\/GjaEyDl8QeLdiDqOYEjP2rd0XER7la3Tfxs8Gwq4u",
     *           "user":{
     *              ...
     *           }
     *       }
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionSignupStep2()
    {
        /** @var User $user */
        $user = $this->_checkAuth();

        $loginType = Yii::$app->request->post('loginType');
        $email = strtolower(Yii::$app->request->Post('email'));
        $username = Yii::$app->request->post('username');
        $name = Yii::$app->request->post('name');

        if ($username === null || $name === null || ($loginType == User::LOGIN_TYPE_INSTAGRAM && $email === null)) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        $isCombined = false;
        if ($email != null) {
            /** @var User $tmpUser */
            $tmpUser = User::findByEmail($email);
            if ($tmpUser != null && $tmpUser->id != $user->id) {
                $tmpUser->insta_id = $user->insta_id;
                $tmpUser->insta_token = $user->insta_token;
                $tmpUser->save(false);
                $user->delete();
                unset($user);
                $user = $tmpUser;
                unset($tmpUser);

                // when user is found - in db
                $token = $user->getAccessToken();
                $response = ['token' => $token, 'user' => $this->_userData($user),
                    'code' => 603, 'info' => 'instagram - user has been merged with previous record.'
                ];
                $message = "User updated successfully";
                $this->_sendResponse($response, $message);
            }
        }

        /** @var User $tmpUser */
        $tmpUser = User::findByUsername($username);
        if ($tmpUser) {
            $login_error_msg = "Username already in use!";
            $this->_sendErrorResponse(200, $login_error_msg, 602); // username in use
        }


        if ($email) {
            $user->email = $email;
        }

        $user->username = $username;
        $user->name = $name;
        $user->status = User::STATUS_VERIFICATION_PENDING;
        if ($user->save(false)) {
            if ($email) {
                $user->sendEmailValidationLink();   // send verification link!
            }

            $profile_pic = UploadedFile::getInstanceByName('profilePic');
            if ($profile_pic) {
                $user->uploadProfilePic($profile_pic); // file upload
            }
            // when user is found - in db
            $token = $user->getAccessToken();
            $response = ['token' => $token, 'user' => $this->_userData($user)];
            $message = "User updated successfully";
            $this->_sendResponse($response, $message);
        } else {
            $login_error_msg = "there was a problem with your request please try again";
            $this->_sendErrorResponse(200, $login_error_msg, 501);
        }
    }

    /**
     * @api {post} /user/block/ Block user
     * @apiName Block
     * @apiGroup user
     *
     * @apiParam {Integer} to_id.
     * @apiVersion 0.2.0
     * @apiDescription Block user
     * @apiSuccess {String} User blocked
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus" : "false",
     *       "message" : "The user is successfully blocked",
     *       "data" : {
     *
     *            "blockuser":{
     *              ...
     *           }
     *       }
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionBlock()
    {
        $user = $this->_checkAuth();
        $toUserId = Yii::$app->request->Post('to_id');


        $fromUserId = $user->id;

        if ($toUserId === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        } else {
            if ($user->hasBlocked($toUserId)) {
                $this->_sendErrorResponse(200, "user is already blocked.", 701);
            }

            $blockUser = new BlockUser();
            $blockUser->from_id = $fromUserId;
            $blockUser->to_id = $toUserId;
            $blockUser->save(false);

            $response = ['blockUser' => $blockUser];
            $message = "The user is successfully blocked";
            $this->_sendResponse($response, $message);
        }
    }

    /**
     * @api {post} /user/follow/ Follow user
     * @apiName Follow
     * @apiGroup user
     *
     * @apiParam {Integer} to_id.
     * @apiVersion 0.2.0
     * @apiDescription Follow user
     * @apiSuccess {String} username . " has been followed successfully
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus" : "false",
     *       "message" : "The user has been followed successfully",
     *       "data" : {
     *
     *          "followUser":{
     *              ...
     *           }
     *       }
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionFollow()
    {
        $user = $this->_checkAuth();
        $toUserId = Yii::$app->request->Post('to_id');
        if ($toUserId === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }

        /** @var Followers $objFollow */
        $objFollow = Followers::findOne(['from_id' => $user->id, 'to_id' => $toUserId]);
        if ($objFollow) {
            $objFollow->delete();
            $isFollow = false;
            $message = $objFollow->to->username . " has been un-followed successfully!";
        } else {
            $objFollow = new Followers();
            $objFollow->from_id = $user->id;
            $objFollow->to_id = $toUserId;
            $objFollow->save(false);
            $isFollow = true;
            $message = $objFollow->to->username . " has been followed successfully!";
        }
        $response = ['followUser' => $toUserId, 'isFollow' => $isFollow];
        $this->_sendResponse($response, $message);
    }

    /**
     * @api {post} /user/follow/ Unfollow user
     * @apiName Unfollow
     * @apiGroup user
     *
     * @apiParam {String} user_ids
     * @apiVersion 0.2.0
     * @apiDescription UnFollow user
     * @apiSuccess {String} username . " has been followed successfully
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus" : "false",
     *       "message" : "Unfollowed successfully",
     *       "data" : {
     *
     *          "followUser":{
     *              ...
     *           }
     *       }
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionUnfollow()
    {
        $user = $this->_checkAuth();
        $userIds = Yii::$app->request->post('user_ids');
        if ($userIds === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        } else {
            $userIdObject = explode(",", $userIds);
            foreach ($userIdObject as $userId) {
                $followObject = Followers::find()->where(['to_id' => $userId])
                    ->andWhere(['from_id' => $user->id])
                    ->one();
                if ($followObject) {
                    $followObject->delete();
                }
            }
        }
        $response = [$userIds];
        $message = 'Unfollowed successfully!.';
        $this->_sendResponse($response, $message);

    }

    /**
     * @api {post} /user/FindByFacebook/
     * @apiName FindByFacebook
     * @apiGroup user
     * @apiParam {String} fb_ids.
     * @apiVersion 0.2.0
     * @apiDescription find user by facebook
     * @apiSuccess {String} users find by facebook sent
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus" : "false",
     *       "message" : "users find by facebook sent",
     *       "data" : {
     *           "token":"$2a$13$ii3izsYSz4T\/GjaEyDl8QeLdiDqOYEjP2rd0XER7la3Tfxs8Gwq4u",
     *           "fb_ids":{
     *              ...
     *           }
     *       }
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionFindByFacebook()
    {
        $user = $this->_checkAuth();
        $fbIDs = Yii::$app->request->post('fb_ids');
        if ($fbIDs === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }

        $fbIDs = explode(",", $fbIDs);
        $followIds = $user->getFollowedUsersIds();
        $blockIds = $user->getBlockedUsersIds();

        $fb_users = User::select()->where(['in', 'fb_id', $fbIDs])
            ->andWhere(['not in', 'id', $followIds])
            ->andWhere(['not in', 'id', $blockIds])
            ->andWhere(['NOT', ['username'=>null]])
            ->asArray()->all();

        $fbIDs = ArrayHelper::getColumn($fb_users, 'fb_id');
        $userCount = count($fb_users);

        $response = ['fb_ids' => $fbIDs, 'users' => $fb_users, 'usersCount' => $userCount];
        $message = "users find by facebook sent.";
        $this->_sendResponse($response, $message);
    }

    /**
     * @api {post} /user/FindByInstagram/
     * @apiName FindByInstagram
     * @apiGroup user
     * @apiDescription find user by insta
     * @apiParam {String} insta_ids.
     * @apiVersion 0.2.0
     * @apiSuccess {String} users find by Instagram sent
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus" : "false",
     *       "message" : "users find by instagram sent",
     *       "data" : {
     *           "token":"$2a$13$ii3izsYSz4T\/GjaEyDl8QeLdiDqOYEjP2rd0XER7la3Tfxs8Gwq4u",
     *           "insta_ids":{
     *              ...
     *           }
     *       }
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionFindByInstagram()
    {
        $user = $this->_checkAuth();
        $instaIDs = Yii::$app->request->post('insta_ids');

        if ($instaIDs === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }

        $instaIDs = explode(",", $instaIDs);
        $followIds = $user->getFollowedUsersIds();
        $blockIds = $user->getBlockedUsersIds();
        $insta_users = User::find()->where(['in', 'insta_id', $instaIDs])
            ->andWhere(['not in', 'id', $followIds])
            ->andWhere(['not in', 'id', $blockIds])
            ->andWhere(['NOT', ['username'=>null]])
            ->asArray()->all();

        $instaIds = ArrayHelper::getColumn($insta_users, 'insta_id');
        $userCount = count($insta_users);

        $response = ['insta_ids' => $instaIds, 'users' => $insta_users, 'usersCount' => $userCount];
        $message = "users find by Instagram sent.";
        $this->_sendResponse($response, $message);
    }

    /**
     * @api {get} /user/find-by-popular/ List popular user
     * @apiName FindByPopular
     * @apiGroup user
     *
     *
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} "Popular user  data sent"
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *      "errorStatus" : "false",
     *      "message":"Popular user  data sent!"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionFindByPopular()
    {
        $user = $this->_checkAuth();
        $limit = 25;        // total number of popular users - to send.
        $followIds = $user->getFollowedUsersIds();
        $blockIds = $user->getBlockedUsersIds();
        $popularUser = User::find()
            ->select(['u.*,COUNT(f.id) AS value_occurrence'])->groupBy('to_id')
            ->alias('u')
            ->innerJoin('followers f', 'u.id = f.to_id')
            ->orderBy(['value_occurrence' => SORT_DESC])
            ->andWhere(['not in', 'u.id', $followIds])
            ->andWhere(['not in', 'u.id', $blockIds])
            ->andWhere(['not in', 'u.id', $user->id])
            ->andWhere(['NOT', ['u.username'=>null]])
            ->limit($limit)
            ->asArray()->all();

        $countPopularUser = count($popularUser);
        if ($countPopularUser < $limit) {
            $limit = $limit - $countPopularUser;
            $selectedUserIds = ArrayHelper::getColumn($popularUser, 'id');
            $popularUser2 = User::find()->alias('u')
                ->where(['NOT', ['u.username'=>null]])
                ->andWhere(['not in', 'id', $selectedUserIds])
                ->andWhere(['not in', 'id', $followIds])
                ->andWhere(['not in', 'id', $blockIds])
                ->andWhere(['not in', 'id', $user->id])
                ->limit($limit)
                ->asArray()->all();

            $popularUser = ArrayHelper::merge($popularUser, $popularUser2);
        }

        $userCount = count($popularUser);
        $response = ['users' => $popularUser, 'usersCount' => $userCount];
        $message = "Popular user  data sent";
        $this->_sendResponse($response, $message);

    }

    /**
     * @api {post} /user/Search/ List of followers who follow me
     * @apiName MyFollowers
     * @apiGroup user
     *
     * @apiParam {String} search_term
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} "Your matches record"
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *      "errorStatus":false,
     *      "message":"Your matches record"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionFindPeople()
    {
        $user = $this->_checkAuth();
        $searchTerm = Yii::$app->request->post('search_term');
        if ($searchTerm === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }

        $searchTerms = explode(" ", $searchTerm);

        $followIds = $user->getFollowedUsersIds();
        $blockIds = $user->getBlockedUsersIds();

        $searchResult = [];
        foreach ($searchTerms as $term) {
            $searchUserQuery = User::find()->alias('u');
            $searchUserQuery->andFilterWhere([
                'OR',
                ['LIKE', 'u.name', $term],
                ['=', 'u.username', $term],
//                ['=', 'u.email', $term],
            ]);

            $searchUserQuery->andWhere(['not in', 'u.id', $followIds])
                ->andWhere(['not in', 'u.id', $blockIds])
                ->andWhere(['not in', 'u.id', $user->id]);

            $searchUserQuery->andWhere(['NOT', ['u.username'=>null]]);

            $searchData = $searchUserQuery->asArray()->all();
            $searchResult = ArrayHelper::merge($searchResult, $searchData);
        }

        $userCount = count($searchResult);
        $response = ['users' => $searchResult, 'usersCount' => $userCount];;
        $message = 'Search result sent!';
        $this->_sendResponse($response, $message);
    }


    /**
     * @api {post} /user/follow-users/
     * @apiName FollowUsers
     * @apiGroup user
     * *@apiDescription follow users - FB / Insta OR Popular user - follow
     *
     * @apiParam {String} insta_ids. Or {String} fb_ids
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} follow user successful
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus" : "false",
     *       "message" : "follow user successful",
     *       "countUsers":
     *
     *       }
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionFollowUsers()
    {
        $user = $this->_checkAuth();
        $userIDs = Yii::$app->request->post('user_ids');

        if ($userIDs === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }

        $userIDs = explode(",", $userIDs);

        $follow_users = User::find()->select('id')
            ->where(['in', 'id', $userIDs])
            ->all();

        $countUsers = 0;
        /** @var User $userToFollow */
        foreach ($follow_users as $userToFollow) {
            if (!$user->isFollowing($userToFollow->id)) {
                $followUser = new Followers();
                $followUser->from_id = $user->id;
                $followUser->to_id = $userToFollow->id;
                $countUsers++;
                $followUser->save(false);
            }
        }
        $response = ['no_of_users_followed' => $countUsers];
        $message = "follow user successful.";
        $this->_sendResponse($response, $message);
    }

    /**
     * @api {post} /user/FollowBySocial/
     * @apiName FollowBySocial
     * @apiGroup user
     * *@apiDescription follow by social users are followed
     *
     * @apiParam {String} insta_ids. Or {String} fb_ids
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} follow user successful
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus" : "false",
     *       "message" : "follow user successful",
     *       "countUsers":
     *
     *       }
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionFollowBySocial()
    {
        $user = $this->_checkAuth();
        $fbIDs = Yii::$app->request->post('fb_ids');
        $instaIDs = Yii::$app->request->post('insta_ids');
        $popularIds = Yii::$app->request->post('popular_ids');

        if ($fbIDs === null && $instaIDs === null && $popularIds) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }

        $fbIDs = explode(",", $fbIDs);
        $instaIDs = explode(",", $instaIDs);
        $popularIds = explode(",", $popularIds);

        $follow_users = User::find()->select('id')
            ->where(['in', 'insta_id', $instaIDs])
            ->orWhere(['in', 'fb_id', $fbIDs])
            ->orWhere(['in', 'id', $popularIds])
            ->all();

        $countUsers = 0;
        /** @var User $userToFollow */
        foreach ($follow_users as $userToFollow) {
            if (!$user->isFollowing($userToFollow->id)) {
                $followUser = new Followers();
                $followUser->from_id = $user->id;
                $followUser->to_id = $userToFollow->id;
                $countUsers++;
                $followUser->save(false);
            }
        }
        $response = ['no_of_users_followed' => $countUsers];
        $message = "follow user successful.";
        $this->_sendResponse($response, $message);
    }

    /*
     * @api {get} /user/Profile/
     * @apiName Profile
     * @apiGroup user
     * @apiVersion 0.2.0
     * @apiSuccess {String} User profile data
     * *@apiDescription send user profile detail
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus" : "false",
     *       "message" : "User profile data",
     *        "data" : {
     *        "user":[
     *          {"column1" : "data1", "column2" : "data2", "..."     : "..."},
     *             }
     *           ]
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     */
    public function actionProfile()
    {
        $user = $this->_checkAuth();
        $userID = Yii::$app->request->get('user_id');

        if ($userID === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }

        $blockedIds = $user->getBlockedUsersIds();

        $query = User::select();
        $query->alias('u');
        $query->where(['u.id' => $userID]);


        //Total Video Liked by user
        $totalVideoLiked = (new Query())
            ->select(['count(user_id)'])
            ->from('likes')
            ->where(['likes.user_id' => $userID]);

        //get total likes received on User's videos [all-videos likes].
        $totalReceivedLikes = (new Query())
            ->select('sum(global_likes)')
            ->from('video')
            ->where(['user_id' => $userID]);

        // user count - whom I follow.
        $followingUserCount = (new Query())
            ->select('count("id")')
            ->from('followers')
            ->where(['from_id' => $userID])->andWhere(['not in', 'to_id', $blockedIds]);

        // user count - who follow me.
        $followersUserCount = (new Query())
            ->select('count("id")')
            ->from('followers')
            ->where(['to_id' => $userID])->andWhere(['not in', 'from_id', $blockedIds]);

        $subIsFollow = (new Query())
            ->select('count(id)')
            ->from(Followers::tableName())
            ->where(['from_id' => $user->id])
            ->andWhere(['to_id' => $userID]);


        // no of contest - participated and completed.

        $subQuery = Video::find()->select('contest_id')->where(['user_id' => $userID])->distinct();
        $completedContests = (new Query())
            ->select('count("contest_id")')
            ->from('contest c1')
            ->where(['c1.isActive' => 0])
            ->andWhere(['in', 'c1.id', $subQuery]);

        // no of contest won by - user.
        $wonContests = (new Query())
            ->select('count("contest_id")')
            ->from('contest_winner')
            ->where(['user_id' => $userID]);

        $noOfPostedVideos = (new Query())
            ->select('count(id)')
            ->from('video')
            ->where(['user_id' => $userID]);

        //prepare sub-query for calculation
        $query->addSelect([
            'totalVideoLiked' => $totalVideoLiked,
            'totalReceivedLikes' => $totalReceivedLikes,
            'followingUserCount' => $followingUserCount,
            'followersUserCount' => $followersUserCount,
            'noOfPostedVideos' => $noOfPostedVideos,
            'isFollow' => $subIsFollow,
            'completedContests' => $completedContests, 'wonContests' => $wonContests

        ]);

        $arrUser = $query->asArray()->all();
        $sqlQuery['sql'] = $query->createCommand()->rawSql;
        $response = ['user' => $arrUser];
        $message = 'User profile data';
        $this->_sendResponse($response, $message);
    }
    /*
        * @api {post} /user/settings/
        * @apiName Settings
        * @apiGroup user
        * @apiVersion 0.2.0
        * @apiSuccess {String} User  updated sucessfully
        * *@apiDescription update user photo and username
        *
        * @apiSuccessExample Success-Response:
        *     HTTP/1.1 200 OK
        *     {
        *       "errorStatus" : "false",
        *       "message" : "User profile data",
        *        "data" : {
        *          "errorStatus": false,
        *          {"column1" : "data1", "column2" : "data2", "..."     : "..."},
        *             }
        *     }
        *
        * @apiError ERROR_CODE The code of the error.
        *
        * @apiErrorExample Error-Response:
        *     HTTP/1.1 200 ok
        *     {
        *       "errorStatus": true,
        *       "code" : "[CODE]",
        *       "message": "error message"
        *     }
        */
    public function actionSettings()
    {
        $user = $this->_checkAuth();
        $username = Yii::$app->request->post('username');
        $profile_pic = UploadedFile::getInstanceByName('profile_pic');
        /** @var User checkuserName */
        if ($username) {
            $tmpUser = User::findByUsername($username);
            if ($tmpUser) {
                $this->_sendErrorResponse(200, "User name is exist", 101);
            } else {
                $user->username = $username;
                $user->save(false);
            }
        }
        if ($profile_pic) {
            $user->uploadProfilePic($profile_pic); // file upload
            $user->save(false);
        }
        $response = ['User' => $user];
        $message = "User  updated sucessfully";
        $this->_sendResponse($response, $message);
    }
    /*
       * @api {post} /user/update-settings/
       * @apiName UpdateSettings
       * @apiGroup user
       * @apiVersion 0.2.0
       * @apiSuccess {String} User  updated sucessfully
       * *@apiDescription update user profile
       *
       * @apiSuccessExample Success-Response:
       *     HTTP/1.1 200 OK
       *     {
       *       "errorStatus" : "false",
       *       "message" : "User updated successfully",
       *        "data" : {
       *          "errorStatus": false,
       *          {"column1" : "data1", "column2" : "data2", "..."     : "..."},
       *             }
       *     }
       *
       * @apiError ERROR_CODE The code of the error.
       *
       * @apiErrorExample Error-Response:
       *     HTTP/1.1 200 ok
       *     {
       *       "errorStatus": true,
       *       "code" : "[CODE]",
       *       "message": "error message"
       *     }
       */

    public function actionUpdateSettings()
    {
        $user = $this->_checkAuth();
        $isLocation = Yii::$app->request->post('isLocation');
        $latitude = Yii::$app->request->post('latitude');
        $longitude = Yii::$app->request->post('longitude');

        $countryCode = Yii::$app->request->post('country_code');
        $language = Yii::$app->request->post('language');
        if($isLocation === null && $countryCode === null && $language === null){
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        if($isLocation != null){
            $user->isLocation = $isLocation;

            if($isLocation == 1){
                if($latitude === null || $longitude === null){
                    $this->_sendErrorResponse(200, "lat / long missing", 101);
                }
                $user->latitude = $latitude;
                $user->longitude = $longitude;
            }
        }
        if($countryCode != null){
            $user->country_code = $countryCode;
        }
        if($language != null)
        {
            $user->language = $language;
        }


        $user->save(false);
        $response = ['User' => $this->_userData($user),$user->errors];
        $message = "User updated successfully";
        $this->_sendResponse($response,$message);
    }
    public function actionLogout()
    {
        $user = $this->_checkAuth();
        $user->save(false);
        $response = [];
        $message = "User  logged out successfully";
        $this->_sendResponse($response, $message);
    }
    /**
     * @api {post} /user/forgot-password/ Forgot Password
     *
     *@apiName ForgetPassword
     * @apiGroup user
     *
     * @apiParam {String} email Email of the user.
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} Password reset request sent successfully
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus": false,
     *       "mailResponse" : ,
     *       "message":"Password reset request sent successfully."
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionForgotPassword()
    {
        $email = Yii::$app->request->post('email');
        $user = User::findByEmail($email);
        if ($user == null) {
            $this->_sendErrorResponse(200, "Sorry, wrong email address", 210);
        }
        /** @var User $user */
        if (!User::isPasswordResetTokenValid($user->password_reset_token)) {
            $user->generatePasswordResetToken();
        }

        if ($user->save(false)) {
            $mailResponse = \Yii::$app->mailer->compose(['html' => 'passwordResetToken-html_api', 'text' => 'passwordResetToken-text'], ['user' => $user])
                ->setFrom([\Yii::$app->params['supportEmail'] => \Yii::$app->name . ' Confirmation'])
                ->setTo($user->email)
                ->setSubject('Password reset for ' . \Yii::$app->name)
                ->send();
            $response = ["mailResponse" => $mailResponse];
            $message = "Password reset request sent successfully";
            $this->_sendResponse($response, $message);
        }
    }

    /**
     * @api {post} /user/reset-password/ Reset Password
     * @apiName ResetPassword
     * @apiGroup user
     *
     * @apiParam {String} email
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} User password changed successfully
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus": false,
     *       "message":"User password changed successfully."
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionResetPassword()
    {
        $token = Yii::$app->request->post('reset_password_token');
        $password = Yii::$app->request->post('password');

        if (( $token === null && !isset($_SERVER['HTTP_AUTH_TOKEN'])) || $password === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }

        if(isset($_SERVER['HTTP_AUTH_TOKEN'])){
            $user = $this->_checkAuth();
        }else{
            $isValidToken = User::isActivateTokenValid($token);
            if (!$isValidToken) {
                $this->_sendErrorResponse(200, "sorry, token has expired or invalid!", 310);
            }

            $user = User::findByPasswordResetToken($token);
            /** @var User $user */
            if ($user == null) {
                $this->_sendErrorResponse(200, "sorry, token has expired or invalid!", 311);
            }
        }

        $user->setPassword($password);      // set new password
        $user->generateAccessToken();       // generate new access token
        if ($user->save(false)) {

            if($token!=null){   // if reset password token is not null
                $user->removePasswordResetToken(); // then remove reset password token from db
            }

            // $user->sendEmailValidationLink();

            // when user is found - in db
            $token = $user->getAccessToken();
            /** @var User $userData */
            $userData = $user->findByPk($user->id);
            $response = ['token' => $token, 'user' => $this->_userData($userData)];
            $message = "User password changed successfully";
            $this->_sendResponse($response, $message);
            // Response end
        } else {
            $login_error_msg = "there was a problem with your request please try again";
            $this->_sendErrorResponse(200, $login_error_msg, 501);
        }
    }

    /**
     * @api {get} /user/all-post/ Sent all user post data
     * @apiName AllPost
     * @apiGroup user
     *
     * @apiParam {String} user_id
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} All user post sent
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus": false,
     *       "message":"All user post sent"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionAllPosts()
    {
        $user = $this->_checkAuth();
        $userId = Yii::$app->request->get('user_id');
        $offset = Yii::$app->request->get('offset', 0);
        $limit = \Yii::$app->params['records_limit'];
        if ($userId === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        $allPostQuery = Video::find();
        $allPostQuery->alias('v');
        $allPostQuery->innerJoin('contest c', 'v.contest_id = c.id');
        $allPostQuery->innerJoin('user u', 'v.user_id = u.id');
        $subIsFollow = (new Query())
            ->select('count("id")')
            ->from(Followers::tableName())
            ->where('from_id = ' . $user->id)
            ->andWhere('to_id = u.id');
        //prepare sub-query for calculation of isFollow
        $subIsLiked = (new Query())
            ->select('count(id)')
            ->from(Likes::tableName())
            ->where('user_id = ' . $user->id)
            ->andWhere('video_id = v.id');
        $allPostQuery->addSelect(['v.*', 'c.contest_name', 'u.username', 'u.profile_pic', 'isFollow' => $subIsFollow, 'isLiked' => $subIsLiked]);
        $allPostQuery->orderBy(['trending_likes' => SORT_DESC]);
        $allPostQuery->andWhere(['v.user_id' => $userId]);
        $allPostQuery->andWhere('v.isActive >= 0');
        $allPostQuery->offset($offset);
        $allPostQuery->limit($limit);
        $allPostQuery->asArray();
        $arrVideo = $allPostQuery->all();
        $sqlQuery['sql'] = $allPostQuery->createCommand()->rawSql;
        $p['offset'] = $offset;
        $p['limit'] = $limit;
        $p['record_sent'] = count($arrVideo);
        $response = ['video' => $arrVideo, 'pagination' => $p];
        $message = 'All user post sent';
        $this->_sendResponse($response, $message);
    }

    /**
     * @api {get} /user/all-liked-post/ Sent all previous liked post By user
     * @apiName AllPost
     * @apiGroup user
     *
     * @apiParam {String} user_id id of the user.
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} All user post sent
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus": false,
     *       "message":"All previous liked post are sent"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionAllLikedPosts()
    {
        $user = $this->_checkAuth();
        $userId = Yii::$app->request->get('user_id');
        $offset = Yii::$app->request->get('offset', 0);
        $limit = \Yii::$app->params['records_limit'];
        if ($userId === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        $blockedIds = $user->getBlockedUsersIds();
        $allLikedPostQuery = Video::find();
        $allLikedPostQuery->alias('v');
        $allLikedPostQuery->innerJoin('contest c', 'v.contest_id = c.id');
        $allLikedPostQuery->innerJoin('user u', 'v.user_id = u.id');
        $allLikedPostQuery->innerJoin('likes l', 'l.video_id = v.id');
        $subIsFollow = (new Query())
            ->select('count(id)')
            ->from(Followers::tableName())
            ->where('from_id = ' . $user->id)
            ->andWhere('to_id = u.id');

        //prepare sub-query for calculation of isFollow
        $subIsLiked = (new Query())
            ->select('count(id)')
            ->from(Likes::tableName())
            ->where('user_id = ' . $user->id)
            ->andWhere('video_id = v.id');
        $allLikedPostQuery->addSelect(['v.*', 'c.contest_name', 'u.username', 'u.profile_pic', 'isFollow' => $subIsFollow, 'isLiked' => $subIsLiked]);
        $allLikedPostQuery->andWhere(['l.user_id' => $userId]);
        $allLikedPostQuery->andWhere(['not in', 'v.user_id', $blockedIds]);
        $allLikedPostQuery->andWhere('v.isActive >= 0');
        $allLikedPostQuery->offset($offset);
        $allLikedPostQuery->limit($limit);
        $allLikedPostQuery->asArray();
        $arrVideo = $allLikedPostQuery->all();
        $sqlQuery['sql'] = $allLikedPostQuery->createCommand()->rawSql;
        $p['offset'] = $offset;
        $p['limit'] = $limit;
        $p['record_sent'] = count($arrVideo);
        $response = ['video' => $arrVideo, 'pagination' => $p];
        $message = 'All previous liked post are sent';
        $this->_sendResponse($response, $message);
    }

    /**
     * @api {post} /user/change-profile-pic/ Change user profile pic
     * @apiName ChangeProfilePic
     * @apiGroup user
     *
     * @apiParam {String} profile_pic
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} User profile pic updated successfully
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus":false,
     *      "message":"User profile pic updated successfully"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionChangeProfilePic()
    {
        $user = $this->_checkAuth();
        $profile_pic = UploadedFile::getInstanceByName('profile_pic');
        if ($profile_pic === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        if ($profile_pic) {
            if (file_exists($user->getProfilePic())) {
                unlink($user->getProfilePic());
            }
            $user->uploadProfilePic($profile_pic); // file upload
            $user->save(false);
        }
        $response = ['user' =>$this->_userData($user)];
        $message = "User profile pic updated successfully";
        $this->_sendResponse($response, $message);
    }

    /**
     * @api {post} /user/user-detail/ Sent user detail
     * @apiName UserDetail
     * @apiGroup user
     *
     * @apiParam {String} user_id
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} User detail send
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *      "errorStatus":false,
     *      "message":"User detail send"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionUserDetail()
    {
        $user = $this->_checkAuth();
        $userID = Yii::$app->request->post('user_id');
        if ($userID === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        //$UserDetail= User::findByPk($userID);
        $userDetail = User::select()->where(['id' => $userID])->one();
        $message = "User detail send";
        $response = ['userDetail' => $userDetail];
        $this->_sendResponse($response, $message);
    }
    /**
     * @api {post} /user/change-username/ change user name
     * @apiName ChangeUsername
     * @apiGroup user
     *
     * @apiParam {String} username
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} User name updated successfully
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *      "errorStatus":false,
     *      "message":"User name updated successfully"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionChangeUsername()
    {
        $user = $this->_checkAuth();
        $userName = Yii::$app->request->post('username');
        if ($userName === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        if ($userName) {
            $tmpUser = User::findByUsername($userName);
            if ($tmpUser) {
                $this->_sendErrorResponse(200, "User name is exist", 101);
            } else {
                $user->username = $userName;
                $user->save(false);
                $response = ['user' => $this->_userData($user)];
                $message = "User name updated successfully";
                $this->_sendResponse($response, $message);
            }
        }
    }

    /**
     * @api {post} /user/change-name/ change user name
     * @apiName ChangeName
     * @apiGroup user
     *
     * @apiParam {String} name
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} User's name updated successfully
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *      "errorStatus":false,
     *      "message":"User's name updated successfully"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionChangeName()
    {
        $user = $this->_checkAuth();
        $name = Yii::$app->request->post('name');
        if ($name === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        $user->name = $name;
        $user->save(false);
        $response = ['user' => $this->_userData($user)];
        $message = "User's name updated successfully";
        $this->_sendResponse($response, $message);
    }

    /**
     * @api {post} /user/social-connect
     * @apiName SocialConnect
     * @apiGroup user
     *
     * @apiParam {String} connectType
     * @apiSuccess {String} your social network is connected successfully.
     *
     */
    public function actionSocialConnect()
    {
        $user = $this->_checkAuth();
        $connectType = Yii::$app->request->post('connectType');
        $fbID = Yii::$app->request->post('fbID');
        $fbToken = Yii::$app->request->post('fbToken');
        $instaID = Yii::$app->request->post('instaID');
        $instaToken = Yii::$app->request->post('instaToken');

        if ($connectType === null || ($fbID === null && $instaID === null)) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        if ($connectType  == User::LOGIN_TYPE_FACEBOOK) {
            $user->fb_id = $fbID;
            $user->fb_token = $fbToken;
        } elseif ($connectType == User::LOGIN_TYPE_INSTAGRAM) {
            $user->insta_id = $instaID;
            $user->insta_token= $instaToken;
        }
        $user->save(false);
        $response = ['user' => $this->_userData($user)];
        $message = "Your social network is connected successfully";
        $this->_sendResponse($response, $message);
    }

    /**
     * @api {post} /user/social-disconnect
     * @apiName SocialDisconnect
     * @apiGroup user
     *
     * @apiParam {String} connectType
     * @apiSuccess {String} your social network is disconnected successfully.
     *
     */
    public function actionSocialDisconnect()
    {
        $user = $this->_checkAuth();
        $connectType = Yii::$app->request->post('connectType');

        if ($connectType === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        if ($connectType  == User::LOGIN_TYPE_FACEBOOK) {
            $user->fb_id = null;
            $user->fb_token = null;
        } elseif ($connectType == User::LOGIN_TYPE_INSTAGRAM) {
            $user->insta_id = null;
            $user->insta_token= null;
        }
        $user->save(false);
        $response = ['user' => $this->_userData($user)];
        $message = "your social network is disconnected successfully.";
        $this->_sendResponse($response, $message);
    }

        /**
     * @api {post} /user/change-email/ change user email
     * @apiName ChangeEmail
     * @apiGroup user
     *
     * @apiParam {String} email
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} "Email is updated successfully and verification mail has been sent!
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus": false,
     *      "message":""Email is updated successfully and verification mail has been sent!"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionChangeEmail()
    {
        $user = $this->_checkAuth();
        $email = Yii::$app->request->post('email');
        if ($email === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        if ($email) {
            $tmpUser = User::findByEmail($email);
            if ($tmpUser) {
                $this->_sendErrorResponse(200, "Email address already taken!", 101);
            } else {
                $user->email = $email;
                $user->status = User::STATUS_VERIFICATION_PENDING;

                $user->sendEmailValidationLink();
                $user->save(false);

                $response = ['user' => $this->_userData($user)];
                $message = "Email is updated successfully and verification mail has been sent!";
                $this->_sendResponse($response, $message);
            }
        }

    }


    /**
     * @api {get} /user/followed-by-me/ list of user which is follow by me
     * @apiName FollowedByMe
     * @apiGroup user
     *
     *
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} "Following user data sent"
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus":false,
     *      "message":"Following user data sent"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionFollowedByMe()
    {
        $user = $this->_checkAuth();
        $blockedIds = $user->getBlockedUsersIds();

//        @todo implement pagination here!

        $followedByMe = User::find()->alias('u')->select(['u.*'])->innerJoin('followers f', 'f.to_id = u.id')
            ->where(['f.from_id' => $user->id])
            ->andWhere(['not in', 'u.id', $blockedIds])
            ->asArray()->all();
        $response = ['following' => $followedByMe];
        $message = 'Following user data sent ';
        $this->_sendResponse($response, $message);

    }

    /**
     * @api {get} /user/my-followers/ List of followers who follow me
     * @apiName MyFollowers
     * @apiGroup user
     *
     *
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} "My followers data sent"
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *      "errorStatus":false,
     *      "message":"My followers data sent"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionMyFollowers()
    {
        $user = $this->_checkAuth();
        $blockedIds = $user->getBlockedUsersIds();

        $myFollowers = User::find()->alias('u')->select(['u.*'])->innerJoin('followers f', 'f.from_id = u.id')
            ->where(['f.to_id' => $user->id])
            ->andWhere(['not in', 'u.id', $blockedIds]);

        $isFollowedByme = (new Query())
            ->select('count("id")')
            ->from('followers')
            ->where('followers.to_id = f.from_id')
            ->andwhere(['followers.from_id' => $user->id]);

        $myFollowers->addSelect(['isFollowedByme' => $isFollowedByme]);
        $myFollowers->asArray()->all();
        $FollowersObj = $myFollowers->asArray()->all();
        $response = ['followers' => $FollowersObj];
        $message = 'My followers data sent';
        $this->_sendResponse($response, $message);
    }


    /**
     * @api {get} /user/following list of user which is follow by me
     * @apiName Following
     * @apiGroup user
     *
     *
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} "Following user data sent"
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "errorStatus":false,
     *      "message":"Following user data sent"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */

    public function actionFollowing()
    {
        $user = $this->_checkAuth();

        $userID = Yii::$app->request->get('user_id');
        if ($userID === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        //$UserDetail= User::findByPk($userID);
        /** @var User $otherUser */
        $otherUser = User::select()->where(['id' => $userID])->one();


        $blockedIds = $user->getBlockedUsersIds();

//        @todo implement pagination here!

        $followedByMeQuery = User::find()->alias('u')->select(['u.*'])->innerJoin('followers f', 'f.to_id = u.id')
            ->where(['f.from_id' => $otherUser->id])
            ->andWhere(['not in', 'u.id', $blockedIds]);

        $isFollowedByme = (new Query())
            ->select('count("id")')
            ->from('followers')
            ->where('followers.to_id = f.to_id')
            ->andwhere(['followers.from_id' => $user->id]);

        $followedByMeQuery->addSelect(['isFollowedByme' => $isFollowedByme]);
        $following = $followedByMeQuery->asArray()->all();

        $response = ['following' => $following];
        $message = 'Following user data sent ';
        $this->_sendResponse($response, $message);

    }

    /**
     * @api {get} /user/followers List of followers who follow me
     * @apiName MyFollowers
     * @apiGroup user
     *
     *
     *
     * @apiVersion 0.2.0
     *
     * @apiSuccess {String} "My followers data sent"
     *
     * @apiSuccessExample Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *      "errorStatus":false,
     *      "message":"My followers data sent"
     *     }
     *
     * @apiError ERROR_CODE The code of the error.
     *
     * @apiErrorExample Error-Response:
     *     HTTP/1.1 200 ok
     *     {
     *       "errorStatus": true,
     *       "code" : "[CODE]",
     *       "message": "error message"
     *     }
     */
    public function actionFollowers()
    {
        $user = $this->_checkAuth();

        $userID = Yii::$app->request->get('user_id');
        if ($userID === null) {
            $this->_sendErrorResponse(200, "input parameters missing", 101);
        }
        //$UserDetail= User::findByPk($userID);
        /** @var User $otherUser */
        $otherUser = User::select()->where(['id' => $userID])->one();


        $blockedIds = $user->getBlockedUsersIds();

        $myFollowers = User::find()->alias('u')->select(['u.*'])->innerJoin('followers f', 'f.from_id = u.id')
            ->where(['f.to_id' => $otherUser->id])
            ->andWhere(['not in', 'u.id', $blockedIds]);

        $isFollowedByme = (new Query())
            ->select('count("id")')
            ->from('followers')
            ->where('f.from_id = followers.to_id')
            ->andwhere(['followers.from_id' => $user->id]);
        $myFollowers->addSelect(['isFollowedByme' => $isFollowedByme]);

        $myFollowers->asArray()->all();
        $FollowersObj = $myFollowers->asArray()->all();
        $response = ['followers' => $FollowersObj];
        $message = 'My followers data sent';
        $this->_sendResponse($response, $message);
    }


}


Advertisements