";
- Html::closeForm();
-
- return true;
-}
-
-
-/**
- * Summary of processMakerShowCase
- * @param mixed $ID
- * @param mixed $from_helpdesk
- */
-function processMakerShowCase($ID, $from_helpdesk) {
- global $CFG_GLPI, $PM_SOAP;
-
- $caseInfo = $PM_SOAP->getCaseInfo( $_REQUEST['case_guid'] );
- if ($caseInfo->status_code == 0) {
- // case is created
- // Must show it...
-
- $rand = rand();
-
- $PM_SOAP->echoDomain();
- echo "";
-
- $tkt = new Ticket;
-
- // as showFormHelpdesk uses $_POST, we must set it
- $_POST = $_REQUEST;
-
- // must be using bare text
- $save_rich_text = $CFG_GLPI["use_rich_text"];
- $CFG_GLPI["use_rich_text"] = false;
-
- // to get the HTML code for the helpdesk form
- $saved_ob_level = ob_get_level();
- ob_start();
-
- $tkt->showFormHelpdesk($ID);
-
- $buffer = ob_get_clean();
-
- $CFG_GLPI["use_rich_text"] = $save_rich_text;
-
- // 9.1 only: hack to fix an issue with the initEditorSystem which calls scriptStart without calling scriptEnd
- if (ob_get_level() > $saved_ob_level) {
- $buffer = ob_get_clean().$buffer;
- }
-
- //echo $buffer;
- //return;
-
- // to change this HTML code
- $dom = new DOMDocument();
-
- // will convert '&' to '&', '<' to '<' and '>' to '>'
- $buffer = htmlspecialchars($buffer, ENT_NOQUOTES);
- // will restore '<' to '<' and '>' to '>'
- // so that only the already escaped entites will get the double encoding
- // will also change end of bold into a local identifier
- $endOfBold = 'end_of_bold'.rand();
- $buffer = str_replace(['<', '>', ''], ['<', '>', $endOfBold], $buffer);
-
- // will convert any UTF-8 char that can't be expressed in ASCII into an HTML entity
- $buffer = mb_convert_encoding($buffer, 'HTML-ENTITIES');
-
- $dom->loadHTML($buffer, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
- $xpath = new DOMXPath($dom);
-
- // hide some fields
- $list = [ 'name', 'type', 'locations_id', 'itilcategories_id', 'items_id', 'add' ];
- $xpath_str = '//*[@name="'.implode( '"]/ancestor::tr[1] | //*[@name="', $list ).'"]/ancestor::tr[1]';
- $res = $xpath->query($xpath_str);
- foreach ($res as $elt) {
- $elt->setAttribute( 'style', 'display:none;');
- }
-
- // add an input for processguid in the form
- $res = $xpath->query('//form[@name="helpdeskform"]');
- $input = $res->item(0)->appendChild(new DOMElement('input'));
- $input->setAttribute('name', 'processmaker_process_guid');
- $input->setAttribute('type', 'hidden');
- $input->setAttribute('value', $caseInfo->processId);
-
- // add an input for processid in the form
- $input = $res->item(0)->appendChild(new DOMElement('input'));
- $input->setAttribute('name', 'processmaker_processes_id');
- $input->setAttribute('type', 'hidden');
- $input->setAttribute('value', $_REQUEST['processes_id']);
-
- // special case for content textarea which is in the same tr than the file upload
- $res = $xpath->query('//*[@name="content"]/ancestor::div[1] | //*[@name="content"]/ancestor::tr[1]/td[1]');
- foreach ($res as $elt) {
- $elt->setAttribute( 'style', 'display:none;');
- }
-
- $res = $xpath->query('//*[@name="content"]/ancestor::td[1]');
- foreach ($res as $elt) {
- // there should be only one td
- $elt->setAttribute( 'colspan', '2');
- }
-
- $res = $xpath->query('//*[@name="content"]/ancestor::tr[1]');
- //$res = $xpath->query('//*[@name="add"]/ancestor::tr[@class="tab_bg_1"]/preceding-sibling::tr[1]');
- $table = $xpath->query('//*[@name="add"]/ancestor::table[1]');
-
- $tr = $table->item(0)->insertBefore(new DOMElement('tr'), $res->item(0));
- //$tr = $table->item(0)->appendChild(new DOMElement('tr'));
-
- $td = $tr->appendChild(new DOMElement('td'));
- $td->setAttribute('colspan', '2');
-
- $iframe = $td->appendChild(new DOMElement('iframe'));
-
- $pmCaseUser = $caseInfo->currentUsers[0]; // by default
- $paramsURL = "DEL_INDEX={$pmCaseUser->delIndex}&action={$caseInfo->caseStatus}";
-
- $iframe->setAttribute('id', 'caseiframe' );
- $iframe->setAttribute('onload', "onLoadFrame( event, '{$caseInfo->caseId}', {$pmCaseUser->delIndex}, {$caseInfo->caseNumber}, '{$caseInfo->processName}') ;" );
- $iframe->setAttribute('width', '100%' );
- $iframe->setAttribute('style', 'border:none;' );
- $iframe->setAttribute('src', "{$PM_SOAP->serverURL}/cases/cases_Open?sid={$PM_SOAP->getPMSessionID()}&APP_UID={$caseInfo->caseId}&{$paramsURL}&rand=$rand&glpi_domain={$PM_SOAP->config->fields['domain']}" );
-
- // set the width and the title of the first table th
- $th = $xpath->query('//*[@name="add"]/ancestor::table[1]/*/th[1]');
- $th->item(0)->setAttribute('width', '30%');
- $th->item(0)->nodeValue = $caseInfo->processName;
-
- $buffer = $dom->saveHTML();
-
- // revert back
- $buffer = str_replace($endOfBold, '', $buffer);
-
- // will revert back any char converted above
- $buffer = mb_convert_encoding($buffer, 'UTF-8', 'HTML-ENTITIES');
- echo $buffer;
- }
-
-}
-
-
-function in_array_recursive($needle, $haystack) {
-
- $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack));
-
- foreach ($it AS $element) {
- if ($element == $needle) {
- return true;
- }
- }
-
- return false;
-}
-
-
-// Change profile system
-if (isset($_POST['newprofile'])) {
- if (isset($_SESSION["glpiprofiles"][$_POST['newprofile']])) {
- Session::changeProfile($_POST['newprofile']);
-
- if ($_SESSION["glpiactiveprofile"]["interface"] == "central") {
- Html::redirect($CFG_GLPI['root_doc']."/front/central.php");
- } else {
- Html::redirect($_SERVER['PHP_SELF']);
- }
-
- } else {
- Html::redirect(preg_replace("/entities_id=.*/", "", $_SERVER['HTTP_REFERER']));
- }
-}
-
-// Manage entity change
-if (isset($_GET["active_entity"])) {
- if (!isset($_GET["is_recursive"])) {
- $_GET["is_recursive"] = 0;
- }
- if (Session::changeActiveEntities($_GET["active_entity"], $_GET["is_recursive"])) {
- if ($_GET["active_entity"] == $_SESSION["glpiactive_entity"]) {
- Html::redirect(preg_replace("/entities_id.*/", "", $_SERVER['HTTP_REFERER']));
- }
- }
-}
-
-// Redirect management
-if (isset($_GET["redirect"])) {
- Toolbox::manageRedirect($_GET["redirect"]);
-}
-
-// redirect if no create ticket right
-if (!Session::haveRight('ticket', CREATE)
- && !Session::haveRight('reminder_public', READ)
- && !Session::haveRight("rssfeed_public", READ)) {
-
- if (Session::haveRight('followup', ITILFollowup::SEEPUBLIC) //TicketFollowup::SEEPUBLIC
- || Session::haveRight('task', TicketTask::SEEPUBLIC)
- || Session::haveRightsOr('ticketvalidation', [TicketValidation::VALIDATEREQUEST,
- TicketValidation::VALIDATEINCIDENT])) {
- Html::redirect($CFG_GLPI['root_doc']."/front/ticket.php");
-
- } else if (Session::haveRight('reservation', ReservationItem::RESERVEANITEM)) {
- Html::redirect($CFG_GLPI['root_doc']."/front/reservationitem.php");
-
- } else if (Session::haveRight('knowbase', KnowbaseItem::READFAQ)) {
- Html::redirect($CFG_GLPI['root_doc']."/front/helpdesk.faq.php");
- }
-}
-
-Session::checkHelpdeskAccess();
-
-Html::helpHeader(__('New ticket'), $_SERVER['PHP_SELF'], $_SESSION["glpiname"]);
-
-
-if (isset($_REQUEST['case_guid'])) {
- $res = $DB->request(
- 'glpi_plugin_processmaker_cases', [
- 'case_guid'=>$_REQUEST['case_guid']
- ]);
- $query = "SELECT * FROM glpi_plugin_processmaker_cases WHERE case_guid='".$_REQUEST['case_guid']."'";
- //$res = $DB->query( $query );
- //if ($DB->numrows( $res )) { // a ticket already exists for this case, then show new cases
- if ($res->numrows()) { // a ticket already exists for this case, then show new cases
- processMakerShowProcessList(Session::getLoginUserID(), 1);
- } else {
- // before showing the case, we must check the rights for this user to view it, if entity has been changed in the meanwhile
- // and must check if entity of the ticket is in the tree of authorized entities for current profile
- $processList = PluginProcessmakerProcessmaker::getProcessesWithCategoryAndProfile( $_REQUEST["itilcategories_id"], $_REQUEST["type"], $_SESSION['glpiactiveprofile']['id'], $_REQUEST['entities_id'] );
- if (in_array( $_REQUEST['entities_id'], $_SESSION['glpiactiveentities']) && in_array_recursive( $_REQUEST['processes_id'], $processList )) {
- processMakerShowCase(Session::getLoginUserID(), 1);
- } else {
- Html::redirect($CFG_GLPI["root_doc"]."/front/helpdesk.public.php?create_ticket=1");
- }
-
- }
-} else {
- processMakerShowProcessList(Session::getLoginUserID(), 1);
-}
-
-Html::helpFooter();
-
+";
+ echo "
";
+ Html::closeForm();
+
+ return true;
+}
+
+
+/**
+ * Summary of processMakerShowCase
+ * @param mixed $users_id
+ * @param mixed $from_helpdesk
+ */
+function processMakerShowCase($users_id, $from_helpdesk) {
+ global $CFG_GLPI, $PM_SOAP;
+
+ $caseInfo = $PM_SOAP->getCaseInfo( $_REQUEST['case_guid'] );
+ if ($caseInfo->status_code == 0) {
+ // case is created
+ // Must show it...
+
+ $rand = rand();
+
+ $PM_SOAP->echoDomain();
+ echo "";
+
+ $tkt = new Ticket;
+
+ // as showFormHelpdesk uses $_POST, we must set it
+ $_POST = $_REQUEST;
+
+ //// must be using bare text
+ //$save_rich_text = $CFG_GLPI["use_rich_text"];
+ //$CFG_GLPI["use_rich_text"] = false;
+
+ // to get the HTML code for the helpdesk form
+ $saved_ob_level = ob_get_level();
+ ob_start();
+
+ $tkt->showFormHelpdesk($users_id);
+
+ $buffer = ob_get_clean();
+
+ //$CFG_GLPI["use_rich_text"] = $save_rich_text;
+
+ // 9.1 only: hack to fix an issue with the initEditorSystem which calls scriptStart without calling scriptEnd
+ if (ob_get_level() > $saved_ob_level) {
+ $buffer = ob_get_clean().$buffer;
+ }
+
+ //echo $buffer;
+ //return;
+
+ // to change this HTML code
+ $dom = new DOMDocument();
+
+ // will convert '&' to '&', '<' to '<' and '>' to '>'
+ $buffer = htmlspecialchars($buffer, ENT_NOQUOTES);
+ // will restore '<' to '<' and '>' to '>'
+ // so that only the already escaped entites will get the double encoding
+ // will also change end of bold into a local identifier
+ $endOfBold = 'end_of_bold'.rand();
+ $endOfSpan = 'end_of_span'.rand();
+ $buffer = str_replace(['<', '>', '', ''], ['<', '>', $endOfBold, $endOfSpan], $buffer);
+
+ // will convert any UTF-8 char that can't be expressed in ASCII into an HTML entity
+ $buffer = mb_convert_encoding($buffer, 'HTML-ENTITIES');
+
+ $dom->loadHTML($buffer, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
+ $xpath = new DOMXPath($dom);
+
+ // hide some fields
+ $list = [ 'name', 'type', 'locations_id', 'itilcategories_id', 'items_id', 'add' ];
+ $xpath_str = '//*[@name="'.implode( '"]/ancestor::tr[1] | //*[@name="', $list ).'"]/ancestor::tr[1]';
+ $res = $xpath->query($xpath_str);
+ foreach ($res as $elt) {
+ $elt->setAttribute( 'style', 'display:none;');
+ }
+
+ // add an input for processguid in the form
+ $res = $xpath->query('//form[@name="helpdeskform"]');
+ $input = $res->item(0)->appendChild(new DOMElement('input'));
+ $input->setAttribute('name', 'processmaker_process_guid');
+ $input->setAttribute('type', 'hidden');
+ $input->setAttribute('value', $caseInfo->processId);
+
+ // add an input for processid in the form
+ $input = $res->item(0)->appendChild(new DOMElement('input'));
+ $input->setAttribute('name', 'processmaker_processes_id');
+ $input->setAttribute('type', 'hidden');
+ $input->setAttribute('value', $_REQUEST['processes_id']);
+
+ // special case for content textarea which is in the same tr than the file upload
+ $res = $xpath->query('//*[@name="content"]/ancestor::div[1] | //*[@name="content"]/ancestor::tr[1]/td[1]');
+ foreach ($res as $elt) {
+ $elt->setAttribute( 'style', 'display:none;');
+ }
+
+ $res = $xpath->query('//*[@name="content"]/ancestor::td[1]');
+ foreach ($res as $elt) {
+ // there should be only one td
+ $elt->setAttribute( 'colspan', '2');
+ }
+
+ $res = $xpath->query('//*[@name="content"]/ancestor::tr[1]');
+ //$res = $xpath->query('//*[@name="add"]/ancestor::tr[@class="tab_bg_1"]/preceding-sibling::tr[1]');
+ $table = $xpath->query('//*[@name="add"]/ancestor::table[1]');
+
+ $tr = $table->item(0)->insertBefore(new DOMElement('tr'), $res->item(0));
+ //$tr = $table->item(0)->appendChild(new DOMElement('tr'));
+
+ $td = $tr->appendChild(new DOMElement('td'));
+ $td->setAttribute('colspan', '2');
+
+ $iframe = $td->appendChild(new DOMElement('iframe'));
+
+ $pmCaseUser = $caseInfo->currentUsers[0]; // by default
+ $paramsURL = "DEL_INDEX={$pmCaseUser->delIndex}&action={$caseInfo->caseStatus}";
+
+ $iframe->setAttribute('id', 'caseiframe' );
+ $iframe->setAttribute('onload', "onLoadFrame( event, '{$caseInfo->caseId}', {$pmCaseUser->delIndex}, {$caseInfo->caseNumber}, '{$caseInfo->processName}') ;" );
+ $iframe->setAttribute('width', '100%' );
+ $iframe->setAttribute('style', 'border:none;' );
+ $iframe->setAttribute('src', "{$PM_SOAP->serverURL}/cases/cases_Open?sid={$PM_SOAP->getPMSessionID()}&APP_UID={$caseInfo->caseId}&{$paramsURL}&rand=$rand&glpi_domain={$PM_SOAP->config->fields['domain']}" );
+
+ // set the width and the title of the first table th
+ $th = $xpath->query('//*[@name="add"]/ancestor::table[1]/*/th[1]');
+ $th->item(0)->setAttribute('width', '30%');
+ $th->item(0)->nodeValue = $caseInfo->processName;
+
+ $buffer = $dom->saveHTML();
+
+ // revert back and
+ $buffer = str_replace([$endOfSpan, $endOfBold], ['', ''], $buffer);
+
+ // will revert back any char converted above
+ $buffer = mb_convert_encoding($buffer, 'UTF-8', 'HTML-ENTITIES');
+ echo $buffer;
+ }
+
+}
+
+
+function in_array_recursive($needle, $haystack) {
+
+ $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack));
+
+ foreach ($it AS $element) {
+ if ($element == $needle) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+// Change profile system
+if (isset($_POST['newprofile'])) {
+ if (isset($_SESSION["glpiprofiles"][$_POST['newprofile']])) {
+ Session::changeProfile($_POST['newprofile']);
+
+ if ($_SESSION["glpiactiveprofile"]["interface"] == "central") {
+ Html::redirect($CFG_GLPI['root_doc']."/front/central.php");
+ } else {
+ Html::redirect($_SERVER['PHP_SELF']);
+ }
+
+ } else {
+ Html::redirect(preg_replace("/entities_id=.*/", "", $_SERVER['HTTP_REFERER']));
+ }
+}
+
+// Manage entity change
+if (isset($_GET["active_entity"])) {
+ if (!isset($_GET["is_recursive"])) {
+ $_GET["is_recursive"] = 0;
+ }
+ if (Session::changeActiveEntities($_GET["active_entity"], $_GET["is_recursive"])) {
+ if ($_GET["active_entity"] == $_SESSION["glpiactive_entity"]) {
+ Html::redirect(preg_replace("/entities_id.*/", "", $_SERVER['HTTP_REFERER']));
+ }
+ }
+}
+
+// Redirect management
+if (isset($_GET["redirect"])) {
+ Toolbox::manageRedirect($_GET["redirect"]);
+}
+
+// redirect if no create ticket right
+if (!Session::haveRight('ticket', CREATE)
+ && !Session::haveRight('reminder_public', READ)
+ && !Session::haveRight("rssfeed_public", READ)) {
+
+ if (Session::haveRight('followup', ITILFollowup::SEEPUBLIC) //TicketFollowup::SEEPUBLIC
+ || Session::haveRight('task', TicketTask::SEEPUBLIC)
+ || Session::haveRightsOr('ticketvalidation', [TicketValidation::VALIDATEREQUEST,
+ TicketValidation::VALIDATEINCIDENT])) {
+ Html::redirect($CFG_GLPI['root_doc']."/front/ticket.php");
+
+ } else if (Session::haveRight('reservation', ReservationItem::RESERVEANITEM)) {
+ Html::redirect($CFG_GLPI['root_doc']."/front/reservationitem.php");
+
+ } else if (Session::haveRight('knowbase', KnowbaseItem::READFAQ)) {
+ Html::redirect($CFG_GLPI['root_doc']."/front/helpdesk.faq.php");
+ }
+}
+
+Session::checkHelpdeskAccess();
+
+Html::helpHeader(__('New ticket'), $_SERVER['PHP_SELF'], $_SESSION["glpiname"]);
+
+
+if (isset($_REQUEST['case_guid'])) {
+ $res = $DB->request('glpi_plugin_processmaker_cases', ['case_guid' => $_REQUEST['case_guid']]);
+ //$query = "SELECT * FROM glpi_plugin_processmaker_cases WHERE case_guid='".$_REQUEST['case_guid']."'";
+ //$res = $DB->query( $query );
+ //if ($DB->numrows( $res )) { // a ticket already exists for this case, then show new cases
+ if ($res->numrows()) { // a ticket already exists for this case, then show new cases
+ processMakerShowProcessList(Session::getLoginUserID(), 1);
+ } else {
+ // before showing the case, we must check the rights for this user to view it, if entity has been changed in the meanwhile
+ // and must check if entity of the ticket is in the tree of authorized entities for current profile
+ $processList = PluginProcessmakerProcessmaker::getProcessesWithCategoryAndProfile( $_REQUEST["itilcategories_id"], $_REQUEST["type"], $_SESSION['glpiactiveprofile']['id'], $_REQUEST['entities_id'] );
+ if (in_array( $_REQUEST['entities_id'], $_SESSION['glpiactiveentities']) && in_array_recursive( $_REQUEST['processes_id'], $processList )) {
+ processMakerShowCase(Session::getLoginUserID(), 1);
+ } else {
+ Html::redirect($CFG_GLPI["root_doc"]."/front/helpdesk.public.php?create_ticket=1");
+ }
+
+ }
+} else {
+ processMakerShowProcessList(Session::getLoginUserID(), 1);
+}
+
+Html::helpFooter();
+
diff --git a/hook.php b/hook.php
index 459ccf8..4a1f2aa 100644
--- a/hook.php
+++ b/hook.php
@@ -1,474 +1,486 @@
- __('Synchronize Task List', 'processmaker')];
- }
- break;
- case 'PluginProcessmakerProcess_Profile' :
- if (plugin_processmaker_haveRight('config', UPDATE)) {
- return ['purge' => __('Delete permanently')];
- }
- break;
- //case 'PluginProcessmakerCase' :
- // if (plugin_processmaker_haveRight("case", DELETE)) {
- // return array('purge' => __('Delete permanently'));
- // }
- //break;
- }
- return [];
-}
-
-
-/**
- * Summary of plugin_processmaker_install
- * Creates tables and initializes tasks, "GLPI Requesters" group
- * and so on
- * @return true or die!
- */
-function plugin_processmaker_install() {
- global $DB;
- if (!$DB->tableExists("glpi_plugin_processmaker_cases")) {
- // new installation
- include_once(GLPI_ROOT."/plugins/processmaker/install/install.php");
- processmaker_install();
-
- } else {
- // upgrade installation
- include_once(GLPI_ROOT."/plugins/processmaker/install/update.php");
- processmaker_update();
- }
-
- // To be called for each task managed by the plugin
- // task in class
- CronTask::Register('PluginProcessmakerProcessmaker', 'pmusers', DAY_TIMESTAMP, [ 'state' => CronTask::STATE_DISABLE, 'mode' => CronTask::MODE_EXTERNAL]);
- CronTask::Register('PluginProcessmakerProcessmaker', 'pmorphancases', DAY_TIMESTAMP, ['param' => 10, 'state' => CronTask::STATE_DISABLE, 'mode' => CronTask::MODE_EXTERNAL]);
- CronTask::Register('PluginProcessmakerProcessmaker', 'pmtaskactions', MINUTE_TIMESTAMP, ['state' => CronTask::STATE_DISABLE, 'mode' => CronTask::MODE_EXTERNAL]);
-
- // required because autoload doesn't work for unactive plugin'
- include_once(GLPI_ROOT."/plugins/processmaker/inc/profile.class.php");
- PluginProcessmakerProfile::createAdminAccess($_SESSION['glpiactiveprofile']['id']);
-
- return true;
-}
-
-function plugin_processmaker_uninstall() {
-
- CronTask::Unregister('PluginProcessmakerProcessmaker');
-
- return true;
-}
-
-
-function plugin_processmaker_getAddSearchOptions($itemtype) {
-
- $sopt = [];
- // TODO add Change and Problem + other fields to the search
- if ($itemtype == 'Ticket') {
- $sopt[10001]['table'] = 'glpi_plugin_processmaker_cases';
- $sopt[10001]['field'] = 'case_status';
- //$sopt[1001]['linkfield'] = 'id';
- $sopt[10001]['massiveaction'] = false;
- $sopt[10001]['name'] = __('Case', 'processmaker').' - '.__('Status', 'processmaker');
- $sopt[10001]['datatype'] = 'text';
- $sopt[10001]['forcegroupby'] = true;
- //$sopt[10001]['searchtype'] = 'equals';
-
- //$sopt[1001]['itemlink_type'] = 'PluginProcessmakerTicketcase';
-
- //$sopt[1001]['table'] = 'glpi_plugin_processmaker_ticketcase';
- //$sopt[1001]['field'] = 'case_status';
- //$sopt[1001]['massiveaction'] = false;
- //$sopt[1001]['name'] = 'Case - Status';
- //$sopt[1001]['forcegroupby'] = true;
- //$sopt[1001]['datatype'] = 'itemlink';
- // $sopt[1001]['itemlink_type'] = 'PluginProcessmakerProcessmaker';
- //$sopt[1001]['joinparams'] = array('beforejoin'
- // => array('table' => 'glpi_plugin_processmaker_ticketcase',
- // 'linkfield' => 'ticket_id'));
-
- //$sopt[1001]['joinparams']['jointype'] = "itemtype_id";
- //$sopt[1001]['pfields_type'] = ;
- }
- return $sopt;
-}
-
-function plugin_processmaker_addLeftJoin($type, $ref_table, $new_table, $linkfield, &$already_link_tables) {
-
- switch ($type) {
-
- case 'Ticket':
- switch ($new_table) {
-
- case "glpi_plugin_processmaker_cases" :
- $out= " LEFT JOIN `glpi_plugin_processmaker_cases`
- ON (`$ref_table`.`id` = `glpi_plugin_processmaker_cases`.`items_id` AND `glpi_plugin_processmaker_cases`.`itemtype` like 'Ticket') ";
- return $out;
-
- }
-
- return "";
-
- }
-
- return "";
-}
-
-/**
- * Summary of plugin_pre_item_update_processmaker
- * @param CommonITILObject $parm is an object
- * @return void
- */
-function plugin_pre_item_update_processmaker(CommonITILObject $parm) {
- global $DB;//, $PM_SOAP;
-
- if (isset($_SESSION['glpiname'])) { // && $parm->getType() == 'Ticket') {
- $locVar = [ ];
- foreach ($parm->input as $key => $val) {
- switch ($key) {
- case 'global_validation' :
- $locVar[ 'GLPI_TICKET_GLOBAL_VALIDATION' ] = $val;
- $locVar[ 'GLPI_ITEM_GLOBAL_VALIDATION' ] = $val;
- break;
- case 'itilcategories_id' :
- $locVar[ 'GLPI_ITEM_ITIL_CATEGORY_ID' ] = $val;
- break;
- case 'date' :
- $locVar[ 'GLPI_ITEM_OPENING_DATE' ] = $val;
- break;
- case 'time_to_resolve' :
- $locVar[ 'GLPI_TICKET_DUE_DATE' ] = $val;
- $locVar[ 'GLPI_ITEM_DUE_DATE' ] = $val;
- break;
- case 'urgency' :
- $locVar[ 'GLPI_TICKET_URGENCY' ] = $val;
- $locVar[ 'GLPI_ITEM_URGENCY' ] = $val;
- break;
- case 'impact' :
- $locVar[ 'GLPI_ITEM_IMPACT' ] = $val;
- break;
- case 'priority' :
- $locVar[ 'GLPI_ITEM_PRIORITY' ] = $val;
- break;
- }
- }
-
- $itemId = $parm->getID();
- $itemType = $parm->getType();
-
- $locCase = new PluginProcessmakerCase;
- foreach (PluginProcessmakerCase::getIDsFromItem($itemType, $itemId ) as $cases_id) {
- $locCase->getFromDB($cases_id);
- $locCase->sendVariables($locVar);
-
- // if entities_id of item has been changed, then must update case
- if (isset($parm->input['entities_id']) && $parm->input['entities_id'] != $parm->fields['entities_id']) {
- $locCase->update(['id' => $cases_id, 'entities_id' => $parm->input['entities_id']]);
- }
- }
- }
-
-}
-
-/**
- * Summary of plugin_item_update_processmaker_satisfaction
- * inject satisfaction survey into case
- * @param mixed $parm is the object
- */
-function plugin_item_update_processmaker_satisfaction($parm) {
- global $PM_SOAP;
- if (Session::isCron()) { // Task cron log with user admin
- $PM_SOAP->login(true);
- }
- $cases = PluginProcessmakerCase::getIDsFromItem('Ticket', $parm->fields['tickets_id']);
- foreach ($cases as $cases_id) {
- $locCase = new PluginProcessmakerCase;
- if ($locCase->getFromDB($cases_id)) {
- // case is existing for this item
- $locCase->sendVariables( ['GLPI_SATISFACTION_QUALITY' => $parm->fields['satisfaction']] );
- }
- }
-}
-
-
-/**
- * Summary of plugin_item_update_processmaker_user
- * When a user login is changed, then must change it in the PM tables
- * @param User $param is the user being changed
- */
-function plugin_item_update_processmaker_user(User $param) {
- // Must test if user login has been changed
- // if yes, must change the login in the PM tables:
- // USERS and RBAC_USERS, othewise the link in the processmaker_users table will be invalid
- if (in_array('name', $param->updates)) {
- // check if user is in the processmaker_user table
- $pm_user = PluginProcessmakerUser::getPMUserId($param->getID());
- if ($pm_user) {
- // must update the user in PM tables
- global $PM_SOAP;
- if ($param->fields['is_active'] == 0 || $param->fields['is_deleted'] == 1) {
- $status = "INACTIVE";
- } else {
- $status = "ACTIVE";
- }
- $PM_SOAP->login(true);
- $pmResult = $PM_SOAP->updateUser( $pm_user, $param->fields['name'], $param->fields['firstname'], $param->fields['realname'], $status );
- }
- }
-}
-
-
-function plugin_processmaker_post_init() {
- global $PM_DB, $PM_SOAP;
- if (!isset($PM_DB)) {
- $PM_DB = new PluginProcessmakerDB;
- }
- if (!isset($PM_SOAP)) {
- $PM_SOAP = new PluginProcessmakerProcessmaker;
- // and default login is current running user if any
- if (Session::getLoginUserID()) {
- $PM_SOAP->login();
- }
- }
-}
-
-
-function plugin_processmaker_giveItem($itemtype, $ID, $data, $num) {
-
- return;
-}
-
-function plugin_processmaker_change_profile() {
- if ($_SESSION['glpiactiveprofile']['interface'] == "helpdesk") {
- // must add the rights for simplified interface
- $_SESSION['glpiactiveprofile']['plugin_processmaker_case'] = READ;
- }
-}
-
-/**
- * Summary of plugin_item_add_update_processmaker_tasks
- * @param mixed $parm
- */
-function plugin_item_update_processmaker_tasks($parm) {
- global $DB, $CFG_GLPI, $PM_SOAP;
-
- $pmTaskCat = new PluginProcessmakerTaskCategory;
- if ($pmTaskCat->getFromDBbyCategory( $parm->fields['taskcategories_id'] )
- && in_array( 'state', $parm->updates )
- && $parm->input['state'] == Planning::DONE
- && $parm->oldvalues['state'] == Planning::TODO) { // the task has just been set to DONE state
-
- //$itemtype = str_replace( 'Task', '', $parm->getType() );
-
- $pmTask = new PluginProcessmakerTask($parm->getType());
- $pmTask->getFromDB($parm->fields['id']);
-
- $locCase = new PluginProcessmakerCase;
- $locCase->getFromDB($pmTask->fields['plugin_processmaker_cases_id']);
- $srccase_guid = $locCase->fields['case_guid'];
-
- //$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) {
-
- // Must check the condition
- $casevariables = [];
-
- $matches = [];
- if (preg_match_all( "/@@(\w+)/u", $targetTask['sourcecondition'], $matches )) {
- $casevariables = $matches[1];
- }
-
- $targetTask['targetactions'] = []; // empty array by default
- foreach ($DB->request( 'glpi_plugin_processmaker_caselinkactions', 'plugin_processmaker_caselinks_id = '.$targetTask['id']) as $actionvalue) {
- $targetTask['targetactions'][$actionvalue['name']] = $actionvalue['value'];
- if (preg_match_all( "/@@(\w+)/u", $actionvalue['value'], $matches )) {
- $casevariables = array_merge( $casevariables, $matches[1] );
- }
- }
- $externalapplication = false; // by default
- if ($targetTask['is_externaldata'] && isset($targetTask['externalapplication'])) {
- // must read some values
- $externalapplication = json_decode( $targetTask['externalapplication'], true );
- // must be of the form
- // {"method":"POST","url":"urloftheservice","params":json_object}
- // Where method is the POST, GET, ... method
- // url is the URL to be called
- // params is a list of parameters to get from running case
- foreach ($externalapplication['params'] as $paramname => $variable) {
- if (preg_match_all( "/@@(\w+)/u", $variable, $matches )) {
- $casevariables = array_merge( $casevariables, $matches[1] );
- }
- }
- }
-
- // ask for those case variables
- //$PM_SOAP = new PluginProcessmakerProcessmaker();
- //$PM_SOAP->login( );
- // now tries to get the variables to check condition
- $infoForTasks = $locCase->getVariables($casevariables);
- foreach ($infoForTasks as $casevar => $varval) {
- $infoForTasks[ "@@$casevar" ] = "'$varval'";
- unset( $infoForTasks[ $casevar ] );
- }
-
- //$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";
-
- if ($eval) {
- // look at each linked ticket if a case is attached and then if a task like $val is TO_DO
- // then will try to routeCase for each tasks in $val
-
- $postdata = [];
- foreach ($targetTask['targetactions'] as $action => $actionvalue) {
- $postdata['form'][$action] = eval( "return ".str_replace( array_keys($infoForTasks), $infoForTasks, $actionvalue)." ;" );
- }
- $postdata['UID'] = $targetTask['targetdynaform_guid'];
- $postdata['__DynaformName__'] = $targetTask['targetprocess_guid']."_".$targetTask['targetdynaform_guid'];
- $postdata['__notValidateThisFields__'] = '[]';
- $postdata['DynaformRequiredFields'] = '[]';
- $postdata['form']['btnGLPISendRequest'] = 'submit';
-
- $externalapplicationparams = [];
- if ($externalapplication) {
- // must call curl
- foreach ($externalapplication['params'] as $paramname => $variable) {
- $externalapplicationparams[$paramname] = eval( "return ".str_replace( array_keys($infoForTasks), $infoForTasks, $variable)." ;" );
- }
- $externalapplicationparams['callback'] = $CFG_GLPI["url_base"]."/plugins/processmaker/ajax/asynchronousdatas.php";
- $ch = curl_init();
- $externalapplication['url'] = eval( "return '".str_replace( array_keys($infoForTasks), $infoForTasks, $externalapplication['url'])."' ;" ); // '???
- curl_setopt($ch, CURLOPT_URL, $externalapplication['url'] );
- if (isset($externalapplication['method']) && $externalapplication['method'] == 'POST') {
- curl_setopt($ch, CURLOPT_POST, 1);
- }
- }
-
- if ($targetTask['is_self']) {
- $PM_SOAP->login(true);
- $taskCase = $PM_SOAP->taskCase( $srccase_guid );
- foreach ($taskCase as $task) {
- // search for target task guid
- if ($task->guid == $targetTask['targettask_guid']) {
- break;
- }
- }
- $PM_SOAP->login();
-
- $postdata['APP_UID'] = $srccase_guid;
- $postdata['DEL_INDEX'] = $task->delegate;
-
- //need to get the 'ProcessMaker' user
- $pmconfig = $PM_SOAP->config; //PluginProcessmakerConfig::getInstance();
-
- $cronaction = new PluginProcessmakerCrontaskaction;
- $cronaction->add( [ 'plugin_processmaker_caselinks_id' => $targetTask['id'],
- 'plugin_processmaker_cases_id' => $locCase->getID(),
- //'itemtype' => $itemtype,
- //'items_id' => $parm->fields['tickets_id'],
- 'users_id' => $pmconfig->fields['users_id'],
- 'is_targettoclaim' => $targetTask['is_targettoclaim'],
- 'state' => ($targetTask['is_externaldata'] ? PluginProcessmakerCrontaskaction::WAITING_DATA : PluginProcessmakerCrontaskaction::DATA_READY),
- 'postdata' => json_encode( $postdata, JSON_HEX_APOS | JSON_HEX_QUOT),
- 'logs_out' => json_encode( $externalapplicationparams, JSON_HEX_APOS | JSON_HEX_QUOT)
- ],
- null,
- false);
-
- if ($externalapplication) {
- // must call external application in order to get the needed data asynchroneously
- // must be of the form
- // {"url":"urloftheservice","params":{"user":"@@USER_ID","system":"GPP","list":"@@ROLE_LIST"}}
- // url is the URL to be called
-
- $externalapplicationparams['id'] = $cronaction->getID();
-
- $externalapplicationparams = json_encode( $externalapplicationparams, JSON_HEX_APOS | JSON_HEX_QUOT);
-
- curl_setopt($ch, CURLOPT_POSTFIELDS, $externalapplicationparams);
- curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Content-Length: ' . strlen($externalapplicationparams), 'Expect:']);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
- curl_setopt($ch, CURLOPT_VERBOSE, 1);
-
- if (isset($externalapplication['ssl_verify'])) {
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $externalapplication['ssl_verify']);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $externalapplication['ssl_verify']);
- }
-
- if (isset($externalapplication['proxy'])) {
- curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1 ) ;
- curl_setopt($ch, CURLOPT_PROXY, $externalapplication['proxy']);
- }
-
- $response = curl_exec ($ch);
- if ($response === false) {
- //throw new Exception(curl_error($ch), curl_errno($ch));
- Toolbox::logDebug( curl_error($ch).":".curl_errno($ch) );
- }
-
- curl_close ($ch);
- }
- // }
- } else {
- // TODO to review this part of code as it is no longer usable like this !!!
- foreach (Ticket_Ticket::getLinkedTicketsTo( $parm->fields['tickets_id'] ) as $tlink) {
- if ($tlink['link'] == Ticket_Ticket::LINK_TO) {
- $query = "SELECT glpi_plugin_processmaker_cases.id, MAX(glpi_plugin_processmaker_tasks.del_index) AS del_index FROM glpi_tickettasks
- JOIN glpi_plugin_processmaker_taskcategories ON glpi_plugin_processmaker_taskcategories.taskcategories_id=glpi_tickettasks.taskcategories_id
- JOIN glpi_plugin_processmaker_cases ON glpi_plugin_processmaker_cases.processes_id=glpi_plugin_processmaker_taskcategories.processes_id
- RIGHT JOIN glpi_plugin_processmaker_tasks ON glpi_plugin_processmaker_tasks.items_id=glpi_tickettasks.id AND glpi_plugin_processmaker_tasks.case_id=glpi_plugin_processmaker_cases.id
- WHERE glpi_plugin_processmaker_taskcategories.pm_task_guid = '".$targetTask['targettask_guid']."' AND glpi_tickettasks.state = 1 AND glpi_tickettasks.tickets_id=".$tlink['tickets_id'];
- foreach ($DB->request($query) as $case) {
- // must be only one row
-
- $postdata['APP_UID'] = $case['id'];
- $postdata['DEL_INDEX'] = $case['del_index'];
-
- $cronaction = new PluginProcessmakerCrontaskaction;
- $cronaction->add( [ 'plugin_processmaker_caselinks_id' => $targetTask['id'],
- 'plugin_processmaker_cases_id' => $locCase->getID(),
- //'itemtype' => $itemtype,
- //'items_id' => $parm->fields['tickets_id'],
- 'users_id' => Session::getLoginUserID(),
- 'is_targettoclaim' => $targetTask['is_targettoclaim'],
- 'state' => ($targetTask['is_externaldata'] ? PluginProcessmakerCrontaskaction::WAITING_DATA : PluginProcessmakerCrontaskaction::DATA_READY),
- 'postdata' => json_encode( $postdata, JSON_HEX_APOS | JSON_HEX_QUOT),
- 'logs_out' => json_encode( $externalapplicationparams, JSON_HEX_APOS | JSON_HEX_QUOT)
- ],
- null,
- false);
- }
- }
- }
- }
-
- if ($targetTask['is_synchronous']) {
- // must call PluginProcessmakerProcessmaker::cronPMTaskActions()
- PluginProcessmakerProcessmaker::cronPMTaskActions();
- }
- }
-
- }
-
- //$msg .= "================\n";
- //Toolbox::logInFile("processmaker", $msg);
-
- }
-}
+ __('Synchronize Task List', 'processmaker')];
+ }
+ break;
+ case 'PluginProcessmakerProcess_Profile' :
+ if (plugin_processmaker_haveRight('config', UPDATE)) {
+ return ['purge' => __('Delete permanently')];
+ }
+ break;
+ //case 'PluginProcessmakerCase' :
+ // if (plugin_processmaker_haveRight("case", DELETE)) {
+ // return array('purge' => __('Delete permanently'));
+ // }
+ //break;
+ }
+ return [];
+}
+
+
+/**
+ * Summary of plugin_processmaker_install
+ * Creates tables and initializes tasks, "GLPI Requesters" group
+ * and so on
+ * @return true or die!
+ */
+function plugin_processmaker_install() {
+ global $DB;
+ if (!$DB->tableExists("glpi_plugin_processmaker_cases")) {
+ // new installation
+ include_once(GLPI_ROOT."/plugins/processmaker/install/install.php");
+ processmaker_install();
+
+ } else {
+ // upgrade installation
+ include_once(GLPI_ROOT."/plugins/processmaker/install/update.php");
+ processmaker_update();
+ }
+
+ // To be called for each task managed by the plugin
+ // task in class
+ CronTask::Register('PluginProcessmakerProcessmaker', 'pmusers', DAY_TIMESTAMP, [ 'state' => CronTask::STATE_DISABLE, 'mode' => CronTask::MODE_EXTERNAL]);
+ CronTask::Register('PluginProcessmakerProcessmaker', 'pmorphancases', DAY_TIMESTAMP, ['param' => 10, 'state' => CronTask::STATE_DISABLE, 'mode' => CronTask::MODE_EXTERNAL]);
+ CronTask::Register('PluginProcessmakerProcessmaker', 'pmtaskactions', MINUTE_TIMESTAMP, ['state' => CronTask::STATE_DISABLE, 'mode' => CronTask::MODE_EXTERNAL]);
+
+ // required because autoload doesn't work for unactive plugin'
+ include_once(GLPI_ROOT."/plugins/processmaker/inc/profile.class.php");
+ PluginProcessmakerProfile::createAdminAccess($_SESSION['glpiactiveprofile']['id']);
+
+ return true;
+}
+
+function plugin_processmaker_uninstall() {
+
+ CronTask::Unregister('PluginProcessmakerProcessmaker');
+
+ return true;
+}
+
+
+function plugin_processmaker_getAddSearchOptions($itemtype) {
+
+ $sopt = [];
+ // TODO add Change and Problem + other fields to the search
+ if ($itemtype == 'Ticket') {
+ $sopt[10001]['table'] = 'glpi_plugin_processmaker_cases';
+ $sopt[10001]['field'] = 'case_status';
+ //$sopt[1001]['linkfield'] = 'id';
+ $sopt[10001]['massiveaction'] = false;
+ $sopt[10001]['name'] = __('Case', 'processmaker').' - '.__('Status', 'processmaker');
+ $sopt[10001]['datatype'] = 'text';
+ $sopt[10001]['forcegroupby'] = true;
+ //$sopt[10001]['searchtype'] = 'equals';
+
+ //$sopt[1001]['itemlink_type'] = 'PluginProcessmakerTicketcase';
+
+ //$sopt[1001]['table'] = 'glpi_plugin_processmaker_ticketcase';
+ //$sopt[1001]['field'] = 'case_status';
+ //$sopt[1001]['massiveaction'] = false;
+ //$sopt[1001]['name'] = 'Case - Status';
+ //$sopt[1001]['forcegroupby'] = true;
+ //$sopt[1001]['datatype'] = 'itemlink';
+ // $sopt[1001]['itemlink_type'] = 'PluginProcessmakerProcessmaker';
+ //$sopt[1001]['joinparams'] = array('beforejoin'
+ // => array('table' => 'glpi_plugin_processmaker_ticketcase',
+ // 'linkfield' => 'ticket_id'));
+
+ //$sopt[1001]['joinparams']['jointype'] = "itemtype_id";
+ //$sopt[1001]['pfields_type'] = ;
+ }
+ return $sopt;
+}
+
+function plugin_processmaker_addLeftJoin($type, $ref_table, $new_table, $linkfield, &$already_link_tables) {
+
+ switch ($type) {
+
+ case 'Ticket':
+ switch ($new_table) {
+
+ case "glpi_plugin_processmaker_cases" :
+ $out= " LEFT JOIN `glpi_plugin_processmaker_cases`
+ ON (`$ref_table`.`id` = `glpi_plugin_processmaker_cases`.`items_id` AND `glpi_plugin_processmaker_cases`.`itemtype` like 'Ticket') ";
+ return $out;
+
+ }
+
+ return "";
+
+ }
+
+ return "";
+}
+
+/**
+ * Summary of plugin_pre_item_update_processmaker
+ * @param CommonITILObject $parm is an object
+ * @return void
+ */
+function plugin_pre_item_update_processmaker(CommonITILObject $parm) {
+ //global $DB;//, $PM_SOAP;
+
+ // look at previous status
+ if (isset($parm->input['status'])
+ && $parm->input['status'] == CommonITILObject::SOLVED
+ && !in_array($parm->fields['status'], [CommonITILObject::SOLVED, CommonITILObject::CLOSED])
+ && !PluginProcessmakerCase::canSolve(['item' => $parm])) {
+ $parm->input = []; // empty array... to prevent item update
+ Session::addMessageAfterRedirect(__('At least one \'Process case\' is running!
Solving is currently disabled!', 'processmaker'), false, ERROR);
+ return;
+ }
+
+
+ if (isset($_SESSION['glpiname'])) {
+ $locVar = [ ];
+ foreach ($parm->input as $key => $val) {
+ switch ($key) {
+ case 'global_validation' :
+ $locVar[ 'GLPI_TICKET_GLOBAL_VALIDATION' ] = $val;
+ $locVar[ 'GLPI_ITEM_GLOBAL_VALIDATION' ] = $val;
+ break;
+ case 'itilcategories_id' :
+ $locVar[ 'GLPI_ITEM_ITIL_CATEGORY_ID' ] = $val;
+ break;
+ case 'date' :
+ $locVar[ 'GLPI_ITEM_OPENING_DATE' ] = $val;
+ break;
+ case 'time_to_resolve' :
+ $locVar[ 'GLPI_TICKET_DUE_DATE' ] = $val;
+ $locVar[ 'GLPI_ITEM_DUE_DATE' ] = $val;
+ break;
+ case 'urgency' :
+ $locVar[ 'GLPI_TICKET_URGENCY' ] = $val;
+ $locVar[ 'GLPI_ITEM_URGENCY' ] = $val;
+ break;
+ case 'impact' :
+ $locVar[ 'GLPI_ITEM_IMPACT' ] = $val;
+ break;
+ case 'priority' :
+ $locVar[ 'GLPI_ITEM_PRIORITY' ] = $val;
+ break;
+ }
+ }
+
+ $itemId = $parm->getID();
+ $itemType = $parm->getType();
+
+ $locCase = new PluginProcessmakerCase;
+ foreach (PluginProcessmakerCase::getIDsFromItem($itemType, $itemId) as $cases_id) {
+ $locCase->getFromDB($cases_id);
+ $locCase->sendVariables($locVar);
+
+ // if entities_id of item has been changed, then must update case
+ if (isset($parm->input['entities_id']) && $parm->input['entities_id'] != $parm->fields['entities_id']) {
+ $locCase->update(['id' => $cases_id, 'entities_id' => $parm->input['entities_id']]);
+ }
+ }
+ }
+
+}
+
+/**
+ * Summary of plugin_item_update_processmaker_satisfaction
+ * inject satisfaction survey into case
+ * @param mixed $parm is the object
+ */
+function plugin_item_update_processmaker_satisfaction($parm) {
+ global $PM_SOAP;
+ if (Session::isCron()) { // Task cron log with user admin
+ $PM_SOAP->login(true);
+ }
+ $cases = PluginProcessmakerCase::getIDsFromItem('Ticket', $parm->fields['tickets_id']);
+ foreach ($cases as $cases_id) {
+ $locCase = new PluginProcessmakerCase;
+ if ($locCase->getFromDB($cases_id)) {
+ // case is existing for this item
+ $locCase->sendVariables( ['GLPI_SATISFACTION_QUALITY' => $parm->fields['satisfaction']] );
+ }
+ }
+}
+
+
+/**
+ * Summary of plugin_item_update_processmaker_user
+ * When a user login is changed, then must change it in the PM tables
+ * @param User $param is the user being changed
+ */
+function plugin_item_update_processmaker_user(User $param) {
+ // Must test if user login has been changed
+ // if yes, must change the login in the PM tables:
+ // USERS and RBAC_USERS, othewise the link in the processmaker_users table will be invalid
+ if (in_array('name', $param->updates)) {
+ // check if user is in the processmaker_user table
+ $pm_user = PluginProcessmakerUser::getPMUserId($param->getID());
+ if ($pm_user) {
+ // must update the user in PM tables
+ global $PM_SOAP;
+ if ($param->fields['is_active'] == 0 || $param->fields['is_deleted'] == 1) {
+ $status = "INACTIVE";
+ } else {
+ $status = "ACTIVE";
+ }
+ $PM_SOAP->login(true);
+ $pmResult = $PM_SOAP->updateUser( $pm_user, $param->fields['name'], $param->fields['firstname'], $param->fields['realname'], $status );
+ }
+ }
+}
+
+
+function plugin_processmaker_post_init() {
+ global $PM_DB, $PM_SOAP;
+ if (!isset($PM_DB)) {
+ $PM_DB = new PluginProcessmakerDB;
+ }
+ if (!isset($PM_SOAP)) {
+ $PM_SOAP = new PluginProcessmakerProcessmaker;
+ // and default login is current running user if any
+ if (Session::getLoginUserID()) {
+ $PM_SOAP->login();
+ }
+ }
+}
+
+
+function plugin_processmaker_giveItem($itemtype, $ID, $data, $num) {
+
+ return;
+}
+
+
+function plugin_processmaker_change_profile() {
+ if ($_SESSION['glpiactiveprofile']['interface'] == "helpdesk") {
+ // must add the rights for simplified interface
+ $_SESSION['glpiactiveprofile']['plugin_processmaker_case'] = READ;
+ }
+}
+
+/**
+ * Summary of plugin_item_add_update_processmaker_tasks
+ * @param mixed $parm
+ */
+function plugin_item_update_processmaker_tasks($parm) {
+ global $DB, $CFG_GLPI, $PM_SOAP;
+
+ $pmTaskCat = new PluginProcessmakerTaskCategory;
+ if ($pmTaskCat->getFromDBbyCategory( $parm->fields['taskcategories_id'] )
+ && in_array( 'state', $parm->updates )
+ && $parm->input['state'] == Planning::DONE
+ && $parm->oldvalues['state'] == Planning::TODO) { // the task has just been set to DONE state
+
+ //$itemtype = str_replace( 'Task', '', $parm->getType() );
+
+ $pmTask = new PluginProcessmakerTask($parm->getType());
+ $pmTask->getFromDB($parm->fields['id']);
+
+ $locCase = new PluginProcessmakerCase;
+ $locCase->getFromDB($pmTask->fields['plugin_processmaker_cases_id']);
+ $srccase_guid = $locCase->fields['case_guid'];
+
+ //$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) {
+
+ // Must check the condition
+ $casevariables = [];
+
+ $matches = [];
+ if (preg_match_all( "/@@(\w+)/u", $targetTask['sourcecondition'], $matches )) {
+ $casevariables = $matches[1];
+ }
+
+ $targetTask['targetactions'] = []; // empty array by default
+ foreach ($DB->request( 'glpi_plugin_processmaker_caselinkactions', 'plugin_processmaker_caselinks_id = '.$targetTask['id']) as $actionvalue) {
+ $targetTask['targetactions'][$actionvalue['name']] = $actionvalue['value'];
+ if (preg_match_all( "/@@(\w+)/u", $actionvalue['value'], $matches )) {
+ $casevariables = array_merge( $casevariables, $matches[1] );
+ }
+ }
+ $externalapplication = false; // by default
+ if ($targetTask['is_externaldata'] && isset($targetTask['externalapplication'])) {
+ // must read some values
+ $externalapplication = json_decode( $targetTask['externalapplication'], true );
+ // must be of the form
+ // {"method":"POST","url":"urloftheservice","params":json_object}
+ // Where method is the POST, GET, ... method
+ // url is the URL to be called
+ // params is a list of parameters to get from running case
+ foreach ($externalapplication['params'] as $paramname => $variable) {
+ if (preg_match_all( "/@@(\w+)/u", $variable, $matches )) {
+ $casevariables = array_merge( $casevariables, $matches[1] );
+ }
+ }
+ }
+
+ // ask for those case variables
+ //$PM_SOAP = new PluginProcessmakerProcessmaker();
+ //$PM_SOAP->login( );
+ // now tries to get the variables to check condition
+ $infoForTasks = $locCase->getVariables($casevariables);
+ foreach ($infoForTasks as $casevar => $varval) {
+ $infoForTasks[ "@@$casevar" ] = "'$varval'";
+ unset( $infoForTasks[ $casevar ] );
+ }
+
+ //$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";
+
+ if ($eval) {
+ // look at each linked ticket if a case is attached and then if a task like $val is TO_DO
+ // then will try to routeCase for each tasks in $val
+
+ $postdata = [];
+ foreach ($targetTask['targetactions'] as $action => $actionvalue) {
+ $postdata['form'][$action] = eval( "return ".str_replace( array_keys($infoForTasks), $infoForTasks, $actionvalue)." ;" );
+ }
+ $postdata['UID'] = $targetTask['targetdynaform_guid'];
+ $postdata['__DynaformName__'] = $targetTask['targetprocess_guid']."_".$targetTask['targetdynaform_guid'];
+ $postdata['__notValidateThisFields__'] = '[]';
+ $postdata['DynaformRequiredFields'] = '[]';
+ $postdata['form']['btnGLPISendRequest'] = 'submit';
+
+ $externalapplicationparams = [];
+ if ($externalapplication) {
+ // must call curl
+ foreach ($externalapplication['params'] as $paramname => $variable) {
+ $externalapplicationparams[$paramname] = eval( "return ".str_replace( array_keys($infoForTasks), $infoForTasks, $variable)." ;" );
+ }
+ $externalapplicationparams['callback'] = $CFG_GLPI["url_base"]."/plugins/processmaker/ajax/asynchronousdatas.php";
+ $ch = curl_init();
+ $externalapplication['url'] = eval( "return '".str_replace( array_keys($infoForTasks), $infoForTasks, $externalapplication['url'])."' ;" ); // '???
+ curl_setopt($ch, CURLOPT_URL, $externalapplication['url'] );
+ if (isset($externalapplication['method']) && $externalapplication['method'] == 'POST') {
+ curl_setopt($ch, CURLOPT_POST, 1);
+ }
+ }
+
+ if ($targetTask['is_self']) {
+ $PM_SOAP->login(true);
+ $taskCase = $PM_SOAP->taskCase( $srccase_guid );
+ foreach ($taskCase as $task) {
+ // search for target task guid
+ if ($task->guid == $targetTask['targettask_guid']) {
+ break;
+ }
+ }
+ $PM_SOAP->login();
+
+ $postdata['APP_UID'] = $srccase_guid;
+ $postdata['DEL_INDEX'] = $task->delegate;
+
+ //need to get the 'ProcessMaker' user
+ $pmconfig = $PM_SOAP->config; //PluginProcessmakerConfig::getInstance();
+
+ $cronaction = new PluginProcessmakerCrontaskaction;
+ $cronaction->add( [ 'plugin_processmaker_caselinks_id' => $targetTask['id'],
+ 'plugin_processmaker_cases_id' => $locCase->getID(),
+ //'itemtype' => $itemtype,
+ //'items_id' => $parm->fields['tickets_id'],
+ 'users_id' => $pmconfig->fields['users_id'],
+ 'is_targettoclaim' => $targetTask['is_targettoclaim'],
+ 'state' => ($targetTask['is_externaldata'] ? PluginProcessmakerCrontaskaction::WAITING_DATA : PluginProcessmakerCrontaskaction::DATA_READY),
+ 'postdata' => json_encode( $postdata, JSON_HEX_APOS | JSON_HEX_QUOT),
+ 'logs_out' => json_encode( $externalapplicationparams, JSON_HEX_APOS | JSON_HEX_QUOT)
+ ],
+ null,
+ false);
+
+ if ($externalapplication) {
+ // must call external application in order to get the needed data asynchroneously
+ // must be of the form
+ // {"url":"urloftheservice","params":{"user":"@@USER_ID","system":"GPP","list":"@@ROLE_LIST"}}
+ // url is the URL to be called
+
+ $externalapplicationparams['id'] = $cronaction->getID();
+
+ $externalapplicationparams = json_encode( $externalapplicationparams, JSON_HEX_APOS | JSON_HEX_QUOT);
+
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $externalapplicationparams);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Content-Length: ' . strlen($externalapplicationparams), 'Expect:']);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
+ curl_setopt($ch, CURLOPT_VERBOSE, 1);
+
+ if (isset($externalapplication['ssl_verify'])) {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $externalapplication['ssl_verify']);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $externalapplication['ssl_verify']);
+ }
+
+ if (isset($externalapplication['proxy'])) {
+ curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1 ) ;
+ curl_setopt($ch, CURLOPT_PROXY, $externalapplication['proxy']);
+ }
+
+ $response = curl_exec ($ch);
+ if ($response === false) {
+ //throw new Exception(curl_error($ch), curl_errno($ch));
+ Toolbox::logDebug( curl_error($ch).":".curl_errno($ch) );
+ }
+
+ curl_close ($ch);
+ }
+ // }
+ } else {
+ // TODO to review this part of code as it is no longer usable like this !!!
+ foreach (Ticket_Ticket::getLinkedTicketsTo( $parm->fields['tickets_id'] ) as $tlink) {
+ if ($tlink['link'] == Ticket_Ticket::LINK_TO) {
+ $query = "SELECT glpi_plugin_processmaker_cases.id, MAX(glpi_plugin_processmaker_tasks.del_index) AS del_index FROM glpi_tickettasks
+ JOIN glpi_plugin_processmaker_taskcategories ON glpi_plugin_processmaker_taskcategories.taskcategories_id=glpi_tickettasks.taskcategories_id
+ JOIN glpi_plugin_processmaker_cases ON glpi_plugin_processmaker_cases.processes_id=glpi_plugin_processmaker_taskcategories.processes_id
+ RIGHT JOIN glpi_plugin_processmaker_tasks ON glpi_plugin_processmaker_tasks.items_id=glpi_tickettasks.id AND glpi_plugin_processmaker_tasks.case_id=glpi_plugin_processmaker_cases.id
+ WHERE glpi_plugin_processmaker_taskcategories.pm_task_guid = '".$targetTask['targettask_guid']."' AND glpi_tickettasks.state = 1 AND glpi_tickettasks.tickets_id=".$tlink['tickets_id'];
+ foreach ($DB->request($query) as $case) {
+ // must be only one row
+
+ $postdata['APP_UID'] = $case['id'];
+ $postdata['DEL_INDEX'] = $case['del_index'];
+
+ $cronaction = new PluginProcessmakerCrontaskaction;
+ $cronaction->add( [ 'plugin_processmaker_caselinks_id' => $targetTask['id'],
+ 'plugin_processmaker_cases_id' => $locCase->getID(),
+ //'itemtype' => $itemtype,
+ //'items_id' => $parm->fields['tickets_id'],
+ 'users_id' => Session::getLoginUserID(),
+ 'is_targettoclaim' => $targetTask['is_targettoclaim'],
+ 'state' => ($targetTask['is_externaldata'] ? PluginProcessmakerCrontaskaction::WAITING_DATA : PluginProcessmakerCrontaskaction::DATA_READY),
+ 'postdata' => json_encode( $postdata, JSON_HEX_APOS | JSON_HEX_QUOT),
+ 'logs_out' => json_encode( $externalapplicationparams, JSON_HEX_APOS | JSON_HEX_QUOT)
+ ],
+ null,
+ false);
+ }
+ }
+ }
+ }
+
+ if ($targetTask['is_synchronous']) {
+ // must call PluginProcessmakerProcessmaker::cronPMTaskActions()
+ PluginProcessmakerProcessmaker::cronPMTaskActions();
+ }
+ }
+
+ }
+
+ //$msg .= "================\n";
+ //Toolbox::logInFile("processmaker", $msg);
+
+ }
+}
diff --git a/inc/case.class.php b/inc/case.class.php
index 80f886f..9613f25 100644
--- a/inc/case.class.php
+++ b/inc/case.class.php
@@ -1,1661 +1,1611 @@
-fields['plugin_processmaker_cases_id'] == 0
- && $this->canDeleteItem()
- && (self::canDelete() || $this->fields['case_status'] == PluginProcessmakerCase::DRAFT);
- }
-
- static function canCancel() {
- return plugin_processmaker_haveRight('case', CANCEL);
- }
-
- /**
- * Summary of getTabNameForItem
- * @param CommonGLPI $item is the item
- * @param mixed $withtemplate has template
- * @return array os strings
- */
- function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
- if ($item->getType() == __CLASS__) {
- // get tab name for a case itself
- $tabname = __('Case', 'processmaker');
- if ($item->fields['plugin_processmaker_cases_id'] > 0) {
- // case is a sub-case
- $tabname = __('Sub-case', 'processmaker');
- }
- return [ 'main' => $tabname."
".self::getStatus($item->fields['case_status']).""];
- } else {
- $items_id = $item->getID();
- $itemtype = $item->getType();
-
- // count how many cases are on this item
- $cnt = count(self::getIDsFromItem($itemtype, $items_id));
- if ($cnt == 0) {
- return ['processmakercases' => __('Process case', 'processmaker')];
- }
- return ['processmakercases' => _n('Process case', 'Process cases', $cnt, 'processmaker')."
$cnt"];
- }
- }
-
-
- /**
- * Summary of getName
- * @param mixed $options
- * @return mixed
- */
- function getName($options = []) {
- return $this->fields['name'];
- }
-
-
- /**
- * Summary of getIDFromItem
- * @param string $itemtype is the item type
- * @param integer $items_id is the item id
- * @return integer cases_id
- */
- //static function getIDFromItem($itemtype, $items_id) {
- // $tmp = New self;
- // if ($tmp->getFromDBByQuery(" WHERE items_id=$items_id and itemtype='$itemtype'")) {
- // return $tmp->getID();
- // }
- // return false;
- //}
-
-
- /**
- * Summary of getIDsFromItem
- * returns an array of the case ids linked to the item
- * @param string $itemtype is the item type of the item (Ticket, Problem, Change)
- * @param mixed $items_id is the GLPI id of the item in the type
- * @return array
- */
- static function getIDsFromItem($itemtype, $items_id) {
- $ret = [];
- $dbu = new DbUtils;
- $restrict = [
- "items_id" => $items_id,
- "itemtype" => $itemtype,];
-
- //foreach ($dbu->getAllDataFromTable( self::getTable(), "items_id=$items_id AND itemtype='$itemtype'") as $case)
- foreach ($dbu->getAllDataFromTable( self::getTable(), $restrict) as $case) {
- $ret[] = $case['id'];
- }
- return $ret;
- }
-
- /**
- * Summary of getFromItem
- * @param mixed $itemtype is the item type
- * @param mixed $items_id is the item id
- * @return mixed: returns false when there is no case associated with the item, else fills in the item fields from DB, and returns true
- */
- //function getFromItem($itemtype, $items_id) {
- // return $this->getFromDBByQuery(" WHERE items_id=$items_id and itemtype='$itemtype'");
- //}
-
-
- /**
- * Summary of getFromGUID
- * @param mixed $case_guid
- * @return boolean
- */
- function getFromGUID($case_guid) {
- $restrict=[
- 'WHERE' => [
- 'case_guid' => $case_guid,
- ],
- ];
- return $this->getFromDBByRequest($restrict);
- }
-
-
- /**
- * Summary of getVariables
- * @param mixed $vars
- * @return mixed
- */
- function getVariables($vars = []) {
- global $PM_SOAP;
- return $PM_SOAP->getVariables($this->fields['case_guid'], $vars);
- }
-
-
- /**
- * Summary of sendVariables
- * @param mixed $vars
- * @return A
- */
- function sendVariables($vars = []) {
- global $PM_SOAP;
- return $PM_SOAP->sendVariables($this->fields['case_guid'], $vars);
- }
-
-
- /**
- * Summary of getCaseInfo
- * @param mixed $delIndex
- * @return stdClass, a getCaseInfoResponse object, or false exception occured
- */
- function getCaseInfo($delIndex = '') {
- global $PM_SOAP;
- return $PM_SOAP->getCaseInfo($this->fields['case_guid'], $delIndex);
- }
-
-
- /**
- * Summary of unpauseCase
- * @param mixed $delIndex
- * @param mixed $userGuid
- * @return an
- */
- function unpauseCase($delIndex, $userGuid) {
- global $PM_SOAP;
- return $PM_SOAP->unpauseCase($this->fields['case_guid'], $delIndex, $userGuid);
- }
-
-
- /**
- * Summary of unassignCase
- * Will unassign the delIndex task, restoring the assigned group
- * @param $delIndex int the delegation index
- * @param $taskGuid string the GUID of the task
- * @param $tasktype string the type of task (TicketTask, ChangeTask, ProblemTask)
- * @param $tasks_id int the id of the task
- * @param $itemtype string the type of the ITIL object (Ticket, Change, Problem)
- * @return bool
- */
- function unassignCase($delIndex, $taskGuid, $tasktype, $tasks_id, $itemtype, $options) {
- global $PM_DB, $PM_SOAP, $DB;
-
- // un-claim task
- // will unclaim the task
- // to unclaim a task, we must un-assign the task in the APP_DELEGATION table
- // and un-assign the task in glpi_itemtypeTask table
- $groupname = '';
-
- // should get the group that is assigned to the task in SELF_SERVICE assign type
- $query = "SELECT TAS_GROUP_VARIABLE FROM TASK WHERE TAS_UID='".$taskGuid."' AND TAS_ASSIGN_TYPE='SELF_SERVICE' LIMIT 1;";
- foreach($PM_DB->request($query) as $pmGroup) {
- // should have only one record
- if ($pmGroup['TAS_GROUP_VARIABLE'] == '') {
- // then we are in the self-service with a group in the TASK_USER table
- // TU_RELATION=2 is groups and TU_TYPE=1 means normal (= not adhoc)
- // then get the group name from the CONTENT table
- $query = "SELECT CONTENT.CON_VALUE FROM TASK_USER
- JOIN CONTENT ON CONTENT.CON_ID=TASK_USER.USR_UID AND CONTENT.CON_CATEGORY='GRP_TITLE' AND CONTENT.CON_LANG = 'en'
- WHERE TASK_USER.TAS_UID='".$taskGuid."' AND TASK_USER.TU_RELATION=2 AND TASK_USER.TU_TYPE=1 LIMIT 1;";
-
- foreach ($PM_DB->request($query) as $onlyrec) {
- $groupname = $onlyrec['CON_VALUE'];
- }
-
-
- } else {
- // then we are in the self-service with a case variable that contains either a group either an array of users
- // array of users is not yet supported by PM plugin, as GLPI tasks have one and only one users_id_tech.
- // group guid (in the case variable) must be retrieved from APP DATA
-
- // TODO
- ////////////////////////////////////////////////////////////////
- // Currently this case is not manageable by GLPI
- // as GLPI needs at least a user or a group to be assigned to a task
- // and when using the self-service value based assignment, there
- // is a case variable that contains a list of users. This list of users cannot be mapped to a group in GLI
- // OR may be we may create an artificial group in GLPI that would contains the list of users
- ////////////////////////////////////////////////////////////////
-
- // and then we get the name of the group from the CONTENT table
- //$query = "SELECT CON_VALUE FROM CONTENT
- // WHERE CONTENT.CON_ID='$groupId' AND CONTENT.CON_CATEGORY='GRP_TITLE' AND CONTENT.CON_LANG='en' ;";
-
- }
- }
-
- $groups_id_tech = PluginProcessmakerProcessmaker::getGLPIGroupId($groupname);
-
- if ($groups_id_tech) {
- // unclaim the case only when a GLPI group can be found
-
- $query = "UPDATE APP_DELEGATION SET USR_UID='', DEL_INIT_DATE=NULL, USR_ID=0 WHERE APP_NUMBER=".$this->getID()." AND DEL_INDEX=$delIndex;";
- $PM_DB->query($query);
-
- $glpi_task = new $tasktype;
- $glpi_task->getFromDB($tasks_id);
- $foreignkey = getForeignKeyFieldForItemType( $itemtype );
-
- $donotif = PluginProcessmakerNotificationTargetProcessmaker::saveNotificationState(false); // do not send notification yet
- $glpi_task->update( ['id' => $glpi_task->getID(),
- $foreignkey => $glpi_task->fields[$foreignkey],
- 'users_id_tech' => 0,
- 'groups_id_tech' => $groups_id_tech,
- 'update' => true] );
- PluginProcessmakerNotificationTargetProcessmaker::restoreNotificationState($donotif);
-
- // send notification now!
- $pm_task = new PluginProcessmakerTask($tasktype);
- $pm_task->getFromDB($tasks_id);
- $glpi_item = new $itemtype;
- $glpi_item->getFromDB($glpi_task->fields[$foreignkey]);
- $pm_task->sendNotification('task_unclaim', $glpi_task, $glpi_item, $this);
-
- // create an information task and add comment
- $pm_process = $this->getProcess();
- $dbu = new DbUtils;
- $info = __('
Task un-claimed!Case: %s
Task: "%s" has been un-assigned from "%s" and assigned to "%s" group.
Reason: %s', 'processmaker');
- $info .= "
";
- $taskCat = new TaskCategory;
- $taskCat->getFromDB( $glpi_task->fields['taskcategories_id'] );
- $info = sprintf($info,
- $this->getNameID(['forceid' => true]),
- DropdownTranslation::getTranslatedValue($glpi_task->fields['taskcategories_id'], 'TaskCategory', 'name', $_SESSION['glpilanguage'], $taskCat->fields['name']),
- Html::clean($dbu->getUserName(isset($glpi_task->oldvalues['users_id_tech']) ? $glpi_task->oldvalues['users_id_tech'] : 0)),
- Html::clean($groupname),
- $options['comment']
- );
- // unescape some chars and replace CRLF, CR or LF by
- $info = str_replace(["\\'", '\\"', '\r\n', '\r', '\n'], ["'", '"', '
', '
', '
'], $info);
-
- $glpi_task->add([$foreignkey => $glpi_task->fields[$foreignkey],
- 'is_private' => 0, // a post-only user can't create private task
- 'taskcategories_id' => $pm_process->fields['taskcategories_id'],
- 'content' => $DB->escape($info),
- 'users_id' => $PM_SOAP->taskWriter,
- 'state' => Planning::INFO,
- 'users_id_tech' => Session::getLoginUserID(),
- ]);
-
- return true;
- }
-
- return false;
- }
-
-
- /**
- * Summary of reassignCase
- * @param mixed $delIndex
- * @param mixed $taskGuid
- * @param mixed $delThread
- * @param mixed $users_id_source
- * @param mixed $users_id_target
- * @return mixed
- */
- function reassignCase($delIndex, $taskGuid, $delThread, $users_id_source, $users_id_target, $options) {
- global $PM_SOAP;
- $users_guid_source = ''; // by default
- if ($users_id_source !== 0) { // when task is not 'to be claimed'
- $users_guid_source = PluginProcessmakerUser::getPMUserId($users_id_source);
- }
- $users_guid_target = PluginProcessmakerUser::getPMUserId($users_id_target);
- $pmResponse = $PM_SOAP->reassignCase($this->fields['case_guid'], $delIndex, $users_guid_source, $users_guid_target);
- // now should manage GLPI Tasks previously assigned to the $users_guid_source
- if ($pmResponse->status_code == 0) {
- // we need to change the delindex of the glpi task and the assigned tech to prevent creation of new tasks
- // we need the delindex of the current glpi task, and the delindex of the new one
- // search for new delIndex and new delThread
- $newCaseInfo = $this->getCaseInfo( );
- $newDelIndex = 0;
- $newDelThread = 0;
- foreach ($newCaseInfo->currentUsers as $newCaseUser) {
- if ($newCaseUser->taskId == $taskGuid && $newCaseUser->delThread == $delThread) {
- $newDelIndex = $newCaseUser->delIndex;
- $newDelThread = $newCaseUser->delThread;
- break;
- }
- }
- $this->reassignTask($delIndex, $newDelIndex, $delThread, $newDelThread, $users_id_target, $options);
- return true;
- }
- return false;
- }
-
-
- /**
- * Summary of reassignTask
- * @param mixed $delIndex
- * @param mixed $newDelIndex
- * @param mixed $newTech
- */
- public function reassignTask ($delIndex, $newDelIndex, $delThread, $newDelThread, $newTech, $options) {
- global $DB, $PM_SOAP;
-
- $dbu = new DbUtils;
- $pm_task_row = $dbu->getAllDataFromTable(PluginProcessmakerTask::getTable(), ['plugin_processmaker_cases_id' => $this->getID(), 'del_index' => $delIndex, 'del_thread' => $delThread]);
- if ($pm_task_row && count($pm_task_row) == 1) {
- $pm_task_row = array_shift($pm_task_row);
- $glpi_task = new $pm_task_row['itemtype'];
- $glpi_task->getFromDB($pm_task_row['items_id']);
-
- $itilobject_itemtype = $this->fields['itemtype'];
- $foreignkey = getForeignKeyFieldForItemType( $itilobject_itemtype );
-
- PluginProcessmakerProcessmaker::addWatcher( $itilobject_itemtype, $glpi_task->fields[ $foreignkey ], $newTech );
-
- $donotif = PluginProcessmakerNotificationTargetProcessmaker::saveNotificationState(false); // do not send notification yet
- $glpi_task->update( ['id' => $glpi_task->getID(),
- $foreignkey => $glpi_task->fields[$foreignkey],
- 'users_id_tech' => $newTech,
- 'groups_id_tech' => 0,
- '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']
- ]
- );
-
- // send notification now!
- $pm_task = new PluginProcessmakerTask($pm_task_row['itemtype']);
- $pm_task->getFromDB($pm_task_row['items_id']);
- $glpi_item = new $itilobject_itemtype;
- $glpi_item->getFromDB($glpi_task->fields[$foreignkey]);
- $pm_task->sendNotification('task_reassign', $glpi_task, $glpi_item, $this);
-
- // create an information task and add comment
- $pm_process = $this->getProcess();
- $old_users_tech_id = isset($glpi_task->oldvalues['users_id_tech']) ? $glpi_task->oldvalues['users_id_tech'] : 0;
- $taskCat = new TaskCategory;
- $taskCat->getFromDB( $glpi_task->fields['taskcategories_id'] );
- $task_name = DropdownTranslation::getTranslatedValue($glpi_task->fields['taskcategories_id'], 'TaskCategory', 'name', $_SESSION['glpilanguage'], $taskCat->fields['name']);
- $new_tech_name = Html::clean($dbu->getUserName($newTech));
- if ($old_users_tech_id) {
- $info = __('
Task re-assigned!Case: %s
Task: "%s" has been re-assigned from "%s" to "%s".
Reason: %s', 'processmaker');
- $info = sprintf($info,
- $this->getNameID(['forceid' => true]),
- $task_name,
- Html::clean($dbu->getUserName(isset($glpi_task->oldvalues['users_id_tech']) ? $glpi_task->oldvalues['users_id_tech'] : 0)),
- $new_tech_name,
- $options['comment']
- );
- } else {
- $info = __('
Task assigned!Case: %s
Task: "%s" has been assigned to "%s".
Reason: %s', 'processmaker');
- $info = sprintf($info,
- $this->getNameID(['forceid' => true]),
- $task_name,
- $new_tech_name,
- $options['comment']
- );
- }
- $info .= "
";
-
- // unescape some chars and replace CRLF, CR or LF by
- $info = str_replace(["\\'", '\\"', '\r\n', '\r', '\n'], ["'", '"', '
', '
', '
'], $info);
-
- $glpi_task->add([$foreignkey => $glpi_task->fields[$foreignkey],
- 'is_private' => 0, // a post-only user can't create private task
- 'taskcategories_id' => $pm_process->fields['taskcategories_id'],
- 'content' => $DB->escape($info),
- 'users_id' => $PM_SOAP->taskWriter,
- 'state' => Planning::INFO,
- 'users_id_tech' => Session::getLoginUserID(),
- ]);
- }
- }
-
-
- /**
- * Summary of getProcess
- * Returns process object
- * @return bool|PluginProcessmakerProcess
- */
- function getProcess() {
- $pm_process = new PluginProcessmakerProcess;
- if (!$this->process && $pm_process->getFromDB($this->fields['plugin_processmaker_processes_id'])) {
- $this->process = $pm_process;
- }
- return $this->process;
- }
-
- /**
- * Summary of showCaseProperties
- */
- function showCaseProperties() {
- global $DB, $PM_DB;
-
- // get all tasks that are OPEN for any sub-case of this case
- $case_tasks = [];
- $res = $DB->request('glpi_plugin_processmaker_tasks', [
- 'AND' => [
- 'plugin_processmaker_cases_id' => $this->getID(),
- 'del_thread_status' => 'OPEN'
- ]
- ]);
- foreach ($res as $task) {
- $case_tasks[$task['del_index']] = $task;
- }
- //$query = "SELECT `glpi_plugin_processmaker_tasks`.* FROM `glpi_plugin_processmaker_tasks`
- // WHERE `glpi_plugin_processmaker_tasks`.`plugin_processmaker_cases_id`={$this->getID()} AND `del_thread_status`='OPEN'";
- //foreach ($DB->request($query) as $task) {
- // $case_tasks[$task['del_index']] = $task;
- //}
-
- //// get all tasks that are OPEN for any sub-case of this case
- //$sub_cases = [];
- //$query = "SELECT `glpi_plugin_processmaker_tasks`.* FROM `glpi_plugin_processmaker_tasks`
- // JOIN `glpi_plugin_processmaker_cases` on `glpi_plugin_processmaker_cases`.`id`=`glpi_plugin_processmaker_tasks`.`plugin_processmaker_cases_id`
- // WHERE `glpi_plugin_processmaker_cases`.`plugin_processmaker_cases_id`={$this->getID()} AND `del_thread_status`='OPEN'";
- //foreach($DB->request($query) as $task) {
- // $sub_cases[$task['plugin_processmaker_cases_id']][$task['del_index']] = $task;
- //}
-
- $caseInfo = $this->getCaseInfo();
- if (property_exists($caseInfo, 'currentUsers')) {
- $caseInfo->currentUsers = $this->sortTasks($caseInfo->currentUsers, PluginProcessmakerUser::getPMUserId(Session::getLoginUserID()));
- }
- $res = $PM_DB->request([
- 'SELECT' => ['DEL_INDEX', 'DEL_DELEGATE_DATE'],
- 'FROM' => 'APP_DELEGATION',
- 'WHERE' => ['APP_UID' => $caseInfo->caseId]
- ]);
- //$query = "SELECT `DEL_INDEX`, `DEL_DELEGATE_DATE` FROM `APP_DELEGATION` WHERE `APP_UID`='{$caseInfo->caseId}'";
- $tasks = [];
- foreach ($res as $row) {
- $tasks[$row['DEL_INDEX']] = $row['DEL_DELEGATE_DATE'];
- }
- //foreach ($PM_DB->request($query) as $row) {
- // $tasks[$row['DEL_INDEX']] = $row['DEL_DELEGATE_DATE'];
- //}
-
- echo "
";
- // show the case properties like given by PM server
- $this->showShort($caseInfo);
-
- // show current (running) tasks properties
- echo "
";
-
- echo "
";
- echo "
";
-
- echo "| ".__('Current task(s) properties', 'processmaker')." |
";
-
- if (property_exists($caseInfo, 'currentUsers') && count($caseInfo->currentUsers) > 0) {
- echo "
- | ".__('Task', 'processmaker')." |
- ".__('Task guid', 'processmaker')." |
- ".__('Current user', 'processmaker')." |
- ".__('Task delegation date', 'processmaker')." |
-
";
- foreach ($caseInfo->currentUsers as $currentTask) {
- $case_url = $this->getLinkURL().'&forcetab=PluginProcessmakerTask$';
- echo "";
- if (isset($case_tasks[$currentTask->delIndex])) {
- $case_url .= $case_tasks[$currentTask->delIndex]['id'];
- echo "| ".$currentTask->taskName." | ";
- } else {
- $res = $PM_DB->request([
- 'SELECT' => 'APP_UID',
- 'FROM' => 'SUB_APPLICATION',
- 'WHERE' => [
- 'AND' => [
- 'APP_PARENT' => $this->fields['case_guid'],
- 'DEL_INDEX_PARENT' => $currentTask->delIndex,
- 'SA_STATUS' => 'ACTIVE'
- ]
- ]
- ]);
- //$res = $PM_DB->query("SELECT APP_UID FROM SUB_APPLICATION WHERE APP_PARENT='{$this->fields['case_guid']}' AND DEL_INDEX_PARENT={$currentTask->delIndex} AND SA_STATUS='ACTIVE'");
- //if ($res && $PM_DB->numrows($res) == 1) {
- // $row = $PM_DB->fetch_assoc($res);
- if ($res->numrows() == 1 && $row = $res->next()) {
- $sub_case = new PluginProcessmakerCase;
- $sub_case->getFromGUID($row['APP_UID']);
- $case_url .= $sub_case->getID()."-".$currentTask->delIndex;
- echo "> ".$currentTask->taskName." | ";
- } else {
- echo "".$currentTask->taskName." | ";
- }
- }
- echo "".$currentTask->taskId." | ";
- if ($currentTask->userName == '') {
- echo "".__('To be claimed', 'processmaker')." | ";
- } else {
- echo "".$currentTask->userName." | ";
- }
- echo "".Html::convDateTime($tasks[$currentTask->delIndex])." | ";
- echo "
";
- }
- } else {
- echo "".__('None')." | ";
- }
-
- echo "
";
-
- echo "
";
-
- // show the parent case if it's a sub-case
- if ($this->fields['plugin_processmaker_cases_id'] > 0) {
- echo "
";
- $sub_case = new self;
- $sub_case->getFromDB($this->fields['plugin_processmaker_cases_id']);
- $sub_case->showShort($sub_case->getCaseInfo(), true);
- }
-
- }
-
- /**
- * Summary of showShort
- * @param mixed $caseInfo
- * @param mixed $showparenturl
- */
- function showShort($caseInfo, $showparenturl = false) {
-
- echo "
";
- echo "
";
-
- if ($this->fields['plugin_processmaker_cases_id'] > 0) {
- echo "| ".__('Sub-case properties', 'processmaker')." |
";
- } else {
- if ($showparenturl) {
- echo "| ".__('Parent case properties', 'processmaker')." |
";
- } else {
- echo "| ".__('Case properties', 'processmaker')." |
";
- }
- }
-
- echo "";
- echo "| ".__('Process', 'processmaker')." | ";
- echo "".__('Case title', 'processmaker')." | ";
- echo "".__('Case number', 'processmaker')." | ";
- echo "".__('Case status', 'processmaker')." | ";
- echo "".__('Case guid', 'processmaker')." | ";
- echo "".__('Creator', 'processmaker')." | ";
- echo "".__('Creation date', 'processmaker')." | ";
- echo "".__('Last update', 'processmaker')." | ";
- //echo "".__('Case description', 'processmaker')." | ";
- echo "
";
-
- echo "";
- echo "| ".$caseInfo->processName." | ";
- if ($showparenturl) {
- echo "".$this->getLink()." | ";
- } else {
- echo "".$caseInfo->caseName." | ";
- }
- echo "".$caseInfo->caseNumber." | ";
- echo "".self::getStatus($caseInfo->caseStatus)." | ";
- echo "".$caseInfo->caseId." | ";
- echo "".$caseInfo->caseCreatorUserName." | ";
- echo "".Html::convDateTime($caseInfo->createDate)." | ";
- echo "".Html::convDateTime($caseInfo->updateDate)." | ";
- //echo "".$caseInfo->????." | ";
- echo "
";
-
- echo "
";
-
- echo "
";
-
- }
-
-
- /**
- * Summary of localSortTasks
- * used to sort array of tasks in a currenUsers object
- * @param mixed $a
- * @param mixed $b
- * @return integer
- */
- static private function localSortTasks ($a, $b) {
- return $a->delIndex - $b->delIndex;
- }
-
- /**
- * Summary of sortTasks
- * @param mixed $tasks is the array of tasks from a getCaseInfo->currentUsers
- * @param mixed $GLPICurrentPMUserId
- * @return array sorted $tasks
- */
- public function sortTasks($tasks, $GLPICurrentPMUserId) {
-
- $tbctasks = [];
- $utasks = [];
- $infotasks = [];
-
- foreach ($tasks as $caseUser) {
- if ($caseUser->userId == $GLPICurrentPMUserId) {
- $utasks[] = $caseUser;
- } else {
- if ($caseUser->userId == '') { // task to be claimed
- $tbctasks[] = $caseUser;
- } else {
- $infotasks[] = $caseUser;
- }
- }
- }
-
- // order task by "current user", then by "to be claimed", and then push to end "tasks assigned to another user"
- // then by delindex ASC in these three parts
- usort($utasks, 'self::localSortTasks');
- usort($tbctasks, 'self::localSortTasks');
- usort($infotasks, 'self::localSortTasks');
-
- return array_merge($utasks, $tbctasks, $infotasks);
- }
-
-
- /**
- * Summary of showCaseInfoTab
- * Will show information about the current case
- * @param CommonGLPI $case is a PluginProcessmakerCase object
- * @param mixed $tabnum
- * @param mixed $withtemplate
- */
- static function showCaseInfoTab(CommonGLPI $case, $tabnum = 1, $withtemplate = 0) {
- // echo 'The idea is to show here the GLPI ITIL item to which it is linked, and to give a resume of the current case status, and to give possibility to delete or cancel the case.';
- $itemtype = $case->fields['itemtype'];
-
- $maintitle = __('Case is linked to a %1s', 'processmaker');
- if ($case->fields['plugin_processmaker_cases_id'] > 0) {
- $maintitle = __('Sub-case is linked to a %1s', 'processmaker');
- }
-
- echo "
| ".sprintf($maintitle, $itemtype::getTypeName(1))." |
|---|
";
-
- Ticket::commonListHeader(Search::HTML_OUTPUT);
-
- $itemtype::showShort($case->fields['items_id']);
-
- echo "";
-
- // show case properties
- $case->showCaseProperties();
-
- if ($case->fields['plugin_processmaker_cases_id'] == 0 && self::canCancel() && $case->fields['case_status'] == self::TO_DO) {
-
- // it's a main case, not a sub-case
- // and we have the rights to cancel cases
-
- echo "
";
- echo "
";
-
- }
-
- // will not show delete button if case is a sub-process
- // and will show it only if it is a draft or if current glpi user has the right to delete cases and session is central
- if ($case->canPurgeItem($case->getID())) {
-
- // then propose a button to delete case
- // the button will be effectively shown by the showFormButtons()
-
- echo "
";
- echo "
";
- echo "
";
-
- }
-
- return;
- }
-
-
- /**
- * Summary of showForItem
- * Shows list of cases attached to an item
- * @param CommonITILObject $item
- */
- static function showForItem(CommonITILObject $item) {
- global $DB, $CFG_GLPI, $PM_SOAP;
-
- $items_id = $item->getField('id');
- $itemtype = $item->getType();
- //if (!Session::haveRight("problem", Problem::READALL)
- // || !$item->can($ID, READ)) {
-
- // return false;
- //}
-
- $canupdate = $item->can($items_id, UPDATE);
-
- $rand = mt_rand();
- $res = $DB->request([
- 'SELECT' => ['gppc.id AS assocID', 'gppc.id AS id', 'gppp.id AS pid', 'gppp.name AS pname', 'gppc.case_status', 'gppc.plugin_processmaker_cases_id'],
- 'FROM' => 'glpi_plugin_processmaker_cases AS gppc',
- 'LEFT JOIN' => [
- 'glpi_plugin_processmaker_processes AS gppp' => [
- 'FKEY' => [
- 'gppp' => 'id',
- 'gppc' => 'plugin_processmaker_processes_id']
- ]
- ],
- 'WHERE' => [
- 'AND' => [
- 'gppc.itemtype' => $itemtype,
- 'gppc.items_id' => $items_id
- ]
- ]
- ]);
- //$query = "SELECT gppc.`id` AS assocID, gppc.`id` as id, gppp.id as pid, gppp.name as pname, gppc.`case_status`, gppc.`plugin_processmaker_cases_id`
- // FROM `glpi_plugin_processmaker_cases` as gppc
- // LEFT JOIN `glpi_plugin_processmaker_processes` AS gppp ON gppp.`id`=gppc.`plugin_processmaker_processes_id`
- // WHERE gppc.`itemtype` = '$itemtype'
- // AND gppc.`items_id` = $items_id
- // ";
- //$result = $DB->query($query);
-
- $cases = [];
- $used = [];
- $pid = [];
- if ($numrows = $res->numrows()) {
- foreach ($res as $data) {
- $cases[$data['id']] = $data;
- $used[$data['id']] = $data['id'];
- if (isset($pid[$data['pid']])) {
- $pid[$data['pid']] += 1;
- } else {
- $pid[$data['pid']] = 1;
- }
- }
- }
- //if ($numrows = $DB->numrows($result)) {
- // while ($data = $DB->fetch_assoc($result)) {
- // $cases[$data['id']] = $data;
- // $used[$data['id']] = $data['id'];
- // if (isset($pid[$data['pid']])) {
- // $pid[$data['pid']] += 1;
- // } else {
- // $pid[$data['pid']] = 1;
- // }
- // }
- //}
-
- $columns = ['pname' => __('Process', 'processmaker'),
- 'name' => __('Title', 'processmaker'),
- 'status' => __('Status', 'processmaker'),
- 'sub' => __('Sub-case of', 'processmaker')
- ];
-
- // check if item is not solved nor closed
- if ($canupdate
- && $item->fields['status'] != CommonITILObject::SOLVED
- && $item->fields['status'] != CommonITILObject::CLOSED
- && $_SESSION['glpiactiveprofile']['interface'] != 'helpdesk'
- && ($numrows < $PM_SOAP->config->fields['max_cases_per_item']
- || $PM_SOAP->config->fields['max_cases_per_item'] == 0)) {
- echo "
";
- }
-
- echo "
";
- if ($canupdate && $numrows) {
- Html::openMassiveActionsForm('mass'.__CLASS__.$rand);
- $massiveactionparams = ['num_displayed' => $numrows,
- 'container' => 'mass'.__CLASS__.$rand];
- Html::showMassiveActions($massiveactionparams);
- }
- echo "
";
- echo "| ".PluginProcessmakerCase::getTypeName($numrows)." | ";
- echo "
";
- if ($numrows) {
- $header_begin = "";
- $header_top = '';
- $header_bottom = '';
- $header_end = '';
- if ($canupdate
- && $numrows) {
- $header_top .= "| ".Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
- $header_top .= " | ";
- $header_bottom .= "".Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
- $header_bottom .= " | ";
- }
-
- foreach ($columns as $key => $val) {
- $header_end .= "$val | ";
- }
-
- $header_end .= "
";
- echo $header_begin.$header_top.$header_end;
-
- //Session::initNavigateListItems('PluginProcessmakerCase',
- // //TRANS : %1$s is the itemtype name,
- // // %2$s is the name of the item (used for headings of a list)
- // sprintf(__('%1$s = %2$s'),
- // $itemtype::getTypeName(1), $item->fields["name"]));
-
- $i = 0;
- foreach ($cases as $data) {
- Session::addToNavigateListItems('PluginProcessmakerCase', $data["id"]);
- $link = NOT_AVAILABLE;
- $case = new self;
- if ($case->getFromDB($data["id"])) {
- $link = $case->getLink();
- }
-
- echo "";
- if ($canupdate) {
- echo "| ";
- // prevent massiveaction on subprocess
- if ($data['plugin_processmaker_cases_id'] == 0) {
- Html::showMassiveActionCheckBox(__CLASS__, $data["assocID"]);
- }
- echo " | ";
- }
- echo "".$data['pname']." | ";
- echo "".$link." | ";
- echo "".self::getStatus($data['case_status'])." | ";
- echo "";
- if ($data['plugin_processmaker_cases_id'] > 0) {
- // then this is a subprocess of
- $maincase = new self;
- if ($maincase->getFromDB($data['plugin_processmaker_cases_id'])) {
- echo $maincase->getLink();
- }
- } else {
- echo '-';
- }
- echo " | ";
- //echo "".Html::convDateTime($data["date_creation"])." | ";
- echo "
";
-
- $i++;
- }
- echo $header_begin.$header_top.$header_end;
-
- }
-
- echo "
";
- if ($canupdate && $numrows) {
- $massiveactionparams['ontop'] = false;
- Html::showMassiveActions($massiveactionparams);
- Html::closeForm();
- }
- echo "
";
- }
-
- /**
- * Summary of displayTabContentForItem
- * @param CommonGLPI $item
- * @param mixed $tabnum
- * @param mixed $withtemplate
- */
- static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
- global $PM_SOAP;
-
- if ($item->getType() == __CLASS__) {
- // we are in a case viewing the main tab
- // the 'Case infos' tab
- //self::showCaseInfoTab($item, $tabnum, $withtemplate);
-
- } else {
-
- // show the list of cases attached to the $item ITIL object
- if (!$PM_SOAP->config->fields['maintenance']) {
- self::showForItem($item);
- } else {
- PluginProcessmakerProcessmaker::showUnderMaintenance();
- }
- }
- }
-
-
- /**
- * Summary of deleteTasks
- * will delete all tasks associated with this case from the item
- * @return true if tasks have been deleted from associated item and from case table
- */
- private function deleteTasks() {
- global $DB;
- $ret = false;
- $sub = new QuerySubQuery([
- 'SELECT' => 'items_id',
- 'FROM' => 'glpi_plugin_processmaker_tasks',
- 'WHERE' => ['plugin_processmaker_cases_id' => $this->fields['id']]
- ]);
-
- if ($DB->delete('glpi_'.strtolower($this->fields['itemtype']).'tasks', ['id' => $sub ])) {
- if ($DB->delete('glpi_plugin_processmaker_tasks', ['plugin_processmaker_cases_id' => $this->fields['id']])) {
- $ret = true;
- }
- }
- //$query = "DELETE FROM glpi_".strtolower($this->fields['itemtype'])."tasks WHERE id IN (SELECT items_id FROM glpi_plugin_processmaker_tasks WHERE plugin_processmaker_cases_id='".$this->fields['id']."')";
- //if ($DB->query( $query )) {
- // $query = "DELETE FROM glpi_plugin_processmaker_tasks WHERE plugin_processmaker_cases_id='".$this->fields['id']."'";
- // if ($DB->query( $query )) {
- // $ret = true;
- // }
- //}
- return $ret;
- }
-
-
- /**
- * Summary of deleteCase
- * will delete case and all tasks associated with this case from the item
- * @return true if case and tasks have been deleted from associated item and from case table
- */
- function deleteCase() {
- return $this->delete(['id' => $this->getID()]);
- }
-
-
- /**
- * Summary of cancelTasks
- * will mark as information all to_do tasks
- * BEWARE that this will only be done when case is in TO_DO status
- * @return true if tasks have been deleted from associated item and from case table
- */
- private function cancelTasks() {
- global $DB;
- $ret = false;
-
- if (isset($this->fields['case_status']) && $this->fields['case_status'] == "TO_DO") {
- $sub = new QuerySubQuery([
- 'SELECT' => 'items_id',
- 'FROM' => 'glpi_plugin_processmaker_tasks',
- 'WHERE' => ['plugin_processmaker_cases_id' => $this->fields['id']]
- ]);
- $res = $DB->update('glpi_'.$this->fields['itemtype'].'tasks', [
- 'state' => 0,
- 'users_id_tech' => 0,
- 'groups_id_tech' => 0,
- 'begin' => null,
- 'end' => null
- ], [
- 'AND' => [
- 'state' => 1,
- 'id' => $sub
- ]
- ]);
- if ($res) {
- $ret = true;
- }
- //$query = "UPDATE glpi_".$this->fields['itemtype']."tasks SET state=0,users_id_tech=0,begin=NULL,end=NULL WHERE state=1 AND id in (select items_id from glpi_plugin_processmaker_tasks where plugin_processmaker_cases_id='".$this->fields['id']."')";
- //if ($DB->query( $query )) {
- // $ret = true;
- //}
- }
- return $ret;
- }
-
-
-
- /**
- * Summary of cancelCase
- * will cancel case and mark 'to_do' tasks associated with this case from the item as information
- * BEWARE that this will only be done when case is in TO_DO status
- * @return true if case and tasks have been cancelled or marked from associated item and from case table
- */
- function cancelCase() {
- global $DB;
- $ret = false;
-
- if (isset($this->fields['case_status']) && $this->fields['case_status'] == "TO_DO") {
- if ($this->cancelTasks()) {
- if ($this->update( [ 'id' => $this->getID(), 'case_status' => 'CANCELLED' ] )) {
- $ret=true;
- }
- }
- }
-
- return $ret;
- }
-
- /**
- * Summary of canSolve
- * To know if a Ticket (Problem or Change) can be solved
- * i.e. the case permits solving of item
- * @param mixed $param is an array containing the item
- * @return bool true to permit solve, false otherwise
- */
- public static function canSolve ($param) {
- $item = $param['item'];
- $cases = self::getIDsFromItem($item->getType(), $item->getID());
- foreach ($cases as $cases_id) {
- $myCase = new self;
- if ($myCase->getFromDB($cases_id)) {
- $pmVar = $myCase->getVariables(['GLPI_ITEM_CAN_BE_SOLVED']);
- if ($myCase->fields['case_status'] != self::COMPLETED
- && $myCase->fields['case_status'] != self::CANCELLED
- && (!isset($pmVar['GLPI_ITEM_CAN_BE_SOLVED']) || $pmVar['GLPI_ITEM_CAN_BE_SOLVED'] != 1)) {
- // then item can't be solved
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Summary of getToDoTasks
- * @param mixed $item is a Ticket, a Problem or a Change
- * @return array list of tasks with status 'to do' for case associated with item
- */
- public static function getToDoTasks($item) {
- $ret = [];
-
- $cases = self::getIDsFromItem($item->getType(), $item->getID());
- foreach ($cases as $cases_id) {
- $ret = $ret + PluginProcessmakerTask::getToDoTasks($cases_id, $item->getType()."Task");
- }
-
- return $ret;
- }
-
-
- /**
- * Summary of getMenuContent
- * @return array
- */
- static function getMenuContent() {
-
- //if (!Session::haveRightsOr('plugin_processmaker_config', [READ, UPDATE])) {
- // return;
- //}
-
- $front_page = "/plugins/processmaker/front";
- $menu = [];
- $menu['title'] = self::getTypeName(Session::getPluralNumber());
- $menu['page'] = "$front_page/case.php";
- $menu['links']['search'] = PluginProcessmakerCase::getSearchURL(false);
- if (Session::haveRightsOr("config", [READ, UPDATE])) {
- $menu['links']['config'] = PluginProcessmakerConfig::getFormURL(false);
- }
-
- $itemtypes = [
- 'PluginProcessmakerCase' => 'cases'
- ];
-
- foreach ($itemtypes as $itemtype => $option) {
- //$menu['options'][$option]['title'] = $itemtype::getTypeName(Session::getPluralNumber());
- $menu['options'][$option]['page'] = $itemtype::getSearchURL(false);
- $menu['options'][$option]['links']['search'] = $itemtype::getSearchURL(false);
- if (Session::haveRightsOr("config", [READ, UPDATE])) {
- $menu['options'][$option]['links']['config'] = PluginProcessmakerConfig::getFormURL(false);
- }
- switch ($itemtype) {
- case 'PluginProcessmakerCase':
- //if ($itemtype::canCreate()) {
- //$menu['options'][$option]['links']['add'] = $itemtype::getFormURL(false);
- //}
- break;
- default :
- $menu['options'][$option]['page'] = PluginProcessmakerProcess::getSearchURL(false);
- break;
- }
-
- }
- return $menu;
- }
-
- /**
- * Summary of getSpecificValueToDisplay
- * @param mixed $field
- * @param mixed $values
- * @param array $options
- * @return mixed
- */
- static function getSpecificValueToDisplay($field, $values, array $options = []) {
- global $PM_DB;
- if (!is_array($values)) {
- $values = [$field => $values];
- }
- switch ($field) {
- case 'id':
- if (isset($options['searchopt']['processmaker_cases'])) {
- switch ($options['searchopt']['processmaker_cases']) {
- case 'creation_date':
- $res = $PM_DB->request('APPLICATION', [
- 'APP_NUMBER' => $values['id']
- ]
- );
- if ($row = $res->next()) {
- return Html::convDateTime($row['APP_CREATE_DATE']);
- }
- //$res = $PM_DB->query('SELECT * FROM APPLICATION WHERE APP_NUMBER = '.$values['id']);
- //if ($res->num_rows > 0) {
- // $row = $PM_DB->fetch_assoc($res);
- // return Html::convDateTime($row['APP_CREATE_DATE']);
- //}
- //$locCase = new self;
- //$locCase->getFromDB($values['id']);
- //$caseInfo = $locCase->getCaseInfo();
- //return Html::convDateTime($caseInfo->createDate);
- break;
- case 'update_date':
- $res = $PM_DB->request('APPLICATION', [
- 'APP_NUMBER' => $values['id']
- ]
- );
- if ($row = $res->next()) {
- return Html::convDateTime($row['APP_UPDATE_DATE']);
- }
- //$res = $PM_DB->query('SELECT * FROM APPLICATION WHERE APP_NUMBER = '.$values['id']);
- //if ($res->num_rows > 0) {
- // $row = $PM_DB->fetch_assoc($res);
- // return Html::convDateTime($row['APP_UPDATE_DATE']);
- //}
- //$locCase = new self;
- //$locCase->getFromDB($values['id']);
- //$caseInfo = $locCase->getCaseInfo();
- //return Html::convDateTime($caseInfo->updateDate);
- break;
- }
- }
- return '-';
- case 'items_id':
- // show an item link
- $item = new $values['itemtype'];
- $item->getFromDB($values['items_id']);
- return $item->getLink(['forceid' => 1]);
-
- case 'case_status':
- return self::getStatus($values['case_status']);
-
- case 'itemtype':
- return self::getItemtype($values['itemtype']);
-
- case 'plugin_processmaker_processes_id':
- $item = new PluginProcessmakerProcess;
- $item->getFromDB($values['plugin_processmaker_processes_id']);
- return $item->getLink();
-
- case 'plugin_processmaker_cases_id':
- if ($values['plugin_processmaker_cases_id'] != 0) {
- $locSCase = new self;
- $locSCase->getFromDB($values['plugin_processmaker_cases_id']);
- return $locSCase->getLink(['forceid' => 1]);
- }
- return '-';
-
- default:
- return parent::getSpecificValueToDisplay($field, $values, $options);
- }
- }
-
-
- static function getSpecificValueToSelect($field, $name = '', $values = '', array $options = []) {
-
- if (!is_array($values)) {
- $values = [$field => $values];
- }
- $options['display'] = false;
-
- switch ($field) {
- case 'case_status':
- $options['name'] = $name;
- $options['value'] = $values[$field];
- return self::dropdownStatus($options);
- case 'itemtype':
- $options['name'] = $name;
- $options['value'] = $values[$field];
- return self::dropdownItemtype($options);
- case 'plugin_processmaker_processes_id':
- $options['name'] = $name;
- $options['value'] = $values[$field];
- $options['specific_tags'] = ['process_restrict' => 0];
- return PluginProcessmakerProcess::dropdown($options);
-
- default:
- return parent::getSpecificValueToSelect($field, $name, $values, $options);
- }
- }
-
-
- static function dropdownStatus(array $options = []) {
-
- $p['name'] = 'case_status';
- $p['value'] = self::TO_DO;
- $p['showtype'] = 'normal';
- $p['display'] = true;
-
- if (is_array($options) && count($options)) {
- foreach ($options as $key => $val) {
- $p[$key] = $val;
- }
- }
-
- switch ($p['showtype']) {
- //case 'allowed' :
- // $tab = static::getAllowedStatusArray($p['value']);
- // break;
-
- case 'search' :
- $tab = static::getAllStatusArray(true);
- break;
-
- default :
- $tab = static::getAllStatusArray(false);
- break;
- }
-
- return Dropdown::showFromArray($p['name'], $tab, $p);
- }
-
-
- static function getAllStatusArray($withmetaforsearch = false) {
-
- $tab = [self::DRAFT => _x('case_status', 'Draft', 'processmaker'),
- self::TO_DO => _x('case_status', 'To do', 'processmaker'),
- self::COMPLETED => _x('case_status', 'Completed', 'processmaker'),
- self::CANCELLED => _x('case_status', 'Cancelled', 'processmaker')];
-
- return $tab;
- }
-
- static function getStatus($value) {
-
- $tab = static::getAllStatusArray(true);
- // Return $value if not defined
- return (isset($tab[$value]) ? $tab[$value] : $value);
- }
-
- static function dropdownItemtype(array $options = []) {
-
- $p['name'] = 'itemtype';
- $p['value'] = 'Ticket';
- $p['showtype'] = 'normal';
- $p['display'] = true;
-
- if (is_array($options) && count($options)) {
- foreach ($options as $key => $val) {
- $p[$key] = $val;
- }
- }
-
- switch ($p['showtype']) {
- //case 'allowed' :
- // $tab = static::getAllowedStatusArray($p['value']);
- // break;
-
- case 'search' :
- $tab = static::getAllItemtypeArray(true);
- break;
-
- default :
- $tab = static::getAllItemtypeArray(false);
- break;
- }
-
- return Dropdown::showFromArray($p['name'], $tab, $p);
- }
-
-
- static function getAllItemtypeArray($withmetaforsearch = false) {
-
- $tab = ['Change' => Change::getTypeName(1),
- 'Ticket' => Ticket::getTypeName(1),
- 'Problem' => Problem::getTypeName(1)
- ];
-
- return $tab;
- }
-
-
- static function getItemtype($value) {
- $tab = static::getAllItemtypeArray(true);
- // Return $value if not defined
- return (isset($tab[$value]) ? $tab[$value] : $value);
- }
-
-
- /**
- * Get default values to search engine to override
- **/
- static function getDefaultSearchRequest() {
-
- $search = ['sort' => 1,
- 'order' => 'DESC'];
-
- return $search;
- }
-
-
- /**
- * Summary of rawSearchOptions
- * @return mixed
- */
- function rawSearchOptions() {
- $tab = [];
-
- $tab[] = [
- 'id' => 'common',
- 'name' => __('Process cases', 'processmaker')
- ];
-
- $tab[] = [
- 'id' => '1',
- 'table' => $this->getTable(),
- 'field' => 'id',
- 'name' => __('ID'),
- 'datatype' => 'number',
- 'searchtype' => 'contains',
- 'massiveaction' => false
- ];
-
- $tab[] = [
- 'id' => '2',
- 'table' => $this->getTable(),
- 'field' => 'name',
- 'name' => __('Title'),
- 'datatype' => 'itemlink',
- 'searchtype' => 'contains',
- 'massiveaction' => false
- ];
-
- $tab[] = [
- 'id' => '3',
- 'table' => $this->getTable(),
- 'field' => 'plugin_processmaker_processes_id',
- 'name' => __('Process', 'processmaker'),
- 'datatype' => 'specific',
- 'searchtype' => [
- '0' => 'contains',
- '1' => 'equals',
- '2' => 'notequals'
- ],
- 'massiveaction' => false
- ];
-
- $tab[] = [
- 'id' => '7',
- 'table' => $this->getTable(),
- 'field' => 'itemtype',
- 'name' => __('Item type'),
- 'massiveaction' => false,
- 'datatype' => 'specific',
- 'searchtype' => [
- '0' => 'contains',
- '1' => 'equals',
- '2' => 'notequals'
- ]
- ];
-
- $tab[] = [
- 'id' => '8',
- 'table' => $this->getTable(),
- 'field' => 'items_id',
- 'name' => __('Item'),
- 'massiveaction' => false,
- 'datatype' => 'specific',
- 'additionalfields' => [
- '0' => 'itemtype'
- ]
- ];
-
- $tab[] = [
- 'id' => '9',
- 'table' => 'glpi_entities',
- 'field' => 'name',
- 'name' => __('Item entity', 'processmaker'),
- 'massiveaction' => false,
- 'datatype' => 'itemlink'
- ];
-
- $tab[] = [
- 'id' => '10',
- 'table' => $this->getTable(),
- 'field' => 'case_status',
- 'name' => __('Status'),
- 'datatype' => 'specific',
- 'searchtype' => [
- '0' => 'contains',
- '1' => 'equals',
- '2' => 'notequals'
- ],
- 'massiveaction' => false
- ];
-
- $tab[] = [
- 'id' => '14',
- 'table' => $this->getTable(),
- 'field' => 'plugin_processmaker_cases_id',
- 'name' => __('Sub-case of', 'processmaker'),
- 'datatype' => 'specific',
- 'massiveaction' => false,
- 'nosearch' => true
- ];
-
- $tab[] = [
- 'id' => '16',
- 'table' => $this->getTable(),
- 'field' => 'id',
- 'name' => __('Creation date'),
- 'datatype' => 'specific',
- 'massiveaction' => false,
- 'nosearch' => true,
- 'processmaker_cases' => 'creation_date'
- ];
-
- $tab[] = [
- 'id' => '18',
- 'table' => $this->getTable(),
- 'field' => 'id',
- 'name' => __('Last update'),
- 'datatype' => 'specific',
- 'massiveaction' => false,
- 'nosearch' => true,
- 'processmaker_cases' => 'update_date'
- ];
-
- return $tab;
- }
-
-
- function showForm ($ID, $options = ['candel'=>false]) {
- $options['colspan'] = 6;
- $options['formtitle'] = sprintf( __('Case status is \'%s\'', 'processmaker'), self::getStatus($this->fields['case_status']));
-
- $this->showFormHeader($options);
-
- $process = new PluginProcessmakerProcess;
- $process->getFromDB($this->fields['plugin_processmaker_processes_id']);
-
- if ($process->fields['maintenance']) {
- PluginProcessmakerProcess::showUnderMaintenance($process->fields['name'], 'small');
- }
- self::showCaseInfoTab($this);
-
- //echo '
' ;
-
- Html::closeForm();
- $options['candel'] = true;
- $this->showFormButtons($options);
-
- echo Html::scriptBlock("
- $('#tabsbody th').css('text-align', 'center');
- $('#tabsbody td').css('text-align', 'center');
- ");
- }
-
-
- /**
- * Summary of defineTabs
- * @param mixed $options
- * @return array
- */
- function defineTabs($options = []) {
-
- $process = new PluginProcessmakerProcess;
- $process->getFromDB($this->fields['plugin_processmaker_processes_id']);
-
- $ong = [];
- if (self::isLayoutWithMain()) {
- $this->addDefaultFormTab($ong);
- }
-
- if (!$process->fields['maintenance']) {
- $this->addStandardTab('PluginProcessmakerTask', $ong, $options);
- }
-
- if (!self::isLayoutWithMain()) {
- $this->addStandardTab(__CLASS__, $ong, $options);
- }
-
- if (!$process->fields['maintenance']) {
- $this->addStandardTab('PluginProcessmakerCasemap', $ong, $options);
-
- $this->addStandardTab('PluginProcessmakerCasehistory', $ong, $options);
-
- $this->addStandardTab('PluginProcessmakerCasechangelog', $ong, $options);
-
- $this->addStandardTab('PluginProcessmakerCasedynaform', $ong, $options);
- }
-
- return $ong;
- }
-
- /**
- * Actions done after the PURGE of the item in the database
- *
- * @return nothing
- **/
-
- /**
- * Summary of post_purgeItem
- * Actions done after the PURGE of the item in the database
- * Will purge the tasks and the PM case and recursively the sub-cases if any
- * @return boolean|integer
- */
- function post_purgeItem() {
- global $PM_SOAP;
- $ret = false;
-
- $PM_SOAP->login(true);
- if ($this->deleteTasks() && $this->deleteCronTaskActions() && $PM_SOAP->deleteCase($this->fields['case_guid'])->status_code == 0) {
- $ret = true;
- $dbu = new DbUtils;
- // then must delete any sub-processes (sub-cases)
- $restrict = ["plugin_processmaker_cases_id" => $this->getID()];
- //foreach ($dbu->getAllDataFromTable(self::getTable(), "`plugin_processmaker_cases_id` = ".$this->getID()) as $row) {
- foreach ($dbu->getAllDataFromTable(self::getTable(), $restrict) as $row) {
- $tmp = new self;
- $tmp->fields = $row;
- $ret &= $tmp->delete(['id' => $row['id']]);
- }
- }
- return $ret;
- }
-
-
- /**
- * Summary of deleteCronTaskActions
- * Will delete any cron task actions taht are linked to current case
- */
- function deleteCronTaskActions() {
- global $DB;
-
- return $DB->delete('glpi_plugin_processmaker_crontaskactions', [
- 'plugin_processmaker_cases_id' => $this->getID()
- ]
- );
- //$query = "DELETE FROM `glpi_plugin_processmaker_crontaskactions` WHERE `plugin_processmaker_cases_id` = ".$this->getID();
- //return $DB->query($query);
- }
-
-}
+fields['plugin_processmaker_cases_id'] == 0
+ && $this->canDeleteItem()
+ && (self::canDelete() || $this->fields['case_status'] == PluginProcessmakerCase::DRAFT);
+ }
+
+ static function canCancel() {
+ return plugin_processmaker_haveRight('case', CANCEL);
+ }
+
+ /**
+ * Summary of getTabNameForItem
+ * @param CommonGLPI $item is the item
+ * @param mixed $withtemplate has template
+ * @return array os strings
+ */
+ function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
+ if ($item->getType() == __CLASS__) {
+ // get tab name for a case itself
+ $tabname = __('Case', 'processmaker');
+ if ($item->fields['plugin_processmaker_cases_id'] > 0) {
+ // case is a sub-case
+ $tabname = __('Sub-case', 'processmaker');
+ }
+ return [ 'main' => $tabname."
".self::getStatus($item->fields['case_status']).""];
+ } else {
+ $items_id = $item->getID();
+ $itemtype = $item->getType();
+
+ // count how many cases are on this item
+ $cnt = count(self::getIDsFromItem($itemtype, $items_id));
+ $tab = self::getTypeName(2); // to force plurial for tab name
+ if ($cnt) {
+ $tab .= "
$cnt";
+ }
+ return ['processmakercases' => $tab];
+ }
+ }
+
+
+ /**
+ * Summary of getName
+ * @param mixed $options
+ * @return mixed
+ */
+ function getName($options = []) {
+ return $this->fields['name'];
+ }
+
+
+ /**
+ * Summary of getIDFromItem
+ * @param string $itemtype is the item type
+ * @param integer $items_id is the item id
+ * @return integer cases_id
+ */
+ //static function getIDFromItem($itemtype, $items_id) {
+ // $tmp = New self;
+ // if ($tmp->getFromDBByQuery(" WHERE items_id=$items_id and itemtype='$itemtype'")) {
+ // return $tmp->getID();
+ // }
+ // return false;
+ //}
+
+
+ /**
+ * Summary of getIDsFromItem
+ * returns an array of the case ids linked to the item
+ * @param string $itemtype is the item type of the item (Ticket, Problem, Change)
+ * @param mixed $items_id is the GLPI id of the item in the type
+ * @return array
+ */
+ static function getIDsFromItem($itemtype, $items_id) {
+ $ret = [];
+ $dbu = new DbUtils;
+ $restrict = [
+ "items_id" => $items_id,
+ "itemtype" => $itemtype,];
+
+ //foreach ($dbu->getAllDataFromTable( self::getTable(), "items_id=$items_id AND itemtype='$itemtype'") as $case)
+ foreach ($dbu->getAllDataFromTable( self::getTable(), $restrict) as $case) {
+ $ret[] = $case['id'];
+ }
+ return $ret;
+ }
+
+ /**
+ * Summary of getFromItem
+ * @param mixed $itemtype is the item type
+ * @param mixed $items_id is the item id
+ * @return mixed: returns false when there is no case associated with the item, else fills in the item fields from DB, and returns true
+ */
+ //function getFromItem($itemtype, $items_id) {
+ // return $this->getFromDBByQuery(" WHERE items_id=$items_id and itemtype='$itemtype'");
+ //}
+
+
+ /**
+ * Summary of getFromGUID
+ * @param mixed $case_guid
+ * @return boolean
+ */
+ function getFromGUID($case_guid) {
+ $restrict=[
+ 'WHERE' => [
+ 'case_guid' => $case_guid,
+ ],
+ ];
+ return $this->getFromDBByRequest($restrict);
+ }
+
+
+ /**
+ * Summary of getVariables
+ * @param mixed $vars
+ * @return mixed
+ */
+ function getVariables($vars = []) {
+ global $PM_SOAP;
+ return $PM_SOAP->getVariables($this->fields['case_guid'], $vars);
+ }
+
+
+ /**
+ * Summary of sendVariables
+ * @param mixed $vars
+ * @return A
+ */
+ function sendVariables($vars = []) {
+ global $PM_SOAP;
+ return $PM_SOAP->sendVariables($this->fields['case_guid'], $vars);
+ }
+
+
+ /**
+ * Summary of getCaseInfo
+ * @param mixed $delIndex
+ * @return stdClass, a getCaseInfoResponse object, or false exception occured
+ */
+ function getCaseInfo($delIndex = '') {
+ global $PM_SOAP;
+ return $PM_SOAP->getCaseInfo($this->fields['case_guid'], $delIndex);
+ }
+
+
+ /**
+ * Summary of unpauseCase
+ * @param mixed $delIndex
+ * @param mixed $userGuid
+ * @return an
+ */
+ function unpauseCase($delIndex, $userGuid) {
+ global $PM_SOAP;
+ return $PM_SOAP->unpauseCase($this->fields['case_guid'], $delIndex, $userGuid);
+ }
+
+
+ /**
+ * Summary of unassignCase
+ * Will unassign the delIndex task, restoring the assigned group
+ * @param $delIndex int the delegation index
+ * @param $taskGuid string the GUID of the task
+ * @param $tasktype string the type of task (TicketTask, ChangeTask, ProblemTask)
+ * @param $tasks_id int the id of the task
+ * @param $itemtype string the type of the ITIL object (Ticket, Change, Problem)
+ * @return bool
+ */
+ function unassignCase($delIndex, $taskGuid, $tasktype, $tasks_id, $itemtype, $options) {
+ global $PM_DB, $PM_SOAP, $DB;
+
+ // un-claim task
+ // will unclaim the task
+ // to unclaim a task, we must un-assign the task in the APP_DELEGATION table
+ // and un-assign the task in glpi_itemtypeTask table
+
+ $groups_id_tech = $PM_SOAP->getGLPIGroupIdForSelfServiceTask($this->fields['case_guid'], $taskGuid);
+
+ if ($groups_id_tech !== false) {
+ // unclaim the case only when a GLPI group can be found
+
+ $query = "UPDATE APP_DELEGATION SET USR_UID='', DEL_INIT_DATE=NULL, USR_ID=0 WHERE APP_NUMBER=".$this->getID()." AND DEL_INDEX=$delIndex;";
+ $PM_DB->query($query);
+
+ $glpi_task = new $tasktype;
+ $glpi_task->getFromDB($tasks_id);
+ $foreignkey = getForeignKeyFieldForItemType( $itemtype );
+
+ $donotif = PluginProcessmakerNotificationTargetProcessmaker::saveNotificationState(false); // do not send notification yet
+ $glpi_task->update( ['id' => $glpi_task->getID(),
+ $foreignkey => $glpi_task->fields[$foreignkey],
+ 'users_id_tech' => 0,
+ 'groups_id_tech' => $groups_id_tech['id'],
+ 'update' => true] );
+ PluginProcessmakerNotificationTargetProcessmaker::restoreNotificationState($donotif);
+
+ // send notification now!
+ $pm_task = new PluginProcessmakerTask($tasktype);
+ $pm_task->getFromDB($tasks_id);
+ $glpi_item = new $itemtype;
+ $glpi_item->getFromDB($glpi_task->fields[$foreignkey]);
+ $pm_task->sendNotification('task_unclaim', $glpi_task, $glpi_item, $this);
+
+ // create an information task and add comment
+ $pm_process = $this->getProcess();
+ $dbu = new DbUtils;
+ $info = __('
Task un-claimed!Case: %s
Task: "%s" has been un-assigned from "%s" and assigned to "%s" group.
Reason: %s', 'processmaker');
+ $info .= "
";
+ $taskCat = new TaskCategory;
+ $taskCat->getFromDB( $glpi_task->fields['taskcategories_id'] );
+ $info = sprintf($info,
+ $this->getNameID(['forceid' => true]),
+ DropdownTranslation::getTranslatedValue($glpi_task->fields['taskcategories_id'], 'TaskCategory', 'name', $_SESSION['glpilanguage'], $taskCat->fields['name']),
+ Html::clean($dbu->getUserName(isset($glpi_task->oldvalues['users_id_tech']) ? $glpi_task->oldvalues['users_id_tech'] : 0)),
+ Html::clean($groups_id_tech['name']),
+ $options['comment']
+ );
+ // unescape some chars and replace CRLF, CR or LF by
+ $info = str_replace(["\\'", '\\"', '\r\n', '\r', '\n'], ["'", '"', '
', '
', '
'], $info);
+
+ $glpi_task->add([$foreignkey => $glpi_task->fields[$foreignkey],
+ 'is_private' => 0, // a post-only user can't create private task
+ 'taskcategories_id' => $pm_process->fields['taskcategories_id'],
+ 'content' => $DB->escape($info),
+ 'users_id' => $PM_SOAP->taskWriter,
+ 'state' => Planning::INFO,
+ 'users_id_tech' => Session::getLoginUserID(),
+ ]);
+
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Summary of reassignCase
+ * @param mixed $delIndex
+ * @param mixed $taskGuid
+ * @param mixed $delThread
+ * @param mixed $users_id_source
+ * @param mixed $users_id_target
+ * @return mixed
+ */
+ function reassignCase($delIndex, $taskGuid, $delThread, $users_id_source, $users_id_target, $options) {
+ global $PM_SOAP;
+ $users_guid_source = ''; // by default
+ if ($users_id_source !== 0) { // when task is not 'to be claimed'
+ $users_guid_source = PluginProcessmakerUser::getPMUserId($users_id_source);
+ }
+ $users_guid_target = PluginProcessmakerUser::getPMUserId($users_id_target);
+ $pmResponse = $PM_SOAP->reassignCase($this->fields['case_guid'], $delIndex, $users_guid_source, $users_guid_target);
+ // now should manage GLPI Tasks previously assigned to the $users_guid_source
+ if ($pmResponse->status_code == 0) {
+ // we need to change the delindex of the glpi task and the assigned tech to prevent creation of new tasks
+ // we need the delindex of the current glpi task, and the delindex of the new one
+ // search for new delIndex and new delThread
+ $newCaseInfo = $this->getCaseInfo( );
+ $newDelIndex = 0;
+ $newDelThread = 0;
+ foreach ($newCaseInfo->currentUsers as $newCaseUser) {
+ if ($newCaseUser->taskId == $taskGuid && $newCaseUser->delThread == $delThread) {
+ $newDelIndex = $newCaseUser->delIndex;
+ $newDelThread = $newCaseUser->delThread;
+ break;
+ }
+ }
+ $this->reassignTask($delIndex, $newDelIndex, $delThread, $newDelThread, $users_id_target, $options);
+ return true;
+ }
+ return false;
+ }
+
+
+ /**
+ * Summary of reassignTask
+ * @param mixed $delIndex
+ * @param mixed $newDelIndex
+ * @param mixed $newTech
+ */
+ public function reassignTask ($delIndex, $newDelIndex, $delThread, $newDelThread, $newTech, $options) {
+ global $DB, $PM_SOAP;
+
+ $dbu = new DbUtils;
+ $pm_task_row = $dbu->getAllDataFromTable(PluginProcessmakerTask::getTable(), ['plugin_processmaker_cases_id' => $this->getID(), 'del_index' => $delIndex, 'del_thread' => $delThread]);
+ if ($pm_task_row && count($pm_task_row) == 1) {
+ $pm_task_row = array_shift($pm_task_row);
+ $glpi_task = new $pm_task_row['itemtype'];
+ $glpi_task->getFromDB($pm_task_row['items_id']);
+
+ $itilobject_itemtype = $this->fields['itemtype'];
+ $foreignkey = getForeignKeyFieldForItemType( $itilobject_itemtype );
+
+ PluginProcessmakerProcessmaker::addWatcher( $itilobject_itemtype, $glpi_task->fields[ $foreignkey ], $newTech );
+
+ $donotif = PluginProcessmakerNotificationTargetProcessmaker::saveNotificationState(false); // do not send notification yet
+ $glpi_task->update( ['id' => $glpi_task->getID(),
+ $foreignkey => $glpi_task->fields[$foreignkey],
+ 'users_id_tech' => $newTech,
+ 'groups_id_tech' => 0,
+ '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']
+ ]
+ );
+
+ // send notification now!
+ $pm_task = new PluginProcessmakerTask($pm_task_row['itemtype']);
+ $pm_task->getFromDB($pm_task_row['items_id']);
+ $glpi_item = new $itilobject_itemtype;
+ $glpi_item->getFromDB($glpi_task->fields[$foreignkey]);
+ $pm_task->sendNotification('task_reassign', $glpi_task, $glpi_item, $this);
+
+ // create an information task and add comment
+ $pm_process = $this->getProcess();
+ $old_users_tech_id = isset($glpi_task->oldvalues['users_id_tech']) ? $glpi_task->oldvalues['users_id_tech'] : 0;
+ $taskCat = new TaskCategory;
+ $taskCat->getFromDB( $glpi_task->fields['taskcategories_id'] );
+ $task_name = DropdownTranslation::getTranslatedValue($glpi_task->fields['taskcategories_id'], 'TaskCategory', 'name', $_SESSION['glpilanguage'], $taskCat->fields['name']);
+ $new_tech_name = Html::clean($dbu->getUserName($newTech));
+ if ($old_users_tech_id) {
+ $info = __('
Task re-assigned!Case: %s
Task: "%s" has been re-assigned from "%s" to "%s".
Reason: %s', 'processmaker');
+ $info = sprintf($info,
+ $this->getNameID(['forceid' => true]),
+ $task_name,
+ Html::clean($dbu->getUserName(isset($glpi_task->oldvalues['users_id_tech']) ? $glpi_task->oldvalues['users_id_tech'] : 0)),
+ $new_tech_name,
+ $options['comment']
+ );
+ } else {
+ $info = __('
Task assigned!Case: %s
Task: "%s" has been assigned to "%s".
Reason: %s', 'processmaker');
+ $info = sprintf($info,
+ $this->getNameID(['forceid' => true]),
+ $task_name,
+ $new_tech_name,
+ $options['comment']
+ );
+ }
+ $info .= "
";
+
+ // unescape some chars and replace CRLF, CR or LF by
+ $info = str_replace(["\\'", '\\"', '\r\n', '\r', '\n'], ["'", '"', '
', '
', '
'], $info);
+
+ $glpi_task->add([$foreignkey => $glpi_task->fields[$foreignkey],
+ 'is_private' => 0, // a post-only user can't create private task
+ 'taskcategories_id' => $pm_process->fields['taskcategories_id'],
+ 'content' => $DB->escape($info),
+ 'users_id' => $PM_SOAP->taskWriter,
+ 'state' => Planning::INFO,
+ 'users_id_tech' => Session::getLoginUserID(),
+ ]);
+ }
+ }
+
+
+ /**
+ * Summary of getProcess
+ * Returns process object
+ * @return bool|PluginProcessmakerProcess
+ */
+ function getProcess() {
+ $pm_process = new PluginProcessmakerProcess;
+ if (!$this->process && $pm_process->getFromDB($this->fields['plugin_processmaker_processes_id'])) {
+ $this->process = $pm_process;
+ }
+ return $this->process;
+ }
+
+ /**
+ * Summary of showCaseProperties
+ */
+ function showCaseProperties() {
+ global $DB, $PM_DB;
+
+ // get all tasks that are OPEN for any sub-case of this case
+ $case_tasks = [];
+ $res = $DB->request('glpi_plugin_processmaker_tasks', [
+ 'AND' => [
+ 'plugin_processmaker_cases_id' => $this->getID(),
+ 'del_thread_status' => 'OPEN'
+ ]
+ ]);
+ foreach ($res as $task) {
+ $case_tasks[$task['del_index']] = $task;
+ }
+ //$query = "SELECT `glpi_plugin_processmaker_tasks`.* FROM `glpi_plugin_processmaker_tasks`
+ // WHERE `glpi_plugin_processmaker_tasks`.`plugin_processmaker_cases_id`={$this->getID()} AND `del_thread_status`='OPEN'";
+ //foreach ($DB->request($query) as $task) {
+ // $case_tasks[$task['del_index']] = $task;
+ //}
+
+ //// get all tasks that are OPEN for any sub-case of this case
+ //$sub_cases = [];
+ //$query = "SELECT `glpi_plugin_processmaker_tasks`.* FROM `glpi_plugin_processmaker_tasks`
+ // JOIN `glpi_plugin_processmaker_cases` on `glpi_plugin_processmaker_cases`.`id`=`glpi_plugin_processmaker_tasks`.`plugin_processmaker_cases_id`
+ // WHERE `glpi_plugin_processmaker_cases`.`plugin_processmaker_cases_id`={$this->getID()} AND `del_thread_status`='OPEN'";
+ //foreach($DB->request($query) as $task) {
+ // $sub_cases[$task['plugin_processmaker_cases_id']][$task['del_index']] = $task;
+ //}
+
+ $caseInfo = $this->getCaseInfo();
+ if (property_exists($caseInfo, 'currentUsers')) {
+ $caseInfo->currentUsers = $this->sortTasks($caseInfo->currentUsers, PluginProcessmakerUser::getPMUserId(Session::getLoginUserID()));
+ }
+ $res = $PM_DB->request([
+ 'SELECT' => ['DEL_INDEX', 'DEL_DELEGATE_DATE'],
+ 'FROM' => 'APP_DELEGATION',
+ 'WHERE' => ['APP_UID' => $caseInfo->caseId]
+ ]);
+ //$query = "SELECT `DEL_INDEX`, `DEL_DELEGATE_DATE` FROM `APP_DELEGATION` WHERE `APP_UID`='{$caseInfo->caseId}'";
+ $tasks = [];
+ foreach ($res as $row) {
+ $tasks[$row['DEL_INDEX']] = $row['DEL_DELEGATE_DATE'];
+ }
+ //foreach ($PM_DB->request($query) as $row) {
+ // $tasks[$row['DEL_INDEX']] = $row['DEL_DELEGATE_DATE'];
+ //}
+
+ echo "
";
+ // show the case properties like given by PM server
+ $this->showShort($caseInfo);
+
+ // show current (running) tasks properties
+ echo "
";
+
+ echo "
";
+ echo "
";
+
+ echo "| ".__('Current task(s) properties', 'processmaker')." |
";
+
+ if (property_exists($caseInfo, 'currentUsers') && count($caseInfo->currentUsers) > 0) {
+ echo "
+ | ".__('Task', 'processmaker')." |
+ ".__('Task guid', 'processmaker')." |
+ ".__('Current user', 'processmaker')." |
+ ".__('Task delegation date', 'processmaker')." |
+
";
+ foreach ($caseInfo->currentUsers as $currentTask) {
+ $case_url = $this->getLinkURL().'&forcetab=PluginProcessmakerTask$';
+ echo "";
+ if (isset($case_tasks[$currentTask->delIndex])) {
+ $case_url .= $case_tasks[$currentTask->delIndex]['id'];
+ echo "| ".$currentTask->taskName." | ";
+ } else {
+ $res = $PM_DB->request([
+ 'SELECT' => 'APP_UID',
+ 'FROM' => 'SUB_APPLICATION',
+ 'WHERE' => [
+ 'AND' => [
+ 'APP_PARENT' => $this->fields['case_guid'],
+ 'DEL_INDEX_PARENT' => $currentTask->delIndex,
+ 'SA_STATUS' => 'ACTIVE'
+ ]
+ ]
+ ]);
+ //$res = $PM_DB->query("SELECT APP_UID FROM SUB_APPLICATION WHERE APP_PARENT='{$this->fields['case_guid']}' AND DEL_INDEX_PARENT={$currentTask->delIndex} AND SA_STATUS='ACTIVE'");
+ //if ($res && $PM_DB->numrows($res) == 1) {
+ // $row = $PM_DB->fetch_assoc($res);
+ if ($res->numrows() == 1 && $row = $res->next()) {
+ $sub_case = new PluginProcessmakerCase;
+ $sub_case->getFromGUID($row['APP_UID']);
+ $case_url .= $sub_case->getID()."-".$currentTask->delIndex;
+ echo "> ".$currentTask->taskName." | ";
+ } else {
+ echo "".$currentTask->taskName." | ";
+ }
+ }
+ echo "".$currentTask->taskId." | ";
+ if ($currentTask->userName == '') {
+ echo "".__('To be claimed', 'processmaker')." | ";
+ } else {
+ echo "".$currentTask->userName." | ";
+ }
+ echo "".Html::convDateTime($tasks[$currentTask->delIndex])." | ";
+ echo "
";
+ }
+ } else {
+ echo "".__('None')." | ";
+ }
+
+ echo "
";
+
+ echo "
";
+
+ // show the parent case if it's a sub-case
+ if ($this->fields['plugin_processmaker_cases_id'] > 0) {
+ echo "
";
+ $sub_case = new self;
+ $sub_case->getFromDB($this->fields['plugin_processmaker_cases_id']);
+ $sub_case->showShort($sub_case->getCaseInfo(), true);
+ }
+
+ }
+
+ /**
+ * Summary of showShort
+ * @param mixed $caseInfo
+ * @param mixed $showparenturl
+ */
+ function showShort($caseInfo, $showparenturl = false) {
+
+ echo "
";
+ echo "
";
+
+ if ($this->fields['plugin_processmaker_cases_id'] > 0) {
+ echo "| ".__('Sub-case properties', 'processmaker')." |
";
+ } else {
+ if ($showparenturl) {
+ echo "| ".__('Parent case properties', 'processmaker')." |
";
+ } else {
+ echo "| ".__('Case properties', 'processmaker')." |
";
+ }
+ }
+
+ echo "";
+ echo "| ".__('Process', 'processmaker')." | ";
+ echo "".__('Case title', 'processmaker')." | ";
+ echo "".__('Case number', 'processmaker')." | ";
+ echo "".__('Case status', 'processmaker')." | ";
+ echo "".__('Case guid', 'processmaker')." | ";
+ echo "".__('Creator', 'processmaker')." | ";
+ echo "".__('Creation date', 'processmaker')." | ";
+ echo "".__('Last update', 'processmaker')." | ";
+ //echo "".__('Case description', 'processmaker')." | ";
+ echo "
";
+
+ echo "";
+ echo "| ".$caseInfo->processName." | ";
+ if ($showparenturl) {
+ echo "".$this->getLink()." | ";
+ } else {
+ echo "".$caseInfo->caseName." | ";
+ }
+ echo "".$caseInfo->caseNumber." | ";
+ echo "".self::getStatus($caseInfo->caseStatus)." | ";
+ echo "".$caseInfo->caseId." | ";
+ echo "".$caseInfo->caseCreatorUserName." | ";
+ echo "".Html::convDateTime($caseInfo->createDate)." | ";
+ echo "".Html::convDateTime($caseInfo->updateDate)." | ";
+ //echo "".$caseInfo->????." | ";
+ echo "
";
+
+ echo "
";
+
+ echo "
";
+
+ }
+
+
+ /**
+ * Summary of localSortTasks
+ * used to sort array of tasks in a currenUsers object
+ * @param mixed $a
+ * @param mixed $b
+ * @return integer
+ */
+ static private function localSortTasks ($a, $b) {
+ return $a->delIndex - $b->delIndex;
+ }
+
+ /**
+ * Summary of sortTasks
+ * @param mixed $tasks is the array of tasks from a getCaseInfo->currentUsers
+ * @param mixed $GLPICurrentPMUserId
+ * @return array sorted $tasks
+ */
+ public function sortTasks($tasks, $GLPICurrentPMUserId) {
+
+ $tbctasks = [];
+ $utasks = [];
+ $infotasks = [];
+
+ foreach ($tasks as $caseUser) {
+ if ($caseUser->userId == $GLPICurrentPMUserId) {
+ $utasks[] = $caseUser;
+ } else {
+ if ($caseUser->userId == '') { // task to be claimed
+ $tbctasks[] = $caseUser;
+ } else {
+ $infotasks[] = $caseUser;
+ }
+ }
+ }
+
+ // order task by "current user", then by "to be claimed", and then push to end "tasks assigned to another user"
+ // then by delindex ASC in these three parts
+ usort($utasks, 'self::localSortTasks');
+ usort($tbctasks, 'self::localSortTasks');
+ usort($infotasks, 'self::localSortTasks');
+
+ return array_merge($utasks, $tbctasks, $infotasks);
+ }
+
+
+ /**
+ * Summary of showCaseInfoTab
+ * Will show information about the current case
+ * @param CommonGLPI $case is a PluginProcessmakerCase object
+ * @param mixed $tabnum
+ * @param mixed $withtemplate
+ */
+ static function showCaseInfoTab(CommonGLPI $case, $tabnum = 1, $withtemplate = 0) {
+ // echo 'The idea is to show here the GLPI ITIL item to which it is linked, and to give a resume of the current case status, and to give possibility to delete or cancel the case.';
+ $itemtype = $case->fields['itemtype'];
+
+ $maintitle = __('Case is linked to a %1s', 'processmaker');
+ if ($case->fields['plugin_processmaker_cases_id'] > 0) {
+ $maintitle = __('Sub-case is linked to a %1s', 'processmaker');
+ }
+
+ echo "
| ".sprintf($maintitle, $itemtype::getTypeName(1))." |
|---|
";
+
+ Ticket::commonListHeader(Search::HTML_OUTPUT);
+
+ $itemtype::showShort($case->fields['items_id']);
+
+ echo "";
+
+ // show case properties
+ $case->showCaseProperties();
+
+ if ($case->fields['plugin_processmaker_cases_id'] == 0 && self::canCancel() && $case->fields['case_status'] == self::TO_DO) {
+
+ // it's a main case, not a sub-case
+ // and we have the rights to cancel cases
+
+ echo "
";
+ echo "
";
+
+ }
+
+ // will not show delete button if case is a sub-process
+ // and will show it only if it is a draft or if current glpi user has the right to delete cases and session is central
+ if ($case->canPurgeItem($case->getID())) {
+
+ // then propose a button to delete case
+ // the button will be effectively shown by the showFormButtons()
+
+ echo "
";
+ echo "
";
+ echo "
";
+
+ }
+
+ return;
+ }
+
+
+ /**
+ * Summary of showForItem
+ * Shows list of cases attached to an item
+ * @param CommonITILObject $item
+ */
+ static function showForItem(CommonITILObject $item) {
+ global $DB, $CFG_GLPI, $PM_SOAP;
+
+ $items_id = $item->getField('id');
+ $itemtype = $item->getType();
+
+
+ $canupdate = $item->can($items_id, UPDATE);
+
+ $rand = mt_rand();
+ $res = $DB->request([
+ 'SELECT' => ['gppc.id AS assocID', 'gppc.id AS id', 'gppp.id AS pid', 'gppp.name AS pname', 'gppc.case_status', 'gppc.plugin_processmaker_cases_id'],
+ 'FROM' => 'glpi_plugin_processmaker_cases AS gppc',
+ 'LEFT JOIN' => [
+ 'glpi_plugin_processmaker_processes AS gppp' => [
+ 'FKEY' => [
+ 'gppp' => 'id',
+ 'gppc' => 'plugin_processmaker_processes_id']
+ ]
+ ],
+ 'WHERE' => [
+ 'AND' => [
+ 'gppc.itemtype' => $itemtype,
+ 'gppc.items_id' => $items_id
+ ]
+ ]
+ ]);
+
+ $cases = [];
+ $used = [];
+ $pid = [];
+ if ($numrows = $res->numrows()) {
+ foreach ($res as $data) {
+ $cases[$data['id']] = $data;
+ $used[$data['id']] = $data['id'];
+ if (isset($pid[$data['pid']])) {
+ $pid[$data['pid']] += 1;
+ } else {
+ $pid[$data['pid']] = 1;
+ }
+ }
+ }
+
+ $columns = ['pname' => __('Process', 'processmaker'),
+ 'name' => __('Title', 'processmaker'),
+ 'status' => __('Status', 'processmaker'),
+ 'sub' => __('Sub-case of', 'processmaker')
+ ];
+
+ // check if item is not solved nor closed
+ if ($canupdate
+ && $item->fields['status'] != CommonITILObject::SOLVED
+ && $item->fields['status'] != CommonITILObject::CLOSED
+ && $_SESSION['glpiactiveprofile']['interface'] != 'helpdesk'
+ && ($numrows < $PM_SOAP->config->fields['max_cases_per_item']
+ || $PM_SOAP->config->fields['max_cases_per_item'] == 0)) {
+ echo "
";
+ }
+
+ echo "
";
+ if ($canupdate && $numrows) {
+ Html::openMassiveActionsForm('mass'.__CLASS__.$rand);
+ $massiveactionparams = ['num_displayed' => $numrows,
+ 'container' => 'mass'.__CLASS__.$rand];
+ Html::showMassiveActions($massiveactionparams);
+ }
+ echo "
";
+ echo "| ".PluginProcessmakerCase::getTypeName($numrows)." | ";
+ echo "
";
+ if ($numrows) {
+ $header_begin = "";
+ $header_top = '';
+ $header_bottom = '';
+ $header_end = '';
+ if ($canupdate
+ && $numrows) {
+ $header_top .= "| ".Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
+ $header_top .= " | ";
+ $header_bottom .= "".Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
+ $header_bottom .= " | ";
+ }
+
+ foreach ($columns as $key => $val) {
+ $header_end .= "$val | ";
+ }
+
+ $header_end .= "
";
+ echo $header_begin.$header_top.$header_end;
+
+ Session::initNavigateListItems('PluginProcessmakerCase',
+ //TRANS : %1$s is the itemtype name,
+ // %2$s is the name of the item (used for headings of a list)
+ sprintf(__('%1$s = %2$s'),
+ $itemtype::getTypeName(1), $item->fields["name"]));
+
+ $i = 0;
+ foreach ($cases as $data) {
+ Session::addToNavigateListItems('PluginProcessmakerCase', $data["id"]);
+ $link = NOT_AVAILABLE;
+ $case = new self;
+ if ($case->getFromDB($data["id"])) {
+ $link = $case->getLink();
+ }
+
+ echo "";
+ if ($canupdate) {
+ echo "| ";
+ // show massive action only for main cases (not for subcases)
+ if ($data['plugin_processmaker_cases_id'] == 0) {
+ Html::showMassiveActionCheckBox(__CLASS__, $data["assocID"]);
+ }
+ echo " | ";
+ }
+ echo "".$data['pname']." | ";
+ echo "".$link." | ";
+ echo "".self::getStatus($data['case_status'])." | ";
+ echo "";
+ if ($data['plugin_processmaker_cases_id'] > 0) {
+ // then this is a subcase of
+ $maincase = new self;
+ if ($maincase->getFromDB($data['plugin_processmaker_cases_id'])) {
+ echo $maincase->getLink();
+ }
+ } else {
+ echo '-';
+ }
+ echo " | ";
+ echo "
";
+
+ $i++;
+ }
+ echo $header_begin.$header_bottom.$header_end;
+
+ }
+
+ echo "
";
+ if ($canupdate && $numrows) {
+ $massiveactionparams['ontop'] = false;
+ Html::showMassiveActions($massiveactionparams);
+ Html::closeForm();
+ }
+ echo "
";
+ }
+
+ /**
+ * Summary of displayTabContentForItem
+ * @param CommonGLPI $item
+ * @param mixed $tabnum
+ * @param mixed $withtemplate
+ */
+ static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
+ global $PM_SOAP;
+
+ if ($item->getType() == __CLASS__) {
+ // we are in a case viewing the main tab
+ // the 'Case infos' tab
+ //self::showCaseInfoTab($item, $tabnum, $withtemplate);
+
+ } else {
+
+ // show the list of cases attached to the $item ITIL object
+ if (!$PM_SOAP->config->fields['maintenance']) {
+ self::showForItem($item);
+ } else {
+ PluginProcessmakerProcessmaker::showUnderMaintenance();
+ }
+ }
+ }
+
+
+ /**
+ * Summary of deleteTasks
+ * will delete all tasks associated with this case from the item
+ * @return true if tasks have been deleted from associated item and from case table
+ */
+ private function deleteTasks() {
+ global $DB;
+ $ret = false;
+ $sub = new QuerySubQuery([
+ 'SELECT' => 'items_id',
+ 'FROM' => 'glpi_plugin_processmaker_tasks',
+ 'WHERE' => ['plugin_processmaker_cases_id' => $this->fields['id']]
+ ]);
+
+ if ($DB->delete('glpi_'.strtolower($this->fields['itemtype']).'tasks', ['id' => $sub ])) {
+ if ($DB->delete('glpi_plugin_processmaker_tasks', ['plugin_processmaker_cases_id' => $this->fields['id']])) {
+ $ret = true;
+ }
+ }
+ //$query = "DELETE FROM glpi_".strtolower($this->fields['itemtype'])."tasks WHERE id IN (SELECT items_id FROM glpi_plugin_processmaker_tasks WHERE plugin_processmaker_cases_id='".$this->fields['id']."')";
+ //if ($DB->query( $query )) {
+ // $query = "DELETE FROM glpi_plugin_processmaker_tasks WHERE plugin_processmaker_cases_id='".$this->fields['id']."'";
+ // if ($DB->query( $query )) {
+ // $ret = true;
+ // }
+ //}
+ return $ret;
+ }
+
+
+ /**
+ * Summary of deleteCase
+ * will delete case and all tasks associated with this case from the item
+ * @return true if case and tasks have been deleted from associated item and from case table
+ */
+ function deleteCase() {
+ return $this->delete(['id' => $this->getID()]);
+ }
+
+
+ /**
+ * Summary of cancelTasks
+ * will mark as information all to_do tasks
+ * BEWARE that this will only be done when case is in TO_DO status
+ * @return true if tasks have been deleted from associated item and from case table
+ */
+ private function cancelTasks() {
+ global $DB;
+ $ret = false;
+
+ if (isset($this->fields['case_status']) && $this->fields['case_status'] == "TO_DO") {
+ $sub = new QuerySubQuery([
+ 'SELECT' => 'items_id',
+ 'FROM' => 'glpi_plugin_processmaker_tasks',
+ 'WHERE' => ['plugin_processmaker_cases_id' => $this->fields['id']]
+ ]);
+ $res = $DB->update('glpi_'.$this->fields['itemtype'].'tasks', [
+ 'state' => 0,
+ 'users_id_tech' => 0,
+ 'groups_id_tech' => 0,
+ 'begin' => null,
+ 'end' => null
+ ], [
+ 'AND' => [
+ 'state' => 1,
+ 'id' => $sub
+ ]
+ ]);
+ if ($res) {
+ $ret = true;
+ }
+ //$query = "UPDATE glpi_".$this->fields['itemtype']."tasks SET state=0,users_id_tech=0,begin=NULL,end=NULL WHERE state=1 AND id in (select items_id from glpi_plugin_processmaker_tasks where plugin_processmaker_cases_id='".$this->fields['id']."')";
+ //if ($DB->query( $query )) {
+ // $ret = true;
+ //}
+ }
+ return $ret;
+ }
+
+
+
+ /**
+ * Summary of cancelCase
+ * will cancel case and mark 'to_do' tasks associated with this case from the item as information
+ * BEWARE that this will only be done when case is in TO_DO status
+ * @return true if case and tasks have been cancelled or marked from associated item and from case table
+ */
+ function cancelCase() {
+ global $DB;
+ $ret = false;
+
+ if (isset($this->fields['case_status']) && $this->fields['case_status'] == "TO_DO") {
+ if ($this->cancelTasks()) {
+ if ($this->update( [ 'id' => $this->getID(), 'case_status' => 'CANCELLED' ] )) {
+ $ret=true;
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Summary of canSolve
+ * To know if a Ticket (Problem or Change) can be solved
+ * i.e. the case permits solving of item
+ * @param mixed $param is an array containing the item
+ * @return bool true to permit solve, false otherwise
+ */
+ public static function canSolve ($param) {
+ $item = $param['item'];
+ $cases = self::getIDsFromItem($item->getType(), $item->getID());
+ foreach ($cases as $cases_id) {
+ $myCase = new self;
+ if ($myCase->getFromDB($cases_id)) {
+ $pmVar = $myCase->getVariables(['GLPI_ITEM_CAN_BE_SOLVED']);
+ if ($myCase->fields['case_status'] != self::COMPLETED
+ && $myCase->fields['case_status'] != self::CANCELLED
+ && (!isset($pmVar['GLPI_ITEM_CAN_BE_SOLVED']) || $pmVar['GLPI_ITEM_CAN_BE_SOLVED'] != 1)) {
+ // then item can't be solved
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Summary of getToDoTasks
+ * @param mixed $item is a Ticket, a Problem or a Change
+ * @return array list of tasks with status 'to do' for case associated with item
+ */
+ public static function getToDoTasks($item) {
+ $ret = [];
+
+ $cases = self::getIDsFromItem($item->getType(), $item->getID());
+ foreach ($cases as $cases_id) {
+ $ret = $ret + PluginProcessmakerTask::getToDoTasks($cases_id, $item->getType()."Task");
+ }
+
+ return $ret;
+ }
+
+
+ //static function getIcon() {
+ // // return "fas fa-code-branch fa-rotate-90";
+ // return "fas fa-blog fa-flip-vertical";
+ // // return "fas fa-cogs fa-flip-vertical";
+ //}
+
+
+ /**
+ * Summary of getMenuContent
+ * @return array
+ */
+ static function getMenuContent() {
+
+ if (!Session::haveRightsOr('plugin_processmaker_case', [READ, DELETE, CANCEL, ADHOC_REASSIGN])) {
+ return [];
+ }
+
+ $front_page = "/plugins/processmaker/front";
+ $menu = [];
+ $menu['title'] = self::getTypeName(Session::getPluralNumber());
+ $menu['page'] = "$front_page/case.php";
+ $menu['icon'] = "'>

' ;
+
+ Html::closeForm();
+
+ $options['candel'] = $options['candel'] ?? $this->canPurgeItem($ID);
+
+ $this->showFormButtons($options);
+
+ echo Html::scriptBlock("
+ $('#tabsbody th').css('text-align', 'center');
+ $('#tabsbody td').css('text-align', 'center');
+ ");
+ }
+
+
+ /**
+ * Summary of defineTabs
+ * @param mixed $options
+ * @return array
+ */
+ function defineTabs($options = []) {
+
+ $process = new PluginProcessmakerProcess;
+ $process->getFromDB($this->fields['plugin_processmaker_processes_id']);
+
+ $ong = [];
+ if (self::isLayoutWithMain()) {
+ $this->addDefaultFormTab($ong);
+ }
+
+ if (!$process->fields['maintenance']) {
+ $this->addStandardTab('PluginProcessmakerTask', $ong, $options);
+ }
+
+ if (!self::isLayoutWithMain()) {
+ $this->addStandardTab(__CLASS__, $ong, $options);
+ }
+
+ if (!$process->fields['maintenance']) {
+ $this->addStandardTab('PluginProcessmakerCasemap', $ong, $options);
+
+ $this->addStandardTab('PluginProcessmakerCasehistory', $ong, $options);
+
+ $this->addStandardTab('PluginProcessmakerCasechangelog', $ong, $options);
+
+ $this->addStandardTab('PluginProcessmakerCasedynaform', $ong, $options);
+ }
+
+ return $ong;
+ }
+
+ /**
+ * Actions done after the PURGE of the item in the database
+ *
+ * @return nothing
+ **/
+
+ /**
+ * Summary of post_purgeItem
+ * Actions done after the PURGE of the item in the database
+ * Will purge the tasks and the PM case and recursively the sub-cases if any
+ * @return boolean|integer
+ */
+ function post_purgeItem() {
+ global $PM_SOAP;
+ $ret = false;
+
+ $PM_SOAP->login(true);
+ if ($this->deleteTasks() && $this->deleteCronTaskActions() && $PM_SOAP->deleteCase($this->fields['case_guid'])->status_code == 0) {
+ $ret = true;
+ $dbu = new DbUtils;
+ // then must delete any sub-processes (sub-cases)
+ $restrict = ["plugin_processmaker_cases_id" => $this->getID()];
+ //foreach ($dbu->getAllDataFromTable(self::getTable(), "`plugin_processmaker_cases_id` = ".$this->getID()) as $row) {
+ foreach ($dbu->getAllDataFromTable(self::getTable(), $restrict) as $row) {
+ $tmp = new self;
+ $tmp->fields = $row;
+ $ret &= $tmp->delete(['id' => $row['id']]);
+ }
+ }
+ return $ret;
+ }
+
+
+ /**
+ * Summary of deleteCronTaskActions
+ * Will delete any cron task actions taht are linked to current case
+ */
+ function deleteCronTaskActions() {
+ global $DB;
+
+ return $DB->delete('glpi_plugin_processmaker_crontaskactions', [
+ 'plugin_processmaker_cases_id' => $this->getID()
+ ]
+ );
+ //$query = "DELETE FROM `glpi_plugin_processmaker_crontaskactions` WHERE `plugin_processmaker_cases_id` = ".$this->getID();
+ //return $DB->query($query);
+ }
+
+}
diff --git a/inc/config.class.php b/inc/config.class.php
index 31ce71d..c7fc636 100644
--- a/inc/config.class.php
+++ b/inc/config.class.php
@@ -1,392 +1,383 @@
-getFromDB(1)) {
- self::$_instance->getEmpty();
- }
- }
- return self::$_instance;
- }
-
- /**
- * Prepare input datas for updating the item
- * @param array $input used to update the item
- * @return array the modified $input array
- **/
- function prepareInputForUpdate($input) {
- global $CFG_GLPI;
-
- if (!isset($input["maintenance"])) {
- $input["maintenance"] = 0;
- }
-
- if (isset($input["pm_dbserver_passwd"])) {
- if (empty($input["pm_dbserver_passwd"])) {
- unset($input["pm_dbserver_passwd"]);
- } else {
- $input["pm_dbserver_passwd"] = Toolbox::encrypt(stripslashes($input["pm_dbserver_passwd"]), GLPIKEY);
- }
- }
-
- if (isset($input["_blank_pm_dbserver_passwd"]) && $input["_blank_pm_dbserver_passwd"]) {
- $input['pm_dbserver_passwd'] = '';
- }
-
- if (isset($input["pm_admin_passwd"])) {
- if (empty($input["pm_admin_passwd"])) {
- unset($input["pm_admin_passwd"]);
- } else {
- $input["pm_admin_passwd"] = Toolbox::encrypt(stripslashes($input["pm_admin_passwd"]), GLPIKEY);
- }
- }
-
- if (isset($input["_blank_pm_admin_passwd"]) && $input["_blank_pm_admin_passwd"]) {
- $input['pm_admin_passwd'] = '';
- }
-
- if (isset($input['pm_server_URL'])) {
- $input['domain'] = self::getCommonDomain( $CFG_GLPI['url_base'], $input['pm_server_URL'] );
- }
-
- return $input;
- }
-
- /**
- * Summary of getCommonDomain
- * @param mixed $url1 first url
- * @param mixed $url2 second url
- * @return string the common domain part of the given urls
- */
- static function getCommonDomain($url1, $url2) {
- $domain = '';
- try {
- $glpi = explode(".", parse_url($url1, PHP_URL_HOST));
- $pm = explode( ".", parse_url($url2, PHP_URL_HOST));
- $cglpi = array_pop( $glpi );
- $cpm = array_pop( $pm );
- while ($cglpi && $cpm && $cglpi == $cpm) {
- $domain = $cglpi.($domain==''?'':'.'.$domain);
- $cglpi = array_pop( $glpi );
- $cpm = array_pop( $pm );
- }
- if ($domain != '') {
- return $domain;
- }
- } catch (Exception $e) {
- $domain = '';
- }
- return $domain;
- }
-
- /**
- * Summary of showConfigForm
- * @param mixed $item is the config
- * @return boolean
- */
- static function showConfigForm($item) {
- global $PM_DB, $CFG_GLPI, $PM_SOAP;
-
- $setup_ok = false;
-
- $ui_theme = [
- 'glpi_classic' => 'glpi_classic',
- 'glpi_neoclassic' => 'glpi_neoclassic'
- ];
-
- $config = $PM_SOAP->config;
- $config->showFormHeader(['colspan' => 4]);
-
- if (!$config->fields['maintenance']) {
-
- echo "