Passed
Push — 3.x ( ff4171...504ae3 )
by Jerome
26:57 queued 12s
created

UsersTable::findActive()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 37
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 3.0006

Importance

Changes 0
Metric Value
cc 3
eloc 25
nc 4
nop 1
dl 0
loc 37
ccs 23
cts 24
cp 0.9583
crap 3.0006
rs 9.52
c 0
b 0
f 0
1
<?php
2
3
namespace Elgg\Database;
4
5
use Elgg\Config as Conf;
6
use Elgg\Database;
7
use Elgg\Database\Clauses\OrderByClause;
8
use ElggUser;
9
use RegistrationException;
10
11
/**
12
 * WARNING: API IN FLUX. DO NOT USE DIRECTLY.
13
 *
14
 * @internal
15
 *
16
 * @since 1.10.0
17
 */
18
class UsersTable {
19
20
	use \Elgg\TimeUsing;
21
22
	/**
23
	 * @var Conf
24
	 */
25
	protected $config;
26
27
	/**
28
	 * @var Database
29
	 */
30
	protected $db;
31
32
	/**
33
	 * @var MetadataTable
34
	 */
35
	protected $metadata;
36
37
	/**
38
	 * Constructor
39
	 *
40
	 * @param Conf          $config   Config
41
	 * @param Database      $db       Database
42
	 * @param MetadataTable $metadata Metadata table
43
	 */
44 5200
	public function __construct(Conf $config, Database $db, MetadataTable $metadata) {
45 5200
		$this->config = $config;
46 5200
		$this->db = $db;
47 5200
		$this->metadata = $metadata;
48 5200
	}
49
50
	/**
51
	 * Get user by username
52
	 *
53
	 * @param string $username The user's username
54
	 *
55
	 * @return ElggUser|false Depending on success
56
	 */
57 516
	public function getByUsername($username) {
58
59
		// Fixes #6052. Username is frequently sniffed from the path info, which,
60
		// unlike $_GET, is not URL decoded. If the username was not URL encoded,
61
		// this is harmless.
62 516
		$username = rawurldecode($username);
63
64 516
		if (!$username) {
65 15
			return false;
66
		}
67
68 511
		$entity =_elgg_services()->dataCache->usernames->load($username);
69 511
		if ($entity instanceof ElggUser) {
70 30
			return $entity;
71
		}
72
73 511
		$users = elgg_get_entities([
74 511
			'types' => 'user',
75
			'metadata_name_value_pairs' => [
76
				[
77 511
					'name' => 'username',
78 511
					'value' => $username,
79
					'case_sensitive' => false,
80
				],
81
			],
82 511
			'limit' => 1,
83
		]);
84
85 511
		return $users ? $users[0] : false;
86
	}
87
88
	/**
89
	 * Get an array of users from an email address
90
	 *
91
	 * @param string $email Email address
92
	 * @return \ElggUser[]
93
	 */
94 498
	public function getByEmail($email) {
95 498
		if (!$email) {
96
			return [];
97
		}
98
99 498
		$users = elgg_get_entities([
100 498
			'types' => 'user',
101
			'metadata_name_value_pairs' => [
102
				[
103 498
					'name' => 'email',
104 498
					'value' => $email,
105
					'case_sensitive' => false,
106
				],
107
			],
108 498
			'limit' => 1,
109
		]);
110
111 498
		return $users ? : [];
112
	}
113
114
	/**
115
	 * Return users (or the number of them) who have been active within a recent period.
116
	 *
117
	 * @param array $options Array of options with keys:
118
	 *
119
	 *   seconds (int)  => Length of period (default 600 = 10min)
120
	 *   limit   (int)  => Limit (default 10)
121
	 *   offset  (int)  => Offset (default 0)
122
	 *   count   (bool) => Return a count instead of users? (default false)
123
	 *
124
	 * @return \ElggUser[]|int
125
	 */
126 1
	public function findActive(array $options = []) {
127
128 1
		$options = array_merge([
129 1
			'seconds' => 600,
130 1
			'limit' => $this->config->default_limit,
131
		], $options);
132
133
		// cast options we're sending to hook
134 1
		foreach (['seconds', 'limit', 'offset'] as $key) {
135 1
			$options[$key] = (int) $options[$key];
136
		}
137 1
		$options['count'] = (bool) $options['count'];
138
139
		// allow plugins to override
140
		$params = [
141 1
			'seconds' => $options['seconds'],
142 1
			'limit' => $options['limit'],
143 1
			'offset' => $options['offset'],
144 1
			'count' => $options['count'],
145 1
			'options' => $options,
146
		];
147 1
		$data = _elgg_services()->hooks->trigger('find_active_users', 'system', $params, null);
148
		// check null because the handler could legitimately return falsey values.
149 1
		if ($data !== null) {
150
			return $data;
151
		}
152
153 1
		$time = $this->getCurrentTime()->getTimestamp() - $options['seconds'];
154 1
		return elgg_get_entities([
155 1
			'type' => 'user',
156 1
			'limit' => $options['limit'],
157 1
			'offset' => $options['offset'],
158 1
			'count' => $options['count'],
159
			'wheres' => function(QueryBuilder $qb, $main_alias) use ($time) {
160 1
				return $qb->compare("{$main_alias}.last_action", '>=', $time, ELGG_VALUE_INTEGER);
161 1
			},
162 1
			'order_by' => new OrderByClause('e.last_action', 'DESC'),
163
		]);
164
	}
165
166
	/**
167
	 * Registers a user, returning false if the username already exists
168
	 *
169
	 * @param string $username              The username of the new user
170
	 * @param string $password              The password
171
	 * @param string $name                  The user's display name
172
	 * @param string $email                 The user's email address
173
	 * @param bool   $allow_multiple_emails Allow the same email address to be
174
	 *                                      registered multiple times?
175
	 * @param string $subtype               Subtype of the user entity
176
	 *
177
	 * @return int|false The new user's GUID; false on failure
178
	 * @throws RegistrationException
179
	 * @deprecated 3.0 Use elgg()->accounts->register()
180
	 */
181
	public function register($username, $password, $name, $email, $allow_multiple_emails = false, $subtype = null) {
182
		_elgg_services()->accounts->register($username, $password, $name, $email, $allow_multiple_emails, $subtype);
183
	}
184
185
	/**
186
	 * Generates a unique invite code for a user
187
	 *
188
	 * @param string $username The username of the user sending the invitation
189
	 *
190
	 * @return string Invite code
191
	 * @see validateInviteCode
192
	 */
193
	public function generateInviteCode($username) {
194
		$time = $this->getCurrentTime()->getTimestamp();
195
		return "$time." . _elgg_services()->hmac->getHmac([(int) $time, $username])->getToken();
196
	}
197
198
	/**
199
	 * Validate a user's invite code
200
	 *
201
	 * @param string $username The username
202
	 * @param string $code     The invite code
203
	 *
204
	 * @return bool
205
	 * @see generateInviteCode
206
	 */
207
	public function validateInviteCode($username, $code) {
208
		// validate the format of the token created by ->generateInviteCode()
209
		if (!preg_match('~^(\d+)\.([a-zA-Z0-9\-_]+)$~', $code, $m)) {
210
			return false;
211
		}
212
		$time = $m[1];
213
		$mac = $m[2];
214
215
		return _elgg_services()->hmac->getHmac([(int) $time, $username])->matchesToken($mac);
216
	}
217
}
218