PMC-10
This commit is contained in:
@@ -672,5 +672,84 @@ class AppDocument extends BaseAppDocument
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will upload a file related to the AppDocument
|
||||
*
|
||||
* @param string $appUid
|
||||
* @param string $userUid
|
||||
* @param integer $delIndex
|
||||
* @param mixed $docUid
|
||||
* @param array $file
|
||||
* @param string $varName
|
||||
* @param string $appDocUid
|
||||
*
|
||||
* @return object
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadAppDocument(
|
||||
$appUid,
|
||||
$userUid,
|
||||
$delIndex = 1,
|
||||
$docUid = -1,
|
||||
$file = [],
|
||||
$varName = null,
|
||||
$appDocUid = null
|
||||
) {
|
||||
$appDocType = 'ATTACHED';
|
||||
$folderId = '';
|
||||
// Create the folder
|
||||
if ($docUid != -1) {
|
||||
$appDocType = 'INPUT';
|
||||
$folder = new AppFolder();
|
||||
$folderId = $folder->createFolderFromInputDoc($docUid, $appUid);
|
||||
}
|
||||
$fieldsInput = [
|
||||
"DOC_VERSION" => 1,
|
||||
"APP_UID" => $appUid,
|
||||
"DEL_INDEX" => $delIndex,
|
||||
"USR_UID" => $userUid,
|
||||
"DOC_UID" => $docUid,
|
||||
"APP_DOC_TYPE" => $appDocType,
|
||||
"APP_DOC_CREATE_DATE" => date("Y-m-d H:i:s"),
|
||||
"APP_DOC_COMMENT" => "",
|
||||
"APP_DOC_TITLE" => "",
|
||||
"APP_DOC_FILENAME" => $file["name"],
|
||||
"APP_DOC_FIELDNAME" => !empty($varName) ? $varName : null,
|
||||
"FOLDER_UID" => $folderId
|
||||
];
|
||||
|
||||
// If the APP_DOC_UID exist will create a new version
|
||||
if (!empty($appDocUid)) {
|
||||
$fieldsInput["APP_DOC_UID"] = $appDocUid;
|
||||
}
|
||||
|
||||
// Create the register in the database
|
||||
$newInstance = new AppDocument();
|
||||
$appDocUid = $newInstance->create($fieldsInput);
|
||||
$docVersion = $newInstance->getDocVersion();
|
||||
|
||||
// Move the uploaded file to the documents folder
|
||||
try {
|
||||
$info = pathinfo($file["name"]);
|
||||
$extension = ((isset($info["extension"])) ? $info["extension"] : "");
|
||||
$pathCase = G::getPathFromUID($appUid);
|
||||
$fileName = $appDocUid . "_" . $docVersion . "." . $extension;
|
||||
|
||||
G::uploadFile(
|
||||
$file["tmp_name"],
|
||||
PATH_DOCUMENT . $pathCase . PATH_SEP,
|
||||
$fileName
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
// Delete the register from Database
|
||||
$this->remove($appDocUid, $docVersion);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return $newInstance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -870,5 +870,23 @@ class AppFolder extends BaseAppFolder
|
||||
$oCriteria->add( AppFolderPeer::FOLDER_UID, $FolderUid );
|
||||
AppFolderPeer::doDelete( $oCriteria );
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will create a folder related to the input document
|
||||
*
|
||||
* @param string $docUid
|
||||
* @param string $appUid
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function createFolderFromInputDoc($docUid, $appUid)
|
||||
{
|
||||
$inputDocument = new InputDocument();
|
||||
$inputDocumentData = $inputDocument->load($docUid);
|
||||
$folder = $this->createFromPath($inputDocumentData["INP_DOC_DESTINATION_PATH"], $appUid);
|
||||
|
||||
return $folder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,50 +4,54 @@ namespace ProcessMaker\BusinessModel;
|
||||
|
||||
use AppCacheView;
|
||||
use AppCacheViewPeer;
|
||||
use Applications;
|
||||
use ApplicationPeer;
|
||||
use AppSolr;
|
||||
use AppDelegation;
|
||||
use AppDelegationPeer;
|
||||
use AppDelay;
|
||||
use AppDelayPeer;
|
||||
use AppDelegation;
|
||||
use AppDelegationPeer;
|
||||
use AppDocument;
|
||||
use AppDocumentPeer;
|
||||
use AppHistoryPeer;
|
||||
use AppThreadPeer;
|
||||
use ApplicationPeer;
|
||||
use Applications;
|
||||
use AppNotesPeer;
|
||||
use AppSolr;
|
||||
use BasePeer;
|
||||
use Bootstrap;
|
||||
use BpmnEngineServicesSearchIndex;
|
||||
use Cases as ClassesCases;
|
||||
use CasesPeer;
|
||||
use Criteria;
|
||||
use Configurations;
|
||||
use Criteria;
|
||||
use DBAdapter;
|
||||
use Exception;
|
||||
use EntitySolrRequestData;
|
||||
use Exception;
|
||||
use G;
|
||||
use Groups;
|
||||
use GroupUserPeer;
|
||||
use InputDocument;
|
||||
use InvalidIndexSearchTextException;
|
||||
use ListParticipatedLast;
|
||||
use PmDynaform;
|
||||
use ProcessMaker\BusinessModel\ProcessSupervisor as BmProcessSupervisor;
|
||||
use ProcessMaker\BusinessModel\Task as BmTask;
|
||||
use ProcessMaker\BusinessModel\User as BmUser;
|
||||
use ProcessMaker\BusinessModel\ProcessSupervisor as BmProcessSupervisor;
|
||||
use ProcessMaker\Core\System;
|
||||
use ProcessMaker\Exception\UploadException;
|
||||
use ProcessMaker\Plugins\PluginRegistry;
|
||||
use ProcessMaker\Services\OAuth2\Server;
|
||||
use ProcessMaker\Validation\ExceptionRestApi;
|
||||
use ProcessMaker\Validation\Validator as FileValidator;
|
||||
use ProcessPeer;
|
||||
use ProcessUser;
|
||||
use ProcessUserPeer;
|
||||
use ProcessPeer;
|
||||
use RBAC;
|
||||
use ResultSet;
|
||||
use RoutePeer;
|
||||
use SubApplication;
|
||||
use SubProcessPeer;
|
||||
use Task as ModelTask;
|
||||
use Tasks as ClassesTasks;
|
||||
use TaskPeer;
|
||||
use Tasks as ClassesTasks;
|
||||
use TaskUserPeer;
|
||||
use Users as ModelUsers;
|
||||
use UsersPeer;
|
||||
@@ -57,6 +61,8 @@ class Cases
|
||||
{
|
||||
private $formatFieldNameInUppercase = true;
|
||||
private $messageResponse = [];
|
||||
const MB_IN_KB = 1024;
|
||||
const UNIT_MB = 'MB';
|
||||
|
||||
/**
|
||||
* Set the format of the fields name (uppercase, lowercase)
|
||||
@@ -3734,4 +3740,142 @@ class Cases
|
||||
|
||||
return $isSupervisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload file in the corresponding folder
|
||||
*
|
||||
* @param string $userUid
|
||||
* @param string $appUid
|
||||
* @param string $varName
|
||||
* @param mixed $inpDocUid
|
||||
* @param string $appDocUid
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function uploadFiles($userUid, $appUid, $varName, $inpDocUid = -1, $appDocUid = null)
|
||||
{
|
||||
$response = [];
|
||||
if (isset($_FILES["form"]["name"]) && count($_FILES["form"]["name"]) > 0) {
|
||||
// Get the delIndex related to the case
|
||||
$cases = new ClassesCases();
|
||||
$delIndex = $cases->getCurrentDelegation($appUid, $userUid);
|
||||
// Get information about the user
|
||||
$user = new ModelUsers();
|
||||
$userCreator = $user->loadDetailed($userUid)['USR_FULLNAME'];
|
||||
$i = 0;
|
||||
foreach ($_FILES["form"]["name"] as $fieldIndex => $fieldValue) {
|
||||
if (!is_array($fieldValue)) {
|
||||
$arrayFileName = [
|
||||
'name' => $_FILES["form"]["name"][$fieldIndex],
|
||||
'tmp_name' => $_FILES["form"]["tmp_name"][$fieldIndex],
|
||||
'error' => $_FILES["form"]["error"][$fieldIndex]
|
||||
];
|
||||
|
||||
// We will to review the validation related to the Input document
|
||||
$file = [
|
||||
'filename' => $arrayFileName["name"],
|
||||
'path' => $arrayFileName["tmp_name"]
|
||||
];
|
||||
$this->canUploadFileRelatedToInput($inpDocUid, $file);
|
||||
|
||||
// There is no error, the file uploaded with success
|
||||
if ($arrayFileName["error"] === UPLOAD_ERR_OK) {
|
||||
$appDocument = new AppDocument();
|
||||
$objCreated = $appDocument->uploadAppDocument(
|
||||
$appUid,
|
||||
$userUid,
|
||||
$delIndex,
|
||||
$inpDocUid ,
|
||||
$arrayFileName,
|
||||
$varName,
|
||||
$appDocUid
|
||||
);
|
||||
$response[$i] = [
|
||||
'appDocUid' => $objCreated->getAppDocUid(),
|
||||
'docVersion' => $objCreated->getDocVersion(),
|
||||
'appDocFilename' => $objCreated->getAppDocFilename(),
|
||||
'appDocCreateDate' => $objCreated->getAppDocCreateDate(),
|
||||
'appDocType' => $objCreated->getAppDocType(),
|
||||
'appDocIndex' => $objCreated->getAppDocIndex(),
|
||||
'appDocCreateUser' => $userCreator
|
||||
];
|
||||
|
||||
$i++;
|
||||
} else {
|
||||
throw new UploadException($arrayFileName['error']);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new Exception(G::LoadTranslation('ID_ERROR_UPLOAD_FILE_CONTACT_ADMINISTRATOR'));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the validations related to an Input Document
|
||||
*
|
||||
* @param array $file
|
||||
* @param mixed $inpDocUid
|
||||
*
|
||||
* @return boolean
|
||||
* @throws ExceptionRestApi
|
||||
*/
|
||||
private function canUploadFileRelatedToInput($file, $inpDocUid = -1)
|
||||
{
|
||||
if ($inpDocUid !== -1) {
|
||||
$inputDocument = new InputDocument();
|
||||
$inputExist = $inputDocument->InputExists($inpDocUid);
|
||||
if ($inputExist) {
|
||||
$inputProperties = $inputDocument->load($inpDocUid);
|
||||
$inpDocTypeFile = $inputProperties['INP_DOC_TYPE_FILE'];
|
||||
$inpDocMaxFileSize = (int)$inputProperties["INP_DOC_MAX_FILESIZE"];
|
||||
$inpDocMaxFileSizeUnit = $inputProperties["INP_DOC_MAX_FILESIZE_UNIT"];
|
||||
|
||||
$validator = new FileValidator();
|
||||
// Rule: extension
|
||||
$validator->addRule()
|
||||
->validate($file, function ($file) use ($inpDocTypeFile) {
|
||||
$result = G::verifyInputDocExtension($inpDocTypeFile, $file->filename, $file->path);
|
||||
|
||||
return $result->status === false;
|
||||
})
|
||||
->status(415)
|
||||
->message(G::LoadTranslation('ID_UPLOAD_INVALID_DOC_TYPE_FILE', [$inpDocTypeFile]))
|
||||
->log(function ($rule) {
|
||||
Bootstrap::registerMonologPhpUploadExecution('phpUpload', 250, $rule->getMessage(),
|
||||
$rule->getData()->filename);
|
||||
});
|
||||
// Rule: maximum file size
|
||||
$validator->addRule()
|
||||
->validate($file, function ($file) use ($inpDocMaxFileSize, $inpDocMaxFileSizeUnit) {
|
||||
if ($inpDocMaxFileSize > 0) {
|
||||
$totalMaxFileSize = $inpDocMaxFileSize * ($inpDocMaxFileSizeUnit == self::UNIT_MB ? self::MB_TO_KB * self::MB_TO_KB : self::MB_TO_KB);
|
||||
$fileSize = filesize($file->path);
|
||||
if ($fileSize > $totalMaxFileSize) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
})
|
||||
->status(413)
|
||||
->message(G::LoadTranslation("ID_UPLOAD_INVALID_DOC_MAX_FILESIZE",
|
||||
[$inpDocMaxFileSize . $inpDocMaxFileSizeUnit]))
|
||||
->log(function ($rule) {
|
||||
Bootstrap::registerMonologPhpUploadExecution('phpUpload', 250, $rule->getMessage(),
|
||||
$rule->getData()->filename);
|
||||
});
|
||||
$validator->validate();
|
||||
// We will to review if the validator has some error
|
||||
if ($validator->fails()) {
|
||||
throw new ExceptionRestApi($validator->getMessage(), $validator->getStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
class UploadException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param integer $code
|
||||
*/
|
||||
public function __construct($code)
|
||||
{
|
||||
$message = $this->getMessageByCode($code);
|
||||
parent::__construct($message, $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message to the corresponding error code
|
||||
*
|
||||
* @param integer $code
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getMessageByCode($code)
|
||||
{
|
||||
// These messages do not have translations because they will be caught in the exceptions
|
||||
switch ($code) {
|
||||
case UPLOAD_ERR_INI_SIZE:
|
||||
$message = "The uploaded file exceeds the upload_max_filesize directive in php.ini";
|
||||
break;
|
||||
case UPLOAD_ERR_FORM_SIZE:
|
||||
$message = "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form";
|
||||
break;
|
||||
case UPLOAD_ERR_PARTIAL:
|
||||
$message = "The uploaded file was only partially uploaded";
|
||||
break;
|
||||
case UPLOAD_ERR_NO_FILE:
|
||||
$message = "No file was uploaded";
|
||||
break;
|
||||
case UPLOAD_ERR_NO_TMP_DIR:
|
||||
$message = "Missing a temporary folder";
|
||||
break;
|
||||
case UPLOAD_ERR_CANT_WRITE:
|
||||
$message = "Failed to write file to disk";
|
||||
break;
|
||||
case UPLOAD_ERR_EXTENSION:
|
||||
$message = "File upload stopped by extension";
|
||||
break;
|
||||
default:
|
||||
$message = "Unknown upload error";
|
||||
break;
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
@@ -1370,4 +1370,38 @@ class Cases extends Api
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload attachment related to the case, it does not need docUid
|
||||
* Upload document related to the case, it does need docUid
|
||||
*
|
||||
* @url POST /:app_uid/upload/:var_name
|
||||
* @url POST /:app_uid/upload/:var_name/:doc_uid
|
||||
* @url POST /:app_uid/upload/:var_name/:doc_uid/:app_doc_uid
|
||||
*
|
||||
* @param string $app_uid
|
||||
* @param string $var_name
|
||||
* @param string $doc_uid
|
||||
* @param string $app_doc_uid
|
||||
*
|
||||
* @return array
|
||||
* @throws RestException
|
||||
*
|
||||
* @access protected
|
||||
* @class AccessControl {@permission PM_CASES}
|
||||
*/
|
||||
public function uploadDocumentToCase($app_uid, $var_name, $doc_uid = '-1', $app_doc_uid = null)
|
||||
{
|
||||
try {
|
||||
$userUid = $this->getUserId();
|
||||
$case = new BmCases();
|
||||
$response = $case->uploadFiles($userUid, $app_uid, $var_name, $doc_uid, $app_doc_uid);
|
||||
} catch (ExceptionRestApi $e) {
|
||||
throw new RestException($e->getCode(), $e->getMessage());
|
||||
} catch (Exception $e) {
|
||||
throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user