Fixed bugs for URL in notifications Set version to 3.6.6

Added new tags in notification templates
Fixed bugs on tag data
Added 1 dim assoc array management in notification templates
Fixed issue on the 2 dim arrays
Added missing notification template tags to get info on item hosting the case (Ticket, Change, Problem)
Added quote to be sure that SQL request will not throw an error
Added a test for the return code from routeCase() to prevent closing of current task if routing is not done
This commit is contained in:
tomolimo
2019-10-28 15:45:54 +01:00
parent eb50535338
commit 7a31eef8af
7 changed files with 190 additions and 88 deletions

View File

@@ -241,10 +241,11 @@ function plugin_item_update_processmaker_tasks($parm) {
$locCase->getFromDB($pmTask->fields['plugin_processmaker_cases_id']);
$srccase_guid = $locCase->fields['case_guid'];
$msg = ' $locCase: '.str_replace("\n", "\n ", print_r($locCase, true))."\n";
$msg .= ' $task: '.str_replace("\n", "\n ", print_r($parm, true))."\n";
$msg .= ' $pmTask: '.str_replace("\n", "\n ", print_r($pmTask, true))."\n";
$msg .= "\n";
//$msg = Toolbox::backtrace(false);
//$msg .= ' $locCase: '.str_replace("\n", "\n ", print_r($locCase, true))."\n";
//$msg .= ' $task: '.str_replace("\n", "\n ", print_r($parm, true))."\n";
//$msg .= ' $pmTask: '.str_replace("\n", "\n ", print_r($pmTask, true))."\n";
//$msg .= "\n";
foreach ($DB->request( 'glpi_plugin_processmaker_caselinks', "is_active = 1 AND sourcetask_guid='".$pmTaskCat->fields['pm_task_guid']."'") as $targetTask) {
@@ -289,17 +290,17 @@ function plugin_item_update_processmaker_tasks($parm) {
unset( $infoForTasks[ $casevar ] );
}
$msg .= " ***********\n";
$msg .= ' $targetTask: '.str_replace("\n", "\n ", print_r($targetTask, true))."\n";
//$msg .= " ***********\n";
//$msg .= ' $targetTask: '.str_replace("\n", "\n ", print_r($targetTask, true))."\n";
$targetTask['sourcecondition'] = str_replace( array_keys($infoForTasks), $infoForTasks, $targetTask['sourcecondition'] );
$eval = eval( "return (".$targetTask['sourcecondition']." ? 1 : 0);" );
$msg .= ' $infoForTasks: '.str_replace("\n", "\n ", print_r($infoForTasks, true))."\n";
$msg .= ' $targetTask[\'sourcecondition\']: '.str_replace("\n", "\n ", print_r($targetTask['sourcecondition'], true))."\n";
$msg .= ' $result: '."$eval\n";
$msg .= "\n";
//$msg .= ' $infoForTasks: '.str_replace("\n", "\n ", print_r($infoForTasks, true))."\n";
//$msg .= ' $targetTask[\'sourcecondition\']: '.str_replace("\n", "\n ", print_r($targetTask['sourcecondition'], true))."\n";
//$msg .= ' $result: '."$eval\n";
//$msg .= "\n";
if ($eval) {
// look at each linked ticket if a case is attached and then if a task like $val is TO_DO
@@ -429,8 +430,8 @@ function plugin_item_update_processmaker_tasks($parm) {
}
$msg .= "================\n";
Toolbox::logInFile("processmaker", $msg);
//$msg .= "================\n";
//Toolbox::logInFile("processmaker", $msg);
}
}

View File

@@ -289,6 +289,15 @@ class PluginProcessmakerCase extends CommonDBTM {
'update' => true] );
PluginProcessmakerNotificationTargetProcessmaker::restoreNotificationState($donotif);
// then update the delIndex and delThread
$DB->Update( 'glpi_plugin_processmaker_tasks', [
'del_index' => $newDelIndex,
'del_thread' => $newDelThread
], [
'id' => $pm_task_row['id']
]
);
// Notification management
// search if at least one active notification is existing for that pm task with that event 'task_update_'.$glpi_task->fields['taskcategories_id']
$res = PluginProcessmakerNotificationTargetTask::getNotifications('task_update', $glpi_task->fields['taskcategories_id'], $this->fields['entities_id']);
@@ -316,17 +325,6 @@ class PluginProcessmakerCase extends CommonDBTM {
'is_private' => isset($glpi_task->fields['is_private']) ? $glpi_task->fields['is_private'] : 0
]);
}
// then update the delIndex and delThread
//$query = "UPDATE glpi_plugin_processmaker_tasks SET del_index = $newDelIndex, del_thread = $newDelThread WHERE id={$row['id']}; ";
//$res = $DB->query($query);
$DB->Update( 'glpi_plugin_processmaker_tasks', [
'del_index' => $newDelIndex,
'del_thread' => $newDelThread
], [
'id' => $pm_task_row['id']
]
);
}
}

View File

@@ -58,11 +58,16 @@ class PluginProcessmakerNotificationTargetProcessmaker extends NotificationTarge
'case.id' => __('Case id', 'processmaker'),
'case.title' => __('Case title', 'processmaker'),
'case.description' => __('Case description', 'processmaker'),
'case.url' => __('URL'),
'case.url' => __('Case URL'),
'var.XXX' => __('Case variable \'XXX\'', 'processmaker'),
'array.YYY' => __('List of values in \'YYY\' array', 'processmaker'),
'array.numberofYYY' => __('Number of rows in \'YYY\' array', 'processmaker'),
'array.YYY.colname' => __('Value for colname in case array \'YYY\'', 'processamker')
'array.YYY.colname' => __('Value for colname in \'YYY\' array', 'processmaker'),
'1darray.ZZZ.key' => __('Value for key in \'ZZZ\' assoc array (1-dimension array)', 'processmaker'),
'item.type' => __('Item type', 'processmaker'),
'item.id' => __('Item id', 'processmaker'),
'item.url' => __('Item URL', 'processmaker'),
'item.title' => __('Item title', 'processmaker')
];
foreach ($tags as $tag => $label) {
@@ -76,6 +81,9 @@ class PluginProcessmakerNotificationTargetProcessmaker extends NotificationTarge
$elt['allowed_values'] = [__('YYY is to be replaced by any array variables', 'processmaker')];
$elt['foreach'] = true;
}
if ($tag == '1darray.ZZZ.key') {
$elt['allowed_values'] = [__('ZZZ is to be replaced by any assoc array variables (1-dimension array with key/value pairs)', 'processmaker')];
}
$this->addTagToList($elt);
}
@@ -87,7 +95,7 @@ class PluginProcessmakerNotificationTargetProcessmaker extends NotificationTarge
* Get all data needed for template processing
**/
public function addDataForTemplate($event, $options = []) {
global $PM_DB, $CFG_GLPI;
global $CFG_GLPI, $PM_DB;
$excluded = ['_VAR_CHANGED_',
'PIN',
@@ -107,11 +115,6 @@ class PluginProcessmakerNotificationTargetProcessmaker extends NotificationTarge
$process->getFromDB($options['case']->fields['plugin_processmaker_processes_id']);
$taskcat_id = $process->fields['taskcategories_id'];
// set defaults to all
foreach ($this->tags as $key => $val) {
$this->data["##$key##"] = "-";
}
// get case variable values
$res = $PM_DB->query("SELECT APP_DATA, APP_TITLE, APP_DESCRIPTION FROM APPLICATION WHERE APP_NUMBER = ".$options['case']->fields['id']);
if ($res && $PM_DB->numrows($res) == 1) {
@@ -125,10 +128,16 @@ class PluginProcessmakerNotificationTargetProcessmaker extends NotificationTarge
// add numberof for count of rows
$this->data["##array.numberof$key##"] = count($val);
// get the keys/vals of the sub-array
foreach ($val as $row) {
foreach ($row as $col_name => $col_val) {
$this->data["array.$key"][]["##array.$key.$col_name##"] = $col_val;
$this->data["##lang.array.$key.$col_name##"] = $col_name;
foreach ($val as $attribute => $row) {
if (is_array($row)) {
$index = isset($this->data["array.$key"]) ? count($this->data["array.$key"]) : 0;
foreach ($row as $col_name => $col_val) {
$this->data["array.$key"][$index]["##array.$key.$col_name##"] = $col_val;
$this->data["##lang.array.$key.$col_name##"] = $col_name;
}
} else {
$this->data["1darray.$key"]["##array.$key.$attribute##"] = $row;
$this->data["##lang.1darray.$key.$attribute##"] = $attribute;
}
}
} else {
@@ -145,18 +154,29 @@ class PluginProcessmakerNotificationTargetProcessmaker extends NotificationTarge
$this->data['##case.id##'] = $options['case']->fields['id'];
// case URL
$this->data['##case.url##'] = $CFG_GLPI["url_base"]."/index.php?redirect=".urlencode("/plugins/processmaker/front/case.form.php?id=".$options['case']->fields['id']);
$this->data['##case.url##'] = $this->formatURL($options['additionnaloption']['usertype'],
urlencode(urlencode($CFG_GLPI["url_base"] .
PluginProcessmakerCase::getFormURLWithID($options['case']->fields['id'], false))));
// parent task information: meta data on process
// will get parent of task which is the process task category
$tmp_taskcatinfo['name'] = DropdownTranslation::getTranslatedValue( $taskcat_id, 'TaskCategory', 'name');
$tmp_taskcatinfo['comment'] = DropdownTranslation::getTranslatedValue( $taskcat_id, 'TaskCategory', 'comment');
$tmp_taskcatinfo['name'] = DropdownTranslation::getTranslatedValue($taskcat_id, 'TaskCategory', 'name');
$tmp_taskcatinfo['comment'] = DropdownTranslation::getTranslatedValue($taskcat_id, 'TaskCategory', 'comment');
// process title
$this->data['##process.categoryid##'] = $taskcat_id;
$this->data['##process.category##'] = $tmp_taskcatinfo['name'];
$this->data['##process.categorycomment##'] = $tmp_taskcatinfo['comment'];
// add labels
// add information about item that hosts the case
$item = new $options['case']->fields['itemtype'];
$item->getFromDB($options['case']->fields['items_id']);
$this->data['##item.type##'] = $item->getTypeName(1);
$this->data['##item.id##'] = sprintf("%07d", $options['case']->fields['items_id']); // to have items_id with 7 digits with leading 0
$this->data['##item.url##'] = $this->formatURL($options['additionnaloption']['usertype'],
urlencode(urlencode($CFG_GLPI["url_base"] .
$item::getFormURLWithID($options['case']->fields['items_id'], false))));
$this->data['##item.title##'] = HTML::entities_deep($item->fields['name']);
// add labels to tags that are not set
$this->getTags();
foreach ($this->tag_descriptions[NotificationTarget::TAG_LANGUAGE] as $tag => $values) {
if (!isset($this->data[$tag])) {
@@ -165,4 +185,36 @@ class PluginProcessmakerNotificationTargetProcessmaker extends NotificationTarge
}
}
/**
* Get header to add to content
**/
function getContentHeader() {
if ($this->getMode() == \Notification_NotificationTemplate::MODE_MAIL
&& MailCollector::getNumberOfActiveMailCollectors()
) {
return NotificationTargetTicket::HEADERTAG.' '.__('To answer by email, write above this line').' '.
NotificationTargetTicket::HEADERTAG;
}
return '';
}
/**
* Get footer to add to content
**/
function getContentFooter() {
if ($this->getMode() == \Notification_NotificationTemplate::MODE_MAIL
&& MailCollector::getNumberOfActiveMailCollectors()
) {
return NotificationTargetTicket::FOOTERTAG.' '.__('To answer by email, write under this line').' '.
NotificationTargetTicket::FOOTERTAG;
}
return '';
}
}

View File

@@ -18,7 +18,8 @@ class PluginProcessmakerNotificationTargetTask extends PluginProcessmakerNotific
*/
private static function getDefaultEvents() {
return ['task_add' => ['event' => 'task_add_', 'label' => __('New task')],
'task_update' => ['event' => 'task_update_', 'label' => __('Update of a task')]
'task_update' => ['event' => 'task_update_', 'label' => __('Update of a task')],
'task_done' => ['event' => 'task_done_', 'label' => __('Task done')]
];
}
@@ -66,8 +67,9 @@ class PluginProcessmakerNotificationTargetTask extends PluginProcessmakerNotific
}
$temp->getFromDB($row['taskcat']);
$actions[$defaultEvents['task_add']['event'].$row['taskcat']] = $ptaskcats[$row['ptaskcat']]." > ".$temp->fields['name'].": " . $defaultEvents['task_add']['label'];
$actions[$defaultEvents['task_add']['event'].$row['taskcat']] = $ptaskcats[$row['ptaskcat']]." > ".$temp->fields['name'].": " . $defaultEvents['task_add']['label'];
$actions[$defaultEvents['task_update']['event'].$row['taskcat']] = $ptaskcats[$row['ptaskcat']]." > ".$temp->fields['name'].": " . $defaultEvents['task_update']['label'];
$actions[$defaultEvents['task_done']['event'].$row['taskcat']] = $ptaskcats[$row['ptaskcat']]." > ".$temp->fields['name'].": " . $defaultEvents['task_done']['label'];
}
return $actions;
@@ -92,7 +94,7 @@ class PluginProcessmakerNotificationTargetTask extends PluginProcessmakerNotific
$baseevent = $locevent[0].'_'.$locevent[1];
$taskcat_id = $locevent[2];
// task action: add or update
// task action: add, update or done
$this->data['##task.action##'] = $events[$baseevent]['label'];
// task category information: meta data on task
@@ -132,6 +134,15 @@ class PluginProcessmakerNotificationTargetTask extends PluginProcessmakerNotific
// task technician
$this->data['##task.user##'] = Html::clean($dbu->getUserName($taskobj->fields['users_id_tech']));
$tech = new User;
$tech->getFromDB($taskobj->fields['users_id_tech']);
$this->data['##task.user.login##'] = $tech->fields['name'];
if (isset($options['old_users_id_tech'])) {
$oldtech = new User;
$oldtech->getFromDB($options['old_users_id_tech']);
$this->data['##task.former.user##'] = Html::clean($dbu->getUserName($options['old_users_id_tech']));
$this->data['##task.former.user.login##'] = $oldtech->fields['name'];
}
// task group technician
$this->data['##task.group##'] = Html::clean(Toolbox::clean_cross_side_scripting_deep(Dropdown::getDropdownName("glpi_groups", $taskobj->fields['groups_id_tech'])), true, 2, false);
@@ -146,7 +157,7 @@ class PluginProcessmakerNotificationTargetTask extends PluginProcessmakerNotific
// task duration
$this->data['##task.time##'] = Html::timestampToString($taskobj->fields['actiontime'], false);
// add labels
// add labels to tags that are not set
$this->getTags();
foreach ($this->tag_descriptions[NotificationTarget::TAG_LANGUAGE] as $tag => $values) {
if (!isset($this->data[$tag])) {
@@ -173,6 +184,9 @@ class PluginProcessmakerNotificationTargetTask extends PluginProcessmakerNotific
'task.categorycomment' => __('Category comment'),
'task.time' => __('Total duration'),
'task.user' => __('User assigned to task'),
'task.user.login' => __('User login assigned to task'),
'task.former.user' => __('Former user assigned to task'),
'task.former.user.login' => __('Former user login assigned to task'),
'task.group' => __('Group assigned to task'),
'task.begin' => __('Start date'),
'task.end' => __('End date'),

View File

@@ -385,9 +385,9 @@ class PluginProcessmakerProcessmaker extends CommonDBTM {
* routes a case (i.e., moves the case to the next task in the process according to its routing rules).
* Embedded routeCase() PM web service call (definition: http://wiki.processmaker.com/index.php/2.0/ProcessMaker_WSDL_Web_Services#routeCase.28.29)
* A session must be open before with login()
* @param $case_guid The case ID, which can be obtained with the caseList() function
* @param $delIndex The delegation index, which is a positive integer to identify the current task of the case. If empty then use current delIndex.
* @return a routeCaseResponse object, or false exception occured. routing is normalized to be always an array of routeListStruct
* @param $case_guid string The case GUID, which can be obtained with the caseList() function
* @param $delIndex integer The delegation index, which is a positive integer to identify the current task of the case. If empty then use current delIndex.
* @return stdClass|boolean routeCaseResponse object or false when exception occured. routing is normalized to be always an array of routeListStruct
*/
function routeCase($case_guid, $delIndex) {
try {
@@ -1854,38 +1854,38 @@ class PluginProcessmakerProcessmaker extends CommonDBTM {
//$query = "INSERT INTO glpi_plugin_processmaker_tasks (items_id, itemtype, plugin_processmaker_cases_id, plugin_processmaker_taskcategories_id, del_index, del_thread)
// VALUES ({$glpi_task->getId()}, '{$glpi_task->getType()}', $cases_id, {$pmtaskcat->fields['id']}, $delIndex, $delThread);";
//$DB->query( $query );
//}
// send notification if needed for new task as now we have the PluginProcessmakerTask in the DB
$donotif = PluginProcessmakerNotificationTargetProcessmaker::saveNotificationState($options['notif']);
// Notification management
$item = new $itemtype;
$item->getFromDB($items_id);
// search if at least one active notification is existing for that pm task with that event 'task_update_'.$glpi_task->fields['taskcategories_id']
$res = PluginProcessmakerNotificationTargetTask::getNotifications('task_add', $glpi_task->fields['taskcategories_id'], $item->fields['entities_id']);
if ($res['notifications'] && count($res['notifications']) > 0) {
$pm_task = new PluginProcessmakerTask($glpi_task->getType());
$pm_task->getFromDB($glpi_task->getId());
NotificationEvent::raiseEvent($res['event'],
$pm_task,
['plugin_processmaker_cases_id' => $cases_id,
'itemtype' => $glpi_task->getType(),
'task_id' => $glpi_task->getID(),
'is_private' => isset($glpi_task->fields['is_private']) ? $glpi_task->fields['is_private'] : 0,
'entities_id' => $item->fields['entities_id']
]);
} else {
NotificationEvent::raiseEvent('add_task',
$item,
['plugin_processmaker_cases_id' => $cases_id,
'itemtype' => $itemtype,
'task_id' => $glpi_task->getID(),
'is_private' => isset($glpi_task->fields['is_private']) ? $glpi_task->fields['is_private'] : 0
]);
}
PluginProcessmakerNotificationTargetProcessmaker::restoreNotificationState($donotif);
}
// send notification if needed for new task as now we have the PluginProcessmakerTask in the DB
$donotif = PluginProcessmakerNotificationTargetProcessmaker::saveNotificationState($options['notif']);
// Notification management
$item = new $itemtype;
$item->getFromDB($items_id);
// search if at least one active notification is existing for that pm task with that event 'task_update_'.$glpi_task->fields['taskcategories_id']
$res = PluginProcessmakerNotificationTargetTask::getNotifications('task_add', $glpi_task->fields['taskcategories_id'], $item->fields['entities_id']);
if ($res['notifications'] && count($res['notifications']) > 0) {
$pm_task = new PluginProcessmakerTask($glpi_task->getType());
$pm_task->getFromDB($glpi_task->getId());
NotificationEvent::raiseEvent($res['event'],
$pm_task,
['plugin_processmaker_cases_id' => $cases_id,
'itemtype' => $glpi_task->getType(),
'task_id' => $glpi_task->getID(),
'is_private' => isset($glpi_task->fields['is_private']) ? $glpi_task->fields['is_private'] : 0,
'entities_id' => $item->fields['entities_id']
]);
} else {
NotificationEvent::raiseEvent('add_task',
$item,
['plugin_processmaker_cases_id' => $cases_id,
'itemtype' => $itemtype,
'task_id' => $glpi_task->getID(),
'is_private' => isset($glpi_task->fields['is_private']) ? $glpi_task->fields['is_private'] : 0
]);
}
PluginProcessmakerNotificationTargetProcessmaker::restoreNotificationState($donotif);
}
@@ -2098,7 +2098,6 @@ class PluginProcessmakerProcessmaker extends CommonDBTM {
$hostItem->getFromDB( $glpi_task->fields[ $itemFKField ] );
// change current glpi_currenttime to be sure that date_mode for solved task will not be identical than date_mode of the newly started task
//$end_date = new DateTime( $_SESSION["glpi_currenttime"] );
$saved_date_time = $_SESSION["glpi_currenttime"];
$_SESSION["glpi_currenttime"] = (new DateTime($saved_date_time))->sub(new DateInterval("PT1S"))->format("Y-m-d H:i:s");
@@ -2132,13 +2131,42 @@ class PluginProcessmakerProcessmaker extends CommonDBTM {
//'groups_id_tech' => 0,
'content' => $DB->escape($glpi_task->fields[ 'content' ].$options['txtToAppend'])
];
$donotif = PluginProcessmakerNotificationTargetProcessmaker::saveNotificationState($options['notif']);
$donotif = PluginProcessmakerNotificationTargetProcessmaker::saveNotificationState(false); // do not send notification yet
$glpi_task->update($params);
PluginProcessmakerNotificationTargetProcessmaker::restoreNotificationState($donotif);
// Close the task
//$DB->query("UPDATE glpi_plugin_processmaker_tasks SET del_thread_status = '".PluginProcessmakerTask::CLOSED."' WHERE id = {$row['id']}");
$DB->update('glpi_plugin_processmaker_tasks', ['del_thread_status' => PluginProcessmakerTask::CLOSED], ['id' => $row['id']]);
// send notification if needed for new task as now the PluginProcessmakerTask has been updated in the DB
$donotif = PluginProcessmakerNotificationTargetProcessmaker::saveNotificationState($options['notif']);
// Notification management
// search if at least one active notification is existing for that pm task with that event 'task_update_'.$glpi_task->fields['taskcategories_id']
$res = PluginProcessmakerNotificationTargetTask::getNotifications('task_done', $glpi_task->fields['taskcategories_id'], $hostItem->fields['entities_id']);
if ($res['notifications'] && count($res['notifications']) > 0) {
$pm_task = new PluginProcessmakerTask($glpi_task->getType());
$pm_task->getFromDB($glpi_task->getId());
NotificationEvent::raiseEvent($res['event'],
$pm_task,
['plugin_processmaker_cases_id' => $cases_id,
'itemtype' => $glpi_task->getType(),
'task_id' => $glpi_task->getID(),
'is_private' => isset($glpi_task->fields['is_private']) ? $glpi_task->fields['is_private'] : 0,
'entities_id' => $hostItem->fields['entities_id']
]);
} else {
NotificationEvent::raiseEvent('update_task',
$hostItem,
['plugin_processmaker_cases_id' => $cases_id,
'itemtype' => $hostItem->getType(),
'task_id' => $glpi_task->getID(),
'is_private' => isset($glpi_task->fields['is_private']) ? $glpi_task->fields['is_private'] : 0
]);
}
PluginProcessmakerNotificationTargetProcessmaker::restoreNotificationState($donotif);
// restore current glpi time
$_SESSION["glpi_currenttime"] = $saved_date_time;
@@ -2903,6 +2931,8 @@ class PluginProcessmakerProcessmaker extends CommonDBTM {
$item = new $itemtype;
$item->getFromDB($items_id);
//Toolbox::logInFile("processmaker_derivate", Toolbox::backtrace(false) . "derivateCase: myCase = " . print_r($myCase, true) . "\nrequest = " . print_r($request, true) . "\nusers_id = " . print_r($users_id, true) );
// save the dynaform variables into the current case
if (isset($request['UID']) && isset($request['APP_UID']) && isset($request['__DynaformName__'])) {
$resultSave = $this->saveForm( $request );
@@ -2910,6 +2940,16 @@ class PluginProcessmakerProcessmaker extends CommonDBTM {
// now derivate the case !!!
$pmRouteCaseResponse = $this->routeCase($myCase->fields['case_guid'], $request['DEL_INDEX']);
//Toolbox::logInFile("processmaker_derivate", "routeCase: pmRouteCaseResponse = " . print_r($pmRouteCaseResponse, true));
if ($pmRouteCaseResponse->status_code != 0) {
Session::addMessageAfterRedirect(sprintf(__('Unable to derivate case! Retry in a moment, or ask your administrator.<hr>Error code: %u<br/>Error message: %s<br/>', 'processmaker'),
$pmRouteCaseResponse->status_code,
$pmRouteCaseResponse->message),
true,
ERROR);
return;
}
$casevariables = ["GLPI_ITEM_TASK_CONTENT",
"GLPI_ITEM_APPEND_TO_TASK",
@@ -3038,9 +3078,6 @@ class PluginProcessmakerProcessmaker extends CommonDBTM {
}
$resultSave = $myCase->sendVariables($resetcasevariables);
// print_r( $pmRouteCaseResponse ) ;
// die() ;
// now manage tasks associated with item
// switch own task to 'done' and create a new one
$this->solveTask($myCase->getID(),

View File

@@ -29,15 +29,15 @@
<compatibility>9.1</compatibility>
</version>
<version>
<num>3.4.14</num>
<num>3.4.17</num>
<compatibility>9.2</compatibility>
</version>
<version>
<num>3.5.5</num>
<num>3.5.6</num>
<compatibility>9.3</compatibility>
</version>
<version>
<num>3.6.5</num>
<num>3.6.6</num>
<compatibility>9.4</compatibility>
</version>
</versions>

View File

@@ -1,6 +1,6 @@
<?php
define('PROCESSMAKER_VERSION', '3.6.5');
define('PROCESSMAKER_VERSION', '3.6.6');
// used for case cancellation
define("CANCEL", 256);