Resolving new conflict with PMCORE-543
This commit is contained in:
@@ -3230,6 +3230,7 @@ class Cases
|
||||
$arrayApplicationData = $this->getApplicationRecordByPk($applicationUid, [], false);
|
||||
$arrayApplicationData['APP_DATA'] = $case->unserializeData($arrayApplicationData['APP_DATA']);
|
||||
$flagDelete = false;
|
||||
$arrayVariableDocumentToDelete = $this->validateAppDocUid($arrayVariableDocumentToDelete);
|
||||
|
||||
foreach ($arrayVariableDocumentToDelete as $key => $value) {
|
||||
if (is_array($value) && !empty($value)) {
|
||||
@@ -3315,6 +3316,24 @@ class Cases
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate if all documents have appDocUid
|
||||
*
|
||||
* @param array $arrayVariableDocument
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function validateAppDocUid(array $arrayVariableDocument)
|
||||
{
|
||||
$newArrayVariableDocument = [];
|
||||
foreach ($arrayVariableDocument as $value) {
|
||||
if (array_key_exists('appDocUid', $value)) {
|
||||
$newArrayVariableDocument[] = $value;
|
||||
}
|
||||
}
|
||||
return $newArrayVariableDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Permissions, Participate, Access, Objects supervisor
|
||||
*
|
||||
|
||||
@@ -683,49 +683,52 @@ class FilesManager
|
||||
public function deleteProcessFilesManager($proUid, $prfUid, $verifyingRelationship = false)
|
||||
{
|
||||
try {
|
||||
$path = '';
|
||||
$criteriaProcessFiles = new Criteria("workflow");
|
||||
$criteriaProcessFiles->addSelectColumn(ProcessFilesPeer::PRF_PATH);
|
||||
$criteriaProcessFiles->add(ProcessFilesPeer::PRF_UID, $prfUid, Criteria::EQUAL);
|
||||
$resultSet1 = ProcessFilesPeer::doSelectRS($criteriaProcessFiles);
|
||||
$resultSet1->setFetchmode(ResultSet::FETCHMODE_ASSOC);
|
||||
$resultSet1->next();
|
||||
while ($row = $resultSet1->getRow()) {
|
||||
$path = $row['PRF_PATH'];
|
||||
$resultSet1->next();
|
||||
}
|
||||
if ($path == '') {
|
||||
throw new Exception(G::LoadTranslation("ID_INVALID_VALUE_FOR", array('prf_uid')));
|
||||
}
|
||||
|
||||
$relationshipEmailEvent = false;
|
||||
$criteria = new Criteria("workflow");
|
||||
$criteria->addSelectColumn(EmailEventPeer::PRF_UID);
|
||||
$criteria->add(EmailEventPeer::PRF_UID, $prfUid, Criteria::EQUAL);
|
||||
$resultSet2 = EmailEventPeer::doSelectRS($criteria);
|
||||
$resultSet2->setFetchmode(ResultSet::FETCHMODE_ASSOC);
|
||||
$resultSet2->next();
|
||||
while ($row = $resultSet2->getRow()) {
|
||||
$relationshipEmailEvent = true;
|
||||
$resultSet2->next();
|
||||
}
|
||||
if ($verifyingRelationship) {
|
||||
$criteriaEmailEvent = new Criteria('workflow');
|
||||
$criteriaEmailEvent->addSelectColumn(EmailEventPeer::PRF_UID);
|
||||
$criteriaEmailEvent->add(EmailEventPeer::PRF_UID, $prfUid, Criteria::EQUAL);
|
||||
$resultSet1 = EmailEventPeer::doSelectRS($criteriaEmailEvent);
|
||||
$resultSet1->setFetchmode(ResultSet::FETCHMODE_ASSOC);
|
||||
|
||||
$path = str_replace("\\", "/", $path);
|
||||
$fileName = basename($path);
|
||||
if ($relationshipEmailEvent && !$verifyingRelationship) {
|
||||
throw new Exception(G::LoadTranslation(G::LoadTranslation('ID_CANNOT_REMOVE_TEMPLATE_EMAIL_EVENT', [$fileName])));
|
||||
}
|
||||
|
||||
$path = PATH_DATA_MAILTEMPLATES . $proUid . "/" . $fileName;
|
||||
if (file_exists($path) && !is_dir($path)) {
|
||||
unlink($path);
|
||||
} else {
|
||||
$path = PATH_DATA_PUBLIC . $proUid . "/" . $fileName;
|
||||
if (file_exists($path) && !is_dir($path)) {
|
||||
unlink($path);
|
||||
if ($resultSet1->next()) {
|
||||
$relationshipEmailEvent = true;
|
||||
}
|
||||
}
|
||||
|
||||
$criteriaProcessFiles = new Criteria('workflow');
|
||||
$criteriaProcessFiles->addSelectColumn(ProcessFilesPeer::PRF_PATH);
|
||||
$criteriaProcessFiles->add(ProcessFilesPeer::PRF_UID, $prfUid, Criteria::EQUAL);
|
||||
$resultSet2 = ProcessFilesPeer::doSelectRS($criteriaProcessFiles);
|
||||
$resultSet2->setFetchmode(ResultSet::FETCHMODE_ASSOC);
|
||||
|
||||
if ($resultSet2->next()) {
|
||||
$row = $resultSet2->getRow();
|
||||
$path = $row['PRF_PATH'];
|
||||
|
||||
if (!empty($path)) {
|
||||
$path = str_replace("\\", "/", $path);
|
||||
$fileName = basename($path);
|
||||
if ($relationshipEmailEvent) {
|
||||
throw new Exception(G::LoadTranslation(
|
||||
G::LoadTranslation('ID_CANNOT_REMOVE_TEMPLATE_EMAIL_EVENT',
|
||||
[$fileName]
|
||||
)));
|
||||
}
|
||||
|
||||
$path = PATH_DATA_MAILTEMPLATES . $proUid . "/" . $fileName;
|
||||
|
||||
if (file_exists($path) && !is_dir($path)) {
|
||||
unlink($path);
|
||||
} else {
|
||||
$path = PATH_DATA_PUBLIC . $proUid . "/" . $fileName;
|
||||
|
||||
if (file_exists($path) && !is_dir($path)) {
|
||||
unlink($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ProcessFilesPeer::doDelete($criteriaProcessFiles);
|
||||
} catch (Exception $e) {
|
||||
throw $e;
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Commands;
|
||||
|
||||
use ProcessMaker\Core\ProcOpen;
|
||||
|
||||
class GenerateDataReport extends ProcOpen
|
||||
{
|
||||
private $workspace;
|
||||
private $tableName;
|
||||
private $type;
|
||||
private $processUid;
|
||||
private $gridKey;
|
||||
private $addTabUid;
|
||||
private $className;
|
||||
private $pathWorkspace;
|
||||
private $start;
|
||||
private $limit;
|
||||
|
||||
/**
|
||||
* Initializes the command parameters.
|
||||
* @param string $workspace
|
||||
* @param string $tableName
|
||||
* @param string $type
|
||||
* @param string $processUid
|
||||
* @param string $gridKey
|
||||
* @param string $addTabUid
|
||||
* @param string $className
|
||||
* @param string $pathWorkspace
|
||||
* @param integer $start
|
||||
* @param integer $limit
|
||||
*/
|
||||
public function __construct(
|
||||
$workspace,
|
||||
$tableName,
|
||||
$type = 'NORMAL',
|
||||
$processUid = '',
|
||||
$gridKey = '',
|
||||
$addTabUid = '',
|
||||
$className = '',
|
||||
$pathWorkspace,
|
||||
$start = 0,
|
||||
$limit = 10)
|
||||
{
|
||||
$this->workspace = $workspace;
|
||||
$this->tableName = $tableName;
|
||||
$this->type = $type;
|
||||
$this->processUid = $processUid;
|
||||
$this->gridKey = $gridKey;
|
||||
$this->addTabUid = $addTabUid;
|
||||
$this->className = $className;
|
||||
$this->pathWorkspace = $pathWorkspace;
|
||||
$this->start = $start;
|
||||
$this->limit = $limit;
|
||||
$this->setCwd(PATH_TRUNK);
|
||||
parent::__construct($this->buildCommand());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command to execute.
|
||||
* @return string
|
||||
*/
|
||||
private function buildCommand(): string
|
||||
{
|
||||
$command = PHP_BINDIR . "/php "
|
||||
. "./processmaker "
|
||||
. "'generate-data-report' "
|
||||
. "'{$this->workspace}' "
|
||||
. "'tableName={$this->tableName}' "
|
||||
. "'type={$this->type}' "
|
||||
. "'process={$this->processUid}' "
|
||||
. "'gridKey={$this->gridKey}' "
|
||||
. "'additionalTable={$this->addTabUid}' "
|
||||
. "'className={$this->className}' "
|
||||
. "'pathWorkspace={$this->pathWorkspace}' "
|
||||
. "'start={$this->start}' "
|
||||
. "'limit={$this->limit}' ";
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Commands;
|
||||
|
||||
use ProcessMaker\Core\ProcOpen;
|
||||
|
||||
class PopulateTableReport extends ProcOpen
|
||||
{
|
||||
private $workspace;
|
||||
private $sql;
|
||||
private $isRbac;
|
||||
|
||||
/**
|
||||
* Initializes the command parameters.
|
||||
* @param string $workspace
|
||||
* @param string $sql
|
||||
* @param boolean $isRbac
|
||||
*/
|
||||
public function __construct($workspace, $sql, $isRbac = false)
|
||||
{
|
||||
$this->workspace = $workspace;
|
||||
$this->sql = $sql;
|
||||
$this->isRbac = $isRbac;
|
||||
$this->setCwd(PATH_TRUNK);
|
||||
parent::__construct($this->buildCommand());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command to execute.
|
||||
* @return string
|
||||
*/
|
||||
public function buildCommand()
|
||||
{
|
||||
$command = PHP_BINDIR . "/php "
|
||||
. "./processmaker "
|
||||
. "'populate-table' "
|
||||
. "'{$this->workspace}' "
|
||||
. base64_encode($this->sql) . " "
|
||||
. ($this->isRbac ? "'1'" : "'0'");
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace ProcessMaker\Core;
|
||||
|
||||
use Bootstrap;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use ProcessMaker\BusinessModel\Factories\Jobs;
|
||||
@@ -140,12 +141,14 @@ class JobsManager
|
||||
|
||||
$_SESSION = $environment['session'];
|
||||
$_SERVER = $environment['server'];
|
||||
Propel::initConfiguration($environment['configuration']);
|
||||
foreach ($environment['constants'] as $key => $value) {
|
||||
if (!defined($key)) {
|
||||
define($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
Propel::close();
|
||||
Propel::init(PATH_CONFIG . "databases.php");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,6 +193,11 @@ class JobsManager
|
||||
$callback($environment);
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage() . ": " . $e->getTraceAsString());
|
||||
$context = [
|
||||
"trace" => $e->getTraceAsString(),
|
||||
"workspace" => $environment["constants"]["SYS_SYS"]
|
||||
];
|
||||
Bootstrap::registerMonolog("queue:work", 400, $e->getMessage(), $context, "");
|
||||
throw $e;
|
||||
}
|
||||
});
|
||||
|
||||
92
workflow/engine/src/ProcessMaker/Core/MultiProcOpen.php
Normal file
92
workflow/engine/src/ProcessMaker/Core/MultiProcOpen.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Core;
|
||||
|
||||
class MultiProcOpen
|
||||
{
|
||||
/**
|
||||
* Represents the waiting time before starting the process monitoring.
|
||||
* @var integer
|
||||
*/
|
||||
private $sleepTime = 1;
|
||||
|
||||
/**
|
||||
* This method obtains a paging by returning the start and limit indexes
|
||||
* compatible with the mysql pagination in its call function.
|
||||
* The return function must return an instance of the object "ProcessMaker\Core\ProcOpen".
|
||||
* Returns an array containing the status, content, and errors generated by
|
||||
* the open process.
|
||||
* @param int $size
|
||||
* @param int $chunk
|
||||
* @param callable $callback
|
||||
* @return array
|
||||
*/
|
||||
public function chunk(int $size, int $chunk, callable $callback): array
|
||||
{
|
||||
$start = 0;
|
||||
$limit = $chunk;
|
||||
$queries = [];
|
||||
for ($i = 1; $start < $size; $i++) {
|
||||
$queries[] = $callback($size, $start, $limit);
|
||||
$start = $i * $limit;
|
||||
}
|
||||
return $this->run($queries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a set of background processes.
|
||||
* The array must contain one or more instances of the object inherited from
|
||||
* the class "ProcessMaker\Core\ProcOpen"
|
||||
* Returns an array containing the status, content, and errors generated by
|
||||
* the open process.
|
||||
* @param array $processes
|
||||
* @return array
|
||||
*/
|
||||
public function run(array $processes): array
|
||||
{
|
||||
foreach ($processes as $procOpen) {
|
||||
$procOpen->open();
|
||||
}
|
||||
return $this->processMonitoring($processes);
|
||||
}
|
||||
|
||||
/**
|
||||
* It monitors the open processes, verifying if they have ended or thrown an
|
||||
* error and later closing the resources related to the process.
|
||||
* Returns an array containing the status, content, and errors generated by
|
||||
* the open process.
|
||||
* @param array $processes
|
||||
* @return array
|
||||
*/
|
||||
private function processMonitoring(array $processes): array
|
||||
{
|
||||
sleep($this->sleepTime); //this sleep is very important
|
||||
$i = 0;
|
||||
$n = count($processes);
|
||||
if ($n === 0) {
|
||||
return [];
|
||||
}
|
||||
$outputs = [];
|
||||
do {
|
||||
$index = $i % $n;
|
||||
if (isset($processes[$index])) {
|
||||
$procOpen = $processes[$index];
|
||||
$status = $procOpen->getStatus();
|
||||
$contents = $procOpen->getContents();
|
||||
$errors = $procOpen->getErrors();
|
||||
if ($status->running === false || !empty($errors)) {
|
||||
$outputs[] = [
|
||||
"status" => $status,
|
||||
"contents" => $contents,
|
||||
"errors" => $errors,
|
||||
];
|
||||
$procOpen->terminate();
|
||||
$procOpen->close();
|
||||
unset($processes[$index]);
|
||||
}
|
||||
}
|
||||
$i = $i + 1;
|
||||
} while (!empty($processes));
|
||||
return $outputs;
|
||||
}
|
||||
}
|
||||
126
workflow/engine/src/ProcessMaker/Core/ProcOpen.php
Normal file
126
workflow/engine/src/ProcessMaker/Core/ProcOpen.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Core;
|
||||
|
||||
class ProcOpen
|
||||
{
|
||||
private $command;
|
||||
private $resource;
|
||||
private $descriptorspec;
|
||||
private $pipes;
|
||||
private $cwd;
|
||||
|
||||
/**
|
||||
* This initializes the descriptors and the command for the open process.
|
||||
* @param string $command
|
||||
*/
|
||||
public function __construct(string $command)
|
||||
{
|
||||
$this->descriptorspec = [
|
||||
['pipe', 'r'],
|
||||
['pipe', 'w'],
|
||||
['pipe', 'w']
|
||||
];
|
||||
$this->command = $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the resource that represents the process.
|
||||
* @return resource
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the process execution directory.
|
||||
* @param string $cwd
|
||||
*/
|
||||
public function setCwd(string $cwd)
|
||||
{
|
||||
$this->cwd = $cwd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a background process.
|
||||
*/
|
||||
public function open()
|
||||
{
|
||||
if (empty($this->cwd)) {
|
||||
$this->resource = proc_open($this->command, $this->descriptorspec, $this->pipes);
|
||||
} else {
|
||||
$this->resource = proc_open($this->command, $this->descriptorspec, $this->pipes, $this->cwd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content of the process when it is finished.
|
||||
* @return string
|
||||
*/
|
||||
public function getContents()
|
||||
{
|
||||
if (is_resource($this->pipes[1])) {
|
||||
return stream_get_contents($this->pipes[1]);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the process errors when it is finished.
|
||||
* @return string
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
if (is_resource($this->pipes[2])) {
|
||||
return stream_get_contents($this->pipes[2]);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the resources related to the open process.
|
||||
* return void
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
if (is_resource($this->resource)) {
|
||||
foreach ($this->pipes as $value) {
|
||||
fclose($value);
|
||||
}
|
||||
proc_close($this->resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End the process before it ends.
|
||||
*/
|
||||
public function terminate()
|
||||
{
|
||||
if (is_resource($this->resource)) {
|
||||
proc_terminate($this->resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status of the process.
|
||||
* @return object
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
$status = [
|
||||
"command" => $this->command,
|
||||
"pid" => null,
|
||||
"running" => false,
|
||||
"signaled" => false,
|
||||
"stopped" => false,
|
||||
"exitcode" => -1,
|
||||
"termsig" => 0,
|
||||
"stopsig" => 0
|
||||
];
|
||||
if (is_resource($this->resource)) {
|
||||
$status = proc_get_status($this->resource);
|
||||
}
|
||||
return (object) $status;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ use Illuminate\Support\Facades\DB;
|
||||
class Application extends Model
|
||||
{
|
||||
protected $table = "APPLICATION";
|
||||
protected $primaryKey = 'APP_NUMBER';
|
||||
public $incrementing = false;
|
||||
// No timestamps
|
||||
public $timestamps = false;
|
||||
|
||||
|
||||
@@ -499,7 +499,7 @@ class Delegation extends Model
|
||||
Delegation::$groups = $groups;
|
||||
|
||||
// Start the first query
|
||||
$query1 = Delegation::query()->select('APP_NUMBER');
|
||||
$query1 = Delegation::query()->select(['APP_NUMBER', 'DEL_INDEX']);
|
||||
|
||||
// Add the join clause
|
||||
$query1->join('TASK', function ($join) {
|
||||
@@ -539,9 +539,10 @@ class Delegation extends Model
|
||||
$selfServiceTasks = TaskUser::getSelfServicePerUser($usrUid);
|
||||
|
||||
if (!empty($selfServiceTasks)) {
|
||||
// Start the first query
|
||||
$query2 = Delegation::query()->select('APP_NUMBER');
|
||||
// Start the second query
|
||||
$query2 = Delegation::query()->select(['APP_NUMBER', 'DEL_INDEX']);
|
||||
$query2->tasksIn($selfServiceTasks);
|
||||
$query2->isThreadOpen();
|
||||
$query2->noUserInThread();
|
||||
|
||||
// Build the complex query that uses "UNION DISTINCT" clause
|
||||
|
||||
12
workflow/engine/src/ProcessMaker/Model/ObjectPermission.php
Normal file
12
workflow/engine/src/ProcessMaker/Model/ObjectPermission.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Model;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ObjectPermission extends Model
|
||||
{
|
||||
protected $table = "OBJECT_PERMISSION";
|
||||
protected $primaryKey = 'OP_UID';
|
||||
public $timestamps = false;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Model;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class RbacAuthenticationSource extends Model
|
||||
{
|
||||
protected $table = "RBAC_AUTHENTICATION_SOURCE";
|
||||
public $incrementing = false;
|
||||
public $timestamps = false;
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace ProcessMaker\Model;
|
||||
|
||||
use G;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Task extends Model
|
||||
@@ -32,4 +33,38 @@ class Task extends Model
|
||||
return $query->where('TAS_ASSIGN_TYPE', '=', 'SELF_SERVICE')
|
||||
->where('TAS_GROUP_VARIABLE', '=', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title of the task
|
||||
*
|
||||
* @param integer $tasId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title($tasId)
|
||||
{
|
||||
$query = Task::query()->select('TAS_TITLE');
|
||||
$query->where('TAS_ID', $tasId);
|
||||
$results = $query->get();
|
||||
$title = '';
|
||||
$results->each(function ($item, $key) use (&$title) {
|
||||
$title = $item->TAS_TITLE;
|
||||
switch ($title) {
|
||||
case "INTERMEDIATE-THROW-EMAIL-EVENT":
|
||||
$title = G::LoadTranslation('ID_INTERMEDIATE_THROW_EMAIL_EVENT');
|
||||
break;
|
||||
case "INTERMEDIATE-THROW-MESSAGE-EVENT":
|
||||
$title = G::LoadTranslation('ID_INTERMEDIATE_THROW_MESSAGE_EVENT');
|
||||
break;
|
||||
case "INTERMEDIATE-CATCH-MESSAGE-EVENT":
|
||||
$title = G::LoadTranslation('ID_INTERMEDIATE_CATCH_MESSAGE_EVENT');
|
||||
break;
|
||||
case "INTERMEDIATE-CATCH-TIMER-EVENT":
|
||||
$title = G::LoadTranslation('ID_INTERMEDIATE_CATCH_TIMER_EVENT');
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
return $title;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -713,7 +713,7 @@ class BpmnWorkflow extends Project\Bpmn
|
||||
if ($emailEvent->existsEvent($bpmnEvent->getPrjUid(), $bpmnEvent->getEvnUid())) {
|
||||
$arrayEmailEventData = $emailEvent->getEmailEventData($bpmnEvent->getPrjUid(), $bpmnEvent->getEvnUid());
|
||||
$arrayEmailEventData = array_change_key_case($arrayEmailEventData, CASE_UPPER);
|
||||
$emailEvent->delete($bpmnEvent->getPrjUid(), $arrayEmailEventData["EMAIL_EVENT_UID"], true);
|
||||
$emailEvent->delete($bpmnEvent->getPrjUid(), $arrayEmailEventData["EMAIL_EVENT_UID"], true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -475,30 +475,40 @@ function changeAbbreviationOfDirectives($size)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encoding header filename used in Content-Disposition
|
||||
* Remove reserved characters for file names, this value will be used in the headers for stream the file
|
||||
*
|
||||
* @param string $fileName
|
||||
* @param string $replacement
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @see cases_Step.php
|
||||
* @see \ProcessMaker\BusinessModel\Cases\OutputDocument::addCasesOutputDocument()
|
||||
* @see workflow/engine/methods/cases/cases_ShowOutputDocument.php
|
||||
*
|
||||
* @link https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#file-and-directory-names
|
||||
* @link https://en.wikipedia.org/wiki/Filename#Comparison_of_filename_limitations
|
||||
*/
|
||||
function fixContentDispositionFilename($fileName, $replacement = '_')
|
||||
{
|
||||
//(double quote) has to be removed
|
||||
//(question mark) has to be replaced by underscore due to the issue in google chrome
|
||||
//(forward slash) has to replaced by underscore
|
||||
//(backslash) has to replaced by underscore
|
||||
$default = [
|
||||
'/[\"]/' => '',
|
||||
'/[\?]/' => $replacement,
|
||||
'/[\\|\/]/' => $replacement,
|
||||
'/\\\\/' => $replacement
|
||||
// The reserved characters vary depending on the S.O., but this list covers the more important
|
||||
$invalidCharacters = [
|
||||
"<", //(less than)
|
||||
">", //(greater than)
|
||||
":", //(colon)
|
||||
"\"", //(double quote)
|
||||
"/", //(forward slash)
|
||||
"\\", //(backslash)
|
||||
"|", //(vertical bar or pipe)
|
||||
"?", //(question mark)
|
||||
"*", //(asterisk)
|
||||
];
|
||||
|
||||
return preg_replace(array_keys($default), array_values($default), $fileName);
|
||||
// Replace the reserved characters
|
||||
$fileName = str_replace($invalidCharacters, $replacement, $fileName);;
|
||||
|
||||
// We need to encode the string in order to preserve some characters like "%"
|
||||
$fileName = rawurlencode($fileName);
|
||||
|
||||
return $fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user