groups.php ➔ group_create()   B
last analyzed

Complexity

Conditions 5
Paths 2

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 2
nop 3
dl 0
loc 24
rs 8.5125
c 0
b 0
f 0
1
<?php
2
3
//------------------------------------------------------------------------------
4
//
5
//  eTraxis - Records tracking web-based system
6
//  Copyright (C) 2005-2011  Artem Rodygin
7
//
8
//  This program is free software: you can redistribute it and/or modify
9
//  it under the terms of the GNU General Public License as published by
10
//  the Free Software Foundation, either version 3 of the License, or
11
//  (at your option) any later version.
12
//
13
//  This program is distributed in the hope that it will be useful,
14
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
//  GNU General Public License for more details.
17
//
18
//  You should have received a copy of the GNU General Public License
19
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//------------------------------------------------------------------------------
22
23
/**
24
 * Groups
25
 *
26
 * This module provides API to work with eTraxis groups.
27
 * See also {@link https://github.com/etraxis/etraxis-obsolete/wiki/tbl_groups tbl_groups} database table.
28
 *
29
 * @package DBO
30
 * @subpackage Groups
31
 */
32
33
/**#@+
34
 * Dependency.
35
 */
36
require_once('../engine/engine.php');
37
require_once('../dbo/accounts.php');
38
/**#@-*/
39
40
//------------------------------------------------------------------------------
41
//  Definitions.
42
//------------------------------------------------------------------------------
43
44
/**#@+
45
 * Data restriction.
46
 */
47
define('MAX_GROUP_NAME',        25);
48
define('MAX_GROUP_DESCRIPTION', 100);
49
/**#@-*/
50
51
//------------------------------------------------------------------------------
52
//  Functions.
53
//------------------------------------------------------------------------------
54
55
/**
56
 * Finds in database and returns the information about specified group.
57
 *
58
 * @param int $id Group ID.
59
 * @return array Array with data if group is found in database, FALSE otherwise.
60
 */
61 View Code Duplication
function group_find ($id)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
{
63
    debug_write_log(DEBUG_TRACE, '[group_find]');
64
    debug_write_log(DEBUG_DUMP,  '[group_find] $id = ' . $id);
65
66
    $rs = dal_query('groups/fndid.sql', $id);
67
68
    if ($rs->rows == 0)
0 ignored issues
show
Documentation introduced by
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
69
    {
70
        return FALSE;
71
    }
72
73
    $row = $rs->fetch();
74
    $row['is_global'] = is_null($row['project_id']);
75
76
    return $row;
77
}
78
79
/**
80
 * Returns {@link CRecordset DAL recordset} which contains all existing global groups and all the local
81
 * groups of specified project, sorted in accordance with current sort mode.
82
 *
83
 * @param int $id Project ID.
84
 * @param int &$sort Sort mode (used as output only). The function retrieves current sort mode from
85
 * client cookie ({@link COOKIE_GROUPS_SORT}) and updates it, if it's out of valid range.
86
 * @param int &$page Number of current page tab (used as output only). The function retrieves current
87
 * page from client cookie ({@link COOKIE_GROUPS_PAGE}) and updates it, if it's out of valid range.
88
 * @return CRecordset Recordset with list of groups.
89
 */
90 View Code Duplication
function groups_list ($id, &$sort, &$page)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
{
92
    debug_write_log(DEBUG_TRACE, '[groups_list]');
93
    debug_write_log(DEBUG_DUMP,  '[groups_list] $id = ' . $id);
94
95
    $sort_modes = array
96
    (
97
        1 => 'is_global asc, group_name asc',
98
        2 => 'description asc, is_global asc, group_name asc',
99
        3 => 'is_global desc, group_name desc',
100
        4 => 'description desc, is_global desc, group_name desc',
101
    );
102
103
    $sort = try_request('sort', try_cookie(COOKIE_GROUPS_SORT));
104
    $sort = ustr2int($sort, 1, count($sort_modes));
105
106
    $page = try_request('page', try_cookie(COOKIE_GROUPS_PAGE));
107
    $page = ustr2int($page, 1, MAXINT);
108
109
    save_cookie(COOKIE_GROUPS_SORT, $sort);
110
    save_cookie(COOKIE_GROUPS_PAGE, $page);
111
112
    return dal_query('groups/list.sql', $id, $sort_modes[$sort]);
113
}
114
115
/**
116
 * Returns {@link CRecordset DAL recordset} which contains all current members of specified group.
117
 *
118
 * @param int $id ID of group to be enumerated.
119
 * @return CRecordset Recordset with list of accounts.
120
 */
121 View Code Duplication
function group_amongs ($id)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
{
123
    debug_write_log(DEBUG_TRACE, '[group_amongs]');
124
    debug_write_log(DEBUG_DUMP,  '[group_amongs] $id = ' . $id);
125
126
    return dal_query('groups/mamongs.sql', $id);
127
}
128
129
/**
130
 * Returns {@link CRecordset DAL recordset} which contains all non-members of specified group.
131
 *
132
 * @param int $id ID of group to be enumerated.
133
 * @return CRecordset Recordset with list of accounts.
134
 */
135
function group_not_amongs ($id)
136
{
137
    debug_write_log(DEBUG_TRACE, '[group_not_amongs]');
138
    debug_write_log(DEBUG_DUMP,  '[group_not_amongs] $id = ' . $id);
139
140
    // Create list of user names for all current members.
141
    $members = array();
142
143
    $list = dal_query('groups/mamongs.sql', $id);
144
145
    while (($row = $list->fetch()))
146
    {
147
        array_push($members, ustrtolower($row['username']));
148
    }
149
150
    // Arrays to store resulted data.
151
    $account_id = array();
152
    $username   = array();
153
    $fullname   = array();
154
155
    // Enumerate all registered accounts.
156
    $list = dal_query('accounts/list.sql', 'username asc');
157
158
    // Push to arrays everyone, who is not in list of current members.
159
    while (($user = $list->fetch()))
160
    {
161 View Code Duplication
        if (!in_array(ustrtolower($user['username']), $members))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
162
        {
163
            array_push($account_id, $user['account_id']);
164
            array_push($username,   $user['username']);
165
            array_push($fullname,   $user['fullname']);
166
        }
167
    }
168
169
    // If LDAP is enabled, add all LDAP non-members too.
170
    if (LDAP_ENABLED)
171
    {
172
        // Enumerate all LDAP accounts from LDAP server.
173
        $list = ldap_findallusers();
174
175
        // Push to arrays everyone, who is not in list of current members.
176
        foreach ($list as $user)
0 ignored issues
show
Bug introduced by
The expression $list of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
177
        {
178 View Code Duplication
            if (!in_array(ustrtolower($user['username']), $members))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
179
            {
180
                array_push($account_id, NULL);
181
                array_push($username,   $user['username']);
182
                array_push($fullname,   $user['fullname']);
183
            }
184
        }
185
    }
186
187
    // Sort all found ono-members in alphabetical order.
188
    array_multisort($fullname, $username, $account_id);
189
190
    // Compose (fake) resulted "recordset".
191
    $retval = array();
192
193
    for ($i = 0; $i < count($fullname); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
194
    {
195
        $entry = array('account_id' => $account_id[$i],
196
                       'username'   => $username[$i],
197
                       'fullname'   => $fullname[$i]);
198
199
        array_push($retval, $entry);
200
    }
201
202
    return $retval;
203
}
204
205
/**
206
 * Validates group information before creation or modification.
207
 *
208
 * @param string $group_name Group name.
209
 * @return int Error code:
210
 * <ul>
211
 * <li>{@link NO_ERROR} - data are valid</li>
212
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li>
213
 * </ul>
214
 */
215 View Code Duplication
function group_validate ($group_name)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
216
{
217
    debug_write_log(DEBUG_TRACE, '[group_validate]');
218
    debug_write_log(DEBUG_DUMP,  '[group_validate] $group_name = ' . $group_name);
219
220
    if (ustrlen($group_name) == 0)
221
    {
222
        debug_write_log(DEBUG_NOTICE, '[group_validate] At least one required field is empty.');
223
        return ERROR_INCOMPLETE_FORM;
224
    }
225
226
    return NO_ERROR;
227
}
228
229
/**
230
 * Creates new group.
231
 *
232
 * @param int $project_id ID of project which new group should be created in. NULL should be used to create a global group.
233
 * @param string $group_name Group name.
234
 * @param string $description Optional description.
235
 * @return int Error code:
236
 * <ul>
237
 * <li>{@link NO_ERROR} - group is successfully created</li>
238
 * <li>{@link ERROR_ALREADY_EXISTS} - group with specified group name already exists</li>
239
 * </ul>
240
 */
241
function group_create ($project_id, $group_name, $description)
242
{
243
    debug_write_log(DEBUG_TRACE, '[group_create]');
244
    debug_write_log(DEBUG_DUMP,  '[group_create] $project_id  = ' . $project_id);
245
    debug_write_log(DEBUG_DUMP,  '[group_create] $group_name  = ' . $group_name);
246
    debug_write_log(DEBUG_DUMP,  '[group_create] $description = ' . $description);
247
248
    // Check that there is no group with the same name and in the same project.
249
    $rs = dal_query('groups/fndk.sql', ($project_id == 0 ? 'is null' : '=' . $project_id), ustrtolower($group_name));
250
251
    if ($rs->rows != 0)
0 ignored issues
show
Documentation introduced by
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
252
    {
253
        debug_write_log(DEBUG_NOTICE, '[group_create] Group already exists.');
254
        return ERROR_ALREADY_EXISTS;
255
    }
256
257
    // Create a group.
258
    dal_query('groups/create.sql',
259
              $project_id == 0 ? NULL : $project_id,
260
              $group_name,
261
              ustrlen($description) == 0 ? NULL : $description);
262
263
    return NO_ERROR;
264
}
265
266
/**
267
 * Modifies specified group.
268
 *
269
 * @param int $id ID of group to be modified.
270
 * @param int $project_id ID of project which the group belongs to. NULL should be used to specify a global group.
271
 * @param string $group_name New group name.
272
 * @param string $description New description.
273
 * @return int Error code:
274
 * <ul>
275
 * <li>{@link NO_ERROR} - group is successfully modified</li>
276
 * <li>{@link ERROR_ALREADY_EXISTS} - another group with specified group name already exists</li>
277
 * </ul>
278
 */
279 View Code Duplication
function group_modify ($id, $project_id, $group_name, $description)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280
{
281
    debug_write_log(DEBUG_TRACE, '[group_modify]');
282
    debug_write_log(DEBUG_DUMP,  '[group_modify] $id          = ' . $id);
283
    debug_write_log(DEBUG_DUMP,  '[group_create] $project_id  = ' . $project_id);
284
    debug_write_log(DEBUG_DUMP,  '[group_modify] $group_name  = ' . $group_name);
285
    debug_write_log(DEBUG_DUMP,  '[group_modify] $description = ' . $description);
286
287
    // Check that there is no group with the same group name, besides this one.
288
    $rs = dal_query('groups/fndku.sql', $id, (is_null($project_id) ? 'is null' : '=' . $project_id), ustrtolower($group_name));
289
290
    if ($rs->rows != 0)
0 ignored issues
show
Documentation introduced by
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
291
    {
292
        debug_write_log(DEBUG_NOTICE, '[group_modify] Group already exists.');
293
        return ERROR_ALREADY_EXISTS;
294
    }
295
296
    // Modify the group.
297
    dal_query('groups/modify.sql',
298
              $id,
299
              $group_name,
300
              ustrlen($description) == 0 ? NULL : $description);
301
302
    return NO_ERROR;
303
}
304
305
/**
306
 * Checks whether group can be deleted.
307
 *
308
 * @param int $id ID of group to be deleted.
309
 * @return bool TRUE if group can be deleted, FALSE otherwise.
310
 */
311
function is_group_removable ($id)
312
{
313
    debug_write_log(DEBUG_TRACE, '[is_group_removable]');
314
    debug_write_log(DEBUG_DUMP,  '[is_group_removable] $id = ' . $id);
315
316
    return TRUE;
317
}
318
319
/**
320
 * Deletes specified group.
321
 *
322
 * @param int $id ID of group to be deleted.
323
 * @return int Always {@link NO_ERROR}.
324
 */
325
function group_delete ($id)
326
{
327
    debug_write_log(DEBUG_TRACE, '[group_delete]');
328
    debug_write_log(DEBUG_DUMP,  '[group_delete] $id = ' . $id);
329
330
    dal_query('groups/rdelall.sql',   $id);
331
    dal_query('groups/fshdelall.sql', $id);
332
    dal_query('groups/fpdelall.sql',  $id);
333
    dal_query('groups/gtdelall.sql',  $id);
334
    dal_query('groups/gpdelall.sql',  $id);
335
    dal_query('groups/msdelall.sql',  $id);
336
    dal_query('groups/sadelall.sql',  $id);
337
    dal_query('groups/delete.sql',    $id);
338
339
    return NO_ERROR;
340
}
341
342
/**
343
 * Adds specified account to list of members of specified group.
344
 *
345
 * @param int $gid ID of group which the account should be added to.
346
 * @param int $aid ID of account to be added.
347
 * @return int Always {@link NO_ERROR}.
348
 */
349
function group_membership_add ($gid, $aid)
350
{
351
    debug_write_log(DEBUG_TRACE, '[group_membership_add]');
352
    debug_write_log(DEBUG_DUMP,  '[group_membership_add] $gid = ' . $gid);
353
    debug_write_log(DEBUG_DUMP,  '[group_membership_add] $aid = ' . $aid);
354
355
    dal_query('groups/mremove.sql', $gid, $aid);
356
    dal_query('groups/madd.sql',    $gid, $aid);
357
358
    return NO_ERROR;
359
}
360
361
/**
362
 * Removes specified account from list of members of specified group.
363
 *
364
 * @param int $gid ID of group which the account should be removed from.
365
 * @param int $aid ID of account to be removed.
366
 * @return int Always {@link NO_ERROR}.
367
 */
368
function group_membership_remove ($gid, $aid)
369
{
370
    debug_write_log(DEBUG_TRACE, '[group_membership_remove]');
371
    debug_write_log(DEBUG_DUMP,  '[group_membership_remove] $gid = ' . $gid);
372
    debug_write_log(DEBUG_DUMP,  '[group_membership_remove] $aid = ' . $aid);
373
374
    dal_query('groups/mremove.sql', $gid, $aid);
375
376
    return NO_ERROR;
377
}
378
379
/**
380
 * Finds in database and returns current permissions of specified group for specified template.
381
 *
382
 * @param int $gid ID of group whose permissions should be retrieved.
383
 * @param int $tid ID of template which permissions should be retrieved for.
384
 * @return int Current permissions set, or 0 if no permissions are set.
385
 */
386 View Code Duplication
function group_get_permissions ($gid, $tid)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
387
{
388
    debug_write_log(DEBUG_TRACE, '[group_get_permissions]');
389
    debug_write_log(DEBUG_DUMP,  '[group_get_permissions] $gid = ' . $gid);
390
    debug_write_log(DEBUG_DUMP,  '[group_get_permissions] $tid = ' . $tid);
391
392
    $rs = dal_query('groups/gpget.sql', $gid, $tid);
393
394
    return ($rs->rows == 0 ? 0 : $rs->fetch('perms'));
0 ignored issues
show
Documentation introduced by
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
395
}
396
397
/**
398
 * Sets permissions of specified group for specified template.
399
 *
400
 * @param int $gid ID of group whose permissions should be set.
401
 * @param int $tid ID of template which permissions should be set for.
402
 * @param int $perm New permissions set.
403
 * @return int Always {@link NO_ERROR}.
404
 */
405 View Code Duplication
function group_set_permissions ($gid, $tid, $perm)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
406
{
407
    debug_write_log(DEBUG_TRACE, '[group_set_permissions]');
408
    debug_write_log(DEBUG_DUMP,  '[group_set_permissions] $gid  = ' . $gid);
409
    debug_write_log(DEBUG_DUMP,  '[group_set_permissions] $tid  = ' . $tid);
410
    debug_write_log(DEBUG_DUMP,  '[group_set_permissions] $perm = ' . $perm);
411
412
    dal_query('groups/gpremove.sql', $gid, $tid);
413
    dal_query('groups/gpadd.sql',    $gid, $tid, $perm);
414
415
    return NO_ERROR;
416
}
417
418
/**
419
 * Exports groups of specified group IDs to XML code (see also {@link project_import}).
420
 *
421
 * @param array Array with Group IDs.
422
 * @return string Generated XML code for specified group IDs.
423
 */
424
function groups_export ($groups)
425
{
426
    debug_write_log(DEBUG_TRACE, '[groups_export]');
427
428
    if (count($groups) == 0)
429
    {
430
        return NULL;
431
    }
432
433
    // List all global and local project groups.
434
    $rs = dal_query('templates/glist.sql', implode(',', $groups));
435
436
    $xml = NULL;
437
438
    if ($rs->rows != 0)
0 ignored issues
show
Documentation introduced by
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
439
    {
440
        // Add XML code for all enumerated groups.
441
        while (($group = $rs->fetch()))
442
        {
443
            // Add XML code for general group information.
444
            $xml .= sprintf("  <group name=\"%s\" type=\"%s\" description=\"%s\">\n",
445
                            ustr2html($group['group_name']),
446
                            (is_null($group['project_id']) ? 'global' : 'local'),
447
                            ustr2html($group['description']));
448
449
            // List all members of this group.
450
            $rsm = dal_query('groups/mamongs.sql', $group['group_id']);
451
452
            // Add XML code for name and type of each account.
453
            while (($account = $rsm->fetch()))
454
            {
455
                $xml .= sprintf("    <account type=\"%s\">%s</account>\n",
456
                                ($account['is_ldapuser'] ? 'ldap' : 'local'),
457
                                account_get_username($account['username'], FALSE));
458
            }
459
460
            $xml .= "  </group>\n";
461
        }
462
    }
463
464
    return $xml;
465
}
466
467
/**
468
 * Imports groups described as XML code into the specified project.
469
 *
470
 * @param int $project_id ID of destination project.
471
 * @param string $xml Valid XML code.
472
 * @param string &$error In case of failure - the error message (used as output only).
473
 * @return bool Whether the import was successful.
474
 */
475
function groups_import ($project_id, $xml, &$error)
476
{
477
    debug_write_log(DEBUG_TRACE, '[groups_import]');
478
    debug_write_log(DEBUG_DUMP,  '[groups_import] $project_id = ' . $project_id);
479
480
    // Enumerate groups.
481
    $groups = $xml->xpath('/project/group');
0 ignored issues
show
Bug introduced by
The method xpath cannot be called on $xml (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
482
483
    if ($groups !== FALSE)
484
    {
485
        foreach ($groups as $group)
486
        {
487
            $group['name']        = ustrcut($group['name'],        MAX_GROUP_NAME);
488
            $group['description'] = ustrcut($group['description'], MAX_GROUP_DESCRIPTION);
489
490
            // Validate group.
491 View Code Duplication
            switch (group_validate($group['name']))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
492
            {
493
                case NO_ERROR:
494
                    break;  // nop
495
                case ERROR_INCOMPLETE_FORM:
496
                    $error = get_html_resource(RES_ALERT_REQUIRED_ARE_EMPTY_ID);
497
                    return FALSE;
498
                default:
499
                    debug_write_log(DEBUG_WARNING, '[groups_import] Group validation failure.');
500
                    $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
501
                    return FALSE;
502
            }
503
504
            // Create group.
505
            group_create($group['type'] == 'global' ? NULL : $project_id,
506
                         $group['name'],
507
                         $group['description']);
508
509
            $rs = dal_query('groups/fndk.sql',
510
                            $group['type'] == 'global' ? 'is null' : '=' . $project_id,
511
                            ustrtolower($group['name']));
512
513
            if ($rs->rows != 0)
0 ignored issues
show
Documentation introduced by
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
514
            {
515
                $group_id = $rs->fetch('group_id');
516
517
                // Add members.
518
                if (isset($group->account))
519
                {
520
                    foreach ($group->account as $account)
521
                    {
522
                        $username     = ustrcut(strval($account), MAX_ACCOUNT_USERNAME);
523
                        $account_info = account_find_username($account['type'] == 'local' ? $username . ACCOUNT_SUFFIX : $username);
524
525
                        if ($account_info !== FALSE)
526
                        {
527
                            group_membership_add($group_id, $account_info['account_id']);
528
                        }
529
                    }
530
                }
531
            }
532
        }
533
    }
534
535
    return TRUE;
536
}
537
538
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
539