Unofficial documentation how to do interesting things and work around problems in ProcessMaker

Moderator: amosbatto

Forum rules: Unofficial documentation for features which have not been tested by Quality Assurance or may change in future versions of ProcessMaker
#813646
Currently the REST endpoint POST /api/1.0/{workspace}/cases/{app_uid}/input-document does not have an options to associate the uploaded file with a File or MultipleFile field, so the uploaded file can be displayed in a DynaForm. This endpoint also does not have an option to give the uploaded file a new filename.

These options can be added by changing the ProcessMaker source code with a plain text editor.
1. First, add 3 additional post variables (variable_name, dynaform_uid, new_file_name) to the REST endpoint. Edit the file workflow/src/ProcessMaker/Services/Api/Cases/InputDocument.php and change the definition of the doPostInputDocument() function to:
Code: Select all
    /**
     * @url POST /:app_uid/input-document
     *
     * @param string $app_uid         Case's ID {@min 32}{@max 32}
     * @param string $tas_uid         Task's ID {@body}{@min 32}{@max 32}
     * @param string $inp_doc_uid     Input Document's unique ID {@min 32}{@max 32}
     * @param string $app_doc_comment (optional) Comment about the file {@body} 
     * @param string $variable_name   (optional) Name of variable associated with file/multipleFile field. If in a grid, set to "<grid-variable>_<row-number>_<field-id>". Ex: "clientList_2_contractFile". {@body}
     * @param string $dynaform_uid    (optional) ID of dynaform which holds file/multipleFile field. {@body} 
     * @param string $new_file_name   (optional) New file name {@body}
     */
    public function doPostInputDocument($app_uid, $tas_uid, $inp_doc_uid, $app_doc_comment='', $variable_name='', $dynaform_uid='', $new_file_name='')
    {
        try {
            $userUid = $this->getUserId();

            $inputDocument = new \ProcessMaker\BusinessModel\Cases\InputDocument();
            $response = $inputDocument->addCasesInputDocument($app_uid, $tas_uid, $app_doc_comment, 
                $inp_doc_uid, $userUid, false, $variable_name, $dynaform_uid, $new_file_name);
            return $response;
        } catch (\Exception $e) {
            throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()));
        }
    }
 

2. Then, edit the file workflow/engine/src/ProcessMaker/BusinessModel/Cases/InputDocument.php and change the definition of the addCasesInputDocument() function to add three additional parameters ($variableName, $dynaformUid, $newFileName). The following code is from version 3.2.1, so your version might be slightly different. Add the code between //ABB edit start and //ABB edit end, plus the two additional parameters in $case->addInputDocument() which are marked as //ABB added:
Code: Select all
    /**
     * Get data of Cases InputDocument
     *
     * @param string $applicationUid
     * @param string $taskUid
     * @param string $appDocComment
     * @param string $inputDocumentUid
     * @param string $userUid 
     * @param boolean $runningWorkflow 
     * @param string $variableName (optional) Variable name associated File/MultipleFile field. If in grid, set to "<grid-var>_<row-number>_<field-id>". Ex: "clientsList_2_contractFile"
     * @param string $dynaformUid (optional) ID of Dynaform holding File/MultipleFile field. Must be set if $variableName is set. 
     * @param string $newFileName (optional) New file name.
     * 
     * return array Return an array with data about the Input Document file
     */
    public function addCasesInputDocument($applicationUid, $taskUid, $appDocComment, $inputDocumentUid, $userUid, $runningWorkflow = true, 
        $variableName='', $dynaformUid='', $newFileName='')
    {
        try {
            if ((isset( $_FILES['form'] )) && ($_FILES['form']['error'] != 0)) {
                $code = $_FILES['form']['error'];
                switch ($code) {
                    case UPLOAD_ERR_INI_SIZE:
                        $message = \G::LoadTranslation( 'ID_UPLOAD_ERR_INI_SIZE' );
                        break;
                    case UPLOAD_ERR_FORM_SIZE:
                        $message = \G::LoadTranslation( 'ID_UPLOAD_ERR_FORM_SIZE' );
                        break;
                    case UPLOAD_ERR_PARTIAL:
                        $message = \G::LoadTranslation( 'ID_UPLOAD_ERR_PARTIAL' );
                        break;
                    case UPLOAD_ERR_NO_FILE:
                        $message = \G::LoadTranslation( 'ID_UPLOAD_ERR_NO_FILE' );
                        break;
                    case UPLOAD_ERR_NO_TMP_DIR:
                        $message = \G::LoadTranslation( 'ID_UPLOAD_ERR_NO_TMP_DIR' );
                        break;
                    case UPLOAD_ERR_CANT_WRITE:
                        $message = \G::LoadTranslation( 'ID_UPLOAD_ERR_CANT_WRITE' );
                        break;
                    case UPLOAD_ERR_EXTENSION:
                        $message = \G::LoadTranslation( 'ID_UPLOAD_ERR_EXTENSION' );
                        break;
                    default:
                        $message = \G::LoadTranslation( 'ID_UPLOAD_ERR_UNKNOWN' );
                        break;
                }
                \G::SendMessageText( $message, "ERROR" );
                $backUrlObj = explode( "sys" . SYS_SYS, $_SERVER['HTTP_REFERER'] );
                \G::header( "location: " . "/sys" . SYS_SYS . $backUrlObj[1] );
                die();
            }
            
            //ABB edit start:
            $fieldName = $variableName;
            
            //check whether variable name can be found in Dynaform and get its properties:
            if (!empty($variableName)) {
                if (empty($dynaformUid)) {
                    throw new Exception("Dynaform ID must be specified if variable_name is set.");  
                }
                
                //Get fields in DynaForm:
                \G::loadClass('pmFunctions');
                $aFields = PMFDynaFormFields($dynaformUid); 
                $aFieldFound = null;
                   
                //if a file field in a grid:
                if (preg_match('/^([a-zA-Z0-9_]+?)_(\d+)_([a-zA-Z0-9_]+)$/', $variableName, $aMatch)) {
                    $gridVar     = $aMatch[1];
                    $rowNo       = $aMatch[2];
                    $gridFieldId = $aMatch[3];
                    $aGridFieldFound = null;
                        
                    //Find the file's field in the grid:
                    foreach ($aFields as $aField) {
                       if (isset($aField->variable) and $aField->variable == $gridVar) {
                           if ($aField->type != 'grid') {
                               throw new Exception("Variable '$gridVar' should be associated with a grid, not a {$aField->type}.");
                           }
                           $aFieldFound = $aField;
                               
                           foreach ($aField->columns as $aColumn) {
                               if (isset($aColumn->id) and $aColumn->id == $gridFieldId) {
                                   $aGridFieldFound = $aColumn;
                                   if ($aGridFieldFound->type == 'file') {
                                       $fieldName = $gridVar.'_'.$rowNo.'_'.$aGridFieldFound->name;
                                   }
                                   break;
                               }
                           }
                               
                           if (empty($aGridFieldFound)) {
                               throw new Exception("Field ID '$gridFieldId' is not found in grid '$gridVar'.");
                           }
    
                           break;
                        }
                    }
                        
                    if (empty($aFieldFound)) {
                        throw new Exception("Grid variable '$gridVar' not found in Dynaform '$dynaformUid'.");
                    }
                }
                else {  //if file/multipleFile field is not in a grid:
                    foreach ($aFields as $aField) {
                       if (isset($aField->variable) and $aField->variable == $variableName) {
                           $aFieldFound = $aField;
                           break;
                       }
                    }
                    
                    if (empty($aFieldFound)) {
                        throw new Exception("Variable '$variableName' is not found in Dynaform '$dynaformUid'.");
                    }    
                       
                    if ($aFieldFound->type == 'file') {
                        $fieldName = $aFieldFound->name; 
                    } elseif ($aFieldFound->type != 'multipleFile') {
                        throw new Exception("Variable '$variableName' must be associated with a file or multipleFile field.");
                    }
                }
            }     
            //ABB edit end
            
            \G::LoadClass("case");
            $appDocUid = \G::generateUniqueID();
            $docVersion = '';
            $appDocType = 'INPUT';
            $case = new \Cases();
            $delIndex = \AppDelegation::getCurrentIndex($applicationUid);

            if ($runningWorkflow) {
                $case->thisIsTheCurrentUser($applicationUid, $delIndex, $userUid, 'REDIRECT', 'casesListExtJs');
            } else {
                $criteria = new \Criteria('workflow');

                $criteria->add(\AppDelegationPeer::APP_UID, $applicationUid);
                $criteria->add(\AppDelegationPeer::DEL_INDEX, $delIndex);
                $criteria->add(\AppDelegationPeer::USR_UID, $userUid);

                $rsCriteria = \ProcessUserPeer::doSelectRS($criteria);

                if (!$rsCriteria->next()) {
                    $case2 = new \ProcessMaker\BusinessModel\Cases();

                    $arrayApplicationData = $case2->getApplicationRecordByPk($applicationUid, [], false);

                    $msg = '';

                    $supervisor = new \ProcessMaker\BusinessModel\ProcessSupervisor();
                    $flagps = $supervisor->isUserProcessSupervisor($arrayApplicationData['PRO_UID'], $userUid);

                    if ($flagps == false) {
                        $msg = \G::LoadTranslation('ID_USER_NOT_IT_BELONGS_CASE_OR_NOT_SUPERVISOR');
                    }

                    if ($msg == '') {
                        $criteria = new \Criteria('workflow');

                        $criteria->add(\StepSupervisorPeer::PRO_UID, $arrayApplicationData['PRO_UID'], \Criteria::EQUAL);
                        $criteria->add(\StepSupervisorPeer::STEP_TYPE_OBJ, 'INPUT_DOCUMENT', \Criteria::EQUAL);
                        $criteria->add(\StepSupervisorPeer::STEP_UID_OBJ, $inputDocumentUid, \Criteria::EQUAL);

                        $rsCriteria = \StepSupervisorPeer::doSelectRS($criteria);

                        if (!$rsCriteria->next()) {
                            $msg = \G::LoadTranslation('ID_USER_IS_SUPERVISOR_DOES_NOT_ASSOCIATED_INPUT_DOCUMENT');
                        }
                    }

                    if ($msg != '') {
                        if ($runningWorkflow) {
                            \G::SendMessageText($msg, 'ERROR');
                            $backUrlObj = explode('sys' . SYS_SYS, $_SERVER['HTTP_REFERER']);

                            \G::header('location: ' . '/sys' . SYS_SYS . $backUrlObj[1]);
                            exit(0);
                        } else {
                            throw new \Exception($msg);
                        }
                    }
                }
            }

            //Load the fields
            $arrayField = $case->loadCase($applicationUid);
            $arrayField["APP_DATA"] = array_merge($arrayField["APP_DATA"], \G::getSystemConstants());
            //Validate Process Uid and Input Document Process Uid
            $inputDocumentInstance = new \InputDocument();
            $inputDocumentFields = $inputDocumentInstance->load($inputDocumentUid);
            if ($arrayField['PRO_UID'] != $inputDocumentFields['PRO_UID']) {
                throw new \Exception(\G::LoadTranslation("ID_INPUT_DOCUMENT_DOES_NOT_EXIST",
                                     array('UID=' . $inputDocumentUid, 'PRO_UID=' . $arrayField['PRO_UID'])));
            }
            //Triggers
            $arrayTrigger = $case->loadTriggers($taskUid, "INPUT_DOCUMENT", $inputDocumentUid, "AFTER");
            //Add Input Document
            if (empty($_FILES)) {
                throw new \Exception(\G::LoadTranslation("ID_CASES_INPUT_FILENAME_DOES_NOT_EXIST"));
            }
            if (!$_FILES["form"]["error"]) {
                $_FILES["form"]["error"] = 0;
            }
            if (isset($_FILES) && isset($_FILES["form"]) && count($_FILES["form"]) > 0) {
                $appDocUid = $case->addInputDocument($inputDocumentUid,
                    $appDocUid,
                    $docVersion,
                    $appDocType,
                    $appDocComment,
                    '',
                    $applicationUid,
                    $delIndex,
                    $taskUid,
                    $userUid,
                    "xmlform",
                    $_FILES["form"]["name"],
                    $_FILES["form"]["error"],
                    $_FILES["form"]["tmp_name"],
                    0,
                    false,
                    $fieldName,  //ABB added
                    $newFileName //ABB added
                );
                
                //ABB edit start:
                //add variable for file to the case if needed:
                if (!empty($appDocUid) and !empty($variableName)) {
                    require_once "classes/model/AppDocument.php";
                    
                    $oDoc = new \AppDocument();
                    $aDocInfo = $oDoc->Load($appDocUid);
                    
                    $aFileVar = array(
                       'appDocUid' => $appDocUid,
                       'name'      => $aDocInfo['APP_DOC_FILENAME'],
                       'version'   => $aDocInfo['DOC_VERSION']
                    );
                    
                    //if a file/multipleFile field in a grid:
                    if ($aFieldFound->type == 'grid') {
                        
                        //add grid variable and/or row number to the case if they don't yet exist:
                        if (!isset($arrayField["APP_DATA"][$gridVar])) {
                            $arrayField["APP_DATA"][$gridVar] = array();
                        }                        
                        if (!isset($arrayField["APP_DATA"][$gridVar][$rowNo])) {
                            $arrayField["APP_DATA"][$gridVar][$rowNo] = array();
                        }
                            
                        if ($aGridFieldFound->type == 'multipleFile') {
                            //add multipleFile field ID to grid row, if it doesn't yet exist:
                            if (!isset($arrayField["APP_DATA"][$gridVar][$rowNo][$gridFieldId])) {
                                $arrayField["APP_DATA"][$gridVar][$rowNo][$gridFieldId] = array();
                            }
                            
                            $arrayField["APP_DATA"][$gridVar][$rowNo][$gridFieldId][] = $aFileVar;                            
                        }
                        elseif ($aGridFieldFound->type == 'file') {
                            //add file field name to grid row:
                            $arrayField["APP_DATA"][$gridVar][$rowNo][$aGridFieldFound->name] = null;
                            
                            $arrayField["APP_DATA"][$fieldName] = json_encode(array($appDocUid));
                            $arrayField["APP_DATA"][$fieldName.'_label'] = json_encode(array($aFileVar['name']));
                        }
                        else {
                            throw new Exception("Field '$gridFieldId' in grid '$gridVar' should be a file or multipleFile field.");
                        } 
                    }
                    //if multipleFile field not in a grid:      
                    elseif ($aFieldFound->type == 'multipleFile') {
                        
                        if (empty($arrayField["APP_DATA"][$variableName])) {
                            $arrayField["APP_DATA"][$variableName] = array();
                        }
                        $arrayField["APP_DATA"][$variableName][] = $aFileVar;
                    }
                    //if file field not in a grid:
                    elseif ($aFieldFound->type == 'file') {
                        $arrayField["APP_DATA"][$fieldName] = json_encode(array($appDocUid));
                        $arrayField["APP_DATA"][$fieldName.'_label'] = json_encode(array($aFileVar['name']));
                    }
                    
                    //add variables to case:    
                    $aCaseInfo = array(
                       'APP_UID'    => $arrayField['APP_UID'], 
                       'APP_NUMBER' => $arrayField['APP_NUMBER'],
                       'DEL_INDEX'  => $delIndex,
                       'TAS_UID'    => $taskUid,
                       'APP_DATA'   => $arrayField['APP_DATA']
                    );
                    $case->updateCase($applicationUid, $aCaseInfo);
                } 
                //ABB edit end    
            }
            //Trigger - Execute after - Start
            $arrayField["APP_DATA"] = $case->executeTriggers ($taskUid,
                "INPUT_DOCUMENT",
                $inputDocumentUid,
                "AFTER",
                $arrayField["APP_DATA"]);
            //Trigger - Execute after - End
            //Save data
            $arrayData = array();
            $arrayData["APP_NUMBER"] = $arrayField["APP_NUMBER"];
            //$arrayData["APP_PROC_STATUS"] = $arrayField["APP_PROC_STATUS"];
            $arrayData["APP_DATA"]  = $arrayField["APP_DATA"];
            $arrayData["DEL_INDEX"] = $delIndex;
            $arrayData["TAS_UID"]   = $taskUid;
            $case->updateCase($applicationUid, $arrayData);
            return($this->getCasesInputDocument($applicationUid, $userUid, $appDocUid));
        } catch (\Exception $e) {
            throw $e;
        }
    } 
3. Finally, edit the file workflow/engine/classes/class.case.php to add two additional parameters ($fieldName, $newFileName) to the addInputDocument() function. The 4 lines with the comment //ABB added have been added to the code. If not using version 3.2.1, then only add those 4 lines and do not change the rest of the function's code:
Code: Select all
    /**
     * Add a input document
     *
     * Return the application document ID
     *
     * @param string $inputDocumentUid Input document ID
     * @param string $appDocUid        Application document ID
     * @param int    $docVersion       Document version
     * @param string $appDocType       Document type
     * @param string $appDocComment    Document comment
     * @param string $inputDocumentAction Action, posible values: null or empty (Add), "R" (Replace), "NV" (New Version)
     * @param string $applicationUid   Application ID
     * @param int    $delIndex         Delegation index
     * @param string $taskUid          Task ID
     * @param string $userUid          User ID
     * @param string $option           Option, posible values: "xmlform", "file"
     * @param string $file             File ($_FILES["form"]["name"]["APP_DOC_FILENAME"] or path to file)
     * @param int    $fileError        File error ($_FILES["form"]["error"]["APP_DOC_FILENAME"] or 0)
     * @param string $fileTmpName      File temporal name ($_FILES["form"]["tmp_name"]["APP_DOC_FILENAME"] or null)
     * @param string $fileSize         File size ($_FILES["form"]["size"]["APP_DOC_FILENAME"] or 0)
     * @param boolean $isInputDocumentOfGrid Set to true if file will be added to grid.
     * @param string $fieldName        Name of DynaForm field to display file or ''. If file field in grid, set to "<grid-var>_<row-number>_<field-name>". If multipleFile in Grid, then "<grid-var>_<row-number>_<field-id>"
     * @param string $newFileName      New file name for file or ''.
     * 
     * @return string Return application document ID
     */
    public function addInputDocument($inputDocumentUid, $appDocUid, $docVersion, $appDocType, $appDocComment, $inputDocumentAction, 
        $applicationUid, $delIndex, $taskUid, $userUid, $option, $file, $fileError = 0, $fileTmpName = null, $fileSize = 0, 
        $isInputDocumentOfGrid = false, $fieldName='', $newFileName='')
    {
        $appDocFileName = null;
        $sw = 0;

        switch ($option) {
            case "xmlform":
                $appDocFileName = $file;

                if ($fileError == 0) {
                    $sw = 1;
                }
                break;
            case "file":
                $appDocFileName = basename($file);

                if (file_exists($file) && is_file($file)) {
                    $sw = 1;
                }
                break;
        }

        if ($sw == 0) {
            return null;
        }

        $folderId = '';
        $tags = '';

        if (!$isInputDocumentOfGrid) {
            //Info
            $inputDocument = new InputDocument();
            $arrayInputDocumentData = $inputDocument->load($inputDocumentUid);

            //--- Validate Filesize of $_FILE
            $inpDocMaxFilesize = $arrayInputDocumentData["INP_DOC_MAX_FILESIZE"];
            $inpDocMaxFilesizeUnit = $arrayInputDocumentData["INP_DOC_MAX_FILESIZE_UNIT"];

            $inpDocMaxFilesize = $inpDocMaxFilesize * (($inpDocMaxFilesizeUnit == "MB") ? 1024 * 1024 : 1024); //Bytes

            if ($inpDocMaxFilesize > 0 && $fileSize > 0) {
                if ($fileSize > $inpDocMaxFilesize) {
                    throw new Exception(G::LoadTranslation("ID_SIZE_VERY_LARGE_PERMITTED"));
                }
            }
            //Get the Custom Folder ID (create if necessary)
            $appFolder = new AppFolder();
            $folderId = $appFolder->createFromPath($arrayInputDocumentData["INP_DOC_DESTINATION_PATH"], $applicationUid);

            $tags = $appFolder->parseTags($arrayInputDocumentData["INP_DOC_TAGS"], $applicationUid);
        }
        
        $fileName = !empty($newFileName) ? $newFileName : $appDocFileName; //ABB added
        $appDocument = new AppDocument();
        $arrayField = array();

        switch ($inputDocumentAction) {
            case "R":
                //Replace
                $arrayField = array(
                    "APP_DOC_UID"      => $appDocUid,
                    "APP_UID"          => $applicationUid,
                    "DOC_VERSION"      => $docVersion,
                    "DEL_INDEX"        => $delIndex,
                    "USR_UID"          => $userUid,
                    "DOC_UID"          => $inputDocumentUid,
                    "APP_DOC_TYPE"     => $appDocType,
                    "APP_DOC_CREATE_DATE" => date("Y-m-d H:i:s"),
                    "APP_DOC_COMMENT"  => $appDocComment,
                    "APP_DOC_TITLE"    => "",
                    "APP_DOC_FILENAME" => $fileName,
                    "APP_DOC_FIELDNAME"=> $fieldName, //ABB added
                    "FOLDER_UID"       => $folderId,
                    "APP_DOC_TAGS"     => $tags
                );

                $appDocument->update($arrayField);
                break;
            case "NV":
                //New Version
                $arrayField = array(
                    "APP_DOC_UID"      => $appDocUid,
                    "APP_UID"          => $applicationUid,
                    "DEL_INDEX"        => $delIndex,
                    "USR_UID"          => $userUid,
                    "DOC_UID"          => $inputDocumentUid,
                    "APP_DOC_TYPE"     => $appDocType,
                    "APP_DOC_CREATE_DATE" => date("Y-m-d H:i:s"),
                    "APP_DOC_COMMENT"  => $appDocComment,
                    "APP_DOC_TITLE"    => "",
                    "APP_DOC_FILENAME" => $fileName,
                    "APP_DOC_FIELDNAME"=> $fieldName,  //ABB added
                    "FOLDER_UID"       => $folderId,
                    "APP_DOC_TAGS"     => $tags
                );

                $appDocument->create($arrayField);
                break;
            default:
                //New
                $arrayField = array(
                    "APP_UID"          => $applicationUid,
                    "DEL_INDEX"        => $delIndex,
                    "USR_UID"          => $userUid,
                    "DOC_UID"          => $inputDocumentUid,
                    "APP_DOC_TYPE"     => $appDocType,
                    "APP_DOC_CREATE_DATE" => date("Y-m-d H:i:s"),
                    "APP_DOC_COMMENT"  => $appDocComment,
                    "APP_DOC_TITLE"    => "",
                    "APP_DOC_FILENAME" => $fileName,
                    "APP_DOC_FIELDNAME"=> $fieldName,  //ABB added
                    "FOLDER_UID"       => $folderId,
                    "APP_DOC_TAGS"     => $tags
                );

                $appDocument->create($arrayField);
                break;
        }

        //Save the file
        $appDocUid = $appDocument->getAppDocUid();
        $docVersion = $appDocument->getDocVersion();
        $arrayInfo = pathinfo($appDocument->getAppDocFilename());
        $extension = (isset($arrayInfo["extension"])) ? $arrayInfo["extension"] : null;
        $strPathName = PATH_DOCUMENT . G::getPathFromUID($applicationUid) . PATH_SEP;
        $strFileName = $appDocUid . "_" . $docVersion . "." . $extension;

        switch ($option) {
            case "xmlform":
                G::uploadFile($fileTmpName, $strPathName, $strFileName);
                break;
            case "file":
                $umaskOld = umask(0);

                if (!is_dir($strPathName)) {
                    G::verifyPath($strPathName, true);
                }

                G::LoadSystem('inputfilter');
                $filter = new InputFilter();
                $file = $filter->xssFilterHard($file, 'path');

                copy($file, $strPathName . $strFileName);
                chmod($strPathName . $strFileName, 0666);
                umask($umaskOld);
                break;
        }

        //Plugin Hook PM_UPLOAD_DOCUMENT for upload document
        $pluginRegistry = &PMPluginRegistry::getSingleton();

        if ($pluginRegistry->existsTrigger(PM_UPLOAD_DOCUMENT) && class_exists("uploadDocumentData")) {
            $triggerDetail = $pluginRegistry->getTriggerInfo(PM_UPLOAD_DOCUMENT);
            $documentData = new uploadDocumentData(
                            $applicationUid,
                            $userUid,
                            $strPathName . $strFileName,
                            $arrayField["APP_DOC_FILENAME"],
                            $appDocUid,
                            $docVersion
            );
            $uploadReturn = $pluginRegistry->executeTriggers(PM_UPLOAD_DOCUMENT, $documentData);

            if ($uploadReturn) {
                $arrayField["APP_DOC_PLUGIN"] = $triggerDetail->sNamespace;

                if (!isset($arrayField["APP_DOC_UID"])) {
                    $arrayField["APP_DOC_UID"] = $appDocUid;
                }

                if (!isset($arrayField["DOC_VERSION"])) {
                    $arrayField["DOC_VERSION"] = $docVersion;
                }

                $appDocument->update($arrayField);

                unlink($strPathName . $strFileName);
            }
        }
        //End plugin

        return $appDocUid;
    }
 
Now, the REST endpoint has the following POST variables:
    [*][b]inp_doc_uid[/b] The unique ID of the Input Document definition. [*][b]tas_uid[/b] The unique ID of the task where the Input Document is a step. [*][b]app_doc_comment[/b] A comment in plain text about the uploaded file. [*][b]form[/b] The path to the file to upload to the ProcessMaker server. This path cannot be a web URL. If needing to use a file located on the internet, first download the file and save it as a local file to be uploaded. [*][b]variable_name[/b] [i]Optional.[/i] The name of the variable associated with a File or MultipleFile field in a DynaForm. If the file is to be placed in a grid, then set this to "{grid-variable}_{row-number}_{file-field-id}" where the row numbers in the grid start counting from the number 1. Example: "clientsList_2_contractFile" Note: It is recommended to use MultipleFile fields in grids, since File fields won't display their files when placed in grids, except by adding JavaScript code to the form. [*][b]dynaform_uid[/b] (optional) The unique ID of the dynaform which holds the File or MultipleFile field that will display the uploaded file. If setting the variable_name, then the dynaform_uid must also be set. [*][b]new_file_name[/b] (optional) New file name. If set, then the file will be renamed. It is strongly recommended to use the correct file extension to avoid problems displaying the file correctly when the user downloads it.
Here is a sample script to test this REST endpoint with PHP:
Code: Select all
$oToken = pmRestLogin($clientId, $clientSecret, 'johndoe', 'p4s$w0rD');

$processId  = '4679993805aa6853c626695082526803';
$taskId     = '8614663415aa68555cdc0c8073493050';
$formId     = '6668196175aa6aa72200f64063863285';
    
$aVars = array(
     'pro_uid' => $processId,
      'tas_uid' => $taskId
);

$oRet = pmRestRequest('POST', '/api/1.0/workflow/cases', $aVars, $oToken->access_token);

if ($oRet->status != 200) {
      var_dump($oRet);
      die;
}
    
print "Case {$oRet->response->app_number} created.\n";
$caseId     = $oRet->response->app_uid;
    
//check a File field outside grid:
$url        = "http://pm.example.com/api/1.0/workflow/cases/$caseId/input-document";
$path       = '/home/amos/setHref_error.png';
$inputDocId = '8025502575aa6aa50191a13019581855';//6

$aVars = array(
       'inp_doc_uid'     => $inputDocId,
       'tas_uid'         => $taskId,
       'app_doc_comment' => 'error image',
       'variable_name'   => 'userPhoto',
       'dynaform_uid'    => $formId,
       'new_file_name'   => 'myerror.png',
       'form'            => new CurlFile($path)
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $oToken->access_token));
curl_setopt($ch, CURLOPT_POSTFIELDS, $aPostVars);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$oRet = new StdClass();
$oRet->response = json_decode(curl_exec($ch));
$oRet->status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
    
print "HTTP status: {$oRet->status}\nResponse: ";
var_dump($oRet->response);
 
And here is a sample process to test it:
(37.2 KiB) Downloaded 42 times

Hello everyone, A couple days ago I tried to displ[…]

Hello, i have next problem When you submit a for[…]

Unfortunately, the Dev team decided that allowin[…]

Hello everyone in previous versions of PM the ca[…]