Passed
Pull Request — dev (#6)
by Rafael
79:24 queued 24:08
created

UserGroup::delrights()   F

Complexity

Conditions 23
Paths 1344

Size

Total Lines 116
Code Lines 70

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 23
eloc 70
nc 1344
nop 4
dl 0
loc 116
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* Copyright (c) 2005       Rodolphe Quiedeville        <[email protected]>
4
 * Copyright (c) 2005-2018	Laurent Destailleur	        <[email protected]>
5
 * Copyright (c) 2005-2018	Regis Houssin		        <[email protected]>
6
 * Copyright (C) 2012		Florian Henry		        <[email protected]>
7
 * Copyright (C) 2014		Juanjo Menent		        <[email protected]>
8
 * Copyright (C) 2014		Alexis Algoud		        <[email protected]>
9
 * Copyright (C) 2018       Nicolas ZABOURI		        <[email protected]>
10
 * Copyright (C) 2019       Abbes Bahfir                <[email protected]>
11
 * Copyright (C) 2023-2024  Frédéric France             <[email protected]>
12
 * Copyright (C) 2024		MDW							<[email protected]>
13
 * Copyright (C) 2024       Rafael San José             <[email protected]>
14
 *
15
 * This program is free software; you can redistribute it and/or modify
16
 * it under the terms of the GNU General Public License as published by
17
 * the Free Software Foundation; either version 3 of the License, or
18
 * (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
27
 */
28
29
namespace Dolibarr\Code\User\Classes;
30
31
use Dolibarr\Code\Core\Classes\Translate;
32
use Dolibarr\Core\Base\CommonObject;
33
use DoliDB;
34
use stdClass;
35
36
/**
37
 *   \file       htdocs/user/class/usergroup.class.php
38
 *   \brief      File of class to manage user groups
39
 */
40
41
/**
42
 *  Class to manage user groups
43
 */
44
class UserGroup extends CommonObject
45
{
46
    /**
47
     * @var string ID to identify managed object
48
     */
49
    public $element = 'usergroup';
50
51
    /**
52
     * @var string Name of table without prefix where object is stored
53
     */
54
    public $table_element = 'usergroup';
55
56
    /**
57
     * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
58
     */
59
    public $picto = 'group';
60
61
    /**
62
     * @var int Entity of group
63
     */
64
    public $entity;
65
66
    /**
67
     * @var string
68
     * @deprecated
69
     * @see $name
70
     */
71
    public $nom;
72
73
    /**
74
     * @var string name
75
     */
76
    public $name; // Name of group
77
78
    public $globalgroup; // Global group
79
80
    /**
81
     * @var array<int>      Entity in table llx_user_group
82
     * @deprecated          Seems not used.
83
     */
84
    public $usergroup_entity;
85
86
    /**
87
     * Date creation record (datec)
88
     *
89
     * @var integer
90
     */
91
    public $datec;
92
93
    /**
94
     * @var string Description
95
     */
96
    public $note;
97
98
    /**
99
     * @var User[]
100
     */
101
    public $members = array(); // Array of users
102
103
    public $nb_rights; // Number of rights granted to the user
104
    public $nb_users;  // Number of users in the group
105
106
    public $rights; // Permissions of the group
107
108
    private $_tab_loaded = array(); // Array of cache of already loaded permissions
109
110
    /**
111
     * @var int all_permissions_are_loaded
112
     */
113
    public $all_permissions_are_loaded;
114
115
    public $oldcopy; // To contains a clone of this when we need to save old properties of object
116
117
    public $fields = array(
118
        'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'index' => 1, 'position' => 1, 'comment' => 'Id'),
119
        'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'visible' => 0, 'notnull' => 1, 'default' => '1', 'index' => 1, 'position' => 5),
120
        'nom' => array('type' => 'varchar(180)', 'label' => 'Name', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'showoncombobox' => 1, 'index' => 1, 'position' => 10, 'searchall' => 1, 'comment' => 'Group name'),
121
        'note' => array('type' => 'html', 'label' => 'Description', 'enabled' => 1, 'visible' => 1, 'position' => 20, 'notnull' => -1, 'searchall' => 1),
122
        'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -2, 'position' => 50, 'notnull' => 1,),
123
        'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -2, 'position' => 60, 'notnull' => 1,),
124
        'model_pdf' => array('type' => 'varchar(255)', 'label' => 'ModelPDF', 'enabled' => 1, 'visible' => 0, 'position' => 100),
125
    );
126
127
    /**
128
     * @var string    Field with ID of parent key if this field has a parent
129
     */
130
    public $fk_element = 'fk_usergroup';
131
132
    /**
133
     * @var array<string, array<string>>    List of child tables. To test if we can delete object.
134
     */
135
    protected $childtables = array();
136
137
    /**
138
     * @var string[]    List of child tables. To know object to delete on cascade.
139
     */
140
    protected $childtablesoncascade = array('usergroup_rights', 'usergroup_user');
141
142
    /**
143
     *    Class constructor
144
     *
145
     *    @param   DoliDB  $db     Database handler
146
     */
147
    public function __construct($db)
148
    {
149
        $this->db = $db;
150
151
        $this->ismultientitymanaged = 1;
152
        $this->nb_rights = 0;
153
    }
154
155
156
    /**
157
     *  Charge un object group avec toutes ses caracteristiques (except ->members array)
158
     *
159
     *  @param      int     $id             Id of group to load
160
     *  @param      string  $groupname      Name of group to load
161
     *  @param      boolean $load_members   Load all members of the group
162
     *  @return     int                     Return integer <0 if KO, >0 if OK
163
     */
164
    public function fetch($id = 0, $groupname = '', $load_members = false)
165
    {
166
        global $conf;
167
168
        dol_syslog(get_class($this) . "::fetch", LOG_DEBUG);
169
        if (!empty($groupname)) {
170
            $result = $this->fetchCommon(0, '', ' AND nom = \'' . $this->db->escape($groupname) . '\'');
171
        } else {
172
            $result = $this->fetchCommon($id);
173
        }
174
175
        $this->name = $this->nom; // For compatibility with field name
176
177
        if ($result) {
178
            if ($load_members) {
179
                $this->members = $this->listUsersForGroup();    // This make a lot of subrequests
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->listUsersForGroup() can also be of type integer. However, the property $members is declared as type Dolibarr\Code\User\Classes\User[]. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
180
            }
181
182
            return 1;
183
        } else {
184
            $this->error = $this->db->lasterror();
185
            return -1;
186
        }
187
    }
188
189
190
    /**
191
     *  Return array of groups objects for a particular user
192
     *
193
     *  @param      int         $userid         User id to search
194
     *  @param      boolean     $load_members   Load all members of the group
195
     *  @return     array|int                   Array of groups objects
196
     */
197
    public function listGroupsForUser($userid, $load_members = true)
198
    {
199
        global $conf, $user;
200
201
        $ret = array();
202
203
        $sql = "SELECT g.rowid, ug.entity as usergroup_entity";
204
        $sql .= " FROM " . $this->db->prefix() . "usergroup as g,";
205
        $sql .= " " . $this->db->prefix() . "usergroup_user as ug";
206
        $sql .= " WHERE ug.fk_usergroup = g.rowid";
207
        $sql .= " AND ug.fk_user = " . ((int) $userid);
208
        if (isModEnabled('multicompany') && $conf->entity == 1 && $user->admin && !$user->entity) {
209
            $sql .= " AND g.entity IS NOT NULL";
210
        } else {
211
            $sql .= " AND g.entity IN (0," . $conf->entity . ")";
212
        }
213
        $sql .= " ORDER BY g.nom";
214
215
        dol_syslog(get_class($this) . "::listGroupsForUser", LOG_DEBUG);
216
        $result = $this->db->query($sql);
217
        if ($result) {
218
            while ($obj = $this->db->fetch_object($result)) {
219
                if (!array_key_exists($obj->rowid, $ret)) {
220
                    $newgroup = new UserGroup($this->db);
221
                    $newgroup->fetch($obj->rowid, '', $load_members);
222
                    $ret[$obj->rowid] = $newgroup;
223
                }
224
                if (!is_array($ret[$obj->rowid]->usergroup_entity)) {
225
                    $ret[$obj->rowid]->usergroup_entity = array();
226
                }
227
                // $ret[$obj->rowid] is instance of UserGroup
228
                $ret[$obj->rowid]->usergroup_entity[] = (int) $obj->usergroup_entity;
229
            }
230
231
            $this->db->free($result);
232
233
            return $ret;
234
        } else {
235
            $this->error = $this->db->lasterror();
236
            return -1;
237
        }
238
    }
239
240
    /**
241
     *  Return array of User objects for group this->id (or all if this->id not defined)
242
     *
243
     *  @param  string  $excludefilter      Filter to exclude. Do not use here a string coming from user input.
244
     *  @param  int     $mode               0=Return array of user instance, 1=Return array of users id only
245
     *  @return mixed                       Array of users or -1 on error
246
     */
247
    public function listUsersForGroup($excludefilter = '', $mode = 0)
248
    {
249
        global $conf, $user;
250
251
        $ret = array();
252
253
        $sql = "SELECT u.rowid, u.login, u.lastname, u.firstname, u.photo, u.fk_soc, u.entity, u.employee, u.email, u.statut as status";
254
        if (!empty($this->id)) {
255
            $sql .= ", ug.entity as usergroup_entity";
256
        }
257
        $sql .= " FROM " . $this->db->prefix() . "user as u";
258
        if (!empty($this->id)) {
259
            $sql .= ", " . $this->db->prefix() . "usergroup_user as ug";
260
        }
261
        $sql .= " WHERE 1 = 1";
262
        if (!empty($this->id)) {
263
            $sql .= " AND ug.fk_user = u.rowid";
264
        }
265
        if (!empty($this->id)) {
266
            $sql .= " AND ug.fk_usergroup = " . ((int) $this->id);
267
        }
268
        if (isModEnabled('multicompany') && $conf->entity == 1 && $user->admin && !$user->entity) {
269
            $sql .= " AND u.entity IS NOT NULL";
270
        } else {
271
            $sql .= " AND u.entity IN (0," . $conf->entity . ")";
272
        }
273
        if (!empty($excludefilter)) {
274
            $sql .= ' AND (' . $excludefilter . ')';
275
        }
276
277
        dol_syslog(get_class($this) . "::listUsersForGroup", LOG_DEBUG);
278
        $resql = $this->db->query($sql);
279
280
        if ($resql) {
281
            while ($obj = $this->db->fetch_object($resql)) {
282
                if (!array_key_exists($obj->rowid, $ret)) {
283
                    if ($mode != 1) {
284
                        $newuser = new User($this->db);
285
                        //$newuser->fetch($obj->rowid);     // We are inside a loop, no subrequests inside a loop
286
                        $newuser->id = $obj->rowid;
287
                        $newuser->login = $obj->login;
288
                        $newuser->photo = $obj->photo;
289
                        $newuser->lastname = $obj->lastname;
290
                        $newuser->firstname = $obj->firstname;
291
                        $newuser->email = $obj->email;
292
                        $newuser->socid = $obj->fk_soc;
293
                        $newuser->entity = $obj->entity;
294
                        $newuser->employee = $obj->employee;
295
                        $newuser->status = $obj->status;
296
297
                        $ret[$obj->rowid] = $newuser;
298
                    } else {
299
                        $ret[$obj->rowid] = $obj->rowid;
300
                    }
301
                }
302
                if ($mode != 1 && !empty($obj->usergroup_entity)) {
303
                    // $ret[$obj->rowid] is instance of User
304
                    if (!is_array($ret[$obj->rowid]->usergroup_entity)) {
305
                        $ret[$obj->rowid]->usergroup_entity = array();
306
                    }
307
                    $ret[$obj->rowid]->usergroup_entity[] = (int) $obj->usergroup_entity;
308
                }
309
            }
310
311
            $this->db->free($resql);
312
313
            return $ret;
314
        } else {
315
            $this->error = $this->db->lasterror();
316
            return -1;
317
        }
318
    }
319
320
    /**
321
     *    Add a permission to a group
322
     *
323
     *    @param    int     $rid        id du droit a ajouter
324
     *    @param    string  $allmodule  Ajouter tous les droits du module allmodule
325
     *    @param    string  $allperms   Ajouter tous les droits du module allmodule, perms allperms
326
     *    @param    int     $entity     Entity to use
327
     *    @return   int                 > 0 if OK, < 0 if KO
328
     */
329
    public function addrights($rid, $allmodule = '', $allperms = '', $entity = 0)
330
    {
331
        global $conf, $user, $langs;
332
333
        $entity = (!empty($entity) ? $entity : $conf->entity);
334
335
        dol_syslog(get_class($this) . "::addrights $rid, $allmodule, $allperms, $entity");
336
        $error = 0;
337
        $whereforadd = '';
338
339
        $this->db->begin();
340
341
        if (!empty($rid)) {
342
            $module = $perms = $subperms = '';
343
344
            // Si on a demande ajout d'un droit en particulier, on recupere
345
            // les caracteristiques (module, perms et subperms) de ce droit.
346
            $sql = "SELECT module, perms, subperms";
347
            $sql .= " FROM " . $this->db->prefix() . "rights_def";
348
            $sql .= " WHERE id = " . ((int) $rid);
349
            $sql .= " AND entity = " . ((int) $entity);
350
351
            $result = $this->db->query($sql);
352
            if ($result) {
353
                $obj = $this->db->fetch_object($result);
354
                if ($obj) {
355
                    $module = $obj->module;
356
                    $perms = $obj->perms;
357
                    $subperms = $obj->subperms;
358
                }
359
            } else {
360
                $error++;
361
                dol_print_error($this->db);
362
            }
363
364
            // Where pour la liste des droits a ajouter
365
            $whereforadd = "id=" . ((int) $rid);
366
            // Find also rights that are herited to add them too
367
            if ($subperms) {
368
                $whereforadd .= " OR (module='" . $this->db->escape($module) . "' AND perms='" . $this->db->escape($perms) . "' AND (subperms='lire' OR subperms='read'))";
369
            } elseif ($perms) {
370
                $whereforadd .= " OR (module='" . $this->db->escape($module) . "' AND (perms='lire' OR perms='read') AND subperms IS NULL)";
371
            }
372
        } else {
373
            // Where pour la liste des droits a ajouter
374
            if (!empty($allmodule)) {
375
                if ($allmodule == 'allmodules') {
376
                    $whereforadd = 'allmodules';
377
                } else {
378
                    $whereforadd = "module='" . $this->db->escape($allmodule) . "'";
379
                    if (!empty($allperms)) {
380
                        $whereforadd .= " AND perms='" . $this->db->escape($allperms) . "'";
381
                    }
382
                }
383
            }
384
        }
385
386
        // Add permission of the list $whereforadd
387
        if (!empty($whereforadd)) {
388
            //print "$module-$perms-$subperms";
389
            $sql = "SELECT id";
390
            $sql .= " FROM " . $this->db->prefix() . "rights_def";
391
            $sql .= " WHERE entity = " . ((int) $entity);
392
            if (!empty($whereforadd) && $whereforadd != 'allmodules') {
393
                $sql .= " AND " . $whereforadd;
394
            }
395
396
            $result = $this->db->query($sql);
397
            if ($result) {
398
                $num = $this->db->num_rows($result);
399
                $i = 0;
400
                while ($i < $num) {
401
                    $obj = $this->db->fetch_object($result);
402
                    $nid = $obj->id;
403
404
                    $sql = "DELETE FROM " . $this->db->prefix() . "usergroup_rights WHERE fk_usergroup = " . ((int) $this->id) . " AND fk_id=" . ((int) $nid) . " AND entity = " . ((int) $entity);
405
                    if (!$this->db->query($sql)) {
406
                        $error++;
407
                    }
408
                    $sql = "INSERT INTO " . $this->db->prefix() . "usergroup_rights (entity, fk_usergroup, fk_id) VALUES (" . ((int) $entity) . ", " . ((int) $this->id) . ", " . ((int) $nid) . ")";
409
                    if (!$this->db->query($sql)) {
410
                        $error++;
411
                    }
412
413
                    $i++;
414
                }
415
            } else {
416
                $error++;
417
                dol_print_error($this->db);
418
            }
419
420
            if (!$error) {
421
                $langs->load("other");
422
                $this->context = array('audit' => $langs->trans("PermissionsAdd") . ($rid ? ' (id=' . $rid . ')' : ''));
423
424
                // Call trigger
425
                $result = $this->call_trigger('USERGROUP_MODIFY', $user);
426
                if ($result < 0) {
427
                    $error++;
428
                }
429
                // End call triggers
430
            }
431
        }
432
433
        if ($error) {
434
            $this->db->rollback();
435
            return -$error;
436
        } else {
437
            $this->db->commit();
438
            return 1;
439
        }
440
    }
441
442
443
    /**
444
     *    Remove a permission from group
445
     *
446
     *    @param    int     $rid        id du droit a retirer
447
     *    @param    string  $allmodule  Retirer tous les droits du module allmodule
448
     *    @param    string  $allperms   Retirer tous les droits du module allmodule, perms allperms
449
     *    @param    int     $entity     Entity to use
450
     *    @return   int                 > 0 if OK, < 0 if OK
451
     */
452
    public function delrights($rid, $allmodule = '', $allperms = '', $entity = 0)
453
    {
454
        global $conf, $user, $langs;
455
456
        $error = 0;
457
        $wherefordel = '';
458
459
        $entity = (!empty($entity) ? $entity : $conf->entity);
460
461
        $this->db->begin();
462
463
        if (!empty($rid)) {
464
            $module = $perms = $subperms = '';
465
466
            // Si on a demande suppression d'un droit en particulier, on recupere
467
            // les caracteristiques module, perms et subperms de ce droit.
468
            $sql = "SELECT module, perms, subperms";
469
            $sql .= " FROM " . $this->db->prefix() . "rights_def";
470
            $sql .= " WHERE id = " . ((int) $rid);
471
            $sql .= " AND entity = " . ((int) $entity);
472
473
            $result = $this->db->query($sql);
474
            if ($result) {
475
                $obj = $this->db->fetch_object($result);
476
                if ($obj) {
477
                    $module = $obj->module;
478
                    $perms = $obj->perms;
479
                    $subperms = $obj->subperms;
480
                }
481
            } else {
482
                $error++;
483
                dol_print_error($this->db);
484
            }
485
486
            // Where for the list of permissions to delete
487
            $wherefordel = "id = " . ((int) $rid);
488
            // Suppression des droits induits
489
            if ($subperms == 'lire' || $subperms == 'read') {
490
                $wherefordel .= " OR (module='" . $this->db->escape($module) . "' AND perms='" . $this->db->escape($perms) . "' AND subperms IS NOT NULL)";
491
            }
492
            if ($perms == 'lire' || $perms == 'read') {
493
                $wherefordel .= " OR (module='" . $this->db->escape($module) . "')";
494
            }
495
496
            // Pour compatibilite, si lowid = 0, on est en mode suppression de tout
497
            // TODO To remove when this will be implemented by the caller
498
            //if (substr($rid,-1,1) == 0) $wherefordel="module='$module'";
499
        } else {
500
            // Add permission of the list $wherefordel
501
            if (!empty($allmodule)) {
502
                if ($allmodule == 'allmodules') {
503
                    $wherefordel = 'allmodules';
504
                } else {
505
                    $wherefordel = "module='" . $this->db->escape($allmodule) . "'";
506
                    if (!empty($allperms)) {
507
                        $wherefordel .= " AND perms='" . $this->db->escape($allperms) . "'";
508
                    }
509
                }
510
            }
511
        }
512
513
        // Suppression des droits de la liste wherefordel
514
        if (!empty($wherefordel)) {
515
            //print "$module-$perms-$subperms";
516
            $sql = "SELECT id";
517
            $sql .= " FROM " . $this->db->prefix() . "rights_def";
518
            $sql .= " WHERE entity = " . ((int) $entity);
519
            if (!empty($wherefordel) && $wherefordel != 'allmodules') {
520
                $sql .= " AND " . $wherefordel;
521
            }
522
523
            $result = $this->db->query($sql);
524
            if ($result) {
525
                $num = $this->db->num_rows($result);
526
                $i = 0;
527
                while ($i < $num) {
528
                    $nid = 0;
529
530
                    $obj = $this->db->fetch_object($result);
531
                    if ($obj) {
532
                        $nid = $obj->id;
533
                    }
534
535
                    $sql = "DELETE FROM " . $this->db->prefix() . "usergroup_rights";
536
                    $sql .= " WHERE fk_usergroup = $this->id AND fk_id=" . ((int) $nid);
537
                    $sql .= " AND entity = " . ((int) $entity);
538
                    if (!$this->db->query($sql)) {
539
                        $error++;
540
                    }
541
542
                    $i++;
543
                }
544
            } else {
545
                $error++;
546
                dol_print_error($this->db);
547
            }
548
549
            if (!$error) {
550
                $langs->load("other");
551
                $this->context = array('audit' => $langs->trans("PermissionsDelete") . ($rid ? ' (id=' . $rid . ')' : ''));
552
553
                // Call trigger
554
                $result = $this->call_trigger('USERGROUP_MODIFY', $user);
555
                if ($result < 0) {
556
                    $error++;
557
                }
558
                // End call triggers
559
            }
560
        }
561
562
        if ($error) {
563
            $this->db->rollback();
564
            return -$error;
565
        } else {
566
            $this->db->commit();
567
            return 1;
568
        }
569
    }
570
571
572
    /**
573
     *  Load the list of permissions for the user into the group object
574
     *
575
     *  @param      string  $moduletag      Name of module we want permissions ('' means all)
576
     *  @return     int                     Return integer <0 if KO, >=0 if OK
577
     */
578
    public function getrights($moduletag = '')
579
    {
580
        global $conf;
581
582
        if ($moduletag && isset($this->_tab_loaded[$moduletag]) && $this->_tab_loaded[$moduletag]) {
583
            // Rights for this module are already loaded, so we leave
584
            return 0;
585
        }
586
587
        if (!empty($this->all_permissions_are_loaded)) {
588
            // We already loaded all rights for this group, so we leave
589
            return 0;
590
        }
591
592
        /*
593
         * Recuperation des droits
594
         */
595
        $sql = "SELECT r.module, r.perms, r.subperms ";
596
        $sql .= " FROM " . $this->db->prefix() . "usergroup_rights as u, " . $this->db->prefix() . "rights_def as r";
597
        $sql .= " WHERE r.id = u.fk_id";
598
        $sql .= " AND r.entity = " . ((int) $conf->entity);
599
        $sql .= " AND u.entity = " . ((int) $conf->entity);
600
        $sql .= " AND u.fk_usergroup = " . ((int) $this->id);
601
        $sql .= " AND r.perms IS NOT NULL";
602
        if ($moduletag) {
603
            $sql .= " AND r.module = '" . $this->db->escape($moduletag) . "'";
604
        }
605
606
        dol_syslog(get_class($this) . '::getrights', LOG_DEBUG);
607
        $resql = $this->db->query($sql);
608
        if ($resql) {
609
            $num = $this->db->num_rows($resql);
610
            $i = 0;
611
            while ($i < $num) {
612
                $obj = $this->db->fetch_object($resql);
613
614
                if ($obj) {
615
                    $module = $obj->module;
616
                    $perms = $obj->perms;
617
                    $subperms = $obj->subperms;
618
619
                    if ($perms) {
620
                        if (!isset($this->rights)) {
621
                            $this->rights = new stdClass(); // For avoid error
622
                        }
623
                        if (!isset($this->rights->$module) || !is_object($this->rights->$module)) {
624
                            $this->rights->$module = new stdClass();
625
                        }
626
                        if ($subperms) {
627
                            if (!isset($this->rights->$module->$perms) || !is_object($this->rights->$module->$perms)) {
628
                                $this->rights->$module->$perms = new stdClass();
629
                            }
630
                            if (empty($this->rights->$module->$perms->$subperms)) {
631
                                $this->nb_rights++;
632
                            }
633
                            $this->rights->$module->$perms->$subperms = 1;
634
                        } else {
635
                            if (empty($this->rights->$module->$perms)) {
636
                                $this->nb_rights++;
637
                            }
638
                            $this->rights->$module->$perms = 1;
639
                        }
640
                    }
641
                }
642
643
                $i++;
644
            }
645
            $this->db->free($resql);
646
        }
647
648
        if ($moduletag == '') {
649
            // Si module etait non defini, alors on a tout charge, on peut donc considerer
650
            // que les droits sont en cache (car tous charges) pour cet instance de group
651
            $this->all_permissions_are_loaded = 1;
652
        } else {
653
            // If module defined, we flag it as loaded into cache
654
            $this->_tab_loaded[$moduletag] = 1;
655
        }
656
657
        return 1;
658
    }
659
660
    /**
661
     *  Delete a group
662
     *
663
     *  @param  User    $user       User that delete
664
     *  @return int                 Return integer <0 if KO, > 0 if OK
665
     */
666
    public function delete(User $user)
667
    {
668
        return $this->deleteCommon($user);
669
    }
670
671
    /**
672
     *  Create group into database
673
     *
674
     *  @param      int     $notrigger  0=triggers enabled, 1=triggers disabled
675
     *  @return     int                 Return integer <0 if KO, >=0 if OK
676
     */
677
    public function create($notrigger = 0)
678
    {
679
        global $user, $conf;
680
681
        $this->datec = dol_now();
682
        if (!empty($this->name)) {
683
            $this->nom = $this->name; // Field for 'name' is called 'nom' in database
684
        }
685
686
        if (!isset($this->entity)) {
687
            $this->entity = $conf->entity; // If not defined, we use default value
688
        }
689
690
        return $this->createCommon($user, $notrigger);
691
    }
692
693
    /**
694
     *      Update group into database
695
     *
696
     *      @param      int     $notrigger      0=triggers enabled, 1=triggers disabled
697
     *      @return     int                     Return integer <0 if KO, >=0 if OK
698
     */
699
    public function update($notrigger = 0)
700
    {
701
        global $user, $conf;
702
703
        if (!empty($this->name)) {
704
            $this->nom = $this->name; // Field for 'name' is called 'nom' in database
705
        }
706
707
        return $this->updateCommon($user, $notrigger);
708
    }
709
710
711
    /**
712
     *  Return full name (civility+' '+name+' '+lastname)
713
     *
714
     *  @param  Translate   $langs          Language object for translation of civility (used only if option is 1)
715
     *  @param  int         $option         0=No option, 1=Add civility
716
     *  @param  int         $nameorder      -1=Auto, 0=Lastname+Firstname, 1=Firstname+Lastname, 2=Firstname, 3=Firstname if defined else lastname, 4=Lastname, 5=Lastname if defined else firstname
717
     *  @param  int         $maxlen         Maximum length
718
     *  @return string                      String with full name
719
     */
720
    public function getFullName($langs, $option = 0, $nameorder = -1, $maxlen = 0)
721
    {
722
        //print "lastname=".$this->lastname." name=".$this->name." nom=".$this->nom."<br>\n";
723
        $lastname = $this->lastname;
724
        $firstname = $this->firstname;
725
        if (empty($lastname)) {
726
            $lastname = (isset($this->lastname) ? $this->lastname : (isset($this->name) ? $this->name : (isset($this->nom) ? $this->nom : (isset($this->societe) ? $this->societe : (isset($this->company) ? $this->company : '')))));
0 ignored issues
show
Bug Best Practice introduced by
The property company does not exist on Dolibarr\Code\User\Classes\UserGroup. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property societe does not exist on Dolibarr\Code\User\Classes\UserGroup. Since you implemented __get, consider adding a @property annotation.
Loading history...
727
        }
728
729
        $ret = '';
730
        if (!empty($option) && !empty($this->civility_code)) {
0 ignored issues
show
Bug Best Practice introduced by
The property civility_code does not exist on Dolibarr\Code\User\Classes\UserGroup. Since you implemented __get, consider adding a @property annotation.
Loading history...
731
            if ($langs->transnoentitiesnoconv("Civility" . $this->civility_code) != "Civility" . $this->civility_code) {
732
                $ret .= $langs->transnoentitiesnoconv("Civility" . $this->civility_code) . ' ';
733
            } else {
734
                $ret .= $this->civility_code . ' ';
735
            }
736
        }
737
738
        $ret .= dolGetFirstLastname($firstname, $lastname, $nameorder);
739
740
        return dol_trunc($ret, $maxlen);
741
    }
742
743
    /**
744
     *  Return the label of the status
745
     *
746
     *  @param  int     $mode          0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
747
     *  @return string                 Label of status
748
     */
749
    public function getLibStatut($mode = 0)
750
    {
751
        return $this->LibStatut(0, $mode);
752
    }
753
754
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
755
    /**
756
     *  Return the label of a given status
757
     *
758
     *  @param  int     $status        Id status
759
     *  @param  int     $mode          0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
760
     *  @return string                 Label of status
761
     */
762
    public function LibStatut($status, $mode = 0)
763
    {
764
		// phpcs:enable
765
        global $langs;
766
        $langs->load('users');
767
        return '';
768
    }
769
770
    /**
771
     * getTooltipContentArray
772
     *
773
     * @param array $params ex option, infologin
774
     * @since v18
775
     * @return array
776
     */
777
    public function getTooltipContentArray($params)
778
    {
779
        global $conf, $langs, $menumanager;
780
781
        $option = $params['option'] ?? '';
782
783
        $datas = [];
784
        if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
785
            $langs->load("users");
786
            return ['optimize' => $langs->trans("ShowGroup")];
787
        }
788
        $datas['divopen'] = '<div class="centpercent">';
789
        $datas['picto'] = img_picto('', 'group') . ' <u>' . $langs->trans("Group") . '</u><br>';
790
        $datas['name'] = '<b>' . $langs->trans('Name') . ':</b> ' . $this->name;
791
        $datas['description'] = '<br><b>' . $langs->trans("Description") . ':</b> ' . $this->note;
792
        $datas['divclose'] = '</div>';
793
794
        return $datas;
795
    }
796
797
    /**
798
     *  Return a link to the user card (with optionally the picto)
799
     *  Use this->id,this->lastname, this->firstname
800
     *
801
     *  @param  int     $withpicto                  Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small)
802
     *  @param  string  $option                     On what the link point to ('nolink', 'permissions')
803
     *  @param  integer $notooltip                  1=Disable tooltip on picto and name
804
     *  @param  string  $morecss                    Add more css on link
805
     *  @param  int     $save_lastsearch_value      -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
806
     *  @return string                              String with URL
807
     */
808
    public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
809
    {
810
        global $langs, $conf, $db, $hookmanager;
811
812
        if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER') && $withpicto) {
813
            $withpicto = 0;
814
        }
815
816
        $result = '';
817
        $params = [
818
            'id' => $this->id,
819
            'objecttype' => $this->element,
820
            'option' => $option,
821
        ];
822
        $classfortooltip = 'classfortooltip';
823
        $dataparams = '';
824
        if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
825
            $classfortooltip = 'classforajaxtooltip';
826
            $dataparams = ' data-params="' . dol_escape_htmltag(json_encode($params)) . '"';
827
            $label = '';
828
        } else {
829
            $label = implode($this->getTooltipContentArray($params));
830
        }
831
832
        if ($option == 'permissions') {
833
            $url = constant('BASE_URL') . '/user/group/perms.php?id=' . $this->id;
834
        } else {
835
            $url = constant('BASE_URL') . '/user/group/card.php?id=' . $this->id;
836
        }
837
838
        if ($option != 'nolink') {
839
            // Add param to save lastsearch_values or not
840
            $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
841
            if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
842
                $add_save_lastsearch_values = 1;
843
            }
844
            if ($add_save_lastsearch_values) {
845
                $url .= '&save_lastsearch_values=1';
846
            }
847
        }
848
849
        $linkclose = "";
850
        if (empty($notooltip)) {
851
            if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
852
                $langs->load("users");
853
                $label = $langs->trans("ShowGroup");
854
                $linkclose .= ' alt="' . dol_escape_htmltag($label, 1, 1) . '"';
855
            }
856
            $linkclose .= ($label ? ' title="' . dol_escape_htmltag($label, 1) . '"' : ' title="tocomplete"');
857
            $linkclose .= $dataparams . ' class="' . $classfortooltip . ($morecss ? ' ' . $morecss : '') . '"';
858
        }
859
860
        $linkstart = '<a href="' . $url . '"';
861
        $linkstart .= $linkclose . '>';
862
        $linkend = '</a>';
863
864
        $result = $linkstart;
865
        if ($withpicto) {
866
            $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="' . (($withpicto != 2) ? 'paddingright ' : '') . '"'), 0, 0, $notooltip ? 0 : 1);
867
        }
868
        if ($withpicto != 2) {
869
            $result .= $this->name;
870
        }
871
        $result .= $linkend;
872
873
        global $action;
874
        $hookmanager->initHooks(array('groupdao'));
875
        $parameters = array('id' => $this->id, 'getnomurl' => &$result);
876
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
877
        if ($reshook > 0) {
878
            $result = $hookmanager->resPrint;
879
        } else {
880
            $result .= $hookmanager->resPrint;
881
        }
882
883
        return $result;
884
    }
885
886
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
887
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
888
    /**
889
     *  Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
890
     *
891
     *  @param      array   $info       Info array loaded by _load_ldap_info
892
     *  @param      int     $mode       0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb)
893
     *                                  1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb)
894
     *                                  2=Return key only (uid=qqq)
895
     *  @return     string              DN
896
     */
897
    public function _load_ldap_dn($info, $mode = 0)
898
    {
899
		// phpcs:enable
900
        global $conf;
901
        $dn = '';
902
        if ($mode == 0) {
903
            $dn = getDolGlobalString('LDAP_KEY_GROUPS') . "=" . $info[getDolGlobalString('LDAP_KEY_GROUPS')] . "," . getDolGlobalString('LDAP_GROUP_DN');
904
        }
905
        if ($mode == 1) {
906
            $dn = getDolGlobalString('LDAP_GROUP_DN');
907
        }
908
        if ($mode == 2) {
909
            $dn = getDolGlobalString('LDAP_KEY_GROUPS') . "=" . $info[getDolGlobalString('LDAP_KEY_GROUPS')];
910
        }
911
        return $dn;
912
    }
913
914
915
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
916
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
917
    /**
918
     *  Initialize the info array (array of LDAP values) that will be used to call LDAP functions
919
     *
920
     *  @return     array       Tableau info des attributes
921
     */
922
    public function _load_ldap_info()
923
    {
924
		// phpcs:enable
925
        global $conf;
926
927
        $info = array();
928
929
        // Object classes
930
        $info["objectclass"] = explode(',', getDolGlobalString('LDAP_GROUP_OBJECT_CLASS'));
931
932
        // Champs
933
        if ($this->name && getDolGlobalString('LDAP_GROUP_FIELD_FULLNAME')) {
934
            $info[getDolGlobalString('LDAP_GROUP_FIELD_FULLNAME')] = $this->name;
935
        }
936
        //if ($this->name && !empty($conf->global->LDAP_GROUP_FIELD_NAME)) $info[$conf->global->LDAP_GROUP_FIELD_NAME] = $this->name;
937
        if ($this->note && getDolGlobalString('LDAP_GROUP_FIELD_DESCRIPTION')) {
938
            $info[getDolGlobalString('LDAP_GROUP_FIELD_DESCRIPTION')] = dol_string_nohtmltag($this->note, 2);
939
        }
940
        if (getDolGlobalString('LDAP_GROUP_FIELD_GROUPMEMBERS')) {
941
            $valueofldapfield = array();
942
            foreach ($this->members as $key => $val) {    // This is array of users for group into dolibarr database.
943
                $muser = new User($this->db);
944
                $muser->fetch($val->id);
945
                $info2 = $muser->_load_ldap_info();
946
                $valueofldapfield[] = $muser->_load_ldap_dn($info2);
947
            }
948
            $info[getDolGlobalString('LDAP_GROUP_FIELD_GROUPMEMBERS')] = (!empty($valueofldapfield) ? $valueofldapfield : '');
949
        }
950
        if (getDolGlobalString('LDAP_GROUP_FIELD_GROUPID')) {
951
            $info[getDolGlobalString('LDAP_GROUP_FIELD_GROUPID')] = $this->id;
952
        }
953
        return $info;
954
    }
955
956
957
    /**
958
     *  Initialise an instance with random values.
959
     *  Used to build previews or test instances.
960
     *  id must be 0 if object instance is a specimen.
961
     *
962
     *  @return int
963
     */
964
    public function initAsSpecimen()
965
    {
966
        global $conf, $user, $langs;
967
968
        // Initialise parameters
969
        $this->id = 0;
970
        $this->ref = 'SPECIMEN';
971
        $this->specimen = 1;
972
973
        $this->name = 'DOLIBARR GROUP SPECIMEN';
974
        $this->note = 'This is a note';
975
        $this->datec = time();
976
        $this->tms = time();
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Core\Base\CommonObject::$tms has been deprecated: Use $date_modification ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

976
        /** @scrutinizer ignore-deprecated */ $this->tms = time();

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
977
978
        // Members of this group is just me
979
        $this->members = array(
980
            $user->id => $user
981
        );
982
983
        return 1;
984
    }
985
986
    /**
987
     *  Create a document onto disk according to template module.
988
     *
989
     *  @param      string      $modele         Force model to use ('' to not force)
990
     *  @param      Translate   $outputlangs    Object langs to use for output
991
     *  @param      int         $hidedetails    Hide details of lines
992
     *  @param      int         $hidedesc       Hide description
993
     *  @param      int         $hideref        Hide ref
994
     *  @param      null|array  $moreparams     Array to provide more information
995
     *  @return     int                         0 if KO, 1 if OK
996
     */
997
    public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
998
    {
999
        global $conf, $user, $langs;
1000
1001
        $langs->load("user");
1002
1003
        // Positionne le modele sur le nom du modele a utiliser
1004
        if (!dol_strlen($modele)) {
1005
            if (getDolGlobalString('USERGROUP_ADDON_PDF')) {
1006
                $modele = getDolGlobalString('USERGROUP_ADDON_PDF');
1007
            } else {
1008
                $modele = 'grass';
1009
            }
1010
        }
1011
1012
        $modelpath = "core/modules/usergroup/doc/";
1013
1014
        return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1015
    }
1016
1017
    /**
1018
     *  Return clicable link of object (with eventually picto)
1019
     *
1020
     *  @param      string      $option                 Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
1021
     *  @param      array       $arraydata              Array of data
1022
     *  @return     string                              HTML Code for Kanban thumb.
1023
     */
1024
    public function getKanbanView($option = '', $arraydata = null)
1025
    {
1026
        global $langs;
1027
1028
        $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1029
1030
        $return = '<div class="box-flex-item box-flex-grow-zero">';
1031
        $return .= '<div class="info-box info-box-sm">';
1032
        $return .= '<span class="info-box-icon bg-infobox-action">';
1033
        $return .= img_picto('', $this->picto);
1034
        $return .= '</span>';
1035
        $return .= '<div class="info-box-content">';
1036
        $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . (method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref) . '</span>';
1037
        if ($selected >= 0) {
1038
            $return .= '<input id="cb' . $this->id . '" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="' . $this->id . '"' . ($selected ? ' checked="checked"' : '') . '>';
1039
        }
1040
        if (property_exists($this, 'members')) {
1041
            $return .= '<br><span class="info-box-status opacitymedium">' . (empty($this->nb_users) ? 0 : $this->nb_users) . ' ' . $langs->trans('Users') . '</span>';
1042
        }
1043
        if (property_exists($this, 'nb_rights')) {
1044
            $return .= '<br><div class="info-box-status margintoponly opacitymedium">' . $langs->trans('NbOfPermissions') . ' : ' . (empty($this->nb_rights) ? 0 : $this->nb_rights) . '</div>';
1045
        }
1046
        $return .= '</div>';
1047
        $return .= '</div>';
1048
        $return .= '</div>';
1049
        return $return;
1050
    }
1051
}
1052