<?php

/**
* @Copyright (C) 2011 - DM Digital
* @license GNU/GPL http://www.gnu.org/copyleft/gpl.html
**/

defined('_JEXEC') or die('Direct Access to this location is not allowed.');

class DMFUMFrontendHelper {

	public static function getUsers($filterSearch = "", $filterGroup = "", $orderBy = ""){

        $user = JFactory::getUser();
        $id = $user->id;
        $myQuery= "
               SELECT DISTINCT #__users.id, name, username, email
               FROM #__users, #__user_usergroup_map
               WHERE user_id = #__users.id
               AND group_id IN (
                    SELECT DISTINCT id_slavegroup
                    FROM #__dmfrontendusermanager_group_permissions
                    WHERE action_view=1
                    AND id_mastergroup IN (
                           SELECT group_id
                           FROM #__users, #__user_usergroup_map
                           WHERE id = " . $id . "
                           AND user_id = id
                    )
               )
        ";
        if ($filterSearch != '') {
            $myQuery .= "AND (
                                #__users.username LIKE '%".$filterSearch."%'
                             OR #__users.name LIKE '%".$filterSearch."%'
                             OR #__users.email LIKE '%".$filterSearch."%'
                         )
            ";
        }

        if ($filterGroup != '') {
            $myQuery .= " AND group_id=" . $filterGroup . " ";
        }

        if ($orderBy != '') {
            $myQuery .= " ORDER BY " . $orderBy;
        }

        return DMData::loadObjectList($myQuery);

    }

    public static function getUserGroups($user){
        
        $myQuery = "SELECT id,title
                        FROM #__user_usergroup_map, #__usergroups
                        WHERE " .$user->id. " = user_id
                        AND group_id = id
                        ORDER BY title ASC
        ";
        return DMData::loadObjectList($myQuery);
    }

    public static function getGroups($action = '') {

        $user = JFactory::getUser();

        $myQuery = "
                    SELECT a.id, a.title, COUNT(DISTINCT b.id) AS level
                    FROM #__usergroups AS a
                    LEFT JOIN #__usergroups AS b ON a.lft > b.lft AND a.rgt < b.rgt
                    WHERE a.id IN (
                                SELECT id_slavegroup
                                FROM #__dmfrontendusermanager_group_permissions
                                WHERE action_" . $action . " = 1
                                AND id_mastergroup IN (
                                                        SELECT c.id
                                                        FROM #__user_usergroup_map, #__usergroups AS c
                                                        WHERE " .$user->id. " = user_id
                                                        AND group_id = id
                                                        ORDER BY title ASC
                                                      )
                                )
                    GROUP BY a.id, a.title, a.lft, a.rgt
                    ORDER BY a.lft ASC
        ";

        $options = DMData::loadObjectList($myQuery);

        foreach ($options as &$option) {
            $option->title = str_repeat('- ', $option->level).$option->title;
        }

        return $options;

    }

    public static function getNonEditableGroupsExistent($userId) {

        $user = JFactory::getUser();

        $myQuery = "
                    SELECT group_id
                    FROM #__user_usergroup_map
                    WHERE user_id = '". $userId .  "'
                    AND group_id NOT IN (
                                SELECT id_slavegroup
                                FROM #__dmfrontendusermanager_group_permissions
                                WHERE action_edit = 1
                                AND id_mastergroup IN (
                                                        SELECT id
                                                        FROM #__user_usergroup_map, #__usergroups
                                                        WHERE '" .$user->id. "' = user_id
                                                        AND group_id = id
                                                        ORDER BY title ASC
                                                      )
                                )
        ";

        return DMData::loadObjectList($myQuery);

    }

    public static function getUserData($userId) {

        $myQuery = "
                SELECT *
                FROM #__users
                WHERE id = '" . $userId .
        "'";

        return DMData::loadObject($myQuery);

    }

    public static function getUserInfo($userId) {

        $user = self::getUserData($userId);
        $canEdit = self::canEdit($userId);
        $canDelete = self::canEdit($userId, 'del');
        $outhtml = DMFUMHHtml::getViewHtml($canEdit, $canDelete, $user);
        return $outhtml;

    }

    public static function deleteUser($userId) {

        if (!self::canEdit($userId, 'del')) return 'false';

        self::addLog($userId, 'delete');

        $myQuery = "DELETE FROM #__user_usergroup_map
                    WHERE user_id = ".$userId
        ;

        DMData::query($myQuery);
        $myQuery = "DELETE FROM #__users
                    WHERE id = ".$userId
        ;
        DMData::query($myQuery);

        return 'OK';
    }

    public static function editUser($params){

        if ($params['name'] == '' || $params['username'] == '' || $params['email'] == '')
            return 'Empty fields';

        if (self::fieldExists(($params['userId']), ($params['username']), 'username'))
            return 'Username in use';

        if (self::fieldExists(($params['userId']), ($params['email']), 'email'))
            return 'Email in use';

        /* Check Password Complexity */
        if (DMVERSION == 30) {
            if ($error = self::_verifyPassword($params['password'])) {
                return $error;
            }
        }

        /* Checks Edit Permissions */
        if ($params['userId'] != 'new') {
            $params['groups'] = self::cleanGroups($params['groups'], 'edit', $params['userId']);
            if (!self::canEdit($params['userId']) && self::canEdit($params['userId'], 'del'))
                return 'canonlydel';
            if (!self::canEdit($params['userId']))
                return 'false';
        } else {
            $params['groups'] = self::cleanGroups($params['groups'], 'add');
        }

        /* Checks if there are groups */
        if (count($params['groups']) == 0)
            return 'no groups';

        $myUser = JTable::getInstance('Users', 'Table');
        $myUser->load($params['userId']);

        $myUser->name = $params['name'];
        $myUser->username = $params['username'];

        /* Generates a random password if it is a new user and the password is empty */
        if (empty($params['password']) && $params['userId'] == 'new') {
            $params['password'] = JUserHelper::genRandomPassword(8);
        }

        /* Generates the passwords with Joomla standards */
        if (!empty($params['password'])) {
            $salt = JUserHelper::genRandomPassword(32);
            $myUser->password = JUserHelper::getCryptedPassword($params['password'] . $salt) . ':' . $salt;
        }

        $myUser->email = $params['email'];
        $myUser->block = $params['blockuser'];
        $myUser->sendEmail = $params['infoemail'];

        if ($params['userId'] == 'new') {
            $myUser->registerDate = JFactory::getDate()->format("Y-m-d H:i:s");
        }
        

        /* Store the user's info */
        if ($myUser->store()) {


            /* Delete all groups associations */
            $db = JFactory::getDBO();
            $myQuery= "
                DELETE
                FROM #__user_usergroup_map
                WHERE user_id = '" . $params['userId'] . "'"
            ;
            $db->setQuery( $myQuery );
            $db->query();

            /* Set the user/groups associations */
            $db = JFactory::getDBO();
            foreach($params['groups'] as $group) {
                $myQuery = "REPLACE INTO #__user_usergroup_map (
                              user_id, group_id
                            ) VALUES (
                             " . $myUser->id ."," . $group . "
                            )

                ";
                $db->setQuery( $myQuery );
                $db->query();
            }
        }
        if ($params['userId'] == 'new') {
            self::addLog($myUser->id, 'add');
            self::sendEmail($myUser, $params['password']);
        } else {
            self::addLog($myUser->id, 'edit');
        }
        return 'OK';
    }

    public static function cleanGroups($groups, $action, $userId = '') {
        $cleanGroups = self::getGroups($action);

        $cleanGroupsIds = array();
        foreach ($cleanGroups as $group) {
            array_push($cleanGroupsIds,$group->id);
        }
        if ($action == 'add') {
            return array_intersect($cleanGroupsIds, $groups);
        } else {
            $g = self::getNonEditableGroupsExistent($userId);
            $t = array_intersect($cleanGroupsIds, $groups);
            foreach ($g as $group) {
                array_push($t, $group->group_id);
            }
            return $t;
        }

    }

    public static function fieldExists($userId, $value, $field) {

        $myQuery = "
                SELECT *
                FROM #__users
                WHERE " . $field . " LIKE '". $value ."'
                AND id != '" . $userId . "'"
        ;

        $result = DMData::loadObject($myQuery);

        if (!empty($result))
            return true;
        else
            return false;
    }
    public static function canEditGroup($groupid) {

        $user = JFactory::getUser();

        $myQuery = "
                SELECT action_edit
                FROM #__dmfrontendusermanager_group_permissions
                WHERE id_mastergroup IN (        SELECT group_id
                                                 FROM #__users, #__user_usergroup_map
                                                 WHERE id = " .$user->id. "
                                                 AND id = user_id)
                AND id_slavegroup = ".$groupid."
                AND action_edit = 1
        ";

        $result = DMData::loadObjectList($myQuery);
        if (!empty($result))
            return true;
        else
            return false;


    }

    public static function canAdd(){

        $user = JFactory::getUser();
        $id = $user->id;
        $myQuery = "SELECT *
                    FROM #__users, #__user_usergroup_map, #__dmfrontendusermanager_group_permissions
                    WHERE #__users.id = " . $id . "
                    AND #__users.id = user_id
                    AND group_id = id_mastergroup
                    AND action_add = 1
        ";
        $result = DMData::loadObjectList($myQuery);
        if (!empty($result))
            return true;
        else
            return false;

    }

    public static function canEdit($slaveId, $action = 'edit') {

        $user = JFactory::getUser();
        if ($slaveId == 'new') return true;

        $myQuery = "
                SELECT action_edit, action_del
                FROM #__dmfrontendusermanager_group_permissions
                WHERE id_mastergroup IN (SELECT group_id
                                                         FROM #__users, #__user_usergroup_map
                                                         WHERE id = " .$user->id. "
                                                         AND id = user_id)
                AND id_slavegroup IN (SELECT group_id
                                                         FROM #__users, #__user_usergroup_map
                                                         WHERE id = " .$slaveId. "
                                                         AND id = user_id)
                AND action_" . $action . "= 1
        ";

        $result = DMData::loadObjectList($myQuery);
        if (!empty($result))
            return true;
        else
            return false;

    }

    public static function addLog($userId, $action) {

        $actionUser = JFactory::getUser();
        $myUserName = DMData::loadResult("SELECT username FROM #__users WHERE id = " . $userId);

        $user = !empty($myUserName) ? $myUserName : $userId;

        $myQuery = "
            INSERT INTO #__dmfrontendusermanager_log
            (action_user_id, user_id, action) VALUES ('" . $actionUser->username . "','" . $user . "','" . $action . "')
        ";

        DMData::query($myQuery);
    }

    public static function checkSession() {

        $user = JFactory::getUser();

        if (empty($user->id)) JFactory::getApplication()->redirect(JURI::root());

    }

    public static function sendEmail($myUser, $password) {

        //Genero la mail di notifica e la invio
        $notifyHtml = self::generateNotifyHtml($myUser, $password);
        $mailer		= JFactory::getMailer();
        $config = JFactory::getConfig();
        $sender = array(
            $config->get( 'mailfrom' ),
            $config->get( 'fromname' )
        );

        $mailer->setSender($sender);
        $mailer->addRecipient($myUser->email);
        $mailer->setSubject('New User Details');
        $mailer->isHTML(true);
        $mailer->setBody($notifyHtml);
        $send = $mailer->Send();

    }

    private static function generateNotifyHtml($myUser, $password) {

        ob_start();
        if (file_exists(JPATH_SITE . DS . 'templates' . DS . JFactory::getApplication()->getTemplate() . DS . 'com_dmfrontendusermanager' . DS . 'html' . DS . 'email.php'))
            require_once(JPATH_SITE . DS . 'templates' . DS . JFactory::getApplication()->getTemplate() . DS . 'com_dmfrontendusermanager' . DS . 'html' . DS . 'email.php');
        else
            require_once(JPATH_COMPONENT . DS . "html" . DS . "email.php");
        $html = ob_get_contents();
        ob_clean();
        return $html;
    }


    /**
     * Check the password complexity
     * @param $password
     */
    protected static function _verifyPassword($password) {

        if (!empty($password)) {

            $params = JComponentHelper::getParams('com_users');
            /**
             * Check the minimum length
             */
            if (strlen($password) < $params->get('minimum_length')) {
                return "Password too short. It has to be long at least " . $params->get('minimum_length') . " characters.";
            }
            /**
             * Check the minimum number of integers
             */
            preg_match_all('/\d/', $password, $integerMatches);
            if (count($integerMatches[0]) < $params->get('minimum_integers')) {
                return "Password needs to have at least " . $params->get('minimum_integers') . " integers.";
            }
            /**
             * Check the minimum number of symbols
             */
            preg_match_all('![^A-z0-9]!i', $password, $symbolMatches);
            if (count($symbolMatches[0]) < $params->get('minimum_symbols')) {
                return "Password needs to have at least " . $params->get('minimum_symbols') . " symbols.";
            }
            /**
             * Check the minimum number of uppercase
             */
            preg_match_all("/[A-Z]/", $password, $uppercaseMatches);
            if (count($uppercaseMatches[0]) < $params->get('minimum_uppercase')) {
                return "Password needs to have at least " . $params->get('minimum_uppercase') . " uppercase letters.";
            }
        }
    }
}

?>
