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

ProfileHandler   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 359
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 44
eloc 109
dl 0
loc 359
rs 8.8798
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A createField() 0 5 1
A __construct() 0 5 1
A insert() 0 17 4
A deleteField() 0 3 1
A insertField() 0 3 1
F saveField() 0 63 12
A getFields() 0 3 1
A get() 0 9 2
A loadFields() 0 7 2
A getUserVars() 0 3 1
A create() 0 11 2
F search() 0 87 16

How to fix   Complexity   

Complex Class

Complex classes like ProfileHandler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ProfileHandler, and based on these observations, apply Extract Interface, too.

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
 * @package             kernel
27
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
28
 */
29
30
use XoopsModules\Yogurt;
31
32
/**
33
 * Class ProfileHandler
34
 * @package XoopsModules\Yogurt
35
 */
36
class ProfileHandler extends \XoopsPersistableObjectHandler
37
{
38
    /**
39
     * holds reference to {@link profileFieldHandler} object
40
     */
41
42
    public $_fHandler;
43
44
    /**
45
     * Array of {@link XoopsYogurt\Field} objects
46
     * @var array
47
     */
48
49
    public $_fields = [];
50
51
    /**
52
     * @param \XoopsDatabase $db
53
     */
54
55
    public function __construct(\XoopsDatabase $db)
56
    {
57
        parent::__construct($db, 'yogurt_profile', Profile::class, 'profile_id');
58
59
        $this->_fHandler = \XoopsModules\Yogurt\Helper::getInstance()->getHandler('Field');
60
    }
61
62
    /**
63
     * create a new {@link ProfileProfile}
64
     *
65
     * @param bool $isNew Flag the new objects as "new"?
66
     *
67
     * @return object {@link ProfileProfile}
68
     */
69
70
    public function create($isNew = true)
71
    {
72
        $obj = new $this->className($this->loadFields());
73
74
        $obj->handler = $this;
75
76
        if ($isNew) {
77
            $obj->setNew();
78
        }
79
80
        return $obj;
81
    }
82
83
    /**
84
     * Get a ProfileProfile object for a user id.
85
     *
86
     * We will create an empty profile if none exists. This behavior allows user objects
87
     * created outside of profile to be edited correctly in the profile module.
88
     *
89
     * @param int|null      $uid
90
     * @param string[]|null $fields array of field names to fetch, null for all
91
     *
92
     * @return object {@link ProfileProfile}
93
     *
94
     * @internal This was get($uid, $createOnFailure = true). No callers found using the extra parameter.
95
     * @internal Modified to match parent signature.
96
     */
97
98
    public function get($uid = null, $fields = null)
99
    {
100
        $obj = parent::get($uid, $fields);
101
102
        if (!\is_object($obj)) {
103
            $obj = $this->create();
104
        }
105
106
        return $obj;
107
    }
108
109
    /**
110
     * Create new {@link Yogurt\Field} object
111
     *
112
     * @param bool $isNew
113
     *
114
     * @return Yogurt\Field
115
     */
116
117
    public function createField($isNew = true)
118
    {
119
        $return = $this->_fHandler->create($isNew);
120
121
        return $return;
122
    }
123
124
    /**
125
     * Load field information
126
     *
127
     * @return array
128
     */
129
130
    public function loadFields()
131
    {
132
        if (0 == \count($this->_fields)) {
133
            $this->_fields = $this->_fHandler->loadFields();
134
        }
135
136
        return $this->_fields;
137
    }
138
139
    /**
140
     * Fetch fields
141
     *
142
     * @param \CriteriaElement $criteria  {@link CriteriaElement} object
143
     * @param bool             $id_as_key return array with field IDs as key?
144
     * @param bool             $as_object return array of objects?
145
     *
146
     * @return array
147
     */
148
149
    public function getFields(\CriteriaElement $criteria, $id_as_key = true, $as_object = true)
150
    {
151
        return $this->_fHandler->getObjects($criteria, $id_as_key, $as_object);
152
    }
153
154
    /**
155
     * Insert a field in the database
156
     *
157
     * @param \XoopsModules\Yogurt\Field $field
158
     * @param bool                       $force
159
     *
160
     * @return bool
161
     */
162
163
    public function insertField(Yogurt\Field $field, $force = false)
164
    {
165
        return $this->_fHandler->insert($field, $force);
166
    }
167
168
    /**
169
     * Delete a field from the database
170
     *
171
     * @param \XoopsModules\Yogurt\Field $field
172
     * @param bool                       $force
173
     *
174
     * @return bool
175
     */
176
177
    public function deleteField(Yogurt\Field $field, $force = false)
178
    {
179
        return $this->_fHandler->delete($field, $force);
180
    }
181
182
    /**
183
     * Save a new field in the database
184
     *
185
     * @param array $vars array of variables, taken from $module->loadInfo('profile')['field']
186
     * @param int   $weight
187
     *
188
     * @return string
189
     * @internal param int $type valuetype of the field
190
     * @internal param int $moduleid ID of the module, this field belongs to
191
     * @internal param int $categoryid ID of the category to add it to
192
     */
193
194
    public function saveField($vars, $weight = 0)
195
    {
196
        $field = $this->createField();
197
198
        $field->setVar('field_name', $vars['name']);
199
200
        $field->setVar('field_valuetype', $vars['valuetype']);
201
202
        $field->setVar('field_type', $vars['type']);
203
204
        $field->setVar('field_weight', $weight);
205
206
        if (isset($vars['title'])) {
207
            $field->setVar('field_title', $vars['title']);
208
        }
209
210
        if (isset($vars['description'])) {
211
            $field->setVar('field_description', $vars['description']);
212
        }
213
214
        if (isset($vars['required'])) {
215
            $field->setVar('field_required', $vars['required']); //0 = no, 1 = yes
216
        }
217
218
        if (isset($vars['maxlength'])) {
219
            $field->setVar('field_maxlength', $vars['maxlength']);
220
        }
221
222
        if (isset($vars['default'])) {
223
            $field->setVar('field_default', $vars['default']);
224
        }
225
226
        if (isset($vars['notnull'])) {
227
            $field->setVar('field_notnull', $vars['notnull']);
228
        }
229
230
        if (isset($vars['show'])) {
231
            $field->setVar('field_show', $vars['show']);
232
        }
233
234
        if (isset($vars['edit'])) {
235
            $field->setVar('field_edit', $vars['edit']);
236
        }
237
238
        if (isset($vars['config'])) {
239
            $field->setVar('field_config', $vars['config']);
240
        }
241
242
        if (isset($vars['options'])) {
243
            $field->setVar('field_options', $vars['options']);
244
        } else {
245
            $field->setVar('field_options', []);
246
        }
247
248
        if ($this->insertField($field)) {
249
            $msg = '&nbsp;&nbsp;Field <strong>' . $vars['name'] . '</strong> added to the database';
250
        } else {
251
            $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>';
252
        }
253
254
        unset($field);
255
256
        return $msg;
257
    }
258
259
    /**
260
     * insert a new object in the database
261
     *
262
     * @param \XoopsObject $obj   reference to the object
263
     * @param bool         $force whether to force the query execution despite security settings
264
     *
265
     * @return bool FALSE if failed, TRUE if already present and unchanged or successful
266
     */
267
268
    public function insert(\XoopsObject $obj, $force = false)
269
    {
270
        if (!($obj instanceof $this->className)) {
271
            return false;
272
        }
273
274
        $uservars = $this->getUserVars();
275
276
        foreach ($uservars as $var) {
277
            unset($obj->vars[$var]);
278
        }
279
280
        if (0 == \count($obj->vars)) {
281
            return true;
282
        }
283
284
        return parent::insert($obj, $force);
285
    }
286
287
    /**
288
     * Get array of standard variable names (user table)
289
     *
290
     * @return array
291
     */
292
293
    public function getUserVars()
294
    {
295
        return $this->_fHandler->getUserVars();
296
    }
297
298
    /**
299
     * Search profiles and users
300
     *
301
     * @param \CriteriaElement $criteria   CriteriaElement
302
     * @param array            $searchvars Fields to be fetched
303
     * @param array            $groups     for Usergroups is selected (only admin!)
304
     *
305
     * @return array
306
     */
307
308
    public function search(\CriteriaElement $criteria, $searchvars = [], $groups = null)
309
    {
310
        $uservars = $this->getUserVars();
311
        $searchvars_user = \array_intersect($searchvars, $uservars);
312
        $searchvars_profile = \array_diff($searchvars, $uservars);
313
314
        $sv = ['u.uid, u.uname, u.email, u.user_viewemail'];
315
316
        if (!empty($searchvars_user)) {
317
            $sv[0] .= ',u.' . \implode(', u.', $searchvars_user);
318
        }
319
320
        if (!empty($searchvars_profile)) {
321
            $sv[] = 'p.' . \implode(', p.', $searchvars_profile);
322
        }
323
324
        $sql_select = 'SELECT ' . (empty($searchvars) ? 'u.*, p.*' : \implode(', ', $sv));
325
326
        $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');
327
328
        $sql_clause = ' WHERE 1=1';
329
330
        $sql_order = '';
331
332
        $limit = $start = 0;
333
334
        if (isset($criteria) && $criteria instanceof \CriteriaElement) {
335
            $sql_clause .= ' AND ' . $criteria->render();
336
337
            if ('' !== $criteria->getSort()) {
338
                $sql_order = ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
339
            }
340
341
            $limit = $criteria->getLimit();
342
343
            $start = $criteria->getStart();
344
        }
345
346
        if (!empty($groups)) {
347
            $sql_clause .= ' AND g.groupid IN (' . \implode(', ', $groups) . ')';
348
        }
349
350
        $sql_users = $sql_select . $sql_from . $sql_clause . $sql_order;
351
352
        $result = $this->db->query($sql_users, $limit, $start);
353
354
        if (!$result) {
355
            return [[], [], 0];
356
        }
357
358
        $userHandler = \xoops_getHandler('user');
359
360
        $uservars = $this->getUserVars();
361
362
        $users = [];
363
364
        $profiles = [];
365
366
        while (false !== ($myrow = $this->db->fetchArray($result))) {
367
            $profile = $this->create(false);
368
369
            $user = $userHandler->create(false);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $user is correct as $userHandler->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

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