From 9b1182405e16b333aab3893d1ace7f25b4c65b52 Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 3 Dec 2021 15:56:39 +0100 Subject: [PATCH 1/9] - core/FHC_Controller->outputFile cleaned - Adapted controllers/lehre/anrechnung/* to make use of the changed core/FHC_Controller->outputFile - Changed application/core/FS_Model: - It's not abstract anymore - Added new constants READ_MODE, READ_WRITE_MODE, READ_APPEND_MODE, BLOCK_SIZE, META_URI - Constructor accept a mandatory parameter - Does not load the FilesystemLib anymore - Renamed all the public methods with the suffix Base64 - Added new public methods openRead, openReadWrite, openReadAppend, close, readBlock and write - Added new private methods _checkPath and _open - Removed the libraries/FilesystemLib - Adapted model content/DmsFS_model to make use of the changed core/FS_Model - Changed libraries/DmsLib: - Does not extend the FHC_Controller anymore - removed private propery UPLOAD_PATH - Cleaned code, make use of the standards - Adapted to use the Base64 suffixed methods from core/FS_Model - Deprecated old methods - Refactored public methods download and getFileInfo --- .../anrechnung/ApproveAnrechnungDetail.php | 8 +- .../ApproveAnrechnungUebersicht.php | 30 +- .../lehre/anrechnung/RequestAnrechnung.php | 11 +- .../anrechnung/ReviewAnrechnungDetail.php | 11 +- .../anrechnung/ReviewAnrechnungUebersicht.php | 12 +- application/core/FHC_Controller.php | 36 ++- application/core/FS_Model.php | 297 ++++++++++++++---- application/libraries/DmsLib.php | 248 +++++++-------- application/libraries/FilesystemLib.php | 142 --------- application/models/content/DmsFS_model.php | 6 +- 10 files changed, 423 insertions(+), 378 deletions(-) delete mode 100644 application/libraries/FilesystemLib.php diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php index 8982b9970..1209674af 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php @@ -385,13 +385,17 @@ class approveAnrechnungDetail extends Auth_Controller } // Check if user is entitled to read dms doc - self::_checkIfEntitledToReadDMSDoc($dms_id); + $this->_checkIfEntitledToReadDMSDoc($dms_id); // Set filename to be used on downlaod $filename = $this->anrechnunglib->setFilenameOnDownload($dms_id); + // Get file to be downloaded from DMS + $download = $this->dmslib->download($dms_id, $filename); + if (isError($download)) return $download; + // Download file - $this->dmslib->download($dms_id, $filename); + $this->outputFile(getData($download)); } /** diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php index d59d97514..804e06206 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php @@ -225,7 +225,7 @@ class approveAnrechnungUebersicht extends Auth_Controller return $this->outputJsonSuccess($retval); } - + /** * Download and open uploaded document (Nachweisdokument). */ @@ -239,16 +239,19 @@ class approveAnrechnungUebersicht extends Auth_Controller } // Check if user is entitled to read dms doc - self::_checkIfEntitledToReadDMSDoc($dms_id); + $this->_checkIfEntitledToReadDMSDoc($dms_id); // Set filename to be used on downlaod $filename = $this->anrechnunglib->setFilenameOnDownload($dms_id); - + + // Get file to be downloaded from DMS + $download = $this->dmslib->download($dms_id, $filename); + if (isError($download)) return $download; + // Download file - $this->dmslib->download($dms_id, $filename); + $this->outputFile(getData($download)); } - - + /** * Retrieve the UID of the logged user and checks if it is valid */ @@ -266,25 +269,24 @@ class approveAnrechnungUebersicht extends Auth_Controller private function _checkIfEntitledToReadDMSDoc($dms_id) { $result = $this->AnrechnungModel->loadWhere(array('dms_id' => $dms_id)); - + if(!$result = getData($result)[0]) { show_error('Failed retrieving Anrechnung'); } - + $result = $this->LehrveranstaltungModel->loadWhere(array( 'lehrveranstaltung_id' => $result->lehrveranstaltung_id )); - - + if(!$result = getData($result)[0]) { show_error('Failed loading Lehrveranstaltung'); } - + // Get STGL $result = $this->StudiengangModel->getLeitung($result->studiengang_kz); - + if($result = getData($result)[0]) { if ($result->uid == $this->_uid) @@ -292,7 +294,7 @@ class approveAnrechnungUebersicht extends Auth_Controller return; } } - + show_error('You are not entitled to read this document'); } @@ -411,4 +413,4 @@ class approveAnrechnungUebersicht extends Auth_Controller return $lector_arr; } -} \ No newline at end of file +} diff --git a/application/controllers/lehre/anrechnung/RequestAnrechnung.php b/application/controllers/lehre/anrechnung/RequestAnrechnung.php index 45a770cf5..ff1682330 100644 --- a/application/controllers/lehre/anrechnung/RequestAnrechnung.php +++ b/application/controllers/lehre/anrechnung/RequestAnrechnung.php @@ -205,9 +205,14 @@ class requestAnrechnung extends Auth_Controller } // Check if user is entitled to read dms doc - self::_checkIfEntitledToReadDMSDoc($dms_id); + $this->_checkIfEntitledToReadDMSDoc($dms_id); - $this->dmslib->download($dms_id); + // Get file to be downloaded from DMS + $download = $this->dmslib->download($dms_id, $filename); + if (isError($download)) return $download; + + // Download file + $this->outputFile(getData($download)); } /** @@ -366,4 +371,4 @@ class requestAnrechnung extends Auth_Controller // Upload document return $this->dmslib->upload($dms, 'uploadfile', array('pdf')); } -} \ No newline at end of file +} diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php index 78175f4e6..c0a757157 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php @@ -217,15 +217,18 @@ class reviewAnrechnungDetail extends Auth_Controller } // Check if user is entitled to read dms doc - self::_checkIfEntitledToReadDMSDoc($dms_id); + $this->_checkIfEntitledToReadDMSDoc($dms_id); // Set filename to be used on downlaod $filename = $this->anrechnunglib->setFilenameOnDownload($dms_id); - // Download file - $this->dmslib->download($dms_id, $filename); - } + // Get file to be downloaded from DMS + $download = $this->dmslib->download($dms_id, $filename); + if (isError($download)) return $download; + // Download file + $this->outputFile(getData($download)); + } /** * Retrieve the UID of the logged user and checks if it is valid diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php index cd0b7afaf..a80d0921a 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php @@ -180,13 +180,17 @@ class reviewAnrechnungUebersicht extends Auth_Controller } // Check if user is entitled to read dms doc - self::_checkIfEntitledToReadDMSDoc($dms_id); + $this->_checkIfEntitledToReadDMSDoc($dms_id); // Set filename to be used on downlaod $filename = $this->anrechnunglib->setFilenameOnDownload($dms_id); - + + // Get file to be downloaded from DMS + $download = $this->dmslib->download($dms_id, $filename); + if (isError($download)) return $download; + // Download file - $this->dmslib->download($dms_id, $filename); + $this->outputFile(getData($download)); } @@ -317,4 +321,4 @@ class reviewAnrechnungUebersicht extends Auth_Controller } } -} \ No newline at end of file +} diff --git a/application/core/FHC_Controller.php b/application/core/FHC_Controller.php index ce8748c5a..efc06c354 100644 --- a/application/core/FHC_Controller.php +++ b/application/core/FHC_Controller.php @@ -132,31 +132,41 @@ abstract class FHC_Controller extends CI_Controller { $this->output->set_content_type('application/json')->set_output(json_encode($mixed)); } - + + /** + * To download the given file represented by the fileObj parameter. + * fileObj has the following structure: + * $fileObj->filename + * $fileObj->file + * $fileObj->name + * $fileObj->mimetype + * $fileObj->disposition + */ protected function outputFile($fileObj) { - if (file_exists($fileObj->file)) + // If the file exists + if (isset($fileObj->file) && !isEmptyString($fileObj->file) && file_exists($fileObj->file)) { - $finfo = new finfo(FILEINFO_MIME); - header('Content-Description: File Transfer'); - header('Content-Type: '. $finfo->file($fileObj->file)); + header('Content-Type: '. $fileObj->mimetype); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($fileObj->file)); - - if (isset($fileObj->disposition) && ($fileObj->disposition == 'inline' || $fileObj->disposition == 'attachment')) + + if (isset($fileObj->disposition) + && ($fileObj->disposition == 'inline' || $fileObj->disposition == 'attachment')) { header('Content-Disposition: '. $fileObj->disposition. '; filename="'. $fileObj->name. '"'); } - - readfile($fileObj->file); - - exit; + + readfile($fileObj->file); // reads the file content to the output buffer + } + else + { + // Otherwise print an error + show_error('The provided file does not exist: '.(isset($fileObj->file) ? $fileObj->file : 'file not given')); } - - return false; } //------------------------------------------------------------------------------------------------------------------ diff --git a/application/core/FS_Model.php b/application/core/FS_Model.php index 03a0ee095..3b117aac8 100644 --- a/application/core/FS_Model.php +++ b/application/core/FS_Model.php @@ -3,113 +3,214 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); /** - * + * Model to work with the filesystem, it represents a directory + * It could be extended or could be used directly to work on the given path */ -abstract class FS_Model extends CI_Model +class FS_Model extends CI_Model { - protected $filepath; // Path of the file + const READ_MODE = 'r'; + const READ_WRITE_MODE = 'w+'; + const READ_APPEND_MODE = 'a+'; + const BLOCK_SIZE = 8192; + const META_URI = 'uri'; + + private $_path; // Directory where this model can operate /** - * Loads FilesystemLib and set properties + * Set properties */ - public function __construct($filepath = null) + public function __construct($path) { parent::__construct(); - // Load the filesystem library - $this->load->library('FilesystemLib'); + $this->_path = $path; + } - $this->filepath = $filepath; + // ------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Opens a file in read mode and returns its file handle + */ + public function openRead($filename) + { + return $this->_open($filename, self::READ_MODE); } /** - * Read data from file system - * - * @return array + * Opens a file in read and write mode and returns its file handle + * If the file does not exist then it is created */ - public function read($filename) + public function openReadWrite($filename) { - // Check Class-Attributes - if (is_null($this->filepath)) return error('The given filepath in not valid', EXIT_ERROR); - - // Check method parameters - if (is_null($filename)) return error('The given filename is not valid', EXIT_ERROR); - - if (!is_null($data = $this->filesystemlib->read($this->filepath, $filename))) - { - return success(base64_encode($data)); - } - else - { - return error('An error occurred while reading a file', EXIT_ERROR); - } + return $this->_open($filename, self::READ_WRITE_MODE); } /** - * Writing data to file system - * - * @param string $fileContent File content - * @return object + * Opens a file in read and append mode and returns its file handle + * If the file does not exist then it is created */ - public function write($filename, $content) + public function openReadAppend($filename) { - // Check Class-Attributes - if (is_null($this->filepath)) return error('The given filepath in not valid', EXIT_ERROR); - - // Check method parameters - if (is_null($content)) return error('The given file content is not valid', EXIT_ERROR); - if (is_null($filename)) return error('The given filename is not valid', EXIT_ERROR); - - if ($this->filesystemlib->write($this->filepath, $filename, base64_decode($content)) === true) - { - return success(); - } - else - { - return error('An error occurred while writing a file', EXIT_ERROR); - } + return $this->_open($filename, self::READ_APPEND_MODE); } /** - * Append data to a file - * - * @param array $data File content - * @return array + * Closes a file handle */ - public function append($filename, $content) + public function close($fileHandle) { - // Check Class-Attributes - if (is_null($this->filepath)) return error('The given filepath in not valid', EXIT_ERROR); + return fclose($fileHandle) === true ? success() : error('Error while closing the file handler'); + } - // Check method parameters - if (is_null($content)) return error('The given file content is not valid', EXIT_ERROR); - if (is_null($filename)) return error('The given filename is not valid', EXIT_ERROR); + /** + * Reads a block of bytes from the given file + * Returns a success that contains the block + * On failure returns an error + */ + public function readBlock($fileHandle) + { + // Reads a block of bytes from the file + $block = fread($fileHandle, self::BLOCK_SIZE); - if ($this->filesystemlib->append($this->filepath, $filename, base64_decode($content)) === true) + // If an error occurred + if ($block === false) { - return success(); + // Prepare the error message + $errorMsg = 'An error occurred while reading a file'; + + // Tries to get the file name and to concatenate it to the error message + $fileMetaData = stream_get_meta_data($fileHandle); + if (isset($fileMetaData[self::META_URI])) $errorMsg .= ': '.$fileMetaData[self::META_URI]; + + return error($errorMsg); // returns the error } - else + + return success($block); // return success if everything was fine + } + + /** + * Writes/appends (depending on how the file was opened) a content into a file + * Returns a success that contains the written number of bytes + * On failure returns an error + */ + public function write($fileHandle, $content) + { + // Writes the provided content to the file + $writeResult = fwrite($fileHandle, $content); + + // If an error occurred + if ($writeResult === false) { - return error('An error occurred while appending to a file', EXIT_ERROR); + $errorMsg = 'An error occurred while writing a file'; + + // Tries to get the file name and to concatenate it to the error message + $fileMetaData = stream_get_meta_data($fileHandle); + if (isset($fileMetaData[self::META_URI])) $errorMsg .= ': '.$fileMetaData[self::META_URI]; + + return error($errorMsg); // returns the error } + + return success($writeResult); + } + + // ------------------------------------------------------------------------------------------------------------------ + // Old public methods that work with the base64 encoding, not to be used! + + /** + * Read data from the given file and encode its content to base64 + */ + public function readBase64($filename) + { + // Open the file in read mode + $openReadResult = $this->openRead($filename); + if (isError($openReadResult)) return $openReadResult; // if an error occurred then return it + + $fileContent = ''; // to store the file content + $fileHandle = getData($openReadResult); // get the file handle + + // While the end of the file is not reached and the read does not fail + while (!feof($fileHandle) && isSuccess($readBlockResult = $this->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; + + // Close the file handler + $closeResult = $this->close($fileHandle); + if (isError($closeResult)) return $closeResult; // if it fails then return the error + + // If everything was fine encode the file content into base64 and return it as a success + return success(base64_encode($fileContent)); + } + + /** + * Writes the given content into the given file. The content is base64 encoded + */ + public function writeBase64($filename, $content) + { + // Open the file in read and write mode + $openWriteResult = $this->openReadWrite($filename); + if (isError($openWriteResult)) return $openWriteResult; // if an error occurred then return it + + $fileHandle = getData($openWriteResult); // get the file handle + + // Writes the given base64 encoded content into to given file + $writeResult = $this->write($fileHandle, base64_decode($content)); + // If an error occurred while writing then return it + if (isError($writeResult)) return $writeResult; + + // Close the file handler + $closeResult = $this->close($fileHandle); + if (isError($closeResult)) return $closeResult; // if it fails then return the error + + // If everything was fine + return success(); + } + + /** + * Appends the given content into the given file. The content is base64 encoded + */ + public function appendBase64($filename, $content) + { + // Open the file in read and append mode + $openWriteResult = $this->openReadAppend($filename); + if (isError($openWriteResult)) return $openWriteResult; // if an error occurred then return it + + $fileHandle = getData($openWriteResult); // get the file handle + + // Writes the given base64 encoded content into to given file + $writeResult = $this->write($fileHandle, base64_decode($content)); + // If an error occurred while writing then return it + if (isError($writeResult)) return $writeResult; + + // Close the file handler + $closeResult = $this->close($fileHandle); + if (isError($closeResult)) return $closeResult; // if it fails then return the error + + // If everything was fine + return success(); } /** * Delete data from file system + * NOTE: it does not work with the base64 encoding but it has been kept for retro compatibility * * @param string $id Primary Key for DELETE * @return array */ - public function remove($filename) + public function removeBase64($filename) { // Check Class-Attributes - if (is_null($this->filepath)) return error('The given filepath in not valid', EXIT_ERROR); + if (is_null($this->_path)) return error('The given _path in not valid', EXIT_ERROR); // Check method parameters if (is_null($filename)) return error('The given filename is not valid', EXIT_ERROR); - if ($this->filesystemlib->remove($this->filepath, $filename) === true) + if (unlink($this->_path.DIRECTORY_SEPARATOR.$filename) === true) { return success(); } @@ -121,20 +222,21 @@ abstract class FS_Model extends CI_Model /** * Rename a file + * NOTE: it does not work with the base64 encoding but it has been kept for retro compatibility * * @param string $id Primary Key for DELETE * @return array */ - public function rename($filename, $newFilename) + public function renameBase64($filename, $newFilename) { // Check Class-Attributes - if (is_null($this->filepath)) return error('The given filepath in not valid', EXIT_ERROR); + if (is_null($this->_path)) return error('The given _path in not valid', EXIT_ERROR); // Check method parameters if (is_null($filename)) return error('The given filename is not valid', EXIT_ERROR); if (is_null($newFilename)) return error('The given new filename is not valid', EXIT_ERROR); - if ($this->filesystemlib->rename($this->filepath, $filename, $this->filepath, $newFilename) === true) + if (rename($this->_path.DIRECTORY_SEPARATOR.$filename, $this->_path.DIRECTORY_SEPARATOR.$newFilename) === true) { return success(); } @@ -143,4 +245,67 @@ abstract class FS_Model extends CI_Model return error('An error occurred while renaming a file', EXIT_ERROR); } } + + // ------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Checks if the given $this->_path is a valid directory + */ + private function _checkPath() + { + // If _path... + if (!isEmptyString($this->_path) // ...is a not empty string... + && file_exists($this->_path) && is_dir($this->_path)) // ...exists on the file system and it is a directory... + { + return success(); // return a success + } + + // If not a valid path return an error + return error('The given path is not valid: '.$this->_path); + } + + /** + * Open a file using the provided mode + * It returns a file handle + * Or write and append if the file does not exist then creates it + */ + private function _open($filename, $mode) + { + // Check if the property _path represents a valid directory + $checkResult = $this->_checkPath(); + if (isError($checkResult)) return $checkResult; // If not then return the error + + // Full file path: path + filename + $fileFullPath = $this->_path.DIRECTORY_SEPARATOR.$filename; + + // If needed then check if the file exists and really it is a file + if ($mode == self::READ_MODE && (!file_exists($fileFullPath) || !is_file($fileFullPath))) + { + return error('Trying to read a not existing file'); + } + + // If needed then check if it is possible to read from the path and the file + if ($mode == self::READ_MODE && (!is_readable($this->_path) || !is_readable($fileFullPath))) + { + return error('The given path or filename are not readable: '.$fileFullPath); + } + + // If needed then check if the path and the filename are writable + if (($mode == self::READ_WRITE_MODE || $mode == self::READ_APPEND_MODE) + && (!is_writable($this->_path) || (file_exists($fileFullPath) && !is_writable($fileFullPath)))) + { + return error('The given path or filename are not writable: '.$fileFullPath); + } + + // Open the file in read mode + $fileHandle = fopen($fileFullPath, $mode); + + // If it was a failure the return the error + if ($fileHandle === false) return error('An error occurred while opening a file in '.$mode.' mode'); + + // Otherwise return the file handle + return success($fileHandle); + } } + diff --git a/application/libraries/DmsLib.php b/application/libraries/DmsLib.php index eae1a9ac4..e0360440c 100644 --- a/application/libraries/DmsLib.php +++ b/application/libraries/DmsLib.php @@ -2,24 +2,35 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); -class DmsLib extends FHC_Controller +class DmsLib { const FILE_CONTENT_PROPERTY = 'file_content'; - - private $UPLOAD_PATH = DMS_PATH; // temporary directory to store the upload file + + private $_ci; // code igniter instance /** * Object initialization */ public function __construct() { - $this->ci =& get_instance(); + $this->_ci =& get_instance(); - $this->ci->load->model('crm/Akte_model', 'AkteModel'); - $this->ci->load->model('content/Dms_model', 'DmsModel'); - $this->ci->load->model('content/DmsVersion_model', 'DmsVersionModel'); - $this->ci->load->model('content/DmsFS_model', 'DmsFSModel'); + $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 + + + // ----------------------------------------------------------------------------------------------------------- + // Private methods + + + // ----------------------------------------------------------------------------------------------------------- + // Deprecated methods, not to be used /** * Load a DMS Document. @@ -33,19 +44,20 @@ class DmsLib extends FHC_Controller { 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); + $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); + return $this->_ci->DmsModel->load($dms_id); } else { - return $this->ci->DmsModel->loadWhere(array('dms_id' => $dms_id, 'version' => $version)); + return $this->_ci->DmsModel->loadWhere(array('dms_id' => $dms_id, 'version' => $version)); } } + return error('The parameter DMS ID must be a number'); } @@ -57,34 +69,30 @@ class DmsLib extends FHC_Controller */ public function read($dms_id, $version = null) { - $result = 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); + $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); + $result = $this->_ci->DmsModel->load($dms_id); } else { - $result = $this->ci->DmsModel->loadWhere(array('dms_id' => $dms_id, 'version' => $version)); + $result = $this->_ci->DmsModel->loadWhere(array('dms_id' => $dms_id, 'version' => $version)); } - } - if (hasData($result)) - { - $resultFS = $this->ci->DmsFSModel->read($result->retval[0]->filename); - if (isSuccess($resultFS)) + // If a dms has been found + if (hasData($result)) { - $result->retval[0]->{DmsLib::FILE_CONTENT_PROPERTY} = $resultFS->retval; - } - else - { - $result = $resultFS; + $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); } } @@ -101,22 +109,16 @@ class DmsLib extends FHC_Controller */ public function getAktenAcceptedDms($person_id, $dokument_kurzbz = null, $no_file = null) { - $result = $this->ci->AkteModel->getAktenAcceptedDms($person_id, $dokument_kurzbz); + $result = $this->_ci->AkteModel->getAktenAcceptedDms($person_id, $dokument_kurzbz); if (hasData($result) && $no_file == null) { - $cnt = count($result->retval); - for ($i = 0; $i < $cnt; $i++) + for ($i = 0; $i < count(getData($result)); $i++) { - $resultFS = $this->ci->DmsFSModel->read($result->retval[$i]->filename); - if (isSuccess($resultFS)) - { - $result->retval[$i]->{DmsLib::FILE_CONTENT_PROPERTY} = $resultFS->retval; - } - else - { - $result = $resultFS; - } + $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); } } @@ -135,24 +137,24 @@ class DmsLib extends FHC_Controller // Init upload configs $this->_loadUploadLibrary($allowed_types); - if (!$this->ci->upload->do_upload($field_name)) + if (!$this->_ci->upload->do_upload($field_name)) { - return error($this->ci->upload->display_errors()); + return error($this->_ci->upload->display_errors()); } - $upload_data = $this->ci->upload->data(); // data about the uploaded file + $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))) + if (!$result = $this->_ci->DmsModel->insert($this->_ci->DmsModel->filterFields($dms))) { return error('Failed inserting to DMS'); } - $upload_data['dms_id'] = $result->retval; + $upload_data['dms_id'] = getData($result); // Insert DMS version - if (!$result = $this->ci->DmsVersionModel->insert( - $this->ci->DmsVersionModel->filterFields($dms, $result->retval, $filename))) + if (!$result = $this->_ci->DmsVersionModel->insert( + $this->_ci->DmsVersionModel->filterFields($dms, getData($result), $filename))) { return error('Failed inserting DMS version'); } @@ -171,36 +173,29 @@ class DmsLib extends FHC_Controller */ public function download($dms_id, $filename = null, $disposition = 'inline') { - $result = $this->getFileInfo($dms_id); - - if (isError($result)) + // 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)) { - return error(getError($result)); + $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); } - $fileObj = getData($result); - - // Change filename, if filename is provided - if (is_string($filename)) - { - $fileObj->name = $filename; - } - - // Add file disposition - if ($disposition == 'attachment') - { - $fileObj->disposition = 'attachment'; - } - else - { - $fileObj->disposition = 'inline'; - } - - // Output file - if(!$this->outputFile($fileObj)) - { - return error('Error on file output'); - } + // If no data have been found then return an empty success + return success(); } /** @@ -212,28 +207,28 @@ class DmsLib extends FHC_Controller */ public function getFileInfo($dms_id, $version = null) { - if (!is_numeric($dms_id)) - { - return error('Wrong parameter'); - } + // Checks the dms_id parameter + if (!is_numeric($dms_id)) return error('Wrong parameter'); - // Load file + // Load DMS from database $result = $this->load($dms_id, $version); + if (isError($result)) return error(getError($result)); - if (isError($result)) + // If data have been found + if (hasData($result)) { - return error(getError($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); } - // 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 users filename - $fileObj->mimetype = DMS_PATH. getData($result)[0]->mimetype; - - return success($fileObj); - + // If no data have been found return an empty success + return success(); } /** @@ -253,20 +248,20 @@ class DmsLib extends FHC_Controller $result = $this->_saveFileOnInsert($dms); if (isSuccess($result)) { - $filename = $result->retval; + $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) + $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)); + $result = $this->_ci->DmsModel->insert($this->_ci->DmsModel->filterFields($dms)); if (isSuccess($result)) { - $result = $this->ci->DmsVersionModel->insert( - $this->ci->DmsVersionModel->filterFields($dms, $result->retval, $filename) + $result = $this->_ci->DmsVersionModel->insert( + $this->_ci->DmsVersionModel->filterFields($dms, getData($result), $filename) ); } } @@ -277,15 +272,15 @@ class DmsLib extends FHC_Controller $result = $this->_saveFileOnUpdate($dms); if (isSuccess($result)) { - $result = $this->ci->DmsModel->update($dms['dms_id'], $this->ci->DmsModel->filterFields($dms)); + $result = $this->_ci->DmsModel->update($dms['dms_id'], $this->_ci->DmsModel->filterFields($dms)); if (isSuccess($result)) { - $result = $this->ci->DmsVersionModel->update( + $result = $this->_ci->DmsVersionModel->update( array( $dms['dms_id'], $dms['version'] ), - $this->ci->DmsVersionModel->filterFields($dms) + $this->_ci->DmsVersionModel->filterFields($dms) ); } } @@ -308,56 +303,54 @@ class DmsLib extends FHC_Controller if (is_numeric($person_id) && is_numeric($dms_id)) { // Start DB transaction - $this->ci->db->trans_start(false); + $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)); + $result = $this->_ci->AkteModel->loadWhere(array('person_id' => $person_id, 'dms_id' => $dms_id)); if (isSuccess($result)) { // Delete all entries in tbl_akte - $cnt = count($result->retval); - for ($i = 0; $i < $cnt; $i++) + for ($i = 0; $i < count(getData($result)); $i++) { - $this->ci->AkteModel->delete($result->retval[$i]->akte_id); + $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)); + $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)); + $result = $this->_ci->DmsVersionModel->delete(array('dms_id' => $dms_id)); if (isSuccess($result)) { // Delete from tbl_dms - $result = $this->ci->DmsModel->delete($dms_id); + $result = $this->_ci->DmsModel->delete($dms_id); } } } // Transaction complete! - $this->ci->db->trans_complete(); + $this->_ci->db->trans_complete(); // Check if everything went ok during the transaction - if ($this->ci->db->trans_status() === false || isError($result)) + if ($this->_ci->db->trans_status() === false || isError($result)) { - $this->ci->db->trans_rollback(); + $this->_ci->db->trans_rollback(); $result = error('An error occurred while performing a delete operation', EXIT_ERROR); } else { - $this->ci->db->trans_commit(); + $this->_ci->db->trans_commit(); $result = success('Dms successfully removed from DB'); } // If everything is ok if (isSuccess($result)) { - $cnt = count($resultFileNames->retval); // Remove all files related to this person and dms - for ($i = 0; $i < $cnt; $i++) + for ($i = 0; $i < count(getData($resultFileNames)); $i++) { - $this->ci->DmsFSModel->remove($resultFileNames->retval[$i]->filename); + $this->_ci->DmsFSModel->removeBase64(getData($resultFileNames)[$i]->filename); } } } @@ -376,19 +369,19 @@ class DmsLib extends FHC_Controller */ public function getAkteContent($akte_id) { - $akte = $this->ci->AkteModel->load($akte_id); + $akte = $this->_ci->AkteModel->load($akte_id); if (hasData($akte)) { - if ($akte->retval[0]->inhalt != '') + if (getData($akte)[0]->inhalt != '') { - return success(base64_decode($akte->retval[0]->inhalt)); + return success(base64_decode(getData($akte)[0]->inhalt)); } - elseif ($akte->retval[0]->dms_id != '') + elseif (getData($akte)[0]->dms_id != '') { - $dmscontent = $this->read($akte->retval[0]->dms_id); + $dmscontent = $this->read(getData($akte)[0]->dms_id); if (isSuccess($dmscontent)) { - return success(base64_decode($dmscontent->retval[0]->file_content)); + return success(base64_decode(getData($dmscontent)[0]->file_content)); } else { @@ -415,10 +408,10 @@ class DmsLib extends FHC_Controller { $filename = uniqid().'.'.pathinfo($dms['name'], PATHINFO_EXTENSION); - $result = $this->ci->DmsFSModel->write($filename, $dms['file_content']); + $result = $this->_ci->DmsFSModel->writeBase64($filename, $dms['file_content']); if (isSuccess($result)) { - $result->retval = $filename; + $result = success($filename); } return $result; @@ -439,7 +432,7 @@ class DmsLib extends FHC_Controller if (hasData($result)) { - $result = $this->ci->DmsFSModel->write($result->retval[0]->filename, $dms['file_content']); + $result = $this->_ci->DmsFSModel->writeBase64(getData($result)[0]->filename, $dms['file_content']); } } @@ -451,12 +444,13 @@ class DmsLib extends FHC_Controller */ private function _loadUploadLibrary($allowed_types) { - $config['upload_path'] = $this->UPLOAD_PATH; + $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); + $this->_ci->load->library('upload', $config); + $this->_ci->upload->initialize($config); } } + diff --git a/application/libraries/FilesystemLib.php b/application/libraries/FilesystemLib.php deleted file mode 100644 index c940acede..000000000 --- a/application/libraries/FilesystemLib.php +++ /dev/null @@ -1,142 +0,0 @@ -checkParameters($filepath, $filename)) - { - $resource = $filepath.DIRECTORY_SEPARATOR.$filename; - if (file_exists($resource) && $fileHandle = fopen($resource, 'r')) - { - $result = ''; - while (!feof($fileHandle)) - { - $result .= fread($fileHandle, 8192); - } - fclose($fileHandle); - } - } - - return $result; - } - - /** - * write - */ - public function write($filepath, $filename, $content) - { - $result = null; - - if ($this->checkParameters($filepath, $filename) && isset($content)) - { - $resource = $filepath.DIRECTORY_SEPARATOR.$filename; - if (is_writable($filepath) && $fileHandle = fopen($resource, 'w')) - { - if (fwrite($fileHandle, $content) !== false) - { - $result = true; - } - fclose($fileHandle); - } - } - - return $result; - } - - /** - * append - */ - public function append($filepath, $filename, $content) - { - $result = null; - - if ($this->checkParameters($filepath, $filename) && isset($content)) - { - $resource = $filepath.DIRECTORY_SEPARATOR.$filename; - if (is_writable($resource) && $fileHandle = fopen($resource, 'a')) - { - if (fwrite($fileHandle, $content) !== false) - { - $result = true; - } - fclose($fileHandle); - } - } - - return $result; - } - - /** - * remove - */ - public function remove($filepath, $filename) - { - $result = null; - - if ($this->checkParameters($filepath, $filename)) - { - if (is_writable($filepath)) - { - $resource = $filepath.DIRECTORY_SEPARATOR.$filename; - $result = unlink($resource); - } - } - - return $result; - } - - /** - * rename - */ - public function rename($filepath, $filename, $newFilepath, $newFilename) - { - $result = null; - - if ($this->checkParameters($filepath, $filename) && $this->checkParameters($newFilepath, $newFilename)) - { - $resource = $filepath.DIRECTORY_SEPARATOR.$filename; - if (is_writable($filepath) && is_writable($newFilepath) && file_exists($resource)) - { - $destination = $newFilepath.DIRECTORY_SEPARATOR.$newFilename; - $result = rename($resource, $destination); - } - } - - return $result; - } -} diff --git a/application/models/content/DmsFS_model.php b/application/models/content/DmsFS_model.php index 38a72d853..81443805f 100644 --- a/application/models/content/DmsFS_model.php +++ b/application/models/content/DmsFS_model.php @@ -7,7 +7,7 @@ class DmsFS_model extends FS_Model */ public function __construct() { - parent::__construct(); - $this->filepath = DMS_PATH; + parent::__construct(DMS_PATH); } -} \ No newline at end of file +} + From d6fb714b217800e10b5c6bdc1e7b59558d40b500 Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Mon, 13 Dec 2021 10:04:15 +0100 Subject: [PATCH 2/9] - added methods in dmslib for adding and removing files and file versions - FS_Model: added remove method --- application/core/FS_Model.php | 19 ++ application/libraries/DmsLib.php | 421 +++++++++++++++++++++++++++++++ 2 files changed, 440 insertions(+) diff --git a/application/core/FS_Model.php b/application/core/FS_Model.php index 3b117aac8..512278374 100644 --- a/application/core/FS_Model.php +++ b/application/core/FS_Model.php @@ -114,6 +114,25 @@ class FS_Model extends CI_Model return success($writeResult); } + public function remove($filename) + { + // Check if the property _path represents a valid directory + $checkResult = $this->_checkPath(); + if (isError($checkResult)) return $checkResult; // If not then return the error + + // Check filename + if (isEmptyString($filename)) return error('The given filename is not valid'); + + if (unlink($this->_path.DIRECTORY_SEPARATOR.$filename) === true) + { + return success(); + } + else + { + return error('An error occurred while removing a file'); + } + } + // ------------------------------------------------------------------------------------------------------------------ // Old public methods that work with the base64 encoding, not to be used! diff --git a/application/libraries/DmsLib.php b/application/libraries/DmsLib.php index e0360440c..f0c4a36e3 100644 --- a/application/libraries/DmsLib.php +++ b/application/libraries/DmsLib.php @@ -7,6 +7,7 @@ class DmsLib const FILE_CONTENT_PROPERTY = 'file_content'; private $_ci; // code igniter instance + private $_uid; /** * Object initialization @@ -14,6 +15,7 @@ class DmsLib 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'); @@ -24,10 +26,429 @@ class DmsLib // ----------------------------------------------------------------------------------------------------------- // 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 From 8c2af28595561fb56bfc8009a940b32052ae56db Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Tue, 14 Dec 2021 06:26:20 +0100 Subject: [PATCH 3/9] added AkteLib for adding, updating and deleting akte together with DMS documents --- application/libraries/AkteLib.php | 214 ++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 application/libraries/AkteLib.php diff --git a/application/libraries/AkteLib.php b/application/libraries/AkteLib.php new file mode 100644 index 000000000..555b2d0f3 --- /dev/null +++ b/application/libraries/AkteLib.php @@ -0,0 +1,214 @@ +_ci =& get_instance(); + $this->_uid = getAuthUID(); + + $this->_ci->load->model('crm/Akte_model', 'AkteModel'); + $this->_ci->load->model('content/DmsFS_model', 'DmsFSModel'); + + $this->_ci->load->library('DmsLib'); + } + + public function add($person_id, $dokument_kurzbz, $titel, $mimetype, $fileHandle, $bezeichnung = null, $uid = null) + { + $dmsAddResult = $this->_ci->dmslib->add($titel, self::AKTE_KATEGORIE_KURZBZ, $mimetype, $fileHandle, $dokument_kurzbz, $bezeichnung); + + if (isError($dmsAddResult)) return $dmsAddResult; + + if (!hasData($dmsAddResult)) + return error("Dms document could not be added"); + + $dmsAddData = getData($dmsAddResult); + + return $this->_ci->AkteModel->insert( + array( + 'person_id' => $person_id, + 'dokument_kurzbz' => $dokument_kurzbz, + 'titel' => $titel, + 'mimetype' => $mimetype, + 'bezeichnung' => $bezeichnung, + 'erstelltam' => date('Y-m-d'), + 'uid' => $uid, + 'dms_id' => $dmsAddData->dms_id, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => $this->_uid + ) + ); + } + + public function update($akte_id, $titel, $mimetype, $fileHandle, $bezeichnung = null) + { + $this->_ci->AkteModel->addSelect('dms_id'); + $akteResult = $this->_ci->AkteModel->load($akte_id); + + if (isError($akteResult)) return $akteResult; + + if (!hasData($akteResult)) + return error("Akte not found"); + + $dms_id = getData($akteResult)[0]->dms_id; + + if (isEmptyString($dms_id)) + return error("Akte has no dms document"); + + $dmsUpdateResult = $this->_ci->dmslib->updateLastVersion($dms_id, $fileHandle, $titel, $mimetype, $bezeichnung); + + if (isError($dmsUpdateResult)) return $dmsUpdateResult; + + if (!hasData($dmsUpdateResult)) + return error("Dms document could not be updated"); + + return $this->_ci->AkteModel->update( + $akte_id, + array( + 'titel' => $titel, + 'mimetype' => $mimetype, + 'bezeichnung' => $bezeichnung, + 'erstelltam' => date('Y-m-d'), + 'dms_id' => $dms_id, + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => $this->_uid + ) + ); + } + + public function get($akte_id) + { + // get Akte data + $this->_ci->AkteModel->addSelect('person_id, dokument_kurzbz, mimetype, erstelltam, titel, bezeichnung, + gedruckt, uid, dms_id, nachgereicht, nachgereicht_am, anmerkung, + ausstellungsnation, formal_geprueft_amum, archiv, signiert, + stud_selfservice, akzeptiertamum, insertvon, insertamum, updatevon, updateamum'); + $this->_ci->AkteModel->load($akte_id); + $akteResult = $this->_ci->AkteModel->load($akte_id); + + if (isError($akteResult)) return $akteResult; + + if (!hasData($akteResult)) + return error("Akte not found"); + + $resultObject = getData($akteResult)[0]; + + $resultObject->akte_mimetype = $resultObject->mimetype; + + // get dms data + $dmsResult = $this->_ci->dmslib->getLastVersion($resultObject->dms_id); + $dmsProperties = array('version', 'filename', 'mimetype', 'name', 'beschreibung', 'cis_suche', 'schlagworte', DmsLib::FILE_CONTENT_PROPERTY); + + if (isError($dmsResult)) return $dmsResult; + + if (hasData($dmsResult)) + { + $dmsData = getData($dmsResult); + + foreach ($dmsProperties as $dmsProperty) + { + $resultObject->{$dmsProperty} = $dmsData->{$dmsProperty}; + } + } + else + { + foreach ($dmsProperties as $dmsProperty) + { + $resultObject->{$dmsProperty} = null; + } + } + + return success($resultObject); + } + + public function getByPersonIdAndDocumentType($person_id, $dokument_kurzbz) + { + $this->_ci->AkteModel->addSelect('akte_id'); + $akteResult = $this->_ci->AkteModel->loadWhere( + array( + 'person_id' => $person_id, + 'dokument_kurzbz' => $dokument_kurzbz + ) + ); + + if (!hasData($akteResult)) + return error("Akte not found"); + + $akteData = getData($akteResult); + + $resultArr = array(); + + foreach ($akteData as $akte) + { + $getAkteDmsResult = $this->get($akte->akte_id); + + if (isError($getAkteDmsResult)) + return $getAkteDmsResult; + + $resultArr[] = getData($getAkteDmsResult); + } + + return success($resultArr); + } + + public function remove($akte_id) + { + $this->_ci->AkteModel->addSelect('dms_id'); + $akteResult = $this->_ci->AkteModel->load($akte_id); + + if (isError($akteResult)) return $akteResult; + + if (!hasData($akteResult)) + return error("Akte not found"); + + $dms_id = getData($akteResult)[0]->dms_id; + $error = null; + + // Start DB transaction + $this->_ci->db->trans_begin(); + + // delete Akte + $deleteResult = $this->_ci->AkteModel->delete($akte_id); + + if (isError($deleteResult)) + { + $error = $deleteResult; + } + else + { + $removeAllResult = $this->_ci->dmslib->removeAll($dms_id); + + if (isError($removeAllResult)) + $error = $removeAllResult; + } + + // 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 $removeAllResult; + } + } +} From 40493936c3d7ebcef737cd3ace8cafa6f1c122ff Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Fri, 17 Dec 2021 18:03:34 +0100 Subject: [PATCH 4/9] - AkteLib: added optional params "archiv", "signiert", "stud_selfservice", removed "uid" - AkteLib and DmsLib: added comments, added fallback default user for insertvon - FS_Model: added TempFS_model.php for writing temp files, added comments --- application/core/FS_Model.php | 5 + application/libraries/AkteLib.php | 89 ++++++++++++----- application/libraries/DmsLib.php | 100 ++++++++++++++++---- application/models/content/TempFS_model.php | 16 ++++ 4 files changed, 164 insertions(+), 46 deletions(-) create mode 100644 application/models/content/TempFS_model.php diff --git a/application/core/FS_Model.php b/application/core/FS_Model.php index 512278374..0d696d378 100644 --- a/application/core/FS_Model.php +++ b/application/core/FS_Model.php @@ -114,15 +114,20 @@ class FS_Model extends CI_Model return success($writeResult); } + /** + * Removes a given file + */ public function remove($filename) { // Check if the property _path represents a valid directory $checkResult = $this->_checkPath(); + if (isError($checkResult)) return $checkResult; // If not then return the error // Check filename if (isEmptyString($filename)) return error('The given filename is not valid'); + // remove file if (unlink($this->_path.DIRECTORY_SEPARATOR.$filename) === true) { return success(); diff --git a/application/libraries/AkteLib.php b/application/libraries/AkteLib.php index 555b2d0f3..28094aabb 100644 --- a/application/libraries/AkteLib.php +++ b/application/libraries/AkteLib.php @@ -4,10 +4,11 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); class AkteLib { - const AKTE_KATEGORIE_KURZBZ = 'Akte'; + const AKTE_KATEGORIE_KURZBZ = 'Akte'; // kategorie_kurzbz of dms when inserting for akte + const DEFAULT_USER = 'Akte'; // fallback string for insertvon if no logged user private $_ci; // Code igniter instance - private $_uid; + private $_uid; // uid of logged user /** * Object initialization @@ -23,17 +24,23 @@ class AkteLib $this->_ci->load->library('DmsLib'); } - public function add($person_id, $dokument_kurzbz, $titel, $mimetype, $fileHandle, $bezeichnung = null, $uid = null) + /** + * Writes a new file, adds a new dms entry with given akte data, + * adds a new dms version 0 for the written file, and adds Akte if dms add was successfull + * Returns success with inserted akte id or error + */ + public function add($person_id, $dokument_kurzbz, $titel, $mimetype, $fileHandle, $bezeichnung = null, $archiv = false, $signiert = false, $stud_selfservice = false) { - $dmsAddResult = $this->_ci->dmslib->add($titel, self::AKTE_KATEGORIE_KURZBZ, $mimetype, $fileHandle, $dokument_kurzbz, $bezeichnung); + // add new dms entry and new dms version for the Akte, using Akte data (title, mimetype, file content as handle) + $dmsAddResult = $this->_ci->dmslib->add($titel, $mimetype, $fileHandle, self::AKTE_KATEGORIE_KURZBZ, $dokument_kurzbz, $bezeichnung); if (isError($dmsAddResult)) return $dmsAddResult; - if (!hasData($dmsAddResult)) - return error("Dms document could not be added"); + if (!hasData($dmsAddResult)) return error("Dms document could not be added"); $dmsAddData = getData($dmsAddResult); + // insert the Akte return $this->_ci->AkteModel->insert( array( 'person_id' => $person_id, @@ -42,36 +49,42 @@ class AkteLib 'mimetype' => $mimetype, 'bezeichnung' => $bezeichnung, 'erstelltam' => date('Y-m-d'), - 'uid' => $uid, 'dms_id' => $dmsAddData->dms_id, + 'archiv' => $archiv, + 'signiert' => $signiert, + 'stud_selfservice' => $stud_selfservice, 'insertamum' => date('Y-m-d H:i:s'), - 'insertvon' => $this->_uid + 'insertvon' => isEmptyString($this->_uid) ? self::DEFAULT_USER : $this->_uid ) ); } - public function update($akte_id, $titel, $mimetype, $fileHandle, $bezeichnung = null) + /** + * Writes a new file, adds a new dms version 0 for the written file, and updates Akte if dms version add was successfull + * Returns success with updated akte id or error + */ + public function update($akte_id, $titel, $mimetype, $fileHandle, $bezeichnung = null, $archiv = false, $signiert = false, $stud_selfservice = false) { + // check if Akte with dms exists $this->_ci->AkteModel->addSelect('dms_id'); $akteResult = $this->_ci->AkteModel->load($akte_id); if (isError($akteResult)) return $akteResult; - if (!hasData($akteResult)) - return error("Akte not found"); + if (!hasData($akteResult)) return error("Akte not found"); $dms_id = getData($akteResult)[0]->dms_id; - if (isEmptyString($dms_id)) - return error("Akte has no dms document"); + if (isEmptyString($dms_id)) return error("Akte has no dms document"); + // if Akte with dms found, update the last dms version $dmsUpdateResult = $this->_ci->dmslib->updateLastVersion($dms_id, $fileHandle, $titel, $mimetype, $bezeichnung); if (isError($dmsUpdateResult)) return $dmsUpdateResult; - if (!hasData($dmsUpdateResult)) - return error("Dms document could not be updated"); + if (!hasData($dmsUpdateResult)) return error("Dms document could not be updated"); + // update the Akte return $this->_ci->AkteModel->update( $akte_id, array( @@ -80,12 +93,19 @@ class AkteLib 'bezeichnung' => $bezeichnung, 'erstelltam' => date('Y-m-d'), 'dms_id' => $dms_id, + 'archiv' => $archiv, + 'signiert' => $signiert, + 'stud_selfservice' => $stud_selfservice, 'updateamum' => date('Y-m-d H:i:s'), 'updatevon' => $this->_uid ) ); } + /** + * Gets akte data and associated dms data by akte Id + * Returns success with akte and dms data or error + */ public function get($akte_id) { // get Akte data @@ -98,19 +118,22 @@ class AkteLib if (isError($akteResult)) return $akteResult; - if (!hasData($akteResult)) - return error("Akte not found"); + if (!hasData($akteResult)) return error("Akte not found"); $resultObject = getData($akteResult)[0]; + // set properties with same name in Akte and Dms table $resultObject->akte_mimetype = $resultObject->mimetype; // get dms data $dmsResult = $this->_ci->dmslib->getLastVersion($resultObject->dms_id); - $dmsProperties = array('version', 'filename', 'mimetype', 'name', 'beschreibung', 'cis_suche', 'schlagworte', DmsLib::FILE_CONTENT_PROPERTY); if (isError($dmsResult)) return $dmsResult; + // properties to retrieve from dms + $dmsProperties = array('version', 'filename', 'mimetype', 'name', 'beschreibung', 'cis_suche', 'schlagworte', DmsLib::FILE_CONTENT_PROPERTY); + + // set dms properties if (hasData($dmsResult)) { $dmsData = getData($dmsResult); @@ -122,17 +145,24 @@ class AkteLib } else { + // set null if no dms result found foreach ($dmsProperties as $dmsProperty) { $resultObject->{$dmsProperty} = null; } } + // return the object containing akte and dms data return success($resultObject); } + /** + * Gets Akte data and associated dms data by person Id and dokument_kurzbz + * Returns success with result array with akte and dms data or error + */ public function getByPersonIdAndDocumentType($person_id, $dokument_kurzbz) { + // load all Akte entries for given person and dokument_kurzbz $this->_ci->AkteModel->addSelect('akte_id'); $akteResult = $this->_ci->AkteModel->loadWhere( array( @@ -141,40 +171,45 @@ class AkteLib ) ); - if (!hasData($akteResult)) - return error("Akte not found"); + if (!hasData($akteResult)) return error("Akte not found"); $akteData = getData($akteResult); $resultArr = array(); + // for each found akte entry foreach ($akteData as $akte) { + // get dms and akte data from akte Id $getAkteDmsResult = $this->get($akte->akte_id); - if (isError($getAkteDmsResult)) - return $getAkteDmsResult; + if (isError($getAkteDmsResult)) return $getAkteDmsResult; $resultArr[] = getData($getAkteDmsResult); } + // return all found entries return success($resultArr); } + /** + * Removes Akte by akte Id, removes all associated dms entries and versions, and deletes all associated files + * Returns success with removed version numbers or error + */ public function remove($akte_id) { + // get dms_id for akte $this->_ci->AkteModel->addSelect('dms_id'); $akteResult = $this->_ci->AkteModel->load($akte_id); if (isError($akteResult)) return $akteResult; - if (!hasData($akteResult)) - return error("Akte not found"); + if (!hasData($akteResult)) return error("Akte not found"); $dms_id = getData($akteResult)[0]->dms_id; $error = null; - // Start DB transaction + // Start DB transaction to avoid deleting only part of the data $this->_ci->db->trans_begin(); // delete Akte @@ -186,6 +221,7 @@ class AkteLib } else { + // remove all dms entry for dms of the akte $removeAllResult = $this->_ci->dmslib->removeAll($dms_id); if (isError($removeAllResult)) @@ -200,6 +236,7 @@ class AkteLib { $this->_ci->db->trans_rollback(); + // return occured error if (isset($error)) return $error; else @@ -208,6 +245,8 @@ class AkteLib else { $this->_ci->db->trans_commit(); + + // return removed dms entry data return $removeAllResult; } } diff --git a/application/libraries/DmsLib.php b/application/libraries/DmsLib.php index f0c4a36e3..017c7fc08 100644 --- a/application/libraries/DmsLib.php +++ b/application/libraries/DmsLib.php @@ -4,10 +4,11 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); class DmsLib { - const FILE_CONTENT_PROPERTY = 'file_content'; + const FILE_CONTENT_PROPERTY = 'file_content'; // property name for file content + const DEFAULT_USER = 'DMS'; // fallback string for insertvon if no logged user private $_ci; // code igniter instance - private $_uid; + private $_uid; // uid of logged user /** * Object initialization @@ -26,8 +27,13 @@ class DmsLib // ----------------------------------------------------------------------------------------------------------- // Public methods - public function add($name, $kategorie_kurzbz, $mimetype, $fileHandle, $dokument_kurzbz = null, $beschreibung = null, $cis_suche = false, $schlagworte = null) + /** + * Writes a new file, adds a new dms entry and a new dms version 0 for the written file + * Returns success info of added dms entry (dms_id, version, filename) or error + */ + public function add($name, $mimetype, $fileHandle, $kategorie_kurzbz = null, $dokument_kurzbz = null, $beschreibung = null, $cis_suche = false, $schlagworte = null) { + // write file with content of fileHandle $writeFileResult = $this->_writeNewFile($name, $fileHandle); if (isError($writeFileResult)) return $writeFileResult; @@ -62,7 +68,7 @@ class DmsLib 'beschreibung' => $beschreibung, 'cis_suche' => $cis_suche, 'schlagworte' => $schlagworte, - 'insertvon' => $this->_uid, + 'insertvon' => isEmptyString($this->_uid) ? self::DEFAULT_USER : $this->_uid, 'insertamum' => date('Y-m-d H:i:s') ); @@ -70,6 +76,7 @@ class DmsLib if (isError($dmsVersionResult)) return $dmsVersionResult; + // return dms info $resObj = new stdClass(); $resObj->dms_id = $dms_id; $resObj->version = $version; @@ -84,6 +91,10 @@ class DmsLib return error("file could not be written"); } + /** + * Writes a new file with content of fileHandle, adds a new dms version (max version number + 1) for the written file + * Returns success with info of added dms version (version, filename) or error + */ public function addNewVersion($dms_id, $fileHandle, $name = null, $mimetype = null, $beschreibung = null, $cis_suche = false, $schlagworte = null) { // get the latest version @@ -97,7 +108,7 @@ class DmsLib $originalName = isset($name) ? $name : $lastVersion->name; - // write new file + // write new file with content of fileHandle $writeFileResult = $this->_writeNewFile($originalName, $fileHandle); if (isError($writeFileResult)) return $writeFileResult; @@ -120,15 +131,15 @@ class DmsLib '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, + 'insertvon' => isEmptyString($this->_uid) ? self::DEFAULT_USER : $this->_uid, 'insertamum' => date('Y-m-d H:i:s') ); $addVersionResult = $this->_ci->DmsVersionModel->insert($newVersion); - if (isError($addVersionResult)) - return $addVersionResult; + if (isError($addVersionResult)) return $addVersionResult; + // return dms info $resObj = new stdClass(); $resObj->version = $newVersionNumber; $resObj->filename = $filename; @@ -142,6 +153,11 @@ class DmsLib return error("last version not found"); } + /** + * Updates the last version (max version number) of a dms entry + * Overwrites the file associated with this version with content read from fileHandle + * Returns success with info of added dms version (version, filename) or error + */ public function updateLastVersion($dms_id, $fileHandle, $name = null, $mimetype = null, $beschreibung = null, $cis_suche = false, $schlagworte = null) { // get the latest version @@ -179,9 +195,9 @@ class DmsLib $newVersion ); - if (isError($addVersionResult)) - return $addVersionResult; + if (isError($addVersionResult)) return $addVersionResult; + // return dms info $resObj = new stdClass(); $resObj->version = $lastVersion->version; $resObj->filename = $filename; @@ -195,8 +211,13 @@ class DmsLib return error("last version not found"); } + /** + * Gets dms version with highest number + * Returns success with dms data and fileHandle with file content or error + */ public function getLastVersion($dms_id) { + // get the latest version number $this->_ci->DmsVersionModel->addSelect('version'); $this->_ci->DmsVersionModel->addOrder('version', 'DESC'); $this->_ci->DmsVersionModel->addOrder('insertamum', 'DESC'); @@ -212,12 +233,17 @@ class DmsLib $lastDmsVersionData = getData($lastDmsVersionResult)[0]; $lastDmsVersion = $lastDmsVersionData->version; + // call get Version with last version number return $this->getVersion($dms_id, $lastDmsVersion); } else return error("Dms last version not found"); } + /** + * Gets specified dms version + * Returns success with dms data and fileHandle with file content or error + */ public function getVersion($dms_id, $version) { $this->_ci->DmsVersionModel->addSelect('dms_id, version, filename, mimetype, name, beschreibung, cis_suche, schlagworte'); @@ -234,7 +260,7 @@ class DmsLib { $dmsVersion = getData($dmsVersionResult)[0]; - // file content as file pointer + // get file content as file pointer $fileHandleResult = $this->_ci->DmsFSModel->openRead($dmsVersion->filename); if (isError($fileHandleResult)) return $fileHandleResult; @@ -244,6 +270,7 @@ class DmsLib $fileHandle = getData($fileHandleResult); $dmsVersion->{self::FILE_CONTENT_PROPERTY} = $fileHandle; + // close file pointer $closeResult = $this->_ci->DmsFSModel->close($fileHandle); if (isError($closeResult)) return $closeResult; @@ -257,9 +284,13 @@ class DmsLib return error("Dms version not found"); } + /** + * Removes dms entry and all its versions, deletes all associated files + * Returns success with removed version numbers or error + */ public function removeAll($dms_id) { - $versions_removed = array(); + $versionsRemoved = array(); $this->_ci->DmsVersionModel->addSelect('version, filename'); $allVersionsResult = $this->_ci->DmsVersionModel->loadWhere(array('dms_id' => $dms_id)); @@ -270,10 +301,10 @@ class DmsLib $error = null; - // Start DB transaction + // Start DB transaction to avoid deleting only part of the data $this->_ci->db->trans_begin(); - // remove all versions + // remove all versions of the dms Id foreach ($allVersionsData as $version) { $removeVersionResult = $this->removeVersion($dms_id, $version->version); @@ -284,7 +315,7 @@ class DmsLib break; } else - $versions_removed[] = $version; + $versionsRemoved[] = $version; // return removed versions } // Transaction complete! @@ -306,9 +337,13 @@ class DmsLib } } - return success($versions_removed); + return success($versionsRemoved); } + /** + * Removes latest version and its associated file + * Returns success with removed dms version data (dms_id, version, filename) or error + */ public function removeLastVersion($dms_id) { $lastVersionNumber = 0; @@ -323,9 +358,14 @@ class DmsLib $lastVersionNumber = $lastVersion->version; } + // call remove method for latest version return $this->removeVersion($dms_id, $lastVersionNumber); } + /** + * Removes latest version and its associated file + * Returns success with removed dms version data (dms_id, version, filename) or error + */ public function removeVersion($dms_id, $version) { $removeVersionResultObj = new stdClass(); @@ -333,7 +373,7 @@ class DmsLib $removeVersionResultObj->version = null; $removeVersionResultObj->filename = null; - // load version and check how many versions there are + // load dms version and check how many versions there are $db = new DB_Model(); $checkDeleteResult = $db->execReadOnlyQuery( @@ -353,6 +393,7 @@ class DmsLib { $checkDeleteData = getData($checkDeleteResult)[0]; + // delete version $deleteVersionResult = $this->_ci->DmsVersionModel->delete(array($dms_id, $version)); if (isError($deleteVersionResult)) return $deleteVersionResult; @@ -373,8 +414,7 @@ class DmsLib // delete file from file system $removeResult = $this->_ci->DmsFSModel->remove($checkDeleteData->filename); - if (isError($removeResult)) - return $removeResult; + if (isError($removeResult)) return $removeResult; } return success($removeVersionResultObj); @@ -382,17 +422,26 @@ class DmsLib // ----------------------------------------------------------------------------------------------------------- // Private methods + + /** + * Writes file with content of fileHandle using original document name for file extension + */ private function _writeNewFile($originalName, $fileHandle) { - // create unique filename + // create unique filename, using original document name to detect file extension $filename = $this->_getUniqueFilename($originalName); + // write the file return $this->_writeFile($filename, $fileHandle); } + /** + * Writes file with content of fileHandle + * Returns number of bytes written and filename + */ private function _writeFile($filename, $fileHandle) { - // copy file content provided by fileHandle + // file content provided by fileHandle $fileContent = ''; $readBlockResult = success(); @@ -421,6 +470,7 @@ class DmsLib if (isError($writeFileResult)) return $writeFileResult; + // return number of bytes written and filename $resObj = new stdClass(); $resObj->bytesWritten = 0; $resObj->filename = ''; @@ -439,11 +489,19 @@ class DmsLib return success($resObj); } + /** + * Generates unique filename, appends file extension from document name + * Returns the filename string + */ private function _getUniqueFilename($dokname) { + // create unique id $uniqueFilename = uniqid(); + + // getting extension of file from document name $fileExtension = pathinfo($dokname, PATHINFO_EXTENSION); + // if file extension found, append it if (!isEmptyString($fileExtension)) $uniqueFilename .= '.'.$fileExtension; diff --git a/application/models/content/TempFS_model.php b/application/models/content/TempFS_model.php new file mode 100644 index 000000000..ac55a24d7 --- /dev/null +++ b/application/models/content/TempFS_model.php @@ -0,0 +1,16 @@ + Date: Wed, 2 Feb 2022 11:52:08 +0100 Subject: [PATCH 5/9] Added commento to an echo in the application/core/FHC_Controller.php because it is not possible to replace the echo --- application/core/FHC_Controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/core/FHC_Controller.php b/application/core/FHC_Controller.php index efc06c354..c71d5f6d0 100644 --- a/application/core/FHC_Controller.php +++ b/application/core/FHC_Controller.php @@ -121,7 +121,7 @@ abstract class FHC_Controller extends CI_Controller protected function terminateWithJsonError($message) { header('Content-Type: application/json'); - echo json_encode(error($message)); + echo json_encode(error($message)); // KEEP IT!!! exit; } From 0344904631e45fe0f8ed293c979dd2072164d039 Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Mon, 11 Apr 2022 10:57:08 +0200 Subject: [PATCH 6/9] AkteLib.php, DmsLib.php coding style fixes: - splitted too long parameter lines - method call closing parenthesis on new line --- application/libraries/AkteLib.php | 5 ++++- application/libraries/DmsLib.php | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/application/libraries/AkteLib.php b/application/libraries/AkteLib.php index 28094aabb..174b21b6c 100644 --- a/application/libraries/AkteLib.php +++ b/application/libraries/AkteLib.php @@ -29,7 +29,10 @@ class AkteLib * adds a new dms version 0 for the written file, and adds Akte if dms add was successfull * Returns success with inserted akte id or error */ - public function add($person_id, $dokument_kurzbz, $titel, $mimetype, $fileHandle, $bezeichnung = null, $archiv = false, $signiert = false, $stud_selfservice = false) + public function add( + $person_id, $dokument_kurzbz, $titel, $mimetype, $fileHandle, // Required parameters + $bezeichnung = null, $archiv = false, $signiert = false, $stud_selfservice = false + ) { // add new dms entry and new dms version for the Akte, using Akte data (title, mimetype, file content as handle) $dmsAddResult = $this->_ci->dmslib->add($titel, $mimetype, $fileHandle, self::AKTE_KATEGORIE_KURZBZ, $dokument_kurzbz, $bezeichnung); diff --git a/application/libraries/DmsLib.php b/application/libraries/DmsLib.php index 017c7fc08..504e94a41 100644 --- a/application/libraries/DmsLib.php +++ b/application/libraries/DmsLib.php @@ -31,7 +31,10 @@ class DmsLib * Writes a new file, adds a new dms entry and a new dms version 0 for the written file * Returns success info of added dms entry (dms_id, version, filename) or error */ - public function add($name, $mimetype, $fileHandle, $kategorie_kurzbz = null, $dokument_kurzbz = null, $beschreibung = null, $cis_suche = false, $schlagworte = null) + public function add( + $name, $mimetype, $fileHandle, // Required parameters + $kategorie_kurzbz = null, $dokument_kurzbz = null, $beschreibung = null, $cis_suche = false, $schlagworte = null + ) { // write file with content of fileHandle $writeFileResult = $this->_writeNewFile($name, $fileHandle); @@ -633,7 +636,8 @@ class DmsLib // Insert DMS version if (!$result = $this->_ci->DmsVersionModel->insert( - $this->_ci->DmsVersionModel->filterFields($dms, getData($result), $filename))) + $this->_ci->DmsVersionModel->filterFields($dms, getData($result), $filename)) + ) { return error('Failed inserting DMS version'); } From d1b487e91a020af948c5ed0ba7d36d93c926f173 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 13 Apr 2022 13:22:16 +0200 Subject: [PATCH 7/9] - Removed authentication functions from AkteLib and DmsLib - Added new optional parameter who to write in the database who added the new document - PHPMD optimizations --- application/libraries/AkteLib.php | 23 ++++++++--- application/libraries/DmsLib.php | 65 +++++++++++++++++++------------ 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/application/libraries/AkteLib.php b/application/libraries/AkteLib.php index 174b21b6c..6c408d5e6 100644 --- a/application/libraries/AkteLib.php +++ b/application/libraries/AkteLib.php @@ -1,5 +1,14 @@ _ci =& get_instance(); - $this->_uid = getAuthUID(); + + // Set the the _who property + $this->_who = 'Akte system'; // default + // It is possible to set it using the who parameter + if (!isEmptyArray($params) && isset($params['who']) && !isEmptyString($params['who'])) $this->_who = $params['who']; $this->_ci->load->model('crm/Akte_model', 'AkteModel'); $this->_ci->load->model('content/DmsFS_model', 'DmsFSModel'); @@ -57,7 +70,7 @@ class AkteLib 'signiert' => $signiert, 'stud_selfservice' => $stud_selfservice, 'insertamum' => date('Y-m-d H:i:s'), - 'insertvon' => isEmptyString($this->_uid) ? self::DEFAULT_USER : $this->_uid + 'insertvon' => $this->_who ) ); } @@ -100,7 +113,7 @@ class AkteLib 'signiert' => $signiert, 'stud_selfservice' => $stud_selfservice, 'updateamum' => date('Y-m-d H:i:s'), - 'updatevon' => $this->_uid + 'updatevon' => $this->_who ) ); } diff --git a/application/libraries/DmsLib.php b/application/libraries/DmsLib.php index 504e94a41..b2c53a7d9 100644 --- a/application/libraries/DmsLib.php +++ b/application/libraries/DmsLib.php @@ -1,22 +1,36 @@ _ci =& get_instance(); - $this->_uid = getAuthUID(); + + // Set the the _who property + $this->_who = 'DMS system'; // default + // It is possible to set it using the who parameter + if (!isEmptyArray($params) && isset($params['who']) && !isEmptyString($params['who'])) $this->_who = $params['who']; $this->_ci->load->model('crm/Akte_model', 'AkteModel'); // deprecated, should not be used here! $this->_ci->load->model('content/Dms_model', 'DmsModel'); @@ -71,7 +85,7 @@ class DmsLib 'beschreibung' => $beschreibung, 'cis_suche' => $cis_suche, 'schlagworte' => $schlagworte, - 'insertvon' => isEmptyString($this->_uid) ? self::DEFAULT_USER : $this->_uid, + 'insertvon' => $this->_who, 'insertamum' => date('Y-m-d H:i:s') ); @@ -134,7 +148,7 @@ class DmsLib 'beschreibung' => isset($beschreibung) ? $beschreibung : $lastVersion->beschreibung, 'cis_suche' => isset($cis_suche) ? $cis_suche : $lastVersion->cis_suche, 'schlagworte' => isset($schlagworte) ? $schlagworte : $lastVersion->schlagworte, - 'insertvon' => isEmptyString($this->_uid) ? self::DEFAULT_USER : $this->_uid, + 'insertvon' => $this->_who, 'insertamum' => date('Y-m-d H:i:s') ); @@ -625,25 +639,25 @@ class DmsLib } $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); + $insDmsResult = $this->_ci->DmsModel->insert($this->_ci->DmsModel->filterFields($dms)); + if (isError($insDmsResult)) return $insDmsResult; + + $upload_data['dms_id'] = getData($insDmsResult); // Insert DMS version - if (!$result = $this->_ci->DmsVersionModel->insert( - $this->_ci->DmsVersionModel->filterFields($dms, getData($result), $filename)) - ) - { - return error('Failed inserting DMS version'); - } + $insVersionResult = $this->_ci->DmsVersionModel->insert( + $this->_ci->DmsVersionModel->filterFields( + $dms, + $upload_data['dms_id'], + $upload_data['file_name'] + ) + ); + if (isError($insVersionResult)) return $insVersionResult; - // return result of uploaded data - return success($upload_data); // data about the uploaded file + // Return result of uploaded data + return success($upload_data); } /** @@ -701,7 +715,7 @@ class DmsLib if (hasData($result)) { // Store file information in fileObj - $fileObj = new StdClass(); + $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 @@ -927,10 +941,11 @@ class DmsLib */ private function _loadUploadLibrary($allowed_types) { - $config['upload_path'] = DMS_PATH; - $config['allowed_types'] = implode('|', $allowed_types); - $config['overwrite'] = true; - $config['file_name'] = uniqid().'.pdf'; + $config = array(); + $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); From 5a00ae5a5e9e536edb0271370750f8a2ac66da34 Mon Sep 17 00:00:00 2001 From: Paolo Date: Thu, 14 Apr 2022 10:21:17 +0200 Subject: [PATCH 8/9] Removed not use constant DEFAULT_USER from libraries/AkteLib.php --- application/libraries/AkteLib.php | 1 - 1 file changed, 1 deletion(-) diff --git a/application/libraries/AkteLib.php b/application/libraries/AkteLib.php index 6c408d5e6..c4aee0095 100644 --- a/application/libraries/AkteLib.php +++ b/application/libraries/AkteLib.php @@ -14,7 +14,6 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); class AkteLib { const AKTE_KATEGORIE_KURZBZ = 'Akte'; // kategorie_kurzbz of dms when inserting for akte - const DEFAULT_USER = 'Akte'; // fallback string for insertvon if no logged user private $_ci; // Code igniter instance private $_who; // who added this document From 974791e19b03d9c6d969a4e983c3453135289b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Fri, 27 May 2022 14:23:24 +0200 Subject: [PATCH 9/9] Ausbildungssemester Limitiert damit bei Wiederholern die anzeige funktioniert --- .../lehre/anrechnung/approveAnrechnungUebersichtData.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php b/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php index 31e848481..368af8b12 100644 --- a/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php +++ b/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php @@ -22,7 +22,10 @@ $query = ' FROM public.tbl_prestudentstatus press WHERE press.prestudent_id = anrechnung.prestudent_id AND press.studiensemester_kurzbz = anrechnung.studiensemester_kurzbz - AND press.status_kurzbz = \'Student\'), + AND press.status_kurzbz = \'Student\' + ORDER BY press.datum DESC + LIMIT 1 + ), lv.bezeichnung AS "lv_bezeichnung", lv.ects, (person.nachname || \' \' || person.vorname) AS "student", @@ -56,7 +59,7 @@ $query = ' JOIN lehre.tbl_anrechnung_anrechnungstatus USING (anrechnung_id) JOIN lehre.tbl_anrechnung_begruendung AS begruendung USING (begruendung_id) ) - + SELECT anrechnungen.*, array_to_json(anrechnungstatus.bezeichnung_mehrsprachig::varchar[])->>' . $LANGUAGE_INDEX . ' AS "status_bezeichnung", CASE @@ -191,4 +194,4 @@ $filterWidgetArray = array( echo $this->widgetlib->widget('TableWidget', $filterWidgetArray); -?> \ No newline at end of file +?>