You can check for duplicate files by creating a trigger which looks up the files uploaded to the case in the
APP_DOCUMENT table. If a file with the same filename already exists in the case, then use
AppDocument::remove() to delete the file and then use
G::SendMessageText() to show a message to the user informing her that the duplicate file was deleted.
The trigger set to execute
after an Input Document would be like:
Code: Select all//check whether any of the uploaded files for the current case
//have duplicate filenames. If so, then delete the more recent file.
$caseId = @@APPLICATION;
$sql = "SELECT AD.*, C.CON_VALUE AS FILENAME FROM APP_DOCUMENT AD, CONTENT C
WHERE AD.APP_UID='$caseId' AND AD.APP_DOC_STATUS='ACTIVE' AND
AD.APP_DOC_TYPE<>'OUTPUT' AND AD.APP_DOC_UID=C.CON_ID AND
C.CON_CATEGORY='APP_DOC_FILENAME' AND C.CON_PARENT=AD.DOC_VERSION
ORDER BY AD.APP_DOC_CREATE_DATE DESC";
$aFiles = executeQuery($sql);
if (!isset($aFiles) or !is_array($aFiles)) {
throw new Exception("Error in query: $sql");
}
elseif (count($aFiles) > 0) {
$aLastFile = $aFiles[1];
@@msg = ''; //message to show the user
//check each file from case for duplicate filenames:
for ($i = 2; $i <= count($aFiles); $i++) {
//if duplicate filename, then delete the last file uploaded
if ($aLastFile['FILENAME'] == $aFiles[$i]['FILENAME']) {
$oLastDoc = new AppDocument();
$oLastDoc->remove($aLastFile['APP_DOC_UID'], $aLastFile['DOC_VERSION']);
$aUser = userInfo($aLastFile['USR_UID']);
$uploader = $aUser['firstname'].' '.$aUser['lastname'];
@@msg = "File '{$aLastFile['FILENAME']}' was deleted because a duplicate file ".
"was uploaded by $uploader at {$aLastFile['APP_DOC_CREATE_DATE']}.";
G::SendMessageText(@@msg, "INFO");
break;
}
}
}
Triggers after an Input Document are executed every time the user uploads a new file, so this trigger only needs to check for the last file uploaded. If you only want to check whether there are duplicates in a particular Input Document, then use this SQL query:
Code: Select all$inpDocId = 'XXXXXXXXXXXXXXXXXXXXXXX'; //set to the unique ID of the Input Document
$sql = "SELECT AD.*, C.CON_VALUE AS FILENAME FROM APP_DOCUMENT AD, CONTENT C
WHERE AD.APP_UID='$caseId' AND AD.APP_DOC_STATUS='ACTIVE' AND
AD.DOC_UID='$inpDocId' AND AD.APP_DOC_UID=C.CON_ID AND
C.CON_CATEGORY='APP_DOC_FILENAME' AND C.CON_PARENT=AD.DOC_VERSION
ORDER BY AD.APP_DOC_CREATE_DATE DESC";
The following trigger is used to check for duplicates uploaded to a File field in a DynaForm. It uses
PMFRedirectToStep() to return to DynaForm if the user uploads a duplicate file. Make sure to set the unique ID of the DynaForm in your process.
Code: Select all//set to the unique ID of the DynaForm to redirect back to:
$objId = '99666081658ed5d1ee7c945016185656';
//check whether any of the uploaded files for the current case
//have duplicate filenames. If so, then delete the more recent file.
$caseId = @@APPLICATION;
$sql = "SELECT AD.*, C.CON_VALUE AS FILENAME FROM APP_DOCUMENT AD, CONTENT C
WHERE AD.APP_UID='$caseId' AND AD.APP_DOC_STATUS='ACTIVE' AND
AD.APP_DOC_TYPE<>'OUTPUT' AND AD.APP_DOC_UID=C.CON_ID AND
C.CON_CATEGORY='APP_DOC_FILENAME' AND C.CON_PARENT=AD.DOC_VERSION
ORDER BY AD.APP_DOC_CREATE_DATE DESC";
$aFiles = executeQuery($sql);
if (!isset($aFiles) or !is_array($aFiles)) {
throw new Exception("Error in query: $sql");
}
elseif (count($aFiles) > 0) {
$aLastFile = $aFiles[1];
@@msg = ''; //message to show the user
//check each file from case for duplicate filenames:
for ($i = 2; $i <= count($aFiles); $i++) {
//if duplicate filename, then delete the last file uploaded
if ($aLastFile['FILENAME'] == $aFiles[$i]['FILENAME']) {
$oLastDoc = new AppDocument();
$oLastDoc->remove($aLastFile['APP_DOC_UID'], $aLastFile['DOC_VERSION']);
$aUser = userInfo($aLastFile['USR_UID']);
$uploader = $aUser['firstname'].' '.$aUser['lastname'];
@@msg = "File '{$aLastFile['FILENAME']}' was deleted because a duplicate file ".
"was uploaded by $uploader at {$aLastFile['APP_DOC_CREATE_DATE']}.";
G::SendMessageText(@@msg, "INFO");
PMFRedirectToStep(@@APPLICATION, @%INDEX, 'DYNAFORM', $objId);
}
}
}
Make sure to set the above trigger to fire
before the next step in the task (or
before assignment if the DynaForm is the last step in the task). Do NOT set it to fire directly after the DynaForm, because at that point the record of the selected file has not yet been saved to the
APP_DOCUMENT table in the database.
This code should work in both classic processes in ProcessMaker 2 and BPMN processes in ProcesMaker 3.
I have prepared an example classic process that shows how to do this with both an Input Document or an DynaForm containing a File field:
(11.83 KiB) Downloaded 360 times