FormUserUpdate::save()   B
last analyzed

Complexity

Conditions 10
Paths 14

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 19
nc 14
nop 0
dl 0
loc 30
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
namespace Apps\Model\Admin\User;
4
5
use Apps\ActiveRecord\Profile;
6
use Apps\ActiveRecord\Role;
7
use Apps\ActiveRecord\User;
8
use Ffcms\Core\Arch\Model;
9
use Ffcms\Core\Helper\Crypt;
10
use Ffcms\Core\Helper\Type\Any;
11
use Ffcms\Core\Helper\Type\Str;
12
use Ffcms\Core\Interfaces\iUser;
13
14
/**
15
 * Class FormUserUpdate. Update user data business logic model
16
 * @package Apps\Model\Admin\User
17
 */
18
class FormUserUpdate extends Model
19
{
20
    public $email;
21
    public $password;
22
    public $newpassword;
23
    public $role_id;
24
    public $approved = false;
25
26
    public $approve_token;
27
28
    /** @var iUser */
29
    public $_user;
30
31
    /**
32
     * FormUserUpdate constructor. Pass user object inside the model
33
     * @param iUser $user
34
     */
35
    public function __construct(iUser $user)
36
    {
37
        $this->_user = $user;
38
        parent::__construct(true);
39
    }
40
41
    /**
42
     * Load user data on before method
43
     */
44
    public function before()
45
    {
46
        foreach ($this->getAllProperties() as $property => $old_data) {
0 ignored issues
show
Bug introduced by
The expression $this->getAllProperties() of type null is not traversable.
Loading history...
Bug introduced by
Are you sure the usage of $this->getAllProperties() targeting Ffcms\Core\Arch\Model::getAllProperties() 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...
47
            if ($this->_user->{$property}) {
48
                $this->{$property} = $this->_user->{$property};
49
            }
50
        }
51
52
        if (!$this->approve_token) {
53
            $this->approved = true;
54
        }
55
    }
56
57
    /**
58
     * Form labels to display
59
     * @return array
60
     */
61
    public function labels(): array
62
    {
63
        return [
64
            'email' => __('Email'),
65
            'newpassword' => __('New password'),
66
            'role_id' => __('Role'),
67
            'approved' => __('Approved')
68
        ];
69
    }
70
71
    /**
72
     * Validation rules for input data
73
     * @return array
74
     */
75
    public function rules(): array
76
    {
77
        return [
78
            [['email', 'role_id', 'approved'], 'required'],
79
            ['newpassword', 'used'],
80
            ['email', 'email'],
81
            ['email', 'Apps\Model\Admin\User\FormUserUpdate::isUniqueEmail', $this->_user->getParam('id')],
82
        ];
83
    }
84
85
    /**
86
     * Get all roles as id=>name array
87
     * @return array|null
88
     */
89
    public function getRoleList()
90
    {
91
        return Role::getIdNameAll();
0 ignored issues
show
Bug introduced by
Are you sure the usage of Apps\ActiveRecord\Role::getIdNameAll() targeting Apps\ActiveRecord\Role::getIdNameAll() 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...
92
    }
93
94
    /**
95
     * Update user information in database based on current obj attributes passed from input data
96
     */
97
    public function save()
98
    {
99
        foreach ($this->getAllProperties() as $property => $value) {
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->getAllProperties() targeting Ffcms\Core\Arch\Model::getAllProperties() 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...
Bug introduced by
The expression $this->getAllProperties() of type null is not traversable.
Loading history...
100
            if ($property === 'password' || $property === 'newpassword') {
101
                // update password only if new is set and length >= 3
102
                if ($this->newpassword && Str::length($this->newpassword) >= 3) {
103
                    $this->_user->password = Crypt::passwordHash($this->newpassword);
104
                }
105
            } elseif ($property === 'approved') {
106
                if ($this->approved) {
107
                    $this->_user->approve_token = null;
108
                } else {
109
                    $this->_user->approve_token = $this->approve_token ?? Crypt::randomString(mt_rand(32, 128));
110
                }
111
            } elseif ($property === 'approve_token') {
112
                continue;
113
            } else {
114
                $this->_user->{$property} = $value;
115
            }
116
        }
117
118
        // get user id before save to determine "add" action
119
        $id = $this->_user->id;
120
        // safe user row
121
        $this->_user->save();
122
        // if new user - add profile link
123
        if ($id < 1) {
124
            $profile = new Profile();
125
            $profile->user_id = $this->_user->id;
126
            $profile->save();
127
        }
128
    }
129
130
    /**
131
     * Check if new email is always exist
132
     * @param string $email
133
     * @param int|null $userId
134
     * @return bool
135
     */
136
    public static function isUniqueEmail($email, $userId = null): bool
137
    {
138
        $find = User::where('email', $email);
139
140
        if ($userId && Any::isInt($userId)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $userId of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
141
            $find->where('id', '!=', $userId);
142
        }
143
144
        return $find->count() === 0;
145
    }
146
}
147