. -------------------------------------------------------------------------- */ /** * PluginProcessmakerTaskCategory short summary. * * PluginProcessmakerTaskCategory description. * * @version 1.0 * @author MoronO */ if (!defined('GLPI_ROOT')) { die("Sorry. You can't access directly to this file"); } class PluginProcessmakerTaskCategory extends CommonDBTM { const REMINDER_NONE = -10; const REMINDER_STOP = -20; static $rightname = 'taskcategory'; function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { if ($item->getType() == 'TaskCategory') { $pmtaskcat = new PluginProcessmakerTaskCategory; if ($pmtaskcat->getFromDBbyCategory($item->fields['id'])) { return __('Process task', 'processmaker'); } else { return ''; // means no tab } } return __('Task list', 'processmaker'); } static function getAllAfterReminders() { $possible_values = []; $possible_values[self::REMINDER_NONE] = __('None'); $min_values = [15, 30]; foreach ($min_values as $val) { $possible_values[$val * MINUTE_TIMESTAMP] = sprintf(_n('%d minute', '%d minutes', $val), $val); } $h_values = [1, 2, 4, 8, 12]; foreach ($h_values as $val) { $possible_values[$val * HOUR_TIMESTAMP] = sprintf(_n('%d hour', '%d hours', $val), $val); } $d_values = [1, 2, 4, 6]; foreach ($d_values as $val) { $possible_values[$val * DAY_TIMESTAMP] = sprintf(_n('%d day', '%d days', $val), $val); } $w_values = [1, 2, 3]; foreach ($w_values as $val) { $possible_values[$val * WEEK_TIMESTAMP] = sprintf(_n('%d week', '%d weeks', $val), $val); } $m_values = [1, 2]; foreach ($m_values as $val) { $possible_values[$val * MONTH_TIMESTAMP] = sprintf(_n('%d month', '%d months', $val), $val); } return $possible_values; } static function getAfterReminder($value) { $arr = self::getAllAfterReminders(); if (array_key_exists($value, $arr)) { return $arr[$value]; } else { return null; } } static function displayTabContentForProcess(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { global $DB, $CFG_GLPI; self::title($item); echo "

"; echo ""; echo "". "" . "" . "" . "" . "" . "" . "" . ""; $res = $DB->request([ 'SELECT' => [ 'pm.pm_task_guid', 'pm.taskcategories_id', 'pm.is_start', 'gl.name', 'gl.completename', 'gl.comment', 'pm.is_active', 'pm.is_reassignreason_mandatory AS pm_is_reassignreason_mandatory', 'pm.is_subprocess', 'gppp.is_reassignreason_mandatory AS gppp_is_reassignreason_mandatory' ], 'FROM' => 'glpi_plugin_processmaker_taskcategories AS pm', 'LEFT JOIN' => [ 'glpi_taskcategories AS gl' => [ 'FKEY' => [ 'gl' => 'id', 'pm' => 'taskcategories_id' ] ], 'glpi_plugin_processmaker_processes AS gppp' => [ 'FKEY' => [ 'gppp' => 'id', 'pm' => 'plugin_processmaker_processes_id' ] ] ], 'WHERE' => [ 'pm.plugin_processmaker_processes_id' => $item->getId() ] ]); foreach ($res as $taskCat) { echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; echo ""; } echo "
".__('Task list', 'processmaker')."
".__('Task name', 'processmaker')."".__('Complete name')."".__('Start', 'processmaker')."".__('Task guid', 'processmaker')."".__('Comments')."".__('Active')."".__('Mandatory re-assign reason', 'processmaker')."".__('Sub-process', 'processmaker')."
" . $taskCat['name']; if ($_SESSION["glpiis_ids_visible"]) { echo " (" . $taskCat['taskcategories_id'] . ")"; } echo "" . $taskCat['completename'] . ""; if ($taskCat['is_start']) { echo "\""."; } echo "".$taskCat['pm_task_guid']."".$taskCat['comment'].""; if ($taskCat['is_active']) { echo "\""."; } echo ""; if (self::inheritedReAssignReason($taskCat['pm_is_reassignreason_mandatory'], $taskCat['gppp_is_reassignreason_mandatory']) == 1) { echo "\""."; } echo ""; if ($taskCat['is_subprocess']) { echo "\""."; } echo "
"; return true; } static function inheritedReAssignReason($taskVal, $processVal) { global $PM_SOAP; $ret = $taskVal; // by default if ($processVal == Entity::CONFIG_PARENT) { if (!isset($PM_SOAP->config)) { $PM_SOAP->config = Config::getConfigurationValues('plugin:processmaker'); } $processVal = $PM_SOAP->config['is_reassignreason_mandatory']; } if ($taskVal == Entity::CONFIG_PARENT) { $ret = $processVal; } return $ret; } static function displayTabContentForTaskCategory($item, $tabnum, $withtemplate) { global $DB, $CFG_GLPI; $processes_id = 0; $pmtaskcat = new self; $pmtaskcat->getFromDBbyCategory($item->fields['id']); $processes_id = $pmtaskcat->fields['plugin_processmaker_processes_id']; $res = $DB->request([ 'SELECT' => [ 'pm.*', 'glp.name as pname', 'gl.name', 'gl.completename', 'gl.comment', 'gppp.is_reassignreason_mandatory AS gppp_is_reassignreason_mandatory' ], 'FROM' => 'glpi_plugin_processmaker_taskcategories AS pm', 'LEFT JOIN' => [ 'glpi_taskcategories AS gl' => [ 'FKEY' => [ 'gl' => 'id', 'pm' => 'taskcategories_id' ] ], 'glpi_taskcategories AS glp' => [ 'FKEY' => [ 'glp' => 'id', 'gl' => 'taskcategories_id' ] ], 'glpi_plugin_processmaker_processes AS gppp' => [ 'FKEY' => [ 'gppp' => 'id', 'pm' => 'plugin_processmaker_processes_id' ] ] ], 'WHERE' => [ 'pm.taskcategories_id' => $item->getId() ] ]); // there is only one row $taskCat = $res->current(); $pmtaskcat->showFormHeader(); echo ""; echo ""; echo "".__('Process name', 'processmaker')."" . $taskCat['pname']; if ($_SESSION["glpiis_ids_visible"]) { echo " (" . $processes_id . ")"; } echo ""; echo ""; echo "".__('Task name', 'processmaker').""; echo $taskCat['name']; if ($_SESSION["glpiis_ids_visible"]) { echo " (" . $taskCat['taskcategories_id'] . ")"; } echo "" . __('Complete name') . ""; echo "" . $taskCat['completename'] . ""; echo ""; echo ""; echo "" . __('Start', 'processmaker') . ""; echo ""; echo Dropdown::getYesNo($taskCat['is_start']); echo ""; echo ""; echo "" . __('Task guid', 'processmaker') . ""; echo "".$taskCat['pm_task_guid'].""; echo "" . __('Comments') . ""; echo "".$taskCat['comment'].""; echo ""; echo ""; echo "" . __('Active') . ""; echo ""; echo Dropdown::getYesNo($taskCat['is_active']); echo ""; echo ""; echo "" . __('Sub-process', 'processmaker') . ""; echo ""; echo Dropdown::getYesNo($taskCat['is_subprocess']); echo ""; echo "" . __('Re-assign reason setting', 'processmaker') . ""; echo ""; echo "" . __('Re-assign reason is mandatory', 'processmaker') . ""; echo ""; $elements = [ Entity::CONFIG_PARENT => __('Inheritance of the process settings', 'processmaker'), 0 => Dropdown::getYesNo(0), 1 => Dropdown::getYesNo(1) ]; Dropdown::showFromArray('is_reassignreason_mandatory', $elements, [ 'value' => $taskCat['is_reassignreason_mandatory'], ]); if ($taskCat['is_reassignreason_mandatory'] == Entity::CONFIG_PARENT) { echo "
" .$elements[self::inheritedReAssignReason($taskCat['is_reassignreason_mandatory'], $taskCat['gppp_is_reassignreason_mandatory'])] ."
"; } echo ""; echo "" . __('Reminder settings', 'processmaker') . ""; echo ""; echo "" . __('Before task (once)', 'processmaker'); echo " "; echo " "; Html::showToolTip(__('Can be overridden by GLPI_ITEM_TASK_REMINDER', 'processmaker'), [ 'link' => 'https://github.com/tomolimo/processmaker/wiki/Case-Variables#glpi_item_task_reminder', 'linktarget' => '_blank' ]); echo ""; echo ""; Dropdown::showFromArray('before_time', self::getAllBeforeReminders(), [ 'value' => $pmtaskcat->fields['before_time'] ]); echo ""; echo "" . __('Outdated task (every)', 'processmaker') . ""; echo ""; Dropdown::showFromArray('after_time', self::getAllAfterReminders(), [ 'value' => $pmtaskcat->fields['after_time'], ]); echo ""; echo ""; echo "" . __('Sender (default: GLPI)', 'processmaker') . ""; echo ""; User::dropdown(['name' => 'users_id', 'display_emptychoice' => true, 'right' => 'all', 'value' => $pmtaskcat->fields['users_id']]); echo ""; $pmtaskcat->showFormButtons(['candel'=>false]); } function prepareInputForUpdate($input) { if (isset($input['_planningrecall']['before_time'])) { $input['reminder_recall_time'] = $input['_planningrecall']['before_time']; unset($input['_planningrecall']); } return $input; } /** * Summary of displayTabContentForItem * @param CommonGLPI $item * @param mixed $tabnum * @param mixed $withtemplate * @return boolean */ static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { $ret = false; switch ($item->getType()) { case 'PluginProcessmakerProcess': $ret = self::displayTabContentForProcess($item, $tabnum, $withtemplate); break; case 'TaskCategory': $ret = self::displayTabContentForTaskCategory($item, $tabnum, $withtemplate); break; } return $ret; } /** * Print a good title for task categories tab * add button for re-synchro of taskcategory list (only if rigths are w) * @return nothing (display) **/ static function title(CommonGLPI $item) { global $CFG_GLPI; if (Session::haveRight('plugin_processmaker_config', UPDATE)) { $title = __('Synchronize Task List', 'processmaker'); $buttons = ["process.form.php?refreshtask=1&id=".$item->getID() => $title]; $pic = Plugin::getWebDir('processmaker') . "/pics/gears.png"; if ($item->fields['maintenance']) { $pic = Plugin::getWebDir('processmaker') . "/pics/verysmall-under_maintenance.png"; } Html::displayTitle($pic, $title, "", $buttons); } } /** * Retrieve a TaskCat from the database using its external id (unique index): pm_task_guid * * @param $task_guid string externalid * * @return true if succeed else false **/ function getFromGUID($task_guid) { return $this->getFromDBByCrit(['pm_task_guid' => $task_guid]); } /** * Retrieve a TaskCat from the database using its category id (unique index): taskcategories_id * * @param $catid string task category id * * @return true if succeed else false **/ function getFromDBbyCategory($catid) { global $DB; $res = $DB->request( $this->getTable(), [ 'taskcategories_id' => $catid ] ); if ($res) { if ($res->numrows() != 1) { return false; } $this->fields = $res->current(); if (is_array($this->fields) && count($this->fields)) { return true; } } return false; } /** * summary of cronInfo * Gives localized information about 1 cron task * @param $name of the task * @return array of strings */ static function cronInfo ($name) { switch ($name) { case 'pmreminders' : return ['description' => __('To send auto-reminders and overdue reminders.', 'processmaker')]; } return []; } /** * Summary of cronPMReminders * @param mixed $crontask * @return int */ static function cronPMReminders ($crontask = null) { global $DB, $CFG_GLPI, $PM_SOAP; if (!$CFG_GLPI["use_notifications"]) { return 0; } $pmconfig = $PM_SOAP->config; $cron_status = 0; $iterator = $DB->request([ 'SELECT' => ['glpi_plugin_processmaker_taskrecalls.*', 'glpi_plugin_processmaker_tasks.itemtype as gppt-itemtype', 'glpi_plugin_processmaker_tasks.items_id as gppt-items_id', 'glpi_plugin_processmaker_tasks.plugin_processmaker_cases_id as gppt-cases_id', 'glpi_plugin_processmaker_cases.id as gppc-id', 'glpi_plugin_processmaker_cases.name as gppc-name', 'glpi_plugin_processmaker_cases.case_status as gppc-case_status'], 'DISTINCT' => true, 'FROM' => 'glpi_plugin_processmaker_taskrecalls', 'LEFT JOIN' => [ 'glpi_plugin_processmaker_taskalerts' => [ 'ON' => [ 'glpi_plugin_processmaker_taskrecalls' => 'id', 'glpi_plugin_processmaker_taskalerts' => 'plugin_processmaker_taskrecalls_id', ] ], 'glpi_plugin_processmaker_tasks' => [ 'ON' => [ 'glpi_plugin_processmaker_tasks' => 'id', 'glpi_plugin_processmaker_taskrecalls' => 'plugin_processmaker_tasks_id' ] ], 'glpi_plugin_processmaker_cases' => [ 'ON' => [ 'glpi_plugin_processmaker_cases' => 'id', 'glpi_plugin_processmaker_tasks' => 'plugin_processmaker_cases_id' ] ], ], 'WHERE' => [ 'NOT' => ['glpi_plugin_processmaker_taskrecalls.when' => null], 'glpi_plugin_processmaker_taskrecalls.when' => ['<', new \QueryExpression('NOW()')], 'glpi_plugin_processmaker_tasks.del_thread_status' => PluginProcessmakerTask::OPEN, 'OR' => [ ['glpi_plugin_processmaker_taskalerts.date' => null], ['glpi_plugin_processmaker_taskalerts.date' => ['<', new \QueryExpression($DB->quoteName('glpi_plugin_processmaker_taskrecalls.when'))]]] ] ]); foreach ($iterator as $data) { if ($data['gppc-case_status'] == PluginProcessmakerCase::CANCELLED) { PluginProcessmakerCase::deleteReminders($data['gppc-id']); continue; } $pm_task = new PluginProcessmakerTask($data['gppt-itemtype']); $pm_task->getFromDB($data['gppt-items_id']); // init sender $pm_task->setSender($data['users_id']); $glpi_task = new $data['gppt-itemtype']; $glpi_task->fields = $pm_task->fields; $itemtype = $pm_task->getItilObjectItemType(); $glpi_item = new $itemtype; $glpi_item->getFromDB($pm_task->fields[$glpi_item->getForeignKeyField()]); $add_alert = false; // by default $new_when = 0; // by default if ($data['before_time'] >= 0) { // then send task "before reminder" if ($pm_task->sendNotification('task_reminder', $glpi_task, $glpi_item)) { // and now add an alert $add_alert = true; // then set the 'before_time' value to self::REMINDER_STOP to permit future "after reminders" $data['before_time'] = self::REMINDER_STOP; $pm_taskrecall = new PluginProcessmakerTaskrecall(); $pm_taskrecall->update($data); } if ($data['after_time'] >= 0) { // if task "after reminder" is set, then compute new when for the first task "after reminder" $new_when = strtotime($pm_task->fields['end']) + $data['after_time']; } } elseif ($data['after_time'] >= 0) { // then task "after reminder" if ($pm_task->sendNotification('task_overdue', $glpi_task, $glpi_item)) { // and now add an alert $add_alert = true; // then compute the new when for the next task "after reminder" $new_when = strtotime($data['when']) + $data['after_time']; // Add a follow-up in the hosting item to indicate the sending of the reminder $fu = new ITILFollowup(); $input = $fu->fields; $fucontent = sprintf( __("Case: '%s',
Task: '%s',
A reminder has been sent to:
", 'processmaker'), $data['gppc-name'], Dropdown::getDropdownName("glpi_taskcategories", $glpi_task->fields["taskcategories_id"]) ); if (isset($glpi_task->fields['users_id_tech']) && $glpi_task->fields['users_id_tech'] > 0) { // get infos for user $dbu = new DbUtils; $userinfos = $dbu->getUserName($glpi_task->fields['users_id_tech'], 2); $fucontent .= "-> " . $userinfos['name'] . "
"; } if (isset($glpi_task->fields['groups_id_tech']) && $glpi_task->fields['groups_id_tech'] > 0) { // get infos for group $grp = new Group(); $grp->getFromDB($glpi_task->fields['groups_id_tech']); $fucontent .= "-> " . $grp->fields['name'] . "
"; } $input['content'] = $DB->escape($fucontent); $input['is_private'] = 0; //$input['requesttypes_id'] = ; $input['items_id'] = $glpi_item->getID(); $input['users_id'] = ($data['users_id'] > 0 ? $data['users_id'] : $pmconfig['users_id']); $input['itemtype'] = $glpi_item->getType(); $fu->add($input); } } if ($new_when != 0) { // if the new_when is less than glpi_currenttime, then set it to be greater than glpi_currenttime // to prevent send of many "after reminders" in case of late cron that missed one or several "after reminders" $glpi_currenttime = strtotime($_SESSION["glpi_currenttime"]); if ($new_when < $glpi_currenttime + $data['after_time']) { $new_when = $glpi_currenttime + $data['after_time']; } $data['when'] = date("Y-m-d H:i:s", $new_when); $pm_taskrecall = new PluginProcessmakerTaskrecall(); $pm_taskrecall->update($data); } if ($add_alert) { $cron_status = 1; $crontask->addVolume(1); $crontask->log(sprintf(__('Reminder for case #%s has been sent!', 'processmaker'), $data['gppt-cases_id'])); $pm_taskalert = new PluginProcessmakerTaskalert(); $input["plugin_processmaker_taskrecalls_id"] = $data['id']; $pm_taskalert->add($input); } else { // Clean item $pr->delete($data); } } return $cron_status; } static function getAllBeforeReminders() { $possible_values = []; $possible_values[self::REMINDER_NONE] = __('None'); $min_values = [0, 15, 30]; foreach ($min_values as $val) { $possible_values[$val * MINUTE_TIMESTAMP] = sprintf(_n('%d minute', '%d minutes', $val), $val); } $h_values = [1, 2, 4, 8, 12]; foreach ($h_values as $val) { $possible_values[$val * HOUR_TIMESTAMP] = sprintf(_n('%d hour', '%d hours', $val), $val); } $d_values = [1, 2]; foreach ($d_values as $val) { $possible_values[$val * DAY_TIMESTAMP] = sprintf(_n('%d day', '%d days', $val), $val); } $w_values = [1]; foreach ($w_values as $val) { $possible_values[$val * WEEK_TIMESTAMP] = sprintf(_n('%d week', '%d weeks', $val), $val); } return $possible_values; } static function getBeforeReminder($value) { $arr = self::getAllBeforeReminders(); if (array_key_exists($value, $arr)) { return $arr[$value]; } return null; } static function getSpecificValueToDisplay($field, $values, array $options=[]) { if (!is_array($values)) { $values = [$field => $values]; } switch ($field) { case 'before_time': return self::getBeforeReminder($values[$field]); case 'after_time': return self::getAfterReminder($values[$field]); } return parent::getSpecificValueToDisplay($field, $values, $options); } static function getSpecificValueToSelect($field, $name='', $values='', array $options=[]) { if (!is_array($values)) { $values = [$field => $values]; } $options['display'] = false; $options['name'] = $name; $options['value'] = $values[$field]; switch ($field) { case 'before_time' : return Dropdown::showFromArray($name, self::getAllBeforeReminders(), $options); case 'after_time' : return Dropdown::showFromArray($name, self::getAllAfterReminders(), $options); } return parent::getSpecificValueToSelect($field, $name, $values, $options); } }