problem_ticket.class.php 17.5 KB
Newer Older
moyooo's avatar
moyooo committed
1
<?php
2
3
4
/**
 * ---------------------------------------------------------------------
 * GLPI - Gestionnaire Libre de Parc Informatique
5
 * Copyright (C) 2015-2021 Teclib' and contributors.
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 *
 * http://glpi-project.org
 *
 * based on GLPI - Gestionnaire Libre de Parc Informatique
 * Copyright (C) 2003-2014 by the INDEPNET Development Team.
 *
 * ---------------------------------------------------------------------
 *
 * LICENSE
 *
 * This file is part of GLPI.
 *
 * GLPI 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 2 of the License, or
 * (at your option) any later version.
 *
 * GLPI 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 GLPI. If not, see <http://www.gnu.org/licenses/>.
 * ---------------------------------------------------------------------
moyooo's avatar
moyooo committed
31
32
33
 */

if (!defined('GLPI_ROOT')) {
Stefan Weil's avatar
Stefan Weil committed
34
   die("Sorry. You can't access this file directly");
moyooo's avatar
moyooo committed
35
36
37
38
39
}

class Problem_Ticket extends CommonDBRelation{

   // From CommonDBRelation
yllen's avatar
CS    
yllen committed
40
41
42
43
44
   static public $itemtype_1   = 'Problem';
   static public $items_id_1   = 'problems_id';

   static public $itemtype_2   = 'Ticket';
   static public $items_id_2   = 'tickets_id';
moyooo's avatar
moyooo committed
45

46

yllen's avatar
CS    
yllen committed
47
   /**
Anael Mobilia's avatar
Anael Mobilia committed
48
    * @since 0.84
yllen's avatar
CS    
yllen committed
49
   **/
50
   function getForbiddenStandardMassiveAction() {
yllen's avatar
CS    
yllen committed
51
52

      $forbidden   = parent::getForbiddenStandardMassiveAction();
moyooo's avatar
moyooo committed
53
      $forbidden[] = 'update';
54
55
      return $forbidden;
   }
yllen's avatar
CS    
yllen committed
56
57


58
   static function getTypeName($nb = 0) {
59
      return _n('Link Ticket/Problem', 'Links Ticket/Problem', $nb);
moyooo's avatar
moyooo committed
60
61
   }

yllen's avatar
CS    
yllen committed
62
63
64
65

   /**
    * @see CommonGLPI::getTabNameForItem()
   **/
66
   function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
moyooo's avatar
moyooo committed
67
68
69
70
71
72

      if (static::canView()) {
         $nb = 0;
         switch ($item->getType()) {
            case 'Ticket' :
               if ($_SESSION['glpishow_count_on_tabs']) {
73
74
                  $problems = self::getTicketProblemsData($item->getID());
                  $nb = count($problems);
moyooo's avatar
moyooo committed
75
               }
76
               return self::createTabEntry(Problem::getTypeName(Session::getPluralNumber()), $nb);
moyooo's avatar
moyooo committed
77

moyooo's avatar
moyooo committed
78
79
            case 'Problem' :
               if ($_SESSION['glpishow_count_on_tabs']) {
80
81
                  $tickets = self::getProblemTicketsData($item->getID());
                  $nb = count($tickets);
moyooo's avatar
moyooo committed
82
               }
83
               return self::createTabEntry(Ticket::getTypeName(Session::getPluralNumber()), $nb);
moyooo's avatar
moyooo committed
84
85
86
87
88
89
         }
      }
      return '';
   }


90
   static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
moyooo's avatar
moyooo committed
91
92
93
94
95

      switch ($item->getType()) {
         case 'Ticket' :
            self::showForTicket($item);
            break;
yllen's avatar
CS    
yllen committed
96

moyooo's avatar
moyooo committed
97
98
99
100
101
102
         case 'Problem' :
            self::showForProblem($item);
            break;
      }
      return true;
   }
yllen's avatar
CS    
yllen committed
103
104


yllen's avatar
yllen committed
105
   /**
Anael Mobilia's avatar
Anael Mobilia committed
106
    * @since 0.84
yllen's avatar
yllen committed
107
   **/
108
109
   function post_addItem() {
      global $CFG_GLPI;
yllen's avatar
yllen committed
110

111
      $donotif = !isset($this->input['_disablenotif']) && $CFG_GLPI["use_notifications"];
112
113
114
115

      if ($donotif) {
         $problem = new Problem();
         if ($problem->getFromDB($this->input["problems_id"])) {
116
            $options = [];
yllen's avatar
yllen committed
117
            NotificationEvent::raiseEvent("new", $problem, $options);
118
119
120
121
122
123
         }
      }

      parent::post_addItem();
   }

yllen's avatar
yllen committed
124
125

   /**
Anael Mobilia's avatar
Anael Mobilia committed
126
    * @since 0.84
yllen's avatar
yllen committed
127
   **/
128
129
130
   function post_deleteFromDB() {
      global $CFG_GLPI;

Johan Cwiklinski's avatar
Johan Cwiklinski committed
131
      $donotif = !isset($this->input['_disablenotif']) && $CFG_GLPI["use_notifications"];
132
133
134
135

      if ($donotif) {
         $problem = new Problem();
         if ($problem->getFromDB($this->fields["problems_id"])) {
136
            $options = [];
yllen's avatar
yllen committed
137
            NotificationEvent::raiseEvent("delete", $problem, $options);
138
139
140
141
142
         }
      }

      parent::post_deleteFromDB();
   }
yllen's avatar
yllen committed
143

yllen's avatar
CS    
yllen committed
144

145
   /**
Anael Mobilia's avatar
Anael Mobilia committed
146
    * @since 0.85
yllen's avatar
CS    
yllen committed
147
    *
webmyster's avatar
webmyster committed
148
    * @see CommonDBTM::showMassiveActionsSubForm()
149
   **/
webmyster's avatar
webmyster committed
150
151
   static function showMassiveActionsSubForm(MassiveAction $ma) {
      switch ($ma->getAction()) {
152
153
154
         case 'add_task' :
            $tasktype = 'TicketTask';
            if ($ttype = getItemForItemtype($tasktype)) {
155
               $ttype->showMassiveActionAddTaskForm();
156
157
158
               return true;
            }
            return false;
159

160
161
         case "solveticket" :
            $problem = new Problem();
webmyster's avatar
webmyster committed
162
            $input = $ma->getInput();
163
            if (isset($input['problems_id']) && $problem->getFromDB($input['problems_id'])) {
164
165
               $problem->showMassiveSolutionForm($problem);
               echo "<br>";
166
               echo Html::submit(_x('button', 'Post'), ['name' => 'massiveaction']);
167
168
169
170
               return true;
            }
            return false;
      }
webmyster's avatar
webmyster committed
171
      return parent::showMassiveActionsSubForm($ma);
172
   }
yllen's avatar
CS    
yllen committed
173
174


175
   /**
Anael Mobilia's avatar
Anael Mobilia committed
176
    * @since 0.85
yllen's avatar
CS    
yllen committed
177
    *
webmyster's avatar
webmyster committed
178
    * @see CommonDBTM::processMassiveActionsForOneItemtype()
179
   **/
webmyster's avatar
webmyster committed
180
181
   static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBTM $item,
                                                       array $ids) {
182

webmyster's avatar
webmyster committed
183
      switch ($ma->getAction()) {
184
185
186
187
188
189
190
191
192
193
194
195
196
         case 'add_task' :
            if (!($task = getItemForItemtype('TicketTask'))) {
               $ma->itemDone($item->getType(), $ids, MassiveAction::ACTION_KO);
               break;
            }
            $ticket = new Ticket();
            $field = $ticket->getForeignKeyField();

            $input = $ma->getInput();

            foreach ($ids as $id) {
               if ($item->can($id, READ)) {
                  if ($ticket->getFromDB($item->fields['tickets_id'])) {
197
                     $input2 = [$field              => $item->fields['tickets_id'],
198
199
                                  'taskcategories_id' => $input['taskcategories_id'],
                                  'actiontime'        => $input['actiontime'],
200
                                  'content'           => $input['content']];
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
                     if ($task->can(-1, CREATE, $input2)) {
                        if ($task->add($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));
                     }
                  } else {
                     $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT);
                     $ma->addMessage($item->getErrorMessage(ERROR_RIGHT));
                  }
               }
            }
            return;
219

220
         case 'solveticket' :
webmyster's avatar
webmyster committed
221
            $input  = $ma->getInput();
222
            $ticket = new Ticket();
webmyster's avatar
webmyster committed
223
224
225
226
            foreach ($ids as $id) {
               if ($item->can($id, READ)) {
                  if ($ticket->getFromDB($item->fields['tickets_id'])
                      && $ticket->canSolve()) {
227
228
229
230
231
232
233
234
235
                     $solution = new ITILSolution();
                     $added = $solution->add([
                        'itemtype'  => $ticket->getType(),
                        'items_id'  => $ticket->getID(),
                        'solutiontypes_id'   => $input['solutiontypes_id'],
                        'content'            => $input['content']
                     ]);

                     if ($added) {
webmyster's avatar
webmyster committed
236
                        $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK);
237
                     } else {
webmyster's avatar
webmyster committed
238
239
                        $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO);
                        $ma->addMessage($ticket->getErrorMessage(ERROR_ON_ACTION));
240
241
                     }
                  } else {
webmyster's avatar
webmyster committed
242
243
                     $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT);
                     $ma->addMessage($ticket->getErrorMessage(ERROR_RIGHT));
244
                  }
webmyster's avatar
webmyster committed
245
246
247
               } else {
                  $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_NORIGHT);
                  $ma->addMessage($ticket->getErrorMessage(ERROR_RIGHT));
248
249
               }
            }
webmyster's avatar
webmyster committed
250
            return;
251
      }
webmyster's avatar
webmyster committed
252
      parent::processMassiveActionsForOneItemtype($ma, $item, $ids);
253
   }
yllen's avatar
CS    
yllen committed
254
255


moyooo's avatar
moyooo committed
256
257
258
259
260
261
262
263
   /**
    * Show tickets for a problem
    *
    * @param $problem Problem object
   **/
   static function showForProblem(Problem $problem) {

      $ID = $problem->getField('id');
264
265

      if (!static::canView() || !$problem->can($ID, READ)) {
moyooo's avatar
moyooo committed
266
267
268
         return false;
      }

moyooo's avatar
moyooo committed
269
      $canedit = $problem->canEdit($ID);
moyooo's avatar
moyooo committed
270

yllen's avatar
yllen committed
271
      $rand = mt_rand();
moyooo's avatar
moyooo committed
272

273
      $tickets = self::getProblemTicketsData($ID);
274
      $used    = [];
275
276
277
      $numrows = count($tickets);
      foreach ($tickets as $ticket) {
         $used[$ticket['id']] = $ticket['id'];
moyooo's avatar
moyooo committed
278
279
      }

yllen's avatar
yllen committed
280
281
282
      if ($canedit
          && !in_array($problem->fields['status'], array_merge($problem->getClosedStatusArray(),
                                                               $problem->getSolvedStatusArray()))) {
283
284
285
286
287
288
289
290
         echo "<div class='firstbloc'>";
         echo "<form name='changeticket_form$rand' id='changeticket_form$rand' method='post'
               action='".Toolbox::getItemTypeFormURL(__CLASS__)."'>";

         echo "<table class='tab_cadre_fixe'>";
         echo "<tr class='tab_bg_2'><th colspan='2'>".__('Add a ticket')."</th></tr>";

         echo "<tr class='tab_bg_2'><td class='right'>";
moyooo's avatar
moyooo committed
291
         echo "<input type='hidden' name='problems_id' value='$ID'>";
292
293
294
295
         Ticket::dropdown([
            'used'        => $used,
            'entity'      => $problem->getEntityID(),
            'entity_sons' => $problem->isRecursive(),
296
297
            'displaywith' => ['id'],
            'condition'   => Ticket::getOpenCriteria()
298
         ]);
moyooo's avatar
moyooo committed
299
         echo "</td><td class='center'>";
300
         echo "<input type='submit' name='add' value=\""._sx('button', 'Add')."\" class='submit'>";
moyooo's avatar
moyooo committed
301
         echo "</td></tr>";
302
303
304
305

         echo "</table>";
         Html::closeForm();
         echo "</div>";
moyooo's avatar
moyooo committed
306
307
      }

308
309
310
      echo "<div class='spaced'>";
      if ($canedit && $numrows) {
         Html::openMassiveActionsForm('mass'.__CLASS__.$rand);
311
         $massiveactionparams = ['num_displayed'    => min($_SESSION['glpilist_limit'], $numrows),
moyooo's avatar
moyooo committed
312
                                      'container'        => 'mass'.__CLASS__.$rand,
313
                                      'specific_actions' => ['purge'
yllen's avatar
CS    
yllen committed
314
                                                                    => _x('button',
yllen's avatar
CS    
yllen committed
315
                                                                          'Delete permanently'),
webmyster's avatar
webmyster committed
316
                                                                  __CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'solveticket'
317
                                                                    => __('Solve tickets'),
318
                                                                  __CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR.'add_task'
319
320
                                                                    => __('Add a new task')],
                                      'extraparams'      => ['problems_id' => $problem->getID()],
yllen's avatar
CS    
yllen committed
321
                                      'width'            => 1000,
322
                                      'height'           => 500];
moyooo's avatar
moyooo committed
323
         Html::showMassiveActions($massiveactionparams);
324
325
      }
      echo "<table class='tab_cadre_fixehov'>";
moyooo's avatar
moyooo committed
326
      echo "<tr class='noHover'><th colspan='12'>".Ticket::getTypeName($numrows)."</th>";
327
328
      echo "</tr>";
      if ($numrows) {
329
         Ticket::commonListHeader(Search::HTML_OUTPUT, 'mass'.__CLASS__.$rand);
330
331
332
         Session::initNavigateListItems('Ticket',
                                 //TRANS : %1$s is the itemtype name,
                                 //        %2$s is the name of the item (used for headings of a list)
yllen's avatar
CS    
yllen committed
333
                                         sprintf(__('%1$s = %2$s'), Problem::getTypeName(1),
yllen's avatar
CS    
yllen committed
334
                                                 $problem->fields["name"]));
moyooo's avatar
moyooo committed
335

336
337
338
         $i = 0;
         foreach ($tickets as $data) {
            Session::addToNavigateListItems('Ticket', $data["id"]);
Cédric Anne's avatar
Cédric Anne committed
339
340
341
342
343
344
345
346
            Ticket::showShort(
               $data['id'],
               [
                  'row_num'                => $i,
                  'type_for_massiveaction' => __CLASS__,
                  'id_for_massiveaction'   => $data['linkid']
               ]
            );
347
348
            $i++;
         }
349
         Ticket::commonListHeader(Search::HTML_OUTPUT, 'mass'.__CLASS__.$rand);
moyooo's avatar
moyooo committed
350
      }
351
352
353
      echo "</table>";
      if ($canedit && $numrows) {
         $massiveactionparams['ontop'] = false;
moyooo's avatar
moyooo committed
354
         Html::showMassiveActions($massiveactionparams);
355
356
357
358
         Html::closeForm();
      }
      echo "</div>";

moyooo's avatar
moyooo committed
359
360
   }

yllen's avatar
yllen committed
361

moyooo's avatar
moyooo committed
362
363
364
   /**
    * Show problems for a ticket
    *
yllen's avatar
yllen committed
365
    * @param $ticket Ticket object
moyooo's avatar
moyooo committed
366
367
368
369
   **/
   static function showForTicket(Ticket $ticket) {

      $ID = $ticket->getField('id');
370

371
      if (!static::canView() || !$ticket->can($ID, READ)) {
moyooo's avatar
moyooo committed
372
373
374
         return false;
      }

moyooo's avatar
moyooo committed
375
      $canedit = $ticket->can($ID, UPDATE);
moyooo's avatar
moyooo committed
376

yllen's avatar
yllen committed
377
      $rand = mt_rand();
moyooo's avatar
moyooo committed
378

379
      $problems = self::getTicketProblemsData($ID);
380
      $used     = [];
381
382
383
      $numrows  = count($problems);
      foreach ($problems as $problem) {
         $used[$problem['id']] = $problem['id'];
384
      }
yllen's avatar
yllen committed
385
386
387
      if ($canedit
          && !in_array($ticket->fields['status'], array_merge($ticket->getClosedStatusArray(),
                                                              $ticket->getSolvedStatusArray()))) {
388
389
         echo "<div class='firstbloc'>";
         echo "<form name='problemticket_form$rand' id='problemticket_form$rand' method='post'
yllen's avatar
CS    
yllen committed
390
                action='".Toolbox::getItemTypeFormURL(__CLASS__)."'>";
moyooo's avatar
moyooo committed
391

392
393
394
395
         echo "<table class='tab_cadre_fixe'>";
         echo "<tr class='tab_bg_2'><th colspan='3'>".__('Add a problem')."</th></tr>";
         echo "<tr class='tab_bg_2'><td>";
         echo "<input type='hidden' name='tickets_id' value='$ID'>";
396
397
398
399

         Problem::dropdown([
            'used'      => $used,
            'entity'    => $ticket->getEntityID(),
400
            'condition' => Problem::getOpenCriteria()
401
         ]);
402
         echo "</td><td class='center'>";
403
         echo "<input type='submit' name='add' value=\""._sx('button', 'Add')."\" class='submit'>";
404
         echo "</td><td>";
405
406
407
408
409
         if (Session::haveRight('problem', CREATE)) {
            echo "<a href='".Toolbox::getItemTypeFormURL('Problem')."?tickets_id=$ID'>";
            echo __('Create a problem from this ticket');
            echo "</a>";
         }
410
411
412
413
414
415
416
417
418

         echo "</td></tr></table>";
         Html::closeForm();
         echo "</div>";
      }

      echo "<div class='spaced'>";
      if ($canedit && $numrows) {
         Html::openMassiveActionsForm('mass'.__CLASS__.$rand);
419
420
         $massiveactionparams = ['num_displayed'  => min($_SESSION['glpilist_limit'], $numrows),
                                      'container'      => 'mass'.__CLASS__.$rand];
moyooo's avatar
moyooo committed
421
         Html::showMassiveActions($massiveactionparams);
422
423
      }
      echo "<table class='tab_cadre_fixehov'>";
moyooo's avatar
moyooo committed
424
      echo "<tr class='noHover'><th colspan='12'>".Problem::getTypeName($numrows)."</th>";
yllen's avatar
CS    
yllen committed
425
      echo "</tr>";
426
      if ($numrows) {
427
         Problem::commonListHeader(Search::HTML_OUTPUT, 'mass'.__CLASS__.$rand);
remi's avatar
gettext    
remi committed
428
         Session::initNavigateListItems('Problem',
yllen's avatar
yllen committed
429
430
                              //TRANS : %1$s is the itemtype name,
                              //        %2$s is the name of the item (used for headings of a list)
yllen's avatar
yllen committed
431
                                        sprintf(__('%1$s = %2$s'),
yllen's avatar
CS    
yllen committed
432
                                                Ticket::getTypeName(1), $ticket->fields["name"]));
moyooo's avatar
gettext    
moyooo committed
433

yllen's avatar
CS    
yllen committed
434
         $i = 0;
435
         foreach ($problems as $data) {
yllen's avatar
yllen committed
436
            Session::addToNavigateListItems('Problem', $data["id"]);
437
            Problem::showShort($data['id'], ['row_num'                => $i,
moyooo's avatar
moyooo committed
438
                                                  'type_for_massiveaction' => __CLASS__,
439
                                                  'id_for_massiveaction'   => $data['linkid']]);
moyooo's avatar
moyooo committed
440
            $i++;
moyooo's avatar
moyooo committed
441
         }
442
         Problem::commonListHeader(Search::HTML_OUTPUT, 'mass'.__CLASS__.$rand);
moyooo's avatar
moyooo committed
443
444
      }

445
446
447
      echo "</table>";
      if ($canedit && $numrows) {
         $massiveactionparams['ontop'] = false;
moyooo's avatar
moyooo committed
448
         Html::showMassiveActions($massiveactionparams);
449
         Html::closeForm();
moyooo's avatar
moyooo committed
450
      }
451
      echo "</div>";
moyooo's avatar
moyooo committed
452
453
   }

454
455
456
457
458
459
460
461
462
463
464
465
466
   /**
    * Returns problems data for given ticket.
    * Returned data is usable by `Problem::showShort()` method.
    *
    * @param integer $tickets_id
    *
    * @return array
    */
   private static function getTicketProblemsData($tickets_id) {

      $ticket = new Ticket();
      $ticket->fields['id'] = $tickets_id;
      $iterator = self::getListForItem($ticket);
yllen's avatar
yllen committed
467

468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
      $problems = [];
      foreach ($iterator as $data) {
         $problem = new Problem();
         $problem->getFromDB($data['id']);
         if ($problem->canViewItem()) {
            $problems[$data['id']] = $data;
         }
      }

      return $problems;
   }

   /**
    * Returns tickets data for given problem.
    * Returned data is usable by `Ticket::showShort()` method.
    *
    * @param integer $problems_id
    *
    * @return array
    */
   private static function getProblemTicketsData($problems_id) {

      $problem = new Problem();
      $problem->fields['id'] = $problems_id;
      $iterator = self::getListForItem($problem);

      $tickets = [];
      foreach ($iterator as $data) {
         $ticket = new Ticket();
         $ticket->getFromDB($data['id']);
         if ($ticket->canViewItem()) {
            $tickets[$data['id']] = $data;
         }
      }

      return $tickets;
   }
moyooo's avatar
moyooo committed
505
}