Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 39
CRAP
0.00% covered (danger)
0.00%
0 / 589
PermissionService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 39
10302.00
0.00% covered (danger)
0.00%
0 / 589
 __construct
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 3
 __clone
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 2
 getInstance
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 5
 getAllStaffPermissions
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 36
 getAllStudentPermissions
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 36
 staffHasPermission
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 9
 studentHasPermission
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 9
 isNBAEnabled
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 4
 checkAuthorisationOfStaffForQuickReport
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 15
 addAuthGroup
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 17
 getAuthGroupById
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 19
 getAuthGroupByModule
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 updateAuthGroup
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 removeAuthGroup
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getAllStaffsHavingPermission
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 31
 addAuthGroupPermission
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 getAuthGroupPermissionByGroupId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 removeAuthGroupPermission
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 userHasPermission
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 7
 checkAuthGroupPermission
0.00% covered (danger)
0.00%
0 / 1
42.00
0.00% covered (danger)
0.00%
0 / 23
 updateAuthGroupPermissionCache
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 14
 getAuthGroupByUserId
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 17
 addAuthGroupUser
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 18
 updateAuthGroupUser
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 10
 removeAuthGroupUser
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 15
 getAuthPermissionIdByCode
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 getAuthPermissionIdByModuleAndCode
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 9
 createAuthStaffAccountsPermission
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 16
 deleteAuthStaffAccountsPermission
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 11
 toFindTheStaffHasAuthPermission
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getAllUserRolePermissions
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 21
 userRoleHasPermission
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 13
 allAuthPermissionOfModule
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 13
 saveGroupPermission
0.00% covered (danger)
0.00%
0 / 1
20.00
0.00% covered (danger)
0.00%
0 / 27
 staffAssignedToGroupById
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 17
 assignStaffToGroup
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 16
 addListOfStaffToGroup
0.00% covered (danger)
0.00%
0 / 1
12.00
0.00% covered (danger)
0.00%
0 / 17
 removeAllStaffFromGroupByGroupId
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 12
 getUserPermissionModules
0.00% covered (danger)
0.00%
0 / 1
6.00
0.00% covered (danger)
0.00%
0 / 41
<?php
namespace com\linways\core\ams\professional\service;
use com\linways\base\cache\LinCache;
use com\linways\core\ams\professional\service\BaseService;
use com\linways\core\ams\professional\exception\ProfessionalException;
use com\linways\core\ams\professional\dto\SettingsConstents;
use com\linways\core\ams\professional\dto\AuthGroupDetail;
use com\linways\core\ams\professional\mapper\PermissionServiceMapper;
class PermissionService extends BaseService
{
    // /Condition 1 - Presence of a static member variable
    private static $_instance = null;
    private $mapper = [];
    // /Condition 2 - Locked down the constructor
    private function __construct()
    {
        $this->mapper = PermissionServiceMapper::getInstance()->getMapper();
    }
    // Prevent any oustide instantiation of this class
    // /Condition 3 - Prevent any object or instance of that class to be cloned
    private function __clone()
    {
    }
    // Prevent any copy of this object
    // /Condition 4 - Have a single globally accessible static method
    public static function getInstance()
    {
        if (!is_object(self::$_instance)) // or if( is_null(self::$_instance) ) or if( self::$_instance == null )
            self::$_instance = new self();
        return self::$_instance;
    }
    /**
     * Get all permissions assigned to a user. Considers both individual and group permissions
     * @param $staffId id of the staff
     * @return array list of permission codes
     * @throws ProfessionalException
     */
    public function getAllStaffPermissions($staffId)
    {
        $sql = "";
        $permissions = [];
        $response = [];
        $staffId = $this->realEscapeString($staffId);
        $sql = "SELECT 
                    pr.code
                FROM
                    staffaccounts sa
                        INNER JOIN
                    auth_staffaccounts_permission up ON sa.staffID = up.staff_id
                        AND sa.staffID = '$staffId'
                        INNER JOIN
                    auth_permission pr ON pr.id = up.auth_permission_id 
                UNION 
                SELECT 
                    pr.code
                FROM
                    staffaccounts sa
                        INNER JOIN
                    auth_staffaccounts_group ug ON sa.staffID = ug.staff_id
                        AND sa.staffID = '$staffId'
                        INNER JOIN
                    auth_group_permission gp ON gp.auth_group_id = ug.auth_group_id
                        INNER JOIN
                    auth_permission pr ON pr.id = gp.auth_permission_id";
        try {
            $permissions = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        foreach ($permissions as $permission) {
            $response[] = $permission->code;
        }
        return $response;
    }
    /**
     * Get all permissions assigned to a user. Considers both individual and group permissions
     * @param $studentId id of the student
     * @return array list of permission codes
     * @throws ProfessionalException
     */
    public function getAllStudentPermissions($studentId)
    {
        $sql = "";
        $permissions = [];
        $response = [];
        $studentId = $this->realEscapeString($studentId);
        $sql = "SELECT 
                    pr.code
                FROM
                    studentaccount sa
                        INNER JOIN
                    auth_studentaccounts_permission up ON sa.studentID = up.student_id
                        AND sa.studentID = '$studentId'
                        INNER JOIN
                    auth_permission pr ON pr.id = up.auth_permission_id 
                UNION 
                SELECT 
                    pr.code
                FROM
                    studentaccount sa
                        INNER JOIN
                    auth_studentaccounts_group ug ON sa.studentID = ug.student_id
                        AND sa.studentID = '$studentId'
                        INNER JOIN
                    auth_group_permission gp ON gp.auth_group_id = ug.auth_group_id
                        INNER JOIN
                    auth_permission pr ON pr.id = gp.auth_permission_id";
        try {
            $permissions = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        foreach ($permissions as $permission) {
            $response[] = $permission->code;
        }
        return $response;
    }
    /**
     * Check whether the staff has specified permission(s)
     * @param integer $staffId id of the staff
     * @param array $permissions array of permission to be checked EG: ["ABCD", "PQRS"]
     * @return bool true if staff have all the permissions specified, false if atleast one permission check fails
     * @throws ProfessionalException
     */
    public function staffHasPermission($staffId, $permissions)
    {
        $staffPermissions = $this->getAllStaffPermissions($staffId);
        foreach ($permissions as $permission) {
            if (!in_array($permission, $staffPermissions)) {
                return false;
            }
        }
        return true;
    }
    /**
     * @param $studentId
     * @param $permissions
     * @return bool
     * @throws ProfessionalException
     */
    public function studentHasPermission($studentId, $permissions)
    {
        $studentPermissions = $this->getAllStudentPermissions($studentId);
        foreach ($permissions as $permission) {
            if (!in_array($permission, $studentPermissions)) {
                return false;
            }
        }
        return true;
    }
    /**
     * Check whether the NBA is enabled in the college
     *
     * @return boolean
     */
    public static function isNBAEnabled()
    {
        global $COLLEGE_CODE, $NBAaccreditation;
        return in_array($COLLEGE_CODE, $NBAaccreditation);
    }
    /**
     * Check whether a staff is authorised for Quick Reports
     * @param Object $authorisation
     * @return bool
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function checkAuthorisationOfStaffForQuickReport($authorisation)
    {
        $authorisation = $this->realEscapeObject($authorisation);
        $quickReportAuthorisationList = null;
        $sql = "SELECT id, quickReportName, staffId FROM quick_reports_staff_authorization WHERE staffId = " . $authorisation->staffId . " AND quickReportName = '" . $authorisation->quickReportName . "'";
        try {
            $quickReportAuthorisationList = $this->executeQueryForList($sql);
            if (empty ($quickReportAuthorisationList)) {
                return false;
            }
            return true;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return false;
    }
    /********* Vishnu M ( Thu 27 Desc, 2018 ) ***********/
    /**
     * Add auth group
     * @param String $authGroupName
     * @param String $code
     * @param String $module
     * @return Integer $authGroupId
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function addAuthGroup($authGroupName, $code, $module)
    {
        $authGroupName = $this->realEscapeString($authGroupName);
        $authGroupId = null;
        if (empty($authGroupName)) {
            throw new ProfessionalException(ProfessionalException::INVALID_AUTH_GROUP_NAME, "Invalid auth group name");
        }
        if (empty($code)) {
            throw new ProfessionalException(ProfessionalException::INVALID_AUTH_GROUP_CODE, "Invalid auth group code");
        }
        $sql = "INSERT INTO auth_group (name, code, module, created_date, updated_date) VALUES ( '" . $authGroupName . "', '" . $code . "', '" . $module . "', utc_timestamp(), utc_timestamp())";
        try {
            $authGroupId = $this->executeQuery($sql, true)->id;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $authGroupId;
    }
    /**
     * Get auth group
     * @param Integer $authGroupId
     * @param Boolean $includeGroupPermissions
     * @return Object $authGroup
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getAuthGroupById($authGroupId,$includeGroupPermissions=false)
    {
        $authGroupId = $this->realEscapeString($authGroupId);
        $authGroup = null;
        $select = "SELECT ag.id, ag.code, ag.name, ag.module ";
        $joinQuery = "";
        if($includeGroupPermissions)
        {
            $select .= ", agp.auth_permission_id AS permissionId, ap.code AS permissionCode, ap.display_name AS displayName, ap.module AS permissionModule ";
            $joinQuery .= " INNER JOIN auth_group_permission agp ON agp.auth_group_id=ag.id 
            INNER JOIN auth_permission ap ON agp.auth_permission_id=ap.id ";
        }
        $sql = $select." FROM auth_group ag ".$joinQuery." WHERE ag.id = " . $authGroupId;
        try {
            $authGroup = $this->executeQueryForObject($sql,false,$this->mapper[PermissionServiceMapper::GET_AUTH_GROUP]);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $authGroup;
    }
    /**
     * Get authorisation group by module
     * @param String $module - ["STAFF", "ADMIN"]
     * @return Array $authGroups
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getAuthGroupByModule($module)
    {
        $module = strtoupper($this->realEscapeString($module));
        $authGroups = NULL;
        try {
            $sql = "SELECT id, name, code FROM auth_group WHERE module = '" . $module . "'";
            $authGroups = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $authGroups;
    }
    /**
     * Update auth group
     * @param Integer $authGroupId
     * @param String $authGroupName
     * @param String $code
     * @param String $module
     * @return Boolean
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function updateAuthGroup($authGroupId, $authGroupName, $code, $module)
    {
        $authGroupName = $this->realEscapeString($authGroupName);
        $code = $this->realEscapeString($code);
        $module = $this->realEscapeString($module);
        $authGroupId = $this->realEscapeString($authGroupId);
        $sql = "UPDATE auth_group SET name = '" . $authGroupName . "', code = '" . $code . "', module = '" . $module . "', updated_date = utc_timestamp() WHERE id = " . $authGroupId . "";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Remove auth group
     * @param Integer $authGroupId
     * @return Boolean
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function removeAuthGroup($authGroupId)
    {
        $authGroupId = $this->realEscapeString($authGroupId);
        $sql = "DELETE FROM auth_group WHERE id = " . $authGroupId . "";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return true;
    }
    /**
     * Get all staffs assigned to a user. Considers both individual and group permissions
     * @param $staffId id of the staff
     * @return array list of permission codes
     */
    public function getAllStaffsHavingPermission($permissions)
    {
        $sql = "";
        $permissions = $this->realEscapeObject($permissions);
        $sql = "SELECT 
                    sa.staffID,sa.staffName,sa.staffAccount
                FROM
                    staffaccounts sa
                        INNER JOIN
                    auth_staffaccounts_permission up ON sa.staffID = up.staff_id
                        INNER JOIN
                    auth_permission pr ON pr.id = up.auth_permission_id 
                    WHERE pr.code in ('" . implode("','", $permissions) . "')
                UNION 
                SELECT 
                    sa.staffID,sa.staffName,sa.staffAccount
                FROM
                    staffaccounts sa
                        INNER JOIN
                    auth_staffaccounts_group ug ON sa.staffID = ug.staff_id
                        INNER JOIN
                    auth_group_permission gp ON gp.auth_group_id = ug.auth_group_id
                        INNER JOIN
                    auth_permission pr ON pr.id = gp.auth_permission_id
                    WHERE pr.code in ('" . implode("','", $permissions) . "')";
        try {
            $staffs = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $staffs;
    }
    /****** Auth Group Permission ******/
    /**
     * Add permissions to a group
     * @param Integer $authGroupId
     * @param Array $permissions - array of permission to be added EG: ["ABCD", "PQRS"]
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function addAuthGroupPermission($authGroupId, $permissions)
    {
        $authGroupId = $this->realEscapeString($authGroupId);
        $permissions = $this->realEscapeArray($permissions);
        $sql = "INSERT INTO auth_group_permission (auth_group_id, auth_permission_id, created_date, updated_date) SELECT " . $authGroupId . ", id, utc_timestamp(), utc_timestamp() FROM auth_permission WHERE code IN ('" . implode("','", $permissions) . "')";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * To get the group permissions for a group
     * @param Integer $authGroupId
     * @return Array $authGroupPermissions - array of objects
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getAuthGroupPermissionByGroupId($authGroupId)
    {
        $authGroupId = $this->realEscapeString($authGroupId);
        $authGroupPermissions = [];
        $sql = "SELECT agp.auth_group_id, agp.auth_permission_id, ap.code FROM auth_group_permission agp INNER JOIN auth_permission ap ON (agp.auth_permission_id = ap.id) WHERE agp.auth_group_id = " . $authGroupId;
        //  and ap.code <> '".SettingsConstents::ENABLE_STAFF_LOGIN_FROM_ADMIN."'";
        try {
            $authGroupPermissions = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }        
        return $authGroupPermissions;
    }
    /**
     * Delete permissions from a group
     * @param Integer $authGroupId
     * @param Array $permissions - array of permission to be removed EG: ["ABCD", "PQRS"]
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function removeAuthGroupPermission($authGroupId, $permissions)
    {
        $authGroupId = $this->realEscapeString($authGroupId);
        $permissions = $this->realEscapeArray($permissions);
        $sql = "DELETE FROM auth_group_permission WHERE auth_group_id = " . $authGroupId . " AND auth_permission_id IN (SELECT id FROM auth_permission WHERE code IN ('" . implode("','", $permissions) . "'))";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * WIP
     * @param $userType
     * @param Integer $userId - adminId or staffId
     * @param array $permissions array of permission to be checked EG: ["ABCD", "PQRS"]
     * @return bool true if staff have any of the permissions specified
     * @throws ProfessionalException
     */
    public function userHasPermission($userType, $userId, $permissions)
    {
        $userType = $this->realEscapeString($userType);
        $userId = $this->realEscapeString($userId);
        $authGroupId = $this->getAuthGroupByUserId($userId, $userType);
        $status = $this->checkAuthGroupPermission($authGroupId, $permissions);
        return $status;
    }
    /**
     * Check authorisation group permissions for each group
     * Cache is used to store the allowed permissions & it contains an array of permission codes
     * @param Integer $authGroupId
     * @param Array $permissions - array of permissions to be checked. Eg: ["ABCD", "PQRS"].
     * @return Boolean True, False
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function checkAuthGroupPermission($authGroupId, $permissions)
    {
        $authGroupId = $this->realEscapeString($authGroupId);
        global $COLLEGE_CODE;
        $allowedPermissions = [];
        $linCache = new LinCache();
        $authorisationKey = $COLLEGE_CODE . "_AUTHORISATION_GROUP_PERMISSION_" . $authGroupId;
        $allowedPermissions = $linCache->getValue($authorisationKey);
        if (empty ($allowedPermissions)) {
            $groupPermissions = $this->getAuthGroupPermissionByGroupId($authGroupId);
            if (!empty ($groupPermissions)) {
                foreach ($groupPermissions as $authPermission) {
                    $allowedPermissions[] = $authPermission->code;
                }
            }
            $linCache->setValue($authorisationKey, $allowedPermissions);
        }
        // If any permission is allowed - return true
        foreach ($permissions as $permission) {
            if (in_array($permission, $allowedPermissions)) {
                return true;
            }
        }
        return false;
    }
    /**
     * Cache is used to store the allowed permissions to a user group
     * To update Cache for Authorisation Group Permissions when permisions are added or removed
     * @param Integer $authGroupId
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function updateAuthGroupPermissionCache($authGroupId)
    {
        global $COLLEGE_CODE;
        $authGroupId = $this->realEscapeString($authGroupId);
        $linCache = new LinCache();
        $allowedPermissions = [];
        $authorisationKey = $COLLEGE_CODE . "_AUTHORISATION_GROUP_PERMISSION_" . $authGroupId;
        $groupPermissions = $this->getAuthGroupPermissionByGroupId($authGroupId);
        if (!empty ($groupPermissions)) {
            foreach ($groupPermissions as $authPermission) {
                $allowedPermissions[] = $authPermission->code;
            }
        }
        $linCache->setValue($authorisationKey, $allowedPermissions);
    }
    /**
     * Get authorisation group id from userId [staffId, AdminId]
     * @param Integer $userId
     * @param String $userType - ["STAFF", "ADMIN"]
     * @return Integer $authGroupId
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function getAuthGroupByUserId($userId, $userType)
    {
        $userId = $this->realEscapeString($userId);
        $userType = $this->realEscapeString($userType);
        $userType = strtoupper($userType);
        $authGroupId = null;
        if ($userType == "STAFF") {
            $sql = "SELECT auth_group_id FROM auth_staffaccounts_group WHERE staff_id = " . $userId;
        } else if ($userType == "ADMIN") {
            $sql = "SELECT auth_group_id FROM auth_staffaccounts_group WHERE admin_id = " . $userId;
        }
        try {
            $authGroupId = $this->executeQueryForObject($sql)->auth_group_id;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $authGroupId;
    }
    /**
     * Add authorisation group user
     * @param Integer $authGroupId
     * @param Integer $userId
     * @param String $userType - ["STAFF", "ADMIN"]
     * @return \com\linways\base\dto\MySqlResult|null $authStaffaccountsGroupId
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function addAuthGroupUser($authGroupId, $userId, $userType)
    {
        $authGroupId = $this->realEscapeString($authGroupId);
        $userId = $this->realEscapeString($userId);
        $userType = $this->realEscapeString($userType);
        $userType = strtoupper($userType);
        $authStaffaccountsGroupId = NULL;
        if ($userType == "STAFF") {
            $sql = "INSERT INTO auth_staffaccounts_group ( auth_group_id, staff_id, admin_id) VALUES (" . $authGroupId . ", " . $userId . ", NULL )";
        } else if ($userType == "ADMIN") {
            $sql = "INSERT INTO auth_staffaccounts_group ( auth_group_id, staff_id, admin_id) VALUES (" . $authGroupId . ", NULL, " . $userId . " )";
        }
        try {
            $authStaffaccountsGroupId = $this->executeQuery($sql, true);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $authStaffaccountsGroupId;
    }
    /**
     * Update authorisation group user (Delete - Insert)
     * @param Integer $authGroupId
     * @param Integer $userId
     * @param String $userType - ["STAFF", "ADMIN"]
     * @return \com\linways\base\dto\MySqlResult|null $authStaffaccountsGroupId
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function updateAuthGroupUser($authGroupId, $userId, $userType)
    {
        $authStaffaccountsGroupId = NULL;
        try {
            $this->removeAuthGroupUser($userId, $userType);
            $authStaffaccountsGroupId = $this->addAuthGroupUser($authGroupId, $userId, $userType);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $authStaffaccountsGroupId;
    }
    /**
     * Remove authorisation group user
     * @param Integer $authGroupId
     * @param Integer $userId
     * @param String $userType - ["STAFF", "ADMIN"]
     * @throws ProfessionalException
     * @author Vishnu M
     */
    public function removeAuthGroupUser($userId, $userType)
    {
        $userId = $this->realEscapeString($userId);
        $userType = $this->realEscapeString($userType);
        $userType = strtoupper($userType);
        if ($userType == "STAFF") {
            $sql = "DELETE FROM auth_staffaccounts_group WHERE staff_id = " . $userId . " AND admin_id IS NULL";
        } else if ($userType == "ADMIN") {
            $sql = "DELETE FROM auth_staffaccounts_group WHERE admin_id = " . $userId . " AND staff_id IS NULL";
        }
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Get auth permission id by code
     * @param int $code
     * @return
     * @throws ProfessionalException
     */
    public function getAuthPermissionIdByCode($code)
    {
        $code = $this->realEscapeString($code);
        $sql = "select id as authPermissionId from auth_permission where code ='" . $code . "'";
        try {
            return $this->executeQueryForObject($sql)->authPermissionId;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * To get auth-permission id by module and code
     *
     * @param string $module
     * @param string $code
     * @return id
     * @throws ProfessionalException
     * @author Nandu
     */
    public function getAuthPermissionIdByModuleAndCode($module, $code)
    {
        $sql = "SELECT id FROM auth_permission WHERE code='$code' and module='$module'";
        try {
            $id = $this->executeQueryForObject($sql)->id;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $id;
    }
    /**
     * To create an auth permission using auth-permission-id and staffID
     * @param dto $AuthStaffAccountsPermission
     * @throws ProfessionalException
     * @author  Nandu
     */
    public function createAuthStaffAccountsPermission($AuthStaffAccountsPermission)
    {
        $AuthStaffAccountsPermission = $this->realEscapeObject($AuthStaffAccountsPermission);
        $staffID = $AuthStaffAccountsPermission->staff_id;
        $authPermissionID = $AuthStaffAccountsPermission->auth_permission_id;
        $created_by = $AuthStaffAccountsPermission->createdBy;
        $updated_by = $AuthStaffAccountsPermission->updatedBy;
        $hasstaff = PermissionService::getInstance()->toFindTheStaffHasAuthPermission($AuthStaffAccountsPermission);
        $sql = "INSERT INTO auth_staffaccounts_permission (staff_id, auth_permission_id, created_by, updated_by, created_date, updated_date) values('$staffID','$authPermissionID','$created_by','$updated_by',UTC_TIMESTAMP(),UTC_TIMESTAMP())";
        try {
            if (!$hasstaff) {
                $this->executeQueryForObject($sql);
            }
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * To delete an auth permission using auth-permission-id and staffID
     * @param dto $AuthStaffAccountsPermission
     * @throws ProfessionalException
     * @author  Nandu
     */
    public function deleteAuthStaffAccountsPermission($AuthStaffAccountsPermission)
    {
        $AuthStaffAccountsPermission = $this->realEscapeObject($AuthStaffAccountsPermission);
        $staffID = $AuthStaffAccountsPermission->staff_id;
        $authPermissionID = $AuthStaffAccountsPermission->auth_permission_id;
        $sql = "DELETE FROM auth_staffaccounts_permission WHERE staff_id = '$staffID' and auth_permission_id ='$authPermissionID'";
        try {
            $this->executeQuery($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * To create an auth permission using auth-permission-id and staffID
     * @param dto $AuthStaffAccountsPermission
     * @return Object
     * @throws ProfessionalException
     * @author  Nandu
     */
    public function toFindTheStaffHasAuthPermission($AuthStaffAccountsPermission)
    {
        $AuthStaffAccountsPermission = $this->realEscapeObject($AuthStaffAccountsPermission);
        $staffID = $AuthStaffAccountsPermission->staff_id;
        $authPermissionID = $AuthStaffAccountsPermission->auth_permission_id;
        $sql = "SELECT * FROM auth_staffaccounts_permission WHERE staff_id = '$staffID' and auth_permission_id ='$authPermissionID'";
        try {
            $staff = $this->executeQueryForObject($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        return $staff;
    }
    /**
     * TODO: Implement auth role permission groups
     *
     * @param $role
     * @param $userId
     * @param $userType
     * @return array
     * @throws ProfessionalException
     */
    public function getAllUserRolePermissions($roles, $userId, $userType)
    {
        $userId = (int)$this->realEscapeString($userId);
        $roles = $this->realEscapeArray($roles);
        $userType = $this->realEscapeString($userType);
        $response = [];
        $sql = "SELECT pr.code 
                FROM auth_role_permissions arp
                INNER JOIN roles r on arp.role_id = r.id
                INNER JOIN user_account_roles uar on r.id = uar.role_id AND user_id = $userId AND user_type = '$userType'
                INNER JOIN auth_permission pr ON pr.id = arp.auth_permission_id
                WHERE r.code IN ('" . implode("','", $roles) . "')";
        try {
            $permissions = $this->executeQueryForList($sql);
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
        foreach ($permissions as $permission) {
            $response[] = $permission->code;
        }
        return $response;
    }
    /**
     * @param array $role
     * @param integer $userId
     * @param string $userType
     * @param array $permissions
     * @return bool
     * @throws ProfessionalException
     */
    public function userRoleHasPermission($roles, $userId, $userType, $permissions)
    {
        try {
            $staffPermissions = $this->getAllUserRolePermissions($roles, $userId, $userType);
            foreach ($permissions as $permission) {
                if (!in_array($permission, $staffPermissions)) {
                    return false;
                }
            }
            return true;
        } catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(), $e->getMessage());
        }
    }
    /**
     * Group Authentication Permission
     * @param String $module
     * @return List $permissions
     * @throws ProfessionalException
     */
    public function allAuthPermissionOfModule(String $module)
    {
       $module = $this->realEscapeString($module);
       $query = "SELECT id,display_name AS displayName,code,module FROM auth_permission WHERE module='$module'";
       try
       {
           $permissions = $this->executeQueryForList($query);
           return $permissions;
       }
       catch (\Exception $e)
       {
           throw new ProfessionalException($e->getCode(),$e->getMessage());
       }
    }
    /**
     * Save Auth Group Permission
     * @param AuthGroupDetail $group
     * @return Null
     * @throws ProfessionalException
     */
    public function saveGroupPermission(AuthGroupDetail $group)
    {
        $group = $this->realEscapeObject($group);
        try
        {
            if(empty($group->id))
            {
                $group->id = $this->addAuthGroup($group->name,$group->code,$group->module);
            }
            else
            {
                $this->updateAuthGroup($group->id,$group->name,$group->code,$group->module);
            }
            $query = "DELETE FROM auth_group_permission WHERE auth_group_id='$group->id'";
            $this->executeQuery($query);
            $sql = "INSERT INTO auth_group_permission (auth_group_id,auth_permission_id,created_date, updated_date) VALUES ";
            foreach($group->permissions as $permission)
            {
                $values [] = "('".$group->id."','".$permission."',utc_timestamp(), utc_timestamp())";
            }
            $sql .= implode(",",$values);
            $this->executeQuery($sql);
        }
        catch (\Exception $e)
        {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
         
    }
    /**
     * Staff Assigned To Group By Group Id
     * @param String $groupId
     * @return List $staffs
     * @throws  ProfessionalException
    */
    public function staffAssignedToGroupById(String $groupId)
    {
        $id = $this->realEscapeString($groupId);
        $query = "SELECT staffID AS staffId,
            staffName AS staffName,
            staffAccount AS staffAccount 
            FROM staffaccounts 
            WHERE staffID IN (SELECT DISTINCT staff_id FROM auth_staffaccounts_group WHERE auth_group_id='$id' AND staff_id IS NOT NULL)";
        try
        {
            $staffs = $this->executeQueryForList($query);
            return $staffs;
        }
        catch (\Exception $e)
        {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Assign Staffs to Group
     * @param String $groupId
     * @param Array $assignedStaffIds
     * @return Null
     * @throws ProfessionalException
     */
    public function assignStaffToGroup(String $groupId,array $assignedStaffIds)
    {
        $groupId = $this->realEscapeString($groupId);
        $assignedStaffIds = $this->realEscapeArray($assignedStaffIds);
        try
        {
            $this->removeAllStaffFromGroupByGroupId($groupId);
            if(!empty($assignedStaffIds))
            {
                $this->addListOfStaffToGroup($groupId,$assignedStaffIds);
            }
        }
        catch (\Exception $e)
        {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Add staff to Auth Group Permission
     * @param String $groupId
     * @param Array $assignedStaffIds
     * @return Null
     * @throws ProfessionalException
     */
    public function addListOfStaffToGroup(String $groupId,array $assignedStaffIds)
    {
        $id = $this->realEscapeString($groupId);
        $assignedStaffIds = $this->realEscapeArray($assignedStaffIds);
        $query = "INSERT INTO auth_staffaccounts_group (auth_group_id,staff_id)  VALUES ";
        try
        {
            foreach($assignedStaffIds as $staffId) {
                $query  .="('".$id."','".$staffId."'),";
            }
            $assignQuery = rtrim($query,",");
            $this->executeQuery($assignQuery);
        }
        catch (\Exception $e)
        {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    /**
     * Remove all staff from group
     * @param String $groupId
     * @return Null
     * @throws ProfessionalException
     */
    public function removeAllStaffFromGroupByGroupId(String $groupId)
    {
        $id = $this->realEscapeString($groupId);
        $query = "DELETE FROM auth_staffaccounts_group WHERE auth_group_id='$id' AND staff_id IS NOT NULL";
        try
        {
            $this->executeQuery($query);
        }
        catch (\Exception $e)
        {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
    }
    public function getUserPermissionModules ( $userId, $userType ) {
        $modules = [];
        try {
            $sql = "SELECT DISTINCT
                    ap.module
                FROM
                    auth_permission ap
                        INNER JOIN 
                    auth_role_permissions arp ON ap.id = arp.auth_permission_id
                        INNER JOIN 
                    user_account_roles uar ON uar.role_id = arp.role_id
                WHERE
                    uar.user_id = '$userId'
                    AND uar.user_type = '$userType'
            UNION
                SELECT DISTINCT
                    ap.module
                FROM
                    auth_permission ap
                        INNER JOIN 
                    auth_group_permission agp ON ap.id = agp.auth_permission_id
                        INNER JOIN 
                    auth_staffaccounts_group asg ON asg.auth_group_id = agp.auth_group_id
                WHERE
                    asg.staff_id = '$userId'
            UNION
                SELECT DISTINCT
                    ap.module
                FROM
                    auth_permission ap
                        INNER JOIN 
                    auth_staffaccounts_permission asp ON ap.id = asp.auth_permission_id
                WHERE
                    asp.staff_id = '$userId'";
            $modules = $this->executeQueryForList($sql);
            $modules = array_column($modules, 'module');
        }
        catch (\Exception $e) {
            throw new ProfessionalException($e->getCode(),$e->getMessage());
        }
        return $modules;
    }
}
?>