PMC-985
This commit is contained in:
@@ -0,0 +1,355 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\BusinessModel\ActionsByEmail;
|
||||
|
||||
use AbeConfigurationPeer;
|
||||
use AbeResponses;
|
||||
use ActionsByEmailCoreClass;
|
||||
use AppDelegation;
|
||||
use AppNotes;
|
||||
use Bootstrap;
|
||||
use Cases;
|
||||
use Criteria;
|
||||
use EmailServerPeer;
|
||||
use Exception;
|
||||
use G;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use PhpImap\IncomingMail;
|
||||
use PhpImap\Mailbox;
|
||||
use PMLicensedFeatures;
|
||||
use ProcessMaker\BusinessModel\ActionsByEmail;
|
||||
use ProcessMaker\BusinessModel\EmailServer;
|
||||
use ProcessMaker\ChangeLog\ChangeLog;
|
||||
use ResultSet;
|
||||
use WsBase;
|
||||
|
||||
/**
|
||||
* Class ResponseReader
|
||||
* @package ProcessMaker\BusinessModel\ActionsByEmail
|
||||
*/
|
||||
class ResponseReader
|
||||
{
|
||||
/*----------------------------------********---------------------------------*/
|
||||
private $channel = "ActionsByEmail";
|
||||
private $case = [];
|
||||
private $messageResponseError = null;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMessageResponseError()
|
||||
{
|
||||
return $this->messageResponseError;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $messageResponseError
|
||||
*/
|
||||
public function setMessageResponseError($messageResponseError)
|
||||
{
|
||||
$this->messageResponseError = $messageResponseError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the Action by Email listener inbox looking for new messages
|
||||
*/
|
||||
public function actionsByEmailEmailResponse()
|
||||
{
|
||||
try {
|
||||
if (!extension_loaded('imap')) {
|
||||
G::outRes(G::LoadTranslation("ID_EXCEPTION_LOG_INTERFAZ", ['php_imap']) . "\n");
|
||||
exit;
|
||||
}
|
||||
if (PMLicensedFeatures
|
||||
::getSingleton()
|
||||
->verifyfeature('zLhSk5TeEQrNFI2RXFEVktyUGpnczV1WEJNWVp6cjYxbTU3R29mVXVZNWhZQT0=')) {
|
||||
$criteriaAbe = new Criteria();
|
||||
$criteriaAbe->add(AbeConfigurationPeer::ABE_TYPE, "RESPONSE");
|
||||
$resultAbe = AbeConfigurationPeer::doSelectRS($criteriaAbe);
|
||||
$resultAbe->setFetchmode(ResultSet::FETCHMODE_ASSOC);
|
||||
while ($resultAbe->next()) {
|
||||
$dataAbe = $resultAbe->getRow();
|
||||
$this->getAllEmails($dataAbe);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Bootstrap::registerMonolog(
|
||||
$this->channel,
|
||||
$e->getCode() != 0 ? $e->getCode() : 300,
|
||||
$e->getMessage(),
|
||||
$this->case,
|
||||
config("system.workspace"),
|
||||
'processmaker.log'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt password of Email Server
|
||||
* @param array $emailSetup
|
||||
* @return mixed|string
|
||||
*/
|
||||
private function decryptPassword(array $emailSetup)
|
||||
{
|
||||
$pass = isset($emailSetup['MESS_PASSWORD']) ? $emailSetup['MESS_PASSWORD'] : '';
|
||||
$passDec = G::decrypt($pass, 'EMAILENCRYPT');
|
||||
$auxPass = explode('hash:', $passDec);
|
||||
if (count($auxPass) > 1) {
|
||||
if (count($auxPass) == 2) {
|
||||
$pass = $auxPass[1];
|
||||
} else {
|
||||
array_shift($auxPass);
|
||||
$pass = implode('', $auxPass);
|
||||
}
|
||||
}
|
||||
return $pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Email of server listener
|
||||
* @param array $dataAbe
|
||||
*/
|
||||
public function getAllEmails(array $dataAbe)
|
||||
{
|
||||
try {
|
||||
$emailServer = new EmailServer();
|
||||
$emailSetup = (!is_null(EmailServerPeer::retrieveByPK($dataAbe['ABE_EMAIL_SERVER_RECEIVER_UID']))) ?
|
||||
$emailServer->getEmailServer($dataAbe['ABE_EMAIL_SERVER_RECEIVER_UID'], true) :
|
||||
$emailServer->getEmailServerDefault();
|
||||
if (empty($emailSetup) || (empty($emailSetup['MESS_INCOMING_SERVER']) && $emailSetup['MESS_INCOMING_PORT'] == 0)) {
|
||||
throw (new Exception(G::LoadTranslation('ID_ABE_LOG_CANNOT_READ'), 500));
|
||||
}
|
||||
$mailbox = new Mailbox(
|
||||
'{'. $emailSetup['MESS_INCOMING_SERVER'] . ':' . $emailSetup['MESS_INCOMING_PORT'] . '/imap/ssl/novalidate-cert}INBOX',
|
||||
$emailSetup['MESS_ACCOUNT'],
|
||||
$this->decryptPassword($emailSetup)
|
||||
);
|
||||
|
||||
// Read all messages into an array
|
||||
$mailsIds = $mailbox->searchMailbox('UNSEEN');
|
||||
if ($mailsIds) {
|
||||
// Get the first message and save its attachment(s) to disk:
|
||||
foreach ($mailsIds as $key => $mailId) {
|
||||
/** @var IncomingMail $mail */
|
||||
$mail = $mailbox->getMail($mailId, false);
|
||||
if (!empty($mail->textPlain)) {
|
||||
preg_match("/{(.*)}/", $mail->textPlain, $matches);
|
||||
if ($matches) {
|
||||
$dataEmail = G::json_decode(Crypt::decryptString($matches[1]), true);
|
||||
$dataAbeReq = loadAbeRequest($dataEmail['ABE_REQ_UID']);
|
||||
if (config("system.workspace") === $dataEmail['workspace']
|
||||
&& (array_key_exists('ABE_UID', $dataAbeReq) && $dataAbeReq['ABE_UID'] == $dataAbe['ABE_UID'])) {
|
||||
$this->case = $dataEmail;
|
||||
try {
|
||||
$appDelegate = new AppDelegation();
|
||||
$alreadyRouted = $appDelegate->alreadyRouted($this->case["appUid"], $this->case["delIndex"]);
|
||||
//Verify if the current case is already routed.
|
||||
if ($alreadyRouted) {
|
||||
$this->setMessageResponseError(G::LoadTranslation('ID_ABE_RESPONSE_ALREADY_ROUTED'));
|
||||
throw (new Exception(G::LoadTranslation('ID_CASE_DELEGATION_ALREADY_CLOSED'), 400));
|
||||
}
|
||||
$this->processABE($this->case, $mail, $dataAbe);
|
||||
$mailbox->markMailAsRead($mailId);
|
||||
Bootstrap::registerMonolog(
|
||||
$this->channel,
|
||||
100, // DEBUG
|
||||
G::LoadTranslation('ID_ABE_LOG_PROCESSED_OK'),
|
||||
$this->case,
|
||||
config("system.workspace"),
|
||||
'processmaker.log'
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
$this->sendMessageError(
|
||||
$this->getMessageResponseError() ? $this->getMessageResponseError() : $e->getMessage(),
|
||||
$this->case,
|
||||
$mail,
|
||||
$emailSetup
|
||||
);
|
||||
Bootstrap::registerMonolog(
|
||||
$this->channel,
|
||||
$e->getCode() != 0 ? $e->getCode() : 400,
|
||||
$e->getMessage(),
|
||||
$this->case,
|
||||
config("system.workspace"),
|
||||
'processmaker.log'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Bootstrap::registerMonolog(
|
||||
$this->channel,
|
||||
$e->getCode() != 0 ? $e->getCode() : 500,
|
||||
$e->getMessage(),
|
||||
$this->case,
|
||||
config("system.workspace"),
|
||||
'processmaker.log'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Derivation of the case with the mail information
|
||||
* @param array $caseInfo
|
||||
* @param IncomingMail $mail
|
||||
* @param array $dataAbe
|
||||
* @throws Exception
|
||||
*/
|
||||
public function processABE(array $caseInfo, IncomingMail $mail, array $dataAbe = [])
|
||||
{
|
||||
try {
|
||||
$actionsByEmail = new ActionsByEmail();
|
||||
$actionsByEmail->verifyLogin($caseInfo['appUid'], $caseInfo['delIndex']);
|
||||
|
||||
$case = new Cases();
|
||||
$caseFieldsABE = $case->loadCase($caseInfo['appUid'], $caseInfo['delIndex']);
|
||||
|
||||
$actionsByEmailCore = new ActionsByEmailCoreClass();
|
||||
$actionField = str_replace(
|
||||
$actionsByEmailCore->getPrefix(),
|
||||
'',
|
||||
$dataAbe['ABE_ACTION_FIELD']
|
||||
);
|
||||
$dataField = [];
|
||||
$dataField[$actionField] = $caseInfo['fieldValue'];
|
||||
$actionBodyField = str_replace(
|
||||
$actionsByEmailCore->getPrefix(),
|
||||
'',
|
||||
$dataAbe['ABE_ACTION_BODY_FIELD']
|
||||
);
|
||||
$textPlain = $mail->textPlain;
|
||||
$textPlain = substr($textPlain, 0, strpos($textPlain, "/="));
|
||||
$dataField[$actionBodyField] = $textPlain;
|
||||
$caseFieldsABE['APP_DATA'] = array_merge($caseFieldsABE['APP_DATA'], $dataField);
|
||||
|
||||
$dataResponses = [];
|
||||
$dataResponses['ABE_REQ_UID'] = $caseInfo['ABE_REQ_UID'];
|
||||
$dataResponses['ABE_RES_CLIENT_IP'] = 'localhost';
|
||||
$dataResponses['ABE_RES_DATA'] = serialize($dataField);
|
||||
$dataResponses['ABE_RES_STATUS'] = 'PENDING';
|
||||
$dataResponses['ABE_RES_MESSAGE'] = '';
|
||||
|
||||
try {
|
||||
$abeAbeResponsesInstance = new AbeResponses();
|
||||
$dataResponses['ABE_RES_UID'] = $abeAbeResponsesInstance->createOrUpdate($dataResponses);
|
||||
} catch (Exception $e) {
|
||||
Bootstrap::registerMonolog(
|
||||
$this->channel,
|
||||
300,
|
||||
$e->getMessage(),
|
||||
$this->case,
|
||||
config("system.workspace"),
|
||||
'processmaker.log'
|
||||
);
|
||||
}
|
||||
|
||||
ChangeLog::getChangeLog()
|
||||
->getUsrIdByUsrUid($caseFieldsABE['CURRENT_USER_UID'], true)
|
||||
->setSourceId(ChangeLog::FromABE);
|
||||
|
||||
$caseFieldsABE['CURRENT_DYNAFORM'] = '';
|
||||
$caseFieldsABE['USER_UID'] = $caseFieldsABE['CURRENT_USER_UID'];
|
||||
$caseFieldsABE['OBJECT_TYPE'] = '';
|
||||
|
||||
$case->updateCase($caseInfo['appUid'], $caseFieldsABE);
|
||||
|
||||
try {
|
||||
$ws = new WsBase();
|
||||
$result = $ws->derivateCase(
|
||||
$caseFieldsABE['CURRENT_USER_UID'],
|
||||
$caseInfo['appUid'],
|
||||
$caseInfo['delIndex'],
|
||||
true
|
||||
);
|
||||
$code = (is_array($result)) ? $result['status_code'] : $result->status_code;
|
||||
if ($code != 0) {
|
||||
throw new Exception(
|
||||
"An error occurred while the application was being processed\n" .
|
||||
"Error code: " . $result->status_code . "\nError message: " . $result->message
|
||||
);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->setMessageResponseError(G::LoadTranslation('ID_ABE_RESPONSE_ROUTING_FAILED'));
|
||||
throw (new Exception(G::LoadTranslation('ID_ABE_LOG_ROUTING_FAILED'), 400));
|
||||
}
|
||||
|
||||
//Update AbeResponses
|
||||
$dataResponses['ABE_RES_STATUS'] = ($code == 0)? 'SENT' : 'ERROR';
|
||||
$dataResponses['ABE_RES_MESSAGE'] = ($code == 0)? '-' : $result->message;
|
||||
|
||||
try {
|
||||
$abeAbeResponsesInstance = new AbeResponses();
|
||||
$abeAbeResponsesInstance->createOrUpdate($dataResponses);
|
||||
} catch (Exception $e) {
|
||||
Bootstrap::registerMonolog(
|
||||
$this->channel,
|
||||
300,
|
||||
$e->getMessage(),
|
||||
$this->case,
|
||||
config("system.workspace"),
|
||||
'processmaker.log'
|
||||
);
|
||||
}
|
||||
$dataAbeRequests = loadAbeRequest($caseInfo['ABE_REQ_UID']);
|
||||
//Save Cases Notes
|
||||
if ($dataAbe['ABE_CASE_NOTE_IN_RESPONSE'] == 1) {
|
||||
$customGrid = unserialize($dataAbe['ABE_CUSTOM_GRID']);
|
||||
$fieldLabel = null;
|
||||
foreach ($customGrid as $key => $value) {
|
||||
if ($value['abe_custom_value'] == $caseInfo['fieldValue']) {
|
||||
$fieldLabel = $value['abe_custom_label'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$appNotes = new AppNotes();
|
||||
$noteText = G::LoadTranslation('ID_ABE_CASE_NOTE_HEADER', ['emailAccount' => $mail->toString]) . "\n\n";
|
||||
$noteText .= G::LoadTranslation('ID_ABE_CASE_NOTE_ANSWER', ['optionLabel' => $fieldLabel ? $fieldLabel : $caseInfo['fieldValue']]) . "\n\n";
|
||||
$noteText .= G::LoadTranslation('ID_ABE_CASE_NOTE_COMMENT', ['emailBody' => $textPlain]);
|
||||
$noteContent = addslashes($noteText);
|
||||
$appNotes->postNewNote($caseInfo['appUid'], $caseFieldsABE['APP_DATA']['USER_LOGGED'], $noteContent, false);
|
||||
}
|
||||
$dataAbeRequests['ABE_REQ_ANSWERED'] = 1;
|
||||
$code == 0 ? uploadAbeRequest($dataAbeRequests) : '';
|
||||
} catch (Exception $e) {
|
||||
if ($e->getCode() == 400) {
|
||||
throw (new Exception($e->getMessage(), $e->getCode()));
|
||||
} else {
|
||||
$this->setMessageResponseError(G::LoadTranslation('ID_ABE_RESPONSE_CANNOT_BE_IDENTIFIED'));
|
||||
throw (new Exception(G::LoadTranslation('ID_ABE_LOG_CANNOT_BE_IDENTIFIED'), 300));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an error message to the sender
|
||||
* @param string $msgError
|
||||
* @param array $caseInf
|
||||
* @param IncomingMail $mail
|
||||
* @param array $emailSetup
|
||||
* @return \ProcessMaker\Util\Response|string|\WsResponse
|
||||
*/
|
||||
public function sendMessageError($msgError, array $caseInf, IncomingMail $mail, array $emailSetup)
|
||||
{
|
||||
$wsBase = new WsBase();
|
||||
$result = $wsBase->sendMessage(
|
||||
$caseInf['appUid'],
|
||||
$mail->toString,
|
||||
$mail->fromAddress,
|
||||
'',
|
||||
'',
|
||||
$mail->subject,
|
||||
'actionsByEmailErrorReply.html',
|
||||
['ACTIONS_BY_EMAIL_ERROR_MESSAGE' => $msgError],
|
||||
null,
|
||||
true,
|
||||
$caseInf['delIndex'],
|
||||
$emailSetup,
|
||||
0
|
||||
);
|
||||
return $result;
|
||||
}
|
||||
/*----------------------------------********---------------------------------*/
|
||||
}
|
||||
@@ -54,13 +54,71 @@ trait SuggestTrait
|
||||
$where = $isWhere ? "WHERE " . $col . "='" . $dv . "'" : $where . " AND " . $col . "='" . $dv . "'";
|
||||
}
|
||||
}
|
||||
if (isset($json->queryField) && isset($dt[0]["base_expr"])) {
|
||||
$col = isset($dt[1]["base_expr"]) ? $dt[1]["base_expr"] : $dt[0]["base_expr"];
|
||||
$qf = str_replace("'", "''", $json->queryFilter);
|
||||
$where = $isWhere ? "WHERE " . $col . " LIKE '%" . $qf . "%'" : $where . " AND " . $col . " LIKE '%" . $qf . "%'";
|
||||
if (isset($json->querySearch) && is_array($json->querySearch) && !empty($json->querySearch)) {
|
||||
$dataSearch = $json->querySearch;
|
||||
$sqlWildcard = "";
|
||||
//We will to search term in the query
|
||||
if (isset($dataSearch['term'])) {
|
||||
$value = isset($dataSearch['term']['value']) ? $dataSearch['term']['value'] : '';
|
||||
$label = isset($dataSearch['term']['text']) ? $dataSearch['term']['text'] : '';
|
||||
$sqlWildcard = "%";
|
||||
}
|
||||
//The match has priority
|
||||
//We will to search match in the query
|
||||
if (isset($dataSearch['match'])) {
|
||||
$value = isset($dataSearch['match']['value']) ? $dataSearch['match']['value'] : '';
|
||||
$label = isset($dataSearch['match']['text']) ? $dataSearch['match']['text'] : '';
|
||||
$sqlWildcard = "";
|
||||
}
|
||||
if (!empty($value) && !empty($label)){
|
||||
//We need to search in the firstColumn and secondColumn
|
||||
//Ex: SELECT COL1, COL2 FROM TABLE WHERE COL1 LIKE 'querySearch' OR COL2 LIKE 'querySearch'
|
||||
//Ex: SELECT COL1, COL2 FROM TABLE WHERE COL1 LIKE '%querySearch%' OR COL2 LIKE '%querySearch%'
|
||||
$col1 = $dt[0]["base_expr"];
|
||||
$col2 = isset($dt[1]["base_expr"]) ? $dt[1]["base_expr"] : $dt[0]["base_expr"];
|
||||
$qfValue = str_replace("'", "''", $value);
|
||||
$qfLabel = str_replace("'", "''", $label);
|
||||
$search = $col1 . " LIKE '" . $sqlWildcard . $qfValue . $sqlWildcard . "' OR " . $col2 . " LIKE '" . $sqlWildcard . $qfLabel . $sqlWildcard . "'";
|
||||
$where = $isWhere ? "WHERE " . $search : $where . " AND (" . $search . ")";
|
||||
} else {
|
||||
$valueOrLabel = '';
|
||||
$column = $dt[0]["base_expr"];
|
||||
if (!empty($value)) {
|
||||
//We need to search in the firstColumn
|
||||
//Ex: SELECT COL1, COL2 FROM TABLE WHERE COL1 LIKE 'querySearch'
|
||||
//Ex: SELECT COL1, COL2 FROM TABLE WHERE COL1 LIKE '%querySearch%'
|
||||
$valueOrLabel = $value;
|
||||
}
|
||||
if (!empty($label)) {
|
||||
//We need to search in the secondColumn
|
||||
//Ex: SELECT COL1, COL2 FROM TABLE WHERE COL2 LIKE 'querySearch'
|
||||
//Ex: SELECT COL1, COL2 FROM TABLE WHERE COL2 LIKE '%querySearch%'
|
||||
$column = isset($dt[1]["base_expr"]) ? $dt[1]["base_expr"] : $column;
|
||||
$valueOrLabel = $label;
|
||||
}
|
||||
$where = $this->buildWhere(
|
||||
$column,
|
||||
$valueOrLabel,
|
||||
$sqlWildcard,
|
||||
$isWhere,
|
||||
$where
|
||||
);
|
||||
}
|
||||
} else {
|
||||
//If the property querySearch does not exist we need to search in the secondColumn
|
||||
//Ex: SELECT COL1, COL2 FROM TABLE WHERE COL2 LIKE '%queryFilter%'
|
||||
if (isset($json->queryField) && isset($dt[0]["base_expr"])) {
|
||||
$where = $this->buildWhere(
|
||||
isset($dt[1]["base_expr"]) ? $dt[1]["base_expr"] : $dt[0]["base_expr"],
|
||||
$json->queryFilter,
|
||||
"%",
|
||||
$isWhere,
|
||||
$where
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($optionsLimit > 0) {
|
||||
if ($optionsLimit >= 0) {
|
||||
$this->addSuggestLimit($json, $select, $limit, $where);
|
||||
} else {
|
||||
$this->addSuggestWhere($json, $parsed, $select, $where, $having);
|
||||
@@ -69,6 +127,26 @@ trait SuggestTrait
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will be define the WHERE clause
|
||||
*
|
||||
* @param string $col, name of column
|
||||
* @param string $value, value to search in the column
|
||||
* @param string $sqlWildcard, if we to search term or correct match
|
||||
* @param boolean $isWhere, if the we need to concat other condition
|
||||
* @param string $where, initial where to add the concat
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
private function buildWhere($col, $value, $sqlWildcard = "", $isWhere = false, $where = "")
|
||||
{
|
||||
$qf = str_replace("'", "''", $value);
|
||||
$searchValue = $col . " LIKE '" . $sqlWildcard . $qf . $sqlWildcard;
|
||||
$where = ($isWhere) ? "WHERE " . $searchValue . "'" : $where . " AND " . $searchValue . "'";
|
||||
return $where;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the limit sentence to the suggest query.
|
||||
*
|
||||
|
||||
@@ -14,9 +14,11 @@ class EmailServer
|
||||
{
|
||||
private $arrayFieldDefinition = array(
|
||||
"MESS_UID" => array("type" => "string", "required" => false, "empty" => false, "defaultValues" => array(), "fieldNameAux" => "emailServerUid"),
|
||||
"MESS_ENGINE" => array("type" => "string", "required" => true, "empty" => false, "defaultValues" => array("PHPMAILER", "MAIL"), "fieldNameAux" => "emailServerEngine"),
|
||||
"MESS_ENGINE" => array("type" => "string", "required" => true, "empty" => false, "defaultValues" => array("PHPMAILER", "MAIL", "IMAP"), "fieldNameAux" => "emailServerEngine"),
|
||||
"MESS_SERVER" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "emailServerServer"),
|
||||
"MESS_PORT" => array("type" => "int", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "emailServerPort"),
|
||||
"MESS_INCOMING_SERVER" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "emailServerIncomingServer"),
|
||||
"MESS_INCOMING_PORT" => array("type" => "int", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "emailServerIncomingPort"),
|
||||
"MESS_RAUTH" => array("type" => "int", "required" => false, "empty" => false, "defaultValues" => array(0, 1), "fieldNameAux" => "emailServerRauth"),
|
||||
"MESS_ACCOUNT" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "emailServerUserName"),
|
||||
"MESS_PASSWORD" => array("type" => "string", "required" => false, "empty" => true, "defaultValues" => array(), "fieldNameAux" => "emailServerPassword"),
|
||||
@@ -52,10 +54,10 @@ class EmailServer
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the default information from the context.
|
||||
*
|
||||
*
|
||||
* @global type $RBAC
|
||||
* @return void
|
||||
*/
|
||||
@@ -527,6 +529,7 @@ class EmailServer
|
||||
}
|
||||
break;
|
||||
case "PHPMAILER":
|
||||
case "IMAP":
|
||||
$numSteps = ($arrayData['MAIL_TO'] != '') ? count($arrayPhpMailerTestName) :
|
||||
count($arrayPhpMailerTestName) - 1;
|
||||
for ($step = 1; $step <= $numSteps; $step++) {
|
||||
@@ -831,6 +834,8 @@ class EmailServer
|
||||
'engine'=> $arrayData["MESS_ENGINE"],
|
||||
'server' => $arrayData["MESS_SERVER"],
|
||||
'port' => $arrayData["MESS_PORT"],
|
||||
'incomingServer' => $arrayData["MESS_INCOMING_SERVER"],
|
||||
'incomingPort' => $arrayData["MESS_INCOMING_PORT"],
|
||||
'requireAuthentication' => $arrayData["MESS_RAUTH"],
|
||||
'account' => $arrayData["MESS_ACCOUNT"],
|
||||
'senderEmail' => $arrayData["MESS_FROM_MAIL"],
|
||||
@@ -1002,6 +1007,8 @@ class EmailServer
|
||||
'engine' => $arrayData["MESS_ENGINE"],
|
||||
'server' => $arrayData["MESS_SERVER"],
|
||||
'port' => $arrayData["MESS_PORT"],
|
||||
'incomingServer' => $arrayData["MESS_INCOMING_SERVER"],
|
||||
'incomingPort' => $arrayData["MESS_INCOMING_PORT"],
|
||||
'requireAuthentication' => $arrayData["MESS_RAUTH"],
|
||||
'account' => $arrayData["MESS_ACCOUNT"],
|
||||
'senderEmail' => $arrayData["MESS_FROM_MAIL"],
|
||||
@@ -1088,6 +1095,8 @@ class EmailServer
|
||||
$criteria->addSelectColumn(\EmailServerPeer::MESS_ENGINE);
|
||||
$criteria->addSelectColumn(\EmailServerPeer::MESS_SERVER);
|
||||
$criteria->addSelectColumn(\EmailServerPeer::MESS_PORT);
|
||||
$criteria->addSelectColumn(\EmailServerPeer::MESS_INCOMING_SERVER);
|
||||
$criteria->addSelectColumn(\EmailServerPeer::MESS_INCOMING_PORT);
|
||||
$criteria->addSelectColumn(\EmailServerPeer::MESS_RAUTH);
|
||||
$criteria->addSelectColumn(\EmailServerPeer::MESS_ACCOUNT);
|
||||
$criteria->addSelectColumn(\EmailServerPeer::MESS_PASSWORD);
|
||||
@@ -1120,6 +1129,8 @@ class EmailServer
|
||||
$this->getFieldNameByFormatFieldName("MESS_ENGINE") => $record["MESS_ENGINE"],
|
||||
$this->getFieldNameByFormatFieldName("MESS_SERVER") => $record["MESS_SERVER"],
|
||||
$this->getFieldNameByFormatFieldName("MESS_PORT") => $record["MESS_PORT"],
|
||||
$this->getFieldNameByFormatFieldName("MESS_INCOMING_SERVER") => $record["MESS_INCOMING_SERVER"],
|
||||
$this->getFieldNameByFormatFieldName("MESS_INCOMING_PORT") => $record["MESS_INCOMING_PORT"],
|
||||
$this->getFieldNameByFormatFieldName("MESS_RAUTH") => $record["MESS_RAUTH"],
|
||||
$this->getFieldNameByFormatFieldName("MESS_ACCOUNT") => $record["MESS_ACCOUNT"],
|
||||
$this->getFieldNameByFormatFieldName("MESS_PASSWORD") => $record["MESS_PASSWORD"],
|
||||
@@ -1165,6 +1176,8 @@ class EmailServer
|
||||
$arrayData["MESS_ENGINE"] = $row["MESS_ENGINE"];
|
||||
$arrayData["MESS_SERVER"] = $row["MESS_SERVER"];
|
||||
$arrayData["MESS_PORT"] = (int)($row["MESS_PORT"]);
|
||||
$arrayData["MESS_INCOMING_SERVER"] = $row["MESS_INCOMING_SERVER"];
|
||||
$arrayData["MESS_INCOMING_PORT"] = (int)($row["MESS_INCOMING_PORT"]);
|
||||
$arrayData["MESS_RAUTH"] = (int)($row["MESS_RAUTH"]);
|
||||
$arrayData["MESS_ACCOUNT"] = $row["MESS_ACCOUNT"];
|
||||
$arrayData["MESS_PASSWORD"] = $row["MESS_PASSWORD"];
|
||||
@@ -1221,6 +1234,7 @@ class EmailServer
|
||||
$criteria->add(
|
||||
$criteria->getNewCriterion(\EmailServerPeer::MESS_ENGINE, "%" . $arrayFilterData["filter"] . "%", \Criteria::LIKE)->addOr(
|
||||
$criteria->getNewCriterion(\EmailServerPeer::MESS_SERVER, "%" . $arrayFilterData["filter"] . "%", \Criteria::LIKE))->addOr(
|
||||
$criteria->getNewCriterion(\EmailServerPeer::MESS_INCOMING_SERVER,"%" . $arrayFilterData["filter"] . "%", \Criteria::LIKE))->addOr(
|
||||
$criteria->getNewCriterion(\EmailServerPeer::MESS_ACCOUNT, "%" . $arrayFilterData["filter"] . "%", \Criteria::LIKE))->addOr(
|
||||
$criteria->getNewCriterion(\EmailServerPeer::MESS_FROM_NAME, "%" . $arrayFilterData["filter"] . "%", \Criteria::LIKE))->addOr(
|
||||
$criteria->getNewCriterion(\EmailServerPeer::SMTPSECURE, "%" . $arrayFilterData["filter"] . "%", \Criteria::LIKE))
|
||||
@@ -1245,7 +1259,7 @@ class EmailServer
|
||||
if (!is_null($sortField) && trim($sortField) != "") {
|
||||
$sortField = strtoupper($sortField);
|
||||
|
||||
if (in_array($sortField, array("MESS_ENGINE", "MESS_SERVER", "MESS_ACCOUNT", "MESS_FROM_NAME", "SMTPSECURE"))) {
|
||||
if (in_array($sortField, array("MESS_ENGINE", "MESS_SERVER", "MESS_INCOMING_SERVER", "MESS_ACCOUNT", "MESS_FROM_NAME", "SMTPSECURE"))) {
|
||||
$sortField = \EmailServerPeer::TABLE_NAME . "." . $sortField;
|
||||
} else {
|
||||
$sortField = \EmailServerPeer::MESS_ENGINE;
|
||||
@@ -1318,6 +1332,7 @@ class EmailServer
|
||||
$row = $rsCriteria->getRow();
|
||||
|
||||
$row["MESS_PORT"] = (int)($row["MESS_PORT"]);
|
||||
$row["MESS_INCOMING_PORT"] = (int)($row["MESS_INCOMING_PORT"]);
|
||||
$row["MESS_RAUTH"] = (int)($row["MESS_RAUTH"]);
|
||||
$row["MESS_TRY_SEND_INMEDIATLY"] = (int)($row["MESS_TRY_SEND_INMEDIATLY"]);
|
||||
$row["MESS_DEFAULT"] = (int)($row["MESS_DEFAULT"]);
|
||||
|
||||
@@ -8,6 +8,7 @@ use G;
|
||||
use PMmemcached;
|
||||
use ProcessPeer;
|
||||
use ResultSet;
|
||||
use UsersPropertiesPeer;
|
||||
|
||||
class Process
|
||||
{
|
||||
@@ -2160,4 +2161,21 @@ class Process
|
||||
|
||||
return $processes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set for the first time the user opened the dynaform editor.
|
||||
*
|
||||
* @param string $usrUid
|
||||
* @param string $seen
|
||||
*/
|
||||
public function setIfFirstTimeConsumed($usrUid, $seen)
|
||||
{
|
||||
if ($seen === '1') {
|
||||
$userProperties = UsersPropertiesPeer::retrieveByPk($usrUid);
|
||||
if ($userProperties) {
|
||||
$userProperties->setPmDynaformFirstTime('1');
|
||||
$userProperties->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -749,6 +749,8 @@ class Variable
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* @see ProcessMaker\BusinessModel\Variable->executeSql()
|
||||
* @see ProcessMaker\BusinessModel\Variable->executeSqlSuggest()
|
||||
*/
|
||||
public function executeSqlControl($proUid, array $params = [])
|
||||
{
|
||||
@@ -758,6 +760,7 @@ class Variable
|
||||
$dynUid = $params["dyn_uid"];
|
||||
$fieldId = $params["field_id"];
|
||||
$filter = isset($params["filter"]) ? $params["filter"] : "";
|
||||
$query = isset($params["query"]) ? $params["query"] : [];
|
||||
$start = isset($params["start"]) ? $params["start"] : 0;
|
||||
$limit = isset($params["limit"]) ? $params["limit"] : 10;
|
||||
$appUid = empty($params["app_uid"]) ? null : $params["app_uid"];
|
||||
@@ -767,6 +770,7 @@ class Variable
|
||||
unset($params["app_uid"]);
|
||||
unset($params["del_index"]);
|
||||
unset($params["filter"]);
|
||||
unset($params["query"]);
|
||||
unset($params["start"]);
|
||||
unset($params["limit"]);
|
||||
|
||||
@@ -797,6 +801,7 @@ class Variable
|
||||
$field->queryField = true;
|
||||
$field->queryInputData = $params;
|
||||
$field->queryFilter = $filter;
|
||||
$field->querySearch = $query;
|
||||
$field->queryStart = $start;
|
||||
$field->queryLimit = $limit;
|
||||
//Grids only access the global variables of 'ProcessMaker', other variables are removed.
|
||||
@@ -809,7 +814,12 @@ class Variable
|
||||
}
|
||||
|
||||
//Populate control data
|
||||
$pmDynaform->clearLastQueryError();
|
||||
$pmDynaform->jsonr($field);
|
||||
$error = $pmDynaform->getLastQueryError();
|
||||
if (!empty($error) && is_object($error)) {
|
||||
throw new Exception(G::LoadTranslation("ID_ERROR_IN_THE_QUERY"));
|
||||
}
|
||||
$result = [];
|
||||
if (isset($field->queryOutputData) && is_array($field->queryOutputData)) {
|
||||
foreach ($field->queryOutputData as $item) {
|
||||
|
||||
98
workflow/engine/src/ProcessMaker/Core/ProcessesManager.php
Normal file
98
workflow/engine/src/ProcessMaker/Core/ProcessesManager.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Core;
|
||||
|
||||
/**
|
||||
* Class to manage the processes that runs in the shell
|
||||
*/
|
||||
class ProcessesManager
|
||||
{
|
||||
// Class properties
|
||||
private $processes;
|
||||
private $sleepTime = 1;
|
||||
private $terminated = [];
|
||||
private $errors = [];
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param array $processes
|
||||
*/
|
||||
public function __construct(array $processes)
|
||||
{
|
||||
$this->processes = $processes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of terminated processes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTerminated()
|
||||
{
|
||||
return $this->terminated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of processes with errors
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sleep time after each statuses revision
|
||||
*
|
||||
* @param int $sleepTime
|
||||
*/
|
||||
public function setSleepTime($sleepTime)
|
||||
{
|
||||
$this->sleepTime = $sleepTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the processes
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// Start all processes
|
||||
foreach ($this->processes as $process) {
|
||||
$process->run();
|
||||
}
|
||||
|
||||
// Manage the processes
|
||||
$this->manage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage all started processes
|
||||
*/
|
||||
private function manage()
|
||||
{
|
||||
do {
|
||||
// Check all remaining processes
|
||||
foreach ($this->processes as $index => $process) {
|
||||
// If the process has finished, save the info and destroy it
|
||||
if ($process->getStatus() === RunProcess::TERMINATED || $process->getStatus() === RunProcess::ERROR) {
|
||||
$processInfo = ['command' => $process->getCommand(), 'rawAnswer' => $process->getRawAnswer()];
|
||||
if ($process->getStatus() === RunProcess::TERMINATED) {
|
||||
// Processes completed successfully
|
||||
$this->terminated[] = $processInfo;
|
||||
} else {
|
||||
// Processes completed with errors
|
||||
$this->errors[] = $processInfo;
|
||||
}
|
||||
|
||||
// Destroy the process
|
||||
unset($this->processes[$index]);
|
||||
}
|
||||
}
|
||||
|
||||
// Waiting...
|
||||
sleep($this->sleepTime);
|
||||
} while (!empty($this->processes));
|
||||
}
|
||||
}
|
||||
146
workflow/engine/src/ProcessMaker/Core/RunProcess.php
Normal file
146
workflow/engine/src/ProcessMaker/Core/RunProcess.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Core;
|
||||
|
||||
/**
|
||||
* This class run a command in shell and stores the pointer to him
|
||||
*/
|
||||
class RunProcess
|
||||
{
|
||||
// Class constants
|
||||
const TERMINATED = 'terminated';
|
||||
const RUNNING = 'running';
|
||||
const NOT_RUNNING = 'not_running';
|
||||
const ERROR = 'error';
|
||||
|
||||
// This constant can be overrides in the child class according to the command response, always should be have a value
|
||||
const EXPECTED_ANSWER = '1';
|
||||
|
||||
// Class properties
|
||||
private $resource;
|
||||
private $command;
|
||||
private $rawAnswer;
|
||||
private $status;
|
||||
private $exitCode;
|
||||
private $pipes;
|
||||
private $descriptors = [
|
||||
['pipe', 'r'],
|
||||
['pipe', 'w'],
|
||||
['pipe', 'w']
|
||||
];
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string $command
|
||||
*/
|
||||
public function __construct($command)
|
||||
{
|
||||
$this->command = $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class destructor, the resource created should be closed
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if (is_resource($this->resource)) {
|
||||
proc_close($this->resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the command
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw response
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRawAnswer()
|
||||
{
|
||||
return $this->rawAnswer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
// If already exist a status return this value
|
||||
if ($this->status !== null) {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
// If doesn't exists a resource the process is not running
|
||||
if (!is_resource($this->resource)) {
|
||||
return self::NOT_RUNNING;
|
||||
}
|
||||
|
||||
// If the process is running return this value
|
||||
if ($this->isRunning()) {
|
||||
return self::RUNNING;
|
||||
}
|
||||
|
||||
// If the process is not running, parse the response to determine the status
|
||||
$this->rawAnswer = stream_get_contents($this->pipes[1]);
|
||||
$this->status = $this->parseAnswer();
|
||||
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exit code
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getExitCode()
|
||||
{
|
||||
return $this->exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the command
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$this->resource = proc_open($this->command, $this->descriptors, $this->pipes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process is running?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isRunning()
|
||||
{
|
||||
// Get the process status
|
||||
$status = proc_get_status($this->resource);
|
||||
|
||||
// If process is not running get the exit code
|
||||
if ($status['running'] === false) {
|
||||
$this->exitCode = $status['exitcode'];
|
||||
}
|
||||
|
||||
return $status['running'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the raw response and compare with the expected answer in order to determine the status
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseAnswer()
|
||||
{
|
||||
return $this->rawAnswer === self::EXPECTED_ANSWER ? self::TERMINATED : self::ERROR;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ use Faker;
|
||||
use G;
|
||||
use GzipFile;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Foundation\Http\Kernel;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use InputFilter;
|
||||
use InstallerModule;
|
||||
@@ -242,39 +243,6 @@ class System
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Review the checksum.txt
|
||||
*
|
||||
* @return array $result
|
||||
*/
|
||||
public static function verifyChecksum()
|
||||
{
|
||||
if (!file_exists(PATH_TRUNK . "checksum.txt")) {
|
||||
return false;
|
||||
}
|
||||
$lines = explode("\n", file_get_contents(PATH_TRUNK . "checksum.txt"));
|
||||
$result = array("diff" => array(), "missing" => array()
|
||||
);
|
||||
foreach ($lines as $line) {
|
||||
if (empty($line)) {
|
||||
continue;
|
||||
}
|
||||
list ($checksum, $empty, $filename) = explode(" ", $line);
|
||||
//Skip xmlform because these files always change.
|
||||
if (strpos($filename, "/xmlform/") !== false) {
|
||||
continue;
|
||||
}
|
||||
if (file_exists(realpath($filename))) {
|
||||
if (strcmp($checksum, G::encryptFileOld(realpath($filename))) != 0) {
|
||||
$result['diff'][] = $filename;
|
||||
}
|
||||
} else {
|
||||
$result['missing'][] = $filename;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks files to do updated to pm
|
||||
*
|
||||
@@ -1629,5 +1597,21 @@ class System
|
||||
{
|
||||
return !empty(self::getServerHostname()) ? self::getServerHostname() : 'processmaker.com';
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize laravel database configuration
|
||||
* @see workflow/engine/bin/tasks/cliWorkspaces.php->check_queries_incompatibilities()
|
||||
*/
|
||||
public static function initLaravel()
|
||||
{
|
||||
config(['database.connections.workflow.host' => DB_HOST]);
|
||||
config(['database.connections.workflow.database' => DB_NAME]);
|
||||
config(['database.connections.workflow.username' => DB_USER]);
|
||||
config(['database.connections.workflow.password' => DB_PASS]);
|
||||
|
||||
app()->useStoragePath(realpath(PATH_DATA));
|
||||
app()->make(Kernel::class)->bootstrap();
|
||||
restore_error_handler();
|
||||
}
|
||||
}
|
||||
// end System class
|
||||
|
||||
@@ -66,4 +66,16 @@ class Dynaform extends Model
|
||||
->where('DYNAFORM.DYN_UID', '!=', $dynUid)
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to filter an specific process
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param string $columns
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeProcess($query, string $proUID)
|
||||
{
|
||||
return $query->where('PRO_UID', $proUID);
|
||||
}
|
||||
}
|
||||
|
||||
27
workflow/engine/src/ProcessMaker/Model/ProcessVariables.php
Normal file
27
workflow/engine/src/ProcessMaker/Model/ProcessVariables.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Model;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ProcessVariables extends Model
|
||||
{
|
||||
// Set our table name
|
||||
protected $table = 'PROCESS_VARIABLES';
|
||||
// No timestamps
|
||||
public $timestamps = false;
|
||||
//primary key
|
||||
protected $primaryKey = 'VAR_UID';
|
||||
|
||||
/**
|
||||
* Scope a query to filter an specific process
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param string $columns
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeProcess($query, string $proUID)
|
||||
{
|
||||
return $query->where('PRJ_UID', $proUID);
|
||||
}
|
||||
}
|
||||
27
workflow/engine/src/ProcessMaker/Model/Triggers.php
Normal file
27
workflow/engine/src/ProcessMaker/Model/Triggers.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Model;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Triggers extends Model
|
||||
{
|
||||
// Set our table name
|
||||
protected $table = 'TRIGGERS';
|
||||
// No timestamps
|
||||
public $timestamps = false;
|
||||
//primary key
|
||||
protected $primaryKey = 'TRI_UID';
|
||||
|
||||
/**
|
||||
* Scope a query to filter an specific process
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param string $columns
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeProcess($query, string $proUID)
|
||||
{
|
||||
return $query->where('PRO_UID', $proUID);
|
||||
}
|
||||
}
|
||||
@@ -154,6 +154,13 @@ class ActionsByEmail extends Api
|
||||
$arrayData = $filesManager->addProcessFilesManager($proId, $userUid, $data);
|
||||
@copy(PATH_TPL . 'actionsByEmail' . PATH_SEP . 'actionsByEmail.html', $path . 'actionsByEmail.html');
|
||||
}
|
||||
/*----------------------------------********---------------------------------*/
|
||||
if (!file_exists($path . 'actionsByEmailErrorReply.html')) {
|
||||
$data = array('prf_content' => '', 'prf_filename' => 'actionsByEmailErrorReply.html', 'prf_path' => 'templates');
|
||||
$arrayData = $filesManager->addProcessFilesManager($proId, $userUid, $data);
|
||||
@copy(PATH_TPL . 'actionsByEmail' . PATH_SEP . 'actionsByEmailErrorReply.html', $path . 'actionsByEmailErrorReply.html');
|
||||
}
|
||||
/*----------------------------------********---------------------------------*/
|
||||
}
|
||||
|
||||
$directory = dir($path);
|
||||
|
||||
@@ -366,8 +366,9 @@ class Project extends Api
|
||||
*
|
||||
* @url GET /:prj_uid/dynaforms
|
||||
* @param string $prj_uid {@min 32}{@max 32}
|
||||
* @param string $seen
|
||||
*/
|
||||
public function doGetDynaForms($prj_uid)
|
||||
public function doGetDynaForms($prj_uid, $seen = '0')
|
||||
{
|
||||
try {
|
||||
$process = new \ProcessMaker\BusinessModel\Process();
|
||||
@@ -375,7 +376,7 @@ class Project extends Api
|
||||
$process->setArrayFieldNameForException(array("processUid" => "prj_uid"));
|
||||
|
||||
$response = $process->getDynaForms($prj_uid);
|
||||
|
||||
$process->setIfFirstTimeConsumed($this->getUserId(), $seen);
|
||||
return DateTime::convertUtcToIso8601($response, $this->arrayFieldIso8601);
|
||||
} catch (Exception $e) {
|
||||
throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()));
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Upgrade;
|
||||
|
||||
use ProcessMaker\Core\RunProcess;
|
||||
|
||||
/**
|
||||
* Extended class to manage the processes that executes a queries in the upgrade process
|
||||
*/
|
||||
class RunProcessUpgradeQuery extends RunProcess
|
||||
{
|
||||
// Class constants
|
||||
const SUCCESS = 'success';
|
||||
const CMD = PHP_BINARY . ' processmaker upgrade-query %s %s %s';
|
||||
const RBAC = '1';
|
||||
const NO_RBAC = '0';
|
||||
|
||||
// Class properties
|
||||
private $workspace;
|
||||
private $sql;
|
||||
private $isRbac;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string $workspace
|
||||
* @param string $sql
|
||||
* @param bool $isRbac
|
||||
*/
|
||||
public function __construct($workspace, $sql, $isRbac = false)
|
||||
{
|
||||
// Set properties values
|
||||
$this->workspace = $workspace;
|
||||
$this->sql = $sql;
|
||||
$this->isRbac = $isRbac;
|
||||
|
||||
// Build the command and send to the parent class
|
||||
parent::__construct($this->buildCommand());
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the parent method in order to compare the raw response with the SUCCESS value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parseAnswer()
|
||||
{
|
||||
return $this->getRawAnswer() === self::SUCCESS ? parent::TERMINATED : parent::ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the command to execute a query for the upgrade process
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function buildCommand()
|
||||
{
|
||||
return sprintf(self::CMD, $this->workspace, base64_encode($this->sql),
|
||||
($this->isRbac ? self::RBAC : self::NO_RBAC));
|
||||
}
|
||||
}
|
||||
32
workflow/engine/src/ProcessMaker/Util/WsMessageResponse.php
Normal file
32
workflow/engine/src/ProcessMaker/Util/WsMessageResponse.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Util;
|
||||
|
||||
use WsResponse;
|
||||
|
||||
class WsMessageResponse extends WsResponse
|
||||
{
|
||||
private $appMessUid = null;
|
||||
|
||||
/**
|
||||
* Get the appMessUid
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAppMessUid()
|
||||
{
|
||||
return $this->appMessUid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the appMessUid
|
||||
*
|
||||
* @param string $v
|
||||
* @return void
|
||||
*/
|
||||
public function setAppMessUid($v)
|
||||
{
|
||||
$this->appMessUid = $v;
|
||||
}
|
||||
}
|
||||
|
||||
110
workflow/engine/src/ProcessMaker/Validation/MySQL57.php
Normal file
110
workflow/engine/src/ProcessMaker/Validation/MySQL57.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Validation;
|
||||
|
||||
use ProcessMaker\Model\Dynaform;
|
||||
use ProcessMaker\Model\Process;
|
||||
use ProcessMaker\Model\ProcessVariables;
|
||||
use ProcessMaker\Model\Triggers;
|
||||
|
||||
class MySQL57
|
||||
{
|
||||
const REGEX = '/(?i)(select|\$).*?UNION.*?(select|\$).*?/ms';
|
||||
|
||||
/**
|
||||
* Checks the queries inside triggers that could have possible incompatibilities with MySQL 5.7
|
||||
*
|
||||
* @see workflow/engine/bin/tasks/cliWorkspaces.php->check_queries_incompatibilities()
|
||||
* @param array $processes
|
||||
* @return array
|
||||
*/
|
||||
public function checkIncompatibilityTriggers($processes)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($processes as $process) {
|
||||
$triggerQuery = Triggers::query()->select();
|
||||
//Call the scope method to filter by process
|
||||
$triggerQuery->process($process['PRO_UID']);
|
||||
$triggers = $triggerQuery->get()->values()->toArray();
|
||||
foreach ($triggers as $trigger) {
|
||||
$resultIncompatibility = $this->analyzeQuery($trigger['TRI_WEBBOT']);
|
||||
if ($resultIncompatibility) {
|
||||
$aux = array_merge($process, $trigger);
|
||||
array_push($result, $aux);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the queries inside dynaforms that could have possible incompatibilities with MySQL 5.7
|
||||
*
|
||||
* @see workflow/engine/bin/tasks/cliWorkspaces.php->check_queries_incompatibilities()
|
||||
* @param array $processes
|
||||
* @return array
|
||||
*/
|
||||
public function checkIncompatibilityDynaforms($processes)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($processes as $process) {
|
||||
$dynaformQuery = Dynaform::query()->select();
|
||||
//Call the scope method to filter by process
|
||||
$dynaformQuery->process($process['PRO_UID']);
|
||||
$dynaforms = $dynaformQuery->get()->values()->toArray();
|
||||
foreach ($dynaforms as $dynaform) {
|
||||
$resultIncompatibility = $this->analyzeQuery($dynaform['DYN_CONTENT']);
|
||||
if ($resultIncompatibility) {
|
||||
$aux = array_merge($process, $dynaform);
|
||||
array_push($result, $aux);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the queries inside variables that could have possible incompatibilities with MySQL 5.7
|
||||
*
|
||||
* @see workflow/engine/bin/tasks/cliWorkspaces.php->check_queries_incompatibilities()
|
||||
* @param array $processes
|
||||
* @return array
|
||||
*/
|
||||
public function checkIncompatibilityVariables($processes)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($processes as $process) {
|
||||
$variablesQuery = ProcessVariables::query()->select();
|
||||
//Call the scope method to filter by process
|
||||
$variablesQuery->process($process['PRO_UID']);
|
||||
$variables = $variablesQuery->get()->values()->toArray();
|
||||
foreach ($variables as $variable) {
|
||||
$resultIncompatibility = $this->analyzeQuery($variable['VAR_SQL']);
|
||||
if ($resultIncompatibility) {
|
||||
$aux = array_merge($process, $variable);
|
||||
array_push($result, $aux);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze the query using the regular expression
|
||||
*
|
||||
* @param string $query
|
||||
* @return bool
|
||||
*/
|
||||
public function analyzeQuery($query)
|
||||
{
|
||||
preg_match_all($this::REGEX, $query, $matches, PREG_SET_ORDER, 0);
|
||||
|
||||
return !empty($matches);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user