User::getGroups()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 17
ccs 9
cts 9
cp 1
rs 9.4285
cc 3
eloc 13
nc 4
nop 0
crap 3
1
<?php
2
3
namespace App;
4
5
class User
6
{
7
8
    /** @var integer The ID of the public group. */
9
    const GROUP_PUBLIC = 1;
10
11
    /** @var integer The ID of the admin group. */
12
    const GROUP_ADMIN = 2;
13
14
    /** @var \App\Db */
15
    protected $db;
16
17
    /** @var stdClass */
18
    protected $data;
19
20 15
    public function __construct($database = null)
21
    {
22 15
        $this->db = ($database) ? $database : new Db();
23 15
    }
24
25 14
    public function register($name, $email = null, $password = null)
26
    {
27
        $params = [
28 14
            'email' => $email,
29 14
            'password' => password_hash($password, PASSWORD_DEFAULT),
30
        ];
31
32
        // Add the user.
33 14
        $userCount = 'SELECT COUNT(*) FROM `users` WHERE `name` LIKE :name';
34 14
        $userNum = $this->db->query($userCount, ['name' => "$name%"])->fetchColumn();
35 14
        $userName = ($userNum > 0) ? $name . ' ' . ($userNum + 1) : $name;
36 14
        $params['name'] = $userName;
37 14
        $this->db->query("INSERT INTO users SET name=:name, email=:email, password=:password", $params);
38 14
        $userId = $this->db->lastInsertId();
39
40
        // Add the new user to a group of their own.
41 14
        $groupCountSql = 'SELECT COUNT(*) FROM `groups` WHERE `name` LIKE :name';
42 14
        $groupNum = $this->db->query($groupCountSql, ['name' => "$name%"])->fetchColumn();
43 14
        $groupName = ($groupNum > 0) ? $name . ' ' . ($groupNum + 1) : $name;
44 14
        $this->db->query('INSERT INTO `groups` SET `name`=:name', ['name' => $groupName]);
45 14
        $personalGroupId = $this->db->lastInsertId();
46 14
        $groupMemberSql = 'INSERT INTO `user_groups` SET `user`=:u, `group`=:g';
47 14
        $this->db->query($groupMemberSql, ['u' => $userId, 'g' => $personalGroupId]);
48
        // Make it their default group.
49 14
        $defaultGroupSql = "UPDATE `users` SET `default_group` = :g WHERE `id`=:u";
50 14
        $this->db->query($defaultGroupSql, ['g' => $personalGroupId, 'u' => $userId]);
51
52
        // Also add them to the public group.
53 14
        $groupMemberSql = 'INSERT INTO `user_groups` SET `user`=:u, `group`=:g';
54 14
        $this->db->query($groupMemberSql, ['u' => $userId, 'g' => self::GROUP_PUBLIC]);
55
56
        // Reload the user's data.
57 14
        $this->load($userId);
58 14
    }
59
60
    /**
61
     * Get a list of all groups that this user belongs to.
62
     * @return string[] Each array item is an array with 'id' and 'name' properties.
63
     */
64 7
    public function getGroups()
65
    {
66 7
        if ($this->getId() === false) {
67 1
            $sql = "SELECT `id`, `name` FROM `groups` WHERE `id` = " . self::GROUP_PUBLIC;
68
        } else {
69
            $sql = "SELECT g.id, g.name FROM users u "
70
                . " JOIN user_groups ug ON ug.user = u.id "
71
                . " JOIN `groups` g ON ug.group = g.id"
72 6
                . " WHERE u.id = :id";
73
        }
74 7
        $groups = [];
75 7
        $results = $this->db->query($sql, ['id' => $this->getId()])->fetchAll();
76 7
        foreach ($results as $res) {
77 7
            $groups[] = ['id' => (int) $res->id, 'name' => $res->name];
78
        }
79 7
        return $groups;
80
    }
81
82
    /**
83
     * Get an array of the IDs of all the groups that this user belongs to.
84
     * @return integer[] The group IDs.
85
     */
86
    public function getGroupIds()
87
    {
88
        $ids = [];
89
        foreach ($this->getGroups() as $group) {
90
            $ids[] = $group['id'];
91
        }
92
        return $ids;
93
    }
94
95
    public function getReminder()
96
    {
97
        if ($this->getId() === false) {
98
            return false;
99
        }
100
        $sql = "UPDATE users SET reminder_token=:t, reminder_time=NOW() WHERE id=:id";
101
        $unhashedToken = md5(time());
102
        $params = [
103
            't' => password_hash($unhashedToken, PASSWORD_DEFAULT),
104
            'id' => $this->getId(),
105
        ];
106
        $this->db->query($sql, $params);
107
        return $unhashedToken;
108
    }
109
110
    public function checkReminderToken($token)
111
    {
112
        return password_verify($token, $this->data->reminder_token);
113
    }
114
115
    public function changePassword($password)
116
    {
117
        if ($this->getId() === false) {
118
            return false;
119
        }
120
        $sql = "UPDATE users SET password=:pwd, reminder_token=NULL, reminder_time=NULL WHERE id=:id";
121
        $params = [
122
            'pwd' => password_hash($password, PASSWORD_DEFAULT),
123
            'id' => $this->getId(),
124
        ];
125
        $this->db->query($sql, $params);
126
    }
127
128 14
    public function load($id)
129
    {
130 14
        $sql = "SELECT * FROM users WHERE id = :id";
131 14
        $this->data = $this->db->query($sql, ['id' => $id])->fetch();
132 14
    }
133
134
    public function loadByName($name)
135
    {
136
        $sql = "SELECT * FROM users WHERE name = :name";
137
        $this->data = $this->db->query($sql, ['name' => $name])->fetch();
138
    }
139
140
    /**
141
     * Whether this user is loaded or not (i.e. has a database ID).
142
     * @return boolean
143
     */
144
    public function loaded()
145
    {
146
        return $this->getId() !== false;
147
    }
148
149
    /**
150
     * Get the user's ID, or false if the user isn't loaded yet.
151
     * @return bool|integer
152
     */
153 13
    public function getId()
154
    {
155 13
        return (isset($this->data->id)) ? (int) $this->data->id : false;
156
    }
157
158 2
    public function getName()
159
    {
160 2
        return isset($this->data->name) ? $this->data->name : false;
161
    }
162
163
    public function getEmail()
164
    {
165
        return isset($this->data->email) ? $this->data->email : false;
166
    }
167
168
    /**
169
     * Get this user's default group.
170
     *
171
     * @return StdClass with attributes: 'id', 'name'.
172
     */
173 13 View Code Duplication
    public function getDefaultGroup()
0 ignored issues
show
Duplication introduced by
This method 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...
174
    {
175 13
        $defaultGroupId = isset($this->data->default_group) ? $this->data->default_group : self::GROUP_PUBLIC;
176 13
        $sql = "SELECT * FROM groups WHERE id = :id";
177 13
        $group = $this->db->query($sql, ['id' => $defaultGroupId])->fetch();
178 13
        return $group;
179
    }
180
}
181