Skip to content
Snippets Groups Projects
Select Git revision
  • 40f956c6bb38fab979c37a8af615fa602c17e158
  • master default
  • disable-new-requests
  • fix-bulletin-view-missing-notes-error
  • add-missing-queue-managers
  • projects-task-53
  • projects-task-51
  • projects-task-43
  • projects-task-24
  • projects-task-31
  • projects-task-32
  • projects-task-8
  • project-setup-docs
  • projects-task-28
  • projects-task-27
  • projects-task-9
  • projects-task-7
  • mass-update-course-codes-in-sections
  • wdn-four
  • learning-outcomes
  • additional-bulletin-pages
  • svn-redesign
  • svn-popups
  • svn-trunk
  • svn-performance
  • svn-tim
26 results

RequestModel.php

Blame
  • user avatar
    Tim Steiner authored
    40f956c6
    History
    RequestModel.php 28.54 KiB
    <?php
    
    class Requests_RequestModel extends Unl_Model
    {
        const FILE_TYPE_SYLLABUS = 'syllabus';
        const FILE_TYPE_CROSSLIST_MEMO = 'crosslist memo';
        const FILE_TYPE_IS_NARRATIVE = 'isNarrative';
        const FILE_TYPE_OTHER = 'other';
    
        static protected $_typeMap;
    
        static public function find($id)
        {
            $db = Zend_Registry::get('db');
    
            $select = new Zend_Db_Select($db);
            $select->from(array('r' => 'creqRequests'));
            $select->join(array('t' => 'creqRequestTypes'), 'r.type = t.requestTypeId', array('type' => 'name', 'module'));
            if (Unl_Util::isArray($id)) {
                if (count($id) == 0) {
                    return new Unl_Model_Collection(__CLASS__);
                }
                $select->where('r.requestId IN (?)', $id);
            } else {
                $select->where('r.requestId = ?', $id);
            }
    
            $records = $select->query()->fetchAll();
            $objects = new Unl_Model_Collection(__CLASS__);
            foreach ($records as $record) {
                $record['files'] = array();
                $object = Unl_Model_Registry::getInstance()->getOrAdd(new self($record));
                $objects[$object->getId()] = $object;
            }
    
        
            $select = new Zend_Db_Select($db);
            $select->from(array('r' => 'creqRequestFiles'));
            $select->join(array('f' => 'creqFiles'), 'r.file = f.fileId');
            if (Unl_Util::isArray($id)) {
                $select->where('r.request IN (?)', $id);
            } else {
                $select->where('r.request = ?', $id);
            }
    
            $records = $select->query()->fetchAll();
            foreach ($records as $record) {
                $objectId = $record['request'];
                $requestFileId = $record['requestFileId'];
                $objects[$objectId]->_data['files'][$requestFileId] = $record;
            }
    
            foreach ($objects as $object) {
            	foreach($object->_data['files'] as $fileId => $file) {
            		if ($file['data'] == '') {
            			$object->_data['files'][$fileId]['data'] = self::_loadFileFromDisk($file['hash']);
            		}
            	}
            }
        
            
            // Most recent approval time
            $select = new Zend_Db_Select($db);
            $select->from(array('h' => 'creqApprovalHistories'), array('request', 'time' => 'MAX(time)'));
            $select->group('request');
            if (Unl_Util::isArray($id)) {
                $select->where('h.request IN (?)', $id);
            } else {
                $select->where('h.request = ?', $id);
            }
    
            $records = $select->query()->fetchAll();
            foreach ($records as $record) {
                $objectId = $record['request'];
                $time = $record['time'];
                $objects[$objectId]->_data['lastApprovalTime'] = $time;
            }
    
            foreach ($objects as $object) {
            	$object->_setClean();
            }
    
            if (Unl_Util::isArray($id)) {
                return $objects;
            } else {
                return $objects[$id];
            }
        }
    
        static public function findByRole($role, $visibleOnly = true)
        {
            $db = Zend_Registry::get('db');
            $select = new Zend_Db_Select($db);
    
            if (Unl_Util::isArray($role)) {
            	if (count($role) == 0) {
            		return new Unl_Model_Collection(__CLASS__);
            	}
                $roleId = array();
                foreach ($role as $aRole) {
                    $roleId[] = $aRole->getId();
                }
            } else {
                $roleId = $role->getId();
            }
    
    
            $records = array();
            $requestIds = array();
            // if user is a member of the "root" role, get all active requests
            if ((Unl_Util::isArray($roleId) && in_array(1, $roleId)) || $roleId == 1) {
                $select = new Zend_Db_Select($db);
                $select->from(array('r' => 'creqRequests'), array('requestId'));
                $select->where('r.complete != ?', 'yes');
    
                $records = array_merge($records, $select->query()->fetchAll());
                foreach ($records as $recordId => $record) {
                    $records[$recordId]['approvalBodyRole'] = 1;
                    $records[$recordId]['visible'] = 'yes';
                    $records[$recordId]['canEdit'] = 'yes';
                    $requestIds[] = $record['requestId'];
                }
            }
    
    
            $select = new Zend_Db_Select($db);
            /* old way
            $select->from(array('q' => 'creqApprovalBodyRoleQueues'), array('approvalBodyRole', 'visible', 'canEdit'));
            $select->join(array('r' => 'creqRequests'), 'q.request = r.requestId', array('requestId'));
            if (Unl_Util::isArray($roleId)) {
                $select->where('q.approvalBodyRole IN (?)', $roleId);
            } else {
                $select->where('q.approvalBodyRole = ?', $roleId);
            }
            if ($visibleOnly) {
                $select->where('q.visible = ?', 'yes');
            }
            */
            $select->from(array('r' => 'creqRequests'), array('requestId'));
            $select->join(array('s' => 'creqRequestStacks'), 'r.stackPointer = s.requestStackId', array());
            $select->join(array('p' => 'creqApprovalActionParticipants'), 's.action = p.approvalAction', array('approvalBodyRole', 'canEdit'));
            if (Unl_Util::isArray($roleId)) {
                $select->where('p.approvalBodyRole IN (?)', $roleId);
            } else {
                $select->where('p.approvalBodyRole = ?', $roleId);
            }
    
            $records = array_merge($select->query()->fetchAll(), $records);
            foreach ($records as $record) {
                $requestIds[] = $record['requestId'];
            }
    
            self::find($requestIds);
    
            $objects = array();
            foreach ($records as $record) {
                $recordRoleId = $record['approvalBodyRole'];
                $requestId = $record['requestId'];
                unset($record['approvalBodyRole']);
                if (!$objects[$recordRoleId] instanceof Unl_Model_Collection) {
                    $objects[$recordRoleId] = new Unl_Model_Collection(__CLASS__);
                }
                $object = Unl_Model_Registry::getInstance()->get(__CLASS__, $requestId);
                $object->_data = array_merge($object->_data, $record);
                $objects[$recordRoleId][$object->getId()] = $object;
            }
    
    
            if (Unl_Util::isArray($roleId)) {
                return $objects;
            } else {
                return $objects[$roleId];
            }
        }
    
        static public function findByWatchingRole($role)
        {
            $db = Zend_Registry::get('db');
            $roleId = $role->getId();
    
    
            $select = new Zend_Db_Select($db);
            $select->from(array('w' => 'creqRequestWatchers'));
            if (Unl_Util::isArray($roleId)) {
            	if (count($roleId) == 0) {
            		return new Unl_Model_Collection(__CLASS__);
            	}
                $select->where('w.watchingApprovalRole IN (?)', $roleId);
            } else {
                $select->where('w.watchingApprovalRole = ?', $roleId);
            }
    
            $records = $select->query()->fetchAll();
            $requestIds = array();
            foreach ($records as $record) {
                $requestIds[] = $record['request'];
            }
    
            self::find($requestIds);
    
            $objects = array();
            foreach ($records as $record) {
                $recordRoleId = $record['watchingApprovalRole'];
                $requestId = $record['request'];
                unset($record['watchingApprovalRole']);
                if (!$objects[$recordRoleId] instanceof Unl_Model_Collection) {
                    $objects[$recordRoleId] = new Unl_Model_Collection(__CLASS__);
                }
                $object = Unl_Model_Registry::getInstance()->get(__CLASS__, $requestId);
                $objects[$recordRoleId][$object->getId()] = $object;
            }
    
    
            if (Unl_Util::isArray($roleId)) {
                return $objects;
            } else {
                return $objects[$roleId];
            }
        }
    
        static public function findByUser($user, $completeOnly = false)
        {
            $db = Zend_Registry::get('db');
            $userId = $user->getId();
    
            $select = new Zend_Db_Select($db);
            $select = new Zend_Db_Select($db);
            $select->from(array('r' => 'creqRequests'), array('owner', 'requestId'));
            if (Unl_Util::isArray($userId)) {
                $select->where('r.owner IN (?)', $userId);
            } else {
                $select->where('r.owner = ?', $userId);
            }
            if ($completeOnly) {
                $select->where('r.complete = ?', 'no');
            }
    
            $records = $select->query()->fetchAll();
            $requestIds = array();
            foreach ($records as $recordId => $record) {
                $records[$recordId]['visible'] = 'yes';
                $records[$recordId]['canEdit'] = $records[$recordId]['submitterAttentionRequired'];
                $requestIds[] = $record['requestId'];
            }
    
            self::find($requestIds);
    
            $objects = array();
    
            if (Unl_Util::isArray($userId)) {
                foreach ($userId as $aUserId) {
                    $objects[$aUserId] = new Unl_Model_Collection(__CLASS__);
                }
            } else {
                $objects[$userId] = new Unl_Model_Collection(__CLASS__);
            }
    
            foreach ($records as $record) {
                $ownerId = $record['owner'];
                $requestId = $record['requestId'];
                unset($record['approvalBodyRole']);
                if (!$objects[$ownerId] instanceof Unl_Model_Collection) {
                    $objects[$ownerId] = new Unl_Model_Collection(__CLASS__);
                }
                $object = Unl_Model_Registry::getInstance()->get(__CLASS__, $requestId);
                $object->_data = array_merge($object->_data, $record);
                $objects[$ownerId][$object->getId()] = $object;
            }
    
    
            if (Unl_Util::isArray($userId)) {
                return $objects;
            } else {
                return $objects[$userId];
            }
        }
    
        static protected function _loadTypeMap()
        {
            if (Unl_Util::isArray(self::$_typeMap)) {
                return;
            }
    
            $db = Zend_Registry::get('db');
            $select = new Zend_Db_Select($db);
            $select->from('creqRequestTypes');
            $data = $select->query()->fetchAll();
            foreach ($data as $row) {
                self::$_typeMap[$row['requestTypeId']] = $row['name'];
            }
        }
    
        static protected function _getTypeIdFromName($name)
        {
            self::_loadTypeMap();
            return array_search($name, self::$_typeMap);
        }
    
        static protected function _getTypeNameFromId($id)
        {
            self::_loadTypeMap();
            return self::$_typeMap[$id];
        }
        
        static public function getTypes()
        {
        	self::_loadTypeMap();
        	return self::$_typeMap;
        }
    
        static public function fetchNew()
        {
            $data = array(
                'requestId'     => null,
                'owner'         => null,
                'justification' => null,
                'stackPointer'  => null,
                'state'         => null,
                'submitterAttentionRequired' => 'no',
                'type'          => null,
                'complete'      => 'no',
                'module'        => null,
                'files'         => array()
            );
    
            $new = new self($data);
            $new->_setClean();
            return $new;
        }
    
        static public function save($models)
        {
        	$db = Zend_Registry::get('db');
        	$db->beginTransaction();
    
        	$unsavedData = array();
        	foreach ($models as $id => $model) {
        	    $unsavedData[$id] = $model->_data;
        	}
    
        	try {
            	if (!Unl_Util::isArray($models)) {
            		$collection = new Unl_Model_Collection(__CLASS__);
            		$collection[] = $models;
            		$models = $collection;
            	}
    
            	$modelsToInsert = array();
            	$modelsToUpdate = array();
            	$requestTableColumns = array('owner', 'justification', 'stackPointer', 'state', 'submitterAttentionRequired', 'type', 'complete');
            	foreach ($models as $model) {
        	        $data = array_intersect_key($model->_data, array_flip($requestTableColumns));
        	        $cleanData = array_intersect_key($model->_cleanData, array_flip($requestTableColumns));
        	        if ($data == $cleanData) {
        	        	continue;
        	        }
        	        if ($model->getId()) {
                        $modelsToUpdate[] = $model;
        	        } else {
                        $modelsToInsert[] = $model;
        	        }
            	}
            	self::_insertRequestRows($modelsToInsert);
            	self::_updateRequestRows($modelsToUpdate);
    
                $filesToInsert = array();
                $filesToUpdate = array();
            	foreach ($models as $model) {
            		foreach ($model->_data['files'] as $fileId => $file) {
            			$model->_data['files'][$fileId]['request'] = $model->getId();
    
            			$fileRef = array(
                            'model'  => $model,
                            'fileId' => $fileId
                        );
    
            			if ($fileId < 0) {
                            $filesToInsert[] = $fileRef;
            			} else {
            				$filesToUpdate[] = $fileRef;
            			}
            		}
            	}
            	$filesToDelete = array();
            	foreach ($models as $model) {
                    $cleanFileIds = array_keys($model->_cleanData['files']);
                    $dirtyFileIds = array_keys($model->_data['files']);
        	        foreach ($cleanFileIds as $cleanFileId) {
        	            if (!in_array($cleanFileId, $dirtyFileIds)) {
        	                $filesToDelete[] = $model->_cleanData['files'][$cleanFileId];
        	            }
        	        }
            	}
            	self::_insertFileRows($filesToInsert);
            	self::_updateFileRows($filesToUpdate);
            	self::_deleteFileRows($filesToDelete);
            	
            	foreach ($models as $model) {
            		foreach (array_keys($model->_data['files']) as $fileKey) {
            			if ($fileKey >= 0) {
            				continue;
            			}
            			$newFileKey = $model->_data['files'][$fileKey]['requestFileId'];
            			$model->_data['files'][$newFileKey] = $model->_data['files'][$fileKey];
            			unset($model->_data['files'][$fileKey]);
            		}
            	}
    
            	foreach ($models as $model) {
            		$model->_setClean();
            	}
    
                $db->commit();
    
        	} catch (Exception $e) {
        	    $db->rollback();
            	foreach ($models as $id => $model) {
            	    $model->_data = $unsavedData[$id];
            	}
        	    throw $e;
        	}
        }
    
        static protected function _insertRequestRows($models)
        {
            if (count($models) == 0) {
                return;
            }
    
            $db = Zend_Registry::get('db');
    
            $sql = 'INSERT INTO creqRequests (owner, justification, stackPointer, state, submitterAttentionRequired, type, complete) VALUES ';
            $sqlParts = array();
            foreach ($models as $model) {
                $sqlParts[] = $db->quoteInto('(?, ', $model->_data['owner'])
                            . $db->quoteInto('?, ' , $model->_data['justification'])
                            . $db->quoteInto('?, ' , $model->_data['stackPointer'])
                            . $db->quoteInto('?, ' , $model->_data['state'])
                            . $db->quoteInto('?, ' , $model->_data['submitterAttentionRequired'])
                            . $db->quoteInto('?, ' , self::_getTypeIdFromName($model->_data['type']))
                            . $db->quoteInto('?)'  , $model->_data['complete']);
            }
            $sql .= implode(', ', $sqlParts);
            $db->query($sql);
    
            $lastId = $db->lastInsertId();
            foreach ($models as $model) {
            	$model->_data['requestId'] = $lastId;
            	$lastId++;
            }
        }
    
        static protected function _updateRequestRows($models)
        {
            if (count($models) == 0) {
            	return;
            }
    
            $db = Zend_Registry::get('db');
    
            $sql = 'CREATE TEMPORARY TABLE creqRequestsUpdate '
                 . 'SELECT * FROM creqRequests LIMIT 0';
            $db->query($sql);
    
            $sql = 'INSERT INTO creqRequestsUpdate VALUES ';
            $sqlParts = array();
            foreach ($models as $model) {
                $sqlParts[] = $db->quoteInto('(?, ', $model->_data['requestId'])
                            . $db->quoteInto('?, ' , $model->_data['owner'])
                            . $db->quoteInto('?, ' , $model->_data['justification'])
                            . $db->quoteInto('?, ' , $model->_data['stackPointer'])
                            . $db->quoteInto('?, ' , $model->_data['state'])
                            . $db->quoteInto('?, ' , $model->_data['submitterAttentionRequired'])
                            . $db->quoteInto('?, ' , self::_getTypeIdFromName($model->_data['type']))
                            . $db->quoteInto('?)'  , $model->_data['complete']);
            }
            $sql .= implode(', ', $sqlParts);
            $db->query($sql);
    
            $sql = 'UPDATE creqRequests AS a, '
                 . '       creqRequestsUpdate AS b '
                 . 'SET a.requestId                  = b.requestId, '
                 . '    a.owner                      = b.owner, '
                 . '    a.justification              = b.justification, '
                 . '    a.stackPointer               = b.stackPointer, '
                 . '    a.state                      = b.state, '
                 . '    a.submitterAttentionRequired = b.submitterAttentionRequired, '
                 . '    a.type                       = b.type, '
                 . '    a.complete                   = b.complete '
                 . 'WHERE a.requestId = b.requestId ';
            $db->query($sql);
            $db->query('DROP TABLE creqRequestsUpdate');
    
        }
    
        static protected function _insertFileRows($models)
        {
            if (count($models) == 0) {
                return;
            }
    
            $db = Zend_Registry::get('db');
    
            $sql = 'INSERT INTO creqFiles (title, mimeType, data, hash) VALUES ';
            $sqlParts = array();
            foreach ($models as $model) {
            	$file = $model['model']->_data['files'][$model['fileId']];
                $file['hash'] = hash('whirlpool', $file['data']);
            	if (strlen($file['data']) >= 0) {
            		self::_saveFileToDisk($file['data']);
            		$file['data'] = "''";
            	} else {
            		$file['data'] = '0x' . bin2hex($file['data']);
            	}
                $sqlParts[] = $db->quoteInto('(?, ', $file['title'])
                            . $db->quoteInto('?, ' , $file['mimeType'])
                            . $file['data'] . ', '
                            . $db->quoteInto('?)'  , $file['hash']);
            }
            $sql .= implode(', ', $sqlParts);
            
            $db->query($sql);
    
            $lastId = $db->lastInsertId();
            foreach ($models as $model) {
                $model['model']->_data['files'][$model['fileId']]['fileId'] = $lastId;
                $lastId++;
            }
    
            $sql = 'INSERT INTO creqRequestFiles (file, request, type) VALUES ';
            $sqlParts = array();
            foreach ($models as $model) {
            	$file = $model['model']->_data['files'][$model['fileId']];
            	$model = $model['model'];
            	$sqlParts[] = $db->quoteInto('(?, ', $file['fileId'])
                            . $db->quoteInto('?, ' , $model->getId())
                            . $db->quoteInto('?)'  , $file['type']);
            }
            $sql .= implode(', ', $sqlParts);
    
            $db->query($sql);
            $lastId = $db->lastInsertId();
            foreach ($models as $model) {
                $model['model']->_data['files'][$model['fileId']]['requestFileId'] = $lastId;
                $lastId++;
            }
        }
    
        static protected function _updateFileRows($models)
        {
        	if (count($models) == 0) {
                return;
            }
    
            $db = Zend_Registry::get('db');
    
            $sql = 'CREATE TEMPORARY TABLE creqFilesUpdate '
                 . 'SELECT * FROM creqFiles LIMIT 0';
            $db->query($sql);
    
            $sql = 'INSERT INTO creqFilesUpdate VALUES ';
            $sqlParts = array();
            foreach ($models as $model) {
                $file = $model['model']->_data['files'][$model['fileId']];
                $file['hash'] = hash('whirlpool', $file['data']);
                if (strlen($file['data']) >= 0) {
                    self::_saveFileToDisk($file['data']);
                    $file['data'] = "''";
                } else {
                	$file['data'] = '0x' . bin2hex($file['data']);
                }
                $sqlParts[] = $db->quoteInto('(?, ', $file['fileId'])
                            . $db->quoteInto('?, ' , $file['title'])
                            . $db->quoteInto('?, ' , $file['mimeType'])
                            . $file['data'] . ', '
                            . $db->quoteInto('?)'  , $file['hash']);
            }
            $sql .= implode(', ', $sqlParts);
            
            $db->query($sql);
    
            $sql = 'UPDATE creqFiles AS a, '
                 . '       creqFilesUpdate AS b '
                 . 'SET a.title    = b.title, '
                 . '    a.mimeType = b.mimeType, '
                 . '    a.data     = b.data, '
                 . '    a.hash     = b.hash '
                 . 'WHERE a.fileId = b.fileId ';
    
            $db->query($sql);
            $db->query('DROP TABLE creqFilesUpdate');
    
    
    
    
    
            $sql = 'CREATE TEMPORARY TABLE creqRequestFilesUpdate '
                 . 'SELECT * FROM creqRequestFiles LIMIT 0';
            $db->query($sql);
    
            $sql = 'INSERT INTO creqRequestFilesUpdate VALUES ';
            $sqlParts = array();
            foreach ($models as $model) {
                $file = $model['model']->_data['files'][$model['fileId']];
                $model = $model['model'];
                $sqlParts[] = $db->quoteInto('(?, ', $file['requestFileId'])
                            . $db->quoteInto('?, ' , $file['fileId'])
                            . $db->quoteInto('?, ' , $model->getId())
                            . $db->quoteInto('?)'  , $file['type']);
            }
            $sql .= implode(', ', $sqlParts);
            $db->query($sql);
    
    
            $sql = 'UPDATE creqRequestFiles AS a, '
                 . '       creqRequestFilesUpdate AS b '
                 . 'SET a.file    = b.file, '
                 . '    a.request = b.request, '
                 . '    a.type    = b.type '
                 . 'WHERE a.requestFileId = b.requestFileId ';
    
            $db->query($sql);
            $db->query('DROP TABLE creqRequestFilesUpdate');
    
        }
    
        static protected function _deleteFileRows($models)
        {
            if (count($models) == 0) {
                return;
            }
    
            $db = Zend_Registry::get('db');
    
            $requestFileIds = array();
            $fileIds = array();
            foreach ($models as $model) {
            	$requestFileIds[] = $model['requestFileId'];
            	$fileIds[] = $model['fileId'];
            }
            $sql = $db->quoteInto('DELETE FROM creqRequestFiles WHERE requestFileId IN (?)', $requestFileIds);
            $db->query($sql);
            $sql = $db->quoteInto('DELETE FROM creqFiles WHERE fileId IN (?)', $fileIds);
            $db->query($sql);
        }
    
        static protected function _saveFileToDisk($data)
        {
            $hash = hash('whirlpool', $data);
            $path = APPLICATION_DIR
                  . DIRECTORY_SEPARATOR
                  . 'uploads'
                  . DIRECTORY_SEPARATOR
                  . substr($hash, 0, 1)
                  . DIRECTORY_SEPARATOR
                  . substr($hash, 1, 2);
                  
            if (!file_exists($path)) {
                @mkdir($path, 0755, true);
            }
            file_put_contents($path . DIRECTORY_SEPARATOR . $hash, $data);
        }
    
        static protected function _loadFileFromDisk($hash)
        {
            $path = APPLICATION_DIR
                  . DIRECTORY_SEPARATOR
                  . 'uploads'
                  . DIRECTORY_SEPARATOR
                  . substr($hash, 0, 1)
                  . DIRECTORY_SEPARATOR
                  . substr($hash, 1, 2);
    
            if (!file_exists($path)) {
                @mkdir($path, 0755, true);
            }
            $data = @file_get_contents($path . DIRECTORY_SEPARATOR . $hash);
            return $data;
        }
        
        public function __sleep()
        {
        	foreach ($this->_data['files'] as &$file) {
        		if (!$file['data']) {
        			continue;
        		}
        		self::_saveFileToDisk($file['data']);
        		$file['data'] = '';
        	}
        	return array_keys(get_object_vars($this));
        }
        
        public function __wakeup()
        {
            foreach ($this->_data['files'] as &$file) {
            	if ($file['data']) {
            		continue;
            	}
                $file['data'] = self::_loadFileFromDisk($file['hash']);
            }
        }
    
        public function getId()
        {
            return $this->_data['requestId'];
        }
    
    	public function getType()
    	{
    		return $this->_data['type'];
    	}
    
    	public function getTypeId()
    	{
            return self::_getTypeIdFromName($this->_data['type']);
    	}
    
    	public function setType($type)
    	{
            if (!in_array($type, array('NewCourse', 'ChangeCourse', 'RemoveCourse', 'AddISToCourse', 'NewCourseWithIS', 'NewCourseWithACE', 'AddACEToCourse', 'AddACEAndChangeCourse', 'RemoveACEFromCourse', 'RemoveACEAndChangeCourse'))) {
                throw new Exception('Unknown request type!');
            }
    
    		$this->_data['type'] = $type;
    	}
    
    	public function isVisible()
    	{
    		return (bool) ($this->_data['visible'] == 'yes');
    	}
    
    	public function isEditable() {
    	   	return (bool) ($this->_data['canEdit'] == 'yes');
    	}
    
    	public function isComplete() {
            return (bool) ($this->_data['complete'] == 'yes');
    	}
    
    	public function setComplete($complete = true)
    	{
    	    if ($complete) {
    	        $this->_data['complete'] = 'yes';
    	    } else {
    	        $this->_data['complete'] = 'no';
    	    }
    	}
    
    	public function isSubmitterAttentionRequired()
    	{
    		return (bool) ($this->_data['submitterAttentionRequired'] == 'yes');
    	}
    
        public function setSubmitterAttentionRequired($set = true)
        {
            if ($set) {
                $this->_data['submitterAttentionRequired'] = 'yes';
            } else {
                $this->_data['submitterAttentionRequired'] = 'no';
            }
        }
    
    	public function getOwner()
    	{
    		return $this->_data['owner'];
    	}
    
    	public function setOwner(Auth_UserModel $owner)
    	{
    		$this->_data['owner'] = $owner->getId();
    	}
    
    	public function getState()
    	{
    		return $this->_data['state'];
    	}
    
    	public function setState($state)
    	{
    	    $this->_data['state'] = $state;
    	}
    
    	public function getModule()
    	{
    		return $this->_data['module'];
    	}
    
    	public function setModule($module)
    	{
    		$this->_data['module'] = $module;
    	}
    
    	public function getJustification()
    	{
    		return $this->_data['justification'];
    	}
    
    	public function setJustification($justification)
    	{
    		$this->_data['justification'] = $justification;
    	}
    
    	public function getFile($type)
    	{
    		$requestedFile = null;
    		foreach ($this->_data['files'] as $file) {
    			if ($file['type'] == $type) {
    				$requestedFile = $file;
    				break;
    			}
    		}
    		return $requestedFile;
    	}
    	
    	public function getFileById($id)
    	{
    		return $this->_data['files'][$id];
    	}
    	
    	public function getFiles($type)
    	{
            $requestedFiles = array();
            foreach ($this->_data['files'] as $id => $file) {
                if ($file['type'] == $type) {
                    $requestedFiles[$id] = $file;
                }
            }
            return $requestedFiles;
    	}
    	
    	public function addFile($type, $title, $mimeType, $data)
    	{	
            $lowestId = min(array_keys($this->_data['files']));
            if (!($lowestId < 0)) {
                $lowestId = 0;
            }
            $lowestId--;
    
            $newFile = array(
                'type'     => $type,
                'title'    => $title,
                'mimeType' => $mimeType,
                'data'     => $data,
                'hash'     => hash('whirlpool', $data)
            );
    
            $this->_data['files'][$lowestId] = $newFile;
    	}
    
        public function setFile($type, $title, $mimeType, $data)
        {
        	$found = false;
        	foreach ($this->_data['files'] as $id => $file) {
        		if ($file['type'] == $type) {
                    $this->_data['files'][$id]['title'] = $title;
                    $this->_data['files'][$id]['mimeType'] = $mimeType;
                    $this->_data['files'][$id]['data'] = $data;
                    $this->_data['files'][$id]['hash'] = hash('whirlpool', $data);
    
        			$found = true;
        		}
        	}
    
        	if ($found) {
        		return;
        	}
    
    
            $lowestId = min(array_keys($this->_data['files']));
            if (!($lowestId < 0)) {
                $lowestId = 0;
            }
            $lowestId--;
    
        	$newFile = array(
                'type'     => $type,
                'title'    => $title,
                'mimeType' => $mimeType,
                'data'     => $data,
        	    'hash'     => hash('whirlpool', $data)
        	);
    
        	$this->_data['files'][$lowestId] = $newFile;
        }
    
        public function removeFile($type)
        {
            foreach ($this->_data['files'] as $fileId => $file) {
                if ($file['type'] == $type) {
                    unset($this->_data['files'][$fileId]);
                }
            }
        }
        
        public function removeFileById($id)
        {
            unset($this->_data['files'][$id]);
        }
    
        public function getStackPointer()
        {
            return $this->_data['stackPointer'];
        }
    
        public function setStackPointer(Requests_StackModel $stack)
        {
            $this->_data['stackPointer'] = $stack->getId();
        }
    
        public function clearStackPointer()
        {
            $this->_data['stackPointer'] = NULL;
        }
        
        public function getLastApprovalTime()
        {
        	$time = $this->_data['lastApprovalTime'];
        	if ($time > 0) {
        		return new Zend_Date($time);
        	}
        	return null;
        }
    
        public function isValid()
        {
        	//TODO: add criteria for this being valid
        	if (!$this->getJustification()) {
        		return false;
        	}
    
        	return true;
        }
    }