Passed
Pull Request — master (#81)
by Michael
03:00
created

ProfileHandler::search()   F

Complexity

Conditions 16
Paths 864

Size

Total Lines 89
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 45
dl 0
loc 89
rs 1.5888
c 0
b 0
f 0
cc 16
nc 864
nop 3

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
declare(strict_types=1);
4
5
namespace XoopsModules\Yogurt;
6
7
/**
8
 * Extended User Profile
9
 *
10
 * You may not change or alter any portion of this comment or credits
11
 * of supporting developers from this source code or any supporting source code
12
 * which is considered copyrighted (c) material of the original comment or credit authors.
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.
16
 *
17
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
18
 * @license             GNU GPL 2 (http://www.gnu.org/licenses/gpl-2.0.html)
19
 * @package             profile
20
 * @since               2.3.0
21
 * @author              Jan Pedersen
22
 * @author              Taiwen Jiang <[email protected]>
23
 */
24
25
26
/**
27
 * @package             kernel
28
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
29
 */
30
31
use XoopsModules\Yogurt;
32
33
class ProfileHandler extends \XoopsPersistableObjectHandler
34
{
35
    /**
36
     * holds reference to {@link profileFieldHandler} object
37
     */
38
39
    public $_fHandler;
40
41
    /**
42
     * Array of {@link XoopsYogurt\Field} objects
43
     * @var array
44
     */
45
46
    public $_fields = [];
47
48
    /**
49
     * @param \XoopsDatabase $db
50
     */
51
52
    public function __construct(\XoopsDatabase $db)
53
    {
54
        parent::__construct($db, 'yogurt_profile', Profile::class, 'profile_id');
55
56
        $this->_fHandler = \xoops_getModuleHandler('field', 'yogurt');
57
    }
58
59
    /**
60
     * create a new {@link ProfileProfile}
61
     *
62
     * @param bool $isNew Flag the new objects as "new"?
63
     *
64
     * @return object {@link ProfileProfile}
65
     */
66
67
    public function create($isNew = true)
68
    {
69
        $obj = new $this->className($this->loadFields());
70
71
        $obj->handler = $this;
72
73
        if ($isNew) {
74
            $obj->setNew();
75
        }
76
77
        return $obj;
78
    }
79
80
    /**
81
     * Get a ProfileProfile object for a user id.
82
     *
83
     * We will create an empty profile if none exists. This behavior allows user objects
84
     * created outside of profile to be edited correctly in the profile module.
85
     *
86
     * @param int|null      $uid
87
     * @param string[]|null $fields array of field names to fetch, null for all
88
     *
89
     * @return object {@link ProfileProfile}
90
     *
91
     * @internal This was get($uid, $createOnFailure = true). No callers found using the extra parameter.
92
     * @internal Modified to match parent signature.
93
     */
94
95
    public function get($uid = null, $fields = null)
96
    {
97
        $obj = parent::get($uid, $fields);
98
99
        if (!\is_object($obj)) {
100
            $obj = $this->create();
101
        }
102
103
        return $obj;
104
    }
105
106
    /**
107
     * Create new {@link Yogurt\Field} object
108
     *
109
     * @param bool $isNew
110
     *
111
     * @return Yogurt\Field
112
     */
113
114
    public function createField($isNew = true)
115
    {
116
        $return = $this->_fHandler->create($isNew);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $return is correct as $this->_fHandler->create($isNew) targeting XoopsObjectHandler::create() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Unused Code introduced by
The call to XoopsObjectHandler::create() has too many arguments starting with $isNew. ( Ignorable by Annotation )

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

116
        /** @scrutinizer ignore-call */ 
117
        $return = $this->_fHandler->create($isNew);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
117
118
        return $return;
119
    }
120
121
    /**
122
     * Load field information
123
     *
124
     * @return array
125
     */
126
127
    public function loadFields()
128
    {
129
        if (0 == \count($this->_fields)) {
130
            $this->_fields = $this->_fHandler->loadFields();
0 ignored issues
show
Bug introduced by
The method loadFields() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler. ( Ignorable by Annotation )

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

130
            /** @scrutinizer ignore-call */ 
131
            $this->_fields = $this->_fHandler->loadFields();
Loading history...
131
        }
132
133
        return $this->_fields;
134
    }
135
136
    /**
137
     * Fetch fields
138
     *
139
     * @param \CriteriaElement $criteria  {@link CriteriaElement} object
140
     * @param bool             $id_as_key return array with field IDs as key?
141
     * @param bool             $as_object return array of objects?
142
     *
143
     * @return array
144
     */
145
146
    public function getFields(\CriteriaElement $criteria, $id_as_key = true, $as_object = true)
147
    {
148
        return $this->_fHandler->getObjects($criteria, $id_as_key, $as_object);
0 ignored issues
show
Bug introduced by
The method getObjects() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of said class. However, the method does not exist in XoopsRankHandler or XoUserHandler. Are you sure you never get one of those? ( Ignorable by Annotation )

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

148
        return $this->_fHandler->/** @scrutinizer ignore-call */ getObjects($criteria, $id_as_key, $as_object);
Loading history...
149
    }
150
151
    /**
152
     * Insert a field in the database
153
     *
154
     * @param \XoopsModules\Yogurt\Field $field
155
     * @param bool                       $force
156
     *
157
     * @return bool
158
     */
159
160
    public function insertField(Yogurt\Field $field, $force = false)
161
    {
162
        return $this->_fHandler->insert($field, $force);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->_fHandler->insert($field, $force) targeting XoopsObjectHandler::insert() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Unused Code introduced by
The call to XoopsObjectHandler::insert() has too many arguments starting with $force. ( Ignorable by Annotation )

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

162
        return $this->_fHandler->/** @scrutinizer ignore-call */ insert($field, $force);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
163
    }
164
165
    /**
166
     * Delete a field from the database
167
     *
168
     * @param \XoopsModules\Yogurt\Field $field
169
     * @param bool                       $force
170
     *
171
     * @return bool
172
     */
173
174
    public function deleteField(Yogurt\Field $field, $force = false)
175
    {
176
        return $this->_fHandler->delete($field, $force);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->_fHandler->delete($field, $force) targeting XoopsObjectHandler::delete() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Unused Code introduced by
The call to XoopsObjectHandler::delete() has too many arguments starting with $force. ( Ignorable by Annotation )

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

176
        return $this->_fHandler->/** @scrutinizer ignore-call */ delete($field, $force);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
177
    }
178
179
    /**
180
     * Save a new field in the database
181
     *
182
     * @param array $vars array of variables, taken from $module->loadInfo('profile')['field']
183
     * @param int   $weight
184
     *
185
     * @return string
186
     * @internal param int $type valuetype of the field
187
     * @internal param int $moduleid ID of the module, this field belongs to
188
     * @internal param int $categoryid ID of the category to add it to
189
     */
190
191
    public function saveField($vars, $weight = 0)
192
    {
193
        $field = $this->createField();
194
195
        $field->setVar('field_name', $vars['name']);
196
197
        $field->setVar('field_valuetype', $vars['valuetype']);
198
199
        $field->setVar('field_type', $vars['type']);
200
201
        $field->setVar('field_weight', $weight);
202
203
        if (isset($vars['title'])) {
204
            $field->setVar('field_title', $vars['title']);
205
        }
206
207
        if (isset($vars['description'])) {
208
            $field->setVar('field_description', $vars['description']);
209
        }
210
211
        if (isset($vars['required'])) {
212
            $field->setVar('field_required', $vars['required']); //0 = no, 1 = yes
213
        }
214
215
        if (isset($vars['maxlength'])) {
216
            $field->setVar('field_maxlength', $vars['maxlength']);
217
        }
218
219
        if (isset($vars['default'])) {
220
            $field->setVar('field_default', $vars['default']);
221
        }
222
223
        if (isset($vars['notnull'])) {
224
            $field->setVar('field_notnull', $vars['notnull']);
225
        }
226
227
        if (isset($vars['show'])) {
228
            $field->setVar('field_show', $vars['show']);
229
        }
230
231
        if (isset($vars['edit'])) {
232
            $field->setVar('field_edit', $vars['edit']);
233
        }
234
235
        if (isset($vars['config'])) {
236
            $field->setVar('field_config', $vars['config']);
237
        }
238
239
        if (isset($vars['options'])) {
240
            $field->setVar('field_options', $vars['options']);
241
        } else {
242
            $field->setVar('field_options', []);
243
        }
244
245
        if ($this->insertField($field)) {
246
            $msg = '&nbsp;&nbsp;Field <strong>' . $vars['name'] . '</strong> added to the database';
247
        } else {
248
            $msg = '&nbsp;&nbsp;<span class="red">ERROR: Could not insert field <strong>' . $vars['name'] . '</strong> into the database. ' . \implode(' ', $field->getErrors()) . $this->db->error() . '</span>';
249
        }
250
251
        unset($field);
252
253
        return $msg;
254
    }
255
256
    /**
257
     * insert a new object in the database
258
     *
259
     * @param \XoopsObject $obj   reference to the object
260
     * @param bool         $force whether to force the query execution despite security settings
261
     *
262
     * @return bool FALSE if failed, TRUE if already present and unchanged or successful
263
     */
264
265
    public function insert(\XoopsObject $obj, $force = false)
266
    {
267
        if (!($obj instanceof $this->className)) {
268
            return false;
269
        }
270
271
        $uservars = $this->getUserVars();
272
273
        foreach ($uservars as $var) {
274
            unset($obj->vars[$var]);
275
        }
276
277
        if (0 == \count($obj->vars)) {
278
            return true;
279
        }
280
281
        return parent::insert($obj, $force);
282
    }
283
284
    /**
285
     * Get array of standard variable names (user table)
286
     *
287
     * @return array
288
     */
289
290
    public function getUserVars()
291
    {
292
        return $this->_fHandler->getUserVars();
0 ignored issues
show
Bug introduced by
The method getUserVars() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler. ( Ignorable by Annotation )

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

292
        return $this->_fHandler->/** @scrutinizer ignore-call */ getUserVars();
Loading history...
293
    }
294
295
    /**
296
     * Search profiles and users
297
     *
298
     * @param \CriteriaElement $criteria   CriteriaElement
299
     * @param array            $searchvars Fields to be fetched
300
     * @param array            $groups     for Usergroups is selected (only admin!)
301
     *
302
     * @return array
303
     */
304
305
    public function search(\CriteriaElement $criteria, $searchvars = [], $groups = null)
306
    {
307
        $uservars = $this->getUserVars();
308
309
        $searchvars_user = \array_intersect($searchvars, $uservars);
310
311
        $searchvars_profile = \array_diff($searchvars, $uservars);
312
313
        $sv = ['u.uid, u.uname, u.email, u.user_viewemail'];
314
315
        if (!empty($searchvars_user)) {
316
            $sv[0] .= ',u.' . \implode(', u.', $searchvars_user);
317
        }
318
319
        if (!empty($searchvars_profile)) {
320
            $sv[] = 'p.' . \implode(', p.', $searchvars_profile);
321
        }
322
323
        $sql_select = 'SELECT ' . (empty($searchvars) ? 'u.*, p.*' : \implode(', ', $sv));
324
325
        $sql_from = ' FROM ' . $this->db->prefix('users') . ' AS u LEFT JOIN ' . $this->table . ' AS p ON u.uid=p.profile_id' . (empty($groups) ? '' : ' LEFT JOIN ' . $this->db->prefix('groups_users_link') . ' AS g ON u.uid=g.uid');
326
327
        $sql_clause = ' WHERE 1=1';
328
329
        $sql_order = '';
330
331
        $limit = $start = 0;
332
333
        if (isset($criteria) && $criteria instanceof \CriteriaElement) {
334
            $sql_clause .= ' AND ' . $criteria->render();
335
336
            if ('' !== $criteria->getSort()) {
337
                $sql_order = ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
338
            }
339
340
            $limit = $criteria->getLimit();
341
342
            $start = $criteria->getStart();
343
        }
344
345
        if (!empty($groups)) {
346
            $sql_clause .= ' AND g.groupid IN (' . \implode(', ', $groups) . ')';
347
        }
348
349
        $sql_users = $sql_select . $sql_from . $sql_clause . $sql_order;
350
351
        $result = $this->db->query($sql_users, $limit, $start);
352
353
        if (!$result) {
354
            return [[], [], 0];
355
        }
356
357
        $user_handler = \xoops_getHandler('user');
358
359
        $uservars = $this->getUserVars();
360
361
        $users = [];
362
363
        $profiles = [];
364
365
        while (false !== ($myrow = $this->db->fetchArray($result))) {
366
            $profile = $this->create(false);
367
368
            $user = $user_handler->create(false);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $user is correct as $user_handler->create(false) targeting XoopsObjectHandler::create() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Unused Code introduced by
The call to XoopsObjectHandler::create() has too many arguments starting with false. ( Ignorable by Annotation )

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

368
            /** @scrutinizer ignore-call */ 
369
            $user = $user_handler->create(false);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
369
370
            foreach ($myrow as $name => $value) {
371
                if (\in_array($name, $uservars)) {
372
                    $user->assignVar($name, $value);
373
                } else {
374
                    $profile->assignVar($name, $value);
375
                }
376
            }
377
378
            $profiles[$myrow['uid']] = $profile;
379
380
            $users[$myrow['uid']] = $user;
381
        }
382
383
        $count = \count($users);
384
385
        if ((!empty($limit) && $count >= $limit) || !empty($start)) {
386
            $sql_count = 'SELECT COUNT(*)' . $sql_from . $sql_clause;
387
388
            $result = $this->db->query($sql_count);
389
390
            [$count] = $this->db->fetchRow($result);
391
        }
392
393
        return [$users, $profiles, (int)$count];
394
    }
395
}
396