Passed
Push — EXTRACT_CLASSES ( ae6b5c...83d77a )
by Rafael
60:14 queued 23:58
created

UserGroup::getNomUrl()   F

Complexity

Conditions 24
Paths 5184

Size

Total Lines 76
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

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

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