Passed
Push — master ( 179526...2874e4 )
by Andreas
28:11
created

midcom_core_group::__construct()   B

Complexity

Conditions 10
Paths 13

Size

Total Lines 31
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 12.7

Importance

Changes 0
Metric Value
cc 10
eloc 21
nc 13
nop 1
dl 0
loc 31
ccs 14
cts 20
cp 0.7
crap 12.7
rs 7.6666
c 0
b 0
f 0

How to fix   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
 * @package midcom
4
 * @author The Midgard Project, http://www.midgard-project.org
5
 * @copyright The Midgard Project, http://www.midgard-project.org
6
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
7
 */
8
9
use Doctrine\ORM\Query\Expr\Join;
10
11
/**
12
 * MidCOM group implementation supporting Midgard Groups.
13
 *
14
 * @package midcom
15
 */
16
class midcom_core_group
17
{
18
    /**
19
     * The storage object on which we are based. This is usually a midgard_group
20
     * directly, as this class has to work outside of the ACLs. It must not be used
21
     * from the outside.
22
     *
23
     * Access to this member is restricted to the ACL user/group core. In case you
24
     * need a real Storage object for this group, call get_storage() instead.
25
     */
26
    protected midgard_group $_storage;
27
28
    /**
29
     * Name of the group
30
     *
31
     * The variable is considered to be read-only.
32
     */
33
    public string $name = '';
34
35
    /**
36
     * The identification string used to internally identify the group uniquely
37
     * in the system. This is usually some kind of group:$guid string combination.
38
     *
39
     * The variable is considered to be read-only.
40
     */
41
    public string $id = '';
42
43
    /**
44
     * The scope value, which must be set during the _load callback, indicates the "depth" of the
45
     * group in the inheritance tree. This is used during privilege merging in the content
46
     * privilege code, which needs a way to determine the proper ordering. Top level groups
47
     * start with a scope of 1.
48
     *
49
     * The variable is considered to be read-only.
50
     */
51
    public int $scope = MIDCOM_PRIVILEGE_SCOPE_ROOTGROUP;
52
53
    /**
54
     * The constructor retrieves the group identified by its name from the database and
55
     * prepares the object for operation.
56
     *
57
     * It will use the Query Builder to retrieve a group by its name and populate the
58
     * $storage, $name and $id members accordingly.
59
     *
60
     * Any error will trigger midcom_error.
61
     */
62 4
    public function __construct(string|int|midcom_db_group|midgard_group $id)
63
    {
64 4
        if (is_object($id)) {
65 2
            $this->_storage = $id;
66
        } else {
67 4
            if (is_string($id)) {
68 4
                $id_parts = explode(':', $id);
69 4
                if (count($id_parts) == 2) {
70 4
                    if ($id_parts[0] != 'group') {
71
                        throw new midcom_error("The group type identifier {$id_parts[0]} is unknown");
72
                    }
73 4
                    $id = $id_parts[1];
74
                }
75 1
            } elseif ($id == 0) {
76
                throw new midcom_error('0 is not a valid DB identifier');
77
            }
78
            try {
79 4
                $this->_storage = new midgard_group($id);
80
            } catch (Exception $e) {
81
                debug_add('Tried to load a midcom_core_group, but got error ' . $e->getMessage(), MIDCOM_LOG_ERROR);
82
                debug_print_r('Passed argument was:', $id);
83
                throw new midcom_error($e->getMessage());
84
            }
85
        }
86
87 4
        $this->name = $this->_storage->official ?: $this->_storage->name ?: "Group #{$this->_storage->id}";
88 4
        $this->id = "group:{$this->_storage->guid}";
89
90
        // Determine scope
91 4
        if ($parent = $this->get_parent_group()) {
92 1
            $this->scope = $parent->scope + 1;
93
        }
94
    }
95
96
    /**
97
     * Retrieves a list of users for which are a member in this group.
98
     *
99
     * @return midcom_core_user[] A list of user objects in which are members of the current group, indexed by their ID.
100
     */
101
    public function list_members() : array
102
    {
103
        $return = [];
104
105
        if (empty($this->_storage->id)) {
106
            debug_add('$this->storage is not object or id is empty', MIDCOM_LOG_ERROR);
107
            return $return;
108
        }
109
110
        $qb = new midgard_query_builder(midcom::get()->config->get('person_class'));
0 ignored issues
show
Bug introduced by
It seems like midcom::get()->config->get('person_class') can also be of type null; however, parameter $class of midgard_query_builder::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

110
        $qb = new midgard_query_builder(/** @scrutinizer ignore-type */ midcom::get()->config->get('person_class'));
Loading history...
111
        $qb->get_doctrine()
112
            ->leftJoin('midgard_member', 'm', Join::WITH, 'm.uid = c.id')
113
            ->where('m.gid = :id')
114
            ->setParameter('id', $this->_storage->id);
115
116
        foreach ($qb->execute() as $person) {
117
            $user = new midcom_core_user($person);
118
            $return[$user->id] = $user;
119
        }
120
121
        return $return;
122
    }
123
124
    /**
125
     * Return a list of all groups in which the MidCOM user passed is a member.
126
     *
127
     * @return midcom_core_group[] Member groups, indexed by their ID.
128
     */
129 101
    public static function list_memberships(midcom_core_user $user) : array
130
    {
131 101
        $qb = new midgard_query_builder('midgard_group');
132 101
        $qb->get_doctrine()
133 101
            ->leftJoin('midgard_member', 'm', Join::WITH, 'm.gid = c.id')
134 101
            ->leftJoin('midgard_person', 'p', Join::WITH, 'm.uid = p.id')
135 101
            ->where('p.guid = :guid')
136 101
            ->setParameter('guid', $user->guid);
137
138 101
        $return = [];
139 101
        foreach ($qb->execute() as $group) {
140 2
            $return['group:' . $group->guid] = new static($group);
141
        }
142
143 101
        return $return;
144
    }
145
146
    /**
147
     * Returns the parent group.
148
     */
149 4
    public function get_parent_group() : ?midcom_core_group
150
    {
151 4
        if ($this->_storage->owner == 0) {
152 4
            return null;
153
        }
154
155 1
        if ($this->_storage->id == $this->_storage->owner) {
156
            debug_print_r('Broken Group', $this, MIDCOM_LOG_CRIT);
157
            throw new midcom_error('A group was its own parent, which will result in an infinite loop. See debug log for more info.');
158
        }
159 1
        return midcom::get()->auth->get_group($this->_storage->owner);
160
    }
161
162
    /**
163
     * Return a list of privileges assigned directly to the group. The default implementation
164
     * queries the GUID directly using the get_self_privileges method of the
165
     * midcom_core_privilege class, which should work fine on all MgdSchema
166
     * objects. If the storage object is null, an empty array is returned.
167
     *
168
     * @return midcom_core_privilege[]
169
     */
170
    public function get_privileges() : array
171
    {
172
        if ($this->_storage === null) {
173
            return [];
174
        }
175
        return midcom_core_privilege::get_self_privileges($this->_storage->guid);
176
    }
177
178
    /**
179
     * Return a MidCOM DBA level storage object for the current group. Be aware,
180
     * that depending on ACL information, the retrieval of the user may fail.
181
     *
182
     * Also, as outlined in the member $_storage, not all groups may have a DBA object associated
183
     * with them, therefore this call may return null.
184
     *
185
     * The default implementation will return an instance of midcom_db_group based
186
     * on the member $this->_storage->id if that object is defined, or null otherwise.
187
     */
188
    public function get_storage() : ?midcom_db_group
189
    {
190
        if ($this->_storage === null) {
191
            return null;
192
        }
193
        return new midcom_db_group($this->_storage);
194
    }
195
}
196