function prepareInputForUpdate($input) { global $CFG_GLPI, $DB; // Get ticket : need for comparison $this->getFromDB($input['id']); // Clean new lines before passing to rules if ($CFG_GLPI["use_rich_text"] && isset($input["content"])) { $input["content"] = preg_replace('/\\\\r\\\\n/', "\n", $input['content']); $input["content"] = preg_replace('/\\\\n/', "\n", $input['content']); } // automatic recalculate if user changes urgence or technician change impact if (isset($input['urgency']) && isset($input['impact']) && ($input['urgency'] != $this->fields['urgency'] || $input['impact'] != $this->fields['impact']) && !isset($input['priority'])) { $input['priority'] = self::computePriority($input['urgency'], $input['impact']); } // Security checks if (!Session::isCron() && !Session::haveRight(self::$rightname, self::ASSIGN)) { if (isset($input["_itil_assign"]) && isset($input['_itil_assign']['_type']) && $input['_itil_assign']['_type'] == 'user') { // must own_ticket to grab a non assign ticket if ($this->countUsers(CommonITILActor::ASSIGN) == 0) { if (!Session::haveRightsOr(self::$rightname, array(self::STEAL, self::OWN)) || !isset($input["_itil_assign"]['users_id']) || $input["_itil_assign"]['users_id'] != Session::getLoginUserID()) { unset($input["_itil_assign"]); } } else { // Can not steal or can steal and not assign to me if (!Session::haveRight(self::$rightname, self::STEAL) || !isset($input["_itil_assign"]['users_id']) || $input["_itil_assign"]['users_id'] != Session::getLoginUserID()) { unset($input["_itil_assign"]); } } } // No supplier assign if (isset($input["_itil_assign"]) && isset($input['_itil_assign']['_type']) && $input['_itil_assign']['_type'] == 'supplier') { unset($input["_itil_assign"]); } // No group if (isset($input["_itil_assign"]) && isset($input['_itil_assign']['_type']) && $input['_itil_assign']['_type'] == 'group') { unset($input["_itil_assign"]); } } $check_allowed_fields_for_template = false; $allowed_fields = array(); if (!Session::isCron() && (!Session::haveRight(self::$rightname, UPDATE) || in_array($this->fields['status'], $this->getClosedStatusArray()))) { $allowed_fields = array('id'); $check_allowed_fields_for_template = true; if (in_array($this->fields['status'], $this->getClosedStatusArray())) { $allowed_fields[] = 'status'; // probably transfer $allowed_fields[] = 'entities_id'; } else { if ($this->canApprove() && isset($input["status"])) { $allowed_fields[] = 'status'; } // for post-only with validate right or validation created by rules if (TicketValidation::canValidate($this->fields['id']) || TicketValidation::canCreate() || isset($input["_rule_process"])) { $allowed_fields[] = 'global_validation'; } // Manage assign and steal right if (Session::haveRightsOr(self::$rightname, array(self::ASSIGN, self::STEAL))) { $allowed_fields[] = '_itil_assign'; } // Can only update initial fields if no followup or task already added if ($this->numberOfFollowups() == 0 && $this->numberOfTasks() == 0 && $this->isUser(CommonITILActor::REQUESTER, Session::getLoginUserID())) { $allowed_fields[] = 'content'; $allowed_fields[] = 'urgency'; $allowed_fields[] = 'priority'; // automatic recalculate if user changes urgence $allowed_fields[] = 'itilcategories_id'; $allowed_fields[] = 'name'; } if ($this->canSolve()) { $allowed_fields[] = 'solutiontypes_id'; $allowed_fields[] = 'solution'; } } foreach ($allowed_fields as $field) { if (isset($input[$field])) { $ret[$field] = $input[$field]; } } $input = $ret; // Only ID return false if (count($input) == 1) { return false; } } //// check mandatory fields // First get ticket template associated : entity and type/category if (isset($input['entities_id'])) { $entid = $input['entities_id']; } else { $entid = $this->fields['entities_id']; } if (isset($input['type'])) { $type = $input['type']; } else { $type = $this->fields['type']; } if (isset($input['itilcategories_id'])) { $categid = $input['itilcategories_id']; } else { $categid = $this->fields['itilcategories_id']; } $tt = $this->getTicketTemplateToUse(0, $type, $categid, $entid); if (count($tt->mandatory)) { $mandatory_missing = array(); $fieldsname = $tt->getAllowedFieldsNames(true); foreach ($tt->mandatory as $key => $val) { if ((!$check_allowed_fields_for_template || in_array($key, $allowed_fields)) && (isset($input[$key]) && (empty($input[$key]) || $input[$key] == 'NULL') && !empty($this->fields[$key]))) { $mandatory_missing[$key] = $fieldsname[$val]; } } if (count($mandatory_missing)) { //TRANS: %s are the fields concerned $message = sprintf(__('Mandatory fields are not filled. Please correct: %s'), implode(", ", $mandatory_missing)); Session::addMessageAfterRedirect($message, false, ERROR); return false; } } /// Process Business Rules // Add actors on standard input $rules = new RuleTicketCollection($entid); $rule = $rules->getRuleClass(); $changes = array(); $tocleanafterrules = array(); $usertypes = array('assign', 'requester', 'observer'); foreach ($usertypes as $t) { if (isset($input['_itil_' . $t]) && isset($input['_itil_' . $t]['_type'])) { $field = $input['_itil_' . $t]['_type'] . 's_id'; if (isset($input['_itil_' . $t][$field]) && !isset($input[$field . '_' . $t])) { $input['_' . $field . '_' . $t] = $input['_itil_' . $t][$field]; $tocleanafterrules['_' . $field . '_' . $t] = $input['_itil_' . $t][$field]; } } } foreach ($rule->getCriterias() as $key => $val) { if (array_key_exists($key, $input)) { if (!isset($this->fields[$key]) || $DB->escape($this->fields[$key]) != $input[$key]) { $changes[] = $key; } } } // Business Rules do not override manual SLT $manual_slts_id = array(); foreach (array(SLT::TTR, SLT::TTO) as $sltType) { list($dateField, $sltField) = SLT::getSltFieldNames($sltType); if (isset($input[$sltField]) && $input[$sltField] > 0) { $manual_slts_id[$sltType] = $input[$sltField]; } } // Only process rules on changes if (count($changes)) { if (in_array('_users_id_requester', $changes)) { // If _users_id_requester changed : set users_locations $user = new User(); if (isset($input["_users_id_requester"]) && $user->getFromDB($input["_users_id_requester"])) { $input['users_locations'] = $user->fields['locations_id']; $changes[] = 'users_locations'; } // If _users_id_requester changed : add _groups_id_of_requester to changes $changes[] = '_groups_id_of_requester'; } $input = $rules->processAllRules(Toolbox::stripslashes_deep($input), Toolbox::stripslashes_deep($input), array('recursive' => true, 'entities_id' => $entid), array('condition' => RuleTicket::ONUPDATE, 'only_criteria' => $changes)); } //Action for send_validation rule : do validation before clean $this->manageValidationAdd($input); // Clean actors fields added for rules foreach ($tocleanafterrules as $key => $val) { if ($input[$key] == $val) { unset($input[$key]); } } // Manage fields from auto update or rules : map rule actions to standard additional ones $usertypes = array('assign', 'requester', 'observer'); $actortypes = array('user', 'group', 'supplier'); foreach ($usertypes as $t) { foreach ($actortypes as $a) { if (isset($input['_' . $a . 's_id_' . $t])) { switch ($a) { case 'user': $additionalfield = '_additional_' . $t . 's'; $input[$additionalfield][] = array('users_id' => $input['_' . $a . 's_id_' . $t]); break; default: $additionalfield = '_additional_' . $a . 's_' . $t . 's'; $input[$additionalfield][] = $input['_' . $a . 's_id_' . $t]; break; } } } } if (isset($input['_link'])) { $ticket_ticket = new Ticket_Ticket(); if (!empty($input['_link']['tickets_id_2'])) { if ($ticket_ticket->can(-1, CREATE, $input['_link'])) { if ($ticket_ticket->add($input['_link'])) { $input['_forcenotif'] = true; } } else { Session::addMessageAfterRedirect(__('Unknown ticket'), false, ERROR); } } } // SLT affect by rules : reset due_date // Manual SLT defined : reset due date // No manual SLT and due date defined : reset auto SLT foreach (array(SLT::TTR, SLT::TTO) as $sltType) { $this->sltAffect($sltType, $input, $manual_slts_id); } if (isset($input['content'])) { if (isset($input['_stock_image'])) { $this->addImagePaste(); $input['content'] = $input['content']; $input['_disablenotif'] = true; } else { if ($CFG_GLPI["use_rich_text"]) { $input['content'] = $this->convertTagToImage($input['content']); if (!isset($input['_filename'])) { $input['_donotadddocs'] = true; } } } } $input = parent::prepareInputForUpdate($input); return $input; }