Skip to content
Snippets Groups Projects
UserModel.php 13.95 KiB
<?php

class Auth_UserModel extends Unl_Model {
	
    /**
     * Singleton LDAP instance for new user lookups
     *
     * @var Unl_Ldap
     */
    static protected $_ldap;
    
    static public function find($id)
	{
        if (Unl_Util::isArray($id) && count($id) == 0) {
            return new Unl_Model_Collection(__CLASS__);
        } else if ($id === NULL) {
            return null;
        }
		
		$db = Zend_Registry::get('db');
		
		$select = new Zend_Db_Select($db);
		$select->from(array('u' => 'creqUsers'));
		$select->join(array('p' => 'creqPeople'), 'u.userId = p.userId');
		if (Unl_Util::isArray($id)) {
			$select->where('u.userId IN(?)', $id);
		} else {
			$select->where('u.userId = ?', $id);
		}
		
		$records = $db->query($select)->fetchAll();
		$objects = new Unl_Model_Collection(__CLASS__);
		foreach ($records as $record) {
			$object = Unl_Model_Registry::getInstance()->getOrAdd(new self($record));
			$objectId = $object->getId();
			$objects[$objectId] = $object;
		}
		
		foreach ($objects as $user) {
		    $user->_setClean();
		}
		
		if (Unl_Util::isArray($id)) {
			return $objects;
		} else {
			return $objects->pop();
		}
		
	}

    static public function findAll()
    {
        $db = Zend_Registry::get('db');
        $select = new Zend_Db_Select($db);

        $select->from(array('u' => 'creqUsers'));
        $records = $select->query()->fetchAll();
        $userIds = array();
        foreach ($records as $record) {
            $userIds[] = $record['userId'];
        }
        
        return self::find($userIds);
    }
	
	public static function findByUsername($username)
	{
		$db = Zend_Registry::get('db');
		
		$select = new Zend_Db_Select($db);
		$select->from(array('u' => 'creqUsers'));
		$select->join(array('p' => 'creqPeople'), 'u.userId = p.userId');
		if (Unl_Util::isArray($username)) {
			$select->where('u.username IN(?)', $username);
		} else {
			$select->where('u.username = ?', $username);
		}
		
		$records = $db->query($select)->fetchAll();
		$userIds = array(-1);
		foreach ($records as $record) {
		    $userIds[] = $record['userId'];
		}
		
		$objects = self::find($userIds);
		
		if (Unl_Util::isArray($username)) {
			return $objects;
		} else {
			return $objects->pop();
		}
		
	}
	
	static public function findCurrentUser()
	{
		$username = Zend_Auth::getInstance()->getIdentity();
		if (!$username) {
			throw new Exception('You must be logged in to view this page.');
		}
		
		return self::findByUsername($username);
	}
	
/**
     * Returns a collection of the users that are members of the given group(s).
     *
     * @param Auth_GroupModel|Unl_Model_Collection $group
     * @param bool[optional] $impliedMemberships
     * @return Unl_Model_Collection
     */
    static public function findByParentGroup($group, $impliedMemberships = true)
    {
        if ((Unl_Util::isArray($group) && count($group) == 0) || $group === NULL) {
            return new Unl_Model_Collection(__CLASS__);
        }
        
        $db = Zend_Registry::get('db');
        $select = new Zend_Db_Select($db);

        $select->from(array('u' => 'creqUsers'), array('userId'));
        $select->join(array('m' => 'creqGroupImpliedMemberships'), 'u.primaryGroup = m.childGroup', array('parentGroup'));
        $select->where('m.type = 1');
        if (!$impliedMemberships) {
            $select->where("m.explicit = 'yes'");
        }
        if (Unl_Util::isArray($group)) {
            if (count($group) == 0) {
                return new Unl_Model_Collection(__CLASS__);
            }
            $select->where('parentGroup IN(?)', $group->getId());
        } else {
            $select->where($db->quoteInto('parentGroup = ?', $group->getId()));
        }
        
        $records = $select->query()->fetchAll();
        $userIds = array();
        foreach ($records as $record) {
            $userIds[] = $record['userId'];
        }
        
        self::find($userIds);
    
        $users = array();
        if (Unl_Util::isArray($group)) {
            foreach ($group->getId() as $groupId) {
                $users[$groupId] = new Unl_Model_Collection(__CLASS__);
            }
        } else {
            $users[$group->getId()] = new Unl_Model_Collection(__CLASS__);
        }
        
        foreach ($records as $record) {
            $users[$record['parentGroup']][$record['userId']] = Unl_Model_Registry::getInstance()->get(__CLASS__, $record['userId']);
        }
        
        if (Unl_Util::isArray($group)) {
            return $users;
        } else {
            return $users[$group->getId()];
        }
    }
	
	static public function fetchNew()
	{
        $data = array(
            'userId'       => null,
            'userName'     => null,
            'primaryGroup' => null,
        
            'firstName'  => null,
            'middleName' => null,
            'lastName'   => null,
            'email'      => null,
            'phone'      => null,
            'department' => null
        );

        $new = new self($data);
        $new->_setClean();
        return $new;
	}
	
    /**
     * Searches the LDAP database for the given username, and creates
     * a new Person object with their data.  If no user is found,
     * null will be returned.
     *
     * @param string $userName
     * @return Person
     */
    public function fetchNewFromLdap($userName)
    {
    	$user = self::findByUsername($userName);
    	if ($user) {
    		return $user;
    	}
    	
        if (!self::$_ldap) {
            self::$_ldap = new Unl_Ldap('ldap://localhost:10389');
            self::$_ldap->bind('uid=fpatrack,ou=service,dc=unl,dc=edu', 'eziehuoz');
        }

        $person = self::fetchNew();

        $filter = 'uid='
                . strtr($userName,
                        array(',' => '', '=' => '', ' ' => ''));
        $userInfo = self::$_ldap->search('ou=people,dc=unl,dc=edu', $filter);
        if (count($userInfo) == 0) {
            return null;
        }

        /*
        $departmentIn = $userInfo[0]['unlhrprimarydepartment'][0];
        $department = Departments::getInstance()->fetchByName($departmentIn);
        if(!$department) {
            $departments = Departments::getInstance()->fetchAll();
            $minDiff = 99999;
            $bestMatch = null;
            foreach($departments as $row) {
                $diff = levenshtein($departmentIn, $row->name);
                if($diff < $minDiff) {
                    $minDiff = $diff;
                    $bestMatch = $row;
                }
            }
            $department = $bestMatch;
        }
        */

        $person->setUserName($userName);
        $person->setFirstName($userInfo[0]['givenname'][0]);
        $person->setLastName($userInfo[0]['sn'][0]);
        $person->setEmail($userInfo[0]['mail'][0]);
        $person->setPhone($userInfo[0]['telephonenumber'][0]);
        //$person->setDepartment($department->getPrimaryKey());

        self::save($person);
        
        return $person;
    }
    
    static public function save($models)
    {
        if (!Unl_Util::isArray($models)) {
            $collection = new Unl_Model_Collection(__CLASS__);
            $collection[] = $models;
            $models = $collection;
        }

        $db = Zend_Registry::get('db');
        $db->beginTransaction();

        $unsavedData = array();
        foreach ($models as $id => $model) {
            $unsavedData[$id] = $model->_data;
        }

        try {

            $modelsToInsert = new Unl_Model_Collection(__CLASS__);
            $modelsToUpdate = new Unl_Model_Collection(__CLASS__);
            foreach ($models as $model) {
                if ($model->getId()) {
                    $modelsToUpdate[] = $model;
                } else {
                    $modelsToInsert[] = $model;
                }
            }
            self::_insert($modelsToInsert);
            self::_update($modelsToUpdate);

            $db->commit();
        } catch (Exception $e) {
            $db->rollback();
            foreach ($models as $id => $model) {
                $model->_data = $unsavedData[$id];
            }
            throw $e;
        }
    }

    static protected function _update(Unl_Model_Collection $models)
    {
    	if (count($models) == 0) {
    		return;
    	}
    	
        $db = Zend_Registry::get('db');

        $sql = 'CREATE TEMPORARY TABLE creqUsersUpdate '
             . 'SELECT * FROM creqUsers LIMIT 0';
        $db->query($sql);

        $sql = 'INSERT INTO creqUsersUpdate VALUES ';
        $sqlParts = array();
        foreach ($models as $model) {
            $sqlParts[] = $db->quoteInto('(?, ', $model->_data['userId'])
                        . $db->quoteInto('?, ' , $model->_data['userName'])
                        . $db->quoteInto('?)'  , $model->_data['primaryGroup']);
        }
        $sql .= implode(', ', $sqlParts);
        $db->query($sql);

        $sql = 'UPDATE creqUsers AS a, '
             . '       creqUsersUpdate AS b '
             . 'SET a.userName     = b.userName, '
             . '    a.primaryGroup = b.primaryGroup '
             . 'WHERE a.userId = b.userId ';
        $db->query($sql);
        $db->query('DROP TABLE creqUsersUpdate');
        
        $sql = 'CREATE TEMPORARY TABLE creqPeopleUpdate '
             . 'SELECT * FROM creqPeople LIMIT 0';
        $db->query($sql);

        
        
        $sql = 'INSERT INTO creqPeopleUpdate VALUES ';
        $sqlParts = array();
        foreach ($models as $model) {
            $sqlParts[] = $db->quoteInto('(?, ', $model->_data['userId'])
                        . $db->quoteInto('?, ' , $model->_data['firstName'])
                        . $db->quoteInto('?, ' , $model->_data['middleName'])
                        . $db->quoteInto('?, ' , $model->_data['lastName'])
                        . $db->quoteInto('?, ' , $model->_data['email'])
                        . $db->quoteInto('?, ' , $model->_data['phone'])
                        . $db->quoteInto('?)'  , $model->_data['department']);
        }
        $sql .= implode(', ', $sqlParts);
        $db->query($sql);

        $sql = 'UPDATE creqPeople AS a, '
             . '       creqPeopleUpdate AS b '
             . 'SET a.firstName  = b.firstName, '
             . '    a.middleName = b.middleName, '
             . '    a.lastName   = b.lastName, '
             . '    a.email      = b.email, '
             . '    a.phone      = b.phone, '
             . '    a.department = b.department '
             . 'WHERE a.userId = b.userId ';
        $db->query($sql);
        $db->query('DROP TABLE creqPeopleUpdate');
    }

    static protected function _insert(Unl_Model_Collection $models)
    {
        if (count($models) == 0) {
            return;
        }
    	
        $db = Zend_Registry::get('db');
    
        $sql = 'INSERT INTO creqGroups (type, name, description) VALUES ';
        $sqlParts = array();
        foreach ($models as $model) {
            $sqlParts[] = $db->quoteInto('(?, ', 1)
                        . $db->quoteInto('?, ' , $model->_data['userName'])
                        . $db->quoteInto('?)'  , $model->_data['firstName'] . ' ' . $model->_data['lastName'] . "'s Primary Group");
        }
        $sql .= implode(', ', $sqlParts);
        $db->query($sql);

        $lastId = $db->lastInsertId();
        foreach ($models as $model) {
            $model->_data['primaryGroup'] = $lastId;
            $lastId++;
        }
        
        
        
        $sql = 'INSERT INTO creqUsers (userName, primaryGroup) VALUES ';
        $sqlParts = array();
        foreach ($models as $model) {
            $sqlParts[] = $db->quoteInto('(?, ', $model->_data['userName'])
                        . $db->quoteInto('?)'  , $model->_data['primaryGroup']);
        }
        $sql .= implode(', ', $sqlParts);
        $db->query($sql);

        $lastId = $db->lastInsertId();
        foreach ($models as $model) {
            $model->_data['userId'] = $lastId;
            $lastId++;
        }
        
        
        
        $sql = 'INSERT INTO creqPeople (userId, firstName, middleName, lastName, email, phone, department) VALUES ';
        $sqlParts = array();
        foreach ($models as $model) {
            $sqlParts[] = $db->quoteInto('(?, ', $model->_data['userId'])
                        . $db->quoteInto('?, ' , $model->_data['firstName'])
                        . $db->quoteInto('?, ' , $model->_data['middleName'])
                        . $db->quoteInto('?, ' , $model->_data['lastName'])
                        . $db->quoteInto('?, ' , $model->_data['email'])
                        . $db->quoteInto('?, ' , $model->_data['phone'])
                        . $db->quoteInto('?)'  , $model->_data['department']);
        }
        $sql .= implode(', ', $sqlParts);
        $db->query($sql);
    }
    
    public function __toString()
    {
        return $this->getFirstName() . ' ' . $this->getLastName();
    }
    
	public function getId()
	{
		return $this->_data['userId'];
	}
	
	public function getUsername()
	{
		return $this->_data['userName'];
	}
	public function setUsername($username)
	{
		$this->_data['userName'] = $username;
	}

    public function getFirstName()
    {
        return $this->_data['firstName'];
    }
    public function setFirstName($firstName)
    {
        $this->_data['firstName'] = $firstName;
    }

    public function getMiddleName()
    {
        return $this->_data['middleName'];
    }
    public function setMiddleName($middleName)
    {
        $this->_data['middleName'] = $middleName;
    }
	
	public function getLastName()
	{
		return $this->_data['lastName'];
	}
	public function setLastName($lastName)
	{
		$this->_data['lastName'] = $lastName;
	}
	
    public function getEmail()
    {
        return $this->_data['email'];
    }
    public function setEmail($email)
    {
        $this->_data['email'] = $email;
    }
    
    public function getPhone()
    {
        return $this->_data['phone'];
    }
    public function setPhone($phone)
    {
        $this->_data['phone'] = $phone;
    }
	
	public function getPrimaryGroup()
	{
		return $this->_data['primaryGroup'];
	}
	public function setPrimaryGroup($primaryGroup)
	{
		$this->_data['primaryGroup'] = $primaryGroup;
	}
}