%PDF- %PDF-
Direktori : /var/www/projetos/suporte.iigd.com.br/src/ |
Current File : /var/www/projetos/suporte.iigd.com.br/src/Ticket_Ticket.php |
<?php /** * --------------------------------------------------------------------- * * GLPI - Gestionnaire Libre de Parc Informatique * * http://glpi-project.org * * @copyright 2015-2024 Teclib' and contributors. * @copyright 2003-2014 by the INDEPNET Development Team. * @licence https://www.gnu.org/licenses/gpl-3.0.html * * --------------------------------------------------------------------- * * LICENSE * * This file is part of GLPI. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * * --------------------------------------------------------------------- */ /// Class Ticket links class Ticket_Ticket extends CommonDBRelation { // From CommonDBRelation public static $itemtype_1 = 'Ticket'; public static $items_id_1 = 'tickets_id_1'; public static $itemtype_2 = 'Ticket'; public static $items_id_2 = 'tickets_id_2'; public static $check_entity_coherency = false; // Ticket links const LINK_TO = 1; const DUPLICATE_WITH = 2; const SON_OF = 3; const PARENT_OF = 4; public static function getTypeName($nb = 0) { return _n('Linked ticket', 'Linked tickets', $nb); } /** * @since 0.85 * * @see CommonDBTM::showMassiveActionsSubForm() **/ public static function showMassiveActionsSubForm(MassiveAction $ma) { switch ($ma->getAction()) { case 'add': Ticket_Ticket::dropdownLinks('link'); printf(__('%1$s: %2$s'), Ticket::getTypeName(1), __('ID')); echo " <input type='text' name='tickets_id_1' value='' size='10'>\n"; echo "<br><br>"; echo "<br><br><input type='submit' name='massiveaction' class='btn btn-primary' value='" . _sx('button', 'Post') . "'>"; return true; } return parent::showMassiveActionsSubForm($ma); } /** * @since 0.85 * * @see CommonDBTM::processMassiveActionsForOneItemtype() **/ public static function processMassiveActionsForOneItemtype( MassiveAction $ma, CommonDBTM $item, array $ids ) { switch ($ma->getAction()) { case 'add': $input = $ma->getInput(); $ticket = new Ticket(); if ( isset($input['link']) && isset($input['tickets_id_1']) ) { if ($item->getFromDB($input['tickets_id_1'])) { foreach ($ids as $id) { $input2 = []; $input2['id'] = $input['tickets_id_1']; $input2['_link']['tickets_id_1'] = $id; $input2['_link']['link'] = $input['link']; $input2['_link']['tickets_id_2'] = $input['tickets_id_1']; if ($item->can($input['tickets_id_1'], UPDATE)) { if ($ticket->update($input2)) { $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); } else { $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO); $ma->addMessage($item->getErrorMessage(ERROR_ON_ACTION)); } } else { $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT); $ma->addMessage($item->getErrorMessage(ERROR_RIGHT)); } } } } return; } parent::processMassiveActionsForOneItemtype($ma, $item, $ids); } /** * Get linked tickets to a ticket * * @param integer $ID ID of the ticket id * @param boolean $check_view_rights check view rights * * @return array of linked tickets array(id=>linktype) **/ public static function getLinkedTicketsTo($ID, bool $check_view_rights = false) { /** @var \DBmysql $DB */ global $DB; // Make new database object and fill variables if (empty($ID)) { return []; } $table = self::getTable(); $criteria = [ 'SELECT' => ["{$table}.*"], 'FROM' => $table, 'WHERE' => [ 'OR' => [ 'tickets_id_1' => $ID, 'tickets_id_2' => $ID ] ] ]; if ($check_view_rights && !Session::haveRight(Ticket::$rightname, Ticket::READALL)) { $ticket_table = Ticket::getTable(); $criteria['LEFT JOIN'] = [ $ticket_table => [ 'ON' => new QueryExpression("{$ticket_table}.id=(CASE WHEN {$table}.tickets_id_1={$ID} THEN {$table}.tickets_id_2 ELSE {$table}.tickets_id_1 END)") ], ]; $unused_ref = []; $joins_str = Search::addDefaultJoin(Ticket::class, Ticket::getTable(), $unused_ref); if (!empty($joins_str)) { $db_it = new DBmysqlIterator($DB); $criteria['LEFT JOIN'] = [new QueryExpression($db_it->analyseJoins(['LEFT JOIN' => $criteria['LEFT JOIN']]) . ' ' . $joins_str)]; } $criteria['WHERE'][] = new QueryExpression(Search::addDefaultWhere(Ticket::class)); } $iterator = $DB->request($criteria); $tickets = []; foreach ($iterator as $data) { if ($data['tickets_id_1'] != $ID) { $tickets[$data['id']] = [ 'link' => $data['link'], 'tickets_id_1' => $data['tickets_id_1'], 'tickets_id' => $data['tickets_id_1'] ]; } else { $tickets[$data['id']] = [ 'link' => $data['link'], 'tickets_id' => $data['tickets_id_2'] ]; } } ksort($tickets); return $tickets; } /** * Dropdown for links between tickets * * @param string $myname select name * @param integer $value default value (default self::LINK_TO) * * @return void **/ public static function dropdownLinks($myname, $value = self::LINK_TO) { $tmp[self::LINK_TO] = __('Linked to'); $tmp[self::DUPLICATE_WITH] = __('Duplicates'); $tmp[self::SON_OF] = __('Son of'); $tmp[self::PARENT_OF] = __('Parent of'); Dropdown::showFromArray($myname, $tmp, ['value' => $value]); } /** * Get Link Name * * @param integer $value Current value * @param boolean $inverted Whether to invert label * @param boolean $with_icon prefix label with an icon * * @return string **/ public static function getLinkName($value, bool $inverted = false, bool $with_icon = false): string { $tmp = []; if (!$inverted) { $tmp[self::LINK_TO] = __('Linked to'); $tmp[self::DUPLICATE_WITH] = __('Duplicates'); $tmp[self::SON_OF] = __('Son of'); $tmp[self::PARENT_OF] = __('Parent of'); } else { $tmp[self::LINK_TO] = __('Linked to'); $tmp[self::DUPLICATE_WITH] = __('Duplicated by'); $tmp[self::SON_OF] = __('Parent of'); $tmp[self::PARENT_OF] = __('Son of'); } if ($with_icon) { $icon_tag = '<i class="fas %1$s me-1" title="%2$s" data-bs-toggle="tooltip"></i>%2$s'; $tmp[self::LINK_TO] = sprintf($icon_tag, "fa-link", $tmp[self::LINK_TO]); $tmp[self::DUPLICATE_WITH] = sprintf($icon_tag, "fa-clone", $tmp[self::DUPLICATE_WITH]); $icon_son = $inverted ? "fa-level-down-alt" : "fa-level-up-alt fa-flip-horizontal"; $tmp[self::SON_OF] = sprintf($icon_tag, $icon_son, $tmp[self::SON_OF]); $icon_parent = $inverted ? "fa-level-down-alt" : "fa-level-up-alt"; $tmp[self::PARENT_OF] = sprintf($icon_tag, $icon_parent, $tmp[self::PARENT_OF]); } if (isset($tmp[$value])) { return $tmp[$value]; } return NOT_AVAILABLE; } public function prepareInputForAdd($input) { // Clean values $input['tickets_id_1'] = Toolbox::cleanInteger($input['tickets_id_1']); $input['tickets_id_2'] = Toolbox::cleanInteger($input['tickets_id_2']); // Check of existance of rights on both Ticket(s) is done by the parent if ($input['tickets_id_2'] == $input['tickets_id_1']) { return false; } if (!isset($input['link'])) { $input['link'] = self::LINK_TO; } $this->checkParentSon($input); // No multiple links $tickets = self::getLinkedTicketsTo($input['tickets_id_1']); if (count($tickets)) { foreach ($tickets as $key => $t) { if ($t['tickets_id'] == $input['tickets_id_2']) { // Delete old simple link if ( ($input['link'] == self::DUPLICATE_WITH) && ($t['link'] == self::LINK_TO) ) { $tt = new Ticket_Ticket(); $tt->delete(["id" => $key]); } else { // No duplicate link return false; } } } } return parent::prepareInputForAdd($input); } public function prepareInputForUpdate($input) { $this->checkParentSon($input); return parent::prepareInputForAdd($input); } /** * Check for parent relation (inverse of son) * * @param array $input Input * * @return void */ public function checkParentSon(&$input) { if (isset($input['link']) && $input['link'] == Ticket_Ticket::PARENT_OF) { //a PARENT_OF relation is an inverted SON_OF one :) $id1 = $input['tickets_id_2']; $id2 = $input['tickets_id_1']; $input['tickets_id_1'] = $id1; $input['tickets_id_2'] = $id2; $input['link'] = Ticket_Ticket::SON_OF; } } public function post_deleteFromDB() { /** @var array $CFG_GLPI */ global $CFG_GLPI; $t = new Ticket(); $t->updateDateMod($this->fields['tickets_id_1']); $t->updateDateMod($this->fields['tickets_id_2']); parent::post_deleteFromDB(); $donotif = !isset($this->input['_disablenotif']) && $CFG_GLPI["use_notifications"]; if ($donotif) { $t->getFromDB($this->fields['tickets_id_1']); NotificationEvent::raiseEvent("update", $t); $t->getFromDB($this->fields['tickets_id_2']); NotificationEvent::raiseEvent("update", $t); } } public function post_addItem() { /** @var array $CFG_GLPI */ global $CFG_GLPI; $t = new Ticket(); $t->updateDateMod($this->fields['tickets_id_1']); $t->updateDateMod($this->fields['tickets_id_2']); parent::post_addItem(); $donotif = !isset($this->input['_disablenotif']) && $CFG_GLPI["use_notifications"]; if ($donotif) { $t->getFromDB($this->fields['tickets_id_1']); NotificationEvent::raiseEvent("update", $t); $t->getFromDB($this->fields['tickets_id_2']); NotificationEvent::raiseEvent("update", $t); } } /** * Count number of open children for a parent * * @param integer $pid Parent ID * * @return integer */ public static function countOpenChildren($pid) { /** @var \DBmysql $DB */ global $DB; $result = $DB->request([ 'COUNT' => 'cpt', 'FROM' => self::getTable() . ' AS links', 'INNER JOIN' => [ Ticket::getTable() . ' AS tickets' => [ 'ON' => [ 'links' => 'tickets_id_1', 'tickets' => 'id' ] ] ], 'WHERE' => [ 'links.link' => self::SON_OF, 'links.tickets_id_2' => $pid, 'NOT' => [ 'tickets.status' => Ticket::getClosedStatusArray() + Ticket::getSolvedStatusArray() ] ] ])->current(); return (int)$result['cpt']; } /** * Affect the same solution/status for duplicates tickets. * * @param integer $ID ID of the ticket id * @param ITILSolution|null $solution Ticket's solution * * @return void **/ public static function manageLinkedTicketsOnSolved($ID, $solution = null) { $ticket = new Ticket(); if (!$ticket->getfromDB($ID)) { return; } $tickets = self::getLinkedTicketsTo($ID); if (false === $tickets) { return; } $tickets = array_filter( $tickets, function ($data) { $linked_ticket = new Ticket(); $linked_ticket->getFromDB($data['tickets_id']); return $linked_ticket->can($data['tickets_id'], UPDATE) && ($data['link'] == self::DUPLICATE_WITH) && ($linked_ticket->fields['status'] != CommonITILObject::SOLVED) && ($linked_ticket->fields['status'] != CommonITILObject::CLOSED); } ); if (null === $solution) { // Change status without adding a solution // This will be done if a ticket is solved/closed without a solution foreach ($tickets as $data) { $linked_ticket = new Ticket(); $linked_ticket->update( [ 'id' => $data['tickets_id'], 'status' => $ticket->fields['status'] ] ); } } else { // Add same solution to duplicates $solution_data = $solution->fields; unset($solution_data['id']); unset($solution_data['date_creation']); unset($solution_data['date_mod']); foreach ($tickets as $data) { $solution_data['items_id'] = $data['tickets_id']; $solution_data['_linked_ticket'] = true; $new_solution = new ITILSolution(); $new_solution->add(Toolbox::addslashes_deep($solution_data)); } } } }