notificationtarget.class.php 44.7 KB
Newer Older
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/>.
 * ---------------------------------------------------------------------
31
32
 */

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

moyooo's avatar
moyooo committed
37
38
39
40

/**
 * NotificationTarget Class
 *
Anael Mobilia's avatar
Anael Mobilia committed
41
 * @since 0.84
moyooo's avatar
moyooo committed
42
**/
43
class NotificationTarget extends CommonDBChild {
44

yllen's avatar
yllen committed
45
   public $prefix                      = '';
46
   // From CommonDBChild
yllen's avatar
yllen committed
47
48
49
   static public $itemtype             = 'Notification';
   static public $items_id             = 'notifications_id';
   public $table                       = 'glpi_notificationtargets';
50

51
52
   public $notification_targets        = [];
   public $notification_targets_labels = [];
yllen's avatar
yllen committed
53
   public $notificationoptions         = 0;
Walid Nouh's avatar
Walid Nouh committed
54

55
   // Tags which have data in HTML : do not try to clean them
56
   public $html_tags                   = [];
57

58
59
   // Data from the objet which can be used by the template
   // See https://forge.indepnet.net/projects/5/wiki/NotificationTemplatesTags
60
61
   public $data                        = [];
   public $tag_descriptions            = [];
62

63
   // From CommonDBTM
yllen's avatar
yllen committed
64
   public $dohistory                   = true;
65
66

   //Array to store emails by notification
67
   public $target                      = [];
yllen's avatar
yllen committed
68
   public $entity                      = '';
69
70

   //Object which raises the notification event
yllen's avatar
yllen committed
71
   public $obj                         = null;
72

Walid Nouh's avatar
Walid Nouh committed
73
   //Object which is associated with the event
74
   public $target_object               = [];
Walid Nouh's avatar
Walid Nouh committed
75

76
   // array of event name => event label
77
78
   public $events                      = [];
   public $options                     = [];
yllen's avatar
yllen committed
79
   public $raiseevent                  = '';
Walid Nouh's avatar
Walid Nouh committed
80

81
   private $allow_response             = true;
Johan Cwiklinski's avatar
Johan Cwiklinski committed
82
83
84
   private $mode                       = null;
   private $event                      = null;

yllen's avatar
yllen committed
85
86
87
   const TAG_LANGUAGE               = 'lang';
   const TAG_VALUE                  = 'tag';
   const TAG_FOR_ALL_EVENTS         = 0;
Walid Nouh's avatar
Walid Nouh committed
88

yllen's avatar
yllen committed
89

90
91
92
93
   const ANONYMOUS_USER             = 0;
   const GLPI_USER                  = 1;
   const EXTERNAL_USER              = 2;

yllen's avatar
yllen committed
94
   /**
Johan Cwiklinski's avatar
Johan Cwiklinski committed
95
96
97
98
    * @param string $entity  (default '')
    * @param string $event   (default '')
    * @param mixed  $object  (default null)
    * @param array  $options Options
yllen's avatar
yllen committed
99
   **/
100
   function __construct($entity = '', $event = '', $object = null, $options = []) {
yllen's avatar
yllen committed
101

remi's avatar
remi committed
102
      if ($entity === '') {
103
         $this->entity = (isset($_SESSION['glpiactive_entity'])?$_SESSION['glpiactive_entity']:0);
yllen's avatar
yllen committed
104
      } else {
105
106
         $this->entity = $entity;
      }
107

108
      if ($object) {
yllen's avatar
yllen committed
109
110
         if ($object instanceof CommonDBTM
             && isset($object->fields['id'])) {
111
112
113
            // Reread to avoid slashes issue
            $object->getFromDB($object->fields['id']);
         }
114
         $this->obj = $object;
Walid Nouh's avatar
Walid Nouh committed
115
         $this->getObjectItem($event);
Walid Nouh's avatar
Walid Nouh committed
116
      }
yllen's avatar
yllen committed
117

Walid Nouh's avatar
Walid Nouh committed
118
      $this->raiseevent = $event;
yllen's avatar
yllen committed
119
      $this->options    = $options;
Johan Cwiklinski's avatar
Johan Cwiklinski committed
120

Johan Cwiklinski's avatar
Johan Cwiklinski committed
121
      $this->addNotificationTargets($this->entity);
Johan Cwiklinski's avatar
Johan Cwiklinski committed
122
123
124

      $this->addAdditionalTargets($event);

yllen's avatar
yllen committed
125
126
127
      // add new target by plugin
      unset($this->data);
      Plugin::doHook('item_add_targets', $this);
128
      asort($this->notification_targets);
129
130
   }

yllen's avatar
CS    
yllen committed
131

132
133
134
135
136
   static function getTable($classname = null) {
      return parent::getTable(__CLASS__);
   }


moyooo's avatar
moyooo committed
137
138
139
   /**
    * Retrieve an item from the database for a specific target
    *
Johan Cwiklinski's avatar
Johan Cwiklinski committed
140
141
142
    * @param integer $notifications_id notification ID
    * @param string  $type             type of the target to retrive
    * @param integer $ID               ID of the target to retrieve
moyooo's avatar
moyooo committed
143
    *
Anael Mobilia's avatar
Anael Mobilia committed
144
    * @since 0.85
moyooo's avatar
moyooo committed
145
    *
Johan Cwiklinski's avatar
Johan Cwiklinski committed
146
    * @return boolean
moyooo's avatar
moyooo committed
147
148
149
   **/
   function getFromDBForTarget($notifications_id, $type, $ID) {

150
151
152
153
154
      if ($this->getFromDBByCrit([
         $this->getTable() . '.notifications_id'   => $notifications_id,
         $this->getTable() . '.items_id'           => $ID,
         $this->getTable() . '.type'               => $type
      ])) {
moyooo's avatar
moyooo committed
155
156
157
158
159
160
         return true;
      }
      return false;
   }


yllen's avatar
yllen committed
161
162
163
   /**
    * Validate send before doing it (may be overloaded : exemple for private tasks or followups)
    *
Anael Mobilia's avatar
Anael Mobilia committed
164
    * @since 0.84 (new parameter)
moyooo's avatar
moyooo committed
165
    *
Johan Cwiklinski's avatar
Johan Cwiklinski committed
166
167
168
169
170
    * @param string  $event     notification event
    * @param array   $infos     destination of the notification
    * @param boolean $notify_me notify me on my action ?
    *                           ($infos contains users_id to check if the target is me)
    *                           (false by default)
171
172
173
174
175
    * @param mixed $emitter     if this action is executed by the cron, we can
    *                           supply the id of the user (or the email if this
    *                           is an anonymous user with no account) who
    *                           triggered the event so it can be used instead of
    *                           getLoginUserID
yllen's avatar
yllen committed
176
    *
Johan Cwiklinski's avatar
Johan Cwiklinski committed
177
    * @return boolean
yllen's avatar
yllen committed
178
   **/
179
180
181
182
   function validateSendTo($event, array $infos, $notify_me = false, $emitter = null) {
      $users_id = Session::getLoginUserID(false);

      // Override session ID with emitter ID if supplied
183
184
      if (is_int($emitter)) {
         // We have an ID, we can use it directly
185
         $users_id = $emitter;
186
187
188
189
190
191
192
193
      } else if (is_string($emitter)) {
         // We have an email, we need to check that the users_id is -1 which
         // is the value used for anonymous user and compare the emails
         if (isset($infos['users_id']) && $infos['users_id'] == -1
            && isset($infos['email']) && $infos['email'] == $emitter
         ) {
            $users_id = -1;
         }
194
      }
moyooo's avatar
moyooo committed
195

196
      if (!$notify_me) {
yllen's avatar
CS    
yllen committed
197
         if (isset($infos['users_id'])
moyooo's avatar
moyooo committed
198
            // Check login user and not event launch by crontask
199
             && ($infos['users_id'] === $users_id)) {
200
201
202
            return false;
         }
      }
yllen's avatar
CS    
yllen committed
203

204
205
206
      return true;
   }

yllen's avatar
yllen committed
207

yllen's avatar
yllen committed
208
209
210
   /**
    * @param $event  (default '')
   **/
211
   function getSubjectPrefix($event = '') {
yllen's avatar
yllen committed
212

213
      $perso_tag = trim(Entity::getUsedConfig('notification_subject_tag', $this->getEntity(),
yllen's avatar
CS    
yllen committed
214
                                              '', ''));
215
216
      if (empty($perso_tag)) {
         $perso_tag = "GLPI";
217
      }
218
219
      return "[$perso_tag] ";

220
   }
Walid Nouh's avatar
Walid Nouh committed
221

moyooo's avatar
moyooo committed
222
223
224
225
226
227
228
229
230
231
232
233
234
235
   /**
   * Get header to add to content
   **/
   function getContentHeader() {
      return '';
   }

   /**
   * Get footer to add to content
   **/
   function getContentFooter() {
      return '';
   }

yllen's avatar
CS    
yllen committed
236
   /**
237
238
    * Get a unique message id.
    *
Anael Mobilia's avatar
Anael Mobilia committed
239
    * @since 0.84
yllen's avatar
CS    
yllen committed
240
    *
241
242
    * @return string
    */
243
   function getMessageID() {
244
245
      if ($this->obj instanceof CommonDBTM) {
         return sprintf(
246
247
            'GLPI_%s-%s-%s.%s.%s@%s',
            Config::getUuid('notification'),
248
249
250
251
252
253
254
255
256
            $this->obj->getType(),
            $this->obj->getField('id'),
            time(),
            rand(),
            php_uname('n')
         );
      }

      return sprintf(
257
258
         'GLPI_%s.%s.%s@%s',
         Config::getUuid('notification'),
259
260
261
262
         time(),
         rand(),
         php_uname('n')
      );
263
   }
yllen's avatar
CS    
yllen committed
264

yllen's avatar
CS    
yllen committed
265

266
   static function getTypeName($nb = 0) {
moyooo's avatar
moyooo committed
267
      return _n('Recipient', 'Recipients', $nb);
268
269
   }

270
   protected function computeFriendlyName() {
271

yllen's avatar
yllen committed
272
273
274
275
276
      if (isset($this->notification_targets_labels[$this->getField("type")]
                                                  [$this->getField("items_id")])) {

         return $this->notification_targets_labels[$this->getField("type")]
                                                  [$this->getField("items_id")];
277
      }
278
      return '';
279
   }
yllen's avatar
yllen committed
280

281
282
   /**
    * Get a notificationtarget class by giving the object which raises the event
yllen's avatar
yllen committed
283
    *
yllen's avatar
yllen committed
284
285
286
    * @param $item            the object which raises the event
    * @param $event           the event which will be used (default '')
    * @param $options   array of options
yllen's avatar
yllen committed
287
    *
288
    * @return NotificationTarget|false
yllen's avatar
yllen committed
289
   **/
290
   static function getInstance($item, $event = '', $options = []) {
yllen's avatar
yllen committed
291

adelaunay's avatar
adelaunay committed
292
293
294
      $itemtype = $item->getType();
      if ($plug = isPluginItemType($itemtype)) {
         // plugins case
295
         $name = 'Plugin'.$plug['plugin'].'NotificationTarget'.$plug['class'];
adelaunay's avatar
lint    
adelaunay committed
296
      } else if (strpos($itemtype, "\\" ) != false) {
adelaunay's avatar
adelaunay committed
297
298
299
300
         // namespace case
         $ns_parts = explode("\\", $itemtype);
         $classname = array_pop($ns_parts);
         $name = implode("\\", $ns_parts)."\\NotificationTarget$classname";
yllen's avatar
yllen committed
301
      } else {
adelaunay's avatar
adelaunay committed
302
303
         // simple class (without namespace)
         $name = "NotificationTarget$itemtype";
304
305
      }

306
      $entity = 0;
307
      if (class_exists($name)) {
remi's avatar
remi committed
308
309
310
311
         //Entity ID exists in the options array
         if (isset($options['entities_id'])) {
            $entity = $options['entities_id'];

adelaunay's avatar
adelaunay committed
312
         } else if (method_exists($item, 'getEntityID') && $item->getEntityID() >= 0) {
313
            //Item which raises the event contains an entityID
moyooo's avatar
moyooo committed
314
            $entity = $item->getEntityID();
yllen's avatar
yllen committed
315

316
         }
yllen's avatar
yllen committed
317

318
         return new $name($entity, $event, $item, $options);
319
      }
yllen's avatar
yllen committed
320
      return false;
321
322
   }

yllen's avatar
yllen committed
323

324
325
   /**
    * Get a notificationtarget class by giving an itemtype
yllen's avatar
yllen committed
326
    *
yllen's avatar
yllen committed
327
328
329
    * @param $itemtype           the itemtype of the object which raises the event
    * @param $event              the event which will be used (default '')
    * @param $options   array    of options
yllen's avatar
yllen committed
330
    *
331
    * @return a notificationtarget class or false
yllen's avatar
yllen committed
332
   **/
333
   static function getInstanceByType($itemtype, $event = '', $options = []) {
yllen's avatar
yllen committed
334

335
      if (($itemtype)
yllen's avatar
yllen committed
336
          && ($item = getItemForItemtype($itemtype))) {
yllen's avatar
yllen committed
337
         return self::getInstance($item, $event, $options);
338
      }
yllen's avatar
yllen committed
339
      return false;
340
341
   }

yllen's avatar
yllen committed
342

yllen's avatar
yllen committed
343
344
345
   /**
    * @param $notification Notification object
   **/
346
   function showForNotification(Notification $notification) {
moyooo's avatar
moyooo committed
347
      if (!Notification::canView()) {
348
349
         return false;
      }
yllen's avatar
yllen committed
350
      if ($notification->getField('itemtype') != '') {
351
         $notifications_id = $notification->fields['id'];
moyooo's avatar
moyooo committed
352
         $canedit = $notification->can($notifications_id, UPDATE);
353

moyooo's avatar
moyooo committed
354
355
356
357
358
359
         if ($canedit) {
            echo "<form name='notificationtargets_form' id='notificationtargets_form'
                  method='post' action=' ";
            echo Toolbox::getItemTypeFormURL(__CLASS__)."'>";
            echo "<input type='hidden' name='notifications_id' value='".$notification->getField('id')."'>";
            echo "<input type='hidden' name='itemtype' value='".$notification->getField('itemtype')."'>";
360

361
         }
moyooo's avatar
moyooo committed
362
         echo "<table class='tab_cadre_fixe'>";
moyooo's avatar
moyooo committed
363
         echo "<tr><th colspan='4'>" . _n('Recipient', 'Recipients', Session::getPluralNumber()) . "</th></tr>";
moyooo's avatar
moyooo committed
364
365
         echo "<tr class='tab_bg_2'>";

366
         $values = [];
moyooo's avatar
moyooo committed
367
368
369
         foreach ($this->notification_targets as $key => $val) {
            list($type,$id) = explode('_', $key);
            $values[$key]   = $this->notification_targets_labels[$type][$id];
370
         }
371
         $targets = getAllDataFromTable(
372
373
374
375
            self::getTable(), [
               'notifications_id' => $notifications_id
            ]
         );
376
         $actives = [];
moyooo's avatar
moyooo committed
377
378
379
         if (count($targets)) {
            foreach ($targets as $data) {
               $actives[$data['type'].'_'.$data['items_id']] = $data['type'].'_'.$data['items_id'];
380
381
382
            }
         }

moyooo's avatar
moyooo committed
383
         echo "<td>";
384
         Dropdown::showFromArray('_targets', $values, ['values'   => $actives,
moyooo's avatar
moyooo committed
385
                                                            'multiple' => true,
386
                                                            'readonly' => !$canedit]);
moyooo's avatar
moyooo committed
387
         echo "</td>";
388
         if ($canedit) {
moyooo's avatar
moyooo committed
389
390
391
            echo "<td width='20%'>";
            echo "<input type='submit' class='submit' name='update' value=\""._x('button', 'Update')."\">";
            echo "</td>";
yllen's avatar
yllen committed
392

393
         }
moyooo's avatar
moyooo committed
394
395
396
         echo "</tr>";
         echo "</table>";
      }
397

moyooo's avatar
moyooo committed
398
399
      if ($canedit) {
         Html::closeForm();
400
401
402
      }
   }

yllen's avatar
yllen committed
403

moyooo's avatar
moyooo committed
404

yllen's avatar
yllen committed
405
406
407
   /**
    * @param $input
   **/
408
409
   static function updateTargets($input) {

yllen's avatar
yllen committed
410
      $type   = "";
411
      $action = "";
adelaunay's avatar
adelaunay committed
412
      $target = self::getInstanceByType(stripslashes($input['itemtype']));
413

moyooo's avatar
moyooo committed
414
415
416
      if (!isset($input['notifications_id'])) {
         return;
      }
417
      $targets = getAllDataFromTable(
418
419
420
421
         self::getTable(), [
            'notifications_id' => $input['notifications_id']
         ]
      );
422
      $actives = [];
moyooo's avatar
moyooo committed
423
424
425
426
427
428
429
430
431
432
433
434
435
436
      if (count($targets)) {
         foreach ($targets as $data) {
            $actives[$data['type'].'_'.$data['items_id']] = $data['type'].'_'.$data['items_id'];
         }
      }
      // Be sure to have items once
      $actives = array_unique($actives);
      if (isset($input['_targets']) && count($input['_targets'])) {
         // Be sure to have items once
         $input['_targets'] = array_unique($input['_targets']);
         foreach ($input['_targets'] as $val) {
            // Add if not set
            if (!isset($actives[$val])) {
               list($type, $items_id)   = explode("_", $val);
437
               $tmp                     = [];
moyooo's avatar
moyooo committed
438
439
440
441
442
443
444
               $tmp['items_id']         = $items_id;
               $tmp['type']             = $type;
               $tmp['notifications_id'] = $input['notifications_id'];
               $target->add($tmp);
            }
            unset($actives[$val]);
         }
445
446
      }

moyooo's avatar
moyooo committed
447
448
449
450
451
      // Drop others
      if (count($actives)) {
         foreach ($actives as $val) {
            list($type, $items_id) = explode("_", $val);
            if ($target->getFromDBForTarget($input['notifications_id'], $type, $items_id)) {
452
               $target->delete(['id' => $target->getID()]);
moyooo's avatar
moyooo committed
453
            }
454
         }
yllen's avatar
yllen committed
455
      }
456
457
   }

yllen's avatar
yllen committed
458

Walid Nouh's avatar
Walid Nouh committed
459
460
461
   function addAdditionnalInfosForTarget() {
   }

yllen's avatar
yllen committed
462

yllen's avatar
yllen committed
463
464
465
   /**
    * @param $data
    *
466
    * @return empty array
yllen's avatar
yllen committed
467
   **/
remi's avatar
remi committed
468
   function addAdditionnalUserInfo(array $data) {
469
      return [];
Walid Nouh's avatar
Walid Nouh committed
470
471
   }

yllen's avatar
yllen committed
472

473
   /**
Johan Cwiklinski's avatar
Johan Cwiklinski committed
474
    * Add new recipient with lang to current recipients array
475
    *
Johan Cwiklinski's avatar
Johan Cwiklinski committed
476
477
478
    * @param array $data Data (users_id, lang[, field used for notification])
    *
    * @return void|false
yllen's avatar
yllen committed
479
   **/
Johan Cwiklinski's avatar
Johan Cwiklinski committed
480
   function addToRecipientsList(array $data) {
481
482
      global $CFG_GLPI;

Johan Cwiklinski's avatar
Johan Cwiklinski committed
483
      $new_target = null;
yllen's avatar
yllen committed
484
      $new_lang = '';
Johan Cwiklinski's avatar
Johan Cwiklinski committed
485

486
      // Default USER TYPE is ANONYMOUS
487
      $notificationoption = ['usertype' => self::ANONYMOUS_USER];
488

489
490
      if (isset($data['language'])) {
         $new_lang = trim($data['language']);
Walid Nouh's avatar
Walid Nouh committed
491
      }
yllen's avatar
yllen committed
492
      $username = '';
493
494
      if (isset($data['name']) && !empty($data['name'])) {
         $username = $data['name'];
495
      }
yllen's avatar
yllen committed
496
      if (isset($data['users_id']) && ($data['users_id'] > 0)) {
yllen's avatar
yllen committed
497
         $user = new User();
498
         if (!$user->getFromDB($data['users_id'])
yllen's avatar
yllen committed
499
             || ($user->getField('is_deleted') == 1)
moyooo's avatar
moyooo committed
500
             || ($user->getField('is_active') == 0)
501
502
503
504
             || (!is_null($user->getField('begin_date'))
                  && ($user->getField('begin_date') > $_SESSION["glpi_currenttime"]))
             || (!is_null($user->getField('end_date'))
                  && ($user->getField('end_date') < $_SESSION["glpi_currenttime"]))) {
505
506
507
            // unknown, deleted or disabled user
            return false;
         }
508
509
         $filt = getEntitiesRestrictCriteria('glpi_profiles_users', '', $this->getEntity(),
                                             true);
510
         $prof = Profile_User::getUserProfiles($data['users_id'], $filt);
511
512
513
514
515
         if (!count($prof)) {
            // No right on the entity of the object
            return false;
         }
         if (empty($username)) {
yllen's avatar
yllen committed
516
517
            $username = formatUserName(0, $user->getField('name'), $user->getField('realname'),
                                       $user->getField('firstname'), 0, 0, true);
518
         }
519
520
         // It is a GLPI user :
         $notificationoption['usertype'] = self::GLPI_USER;
521
522
         if ($user->fields['authtype'] == Auth::LDAP
             || Auth::isAlternateAuth($user->fields['authtype'])
yllen's avatar
CS    
yllen committed
523
524
             || (($user->fields['authtype'] == Auth::NOT_YET_AUTHENTIFIED)
                 && Auth::isAlternateAuth(Auth::checkAlternateAuthSystems()))) {
525
526
527
            $notificationoption['usertype'] = self::EXTERNAL_USER;
         }
      }
yllen's avatar
CS    
yllen committed
528

529
530
531
      // Pass user type as argument ? forced for specific cases
      if (isset($data['usertype'])) {
         $notificationoption['usertype'] = $data['usertype'];
532
      }
yllen's avatar
CS    
yllen committed
533

534
      $notificationoption = array_merge($this->addAdditionnalUserInfo($data),
yllen's avatar
CS    
yllen committed
535
                                        $notificationoption);
536

Johan Cwiklinski's avatar
Johan Cwiklinski committed
537
538
539
540
541
542
543
544
545
546
547
548
549
550
      $param = [
         'language'           => (empty($new_lang) ? $CFG_GLPI["language"] : $new_lang),
         'additionnaloption'  => $notificationoption,
         'username'           => $username
      ];
      if (isset($data['users_id']) && $data['users_id']) {
         $param['users_id'] = $data['users_id'];
      }

      $eventclass = $this->event;
      $target_field = $eventclass::getTargetField($data, $param);
      if ($data[$target_field] !== null) {
         $param[$target_field] = $data[$target_field];
         $this->target[$data[$target_field]] = $param;
551
      }
552
553
554
555
556
557
558
559
560

      if (isset($data['users_id']) && $data['users_id']) {
         $this->recipient_data = [
            'itemtype' => User::class,
            'items_id' => $data['users_id'],
         ];
         Plugin::doHook('add_recipient_to_target', $this);
         unset($this->recipient_data);
      }
561
562
   }

yllen's avatar
CS    
yllen committed
563
564

   /**
Anael Mobilia's avatar
Anael Mobilia committed
565
    * @since 0.84
yllen's avatar
CS    
yllen committed
566
   **/
567
   function getDefaultUserType() {
yllen's avatar
CS    
yllen committed
568

569
570
571
      if (Auth::isAlternateAuth(Auth::checkAlternateAuthSystems())) {
         return self::EXTERNAL_USER;
      }
yllen's avatar
CS    
yllen committed
572
      return self::GLPI_USER;
573
   }
yllen's avatar
CS    
yllen committed
574
575
576


   /**
Anael Mobilia's avatar
Anael Mobilia committed
577
    * @since 0.84
yllen's avatar
CS    
yllen committed
578
579
580
581
    *
    * @param $usertype
    * @param $redirect
   **/
582
583
   function formatURL($usertype, $redirect) {
      global $CFG_GLPI;
yllen's avatar
CS    
yllen committed
584

585
586
      switch ($usertype) {
         case self::EXTERNAL_USER :
yllen's avatar
CS    
yllen committed
587
588
            return urldecode($CFG_GLPI["url_base"]."/index.php?redirect=$redirect");

589
590
591
         case self::ANONYMOUS_USER :
            // No URL
            return '';
yllen's avatar
CS    
yllen committed
592

593
         case self::GLPI_USER :
yllen's avatar
CS    
yllen committed
594
            return urldecode($CFG_GLPI["url_base"]."/index.php?redirect=$redirect&noAUTO=1");
595
596
      }
   }
yllen's avatar
yllen committed
597

yllen's avatar
CS    
yllen committed
598

599
   /**
Johan Cwiklinski's avatar
Johan Cwiklinski committed
600
601
602
603
    * Add GLPI's global administrator email
    *
    * @return void
    */
604
   final public function addAdmin() {
Johan Cwiklinski's avatar
Johan Cwiklinski committed
605
606
607
608
609
      $eventclass = $this->event;
      $admin_data = $eventclass::getAdminData();

      if ($admin_data) {
         if (!isset($admin_data['usertype'])) {
610
            $admin_data['usertype'] = $this->getDefaultUserType();
Johan Cwiklinski's avatar
Johan Cwiklinski committed
611
612
613
         }
         $this->addToRecipientsList($admin_data);
      }
614
615
   }

yllen's avatar
yllen committed
616

617
   /**
Johan Cwiklinski's avatar
Johan Cwiklinski committed
618
619
620
621
622
623
    * Add item's author
    *
    * @since 9.2
    *
    * @return void
    */
624
   public function addItemAuthor() {
yllen's avatar
yllen committed
625
      $user = new User();
yllen's avatar
yllen committed
626
627
      if ($this->obj->isField('users_id')
          && $user->getFromDB($this->obj->getField('users_id'))) {
Johan Cwiklinski's avatar
Johan Cwiklinski committed
628
629
630
631
         $this->addToRecipientsList([
            'language' => $user->getField('language'),
            'users_id' => $user->getField('id')
         ]);
632
      }
633
634
   }

yllen's avatar
yllen committed
635

636
   /**
Johan Cwiklinski's avatar
Johan Cwiklinski committed
637
    * Add item's group
yllen's avatar
yllen committed
638
    *
Johan Cwiklinski's avatar
Johan Cwiklinski committed
639
640
641
642
    * @since 9.2
    *
    * @return void
    */
643
   final public function addItemGroup() {
644

moyooo's avatar
moyooo committed
645
      if (!empty($this->target_object)) {
Anael Mobilia's avatar
Anael Mobilia committed
646
         foreach ($this->target_object as $val) {
tsmr's avatar
tsmr committed
647
            if ($val->fields['groups_id'] > 0) {
Johan Cwiklinski's avatar
Johan Cwiklinski committed
648
               $this->addForGroup(0, $val->fields['groups_id']);
moyooo's avatar
moyooo committed
649
            }
650
651
652
653
         }
      }
   }

yllen's avatar
yllen committed
654

655
   /**
Johan Cwiklinski's avatar
Johan Cwiklinski committed
656
    * Add item's group supervisor
yllen's avatar
yllen committed
657
    *
Johan Cwiklinski's avatar
Johan Cwiklinski committed
658
659
660
661
    * @since 9.2
    *
    * @return void
    */
662
   final public function addItemGroupSupervisor() {
moyooo's avatar
moyooo committed
663
664
665
      if (!empty($this->target_object)) {
         foreach ($this->target_object as $val) {
            if ($val->fields['groups_id'] > 0) {
Johan Cwiklinski's avatar
Johan Cwiklinski committed
666
               $this->addForGroup(1, $val->fields['groups_id']);
moyooo's avatar
moyooo committed
667
            }
668
669
670
671
         }
      }
   }

yllen's avatar
yllen committed
672

673
   /**
Johan Cwiklinski's avatar
Johan Cwiklinski committed
674
    * Add item's group users exepted supervisor
yllen's avatar
yllen committed
675
    *
Johan Cwiklinski's avatar
Johan Cwiklinski committed
676
677
678
679
    * @since 9.2
    *
    * @return void
    */
680
   final public function addItemGroupWithoutSupervisor() {
yllen's avatar
yllen committed
681

moyooo's avatar
moyooo committed
682
683
684
      if (!empty($this->target_object)) {
         foreach ($this->target_object as $val) {
            if ($val->fields['groups_id'] > 0) {
Johan Cwiklinski's avatar
Johan Cwiklinski committed
685
               $this->addForGroup(2, $val->fields['groups_id']);
moyooo's avatar
moyooo committed
686
            }
687
688
689
         }
      }
   }
yllen's avatar
yllen committed
690
691


692
   /**
Johan Cwiklinski's avatar
Johan Cwiklinski committed
693
694
695
696
    * Add entity admin
    *
    * @return void
    */
697
   final public function addEntityAdmin() {
Johan Cwiklinski's avatar
Johan Cwiklinski committed
698
699
700
      $eventclass = $this->event;
      $admins_data = $eventclass::getEntityAdminsData($this->entity);

yllen's avatar
yllen committed
701
      if ($admins_data) {
Johan Cwiklinski's avatar
Johan Cwiklinski committed
702
703
         foreach ($admins_data as $admin_data) {
            if (!isset($admin_data['usertype'])) {
704
               $admin_data['usertype'] = $this->getDefaultUserType();
Johan Cwiklinski's avatar
Johan Cwiklinski committed
705
706
707
            }
            $this->addToRecipientsList($admin_data);
         }
708
709
710
      }
   }

yllen's avatar
yllen committed
711

712
   /**
Johan Cwiklinski's avatar
Johan Cwiklinski committed
713
714
715
716
717
718
    * Add users of a group to targets
    *
    * @param integer $manager  0 all users, 1 only supervisors, 2 all users without supervisors
    * @param integer $group_id id of the group
    *
    * @since 9.2
yllen's avatar
yllen committed
719
    *
Johan Cwiklinski's avatar
Johan Cwiklinski committed
720
    * @return void
yllen's avatar
yllen committed
721
   **/
722
   final public function addForGroup($manager, $group_id) {
723
724
      global $DB;

725
726
      // members/managers of the group allowed on object entity
      // filter group with 'is_assign' (attribute can be unset after notification)
727
728
729
      $criteria = $this->getDistinctUserCriteria() + $this->getProfileJoinCriteria();
      $criteria['FROM'] = Group_User::getTable();
      $criteria['INNER JOIN'] = array_merge(
Johan Cwiklinski's avatar
Johan Cwiklinski committed
730
         [
731
732
733
734
735
736
737
738
739
740
            User::getTable() => [
               'ON' => [
                  Group_User::getTable()  => 'users_id',
                  User::getTable()        => 'id'
               ]
            ],
            Group::getTable() => [
               'ON' => [
                  Group_User::getTable()  => 'groups_id',
                  Group::getTable()       => 'id'
Johan Cwiklinski's avatar
Johan Cwiklinski committed
741
742
743
               ]
            ]
         ],
744
         $criteria['INNER JOIN']
Johan Cwiklinski's avatar
Johan Cwiklinski committed
745
746
747
748
749
750
751
      );
      $criteria['WHERE'] = array_merge(
         $criteria['WHERE'], [
            Group_User::getTable() . '.groups_id'  => $group_id,
            Group::getTable() . '.is_notify'       => 1,
         ]
      );
moyooo's avatar
moyooo committed
752

753
      if ($manager == 1) {
754
         $criteria['WHERE']['glpi_groups_users.is_manager'] = 1;
755
      } else if ($manager == 2) {
756
         $criteria['WHERE']['glpi_groups_users.is_manager'] = 0;
757
      }
758

Johan Cwiklinski's avatar
Johan Cwiklinski committed
759
      $iterator = $DB->request($criteria);
760
      while ($data = $iterator->next()) {
Johan Cwiklinski's avatar
Johan Cwiklinski committed
761
         $this->addToRecipientsList($data);
moyooo's avatar
moyooo committed
762
      }
763
764
765
766
767
768
769
770
771
772

      if ($manager != 1) {
         // Do not consider it as a group notification if it only targets supervisor
         $this->recipient_data = [
            'itemtype' => Group::class,
            'items_id' => $group_id,
         ];
         Plugin::doHook('add_recipient_to_target', $this);
         unset($this->recipient_data);
      }
773
774
   }

yllen's avatar
yllen committed
775

Johan Cwiklinski's avatar
Johan Cwiklinski committed
776
777
778
779
780
781
782
783
784
   /**
    * Get request criteria to select uniques users
    *
    * @since 9.4
    *
    * @return array
    */
   final public function getDistinctUserCriteria() {
      return [
785
786
787
788
789
         'FIELDS'          => [
            User::getTable() . '.id AS users_id',
            User::getTable() . '.language AS language'
         ],
         'DISTINCT'        => true,
Johan Cwiklinski's avatar
Johan Cwiklinski committed
790
791
792
      ];
   }

yllen's avatar
yllen committed
793

794
   /**
795
796
797
    * Return main notification events for the object type
    * Internal use only => should use getAllEvents
    *
798
    * @return an array which contains : event => event label
yllen's avatar
yllen committed
799
   **/
800
   function getEvents() {
801
      return [];
802
803
   }

yllen's avatar
yllen committed
804

805
806
   /**
    * Return all (GLPI + plugins) notification events for the object type
yllen's avatar
yllen committed
807
    *
808
    * @return an array which contains : event => event label
yllen's avatar
yllen committed
809
   **/
810
811
812
   function getAllEvents() {

      $this->events = $this->getEvents();
813
      //If plugin adds new events for an already defined type
yllen's avatar
yllen committed
814
      Plugin::doHook('item_get_events', $this);
815
816
817
818

      return $this->events;
   }

yllen's avatar
yllen committed
819

yllen's avatar
yllen committed
820
821
822
823
824
   /**
    * @param $target    (default '')
    * @param $label     (default '')
    * @param $type      (=Notification::USER_TYPE)
   **/
825
   function addTarget ($target = '', $label = '', $type = Notification::USER_TYPE) {
yllen's avatar
yllen committed
826

yllen's avatar
yllen committed
827
      $key                                               = $type.'_'.$target;
828
829
830
      // Value used for sort
      $this->notification_targets[$key]                  = $type.'_'.$label;
      // Displayed value
831
832
      $this->notification_targets_labels[$type][$target] = $label;
   }
833

yllen's avatar
yllen committed
834

835
   function addProfilesToTargets() {
yllen's avatar
yllen committed
836
      global $DB;
yllen's avatar
yllen committed
837

838
      foreach ($DB->request('glpi_profiles') as $data) {
839
         $this->addTarget($data["id"], sprintf(__('%1$s: %2$s'), Profile::getTypeName(1), $data["name"]),
840
                          Notification::PROFILE_TYPE);
841
      }
842
   }
843

yllen's avatar
yllen committed
844

yllen's avatar
yllen committed
845
846
847
   /**
    * @param $entity
   **/
848
   final public function addGroupsToTargets($entity) {
yllen's avatar
yllen committed
849
      global $DB;
yllen's avatar
yllen committed
850

yllen's avatar
yllen committed
851
      // Filter groups which can be notified and have members (as notifications are sent to members)
Johan Cwiklinski's avatar
Johan Cwiklinski committed
852
853
854
855
856
857
858
859
860
861
862
      $iterator = $DB->request([
         'SELECT' => ['id', 'name'],
         'FROM'   => Group::getTable(),
         'WHERE'  => [
            'is_usergroup' => 1,
            'is_notify'    => 1
         ] + getEntitiesRestrictCriteria('glpi_groups', 'entities_id', $entity, true),
         'ORDER'  => 'name'
      ]);

      while ($data = $iterator->next()) {
863
         //Add group
864
         $this->addTarget($data["id"], sprintf(__('%1$s: %2$s'), Group::getTypeName(1), $data["name"]),
865
                          Notification::GROUP_TYPE);
866
         //Add group supervisor
yllen's avatar
yllen committed
867
868
         $this->addTarget($data["id"], sprintf(__('%1$s: %2$s'), __('Manager of group'),
                                               $data["name"]),
869
                          Notification::SUPERVISOR_GROUP_TYPE);
870
         //Add group without supervisor
871
         $this->addTarget($data["id"], sprintf(__('%1$s: %2$s'), __("Group except manager users"),
872
873
                                               $data["name"]),
                          Notification::GROUP_WITHOUT_SUPERVISOR_TYPE);
874
875
876
      }
   }

yllen's avatar
yllen committed
877

878
   /**
Johan Cwiklinski's avatar
Johan Cwiklinski committed
879
880
881
882
883
884
    * Add all targets for this notification
    *
    * Can be updated by implementing the addAdditionnalTargets() method
    * Can be overriden (like dbconnection)
    *
    * @param integer $entity the entity on which the event is raised
yllen's avatar
yllen committed
885
    *
Johan Cwiklinski's avatar
Johan Cwiklinski committed
886
    * @return void
yllen's avatar
yllen committed
887
   **/
888
   public function addNotificationTargets($entity) {
889

moyooo's avatar
moyooo committed
890
      if (Session::haveRight("config", UPDATE)) {
moyooo's avatar
moyooo committed
891
         $this->addTarget(Notification::GLOBAL_ADMINISTRATOR, __('Administrator'));
892
      }
yllen's avatar
yllen committed
893
      $this->addTarget(Notification::ENTITY_ADMINISTRATOR, __('Entity administrator'));
894
895
896
897
898

      $this->addProfilesToTargets();
      $this->addGroupsToTargets($entity);
   }

yllen's avatar
yllen committed
899

900
901
902
   /**
    * Allows to add more notification targets
    * Can be overridden in some case (for example Ticket)
yllen's avatar
yllen committed
903
    *
Johan Cwiklinski's avatar
Johan Cwiklinski committed
904
905
906
907
    * @param string $event specif event to get additional targets (default '')
    *
    * @return void
    */
Johan Cwiklinski's avatar