Merged in feature/PMC-15 (pull request #6698)
PMC-10 Approved-by: Julio Cesar Laura Avendaño <contact@julio-laura.com>
This commit is contained in:
@@ -672,5 +672,84 @@ class AppDocument extends BaseAppDocument
|
|||||||
}
|
}
|
||||||
return false;
|
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 );
|
$oCriteria->add( AppFolderPeer::FOLDER_UID, $FolderUid );
|
||||||
AppFolderPeer::doDelete( $oCriteria );
|
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 AppCacheView;
|
||||||
use AppCacheViewPeer;
|
use AppCacheViewPeer;
|
||||||
use Applications;
|
|
||||||
use ApplicationPeer;
|
|
||||||
use AppSolr;
|
|
||||||
use AppDelegation;
|
|
||||||
use AppDelegationPeer;
|
|
||||||
use AppDelay;
|
use AppDelay;
|
||||||
use AppDelayPeer;
|
use AppDelayPeer;
|
||||||
|
use AppDelegation;
|
||||||
|
use AppDelegationPeer;
|
||||||
use AppDocument;
|
use AppDocument;
|
||||||
use AppDocumentPeer;
|
use AppDocumentPeer;
|
||||||
use AppHistoryPeer;
|
use AppHistoryPeer;
|
||||||
use AppThreadPeer;
|
use ApplicationPeer;
|
||||||
|
use Applications;
|
||||||
use AppNotesPeer;
|
use AppNotesPeer;
|
||||||
|
use AppSolr;
|
||||||
use BasePeer;
|
use BasePeer;
|
||||||
|
use Bootstrap;
|
||||||
use BpmnEngineServicesSearchIndex;
|
use BpmnEngineServicesSearchIndex;
|
||||||
use Cases as ClassesCases;
|
use Cases as ClassesCases;
|
||||||
use CasesPeer;
|
use CasesPeer;
|
||||||
use Criteria;
|
|
||||||
use Configurations;
|
use Configurations;
|
||||||
|
use Criteria;
|
||||||
use DBAdapter;
|
use DBAdapter;
|
||||||
use Exception;
|
|
||||||
use EntitySolrRequestData;
|
use EntitySolrRequestData;
|
||||||
|
use Exception;
|
||||||
use G;
|
use G;
|
||||||
use Groups;
|
use Groups;
|
||||||
use GroupUserPeer;
|
use GroupUserPeer;
|
||||||
|
use InputDocument;
|
||||||
use InvalidIndexSearchTextException;
|
use InvalidIndexSearchTextException;
|
||||||
use ListParticipatedLast;
|
use ListParticipatedLast;
|
||||||
use PmDynaform;
|
use PmDynaform;
|
||||||
|
use ProcessMaker\BusinessModel\ProcessSupervisor as BmProcessSupervisor;
|
||||||
use ProcessMaker\BusinessModel\Task as BmTask;
|
use ProcessMaker\BusinessModel\Task as BmTask;
|
||||||
use ProcessMaker\BusinessModel\User as BmUser;
|
use ProcessMaker\BusinessModel\User as BmUser;
|
||||||
use ProcessMaker\BusinessModel\ProcessSupervisor as BmProcessSupervisor;
|
|
||||||
use ProcessMaker\Core\System;
|
use ProcessMaker\Core\System;
|
||||||
|
use ProcessMaker\Exception\UploadException;
|
||||||
use ProcessMaker\Plugins\PluginRegistry;
|
use ProcessMaker\Plugins\PluginRegistry;
|
||||||
use ProcessMaker\Services\OAuth2\Server;
|
use ProcessMaker\Services\OAuth2\Server;
|
||||||
|
use ProcessMaker\Validation\ExceptionRestApi;
|
||||||
|
use ProcessMaker\Validation\Validator as FileValidator;
|
||||||
|
use ProcessPeer;
|
||||||
use ProcessUser;
|
use ProcessUser;
|
||||||
use ProcessUserPeer;
|
use ProcessUserPeer;
|
||||||
use ProcessPeer;
|
|
||||||
use RBAC;
|
use RBAC;
|
||||||
use ResultSet;
|
use ResultSet;
|
||||||
use RoutePeer;
|
use RoutePeer;
|
||||||
use SubApplication;
|
use SubApplication;
|
||||||
use SubProcessPeer;
|
use SubProcessPeer;
|
||||||
use Task as ModelTask;
|
use Task as ModelTask;
|
||||||
use Tasks as ClassesTasks;
|
|
||||||
use TaskPeer;
|
use TaskPeer;
|
||||||
|
use Tasks as ClassesTasks;
|
||||||
use TaskUserPeer;
|
use TaskUserPeer;
|
||||||
use Users as ModelUsers;
|
use Users as ModelUsers;
|
||||||
use UsersPeer;
|
use UsersPeer;
|
||||||
@@ -57,6 +61,8 @@ class Cases
|
|||||||
{
|
{
|
||||||
private $formatFieldNameInUppercase = true;
|
private $formatFieldNameInUppercase = true;
|
||||||
private $messageResponse = [];
|
private $messageResponse = [];
|
||||||
|
const MB_IN_KB = 1024;
|
||||||
|
const UNIT_MB = 'MB';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the format of the fields name (uppercase, lowercase)
|
* Set the format of the fields name (uppercase, lowercase)
|
||||||
@@ -3734,4 +3740,142 @@ class Cases
|
|||||||
|
|
||||||
return $isSupervisor;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1393,4 +1393,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