Files
FHC-Core/application/libraries/DmsLib.php
T
2021-12-13 10:04:15 +01:00

878 lines
23 KiB
PHP

<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class DmsLib
{
const FILE_CONTENT_PROPERTY = 'file_content';
private $_ci; // code igniter instance
private $_uid;
/**
* Object initialization
*/
public function __construct()
{
$this->_ci =& get_instance();
$this->_uid = getAuthUID();
$this->_ci->load->model('crm/Akte_model', 'AkteModel'); // deprecated, should not be used here!
$this->_ci->load->model('content/Dms_model', 'DmsModel');
$this->_ci->load->model('content/DmsVersion_model', 'DmsVersionModel');
$this->_ci->load->model('content/DmsFS_model', 'DmsFSModel');
}
// -----------------------------------------------------------------------------------------------------------
// Public methods
public function add($name, $kategorie_kurzbz, $mimetype, $fileHandle, $dokument_kurzbz = null, $beschreibung = null, $cis_suche = false, $schlagworte = null)
{
$writeFileResult = $this->_writeNewFile($name, $fileHandle);
if (isError($writeFileResult)) return $writeFileResult;
if (hasData($writeFileResult))
{
$writeFileData = getData($writeFileResult);
$filename = $writeFileData->filename;
// if file written successful, insert dms
$dmsResult = $this->_ci->DmsModel->insert(
array(
'kategorie_kurzbz' => $kategorie_kurzbz,
'dokument_kurzbz' => $dokument_kurzbz
)
);
if (isError($dmsResult)) return $dmsResult;
if (hasData($dmsResult))
{
$dms_id = getData($dmsResult);
$version = 0;
// insert dms version
$dmsVersion = array(
'dms_id' => $dms_id,
'version' => $version,
'filename' => $filename,
'mimetype' => $mimetype,
'name' => $name,
'beschreibung' => $beschreibung,
'cis_suche' => $cis_suche,
'schlagworte' => $schlagworte,
'insertvon' => $this->_uid,
'insertamum' => date('Y-m-d H:i:s')
);
$dmsVersionResult = $this->_ci->DmsVersionModel->insert($dmsVersion);
if (isError($dmsVersionResult)) return $dmsVersionResult;
$resObj = new stdClass();
$resObj->dms_id = $dms_id;
$resObj->version = $version;
$resObj->filename = $filename;
return success($resObj);
}
else
return error("error when inserting DMS");
}
else
return error("file could not be written");
}
public function addNewVersion($dms_id, $fileHandle, $name = null, $mimetype = null, $beschreibung = null, $cis_suche = false, $schlagworte = null)
{
// get the latest version
$lastVersionResult = $this->getLastVersion($dms_id);
if (isError($lastVersionResult)) return $lastVersionResult;
if (hasData($lastVersionResult))
{
$lastVersion = getData($lastVersionResult);
$originalName = isset($name) ? $name : $lastVersion->name;
// write new file
$writeFileResult = $this->_writeNewFile($originalName, $fileHandle);
if (isError($writeFileResult)) return $writeFileResult;
if (hasData($writeFileResult))
{
$writeFileData = getData($writeFileResult);
$filename = $writeFileData->filename;
// insert new version
$newVersionNumber = $lastVersion->version + 1;
// if new parameters given, use them, otherwise use parameters from last version
$newVersion = array(
'dms_id' => $dms_id,
'name' => $originalName,
'filename' => $filename,
'version' => $newVersionNumber,
'mimetype' => isset($mimetype) ? $mimetype : $lastVersion->mimetype,
'beschreibung' => isset($beschreibung) ? $beschreibung : $lastVersion->beschreibung,
'cis_suche' => isset($cis_suche) ? $cis_suche : $lastVersion->cis_suche,
'schlagworte' => isset($schlagworte) ? $schlagworte : $lastVersion->schlagworte,
'insertvon' => $this->_uid,
'insertamum' => date('Y-m-d H:i:s')
);
$addVersionResult = $this->_ci->DmsVersionModel->insert($newVersion);
if (isError($addVersionResult))
return $addVersionResult;
$resObj = new stdClass();
$resObj->version = $newVersionNumber;
$resObj->filename = $filename;
return success($resObj);
}
else
return error("file could not be written");
}
else
return error("last version not found");
}
public function updateLastVersion($dms_id, $fileHandle, $name = null, $mimetype = null, $beschreibung = null, $cis_suche = false, $schlagworte = null)
{
// get the latest version
$lastVersionResult = $this->getLastVersion($dms_id);
if (isError($lastVersionResult)) return $lastVersionResult;
if (hasData($lastVersionResult))
{
$lastVersion = getData($lastVersionResult);
// update file in filesystem
$writeFileResult = $this->_writeFile($lastVersion->filename, $fileHandle);
if (isError($writeFileResult)) return $writeFileResult;
if (hasData($writeFileResult))
{
$writeFileData = getData($writeFileResult);
$filename = $writeFileData->filename;
// if new parameters given, use them, otherwise use parameters from last version
$newVersion = array(
'name' => isset($name) ? $name : $lastVersion->name,
'filename' => $filename,
'mimetype' => isset($mimetype) ? $mimetype : $lastVersion->mimetype,
'beschreibung' => isset($beschreibung) ? $beschreibung : $lastVersion->beschreibung,
'cis_suche' => isset($cis_suche) ? $cis_suche : $lastVersion->cis_suche,
'schlagworte' => isset($schlagworte) ? $schlagworte : $lastVersion->schlagworte,
);
// update last dms version
$addVersionResult = $this->_ci->DmsVersionModel->update(
array($dms_id, $lastVersion->version),
$newVersion
);
if (isError($addVersionResult))
return $addVersionResult;
$resObj = new stdClass();
$resObj->version = $lastVersion->version;
$resObj->filename = $filename;
return success($resObj);
}
else
return error("file could not be written");
}
else
return error("last version not found");
}
public function getLastVersion($dms_id)
{
$this->_ci->DmsVersionModel->addSelect('version');
$this->_ci->DmsVersionModel->addOrder('version', 'DESC');
$this->_ci->DmsVersionModel->addOrder('insertamum', 'DESC');
$this->_ci->DmsVersionModel->addLimit(1);
$lastDmsVersionResult = $this->_ci->DmsVersionModel->loadWhere(
array('dms_id' => $dms_id)
);
if (isError($lastDmsVersionResult)) return $lastDmsVersionResult;
if (hasData($lastDmsVersionResult))
{
$lastDmsVersionData = getData($lastDmsVersionResult)[0];
$lastDmsVersion = $lastDmsVersionData->version;
return $this->getVersion($dms_id, $lastDmsVersion);
}
else
return error("Dms last version not found");
}
public function getVersion($dms_id, $version)
{
$this->_ci->DmsVersionModel->addSelect('dms_id, version, filename, mimetype, name, beschreibung, cis_suche, schlagworte');
$dmsVersionResult = $this->_ci->DmsVersionModel->loadWhere(
array(
'dms_id' => $dms_id,
'version' => $version
)
);
if (isError($dmsVersionResult)) return $dmsVersionResult;
if (hasData($dmsVersionResult))
{
$dmsVersion = getData($dmsVersionResult)[0];
// file content as file pointer
$fileHandleResult = $this->_ci->DmsFSModel->openRead($dmsVersion->filename);
if (isError($fileHandleResult)) return $fileHandleResult;
if (hasData($fileHandleResult))
{
$fileHandle = getData($fileHandleResult);
$dmsVersion->{self::FILE_CONTENT_PROPERTY} = $fileHandle;
$closeResult = $this->_ci->DmsFSModel->close($fileHandle);
if (isError($closeResult)) return $closeResult;
return success($dmsVersion);
}
else
return error("File could not be opened");
}
else
return error("Dms version not found");
}
public function removeAll($dms_id)
{
$versions_removed = array();
$this->_ci->DmsVersionModel->addSelect('version, filename');
$allVersionsResult = $this->_ci->DmsVersionModel->loadWhere(array('dms_id' => $dms_id));
if (hasData($allVersionsResult))
{
$allVersionsData = getData($allVersionsResult);
$error = null;
// Start DB transaction
$this->_ci->db->trans_begin();
// remove all versions
foreach ($allVersionsData as $version)
{
$removeVersionResult = $this->removeVersion($dms_id, $version->version);
if (isError($removeVersionResult))
{
$error = $removeVersionResult;
break;
}
else
$versions_removed[] = $version;
}
// Transaction complete!
$this->_ci->db->trans_complete();
// Check if everything went ok during the transaction
if ($this->_ci->db->trans_status() === false || isset($error))
{
$this->_ci->db->trans_rollback();
if (isset($error))
return $error;
else
return error("Error occured when deleting, rolled back");
}
else
{
$this->_ci->db->trans_commit();
}
}
return success($versions_removed);
}
public function removeLastVersion($dms_id)
{
$lastVersionNumber = 0;
// get the latest version
$lastVersionResult = $this->getLastVersion($dms_id);
if (isError($lastVersionResult)) return $lastVersionResult;
if (hasData($lastVersionResult))
{
$lastVersion = getData($lastVersionResult);
$lastVersionNumber = $lastVersion->version;
}
return $this->removeVersion($dms_id, $lastVersionNumber);
}
public function removeVersion($dms_id, $version)
{
$removeVersionResultObj = new stdClass();
$removeVersionResultObj->dms_id = null;
$removeVersionResultObj->version = null;
$removeVersionResultObj->filename = null;
// load version and check how many versions there are
$db = new DB_Model();
$checkDeleteResult = $db->execReadOnlyQuery(
"SELECT filename,
(SELECT count(version)
FROM campus.tbl_dms_version dv_anzahl
WHERE dv_anzahl.dms_id = dv.dms_id) AS anzahl_versionen
FROM campus.tbl_dms_version dv
WHERE dms_id=?
AND version=?",
array($dms_id, $version)
);
if (isError($checkDeleteResult)) return $checkDeleteResult;
if (hasData($checkDeleteResult))
{
$checkDeleteData = getData($checkDeleteResult)[0];
$deleteVersionResult = $this->_ci->DmsVersionModel->delete(array($dms_id, $version));
if (isError($deleteVersionResult)) return $deleteVersionResult;
$removeVersionResultObj->version = $version;
$removeVersionResultObj->filename = $checkDeleteData->filename;
// delete dms too if no versions left
if ($checkDeleteData->anzahl_versionen <= 1)
{
$deleteDmsResult = $this->_ci->DmsModel->delete($dms_id);
if (isError($deleteDmsResult)) return $deleteDmsResult;
$removeVersionResultObj->dms_id = $dms_id;
}
// delete file from file system
$removeResult = $this->_ci->DmsFSModel->remove($checkDeleteData->filename);
if (isError($removeResult))
return $removeResult;
}
return success($removeVersionResultObj);
}
// -----------------------------------------------------------------------------------------------------------
// Private methods
private function _writeNewFile($originalName, $fileHandle)
{
// create unique filename
$filename = $this->_getUniqueFilename($originalName);
return $this->_writeFile($filename, $fileHandle);
}
private function _writeFile($filename, $fileHandle)
{
// copy file content provided by fileHandle
$fileContent = '';
$readBlockResult = success();
// While the end of the file is not reached and the read does not fail
while (!feof($fileHandle) && isSuccess($readBlockResult = $this->_ci->DmsFSModel->readBlock($fileHandle)))
{
// Concatenate the content of the file
$fileContent .= getData($readBlockResult);
}
// If an error occurred while reading then return it
if (isError($readBlockResult)) return $readBlockResult;
// open file for writing
$openFileResult = $this->_ci->DmsFSModel->openReadWrite($filename);
if (isError($openFileResult)) return $openFileResult;
if (!hasData($openFileResult)) return error("File could not be opened");
$newFileHandle = getData($openFileResult);
// write file
$writeFileResult = $this->_ci->DmsFSModel->write($newFileHandle, $fileContent);
if (isError($writeFileResult)) return $writeFileResult;
$resObj = new stdClass();
$resObj->bytesWritten = 0;
$resObj->filename = '';
if (hasData($writeFileResult))
{
$resObj->bytesWritten = getData($writeFileResult);
$resObj->filename = $filename;
}
// close handle
$closeResult = $this->_ci->DmsFSModel->close($newFileHandle, $fileContent);
if (isError($closeResult)) return $closeResult;
return success($resObj);
}
private function _getUniqueFilename($dokname)
{
$uniqueFilename = uniqid();
$fileExtension = pathinfo($dokname, PATHINFO_EXTENSION);
if (!isEmptyString($fileExtension))
$uniqueFilename .= '.'.$fileExtension;
return $uniqueFilename;
}
// -----------------------------------------------------------------------------------------------------------
// Deprecated methods, not to be used
/**
* Load a DMS Document.
* If no version is particularly given, the latest version is loaded.
*
* @param $dms_id
* @param integer $version
* @return array
*/
public function load($dms_id, $version = null)
{
if (is_numeric($dms_id))
{
$this->_ci->DmsModel->addJoin('campus.tbl_dms_version', 'dms_id');
$this->_ci->DmsModel->addOrder('version', 'DESC');
$this->_ci->DmsModel->addLimit(1);
if (!is_numeric($version))
{
return $this->_ci->DmsModel->load($dms_id);
}
else
{
return $this->_ci->DmsModel->loadWhere(array('dms_id' => $dms_id, 'version' => $version));
}
}
return error('The parameter DMS ID must be a number');
}
/**
* Read a DMS Document from the Filesystem
* @param int $dms_id ID of the Document.
* @param int $version The version of the Document (latest if null).
* @return object success or error
*/
public function read($dms_id, $version = null)
{
$result = error('Wrong dms_id parameter');
if (isset($dms_id))
{
$this->_ci->DmsModel->addJoin('campus.tbl_dms_version', 'dms_id');
$this->_ci->DmsModel->addOrder('version', 'DESC');
$this->_ci->DmsModel->addLimit(1);
if (!isset($version))
{
$result = $this->_ci->DmsModel->load($dms_id);
}
else
{
$result = $this->_ci->DmsModel->loadWhere(array('dms_id' => $dms_id, 'version' => $version));
}
// If a dms has been found
if (hasData($result))
{
$resultFS = $this->_ci->DmsFSModel->readBase64(getData($result)[0]->filename);
if (isError($resultFS)) return $resultFS; // if an error occurred return it
$result->retval[0]->{self::FILE_CONTENT_PROPERTY} = getData($resultFS);
}
}
return $result;
}
/**
* Get all accepted Documents of a Person
*
* @param int $person_id ID of the person.
* @param string $dokument_kurzbz Type of document.
* @param bool $no_file If null then loads also the content.
* @return object success or error
*/
public function getAktenAcceptedDms($person_id, $dokument_kurzbz = null, $no_file = null)
{
$result = $this->_ci->AkteModel->getAktenAcceptedDms($person_id, $dokument_kurzbz);
if (hasData($result) && $no_file == null)
{
for ($i = 0; $i < count(getData($result)); $i++)
{
$resultFS = $this->_ci->DmsFSModel->readBase64(getData($result)[$i]->filename);
if (isError($resultFS)) return $resultFS; // if an error occurred return it
$result->retval[$i]->{self::FILE_CONTENT_PROPERTY} = getData($resultFS);
}
}
return $result;
}
/**
* Uploads a document and saves it to DMS
* @param $dms DMS assoc array
* @param $field_name Name of the HTML uploadfile input name attribute
* @param array $allowed_types Default: all. Param example: array(jpg, pdf)
* @return array
*/
public function upload($dms, $field_name, $allowed_types = array('*'))
{
// Init upload configs
$this->_loadUploadLibrary($allowed_types);
if (!$this->_ci->upload->do_upload($field_name))
{
return error($this->_ci->upload->display_errors());
}
$upload_data = $this->_ci->upload->data(); // data about the uploaded file
$filename = $upload_data['file_name'];
// Insert to DMS table
if (!$result = $this->_ci->DmsModel->insert($this->_ci->DmsModel->filterFields($dms)))
{
return error('Failed inserting to DMS');
}
$upload_data['dms_id'] = getData($result);
// Insert DMS version
if (!$result = $this->_ci->DmsVersionModel->insert(
$this->_ci->DmsVersionModel->filterFields($dms, getData($result), $filename)))
{
return error('Failed inserting DMS version');
}
// return result of uploaded data
return success($upload_data); // data about the uploaded file
}
/**
* Download a document.
*
* @param $dms_id
* @param string $filename $filename If String is given, it will be used as filename on download
* @param string $disposition [inline | attachment]
* Inline opens doc in new tab. Attachment displays download dialog box.
*/
public function download($dms_id, $filename = null, $disposition = 'inline')
{
// Retrieves info about the given dms
$fileInfoResult = $this->getFileInfo($dms_id);
if (isError($fileInfoResult)) return error(getError($fileInfoResult));
// If data have been found
if (hasData($fileInfoResult))
{
$fileObj = getData($fileInfoResult);
// Change filename, if filename is provided
if (!isEmptyString($filename)) $fileObj->name = $filename;
// Add file disposition if disposition has a valid value
if ($disposition == 'attachment' || $disposition == 'inline')
{
$fileObj->disposition = $disposition;
}
return success($fileObj);
}
// If no data have been found then return an empty success
return success();
}
/**
* Get file information.
*
* @param $dms_id
* @param integer $version
* @return array with File Object.
*/
public function getFileInfo($dms_id, $version = null)
{
// Checks the dms_id parameter
if (!is_numeric($dms_id)) return error('Wrong parameter');
// Load DMS from database
$result = $this->load($dms_id, $version);
if (isError($result)) return error(getError($result));
// If data have been found
if (hasData($result))
{
// Store file information in fileObj
$fileObj = new StdClass();
$fileObj->filename = getData($result)[0]->filename;
$fileObj->file = DMS_PATH.getData($result)[0]->filename;
$fileObj->name = DMS_PATH.getData($result)[0]->name; // original user filename
$fileObj->mimetype = getData($result)[0]->mimetype;
return success($fileObj);
}
// If no data have been found return an empty success
return success();
}
/**
* Saves a Document
* @param object $dms DMS Object ot be saved.
* @return object
*/
public function save($dms)
{
$result = null;
if (isset($dms['new']) && $dms['new'] == true)
{
// Remove new parameter to avoid DB insert errors
unset($dms['new']);
$result = $this->_saveFileOnInsert($dms);
if (isSuccess($result))
{
$filename = getData($result);
if (isset($dms['dms_id']) && $dms['dms_id'] != '')
{
$result = $this->_ci->DmsVersionModel->insert(
$this->_ci->DmsVersionModel->filterFields($dms, $dms['dms_id'], $filename)
);
}
else
{
$result = $this->_ci->DmsModel->insert($this->_ci->DmsModel->filterFields($dms));
if (isSuccess($result))
{
$result = $this->_ci->DmsVersionModel->insert(
$this->_ci->DmsVersionModel->filterFields($dms, getData($result), $filename)
);
}
}
}
}
else
{
$result = $this->_saveFileOnUpdate($dms);
if (isSuccess($result))
{
$result = $this->_ci->DmsModel->update($dms['dms_id'], $this->_ci->DmsModel->filterFields($dms));
if (isSuccess($result))
{
$result = $this->_ci->DmsVersionModel->update(
array(
$dms['dms_id'],
$dms['version']
),
$this->_ci->DmsVersionModel->filterFields($dms)
);
}
}
}
return $result;
}
/**
* Deletes a Akte of a Person
* @param int $person_id ID of the person.
* @param int $dms_id Id of the Document.
* @return object
*/
public function delete($person_id, $dms_id)
{
$result = null;
// If the parameters are valid
if (is_numeric($person_id) && is_numeric($dms_id))
{
// Start DB transaction
$this->_ci->db->trans_start(false);
// Get akte_id from table tbl_akte
$result = $this->_ci->AkteModel->loadWhere(array('person_id' => $person_id, 'dms_id' => $dms_id));
if (isSuccess($result))
{
// Delete all entries in tbl_akte
for ($i = 0; $i < count(getData($result)); $i++)
{
$this->_ci->AkteModel->delete(getData($result)[$i]->akte_id);
}
// Get all filenames related to this dms
$resultFileNames = $this->_ci->DmsVersionModel->loadWhere(array('dms_id' => $dms_id));
if (isSuccess($resultFileNames))
{
// Delete from tbl_dms_version
$result = $this->_ci->DmsVersionModel->delete(array('dms_id' => $dms_id));
if (isSuccess($result))
{
// Delete from tbl_dms
$result = $this->_ci->DmsModel->delete($dms_id);
}
}
}
// Transaction complete!
$this->_ci->db->trans_complete();
// Check if everything went ok during the transaction
if ($this->_ci->db->trans_status() === false || isError($result))
{
$this->_ci->db->trans_rollback();
$result = error('An error occurred while performing a delete operation', EXIT_ERROR);
}
else
{
$this->_ci->db->trans_commit();
$result = success('Dms successfully removed from DB');
}
// If everything is ok
if (isSuccess($result))
{
// Remove all files related to this person and dms
for ($i = 0; $i < count(getData($resultFileNames)); $i++)
{
$this->_ci->DmsFSModel->removeBase64(getData($resultFileNames)[$i]->filename);
}
}
}
else
{
$result = error('Invalid parameters');
}
return $result;
}
/**
* Loads the Content of an akte
* @param int $akte_id Id of the akte.
* @return object with document content or error
*/
public function getAkteContent($akte_id)
{
$akte = $this->_ci->AkteModel->load($akte_id);
if (hasData($akte))
{
if (getData($akte)[0]->inhalt != '')
{
return success(base64_decode(getData($akte)[0]->inhalt));
}
elseif (getData($akte)[0]->dms_id != '')
{
$dmscontent = $this->read(getData($akte)[0]->dms_id);
if (isSuccess($dmscontent))
{
return success(base64_decode(getData($dmscontent)[0]->file_content));
}
else
{
return error(getError($dmscontent));
}
}
else
{
return error('No Content available');
}
}
else
{
return error(getError($akte));
}
}
/**
* Saves the Content of a DMS in the Filesystem
* @param object $dms DMS object to be saved.
* @return object
*/
private function _saveFileOnInsert($dms)
{
$filename = uniqid().'.'.pathinfo($dms['name'], PATHINFO_EXTENSION);
$result = $this->_ci->DmsFSModel->writeBase64($filename, $dms['file_content']);
if (isSuccess($result))
{
$result = success($filename);
}
return $result;
}
/**
* Updates the File in the Filesystem
* @param object $dms DMS object to update.
* @return object
*/
private function _saveFileOnUpdate($dms)
{
$result = null;
if (isset($dms['version']))
{
$result = $this->read($dms['dms_id'], $dms['version']);
if (hasData($result))
{
$result = $this->_ci->DmsFSModel->writeBase64(getData($result)[0]->filename, $dms['file_content']);
}
}
return $result;
}
/**
* Loads the upload library of CI
*/
private function _loadUploadLibrary($allowed_types)
{
$config['upload_path'] = DMS_PATH;
$config['allowed_types'] = implode('|', $allowed_types);
$config['overwrite'] = true;
$config['file_name'] = uniqid().'.pdf';
$this->_ci->load->library('upload', $config);
$this->_ci->upload->initialize($config);
}
}