<?php

/**
 * Model for users.
 *
 * @see XenForo_Model_User
 */
class Waindigo_LoginAsUser_Extend_XenForo_Model_User_Base extends XFCP_Waindigo_LoginAsUser_Extend_XenForo_Model_User
{

    /**
     *
     * @param array $userGroupIds
     * @param array $conditions
     * @param array $fetchOptions
     */
    public function getUsersByUserGroupIds(array $userGroupIds, $conditions = array(), $fetchOptions = array())
    {
        $whereClause = $this->prepareUserConditions($conditions, $fetchOptions);

        $db = $this->_getDb();
        $groupConds[] = 'user.user_group_id IN (' . $db->quote($userGroupIds) . ')';
        foreach ($userGroupIds as $groupId) {
            $groupConds[] = 'FIND_IN_SET(' . $db->quote($groupId) . ', user.secondary_group_ids)';
        }
        return $this->fetchAllKeyed(
            '
			SELECT user.*
			FROM xf_user AS user
			WHERE ' . $whereClause . '
			    AND (' . implode(' OR ', $groupConds) . ')
		    ORDER BY username ASC
		', 'user_id');
    } /* END getUsersByUserGroupIds */

    /**
     * Determines if the viewing user can login as the specified user.
     *
     * @param array $user
     * @param string $errorPhraseKey By ref. More specific error, if available.
     * @param array|null $viewingUser Viewing user reference
     *
     * @return boolean
     */
    public function canLoginAsUser(array $user, &$errorPhraseKey = '', array $viewingUser = null)
    {
        $this->standardizeViewingUserReference($viewingUser);
        if ($viewingUser['user_id'] &&
             XenForo_Permission::hasPermission($viewingUser['permissions'], 'general', 'loginAsDifferentUser')) {
            if (empty($user) || !$user['user_id']) {
                return true;
            }

            $userGroupIds = XenForo_Application::get('options')->waindigo_loginAsUser_userGroups;

            if (is_array($userGroupIds)) {
                foreach (array_keys($userGroupIds) as $userGroupId) {
                    if ($this->isMemberOfUserGroup($user, $userGroupId)) {
                        return true;
                    }
                }
            }
        }
        return false;
    } /* END canLoginAsUser */

    /**
     * Determines if the viewing user can login as different users.
     *
     * @param string $errorPhraseKey By ref. More specific error, if available.
     * @param array|null $viewingUser Viewing user reference
     *
     * @return boolean
     */
    public function canLoginAsUsers(&$errorPhraseKey = '', array $viewingUser = null)
    {
        $this->standardizeViewingUserReference($viewingUser);

        return ($viewingUser['user_id'] &&
             XenForo_Permission::hasPermission($viewingUser['permissions'], 'general', 'loginAsDifferentUser'));
    } /* END canLoginAsUsers */

    /**
     * Determines if the viewing user can login as the specified user without
     * giving a reason.
     *
     * @param array $user
     * @param string $errorPhraseKey By ref. More specific error, if available.
     * @param array|null $viewingUser Viewing user reference
     *
     * @return boolean
     */
    public function canLoginAsUserWithoutReason(array $user, &$errorPhraseKey = '', array $viewingUser = null)
    {
        $this->standardizeViewingUserReference($viewingUser);
        if (empty($user) || !$user['user_id']) {
            return $this->canLoginAsUser($user, $errorPhraseKey, $viewingUser);
        }

        if ($viewingUser['user_id']) {
            if (XenForo_Permission::hasPermission($viewingUser['permissions'], 'general', 'loginAsUserNoReason')) {
                return $this->canLoginAsUser($user, $errorPhraseKey, $viewingUser);
            }

            $userGroupIds = XenForo_Application::get('options')->waindigo_loginAsUser_reasonUserGroups;

            if (is_array($userGroupIds)) {
                foreach (array_keys($userGroupIds) as $userGroupId) {
                    if ($this->isMemberOfUserGroup($user, $userGroupId)) {
                        $errorPhraseKey = 'waindigo_you_must_give_a_reason_to_login_as_user_loginasuser';
                        return false;
                    }
                }
            }
            return $this->canLoginAsUser($user, $errorPhraseKey, $viewingUser);
        }
        $errorPhraseKey = 'waindigo_you_must_give_a_reason_to_login_as_user_loginasuser';
        return false;
    } /* END canLoginAsUserWithoutReason */

    public function getLoginAsUsers(array $conditions = array(), array $viewingUser = null)
    {
        $this->standardizeViewingUserReference($viewingUser);

        $users = array();
        if ($viewingUser['user_id'] &&
             XenForo_Permission::hasPermission($viewingUser['permissions'], 'general', 'loginAsDifferentUser')) {
            $userGroupIds = array_keys(XenForo_Application::get('options')->waindigo_loginAsUser_userGroups);

            if (!empty($userGroupIds)) {
                $users = $this->getUsersByUserGroupIds($userGroupIds, $conditions);
                unset($users[XenForo_Visitor::getUserId()]);
                unset($users[$viewingUser['user_id']]);
            }
        }

        return $users;
    } /* END getLoginAsUsers */
}

if (XenForo_Application::$versionId < 1020000) {

    class Waindigo_LoginAsUser_Extend_XenForo_Model_User extends Waindigo_LoginAsUser_Extend_XenForo_Model_User_Base
    {

        /**
         *
         * @see XenForo_Model_User::updateSessionActivity
         */
        public function updateSessionActivity($userId, $ip, $controllerName, $action, $viewState, array $inputParams,
            $viewDate = null)
        {
            if (!XenForo_Application::isRegistered('session') ||
                 !XenForo_Application::get('session')->isRegistered('loggedInAs') ||
                 !XenForo_Application::get('options')->get('waindigo_loginAsUser_stealthLogin')) {
                parent::updateSessionActivity($userId, $ip, $controllerName, $action, $viewState, $inputParams,
                    $viewDate);
            }
        } /* END updateSessionActivity */
    }
} else {

    class Waindigo_LoginAsUser_Extend_XenForo_Model_User extends Waindigo_LoginAsUser_Extend_XenForo_Model_User_Base
    {

        /**
         *
         * @see XenForo_Model_User::updateSessionActivity
         */
        public function updateSessionActivity($userId, $ip, $controllerName, $action, $viewState, array $inputParams,
            $viewDate = null, $robotKey = '')
        {
            if (!XenForo_Application::isRegistered('session') ||
                 !XenForo_Application::getSession()->isRegistered('loggedInAs') ||
                 !XenForo_Application::get('options')->get('waindigo_loginAsUser_stealthLogin')) {
                parent::updateSessionActivity($userId, $ip, $controllerName, $action, $viewState, $inputParams,
                    $viewDate, $robotKey);
            }
        } /* END updateSessionActivity */
    }
}