Completed
Push — master ( 910289...c5392c )
by Nekrasov
04:44
created

EloquentModel::refresh()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 8
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 8
loc 8
rs 9.4285
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
3
namespace Arrilot\BitrixModels\Models;
4
5
use Arrilot\BitrixModels\Queries\UserQuery;
6
7 View Code Duplication
class EloquentModel extends BaseModel
0 ignored issues
show
Duplication introduced by
This class 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...
8
{
9
    /**
10
     * Corresponding object class name.
11
     *
12
     * @var string
13
     */
14
    protected static $objectClass = 'CUser';
15
16
    /**
17
     * Have groups been already fetched from DB?
18
     *
19
     * @var bool
20
     */
21
    protected $groupsAreFetched = false;
22
23
    /**
24
     * Instantiate a query object for the model.
25
     *
26
     * @return UserQuery
27
     */
28
    public static function query()
29
    {
30
        return new UserQuery(static::instantiateObject(), get_called_class());
31
    }
32
33
    /**
34
     * Get a new instance for the current user.
35
     *
36
     * @param null $fields
37
     *
38
     * @return static
39
     */
40
    public static function current($fields = null)
41
    {
42
        global $USER;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
43
44
        $user = new static($USER->getId());
45
46
        if (!is_null($fields)) {
47
            $user->fill($fields);
48
        }
49
50
        return $user;
51
    }
52
53
    /**
54
     * Fill extra fields when $this->field is called.
55
     *
56
     * @return null
57
     */
58
    protected function afterFill()
59
    {
60
        if (isset($this->fields['GROUP_ID']) && is_array(['GROUP_ID'])) {
61
            $this->groupsAreFetched = true;
62
        }
63
    }
64
65
    /**
66
     * Fill model groups if they are already known.
67
     * Saves DB queries.
68
     *
69
     * @param array $groups
70
     *
71
     * @return null
72
     */
73
    public function fillGroups($groups)
74
    {
75
        $this->fields['GROUP_ID'] = $groups;
76
77
        $this->groupsAreFetched = true;
78
    }
79
80
    /**
81
     * Get all model attributes from cache or database.
82
     *
83
     * @return array
84
     */
85
    public function get()
86
    {
87
        $this->getFields();
88
89
        $this->getGroups();
90
91
        return $this->fields;
92
    }
93
94
    /**
95
     * Get user groups from cache or database.
96
     *
97
     * @return array
98
     */
99
    public function getGroups()
100
    {
101
        if ($this->groupsAreFetched) {
102
            return $this->fields['GROUP_ID'];
103
        }
104
105
        return $this->refreshGroups();
106
    }
107
108
    /**
109
     * Refresh model from database and place data to $this->fields.
110
     *
111
     * @return array
112
     */
113
    public function refresh()
114
    {
115
        $this->refreshFields();
116
117
        $this->refreshGroups();
118
119
        return $this->fields;
120
    }
121
122
    /**
123
     * Refresh user fields and save them to a class field.
124
     *
125
     * @return array
126
     */
127
    public function refreshFields()
128
    {
129
        if ($this->id === null) {
130
            return  $this->fields = [];
131
        }
132
133
        $groupBackup = isset($this->fields['GROUP_ID']) ? $this->fields['GROUP_ID'] : null;
134
135
        $this->fields = static::query()->getById($this->id)->fields;
136
137
        if ($groupBackup) {
138
            $this->fields['GROUP_ID'] = $groupBackup;
139
        }
140
141
        $this->fieldsAreFetched = true;
142
143
        return $this->fields;
144
    }
145
146
    /**
147
     * Refresh user groups and save them to a class field.
148
     *
149
     * @return array
150
     */
151
    public function refreshGroups()
152
    {
153
        if ($this->id === null) {
154
            return [];
155
        }
156
157
        global $USER;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
158
159
        $this->fields['GROUP_ID'] = $this->isCurrent()
160
            ? $USER->getUserGroupArray()
161
            : static::$bxObject->getUserGroup($this->id);
162
163
        $this->groupsAreFetched = true;
164
165
        return $this->fields['GROUP_ID'];
166
    }
167
168
    /**
169
     * Check if user is an admin.
170
     */
171
    public function isAdmin()
172
    {
173
        return $this->hasGroupWithId(1);
174
    }
175
176
    /**
177
     * Check if this user is the operating user.
178
     */
179
    public function isCurrent()
180
    {
181
        global $USER;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
182
183
        return $USER->getId() && $this->id == $USER->getId();
184
    }
185
186
    /**
187
     * Check if user has role with a given ID.
188
     *
189
     * @param $role_id
190
     *
191
     * @return bool
192
     */
193
    public function hasGroupWithId($role_id)
194
    {
195
        return in_array($role_id, $this->getGroups());
196
    }
197
198
    /**
199
     * Check if user is authorized.
200
     *
201
     * @return bool
202
     */
203
    public function isAuthorized()
204
    {
205
        global $USER;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
206
207
        return ($USER->getId() == $this->id) && $USER->isAuthorized();
208
    }
209
210
    /**
211
     * Check if user is guest.
212
     *
213
     * @return bool
214
     */
215
    public function isGuest()
216
    {
217
        return ! $this->isAuthorized();
218
    }
219
220
    /**
221
     * Logout user.
222
     *
223
     * @return void
224
     */
225
    public function logout()
226
    {
227
        global $USER;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
228
229
        $USER->logout();
230
    }
231
232
    /**
233
     * Scope to get only users from a given group / groups.
234
     *
235
     * @param UserQuery $query
236
     * @param int|array $id
237
     *
238
     * @return UserQuery
239
     */
240
    public function scopeFromGroup($query, $id)
241
    {
242
        $query->filter['GROUPS_ID'] = $id;
243
244
        return $query;
245
    }
246
247
    /**
248
     * Substitute old group with the new one.
249
     *
250
     * @param int $old
251
     * @param int $new
252
     *
253
     * @return void
254
     */
255
    public function substituteGroup($old, $new)
256
    {
257
        $groups = $this->getGroups();
258
259
        if(($key = array_search($old, $groups)) !== false) {
260
            unset($groups[$key]);
261
        }
262
263
        if (!in_array($new, $groups)) {
264
            $groups[] = $new;
265
        }
266
267
        $this->fields['GROUP_ID'] = $groups;
268
    }
269
}
270