ProfileHandler::loadFields()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Suico;
4
5
/**
6
 * Extended User Profile
7
 *
8
 * You may not change or alter any portion of this comment or credits
9
 * of supporting developers from this source code or any supporting source code
10
 * which is considered copyrighted (c) material of the original comment or credit authors.
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 *
15
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
16
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
17
 * @since               2.3.0
18
 * @author              Jan Pedersen
19
 * @author              Taiwen Jiang <[email protected]>
20
 */
21
22
/**
23
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
24
 */
25
26
use XoopsModules\Suico;
27
28
/**
29
 * Class ProfileHandler
30
 */
31
class ProfileHandler extends \XoopsPersistableObjectHandler
32
{
33
    /**
34
     * holds reference to {@link ProfileFieldHandler} object
35
     */
36
    public $fieldHandler;
37
    /**
38
     * Array of {@link Suico\Field} objects
39
     * @var array
40
     */
41
    public array $_fields = [];
42
43
    /**
44
     * @param \XoopsDatabase $db
45
     */
46
    public function __construct(\XoopsDatabase $db)
47
    {
48
        parent::__construct($db, 'suico_profile', Profile::class, 'profile_id');
49
        $this->fieldHandler = Helper::getInstance()->getHandler('Field');
50
    }
51
52
    /**
53
     * create a new {@link ProfileProfile}
54
     *
55
     * @param bool $isNew Flag the new objects as "new"?
56
     *
57
     * @return object {@link ProfileProfile}
58
     */
59
    public function create($isNew = true)
60
    {
61
        $obj          = new $this->className($this->loadFields());
62
        $obj->handler = $this;
63
        if ($isNew) {
64
            $obj->setNew();
65
        }
66
67
        return $obj;
68
    }
69
70
    /**
71
     * Get a ProfileProfile object for a user id.
72
     *
73
     * We will create an empty profile if none exists. This behavior allows user objects
74
     * created outside of profile to be edited correctly in the profile module.
75
     *
76
     * @param int|null      $id User ID
77
     * @param string[]|null $fields array of field names to fetch, null for all
78
     *
79
     * @return object {@link ProfileProfile}
80
     *
81
     * @internal This was get($id, $createOnFailure = true). No callers found using the extra parameter.
82
     * @internal Modified to match parent signature.
83
     */
84
    public function get($id = null, $fields = null)
85
    {
86
        $obj = parent::get($id, $fields);
87
        if (!\is_object($obj)) {
88
            $obj = $this->create();
89
        }
90
91
        return $obj;
92
    }
93
94
    /**
95
     * Create new {@link Suico\Field} object
96
     *
97
     * @param bool $isNew
98
     *
99
     * @return \XoopsModules\Suico\Field|\XoopsObject
100
     */
101
    public function createField($isNew = true)
102
    {
103
        $return = $this->fieldHandler->create($isNew);
104
105
        return $return;
106
    }
107
108
    /**
109
     * Load field information
110
     *
111
     * @return array
112
     */
113
    public function loadFields()
114
    {
115
        if (0 == \count($this->_fields)) {
116
            $this->_fields = $this->fieldHandler->loadFields();
117
        }
118
119
        return $this->_fields;
120
    }
121
122
    /**
123
     * Fetch fields
124
     *
125
     * @param \CriteriaElement $criteria  {@link CriteriaElement} object
126
     * @param bool             $id_as_key return array with field IDs as key?
127
     * @param bool             $as_object return array of objects?
128
     *
129
     * @return array
130
     */
131
    public function getFields(\CriteriaElement $criteria, $id_as_key = true, $as_object = true)
132
    {
133
        return $this->fieldHandler->getObjects($criteria, $id_as_key, $as_object);
134
    }
135
136
    /**
137
     * Insert a field in the database
138
     *
139
     * @param \XoopsModules\Suico\Field $field
140
     * @param bool                      $force
141
     *
142
     * @return bool
143
     */
144
    public function insertField(Suico\Field $field, $force = false)
145
    {
146
        return $this->fieldHandler->insert($field, $force);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->fieldHandl...>insert($field, $force) also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
147
    }
148
149
    /**
150
     * Delete a field from the database
151
     *
152
     * @param \XoopsModules\Suico\Field $field
153
     * @param bool                      $force
154
     *
155
     * @return bool
156
     */
157
    public function deleteField(Suico\Field $field, $force = false)
158
    {
159
        return $this->fieldHandler->delete($field, $force);
160
    }
161
162
    /**
163
     * Save a new field in the database
164
     *
165
     * @param array $vars array of variables, taken from $module->loadInfo('profile')['field']
166
     * @param int   $weight
167
     *
168
     * @return string
169
     * @internal param int $type valuetype of the field
170
     * @internal param int $moduleid ID of the module, this field belongs to
171
     * @internal param int $categoryid ID of the category to add it to
172
     */
173
    public function saveField($vars, $weight = 0)
174
    {
175
        $field = $this->createField();
176
        $field->setVar('field_name', $vars['name']);
177
        $field->setVar('field_valuetype', $vars['valuetype']);
178
        $field->setVar('field_type', $vars['type']);
179
        $field->setVar('field_weight', $weight);
180
        if (isset($vars['title'])) {
181
            $field->setVar('field_title', $vars['title']);
182
        }
183
        if (isset($vars['description'])) {
184
            $field->setVar('field_description', $vars['description']);
185
        }
186
        if (isset($vars['required'])) {
187
            $field->setVar('field_required', $vars['required']); //0 = no, 1 = yes
188
        }
189
        if (isset($vars['maxlength'])) {
190
            $field->setVar('field_maxlength', $vars['maxlength']);
191
        }
192
        if (isset($vars['default'])) {
193
            $field->setVar('field_default', $vars['default']);
194
        }
195
        if (isset($vars['notnull'])) {
196
            $field->setVar('field_notnull', $vars['notnull']);
197
        }
198
        if (isset($vars['show'])) {
199
            $field->setVar('field_show', $vars['show']);
200
        }
201
        if (isset($vars['edit'])) {
202
            $field->setVar('field_edit', $vars['edit']);
203
        }
204
        if (isset($vars['config'])) {
205
            $field->setVar('field_config', $vars['config']);
206
        }
207
        if (isset($vars['options'])) {
208
            $field->setVar('field_options', $vars['options']);
209
        } else {
210
            $field->setVar('field_options', []);
211
        }
212
        if ($this->insertField($field)) {
213
            $msg = '&nbsp;&nbsp;Field <strong>' . $vars['name'] . '</strong> added to the database';
214
        } else {
215
            $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>';
216
        }
217
        unset($field);
218
219
        return $msg;
220
    }
221
222
    /**
223
     * insert a new object in the database
224
     *
225
     * @param \XoopsObject $object   reference to the object
226
     * @param bool         $force whether to force the query execution despite security settings
227
     *
228
     * @return bool FALSE if failed, TRUE if already present and unchanged or successful
229
     */
230
    public function insert(\XoopsObject $object, $force = false)
231
    {
232
        if (!($object instanceof $this->className)) {
233
            return false;
234
        }
235
        $uservars = $this->getUserVars();
236
        foreach ($uservars as $var) {
237
            unset($object->vars[$var]);
238
        }
239
        if (0 == \count($object->vars)) {
240
            return true;
241
        }
242
243
        return parent::insert($object, $force);
244
    }
245
246
    /**
247
     * Get array of standard variable names (user table)
248
     *
249
     * @return array
250
     */
251
    public function getUserVars()
252
    {
253
        return $this->fieldHandler->getUserVars();
254
    }
255
256
    /**
257
     * Search profiles and users
258
     *
259
     * @param \CriteriaElement $criteria   CriteriaElement
260
     * @param array            $searchvars Fields to be fetched
261
     * @param array|null       $groups     for Usergroups is selected (only admin!)
262
     *
263
     * @return array
264
     */
265
    public function search(\CriteriaElement $criteria, $searchvars = [], $groups = null)
266
    {
267
        $uservars           = $this->getUserVars();
268
        $searchvars_user    = \array_intersect($searchvars, $uservars);
269
        $searchvars_profile = \array_diff($searchvars, $uservars);
270
        $sv                 = ['u.uid, u.uname, u.email, u.user_viewemail'];
271
        if (!empty($searchvars_user)) {
272
            $sv[0] .= ',u.' . \implode(', u.', $searchvars_user);
273
        }
274
        if (!empty($searchvars_profile)) {
275
            $sv[] = 'p.' . \implode(', p.', $searchvars_profile);
276
        }
277
        $sql_select = 'SELECT ' . (empty($searchvars) ? 'u.*, p.*' : \implode(', ', $sv));
278
        $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');
279
        $sql_clause = ' WHERE 1=1';
280
        $sql_order  = '';
281
        $start      = 0;
282
        $limit      = 0;
283
        if (($criteria instanceof \CriteriaCompo) || ($criteria instanceof \Criteria)) {
284
            $sql_clause .= ' AND ' . $criteria->render();
285
            if ('' !== $criteria->getSort()) {
286
                $sql_order = ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
287
            }
288
            $limit = $criteria->getLimit();
289
            $start = $criteria->getStart();
290
        }
291
        if (!empty($groups)) {
292
            $sql_clause .= ' AND g.groupid IN (' . \implode(', ', $groups) . ')';
293
        }
294
        $sql_users = $sql_select . $sql_from . $sql_clause . $sql_order;
295
        $result    = $this->db->query($sql_users, $limit, $start);
296
        if (!$result) {
297
            return [[], [], 0];
298
        }
299
        $userHandler = \xoops_getHandler('user');
300
        $uservars    = $this->getUserVars();
301
        $users       = [];
302
        $profiles    = [];
303
        while (false !== ($myrow = $this->db->fetchArray($result))) {
304
            $profile = $this->create(false);
305
            $user    = $userHandler->create(false);
0 ignored issues
show
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

305
            /** @scrutinizer ignore-call */ 
306
            $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...
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...
306
            foreach ($myrow as $name => $value) {
307
                if (\in_array($name, $uservars, true)) {
308
                    $user->assignVar($name, $value);
309
                } else {
310
                    $profile->assignVar($name, $value);
311
                }
312
            }
313
            $profiles[$myrow['uid']] = $profile;
314
            $users[$myrow['uid']]    = $user;
315
        }
316
        $count = \count($users);
317
        if ((!empty($limit) && $count >= $limit) || !empty($start)) {
318
            $sql_count = 'SELECT COUNT(*)' . $sql_from . $sql_clause;
319
            $result    = $this->db->query($sql_count);
320
            [$count] = $this->db->fetchRow($result);
321
        }
322
323
        return [$users, $profiles, (int)$count];
324
    }
325
}
326